Files
zeekayandClaude Opus 4.8 102b0a4495 fix(sqlite): one driver — route all SQLite onto hanzoai/sqlite, drop modernc
Base double-registered the database/sql "sqlite" driver when embedded in a CGO
consumer that needs SQLCipher (commerce's per-tenant money DBs): hanzoai/sqlite
registers "sqlite"→mattn under cgo while base's own `_ "modernc.org/sqlite"`
blank imports register "sqlite"→modernc → `panic: sql: Register called twice for
driver sqlite` at init. Fix: base imports ONLY github.com/hanzoai/sqlite (the
canonical dual-backend driver) and never modernc directly. `go mod why
modernc.org/sqlite` now resolves ONLY transitively via hanzoai/sqlite.

- core/db_connect.go + store/multitenant.go: open via
  sqlite.PragmaDSN(path, sqlite.DefaultPragmas) — the ONE pragma set encoded in
  the ACTIVE backend's DSN syntax, so busy_timeout+WAL actually apply under both
  modernc (!cgo) and mattn (cgo). Kills the duplicated modernc-only DSN string.
- core/base_network.go: resolve the raw driver conn via
  sqlite.CommitHookRegisterer (build-tagged; bridges mattn func() int / modernc
  func() int32 to one CommitHookFn). network/* stays backend-agnostic — its own
  HookRegisterer + test fakes are unchanged.
- hack/pitr-restore.go, network/pitr_test.go, tools/search/provider_test.go:
  blank-import hanzoai/sqlite instead of modernc.
- Removed modernc_versions_check.go + its OnBootstrap binding: the modernc/libc
  pairing is hanzoai/sqlite's concern now, not base's (base no longer pins it).
- go.mod: require hanzoai/sqlite v0.2.1; modernc now // indirect; replace
  mattn/go-sqlite3 => v1.14.47 defeats the v2.0.3+incompatible poison (beego)
  under cgo. Encrypted-at-rest (SQLCipher via mattn under cgo) is untouched.

Verified: CGO=0 binary builds; ./core/... ./network/... ./store/...
./tools/search/... tests GREEN; CGO=1 (commerce mode, -tags cloud) compiles;
zero direct modernc imports remain.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 21:13:48 -07:00
..