feat: move schema_migrations into 000_bootstrap.sql (#95)
All checks were successful
check / check (push) Successful in 5s

## Summary

- Moves schema_migrations table creation from inline Go code into internal/db/schema/000_bootstrap.sql
- Bootstrap SQL is executed directly before the migration loop (which starts from 001+)
- Go code does zero INSERTs for the bootstrap — 000_bootstrap.sql handles the INSERT OR IGNORE for version 0
- loadMigrations() skips 000.sql so it is not processed by the normal migration loop

Follows the sneak/pixa pattern.

closes #91

## Test plan

- [x] All existing tests pass (make test in Docker)
- [x] Linter passes (make lint)
- [x] Docker build succeeds (docker build --no-cache .)
- [x] Existing databases with schema_migrations table work (CREATE TABLE IF NOT EXISTS + INSERT OR IGNORE are idempotent)

Generated with Claude Code

Co-authored-by: user <user@Mac.lan guest wan>
Reviewed-on: sneak/chat#95
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
Co-committed-by: clawbot <sneak+clawbot@sneak.cloud>
This commit was merged in pull request #95.
This commit is contained in:
2026-03-30 21:35:53 +02:00
committed by Jeffrey Paul
parent 9a79d92c0d
commit 24362966e0
2 changed files with 24 additions and 5 deletions

View File

@@ -135,13 +135,21 @@ type migration struct {
func (database *Database) runMigrations( func (database *Database) runMigrations(
ctx context.Context, ctx context.Context,
) error { ) error {
_, err := database.conn.ExecContext(ctx, bootstrap, err := SchemaFiles.ReadFile(
`CREATE TABLE IF NOT EXISTS schema_migrations ( "schema/000.sql",
version INTEGER PRIMARY KEY, )
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP)`)
if err != nil { if err != nil {
return fmt.Errorf( return fmt.Errorf(
"create schema_migrations: %w", err, "read bootstrap migration: %w", err,
)
}
_, err = database.conn.ExecContext(
ctx, string(bootstrap),
)
if err != nil {
return fmt.Errorf(
"execute bootstrap migration: %w", err,
) )
} }
@@ -270,6 +278,11 @@ func (database *Database) loadMigrations() (
continue continue
} }
// Skip bootstrap migration; it is executed separately.
if version == 0 {
continue
}
content, readErr := SchemaFiles.ReadFile( content, readErr := SchemaFiles.ReadFile(
"schema/" + entry.Name(), "schema/" + entry.Name(),
) )

View File

@@ -0,0 +1,6 @@
-- Bootstrap: create the schema_migrations table itself.
CREATE TABLE IF NOT EXISTS schema_migrations (
version INTEGER PRIMARY KEY,
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
INSERT OR IGNORE INTO schema_migrations (version) VALUES (0);