From 561efa50acbab5335383f88f30c61ebe6aae4a34 Mon Sep 17 00:00:00 2001 From: 43081j <43081j@users.noreply.github.com> Date: Tue, 12 Mar 2024 21:53:38 +0000 Subject: [PATCH] test: add column-queries data loss tests --- .changeset/yellow-ducks-greet.md | 5 ++ packages/db/src/core/cli/migration-queries.ts | 3 +- packages/db/test/unit/column-queries.test.js | 71 +++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 .changeset/yellow-ducks-greet.md diff --git a/.changeset/yellow-ducks-greet.md b/.changeset/yellow-ducks-greet.md new file mode 100644 index 0000000000000..8d2e7e3959ac6 --- /dev/null +++ b/.changeset/yellow-ducks-greet.md @@ -0,0 +1,5 @@ +--- +"@astrojs/db": patch +--- + +Added github-slugger as a direct dependency of the db package diff --git a/packages/db/src/core/cli/migration-queries.ts b/packages/db/src/core/cli/migration-queries.ts index 0301d2e11945c..6e54ba93eea90 100644 --- a/packages/db/src/core/cli/migration-queries.ts +++ b/packages/db/src/core/cli/migration-queries.ts @@ -7,7 +7,6 @@ import { hasPrimaryKey } from '../../runtime/index.js'; import { getCreateIndexQueries, getCreateTableQuery, - getDropTableIfExistsQuery, getModifiers, getReferencesConfig, hasDefault, @@ -76,7 +75,7 @@ export async function getMigrationQueries({ const addedColumns = getAdded(oldCollection.columns, newCollection.columns); const droppedColumns = getDropped(oldCollection.columns, newCollection.columns); const notDeprecatedDroppedColumns = Object.fromEntries( - Object.entries(droppedColumns).filter(([key, col]) => !col.schema.deprecated) + Object.entries(droppedColumns).filter(([, col]) => !col.schema.deprecated) ); if (!isEmpty(addedColumns) && !isEmpty(notDeprecatedDroppedColumns)) { throw new Error( diff --git a/packages/db/test/unit/column-queries.test.js b/packages/db/test/unit/column-queries.test.js index d7f65dff27358..e2abcfb5c9da7 100644 --- a/packages/db/test/unit/column-queries.test.js +++ b/packages/db/test/unit/column-queries.test.js @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import * as color from 'kleur/colors'; import { getCollectionChangeQueries, getMigrationQueries, @@ -106,6 +107,76 @@ describe('column queries', () => { expect(queries).to.deep.equal([]); }); + it('should return warning if column type change introduces data loss', async () => { + const blogInitial = tableSchema.parse({ + ...userInitial, + columns: { + date: column.text(), + }, + }); + const blogFinal = tableSchema.parse({ + ...userInitial, + columns: { + date: column.date(), + }, + }); + const { queries, confirmations } = await userChangeQueries(blogInitial, blogFinal); + expect(queries).to.deep.equal([ + 'DROP TABLE "Users"', + 'CREATE TABLE "Users" (_id INTEGER PRIMARY KEY, "date" text NOT NULL)', + ]); + expect(confirmations).to.deep.equal([ + `Updating existing column ${color.bold( + `${TABLE_NAME}.date` + )} to a new type that cannot be handled automatically.`, + ]); + }); + + it('should return warning if new required column added', async () => { + const blogInitial = tableSchema.parse({ + ...userInitial, + columns: {}, + }); + const blogFinal = tableSchema.parse({ + ...userInitial, + columns: { + date: column.date({ optional: false }), + }, + }); + const { queries, confirmations } = await userChangeQueries(blogInitial, blogFinal); + expect(queries).to.deep.equal([ + 'DROP TABLE "Users"', + 'CREATE TABLE "Users" (_id INTEGER PRIMARY KEY, "date" text NOT NULL)', + ]); + expect(confirmations).to.deep.equal([ + `You added new required column '${color.bold( + `${TABLE_NAME}.date` + )}' with no default value.` + '\n This cannot be executed on an existing table.', + ]); + }); + + it('should return warning if non-number primary key with no default added', async () => { + const blogInitial = tableSchema.parse({ + ...userInitial, + columns: {}, + }); + const blogFinal = tableSchema.parse({ + ...userInitial, + columns: { + id: column.text({ primaryKey: true }), + }, + }); + const { queries, confirmations } = await userChangeQueries(blogInitial, blogFinal); + expect(queries).to.deep.equal([ + 'DROP TABLE "Users"', + 'CREATE TABLE "Users" ("id" text PRIMARY KEY)', + ]); + expect(confirmations).to.deep.equal([ + `You added new required column '${color.bold(`${TABLE_NAME}.id`)}' with no default value.` + + '\n This cannot be executed on an existing table.', + ]); + }); + it('should be empty when type updated to same underlying SQL type', async () => { const blogInitial = tableSchema.parse({ ...userInitial,