improvement: minizime kms key slug -> name transition impact

This commit is contained in:
Scott Wilson
2024-10-05 10:43:57 -07:00
parent f8358a0807
commit 1cc22a6195
3 changed files with 75 additions and 1 deletions

View File

@@ -0,0 +1,38 @@
import { Knex } from "knex";
import {
createKmsKeyNameSyncTrigger,
dropKmsKeyNameSyncTrigger
} from "@app/db/migrations/utils/kmsKeySlugNameTransition";
import { TableName } from "@app/db/schemas";
export async function up(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.KmsKey)) {
const hasSlug = await knex.schema.hasColumn(TableName.KmsKey, "slug");
if (!hasSlug) {
// add slug back temporarily and set value equal to name
await knex.schema
.alterTable(TableName.KmsKey, (table) => {
table.string("slug", 32);
})
.then(() => knex(TableName.KmsKey).update("slug", knex.ref("name")));
await createKmsKeyNameSyncTrigger(knex);
}
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.KmsKey)) {
const hasSlug = await knex.schema.hasColumn(TableName.KmsKey, "slug");
if (hasSlug) {
await dropKmsKeyNameSyncTrigger(knex);
await knex.schema.alterTable(TableName.KmsKey, (table) => {
table.dropColumn("slug");
});
}
}
}

View File

@@ -0,0 +1,35 @@
import { Knex } from "knex";
import { TableName } from "@app/db/schemas";
// These utils are meant to mitigate any delays between postgres update and application deployement for the KMS feature
// where slug col was migrated to name col
// this is a postgres function to keep name in-sync with slug during transition period
export const createKmsKeyNameSyncTrigger = async (knex: Knex) => {
// create function
await knex.raw(`
CREATE OR REPLACE FUNCTION on_sync_kms_key_name() RETURNS TRIGGER AS $$ BEGIN NEW."name" = NEW."slug";
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
`);
// create trigger
await knex.raw(`
CREATE TRIGGER "${TableName.KmsKey}_name_sync"
BEFORE INSERT OR UPDATE OF "slug" ON ${TableName.KmsKey}
FOR EACH ROW
EXECUTE PROCEDURE on_sync_kms_key_name();
`);
};
export const dropKmsKeyNameSyncTrigger = async (knex: Knex) => {
// drop trigger
await knex.raw(`DROP TRIGGER IF EXISTS "${TableName.KmsKey}_name_sync" ON ${TableName.KmsKey}`);
// drop function
await knex.raw(`
DROP FUNCTION IF EXISTS on_sync_kms_key_name() CASCADE;
`);
};

View File

@@ -16,7 +16,8 @@ export const KmsKeysSchema = z.object({
name: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
projectId: z.string().nullable().optional()
projectId: z.string().nullable().optional(),
slug: z.string().nullable().optional()
});
export type TKmsKeys = z.infer<typeof KmsKeysSchema>;