Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
OleksiiKH0240 committed Jan 27, 2025
1 parent 32b71c0 commit e5713d6
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 73 deletions.
27 changes: 12 additions & 15 deletions drizzle-seed/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,13 +659,12 @@ const getPostgresInfo = (
tableRelations[tableTsName]?.some((rel) =>
rel.table === relation.table
&& rel.refTable === relation.refTable
) === true
)
) {
console.warn(
`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
+ `You can specify either the foreign key constraint or the relation, but not both.\n`
+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
`You are providing a one-to-many relation between the '${relation.refTable}' and '${relation.table}' tables,\n`
+ `while the '${relation.table}' table object already has foreign key constraint in the schema referencing '${relation.refTable}' table.\n`
+ `In this case, the foreign key constraint will be used.\n`,
);
continue;
}
Expand Down Expand Up @@ -1053,13 +1052,12 @@ const getMySqlInfo = (
tableRelations[tableTsName]?.some((rel) =>
rel.table === relation.table
&& rel.refTable === relation.refTable
) === true
)
) {
console.warn(
`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
+ `You can specify either the foreign key constraint or the relation, but not both.\n`
+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
`You are providing a one-to-many relation between the '${relation.refTable}' and '${relation.table}' tables,\n`
+ `while the '${relation.table}' table object already has foreign key constraint in the schema referencing '${relation.refTable}' table.\n`
+ `In this case, the foreign key constraint will be used.\n`,
);
continue;
}
Expand Down Expand Up @@ -1374,13 +1372,12 @@ const getSqliteInfo = (
tableRelations[tableTsName]?.some((rel) =>
rel.table === relation.table
&& rel.refTable === relation.refTable
) === true
)
) {
console.warn(
`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
+ `You can specify either the foreign key constraint or the relation, but not both.\n`
+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
`You are providing a one-to-many relation between the '${relation.refTable}' and '${relation.table}' tables,\n`
+ `while the '${relation.table}' table object already has foreign key constraint in the schema referencing '${relation.refTable}' table.\n`
+ `In this case, the foreign key constraint will be used.\n`,
);
continue;
}
Expand Down
7 changes: 0 additions & 7 deletions drizzle-seed/tests/mysql/allDataTypesTest/drizzle.config.ts

This file was deleted.

7 changes: 0 additions & 7 deletions drizzle-seed/tests/mysql/drizzle.config.ts

This file was deleted.

7 changes: 0 additions & 7 deletions drizzle-seed/tests/mysql/generatorsTest/drizzle.config.ts

This file was deleted.

64 changes: 62 additions & 2 deletions drizzle-seed/tests/mysql/mysql.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Docker from 'dockerode';
import { sql } from 'drizzle-orm';
import { relations, sql } from 'drizzle-orm';
import type { MySql2Database } from 'drizzle-orm/mysql2';
import { drizzle } from 'drizzle-orm/mysql2';
import getPort from 'get-port';
import type { Connection } from 'mysql2/promise';
import { createConnection } from 'mysql2/promise';
import { v4 as uuid } from 'uuid';
import { afterAll, afterEach, beforeAll, expect, test } from 'vitest';
import { afterAll, afterEach, beforeAll, expect, test, vi } from 'vitest';
import { reset, seed } from '../../src/index.ts';
import * as schema from './mysqlSchema.ts';

Expand Down Expand Up @@ -180,6 +180,29 @@ beforeAll(async () => {
`,
);

await db.execute(
sql`
CREATE TABLE \`users\` (
\`id\` int,
\`name\` text,
\`invitedBy\` int,
CONSTRAINT \`users_id\` PRIMARY KEY(\`id\`)
);
`,
);

await db.execute(
sql`
CREATE TABLE \`posts\` (
\`id\` int,
\`name\` text,
\`content\` text,
\`userId\` int,
CONSTRAINT \`posts_id\` PRIMARY KEY(\`id\`)
);
`,
);

await db.execute(
sql`
ALTER TABLE \`order_detail\` ADD CONSTRAINT \`order_detail_order_id_order_id_fk\` FOREIGN KEY (\`order_id\`) REFERENCES \`order\`(\`id\`) ON DELETE cascade ON UPDATE no action;
Expand Down Expand Up @@ -215,6 +238,18 @@ beforeAll(async () => {
ALTER TABLE \`product\` ADD CONSTRAINT \`product_supplier_id_supplier_id_fk\` FOREIGN KEY (\`supplier_id\`) REFERENCES \`supplier\`(\`id\`) ON DELETE cascade ON UPDATE no action;
`,
);

await db.execute(
sql`
ALTER TABLE \`users\` ADD CONSTRAINT \`users_invitedBy_users_id_fk\` FOREIGN KEY (\`invitedBy\`) REFERENCES \`users\`(\`id\`) ON DELETE cascade ON UPDATE no action;
`,
);

await db.execute(
sql`
ALTER TABLE \`posts\` ADD CONSTRAINT \`posts_userId_users_id_fk\` FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON DELETE cascade ON UPDATE no action;
`,
);
});

