mirror of
https://github.com/go-admin-team/go-admin.git
synced 2026-10-14 01:08:36 +00:00
fix🐛: only treat exact in-memory forms as in-memory sqlite sources
A file whose name merely contained :memory: or mode=memory was classified as an in-memory database and skipped the locking defaults. Parse the query and match the exact filename forms or a mode=memory parameter.
This commit is contained in:
@@ -30,10 +30,9 @@ var sqlitePragmas = [][2]string{
|
||||
}
|
||||
|
||||
// sqliteDSN returns source with the defaults in sqlitePragmas added.
|
||||
// In-memory databases are returned untouched: WAL has no meaning there, and
|
||||
// every connection to one is its own database anyway.
|
||||
// In-memory databases are returned untouched: WAL has no meaning there.
|
||||
func sqliteDSN(source string) string {
|
||||
if source == "" || strings.Contains(source, ":memory:") || strings.Contains(source, "mode=memory") {
|
||||
if source == "" {
|
||||
return source
|
||||
}
|
||||
|
||||
@@ -46,6 +45,9 @@ func sqliteDSN(source string) string {
|
||||
// Not something to rewrite blind; the driver will report it.
|
||||
return source
|
||||
}
|
||||
if isMemoryDB(path, q) {
|
||||
return source
|
||||
}
|
||||
for _, p := range sqlitePragmas {
|
||||
if _, set := q[p[0]]; !set {
|
||||
q.Set(p[0], p[1])
|
||||
@@ -54,6 +56,17 @@ func sqliteDSN(source string) string {
|
||||
return path + "?" + q.Encode()
|
||||
}
|
||||
|
||||
// isMemoryDB reports whether the source names an in-memory database: the exact
|
||||
// filename forms sqlite recognises, or a mode=memory parameter. A file that
|
||||
// merely has ":memory:" or "mode=memory" somewhere in its name is a file.
|
||||
func isMemoryDB(path string, q url.Values) bool {
|
||||
switch path {
|
||||
case ":memory:", "file::memory:", "file:":
|
||||
return true
|
||||
}
|
||||
return q.Get("mode") == "memory"
|
||||
}
|
||||
|
||||
// withSqliteDefaults wraps open so every connection string handed to a sqlite3
|
||||
// dialector - the primary and any replicas - carries the defaults above.
|
||||
func withSqliteDefaults(driver string, open func(string) gorm.Dialector) func(string) gorm.Dialector {
|
||||
|
||||
@@ -36,6 +36,14 @@ func TestSqliteDSN(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("files that only look like memory databases get the defaults", func(t *testing.T) {
|
||||
for _, s := range []string{"mode=memory.db", "/tmp/:memory:.db", "data/mode=memory/app.db"} {
|
||||
if got := sqliteDSN(s); got == s {
|
||||
t.Errorf("sqliteDSN(%q) was left untouched", s)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("in-memory and empty untouched", func(t *testing.T) {
|
||||
for _, s := range []string{"", ":memory:", "file::memory:?cache=shared", "file:x?mode=memory"} {
|
||||
if got := sqliteDSN(s); got != s {
|
||||
|
||||
Reference in New Issue
Block a user