db: fix 3->4 migration of empty DB

This commit is contained in:
Evan Goode 2024-12-23 21:57:35 -05:00
parent 4a48ef6ed3
commit d8ec0bc56a
3 changed files with 30 additions and 2 deletions

6
db.go
View File

@ -335,8 +335,10 @@ func Migrate(config *Config, dbPath mo.Option[string], db *gorm.DB, alreadyExist
user.Players = append(user.Players, player)
users = append(users, user)
}
if err := tx.Session(&gorm.Session{FullSaveAssociations: true}).Save(&users).Error; err != nil {
return err
if len(users) > 0 {
if err := tx.Session(&gorm.Session{FullSaveAssociations: true}).Save(&users).Error; err != nil {
return err
}
}
userVersion += 1
}

View File

@ -42,6 +42,7 @@ func TestDB(t *testing.T) {
t.Run("Test 2->3 migration", ts.testMigrate2To3)
t.Run("Test 3->4 migration", ts.testMigrate3To4)
t.Run("Test 3->4 migration, username/player name collision", ts.testMigrate3To4Collision)
t.Run("Test 3->4 migration, empty database", ts.testMigrate3To4Empty)
t.Run("Test backwards migration", ts.testMigrateBackwards)
}
@ -145,6 +146,21 @@ func (ts *TestSuite) testMigrate3To4Collision(t *testing.T) {
assert.Equal(t, "qux", v4qux.Players[0].Name)
}
func (ts *TestSuite) testMigrate3To4Empty(t *testing.T) {
db := ts.getFreshDatabase(t)
query, err := os.ReadFile("sql/3-empty.sql")
assert.Nil(t, err)
assert.Nil(t, db.Exec(string(query)).Error)
var users []User
assert.Nil(t, db.Find(&users).Error)
assert.Equal(t, 0, len(users))
err = Migrate(ts.Config, mo.None[string](), db, true, 4)
assert.Nil(t, err)
}
func (ts *TestSuite) testMigrateBackwards(t *testing.T) {
db := ts.getFreshDatabase(t)

10
sql/3-empty.sql Normal file
View File

@ -0,0 +1,10 @@
PRAGMA user_version=3;
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `users` (`is_admin` numeric,`is_locked` numeric,`uuid` text,`username` text NOT NULL UNIQUE,`password_salt` blob NOT NULL,`password_hash` blob NOT NULL,`server_id` text,`player_name` text collate nocase NOT NULL UNIQUE,`offline_uuid` text NOT NULL,`fallback_player` text,`preferred_language` text,`browser_token` text,`api_token` text,`skin_hash` text,`skin_model` text,`cape_hash` text,`created_at` datetime,`name_last_changed_at` datetime,PRIMARY KEY (`uuid`));
CREATE TABLE `clients` (`uuid` text,`client_token` text,`version` integer,`user_uuid` text,PRIMARY KEY (`uuid`),CONSTRAINT `fk_users_clients` FOREIGN KEY (`user_uuid`) REFERENCES `users`(`uuid`));
CREATE TABLE `invites` (`code` text,`created_at` datetime,PRIMARY KEY (`code`));
CREATE INDEX `idx_users_cape_hash` ON `users`(`cape_hash`);
CREATE INDEX `idx_users_skin_hash` ON `users`(`skin_hash`);
CREATE INDEX `idx_users_browser_token` ON `users`(`browser_token`);
COMMIT;