Files
2026-07-13 12:10:05 +08:00

283 lines
7.4 KiB
TypeScript

import { sql } from 'drizzle-orm';
import { check, integer, pgTable, serial, varchar } from 'drizzle-orm/pg-core';
import { JsonCreateTableStatement } from 'src/jsonStatements';
import { expect, test } from 'vitest';
import { diffTestSchemas } from './schemaDiffer';
test('create table with check', async (t) => {
const to = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}, (table) => ({
checkConstraint: check('some_check_name', sql`${table.age} > 21`),
})),
};
const { sqlStatements, statements } = await diffTestSchemas({}, to, []);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'create_table',
tableName: 'users',
schema: '',
columns: [
{
name: 'id',
type: 'serial',
notNull: true,
primaryKey: true,
},
{
name: 'age',
type: 'integer',
notNull: false,
primaryKey: false,
},
],
compositePKs: [],
checkConstraints: ['some_check_name;"users"."age" > 21'],
compositePkName: '',
uniqueConstraints: [],
isRLSEnabled: false,
policies: [],
} as JsonCreateTableStatement);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`CREATE TABLE "users" (
\t"id" serial PRIMARY KEY NOT NULL,
\t"age" integer,
\tCONSTRAINT "some_check_name" CHECK ("users"."age" > 21)
);\n`);
});
test('add check contraint to existing table', 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) => ({
checkConstraint: check('some_check_name', sql`${table.age} > 21`),
})),
};
const { sqlStatements, statements } = await diffTestSchemas(from, to, []);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'create_check_constraint',
tableName: 'users',
schema: '',
data: 'some_check_name;"users"."age" > 21',
});
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "users" ADD CONSTRAINT "some_check_name" CHECK ("users"."age" > 21);`,
);
});
test('drop check contraint in existing table', async (t) => {
const from = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}, (table) => ({
checkConstraint: check('some_check_name', sql`${table.age} > 21`),
})),
};
const to = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}),
};
const { sqlStatements, statements } = await diffTestSchemas(from, to, []);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'delete_check_constraint',
tableName: 'users',
schema: '',
constraintName: 'some_check_name',
});
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "users" DROP CONSTRAINT "some_check_name";`,
);
});
test('rename check constraint', async (t) => {
const from = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}, (table) => ({
checkConstraint: check('some_check_name', sql`${table.age} > 21`),
})),
};
const to = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}, (table) => ({
checkConstraint: check('new_check_name', sql`${table.age} > 21`),
})),
};
const { sqlStatements, statements } = await diffTestSchemas(from, to, []);
expect(statements.length).toBe(2);
expect(statements[0]).toStrictEqual({
constraintName: 'some_check_name',
schema: '',
tableName: 'users',
type: 'delete_check_constraint',
});
expect(statements[1]).toStrictEqual({
data: 'new_check_name;"users"."age" > 21',
schema: '',
tableName: 'users',
type: 'create_check_constraint',
});
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "users" DROP CONSTRAINT "some_check_name";`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "users" ADD CONSTRAINT "new_check_name" CHECK ("users"."age" > 21);`,
);
});
test('alter check constraint', async (t) => {
const from = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}, (table) => ({
checkConstraint: check('some_check_name', sql`${table.age} > 21`),
})),
};
const to = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
}, (table) => ({
checkConstraint: check('new_check_name', sql`${table.age} > 10`),
})),
};
const { sqlStatements, statements } = await diffTestSchemas(from, to, []);
expect(statements.length).toBe(2);
expect(statements[0]).toStrictEqual({
constraintName: 'some_check_name',
schema: '',
tableName: 'users',
type: 'delete_check_constraint',
});
expect(statements[1]).toStrictEqual({
data: 'new_check_name;"users"."age" > 10',
schema: '',
tableName: 'users',
type: 'create_check_constraint',
});
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "users" DROP CONSTRAINT "some_check_name";`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "users" ADD CONSTRAINT "new_check_name" CHECK ("users"."age" > 10);`,
);
});
test('alter multiple check constraints', async (t) => {
const from = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
name: varchar('name'),
}, (table) => ({
checkConstraint1: check('some_check_name_1', sql`${table.age} > 21`),
checkConstraint2: check('some_check_name_2', sql`${table.name} != 'Alex'`),
})),
};
const to = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
name: varchar('name'),
}, (table) => ({
checkConstraint1: check('some_check_name_3', sql`${table.age} > 21`),
checkConstraint2: check('some_check_name_4', sql`${table.name} != 'Alex'`),
})),
};
const { sqlStatements, statements } = await diffTestSchemas(from, to, []);
expect(statements.length).toBe(4);
expect(statements[0]).toStrictEqual({
constraintName: 'some_check_name_1',
schema: '',
tableName: 'users',
type: 'delete_check_constraint',
});
expect(statements[1]).toStrictEqual({
constraintName: 'some_check_name_2',
schema: '',
tableName: 'users',
type: 'delete_check_constraint',
});
expect(statements[2]).toStrictEqual({
data: 'some_check_name_3;"users"."age" > 21',
schema: '',
tableName: 'users',
type: 'create_check_constraint',
});
expect(statements[3]).toStrictEqual({
data: 'some_check_name_4;"users"."name" != \'Alex\'',
schema: '',
tableName: 'users',
type: 'create_check_constraint',
});
expect(sqlStatements.length).toBe(4);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "users" DROP CONSTRAINT "some_check_name_1";`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "users" DROP CONSTRAINT "some_check_name_2";`,
);
expect(sqlStatements[2]).toBe(
`ALTER TABLE "users" ADD CONSTRAINT "some_check_name_3" CHECK ("users"."age" > 21);`,
);
expect(sqlStatements[3]).toBe(
`ALTER TABLE "users" ADD CONSTRAINT "some_check_name_4" CHECK ("users"."name" != \'Alex\');`,
);
});
test('create checks with same names', async (t) => {
const to = {
users: pgTable('users', {
id: serial('id').primaryKey(),
age: integer('age'),
name: varchar('name'),
}, (table) => ({
checkConstraint1: check('some_check_name', sql`${table.age} > 21`),
checkConstraint2: check('some_check_name', sql`${table.name} != 'Alex'`),
})),
};
await expect(diffTestSchemas({}, to, [])).rejects.toThrowError();
});