db_kv.go 1.7 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. "iter"
  9. "github.com/jmoiron/sqlx"
  10. "github.com/syncthing/syncthing/internal/db"
  11. )
  12. func (s *baseDB) GetKV(key string) ([]byte, error) {
  13. var val []byte
  14. if err := s.stmt(`
  15. SELECT value FROM kv
  16. WHERE key = ?
  17. `).Get(&val, key); err != nil {
  18. return nil, wrap(err)
  19. }
  20. return val, nil
  21. }
  22. func (s *baseDB) PutKV(key string, val []byte) error {
  23. s.updateLock.Lock()
  24. defer s.updateLock.Unlock()
  25. _, err := s.stmt(`
  26. INSERT OR REPLACE INTO kv (key, value)
  27. VALUES (?, ?)
  28. `).Exec(key, val)
  29. return wrap(err)
  30. }
  31. func (s *baseDB) DeleteKV(key string) error {
  32. s.updateLock.Lock()
  33. defer s.updateLock.Unlock()
  34. _, err := s.stmt(`
  35. DELETE FROM kv WHERE key = ?
  36. `).Exec(key)
  37. return wrap(err)
  38. }
  39. func (s *baseDB) PrefixKV(prefix string) (iter.Seq[db.KeyValue], func() error) {
  40. var rows *sqlx.Rows
  41. var err error
  42. if prefix == "" {
  43. rows, err = s.stmt(`SELECT key, value FROM kv`).Queryx()
  44. } else {
  45. end := prefixEnd(prefix)
  46. rows, err = s.stmt(`
  47. SELECT key, value FROM kv
  48. WHERE key >= ? AND key < ?
  49. `).Queryx(prefix, end)
  50. }
  51. if err != nil {
  52. return func(_ func(db.KeyValue) bool) {}, func() error { return err }
  53. }
  54. return func(yield func(db.KeyValue) bool) {
  55. defer rows.Close()
  56. for rows.Next() {
  57. var key string
  58. var val []byte
  59. if err = rows.Scan(&key, &val); err != nil {
  60. return
  61. }
  62. if !yield(db.KeyValue{Key: key, Value: val}) {
  63. return
  64. }
  65. }
  66. err = rows.Err()
  67. }, func() error {
  68. return err
  69. }
  70. }