From 0d3591702345aefe9751bb50c00fb0230c60c48a Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Mon, 23 Dec 2024 21:57:35 -0500 Subject: [PATCH] db: fix 3->4 migration of empty DB --- db.go | 6 ++++-- db_test.go | 16 ++++++++++++++++ sql/3-empty.sql | 10 ++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 sql/3-empty.sql diff --git a/db.go b/db.go index 4529f07..5e6df3a 100644 --- a/db.go +++ b/db.go @@ -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 } diff --git a/db_test.go b/db_test.go index 560c7d6..0a9c685 100644 --- a/db_test.go +++ b/db_test.go @@ -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) diff --git a/sql/3-empty.sql b/sql/3-empty.sql new file mode 100644 index 0000000..f7fd8d2 --- /dev/null +++ b/sql/3-empty.sql @@ -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;