mirror of
https://github.com/syncthing/syncthing.git
synced 2026-03-26 02:01:11 -04:00
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>
89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
// 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 sqlite
|
|
|
|
import (
|
|
"embed"
|
|
"io/fs"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/syncthing/syncthing/lib/build"
|
|
)
|
|
|
|
const currentSchemaVersion = 1
|
|
|
|
//go:embed sql/**
|
|
var embedded embed.FS
|
|
|
|
func (s *DB) runScripts(glob string, filter ...func(s string) bool) error {
|
|
scripts, err := fs.Glob(embedded, glob)
|
|
if err != nil {
|
|
return wrap(err)
|
|
}
|
|
|
|
tx, err := s.sql.Begin()
|
|
if err != nil {
|
|
return wrap(err)
|
|
}
|
|
defer tx.Rollback() //nolint:errcheck
|
|
|
|
nextScript:
|
|
for _, scr := range scripts {
|
|
for _, fn := range filter {
|
|
if !fn(scr) {
|
|
l.Debugln("Skipping script", scr)
|
|
continue nextScript
|
|
}
|
|
}
|
|
l.Debugln("Executing script", scr)
|
|
bs, err := fs.ReadFile(embedded, scr)
|
|
if err != nil {
|
|
return wrap(err, scr)
|
|
}
|
|
// SQLite requires one statement per exec, so we split the init
|
|
// files on lines containing only a semicolon and execute them
|
|
// separately. We require it on a separate line because there are
|
|
// also statement-internal semicolons in the triggers.
|
|
for _, stmt := range strings.Split(string(bs), "\n;") {
|
|
if _, err := tx.Exec(stmt); err != nil {
|
|
return wrap(err, stmt)
|
|
}
|
|
}
|
|
}
|
|
|
|
return wrap(tx.Commit())
|
|
}
|
|
|
|
type schemaVersion struct {
|
|
SchemaVersion int
|
|
AppliedAt int64
|
|
SyncthingVersion string
|
|
}
|
|
|
|
func (s *schemaVersion) AppliedTime() time.Time {
|
|
return time.Unix(0, s.AppliedAt)
|
|
}
|
|
|
|
func (s *DB) setAppliedSchemaVersion(ver int) error {
|
|
_, err := s.stmt(`
|
|
INSERT OR IGNORE INTO schemamigrations (schema_version, applied_at, syncthing_version)
|
|
VALUES (?, ?, ?)
|
|
`).Exec(ver, time.Now().UnixNano(), build.LongVersion)
|
|
return wrap(err)
|
|
}
|
|
|
|
func (s *DB) getAppliedSchemaVersion() (schemaVersion, error) {
|
|
var v schemaVersion
|
|
err := s.stmt(`
|
|
SELECT schema_version as schemaversion, applied_at as appliedat, syncthing_version as syncthingversion FROM schemamigrations
|
|
ORDER BY schema_version DESC
|
|
LIMIT 1
|
|
`).Get(&v)
|
|
return v, wrap(err)
|
|
}
|