From 79c5c1eacf998194d1668497ccc6c5ad79379aec Mon Sep 17 00:00:00 2001 From: bholmesdev Date: Tue, 6 Feb 2024 17:27:50 -0500 Subject: [PATCH] feat(test): foreignKeys --- .../db/test/unit/reference-queries.test.js | 81 ++++++++++++++++--- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/packages/db/test/unit/reference-queries.test.js b/packages/db/test/unit/reference-queries.test.js index ed7b3ae267..544c4665f8 100644 --- a/packages/db/test/unit/reference-queries.test.js +++ b/packages/db/test/unit/reference-queries.test.js @@ -16,7 +16,8 @@ let User = defineCollection({ let SentBox = defineCollection({ fields: { - to: field.text({ references: () => User.fields.id }), + to: field.text(), + toName: field.text(), subject: field.text(), body: field.text(), }, @@ -49,11 +50,34 @@ function userChangeQueries( describe('reference queries', () => { it('adds references with lossless table recreate', async () => { + const SentBoxFinal = collectionSchema.parse( + defineCollection({ + fields: { + ...SentBox.fields, + to: field.text({ references: () => User.fields.id }), + }, + }) + ); + + const { queries } = await userChangeQueries(SentBox, SentBoxFinal); + + expect(queries[0]).to.not.be.undefined; + const tempTableName = getTempTableName(queries[0]); + + expect(queries).to.deep.equal([ + `CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL REFERENCES \"User\" (\"id\"), \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL)`, + `INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`, + 'DROP TABLE "User"', + `ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`, + ]); + }); + + it('removes references with lossless table recreate', async () => { const SentBoxInitial = collectionSchema.parse( defineCollection({ fields: { ...SentBox.fields, - to: field.text(), + to: field.text({ references: () => User.fields.id }), }, }) ); @@ -64,34 +88,73 @@ describe('reference queries', () => { const tempTableName = getTempTableName(queries[0]); expect(queries).to.deep.equal([ - `CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL REFERENCES \"User\" (\"id\"), \"subject\" text NOT NULL, \"body\" text NOT NULL)`, - `INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"subject\", \"body\" FROM \"User\"`, + `CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL)`, + `INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`, 'DROP TABLE "User"', `ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`, ]); }); - it('removes references with lossless table recreate', async () => { + it('does not use ADD COLUMN when adding optional column with reference', async () => { const SentBoxFinal = collectionSchema.parse( defineCollection({ fields: { ...SentBox.fields, - to: field.text(), + from: field.text({ references: () => User.fields.id, optional: true }), }, }) ); - const { queries } = await userChangeQueries(SentBox, SentBoxFinal); + const { queries } = await userChangeQueries(SentBox, SentBoxFinal); expect(queries[0]).to.not.be.undefined; const tempTableName = getTempTableName(queries[0]); expect(queries).to.deep.equal([ - `CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL)`, - `INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"subject\", \"body\" FROM \"User\"`, + `CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL, \"from\" text REFERENCES \"User\" (\"id\"))`, + `INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`, 'DROP TABLE "User"', `ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`, ]); }); + + it('adds and updates foreign key with lossless table recreate', async () => { + const SentBoxFinal = collectionSchema.parse( + defineCollection({ + ...SentBox, + foreignKeys: [ + { fields: ['to', 'toName'], references: () => [User.fields.id, User.fields.name] }, + ], + }) + ); + + const SentBoxWithDifferentFK = collectionSchema.parse( + defineCollection({ + ...SentBox, + foreignKeys: [{ fields: ['to'], references: () => [User.fields.id] }], + }) + ); + + const expected = (tempTableName) => [ + `CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL, FOREIGN KEY (\"to\", \"toName\") REFERENCES \"User\"(\"id\", \"name\"))`, + `INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`, + 'DROP TABLE "User"', + `ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`, + ]; + + const addedForeignKey = await userChangeQueries(SentBox, SentBoxFinal); + const updatedForeignKey = await userChangeQueries(SentBoxWithDifferentFK, SentBoxFinal); + + expect(addedForeignKey.queries[0]).to.not.be.undefined; + expect(updatedForeignKey.queries[0]).to.not.be.undefined; + + expect(addedForeignKey.queries).to.deep.equal( + expected(getTempTableName(addedForeignKey.queries[0])) + ); + + expect(updatedForeignKey.queries).to.deep.equal( + expected(getTempTableName(updatedForeignKey.queries[0])) + ); + }); }); /** @param {string} query */