From 91edf0f995d01a32e3a287bb17f374252420ebf8 Mon Sep 17 00:00:00 2001 From: Cornelius Denninger Date: Wed, 29 Jan 2025 15:14:57 +0100 Subject: [PATCH] Allow migration of adding or dropping unique columns (#44) --- bun.lockb | Bin 78527 -> 78448 bytes package.json | 2 +- src/utils/field.ts | 30 +++++++++++++++++++++----- src/utils/queries.ts | 9 +++++++- tests/fixtures/index.ts | 7 ++++++ tests/utils/apply.test.ts | 44 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 7 deletions(-) diff --git a/bun.lockb b/bun.lockb index beb7558a7a0a2d964f5b591180ba935d8e67fa68..99b364c1286e87a53b58ec9819956c75d3f6667b 100755 GIT binary patch delta 9393 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 Vlk44zy~(0Dd*WNTtQGUu{0lgHJmdfX delta 9231 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 diff --git a/package.json b/package.json index 28057ab..b0995bd 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "resolve-from": "5.0.0" }, "devDependencies": { - "ronin": "6.0.25", + "ronin": "6.0.27", "@biomejs/biome": "1.9.4", "@types/bun": "1.2.1", "@types/ini": "4.1.1", diff --git a/src/utils/field.ts b/src/utils/field.ts index f7c3a4f..21104f1 100644 --- a/src/utils/field.ts +++ b/src/utils/field.ts @@ -73,8 +73,8 @@ export const diffFields = async ( } } - diff.push(...createFields(fieldsToAdd, modelSlug)); - diff.push(...deleteFields(fieldsToDelete, modelSlug)); + diff.push(...createFields(fieldsToAdd, modelSlug, definedFields)); + diff.push(...deleteFields(fieldsToDelete, modelSlug, definedFields)); for (const field of queriesForAdjustment || []) { // SQLite's ALTER TABLE is limited - adding UNIQUE or NOT NULL to an existing column @@ -212,10 +212,24 @@ export const fieldsToCreate = ( export const createFields = ( fields: Array, modelSlug: string, + definedFields?: Array, ): Array => { const diff: Array = []; for (const fieldToAdd of fields) { + if (fieldToAdd.unique) { + const existingFields = definedFields?.filter( + (f) => !fields.find((f2) => f2.slug === f.slug), + ); + return createTempModelQuery( + modelSlug, + definedFields || [], + [], + [], + [], + existingFields, + ); + } diff.push(createFieldQuery(modelSlug, fieldToAdd)); } @@ -247,10 +261,16 @@ export const fieldsToDrop = ( * * @returns An array of SQL queries for deleting fields. */ -const deleteFields = (fields: Array, modelSlug: string): Array => { +const deleteFields = ( + fieldsToDrop: Array, + modelSlug: string, + fields: Array, +): Array => { const diff: Array = []; - - for (const fieldToDrop of fields) { + for (const fieldToDrop of fieldsToDrop) { + if (fieldToDrop.unique) { + return createTempModelQuery(modelSlug, fields, [], [], [], fields); + } diff.push(dropFieldQuery(modelSlug, fieldToDrop.slug)); } diff --git a/src/utils/queries.ts b/src/utils/queries.ts index e6cc011..fdad6e4 100644 --- a/src/utils/queries.ts +++ b/src/utils/queries.ts @@ -131,6 +131,7 @@ export const createTempModelQuery = ( _indexes: Array, triggers: Array, customQueries?: Array, + includeFields?: Array, ): Array => { const queries: Array = []; @@ -140,7 +141,13 @@ export const createTempModelQuery = ( queries.push(createModelQuery(tempModelSlug, { fields })); // Move all the data to the copied model - queries.push(`add.${tempModelSlug}.with(() => get.${modelSlug}())`); + queries.push( + `add.${tempModelSlug}.with(() => get.${modelSlug}(${ + includeFields + ? JSON.stringify({ selecting: includeFields.map((field) => field.slug) }) + : '' + }))`, + ); if (customQueries) { queries.push(...customQueries); diff --git a/tests/fixtures/index.ts b/tests/fixtures/index.ts index 8ed0cd8..8407ee4 100644 --- a/tests/fixtures/index.ts +++ b/tests/fixtures/index.ts @@ -282,3 +282,10 @@ export const TestM = model({ name: string(), }, }) as unknown as Model; + +export const TestN = model({ + slug: 'test', + fields: { + name: string(), + }, +}) as unknown as Model; diff --git a/tests/utils/apply.test.ts b/tests/utils/apply.test.ts index fb88177..3b2a5b1 100644 --- a/tests/utils/apply.test.ts +++ b/tests/utils/apply.test.ts @@ -15,6 +15,7 @@ import { TestK, TestL, TestM, + TestN, } from '@/fixtures/index'; import { describe, expect, test } from 'bun:test'; @@ -457,4 +458,47 @@ describe('apply', () => { // @ts-expect-error This is defined! expect(newModels[0]?.fields[1]?.type).toBe('json'); }); + + test('adding a unique field', async () => { + const definedModels: Array = [TestG]; + const existingModels: Array = [TestN]; + + const db = await queryEphemeralDatabase(existingModels); + const packages = await getLocalPackages(); + const models = await getModels(packages, db); + + const modelDiff = await diffModels(definedModels, models); + + const protocol = new Protocol(packages, modelDiff); + await protocol.convertToQueryObjects(); + + const statements = protocol.getSQLStatements(models); + await db.query(statements); + + const newModels = await getModels(packages, db); + expect(newModels).toHaveLength(1); + // @ts-expect-error This is defined! + expect(newModels[0]?.fields[0]?.unique).toBe(true); + }); + + test('removing a unique field', async () => { + const definedModels: Array = [TestN]; + const existingModels: Array = [TestG]; + + const db = await queryEphemeralDatabase(existingModels); + const packages = await getLocalPackages(); + const models = await getModels(packages, db); + + const modelDiff = await diffModels(definedModels, models); + const protocol = new Protocol(packages, modelDiff); + await protocol.convertToQueryObjects(); + + const statements = protocol.getSQLStatements(models); + await db.query(statements); + + const newModels = await getModels(packages, db); + expect(newModels).toHaveLength(1); + // @ts-expect-error This is defined! + expect(newModels[0]?.fields[0]?.type).toBe('string'); + }); });