50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
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
|
|
}
|