Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/storage/dolt/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package dolt
// currentSchemaVersion is bumped whenever the schema or migrations change.
// initSchemaOnDB checks this against the stored version and skips re-initialization
// when they match, avoiding ~20 DDL statements per bd invocation.
const currentSchemaVersion = 7
const currentSchemaVersion = 8

// schema defines the MySQL-compatible database schema for Dolt.
const schema = `
Expand Down
56 changes: 56 additions & 0 deletions internal/storage/dolt/schema_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ func TestSchemaVersionSetAfterInit(t *testing.T) {
if version != currentSchemaVersion {
t.Errorf("schema_version = %d, want %d", version, currentSchemaVersion)
}

var stagedRows int
err = store.db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_status WHERE table_name = 'config'").Scan(&stagedRows)
if err != nil {
t.Fatalf("query dolt_status for config: %v", err)
}
if stagedRows != 0 {
t.Fatalf("config left staged in dolt_status after init: %d row(s)", stagedRows)
}
}

// TestSchemaVersionSkipsReinit verifies that initSchemaOnDB returns early
Expand Down Expand Up @@ -105,6 +114,53 @@ func TestSchemaVersionRunsInitWhenStale(t *testing.T) {
}
}

// TestSchemaVersionRunsLatestMigrationsWhenOneVersionBehind verifies that a
// database marked one schema version behind re-enters initSchemaOnDB and picks
// up the latest migration-backed columns.
func TestSchemaVersionRunsLatestMigrationsWhenOneVersionBehind(t *testing.T) {
store, cleanup := setupTestStore(t)
defer cleanup()

ctx, cancel := testContext(t)
defer cancel()

for _, stmt := range []string{
"ALTER TABLE issues DROP COLUMN no_history",
"ALTER TABLE wisps DROP COLUMN no_history",
} {
if _, err := store.db.ExecContext(ctx, stmt); err != nil {
t.Fatalf("exec %q: %v", stmt, err)
}
}

_, err := store.db.ExecContext(ctx,
"UPDATE config SET `value` = ? WHERE `key` = 'schema_version'",
currentSchemaVersion-1,
)
if err != nil {
t.Fatalf("failed to set prior schema_version: %v", err)
}

if err := initSchemaOnDB(ctx, store.db); err != nil {
t.Fatalf("initSchemaOnDB failed: %v", err)
}

for _, table := range []string{"issues", "wisps"} {
var count int
err := store.db.QueryRowContext(
ctx,
"SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = ? AND column_name = 'no_history'",
table,
).Scan(&count)
if err != nil {
t.Fatalf("check %s.no_history: %v", table, err)
}
if count != 1 {
t.Fatalf("%s.no_history missing after initSchemaOnDB", table)
}
}
}

// TestSchemaVersionRunsInitWhenMissing verifies that initSchemaOnDB runs
// full initialization when the schema_version key doesn't exist (fresh db
// or pre-versioning upgrade).
Expand Down
6 changes: 6 additions & 0 deletions internal/storage/dolt/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,12 @@ func initSchemaOnDB(ctx context.Context, db *sql.DB) error {
"INSERT INTO config (`key`, `value`) VALUES ('schema_version', ?) "+
"ON DUPLICATE KEY UPDATE `value` = ?",
currentSchemaVersion, currentSchemaVersion)
_, _ = db.ExecContext(ctx, "CALL DOLT_ADD('config')")
if _, err := db.ExecContext(ctx, "CALL DOLT_COMMIT('-m', 'schema: update schema_version')"); err != nil {
if !strings.Contains(strings.ToLower(err.Error()), "nothing to commit") {
return fmt.Errorf("failed to commit schema_version update: %w", err)
}
}

return nil
}
Expand Down
Loading