store: add users table and user_id scoping to migrations
Schema-only step toward per-user profile isolation: profile/workout_kinds/ sync_state are rebuilt to drop their singleton constraints, activities/ sync_runs gain a nullable user_id column. Store methods are scoped in later tasks.
This commit is contained in:
@@ -24,7 +24,10 @@ type DB struct {
|
||||
// Open opens (creating if needed) the SQLite database at path and applies
|
||||
// any migrations that haven't run yet.
|
||||
func Open(path string) (*DB, error) {
|
||||
sqlDB, err := sql.Open("sqlite", path+"?_pragma=foreign_keys(1)")
|
||||
// Don't enable foreign keys in connection string; instead, enable them
|
||||
// after migrations complete. This allows migrations to disable FK checks
|
||||
// as needed for table rebuilds.
|
||||
sqlDB, err := sql.Open("sqlite", path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open sqlite database: %w", err)
|
||||
}
|
||||
@@ -82,10 +85,23 @@ func (db *DB) migrate() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("begin migration tx for %s: %w", name, err)
|
||||
}
|
||||
// Disable foreign key enforcement for the migration so that table
|
||||
// rebuilds (e.g. dropping a table with dependent foreign keys) can
|
||||
// succeed. The migrations themselves use PRAGMA defer_foreign_keys
|
||||
// when possible; this is a fallback for modernc.org/sqlite's
|
||||
// limitations with that pragma in transactions.
|
||||
if _, err := tx.Exec(`PRAGMA foreign_keys = OFF`); err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("disable foreign keys for migration %s: %w", name, err)
|
||||
}
|
||||
if _, err := tx.Exec(string(content)); err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("apply migration %s: %w", name, err)
|
||||
}
|
||||
if _, err := tx.Exec(`PRAGMA foreign_keys = ON`); err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("enable foreign keys after migration %s: %w", name, err)
|
||||
}
|
||||
if _, err := tx.Exec(`INSERT INTO schema_migrations (filename) VALUES (?)`, name); err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("record migration %s: %w", name, err)
|
||||
@@ -94,5 +110,9 @@ func (db *DB) migrate() error {
|
||||
return fmt.Errorf("commit migration %s: %w", name, err)
|
||||
}
|
||||
}
|
||||
// Enable foreign key enforcement after all migrations are complete.
|
||||
if _, err := db.Exec(`PRAGMA foreign_keys = ON`); err != nil {
|
||||
return fmt.Errorf("enable foreign keys after migrations: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user