package store import ( "database/sql" "fmt" "os" "path/filepath" "strings" _ "modernc.org/sqlite" ) // OpenWriter 按 DEVELOPMENT 7.7 打开写连接(带 _txlock=immediate)。 func OpenWriter(dataDir, synchronous string) (*sql.DB, error) { if err := os.MkdirAll(dataDir, 0o755); err != nil { return nil, fmt.Errorf("mkdir data_dir: %w", err) } dsn, err := writeDSN(dataDir, synchronous) if err != nil { return nil, err } db, err := sql.Open("sqlite", dsn) if err != nil { return nil, fmt.Errorf("open sqlite: %w", err) } db.SetMaxOpenConns(1) db.SetMaxIdleConns(1) if err := db.Ping(); err != nil { _ = db.Close() return nil, fmt.Errorf("ping sqlite: %w", err) } return db, nil } func writeDSN(dataDir, synchronous string) (string, error) { sync := strings.ToUpper(strings.TrimSpace(synchronous)) if sync == "" { sync = "FULL" } if sync != "FULL" && sync != "NORMAL" { return "", fmt.Errorf("invalid sqlite_synchronous: %s", synchronous) } dbPath := filepath.ToSlash(filepath.Join(dataDir, "nixmsg.db")) return fmt.Sprintf( "file:%s?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)&_pragma=synchronous(%s)&_pragma=foreign_keys(ON)&_pragma=secure_delete(ON)&_txlock=immediate", dbPath, sync, ), nil }