Files
sqlite/filecontrol_nocgo.go
zeekay eea9c2f72b feat: SetPersistWAL + OpenPragma — let replicate drop direct modernc
Two backend-neutral primitives so hanzoai/replicate can route through
hanzoai/sqlite and stop blank-importing modernc.org/sqlite — which under
CGO=1 registers 'sqlite' a SECOND time (mattn already registered it),
the live 'sql: Register called twice for driver sqlite' panic in
base/store/replicator (base -> commerce -> cloud all embed replicate, so
this would panic the cgo cloud binary at startup).

- SetPersistWAL(rawConn, on): SQLITE_FCNTL_PERSIST_WAL via mattn
  SetFileControlInt (cgo) / modernc FileControl.FileControlPersistWAL
  (nocgo). Keeps -wal across close (WAL-shipping needs it). Proven: -wal
  survives db.Close() on both backends.
- OpenPragma(dsn, pragmas): a database/sql Connector applying pragmas to
  EVERY pooled connection at connect. wal_autocheckpoint is the reason:
  mattn drops it from the DSN, so a naive port would re-enable
  auto-checkpoint and truncate the WAL under a replicator (data loss).
  Per-connection ExecContext is backend-neutral. Proven on 3 concurrent
  conns under both backends (busy_timeout/journal_mode/wal_autocheckpoint/
  foreign_keys all applied per-conn). Tag-neutral driver resolution.

All three tag combos green (modernc, mattn, mattn+sqlite_purego); vet clean.
LLM.md -> v0.2.3.
2026-07-08 15:16:20 -07:00

35 lines
1.1 KiB
Go

//go:build !cgo || sqlite_purego
package sqlite
import (
"fmt"
mod "modernc.org/sqlite"
)
// SetPersistWAL sets SQLite's SQLITE_FCNTL_PERSIST_WAL file control on rawConn —
// the raw driver connection handed to the callback of (*sql.Conn).Raw. When on,
// the -wal file is kept across the last connection close (SQLite otherwise
// deletes it), which WAL-shipping replication (hanzoai/replicate) requires so a
// crash mid-sync doesn't lose committed frames.
//
// It is the one backend-neutral way to set PERSIST_WAL; consumers never touch
// the mattn/modernc conn type directly. Returns an error if rawConn is not this
// build's SQLite connection type.
//
// Pure-Go backend: modernc.org/sqlite's *conn satisfies its exported FileControl
// interface; mode 1 enables, 0 disables (-1 would query).
func SetPersistWAL(rawConn any, on bool) error {
fc, ok := rawConn.(mod.FileControl)
if !ok {
return fmt.Errorf("sqlite: SetPersistWAL: driver conn is %T, want modernc.FileControl", rawConn)
}
mode := 0
if on {
mode = 1
}
_, err := fc.FileControlPersistWAL("main", mode)
return err
}