fix(platform): normalize native paths for storage and backup validation
This commit is contained in:
1 parent
bea53ce3c8
commit
1a8f70ca13
9 files changed
+120
-8
No files matched your search
@@ -5,6 +5,7 @@ import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"rawmark/internal/i18n"
|
||||
"strings"
|
||||
)
|
||||
@@ -83,7 +84,15 @@ func (s *Store) CheckBackup() error {
|
||||
|
||||
// OpenExisting opens only existing databases; import validation must not create tables or change journal modes.
|
||||
func OpenExisting(path string) (*Store, error) {
|
||||
db, err := sql.Open("sqlite", (&url.URL{Scheme: "file", Path: path, RawQuery: "mode=rw&_pragma=busy_timeout(5000)"}).String())
|
||||
absolute, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uriPath := filepath.ToSlash(absolute)
|
||||
if filepath.VolumeName(absolute) != "" && !strings.HasPrefix(uriPath, "/") {
|
||||
uriPath = "/" + uriPath
|
||||
}
|
||||
db, err := sql.Open("sqlite", (&url.URL{Scheme: "file", Path: uriPath, RawQuery: "mode=rw&_pragma=busy_timeout(5000)"}).String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOpenExistingUsesNativeEscapedPathWithoutCreating(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
path := filepath.Join(root, "数据库 # %.db")
|
||||
original, err := Open(filepath.Join(root, "source.db"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := original.SetSetting("portable", "retained"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := original.Snapshot(context.Background(), path); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := original.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
existing, err := OpenExisting(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
value, ok, err := existing.Setting("portable")
|
||||
if err != nil || !ok || value != "retained" {
|
||||
t.Fatalf("existing database path: %q, %v, %v", value, ok, err)
|
||||
}
|
||||
if err := existing.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
missingPath := filepath.Join(root, "missing.db")
|
||||
missing, err := OpenExisting(missingPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer missing.Close()
|
||||
if _, _, err := missing.Setting("portable"); err == nil {
|
||||
t.Fatal("missing database accepted")
|
||||
}
|
||||
if _, err := os.Stat(missingPath); !errors.Is(err, os.ErrNotExist) {
|
||||
t.Fatalf("missing database was created: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user