afterAll(async () => {
Expand Down Expand Up @@ -379,3 +414,28 @@ test("sequential using of 'with'", async () => {
expect(products.length).toBe(11);
expect(suppliers.length).toBe(11);
});

test('overlapping a foreign key constraint with a one-to-many relation', async () => {
const postsRelation = relations(schema.posts, ({ one }) => ({
user: one(schema.users, { fields: [schema.posts.userId], references: [schema.users.id] }),
}));

const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => {});

await reset(db, { users: schema.users, posts: schema.posts, postsRelation });
await seed(db, { users: schema.users, posts: schema.posts, postsRelation });
// expecting to get a warning
expect(consoleMock).toBeCalled();
expect(consoleMock).toBeCalledWith(expect.stringMatching(/^You are providing a one-to-many relation.+/));

const users = await db.select().from(schema.users);
const posts = await db.select().from(schema.posts);

expect(users.length).toBe(10);
let predicate = users.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
expect(predicate).toBe(true);

expect(posts.length).toBe(10);
predicate = posts.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
expect(predicate).toBe(true);
});
19 changes: 19 additions & 0 deletions drizzle-seed/tests/mysql/mysqlSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,22 @@ export const details = mysqlTable('order_detail', {
.notNull()
.references(() => products.id, { onDelete: 'cascade' }),
});

export const users = mysqlTable(
'users',
{
id: int().primaryKey(),
name: text(),
invitedBy: int().references((): AnyMySqlColumn => users.id),
},
);

export const posts = mysqlTable(
'posts',
{
id: int().primaryKey(),
name: text(),
content: text(),
userId: int().references(() => users.id),
},
);
46 changes: 23 additions & 23 deletions drizzle-seed/tests/pg/allDataTypesTest/pgSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,31 +64,31 @@ export const allDataTypes = schema.table('all_data_types', {
});

export const allArrayDataTypes = schema.table('all_array_data_types', {
// integerArray: integer('integer_array').array(),
// smallintArray: smallint('smallint_array').array(),
// bigintegerArray: bigint('bigint_array', { mode: 'bigint' }).array(),
// bigintNumberArray: bigint('bigint_number_array', { mode: 'number' }).array(),
// booleanArray: boolean('boolean_array').array(),
// textArray: text('text_array').array(),
// varcharArray: varchar('varchar_array', { length: 256 }).array(),
// charArray: char('char_array', { length: 256 }).array(),
// numericArray: numeric('numeric_array').array(),
// decimalArray: decimal('decimal_array').array(),
// realArray: real('real_array').array(),
// doublePrecisionArray: doublePrecision('double_precision_array').array(),
// jsonArray: json('json_array').array(),
// jsonbArray: jsonb('jsonb_array').array(),
// timeArray: time('time_array').array(),
// timestampDateArray: timestamp('timestamp_date_array', { mode: 'date' }).array(),
// timestampStringArray: timestamp('timestamp_string_array', { mode: 'string' }).array(),
integerArray: integer('integer_array').array(),
smallintArray: smallint('smallint_array').array(),
bigintegerArray: bigint('bigint_array', { mode: 'bigint' }).array(),
bigintNumberArray: bigint('bigint_number_array', { mode: 'number' }).array(),
booleanArray: boolean('boolean_array').array(),
textArray: text('text_array').array(),
varcharArray: varchar('varchar_array', { length: 256 }).array(),
charArray: char('char_array', { length: 256 }).array(),
numericArray: numeric('numeric_array').array(),
decimalArray: decimal('decimal_array').array(),
realArray: real('real_array').array(),
doublePrecisionArray: doublePrecision('double_precision_array').array(),
jsonArray: json('json_array').array(),
jsonbArray: jsonb('jsonb_array').array(),
timeArray: time('time_array').array(),
timestampDateArray: timestamp('timestamp_date_array', { mode: 'date' }).array(),
timestampStringArray: timestamp('timestamp_string_array', { mode: 'string' }).array(),
dateStringArray: date('date_string_array', { mode: 'string' }).array(),
dateArray: date('date_array', { mode: 'date' }).array(),
// intervalArray: interval('interval_array').array(),
// pointArray: point('point_array', { mode: 'xy' }).array(),
// pointTupleArray: point('point_tuple_array', { mode: 'tuple' }).array(),
// lineArray: line('line_array', { mode: 'abc' }).array(),
// lineTupleArray: line('line_tuple_array', { mode: 'tuple' }).array(),
// moodEnumArray: moodEnum('mood_enum_array').array(),
intervalArray: interval('interval_array').array(),
pointArray: point('point_array', { mode: 'xy' }).array(),
pointTupleArray: point('point_tuple_array', { mode: 'tuple' }).array(),
lineArray: line('line_array', { mode: 'abc' }).array(),
lineTupleArray: line('line_tuple_array', { mode: 'tuple' }).array(),
moodEnumArray: moodEnum('mood_enum_array').array(),
});

export const ndArrays = schema.table('nd_arrays', {
Expand Down
54 changes: 47 additions & 7 deletions drizzle-seed/tests/pg/pg.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { PGlite } from '@electric-sql/pglite';
import { sql } from 'drizzle-orm';
import { relations, sql } from 'drizzle-orm';
import type { PgliteDatabase } from 'drizzle-orm/pglite';
import { drizzle } from 'drizzle-orm/pglite';
import { afterAll, afterEach, beforeAll, expect, test } from 'vitest';
import { afterAll, afterEach, beforeAll, expect, test, vi } from 'vitest';
import { reset, seed } from '../../src/index.ts';
import * as schema from './pgSchema.ts';

Expand Down Expand Up @@ -193,14 +193,29 @@ beforeAll(async () => {

await db.execute(
sql`
create table "seeder_lib_pg"."user"
create table "seeder_lib_pg"."users"
(
id serial
primary key,
name text,
"invitedBy" integer
constraint "user_invitedBy_user_id_fk"
references "seeder_lib_pg"."user"
constraint "users_invitedBy_user_id_fk"
references "seeder_lib_pg"."users"
);
`,
);

await db.execute(
sql`
create table "seeder_lib_pg"."posts"
(
id serial
primary key,
name text,
content text,
"userId" integer
constraint "users_userId_user_id_fk"
references "seeder_lib_pg"."users"
);
`,
);
Expand Down Expand Up @@ -385,11 +400,36 @@ test('seeding with identity columns', async () => {
});

test('seeding with self relation', async () => {
await seed(db, { user: schema.user });
await seed(db, { users: schema.users });

const result = await db.select().from(schema.user);
const result = await db.select().from(schema.users);

expect(result.length).toBe(10);
const predicate = result.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
expect(predicate).toBe(true);
});

test('overlapping a foreign key constraint with a one-to-many relation', async () => {
const postsRelation = relations(schema.posts, ({ one }) => ({
user: one(schema.users, { fields: [schema.posts.userId], references: [schema.users.id] }),
}));

const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => {});

await reset(db, { users: schema.users, posts: schema.posts, postsRelation });
await seed(db, { users: schema.users, posts: schema.posts, postsRelation });
// expecting to get a warning
expect(consoleMock).toBeCalled();
expect(consoleMock).toBeCalledWith(expect.stringMatching(/^You are providing a one-to-many relation.+/));

const users = await db.select().from(schema.users);
const posts = await db.select().from(schema.posts);

expect(users.length).toBe(10);
let predicate = users.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
expect(predicate).toBe(true);

expect(posts.length).toBe(10);
predicate = posts.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
expect(predicate).toBe(true);
});
16 changes: 13 additions & 3 deletions drizzle-seed/tests/pg/pgSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,21 @@ export const identityColumnsTable = schema.table('identity_columns_table', {
name: text(),
});

export const user = schema.table(
'user',
export const users = schema.table(
'users',
{
id: serial().primaryKey(),
name: text(),
invitedBy: integer().references((): AnyPgColumn => user.id),
invitedBy: integer().references((): AnyPgColumn => users.id),
},
);

export const posts = schema.table(
'posts',
{
id: serial().primaryKey(),
name: text(),
content: text(),
userId: integer().references(() => users.id),
},
);
Loading

0 comments on commit e5713d6

Please sign in to comment.