Switch the database from LevelDB to SQLite, for greater stability and simpler code. Co-authored-by: Tommy van der Vorst <tommy@pixelspark.nl> Co-authored-by: bt90 <btom1990@googlemail.com>
This commit is contained in:
co-authored by
Tommy van der Vorst
bt90
parent
b1c8f88a44
commit
025905fcdf
@@ -0,0 +1,123 @@
|
||||
// Copyright (C) 2025 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
package db // import "github.com/syncthing/syncthing/internal/db/sqlite"
|
||||
|
||||
import (
|
||||
"iter"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/thejerf/suture/v4"
|
||||
)
|
||||
|
||||
type DB interface {
|
||||
Service(maintenanceInterval time.Duration) suture.Service
|
||||
|
||||
// Basics
|
||||
Update(folder string, device protocol.DeviceID, fs []protocol.FileInfo) error
|
||||
Close() error
|
||||
|
||||
// Single files
|
||||
GetDeviceFile(folder string, device protocol.DeviceID, file string) (protocol.FileInfo, bool, error)
|
||||
GetGlobalAvailability(folder, file string) ([]protocol.DeviceID, error)
|
||||
GetGlobalFile(folder string, file string) (protocol.FileInfo, bool, error)
|
||||
|
||||
// File iterators
|
||||
//
|
||||
// n.b. there is a slight inconsistency in the return types where some
|
||||
// return a FileInfo iterator and some a FileMetadata iterator. The
|
||||
// latter is more lightweight, and the discrepancy depends on how the
|
||||
// functions tend to be used. We can introduce more variations as
|
||||
// required.
|
||||
AllGlobalFiles(folder string) (iter.Seq[FileMetadata], func() error)
|
||||
AllGlobalFilesPrefix(folder string, prefix string) (iter.Seq[FileMetadata], func() error)
|
||||
AllLocalBlocksWithHash(hash []byte) (iter.Seq[BlockMapEntry], func() error)
|
||||
AllLocalFiles(folder string, device protocol.DeviceID) (iter.Seq[protocol.FileInfo], func() error)
|
||||
AllLocalFilesBySequence(folder string, device protocol.DeviceID, startSeq int64, limit int) (iter.Seq[protocol.FileInfo], func() error)
|
||||
AllLocalFilesWithPrefix(folder string, device protocol.DeviceID, prefix string) (iter.Seq[protocol.FileInfo], func() error)
|
||||
AllLocalFilesWithBlocksHash(folder string, h []byte) (iter.Seq[FileMetadata], func() error)
|
||||
AllLocalFilesWithBlocksHashAnyFolder(h []byte) (iter.Seq2[string, FileMetadata], func() error)
|
||||
AllNeededGlobalFiles(folder string, device protocol.DeviceID, order config.PullOrder, limit, offset int) (iter.Seq[protocol.FileInfo], func() error)
|
||||
|
||||
// Cleanup
|
||||
DropAllFiles(folder string, device protocol.DeviceID) error
|
||||
DropDevice(device protocol.DeviceID) error
|
||||
DropFilesNamed(folder string, device protocol.DeviceID, names []string) error
|
||||
DropFolder(folder string) error
|
||||
|
||||
// Various metadata
|
||||
GetDeviceSequence(folder string, device protocol.DeviceID) (int64, error)
|
||||
ListFolders() ([]string, error)
|
||||
ListDevicesForFolder(folder string) ([]protocol.DeviceID, error)
|
||||
RemoteSequences(folder string) (map[protocol.DeviceID]int64, error)
|
||||
|
||||
// Counts
|
||||
CountGlobal(folder string) (Counts, error)
|
||||
CountLocal(folder string, device protocol.DeviceID) (Counts, error)
|
||||
CountNeed(folder string, device protocol.DeviceID) (Counts, error)
|
||||
CountReceiveOnlyChanged(folder string) (Counts, error)
|
||||
|
||||
// Index IDs
|
||||
DropAllIndexIDs() error
|
||||
GetIndexID(folder string, device protocol.DeviceID) (protocol.IndexID, error)
|
||||
SetIndexID(folder string, device protocol.DeviceID, id protocol.IndexID) error
|
||||
|
||||
// MtimeFS
|
||||
DeleteMtime(folder, name string) error
|
||||
GetMtime(folder, name string) (ondisk, virtual time.Time)
|
||||
PutMtime(folder, name string, ondisk, virtual time.Time) error
|
||||
|
||||
KV
|
||||
}
|
||||
|
||||
// Generic KV store
|
||||
type KV interface {
|
||||
GetKV(key string) ([]byte, error)
|
||||
PutKV(key string, val []byte) error
|
||||
DeleteKV(key string) error
|
||||
PrefixKV(prefix string) (iter.Seq[KeyValue], func() error)
|
||||
}
|
||||
|
||||
type BlockMapEntry struct {
|
||||
BlocklistHash []byte
|
||||
Offset int64
|
||||
BlockIndex int
|
||||
Size int
|
||||
}
|
||||
|
||||
type KeyValue struct {
|
||||
Key string
|
||||
Value []byte
|
||||
}
|
||||
|
||||
type FileMetadata struct {
|
||||
Name string
|
||||
Sequence int64
|
||||
ModNanos int64
|
||||
Size int64
|
||||
LocalFlags int64
|
||||
Type protocol.FileInfoType
|
||||
Deleted bool
|
||||
Invalid bool
|
||||
}
|
||||
|
||||
func (f *FileMetadata) ModTime() time.Time {
|
||||
return time.Unix(0, f.ModNanos)
|
||||
}
|
||||
|
||||
func (f *FileMetadata) IsReceiveOnlyChanged() bool {
|
||||
return f.LocalFlags&protocol.FlagLocalReceiveOnly != 0
|
||||
}
|
||||
|
||||
func (f *FileMetadata) IsDirectory() bool {
|
||||
return f.Type == protocol.FileInfoTypeDirectory
|
||||
}
|
||||
|
||||
func (f *FileMetadata) ShouldConflict() bool {
|
||||
return f.LocalFlags&protocol.LocalConflictFlags != 0
|
||||
}
|
||||
Reference in New Issue
Block a user