Skip to content

Commit

Permalink
Insert parameters in check constraint
Browse files Browse the repository at this point in the history
  • Loading branch information
L-Mario564 committed Jan 30, 2025
1 parent 11f0ab2 commit 7acbbfb
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 6 deletions.
4 changes: 2 additions & 2 deletions drizzle-kit/src/serializer/mysqlSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
UniqueConstraint,
View,
} from '../serializer/mysqlSchema';
import { type DB, escapeSingleQuotes } from '../utils';
import { type DB, escapeSingleQuotes, replaceQueryParams } from '../utils';
import { getColumnCasing, sqlToStr } from './utils';

export const indexName = (tableName: string, columns: string[]) => {
Expand Down Expand Up @@ -399,7 +399,7 @@ export const generateMySqlSnapshot = (

checkConstraintObject[checkName] = {
name: checkName,
value: dialect.sqlToQuery(check.value).sql,
value: replaceQueryParams('mysql', dialect.sqlToQuery(check.value)),
};
});

Expand Down
4 changes: 2 additions & 2 deletions drizzle-kit/src/serializer/pgSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import type {
UniqueConstraint,
View,
} from '../serializer/pgSchema';
import { type DB, escapeSingleQuotes, isPgArrayType } from '../utils';
import { type DB, escapeSingleQuotes, isPgArrayType, replaceQueryParams } from '../utils';
import { getColumnCasing, sqlToStr } from './utils';

export const indexName = (tableName: string, columns: string[]) => {
Expand Down Expand Up @@ -559,7 +559,7 @@ export const generatePgSnapshot = (

checksObject[checkName] = {
name: checkName,
value: dialect.sqlToQuery(check.value).sql,
value: replaceQueryParams('postgresql', dialect.sqlToQuery(check.value)),
};
});

Expand Down
4 changes: 2 additions & 2 deletions drizzle-kit/src/serializer/sqliteSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import type {
UniqueConstraint,
View,
} from '../serializer/sqliteSchema';
import { escapeSingleQuotes, type SQLiteDB } from '../utils';
import { escapeSingleQuotes, replaceQueryParams, type SQLiteDB } from '../utils';
import { getColumnCasing, sqlToStr } from './utils';

export const generateSqliteSnapshot = (
Expand Down Expand Up @@ -309,7 +309,7 @@ export const generateSqliteSnapshot = (

checkConstraintObject[checkName] = {
name: checkName,
value: dialect.sqlToQuery(check.value).sql,
value: replaceQueryParams('sqlite', dialect.sqlToQuery(check.value)),
};
});

Expand Down
24 changes: 24 additions & 0 deletions drizzle-kit/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { RunResult } from 'better-sqlite3';
import chalk from 'chalk';
import type { Query } from 'drizzle-orm';
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'fs';
import { join } from 'path';
import { parse } from 'url';
Expand Down Expand Up @@ -368,3 +369,26 @@ export function unescapeSingleQuotes(str: string, ignoreFirstAndLastChar: boolea
const regex = ignoreFirstAndLastChar ? /(?<!^)'(?!$)/g : /'/g;
return str.replace(/''/g, "'").replace(regex, "\\'");
}

export function replaceQueryParams(dialect: Dialect, query: Query): string {
let str = query.sql;
const params = query.params.map((p) => {
try {
return JSON.stringify(p);
} catch {
return String(p);
}
});

if (dialect === 'postgresql') {
for (let i = 0; i < params.length; i++) {
str = str.replace(`$${i + 1}`, params[i]);
}
return str;
}

for (const param of params) {
str = str.replace('?', param);
}
return str;
}
25 changes: 25 additions & 0 deletions drizzle-kit/tests/mysql-checks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,28 @@ test('create checks with same names', async (t) => {

await expect(diffTestSchemasMysql({}, to, [])).rejects.toThrowError();
});

test('check with param', async (t) => {
const from = {
users: mysqlTable('users', {
id: serial('id').primaryKey(),
age: int('age'),
}),
};

const to = {
users: mysqlTable('users', {
id: serial('id').primaryKey(),
age: int('age'),
}, (table) => [
check('name', sql`${table.age} > ${21}`),
]),
};

const { sqlStatements } = await diffTestSchemasMysql(from, to, []);

expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE \`users\` ADD CONSTRAINT \`name\` CHECK (\`users\`.\`age\` > 21);`,
);
});
25 changes: 25 additions & 0 deletions drizzle-kit/tests/pg-checks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,28 @@ test('create checks with same names', async (t) => {

await expect(diffTestSchemas({}, to, [])).rejects.toThrowError();
});

test('check with param', async (t) => {
const from = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}),
};

const to = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}, (table) => [
check('name', sql`${table.age} > ${21}`),
]),
};

const { sqlStatements } = await diffTestSchemas(from, to, []);

expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "users" ADD CONSTRAINT "name" CHECK ("users"."age" > 21);`,
);
});
30 changes: 30 additions & 0 deletions drizzle-kit/tests/sqlite-checks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,33 @@ test('create checks with same names', async (t) => {

await expect(diffTestSchemasSqlite({}, to, [])).rejects.toThrowError();
});

test('check with param', async (t) => {
const from = {
users: sqliteTable('users', {
id: int('id').primaryKey(),
age: int('age'),
}),
};

const to = {
users: sqliteTable('users', {
id: int('id').primaryKey(),
age: int('age'),
}, (table) => [
check('name', sql`${table.age} > ${21}`),
]),
};

const { sqlStatements } = await diffTestSchemasSqlite(from, to, []);

expect(sqlStatements.length).toBe(6);
expect(sqlStatements).toStrictEqual([
'PRAGMA foreign_keys=OFF;',
'CREATE TABLE `__new_users` (\n\t`id` integer PRIMARY KEY NOT NULL,\n\t`age` integer,\n\tCONSTRAINT "name" CHECK("__new_users"."age" > 21)\n);\n',
'INSERT INTO `__new_users`("id", "age") SELECT "id", "age" FROM `users`;',
'DROP TABLE `users`;',
'ALTER TABLE `__new_users` RENAME TO `users`;',
'PRAGMA foreign_keys=ON;',
]);
});

0 comments on commit 7acbbfb

Please sign in to comment.