From 66ff40dac0ff6d42222ca3ed07ac0aba6b4b373a Mon Sep 17 00:00:00 2001 From: andig Date: Thu, 30 Apr 2026 15:21:40 +0200 Subject: [PATCH] chore: replace sqlite fork (#29493) --- Makefile | 1 - go.mod | 9 +++---- go.sum | 22 ++++++++--------- server/db/db.go | 66 +++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index ee3298c54..46af8a6fd 100644 --- a/Makefile +++ b/Makefile @@ -161,5 +161,4 @@ patch-asn1:: upgrade:: $(shell go list -u -f '{{if (and (not (or .Main .Indirect)) .Update)}}{{.Path}}{{end}}' -m all | xargs go get) - go get modernc.org/sqlite@latest go mod tidy diff --git a/go.mod b/go.mod index 62c5605f6..c9c4aeb83 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,6 @@ require ( github.com/evcc-io/tesla-proxy-client v0.0.0-20260324063928-151fe10796ae github.com/fatih/structs v1.1.0 github.com/getkin/kin-openapi v0.135.0 - github.com/glebarez/sqlite v1.11.0 github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1 github.com/go-playground/validator/v10 v10.30.2 github.com/go-telegram/bot v1.20.0 @@ -71,6 +70,7 @@ require ( github.com/koron/go-ssdp v0.1.0 github.com/korylprince/ipnetgen v1.0.1 github.com/libp2p/zeroconf/v2 v2.2.0 + github.com/libtnb/sqlite v1.0.4 github.com/lorenzodonini/ocpp-go v0.19.0 github.com/lunixbochs/struc v0.0.0-20241101090106-8d528fa2c543 github.com/mabunixda/wattpilot v1.8.5 @@ -118,6 +118,7 @@ require ( google.golang.org/grpc v1.80.0 google.golang.org/protobuf v1.36.11 gorm.io/gorm v1.31.1 + modernc.org/sqlite v1.50.0 ) require ( @@ -162,7 +163,6 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gabriel-vasile/mimetype v1.4.13 // indirect - github.com/glebarez/go-sqlite v1.22.0 // indirect github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 // indirect github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect @@ -250,10 +250,9 @@ require ( gopkg.in/go-playground/validator.v9 v9.30.0 // indirect gopkg.in/sourcemap.v1 v1.0.5 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.70.0 // indirect + modernc.org/libc v1.72.0 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect - modernc.org/sqlite v1.48.2 // indirect ) tool ( @@ -271,5 +270,3 @@ replace github.com/grid-x/modbus => github.com/evcc-io/modbus v0.0.0-20250501165 replace github.com/lorenzodonini/ocpp-go => github.com/evcc-io/ocpp-go v0.0.0-20251212212612-b7f92ee0443b replace go.yaml.in/yaml/v4 => go.yaml.in/yaml/v4 v4.0.0-rc.3 - -replace github.com/glebarez/sqlite => github.com/evcc-io/sqlite v0.0.0-20260421123006-d66e0643f9bb diff --git a/go.sum b/go.sum index 57f06df95..205b7590b 100644 --- a/go.sum +++ b/go.sum @@ -206,8 +206,6 @@ github.com/evcc-io/optimizer v0.0.0-20260411145738-bf13a64d411c h1:KUJqCEBzEXepn github.com/evcc-io/optimizer v0.0.0-20260411145738-bf13a64d411c/go.mod h1:cHMeq6GfoXQ8LxqY4LH1wn/hrgYEn+ka5RPI1CF37SY= github.com/evcc-io/rct v0.2.0 h1:qjXKI7NKwW5YpEKEb27MwLMBaR4ne2Kd2cPV2PYTKn4= github.com/evcc-io/rct v0.2.0/go.mod h1:n6MTBU36QOadGlxxiADu86VaT5l0eYdbmFBHF14AD/s= -github.com/evcc-io/sqlite v0.0.0-20260421123006-d66e0643f9bb h1:k0oq1Bcuidy30jREK6drmSVk0i5M9PENZULzBfk9Amw= -github.com/evcc-io/sqlite v0.0.0-20260421123006-d66e0643f9bb/go.mod h1:jTnU6XZ6pKY74rm4VrCSxgXmH0x3p3PcA00uAzr0OtQ= github.com/evcc-io/tesla-proxy-client v0.0.0-20260324063928-151fe10796ae h1:0ihqBMBjkekSlwD3ZYQIiYite6ZAln9ze60evOE6FkQ= github.com/evcc-io/tesla-proxy-client v0.0.0-20260324063928-151fe10796ae/go.mod h1:L8AR3E7/MbbvCgnrtzsT6YsgQJtN5gk/LumR1gDBeJM= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= @@ -230,8 +228,6 @@ github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9t github.com/getkin/kin-openapi v0.135.0 h1:751SjYfbiwqukYuVjwYEIKNfrSwS5YpA7DZnKSwQgtg= github.com/getkin/kin-openapi v0.135.0/go.mod h1:6dd5FJl6RdX4usBtFBaQhk9q62Yb2J0Mk5IhUO/QqFI= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= -github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1 h1:zga7zaRE8HCbWjcXMDlfvmQtH0/kMVLo7cQ48dy6kWg= github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1/go.mod h1:PumS+5d59wmAGsZo6IfRpVNaJUq+6xjC4Utt/k8GO6Q= github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 h1:O6yi4xa9b2DMosGsXzlMe2E9qXgXCVkRLCoRX+5amxI= @@ -480,6 +476,8 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= +github.com/libtnb/sqlite v1.0.4 h1:SPFG8aSNNaUjO1ises/AFeWV+q1etBAVrtXPci0Uhvs= +github.com/libtnb/sqlite v1.0.4/go.mod h1:PNlcqMVWU+pMIUR499fHvRLUdxrNVVVXwEZkW1c9stE= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lunixbochs/struc v0.0.0-20241101090106-8d528fa2c543 h1:GxMuVb9tJajC1QpbQwYNY1ZAo1EIE8I+UclBjOfjz/M= @@ -1080,10 +1078,10 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis= -modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= -modernc.org/ccgo/v4 v4.32.0 h1:hjG66bI/kqIPX1b2yT6fr/jt+QedtP2fqojG2VrFuVw= -modernc.org/ccgo/v4 v4.32.0/go.mod h1:6F08EBCx5uQc38kMGl+0Nm0oWczoo1c7cgpzEry7Uc0= +modernc.org/cc/v4 v4.27.3 h1:uNCgn37E5U09mTv1XgskEVUJ8ADKpmFMPxzGJ0TSo+U= +modernc.org/cc/v4 v4.27.3/go.mod h1:3YjcbCqhoTTHPycJDRl2WZKKFj0nwcOIPBfEZK0Hdk8= +modernc.org/ccgo/v4 v4.32.4 h1:L5OB8rpEX4ZsXEQwGozRfJyJSFHbbNVOoQ59DU9/KuU= +modernc.org/ccgo/v4 v4.32.4/go.mod h1:lY7f+fiTDHfcv6YlRgSkxYfhs+UvOEEzj49jAn2TOx0= modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM= modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= @@ -1092,8 +1090,8 @@ modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo= modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY= modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= -modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw= -modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo= +modernc.org/libc v1.72.0 h1:IEu559v9a0XWjw0DPoVKtXpO2qt5NVLAnFaBbjq+n8c= +modernc.org/libc v1.72.0/go.mod h1:tTU8DL8A+XLVkEY3x5E/tO7s2Q/q42EtnNWda/L5QhQ= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= @@ -1102,8 +1100,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.48.2 h1:5CnW4uP8joZtA0LedVqLbZV5GD7F/0x91AXeSyjoh5c= -modernc.org/sqlite v1.48.2/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig= +modernc.org/sqlite v1.50.0 h1:eMowQSWLK0MeiQTdmz3lqoF5dqclujdlIKeJA11+7oM= +modernc.org/sqlite v1.50.0/go.mod h1:m0w8xhwYUVY3H6pSDwc3gkJ/irZT/0YEXwBlhaxQEew= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/server/db/db.go b/server/db/db.go index 4c4cea7b4..f5b898198 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -1,15 +1,18 @@ package db import ( + "context" + "errors" "fmt" "os" "path/filepath" "strings" "github.com/evcc-io/evcc/util" - "github.com/glebarez/sqlite" + "github.com/libtnb/sqlite" "github.com/mitchellh/go-homedir" "gorm.io/gorm" + sqlite3 "modernc.org/sqlite" ) var ( @@ -30,7 +33,7 @@ func New(driver, dsn string) (*gorm.DB, error) { // ":memory:" // Split database path and connection parameters - dbPath, connectionParams, _ := strings.Cut(dsn, "?") + dbPath, params, _ := strings.Cut(dsn, "?") file, err := homedir.Expand(dbPath) if err != nil { @@ -44,18 +47,29 @@ func New(driver, dsn string) (*gorm.DB, error) { // Store the expanded file path for later use FilePath = file - // Add busy_timeout pragma if not already present - if !strings.Contains(connectionParams, "_pragma=busy_timeout") { + addParam := func(typ, param string) { + // Add busy_timeout pragma if not already present + if short, _, _ := strings.Cut(param, "("); strings.Contains(params, typ+"="+short) { + return + } + // Append '&' if there are existing connection parameters - if len(connectionParams) > 0 { - connectionParams += "&" + if len(params) > 0 { + params += "&" } // Add busy_timeout pragma to connection parameters - connectionParams += "_pragma=busy_timeout(5000)" + params += typ + "=" + param } - connectionStr := file + "?" + connectionParams + for _, pragma := range []string{"busy_timeout(5000)", "foreign_keys(1)", "synchronous(NORMAL)"} { + addParam("_pragma", pragma) + } + + // https://github.com/libtnb/sqlite/issues/15 + addParam("_time_format", "sqlite") + + connectionStr := file + "?" + params util.NewLogger("main").INFO.Println("using sqlite database:", connectionStr) @@ -100,3 +114,39 @@ func Close() error { } return db.Close() } + +func Backup(ctx context.Context, target string) error { + live, err := Instance.DB() + if err != nil { + return err + } + + conn, err := live.Conn(ctx) + if err != nil { + return err + } + defer conn.Close() + + return conn.Raw(func(driverConn any) error { + type backuper interface { + NewBackup(string) (*sqlite3.Backup, error) + NewRestore(string) (*sqlite3.Backup, error) + } + + conn, ok := driverConn.(backuper) + if !ok { + return errors.New("invalid db type") + } + + bck, err := conn.NewBackup(target) + if err != nil { + return err + } + + if _, err := bck.Step(-1); err != nil { + return err + } + + return bck.Finish() + }) +}