Migrate store to SQLite (modernc, cgo-free) + boot import of legacy JSON (#28) #30
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/sqlite-store"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements #28. Not auto-merged — this swaps the live server's storage engine, so it wants your review + a deliberate deploy.
What changed
Only
main.go(plusgo.mod/go.sumand a new test). The in-memory maps stay the authoritative read/write model, so every other file'sst.Recs[...]/st.save()call site is unchanged — the migration is confined toopenStore()andsave().modernc.org/sqlitev1.57.0 — pure Go.CGO_ENABLED=0 go build ./...verified green in CI, so the existing cross-compile/deploy is unaffected.licenses/accounts/orgs/invites. Primary key + a couple of extracted lookup columns (paddle_sub, email, org_id, revoked on licenses) for future SQL/reporting; the full struct lives JSON-encoded in adatacolumn, so Go struct changes never need a column migration.save(): whole in-memory state written in one transaction (WAL). A crash or failed statement rolls back — the old whole-file JSON write had no such guarantee. Kept void/best-effort to match the previous contract; failures now log via an optional store logger.licenses.jsonexists, it's imported once, then renamedlicenses.json.migrated. Idempotent — a second boot reads from the DB and skips it.DATA_PATHmay still point at the old.json; the.dbis derived beside it, so the systemd env needs no change. Default is nowlicenses.db.Sessions / reset / OAuth state
Unchanged — still in-memory (a restart re-prompts login by design).
Retention
Unchanged — records kept forever (load-bearing for late-renewal same-id re-sync).
Verification (CI, this branch)
CGO_ENABLED=0 go build ./...— clean.go vet ./...— clean.store_sqlite_test.go:TestSQLiteImportsLegacyJSON(import once, rename aside, no re-import on reopen) andTestSQLiteRoundTrip(persist → reopen → extracted-column check → delete propagates through the full-rewrite save). Both PASS.Deploy notes (when you choose to)
licenses.jsonoff the box first — belt-and-braces; the import only renames it, but take the snapshot anyway..migrated. First-boot logs will show issuance/paddle warnings as usual; checkhealthz.mv licenses.json.migrated licenses.json, redeploy the previous binary. The DB file can be left or removed.