1
0

folderdb_open.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright (C) 2025 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package sqlite
  7. import (
  8. "fmt"
  9. "time"
  10. "github.com/syncthing/syncthing/lib/protocol"
  11. )
  12. type folderDB struct {
  13. *baseDB
  14. folderID string
  15. localDeviceIdx int64
  16. deleteRetention time.Duration
  17. }
  18. func openFolderDB(folder, path string, deleteRetention time.Duration) (*folderDB, error) {
  19. pragmas := []string{
  20. "journal_mode = WAL",
  21. "optimize = 0x10002",
  22. "auto_vacuum = INCREMENTAL",
  23. fmt.Sprintf("application_id = %d", applicationIDFolder),
  24. }
  25. schemas := []string{
  26. "sql/schema/common/*",
  27. "sql/schema/folder/*",
  28. }
  29. migrations := []string{
  30. "sql/migrations/common/*",
  31. "sql/migrations/folder/*",
  32. }
  33. base, err := openBase(path, maxDBConns, pragmas, schemas, migrations)
  34. if err != nil {
  35. return nil, err
  36. }
  37. fdb := &folderDB{
  38. folderID: folder,
  39. baseDB: base,
  40. deleteRetention: deleteRetention,
  41. }
  42. _ = fdb.PutKV("folderID", []byte(folder))
  43. // Touch device IDs that should always exist and have a low index
  44. // numbers, and will never change
  45. fdb.localDeviceIdx, _ = fdb.deviceIdxLocked(protocol.LocalDeviceID)
  46. fdb.tplInput["LocalDeviceIdx"] = fdb.localDeviceIdx
  47. return fdb, nil
  48. }
  49. // Open the database with options suitable for the migration inserts. This
  50. // is not a safe mode of operation for normal processing, use only for bulk
  51. // inserts with a close afterwards.
  52. func openFolderDBForMigration(folder, path string, deleteRetention time.Duration) (*folderDB, error) {
  53. pragmas := []string{
  54. "journal_mode = OFF",
  55. "foreign_keys = 0",
  56. "synchronous = 0",
  57. "locking_mode = EXCLUSIVE",
  58. fmt.Sprintf("application_id = %d", applicationIDFolder),
  59. }
  60. schemas := []string{
  61. "sql/schema/common/*",
  62. "sql/schema/folder/*",
  63. }
  64. base, err := openBase(path, 1, pragmas, schemas, nil)
  65. if err != nil {
  66. return nil, err
  67. }
  68. fdb := &folderDB{
  69. folderID: folder,
  70. baseDB: base,
  71. deleteRetention: deleteRetention,
  72. }
  73. // Touch device IDs that should always exist and have a low index
  74. // numbers, and will never change
  75. fdb.localDeviceIdx, _ = fdb.deviceIdxLocked(protocol.LocalDeviceID)
  76. fdb.tplInput["LocalDeviceIdx"] = fdb.localDeviceIdx
  77. return fdb, nil
  78. }
  79. func (s *folderDB) deviceIdxLocked(deviceID protocol.DeviceID) (int64, error) {
  80. devStr := deviceID.String()
  81. var idx int64
  82. if err := s.stmt(`
  83. INSERT INTO devices(device_id)
  84. VALUES (?)
  85. ON CONFLICT(device_id) DO UPDATE
  86. SET device_id = excluded.device_id
  87. RETURNING idx
  88. `).Get(&idx, devStr); err != nil {
  89. return 0, wrap(err)
  90. }
  91. return idx, nil
  92. }