From 8ce92a1edbd2bd22846326fd3fa4bf5c139aae3d Mon Sep 17 00:00:00 2001 From: avallete Date: Tue, 19 Mar 2024 00:40:53 +0100 Subject: [PATCH 1/3] wip: add cyclic tables tests --- packages/seed/e2e/e2e.keys.test.ts | 785 +++++++++++++++++- .../introspect/queries/fetchSequences.ts | 3 +- 2 files changed, 779 insertions(+), 9 deletions(-) diff --git a/packages/seed/e2e/e2e.keys.test.ts b/packages/seed/e2e/e2e.keys.test.ts index 82d094f9..6406b772 100644 --- a/packages/seed/e2e/e2e.keys.test.ts +++ b/packages/seed/e2e/e2e.keys.test.ts @@ -2,9 +2,6 @@ import { describe, expect, test } from "vitest"; import { type Dialect, adapters } from "#test/adapters.js"; import { setupProject } from "#test/setupProject.js"; -type DialectRecordWithDefault = Partial> & - Record<"default", string>; - for (const dialect of Object.keys(adapters) as Array) { const adapter = await adapters[dialect](); @@ -20,7 +17,7 @@ for (const dialect of Object.keys(adapters) as Array) { `e2e keys: ${dialect}`, () => { test("work as expected with composites primary keys", async () => { - const schema: DialectRecordWithDefault = { + const schema: Partial> = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -117,7 +114,7 @@ for (const dialect of Object.keys(adapters) as Array) { ]); }); test("work as expected with composite primary keys made by non nullable unique index", async () => { - const schema: DialectRecordWithDefault = { + const schema: Partial> = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -210,7 +207,7 @@ for (const dialect of Object.keys(adapters) as Array) { ]); }); test("work as expected with composite primary keys made by nullable unique index", async () => { - const schema: DialectRecordWithDefault = { + const schema: Partial> = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -327,7 +324,7 @@ for (const dialect of Object.keys(adapters) as Array) { } }); test("work as expected and UPDATE children with PRIMARY KEY field", async () => { - const schema: DialectRecordWithDefault = { + const schema: Partial> = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -419,7 +416,7 @@ for (const dialect of Object.keys(adapters) as Array) { ]); }); test("work as expected and UPDATE children with UNIQUE NON NULLABLE field", async () => { - const schema: DialectRecordWithDefault = { + const schema: Partial> = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -508,6 +505,778 @@ for (const dialect of Object.keys(adapters) as Array) { { gameId: 3, score: expect.any(Number), teamId: 2 }, ]); }); + test("should handle auto circular references", async () => { + const schema: Partial> = { + default: ` + create table customer ( + id serial primary key, + name text not null, + referrer_id integer references customer(id) + ); + `, + sqlite: ` + create table customer ( + id integer primary key autoincrement not null, + name text not null, + referrer_id integer references customer(id) + ); + `, + }; + const { db } = await setupProject({ + adapter, + databaseSchema: schema[dialect] ?? schema.default, + seedScript: ` + import { createSeedClient } from "#seed" + const seed = await createSeedClient() + await seed.customers([ + { name: "John Doe", referrerId: 2 }, + { name: "Jane Doe", referrerId: 1 }, + ]); + `, + }); + const results = await db.query( + `select * from customer order by id asc`, + ); + expect(results).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + referrer_id: 2, + }, + { + id: 2, + name: "Jane Doe", + referrer_id: 1, + }, + ]), + ); + }); + test("should connect auto circular references", async () => { + const schema: Partial> = { + default: ` + create table customer ( + id serial primary key, + name text not null, + referrer_id integer references customer(id) + ); + `, + sqlite: ` + create table customer ( + id integer primary key autoincrement not null, + name text not null, + referrer_id integer references customer(id) + ); + `, + }; + const { db } = await setupProject({ + adapter, + databaseSchema: schema[dialect] ?? schema.default, + seedScript: ` + import { createSeedClient } from "#seed" + const seed = await createSeedClient() + const {customers} = await seed.customers([{name: "John Doe"}]) + await seed.customers([{name: "Jane Doe"}], {connect: {customers}}) + `, + }); + const results = await db.query( + `select * from customer order by id asc`, + ); + expect(results).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + referrer_id: null, + }, + { + id: 2, + name: "Jane Doe", + referrer_id: 1, + }, + ]), + ); + }); + test("should handle complex circular references", async () => { + const schema: Partial> = { + default: ` + create table customer ( + id serial primary key, + name text not null, + last_order_id integer + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer + ); + + create table "order" ( + id serial primary key, + customer_id integer not null, + product_id integer not null, + quantity integer not null, + CONSTRAINT fk_customer + FOREIGN KEY(customer_id) + REFERENCES customer(id), + CONSTRAINT fk_product + FOREIGN KEY(product_id) + REFERENCES product(id) + ); + -- Add constraints to customer and product tables + alter table customer add constraint fk_last_order + foreign key (last_order_id) references "order"(id); + + alter table product add constraint fk_first_order + foreign key (first_order_id) references "order"(id); + `, + sqlite: ` + create table customer ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + last_order_id INTEGER, + FOREIGN KEY(last_order_id) REFERENCES "order"(id) + ); + create table product ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + first_order_id INTEGER, + FOREIGN KEY(first_order_id) REFERENCES "order"(id) + ); + create table "order" ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + customer_id INTEGER NOT NULL, + product_id INTEGER NOT NULL, + quantity INTEGER NOT NULL, + FOREIGN KEY(customer_id) REFERENCES customer(id), + FOREIGN KEY(product_id) REFERENCES product(id) + ); + PRAGMA foreign_keys = ON; + `, + }; + const { db } = await setupProject({ + adapter, + databaseSchema: schema[dialect] ?? schema.default, + seedScript: ` + import { createSeedClient } from "#seed" + const seed = await createSeedClient() + // Create a new customer + const customersStore = await seed.customers([ + { name: "John Doe" }, + ]); + // Create an order and a product on this customer, set the first order id on the product + // to match the order id + await seed.orders([{ + quantity: 10, + productsByFirstOrderId: { + firstOrderId: 1, + name: "Gadget", + } + }], { connect: customersStore }); + `, + }); + const customerResults = await db.query( + `select * from customer order by id asc`, + ); + const orderResults = await db.query( + `select * from "order" order by id asc`, + ); + const productResults = await db.query( + `select * from product order by id asc`, + ); + expect(customerResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + last_order_id: null, + }, + ]), + ); + + expect(orderResults).toEqual( + expect.arrayContaining([ + { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }, + ]), + ); + + expect(productResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "Gadget", + first_order_id: 1, + }, + ]), + ); + }); + test("should handle circular references with bigger circular loop", async () => { + const schema: Partial> = { + default: ` + -- Create tables without foreign keys that reference "order" + create table customer ( + id serial primary key, + name text not null, + last_order_id integer + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer + ); + + create table supplier ( + id serial primary key, + name text not null, + first_shipment_id integer + ); + + -- Now create the order and shipment tables + create table "order" ( + id serial primary key, + customer_id integer not null, + product_id integer not null, + quantity integer not null, + shipment_id integer + ); + + create table shipment ( + id serial primary key, + order_id integer not null, + supplier_id integer not null + ); + + -- After all tables are created, add the foreign key constraints + ALTER TABLE customer ADD CONSTRAINT fk_customer_last_order FOREIGN KEY(last_order_id) REFERENCES "order"(id); + ALTER TABLE product ADD CONSTRAINT fk_product_first_order FOREIGN KEY(first_order_id) REFERENCES "order"(id); + ALTER TABLE supplier ADD CONSTRAINT fk_supplier_first_shipment FOREIGN KEY(first_shipment_id) REFERENCES shipment(id); + + ALTER TABLE "order" ADD CONSTRAINT fk_order_customer FOREIGN KEY(customer_id) REFERENCES customer(id); + ALTER TABLE "order" ADD CONSTRAINT fk_order_product FOREIGN KEY(product_id) REFERENCES product(id); + ALTER TABLE "order" ADD CONSTRAINT fk_order_shipment FOREIGN KEY(shipment_id) REFERENCES shipment(id); + + ALTER TABLE shipment ADD CONSTRAINT fk_shipment_order FOREIGN KEY(order_id) REFERENCES "order"(id); + ALTER TABLE shipment ADD CONSTRAINT fk_shipment_supplier FOREIGN KEY(supplier_id) REFERENCES supplier(id); + `, + sqlite: ` + -- Create tables without foreign keys that reference "order" + create table customer ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name text not null + ); + + create table product ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name text not null + ); + + create table supplier ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name text not null + ); + + -- Now create the order and shipment tables + create table "order" ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + quantity integer not null + ); + + create table shipment ( + id INTEGER PRIMARY KEY AUTOINCREMENT + ); + + -- After all tables are created, add the foreign key constraints + ALTER TABLE customer ADD COLUMN last_order_id integer REFERENCES "order"(id); + ALTER TABLE product ADD COLUMN first_order_id integer REFERENCES "order"(id); + ALTER TABLE supplier ADD COLUMN first_shipment_id integer REFERENCES shipment(id); + + ALTER TABLE "order" ADD COLUMN customer_id integer not null REFERENCES customer(id); + ALTER TABLE "order" ADD COLUMN product_id integer not null REFERENCES product(id); + ALTER TABLE "order" ADD COLUMN shipment_id integer REFERENCES shipment(id); + + ALTER TABLE shipment ADD COLUMN order_id integer not null REFERENCES "order"(id); + ALTER TABLE shipment ADD COLUMN supplier_id integer not null REFERENCES supplier(id); + PRAGMA foreign_keys = ON; + `, + }; + const { db } = await setupProject({ + adapter, + databaseSchema: schema[dialect] ?? schema.default, + seedScript: ` + import { createSeedClient } from "#seed" + const seed = await createSeedClient() + const ordersStore = await seed.orders([{ + quantity: 10, + productsByFirstOrderId: { + firstOrderId: 1, + name: 'Gadget', + }, + customersByLastOrderId: { + lastOrderId: 1, + name: 'John Doe' + }, + }]); + await seed.shipments([ + { + suppliersByFirstShipmentId: {name: "GizmoCorp", firstShipmentId: 1}, + } + ], {connect: ordersStore}) + `, + }); + // Verify the circular dependencies + const customerResult = await db.query(`SELECT * FROM customer`); + const productResult = await db.query(`SELECT * FROM product`); + const orderResult = await db.query(`SELECT * FROM "order"`); + const shipmentResult = await db.query(`SELECT * FROM shipment`); + const supplierResult = await db.query(`SELECT * FROM supplier`); + + // Assertions + expect(customerResult).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + last_order_id: 1, + }, + ]), + ); + + expect(productResult).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "Gadget", + first_order_id: 1, + }, + ]), + ); + + expect(orderResult).toEqual( + expect.arrayContaining([ + { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + shipment_id: null, + }, + ]), + ); + + expect(shipmentResult).toEqual( + expect.arrayContaining([ + { + id: 1, + order_id: 1, + supplier_id: 1, + }, + ]), + ); + + expect(supplierResult).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "GizmoCorp", + first_shipment_id: 1, + }, + ]), + ); + }); + test("should work with one single nullable FK table in the circular loop", async () => { + const schema: Partial> = { + default: ` + create table customer ( + id serial primary key, + name text not null, + last_order_id integer NOT NULL + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer NOT NULL + ); + + create table "order" ( + id serial primary key, + customer_id integer, + product_id integer, + quantity integer not null, + CONSTRAINT fk_customer + FOREIGN KEY(customer_id) + REFERENCES customer(id), + CONSTRAINT fk_product + FOREIGN KEY(product_id) + REFERENCES product(id) + ); + -- Add constraints to customer and product tables + alter table customer add constraint fk_last_order + foreign key (last_order_id) references "order"(id); + + alter table product add constraint fk_first_order + foreign key (first_order_id) references "order"(id); + `, + sqlite: ` + create table customer ( + id integer primary key autoincrement, + name text not null + ); + + create table product ( + id integer primary key autoincrement, + name text not null + ); + + create table "order" ( + id integer primary key autoincrement, + customer_id integer REFERENCES customer(id), + product_id integer REFERENCES product(id), + quantity integer not null + ); + ALTER TABLE customer ADD COLUMN last_order_id integer not null REFERENCES "order"(id); + ALTER TABLE product ADD COLUMN first_order_id integer not null REFERENCES "order"(id); + PRAGMA foreign_keys = ON; + `, + }; + const { db } = await setupProject({ + adapter, + databaseSchema: schema[dialect] ?? schema.default, + seedScript: ` + import { createSeedClient } from "#seed" + const seed = await createSeedClient() + await seed.customers([{name: "John Doe"}], {connect: true}) + await seed.products([{name: "Gadget"}], {connect: true}) + await seed.orders([{ + quantity: 10, + }], {connect: true}) + `, + }); + const customerResults = await db.query( + `select * from customer order by id asc`, + ); + const orderResults = await db.query( + `select * from "order" order by id asc`, + ); + const productResults = await db.query( + `select * from product order by id asc`, + ); + + expect(customerResults).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: 1, + name: "John Doe", + last_order_id: 1, + }), + ]), + ); + + expect(orderResults).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + customer_id: 1, + product_id: 1, + quantity: 10, + }), + ]), + ); + + expect(productResults).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: 1, + name: "Gadget", + first_order_id: 1, + }), + ]), + ); + }); + test("should handle join table relationship", async () => { + const schema: Partial> = { + default: ` + CREATE TABLE authors ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL + ); + + CREATE TABLE books ( + id SERIAL PRIMARY KEY, + title TEXT NOT NULL + ); + + CREATE TABLE author_books ( + author_id INTEGER NOT NULL, + book_id INTEGER NOT NULL, + PRIMARY KEY (author_id, book_id), + FOREIGN KEY (author_id) REFERENCES authors(id), + FOREIGN KEY (book_id) REFERENCES books(id) + ); + `, + sqlite: ` + CREATE TABLE authors ( + id INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL + ); + + CREATE TABLE books ( + id INTEGER NOT NULL PRIMARY KEY, + title TEXT NOT NULL + ); + + CREATE TABLE author_books ( + author_id INTEGER NOT NULL, + book_id INTEGER NOT NULL, + PRIMARY KEY (author_id, book_id), + FOREIGN KEY (author_id) REFERENCES authors(id), + FOREIGN KEY (book_id) REFERENCES books(id) + ); + PRAGMA foreign_keys = ON; + `, + }; + const { db } = await setupProject({ + adapter, + databaseSchema: schema[dialect] ?? schema.default, + seedScript: ` + import { createSeedClient } from "#seed" + const seed = await createSeedClient() + await seed.authors([ + { + name: "Author One", + authorBooks: [{book: {id: 1, title: "Book One"}}, {book: {id: 2, title: "Book Two"}}] + }, + { + name: "Author Two", + authorBooks: [{bookId: 1}] + } + ]) + `, + }); + const results = await db.query(` + SELECT a.name, b.title + FROM author_books ab + JOIN authors a ON ab.author_id = a.id + JOIN books b ON ab.book_id = b.id + `); + + // Assertions to verify the join table relationships + // This assumes your testing framework has an expect function and that + // you're familiar with its assertion syntax. Adjust accordingly. + expect(results).toEqual( + expect.arrayContaining([ + { name: "Author One", title: "Book One" }, + { name: "Author One", title: "Book Two" }, + { name: "Author Two", title: "Book One" }, + ]), + ); + }); + test.only("should error on non nullables complex circular references", async () => { + const schema: Partial> = { + default: ` + create table customer ( + id serial primary key, + name text not null, + last_order_id integer NOT NULL + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer NOT NULL + ); + + create table "order" ( + id serial primary key, + customer_id integer not null, + product_id integer not null, + quantity integer not null, + CONSTRAINT fk_customer + FOREIGN KEY(customer_id) + REFERENCES customer(id), + CONSTRAINT fk_product + FOREIGN KEY(product_id) + REFERENCES product(id) + ); + -- Add constraints to customer and product tables + alter table customer add constraint fk_last_order foreign key (last_order_id) references "order"(id); + + alter table product add constraint fk_first_order foreign key (first_order_id) references "order"(id); + `, + sqlite: ` + create table customer ( + id integer primary key autoincrement, + name text not null + ); + + create table product ( + id integer primary key autoincrement, + name text not null + ); + + create table "order" ( + id integer primary key autoincrement, + customer_id integer REFERENCES customer(id), + product_id integer REFERENCES product(id), + quantity integer not null + ); + ALTER TABLE customer ADD COLUMN last_order_id integer not null REFERENCES "order"(id); + ALTER TABLE product ADD COLUMN first_order_id integer not null REFERENCES "order"(id); + PRAGMA foreign_keys = ON; + `, + }; + await expect(() => + setupProject({ + adapter, + databaseSchema: schema[dialect] ?? schema.default, + seedScript: ` + import { createSeedClient } from "#seed" + const seed = await createSeedClient({dryRun: true}) + await seed.orders([ + { + quantity: 10, + productsByFirstOrderId: { + name: "Gadget", + }, + customersByLastOrderId: { + name: "John Doe", + } + } + ]) + `, + }), + ).rejects.toThrow("Maximum call stack size exceeded"); + }); + + // This should pass or fail at types analysis level + test.todo( + "should handle complex circular references using connection", + async () => { + const schema: Partial> = { + default: ` + create table customer ( + id serial primary key, + name text not null, + last_order_id integer + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer + ); + + create table "order" ( + id serial primary key, + customer_id integer not null, + product_id integer not null, + quantity integer not null, + CONSTRAINT fk_customer + FOREIGN KEY(customer_id) + REFERENCES customer(id), + CONSTRAINT fk_product + FOREIGN KEY(product_id) + REFERENCES product(id) + ); + -- Add constraints to customer and product tables + alter table customer add constraint fk_last_order + foreign key (last_order_id) references "order"(id); + + alter table product add constraint fk_first_order + foreign key (first_order_id) references "order"(id); + `, + sqlite: ` + create table customer ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + last_order_id INTEGER, + FOREIGN KEY(last_order_id) REFERENCES "order"(id) + ); + create table product ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + first_order_id INTEGER, + FOREIGN KEY(first_order_id) REFERENCES "order"(id) + ); + create table "order" ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + customer_id INTEGER NOT NULL, + product_id INTEGER NOT NULL, + quantity INTEGER NOT NULL, + FOREIGN KEY(customer_id) REFERENCES customer(id), + FOREIGN KEY(product_id) REFERENCES product(id) + ); + PRAGMA foreign_keys = ON; + `, + }; + const { db } = await setupProject({ + adapter, + databaseSchema: schema[dialect] ?? schema.default, + seedScript: ` + import { createSeedClient } from "#seed" + const seed = await createSeedClient() + // Create a new customer + const customersStore = await seed.customers([ + { name: "John Doe" }, + ]); + // Create an order and a product on this customer, set the first order id on the product + // to match the order id + await seed.orders([{ + quantity: 10, + productsByFirstOrderId: { + firstOrderId: (ctx) => ctx.$store.orders[0].id!, + name: "Gadget", + } + }], { connect: customersStore }); + `, + }); + const customerResults = await db.query( + `select * from customer order by id asc`, + ); + const orderResults = await db.query( + `select * from "order" order by id asc`, + ); + const productResults = await db.query( + `select * from product order by id asc`, + ); + expect(customerResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + last_order_id: null, + }, + ]), + ); + + expect(orderResults).toEqual( + expect.arrayContaining([ + { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }, + ]), + ); + + expect(productResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "Gadget", + first_order_id: 1, + }, + ]), + ); + }, + ); }, { timeout: 45000, diff --git a/packages/seed/src/dialects/sqlite/introspect/queries/fetchSequences.ts b/packages/seed/src/dialects/sqlite/introspect/queries/fetchSequences.ts index 42221a22..7ddcbb37 100644 --- a/packages/seed/src/dialects/sqlite/introspect/queries/fetchSequences.ts +++ b/packages/seed/src/dialects/sqlite/introspect/queries/fetchSequences.ts @@ -1,4 +1,5 @@ import { type DrizzleDbClient } from "#core/adapters.js"; +import { escapeIdentifier } from "#dialects/sqlite/utils.js"; import { FETCH_TABLE_COLUMNS_LIST, type FetchTableAndColumnsResultRaw, @@ -42,7 +43,7 @@ export async function fetchSequences(client: DrizzleDbClient) { const pkKey = tablePk && tablePk.affinity === "integer" ? tablePk.colName : "rowid"; const maxSeqRes = await client.query<{ currentSequenceValue: number }>( - `SELECT MAX(${pkKey}) + 1 as currentSequenceValue FROM ${tableId}`, + `SELECT MAX(${escapeIdentifier(pkKey)}) + 1 as currentSequenceValue FROM ${escapeIdentifier(tableId)}`, ); const maxSeqNo = maxSeqRes[0]; results.push({ From a5eb951f6d2cf9f6284e00a11f48e9a381f86ba0 Mon Sep 17 00:00:00 2001 From: avallete Date: Tue, 19 Mar 2024 00:48:43 +0100 Subject: [PATCH 2/3] wip: setup circular references e2e tests --- packages/seed/e2e/e2e.keys.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/seed/e2e/e2e.keys.test.ts b/packages/seed/e2e/e2e.keys.test.ts index 6406b772..b76a90d6 100644 --- a/packages/seed/e2e/e2e.keys.test.ts +++ b/packages/seed/e2e/e2e.keys.test.ts @@ -1077,7 +1077,7 @@ for (const dialect of Object.keys(adapters) as Array) { ]), ); }); - test.only("should error on non nullables complex circular references", async () => { + test("should error on non nullables complex circular references", async () => { const schema: Partial> = { default: ` create table customer ( @@ -1122,8 +1122,8 @@ for (const dialect of Object.keys(adapters) as Array) { create table "order" ( id integer primary key autoincrement, - customer_id integer REFERENCES customer(id), - product_id integer REFERENCES product(id), + customer_id integer not null REFERENCES customer(id), + product_id integer not null REFERENCES product(id), quantity integer not null ); ALTER TABLE customer ADD COLUMN last_order_id integer not null REFERENCES "order"(id); From d38dea759103e58d7e4e3aea2b23adf863acefed Mon Sep 17 00:00:00 2001 From: avallete Date: Tue, 19 Mar 2024 11:09:22 +0100 Subject: [PATCH 3/3] fix: type --- packages/seed/e2e/e2e.keys.test.ts | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/seed/e2e/e2e.keys.test.ts b/packages/seed/e2e/e2e.keys.test.ts index b76a90d6..216f3649 100644 --- a/packages/seed/e2e/e2e.keys.test.ts +++ b/packages/seed/e2e/e2e.keys.test.ts @@ -2,6 +2,9 @@ import { describe, expect, test } from "vitest"; import { type Dialect, adapters } from "#test/adapters.js"; import { setupProject } from "#test/setupProject.js"; +type DialectRecordWithDefault = Partial> & + Record<"default", string>; + for (const dialect of Object.keys(adapters) as Array) { const adapter = await adapters[dialect](); @@ -17,7 +20,7 @@ for (const dialect of Object.keys(adapters) as Array) { `e2e keys: ${dialect}`, () => { test("work as expected with composites primary keys", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -114,7 +117,7 @@ for (const dialect of Object.keys(adapters) as Array) { ]); }); test("work as expected with composite primary keys made by non nullable unique index", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -207,7 +210,7 @@ for (const dialect of Object.keys(adapters) as Array) { ]); }); test("work as expected with composite primary keys made by nullable unique index", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -324,7 +327,7 @@ for (const dialect of Object.keys(adapters) as Array) { } }); test("work as expected and UPDATE children with PRIMARY KEY field", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -416,7 +419,7 @@ for (const dialect of Object.keys(adapters) as Array) { ]); }); test("work as expected and UPDATE children with UNIQUE NON NULLABLE field", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` CREATE TABLE "Team" ( "id" SERIAL PRIMARY KEY @@ -506,7 +509,7 @@ for (const dialect of Object.keys(adapters) as Array) { ]); }); test("should handle auto circular references", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` create table customer ( id serial primary key, @@ -553,7 +556,7 @@ for (const dialect of Object.keys(adapters) as Array) { ); }); test("should connect auto circular references", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` create table customer ( id serial primary key, @@ -598,7 +601,7 @@ for (const dialect of Object.keys(adapters) as Array) { ); }); test("should handle complex circular references", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` create table customer ( id serial primary key, @@ -717,7 +720,7 @@ for (const dialect of Object.keys(adapters) as Array) { ); }); test("should handle circular references with bigger circular loop", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` -- Create tables without foreign keys that reference "order" create table customer ( @@ -891,7 +894,7 @@ for (const dialect of Object.keys(adapters) as Array) { ); }); test("should work with one single nullable FK table in the circular loop", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` create table customer ( id serial primary key, @@ -1000,7 +1003,7 @@ for (const dialect of Object.keys(adapters) as Array) { ); }); test("should handle join table relationship", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` CREATE TABLE authors ( id SERIAL PRIMARY KEY, @@ -1078,7 +1081,7 @@ for (const dialect of Object.keys(adapters) as Array) { ); }); test("should error on non nullables complex circular references", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` create table customer ( id serial primary key, @@ -1158,7 +1161,7 @@ for (const dialect of Object.keys(adapters) as Array) { test.todo( "should handle complex circular references using connection", async () => { - const schema: Partial> = { + const schema: DialectRecordWithDefault = { default: ` create table customer ( id serial primary key,