docs: GORM vs sqlc data-layer decision report#48
Conversation
Adds a decision-grade comparison of GORM and sqlc for the planned Go + SQLite rewrite, covering philosophy, SQLite support, type safety, performance, migrations, testing, codegen pipeline, community health, workload fit, and alternatives (sqlx/ent/bun/jet). Recommends sqlc as the primary data layer with an external migration tool and a hand-written SQL escape hatch for dynamic queries, since the queue/event-stream core benefits from explicit, compile-time-checked SQL while SQLite's single-writer model dominates regardless of ORM. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Greptile SummaryAdds
Confidence Score: 5/5Documentation-only addition with no code changes; safe to merge. This PR adds a single markdown decision document. All load-bearing technical claims in the document were verified as accurate: sqlc's migration-by-design behavior, GORM's zero-value update and soft-delete footguns, SQLite single-writer serialization, and the BEGIN IMMEDIATE / SQLITE_BUSY_SNAPSHOT relationship. No code is modified, so there is no runtime risk. No files require special attention; the only finding is a minor wording ambiguity in the glebarez/sqlite maintenance status description. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Schema Changes / New Query] --> B{Use sqlc?}
B -- Yes: static hot paths --> C[Write/update query.sql]
C --> D[sqlc generate]
D --> E{Parser OK?}
E -- No: exotic DDL / FTS5 --> F[Keep in migration-only files\nhand-write accessor]
E -- Yes --> G[Compiler validates\nall call sites]
G --> H[Run golang-migrate/goose\nat deploy]
B -- No: dynamic filter query --> I[Write sqlx / raw database/sql\nhand-crafted SQL]
I --> J[Share single WAL-mode *sql.DB\nSetMaxOpenConns 1 on write pool]
H --> J
F --> J
J --> K{Write transaction?}
K -- Yes --> L[BEGIN IMMEDIATE\navoids SQLITE_BUSY_SNAPSHOT]
K -- No --> M[Read pool mode=ro\nmulti-conn OK]
Reviews (2): Last reviewed commit: "docs: expand ORM report with fact-checke..." | Re-trigger Greptile |
Replace the report with the deeper, fact-checked version (75 sources, adversarial verification pass) and correct the inline 'ent.io' domain to 'entgo.io' per review feedback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Adds
docs/orm-decision.md, a decision-grade comparison of GORM vs sqlc for the planned Go + SQLite rewrite of the agent-orchestrator.Covers all requested dimensions:
Recommendation (TL;DR)
Use sqlc as the primary data layer — compile-time-checked, explicit, low-overhead SQL suits a job-queue/event-stream core with a stable schema. Pair with goose/golang-migrate/atlas for migrations (sqlc does none) and a thin sqlx/
database/sqlescape hatch for dynamic filter queries. Choose GORM only if velocity + pervasive dynamic queries outweigh compile-time safety. Regardless of ORM, the decisive lever is SQLite tuning: WAL + busy_timeout + single writer connection.How it was produced
Fan-out web research across the comparison dimensions, then an adversarial fact-check pass on the four load-bearing claims (sqlc migrations, GORM footguns, sqlc SQLite/dynamic-SQL limits, SQLite single-writer) — all confirmed — followed by synthesis.
🤖 Generated with Claude Code