db.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. "sync"
  9. "time"
  10. "github.com/jmoiron/sqlx"
  11. "github.com/syncthing/syncthing/internal/db"
  12. "github.com/syncthing/syncthing/lib/protocol"
  13. "github.com/thejerf/suture/v4"
  14. )
  15. type DB struct {
  16. sql *sqlx.DB
  17. localDeviceIdx int64
  18. updateLock sync.Mutex
  19. updatePoints int
  20. statementsMut sync.RWMutex
  21. statements map[string]*sqlx.Stmt
  22. tplInput map[string]any
  23. }
  24. var _ db.DB = (*DB)(nil)
  25. func (s *DB) Close() error {
  26. s.updateLock.Lock()
  27. s.statementsMut.Lock()
  28. defer s.updateLock.Unlock()
  29. defer s.statementsMut.Unlock()
  30. for _, stmt := range s.statements {
  31. stmt.Close()
  32. }
  33. return wrap(s.sql.Close())
  34. }
  35. func (s *DB) Service(maintenanceInterval time.Duration) suture.Service {
  36. return newService(s, maintenanceInterval)
  37. }
  38. func (s *DB) ListFolders() ([]string, error) {
  39. var res []string
  40. err := s.stmt(`
  41. SELECT folder_id FROM folders
  42. ORDER BY folder_id
  43. `).Select(&res)
  44. return res, wrap(err)
  45. }
  46. func (s *DB) ListDevicesForFolder(folder string) ([]protocol.DeviceID, error) {
  47. var res []string
  48. err := s.stmt(`
  49. SELECT d.device_id FROM counts s
  50. INNER JOIN folders o ON o.idx = s.folder_idx
  51. INNER JOIN devices d ON d.idx = s.device_idx
  52. WHERE o.folder_id = ? AND s.count > 0 AND s.device_idx != {{.LocalDeviceIdx}}
  53. GROUP BY d.device_id
  54. ORDER BY d.device_id
  55. `).Select(&res, folder)
  56. if err != nil {
  57. return nil, wrap(err)
  58. }
  59. devs := make([]protocol.DeviceID, len(res))
  60. for i, s := range res {
  61. devs[i], err = protocol.DeviceIDFromString(s)
  62. if err != nil {
  63. return nil, wrap(err)
  64. }
  65. }
  66. return devs, nil
  67. }