Files
grafana/pkg/services/sqlstore/migrator/migrations_test.go
Peter Štibraný 8a160a8ca1 Convert unique keys in 3 tables to primary keys (#115421)
* Added method for adding migrations for convering unique to primary key.

Based on existing migration for `file` table (in `db_file_storage.go`) migrations.

* Added better default migration names. Added ability to override migration name.

* Use ConvertUniqueKeyToPrimaryKey for cloud_migration_snapshot_partition table.

* Convert resource_version UQE to PK.

* Convert secret_encrypted_value UQE to PK.

* Removed extra test.

* Removed testdata.

* Remove support for renaming migrations for now. We can bring it in later, when we want to convert existing migrations for file, file_meta and setting tables.

* Revert removal of ColumnName to ease backporting, since this field is referenced from enterprise code.

* Use quoted identifiers in Postgres statement.
2025-12-17 15:37:49 +01:00

80 lines
2.8 KiB
Go

package migrator
import (
_ "embed"
"testing"
"github.com/stretchr/testify/require"
)
//go:embed testdata/sqlite_file_migration_statement.sql
var sqliteMigrationStatement string
func TestConvertUniqueKeyToPrimaryKey(t *testing.T) {
names := []string{
"drop my_row_id and add primary key with columns path_hash,etag to table file if my_row_id exists (auto-generated mysql column)",
"drop unique index UQE_file_path_hash_etag from file table if it exists (mysql)",
"add primary key with columns path_hash,etag to table file if it doesn't exist (mysql)",
"add primary key with columns path_hash,etag to table file (postgres and sqlite)",
}
expectedMigrations := map[string][]ExpectedMigration{
MySQL: {
{Id: names[0], SQL: `
ALTER TABLE file
DROP PRIMARY KEY,
DROP COLUMN my_row_id,
DROP INDEX UQE_file_path_hash_etag,
ADD PRIMARY KEY (` + "`path_hash`" + `,` + "`etag`" + `);`},
{Id: names[1], SQL: "ALTER TABLE file DROP INDEX UQE_file_path_hash_etag"},
{Id: names[2], SQL: "ALTER TABLE file ADD PRIMARY KEY (`path_hash`,`etag`)"},
{Id: names[3], SQL: ""},
},
Postgres: {
{Id: names[0], SQL: ""},
{Id: names[1], SQL: ""},
{Id: names[2], SQL: ""},
{Id: names[3], SQL: `
DO $$
BEGIN
-- Drop the unique constraint if it exists
DROP INDEX IF EXISTS "UQE_file_path_hash_etag";
-- Add primary key if it doesn't already exist
IF NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = 'file'::regclass AND indisprimary) THEN
ALTER TABLE "file" ADD PRIMARY KEY ("path_hash","etag");
END IF;
END $$;`},
},
SQLite: {
{Id: names[0], SQL: ""},
{Id: names[1], SQL: ""},
{Id: names[2], SQL: ""},
{Id: names[3], SQL: sqliteMigrationStatement}, // Embed used here because sqlite statement is full of backquotes.
},
}
for dialectName, migrations := range expectedMigrations {
t.Run(dialectName, func(t *testing.T) {
err := CheckExpectedMigrations(dialectName, migrations, func(migrator *Migrator) {
ConvertUniqueKeyToPrimaryKey(migrator,
Index{Cols: []string{"path_hash", "etag"}, Type: UniqueIndex}, // Convert this unique key to primary key
Table{
Name: "file",
Columns: []*Column{
{Name: "path", Type: DB_NVarchar, Length: 1024, Nullable: false},
{Name: "path_hash", Type: DB_NVarchar, Length: 64, Nullable: false, IsPrimaryKey: true},
{Name: "parent_folder_path_hash", Type: DB_NVarchar, Length: 64, Nullable: false},
{Name: "contents", Type: DB_Blob, Nullable: false},
{Name: "etag", Type: DB_NVarchar, Length: 32, Nullable: false, IsPrimaryKey: true},
},
PrimaryKeys: []string{"path_hash", "etag"},
Indices: []*Index{
{Cols: []string{"parent_folder_path_hash"}},
},
})
})
require.NoError(t, err)
})
}
}