554 lines
15 KiB
TypeScript
554 lines
15 KiB
TypeScript
import { sql } from 'drizzle-orm';
|
|
import { int, mysqlTable, mysqlView } from 'drizzle-orm/mysql-core';
|
|
import { expect, test } from 'vitest';
|
|
import { diffTestSchemasMysql } from './schemaDiffer';
|
|
|
|
test('create view #1', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view').as((qb) => qb.select().from(users)),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(1);
|
|
expect(statements[0]).toStrictEqual({
|
|
type: 'mysql_create_view',
|
|
name: 'some_view',
|
|
algorithm: 'undefined',
|
|
replace: false,
|
|
definition: 'select `id` from `users`',
|
|
withCheckOption: undefined,
|
|
sqlSecurity: 'definer',
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(1);
|
|
expect(sqlStatements[0]).toBe(`CREATE ALGORITHM = undefined
|
|
SQL SECURITY definer
|
|
VIEW \`some_view\` AS (select \`id\` from \`users\`);`);
|
|
});
|
|
|
|
test('create view #2', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(1);
|
|
expect(statements[0]).toStrictEqual({
|
|
type: 'mysql_create_view',
|
|
name: 'some_view',
|
|
algorithm: 'merge',
|
|
replace: false,
|
|
definition: 'SELECT * FROM \`users\`',
|
|
withCheckOption: 'cascaded',
|
|
sqlSecurity: 'definer',
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(1);
|
|
expect(sqlStatements[0]).toBe(`CREATE ALGORITHM = merge
|
|
SQL SECURITY definer
|
|
VIEW \`some_view\` AS (SELECT * FROM \`users\`)
|
|
WITH cascaded CHECK OPTION;`);
|
|
});
|
|
|
|
test('create view with existing flag', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).existing(),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(0);
|
|
expect(sqlStatements.length).toBe(0);
|
|
});
|
|
|
|
test('drop view', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(1);
|
|
expect(statements[0]).toStrictEqual({
|
|
type: 'drop_view',
|
|
name: 'some_view',
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(1);
|
|
expect(sqlStatements[0]).toBe(`DROP VIEW \`some_view\`;`);
|
|
});
|
|
|
|
test('drop view with existing flag', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(0);
|
|
expect(sqlStatements.length).toBe(0);
|
|
});
|
|
|
|
test('rename view', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('new_some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, [
|
|
'public.some_view->public.new_some_view',
|
|
]);
|
|
|
|
expect(statements.length).toBe(1);
|
|
expect(statements[0]).toStrictEqual({
|
|
type: 'rename_view',
|
|
nameFrom: 'some_view',
|
|
nameTo: 'new_some_view',
|
|
});
|
|
expect(sqlStatements.length).toBe(1);
|
|
expect(sqlStatements[0]).toBe(`RENAME TABLE \`some_view\` TO \`new_some_view\`;`);
|
|
});
|
|
|
|
test('rename view and alter meta options', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('new_some_view', {}).sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, [
|
|
'public.some_view->public.new_some_view',
|
|
]);
|
|
|
|
expect(statements.length).toBe(2);
|
|
expect(statements[0]).toStrictEqual({
|
|
type: 'rename_view',
|
|
nameFrom: 'some_view',
|
|
nameTo: 'new_some_view',
|
|
});
|
|
expect(statements[1]).toStrictEqual({
|
|
algorithm: 'undefined',
|
|
columns: {},
|
|
definition: 'SELECT * FROM `users`',
|
|
isExisting: false,
|
|
name: 'new_some_view',
|
|
sqlSecurity: 'definer',
|
|
type: 'alter_mysql_view',
|
|
withCheckOption: 'cascaded',
|
|
});
|
|
expect(sqlStatements.length).toBe(2);
|
|
expect(sqlStatements[0]).toBe(`RENAME TABLE \`some_view\` TO \`new_some_view\`;`);
|
|
expect(sqlStatements[1]).toBe(`ALTER ALGORITHM = undefined
|
|
SQL SECURITY definer
|
|
VIEW \`new_some_view\` AS SELECT * FROM \`users\`
|
|
WITH cascaded CHECK OPTION;`);
|
|
});
|
|
|
|
test('rename view with existing flag', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('new_some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, [
|
|
'public.some_view->public.new_some_view',
|
|
]);
|
|
|
|
expect(statements.length).toBe(0);
|
|
expect(sqlStatements.length).toBe(0);
|
|
});
|
|
|
|
test('add meta to view', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(1);
|
|
expect(statements[0]).toStrictEqual({
|
|
algorithm: 'merge',
|
|
columns: {},
|
|
definition: 'SELECT * FROM `users`',
|
|
isExisting: false,
|
|
name: 'some_view',
|
|
sqlSecurity: 'definer',
|
|
type: 'alter_mysql_view',
|
|
withCheckOption: 'cascaded',
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(1);
|
|
expect(sqlStatements[0]).toBe(`ALTER ALGORITHM = merge
|
|
SQL SECURITY definer
|
|
VIEW \`some_view\` AS SELECT * FROM \`users\`
|
|
WITH cascaded CHECK OPTION;`);
|
|
});
|
|
|
|
test('add meta to view with existing flag', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).existing(),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(0);
|
|
expect(sqlStatements.length).toBe(0);
|
|
});
|
|
|
|
test('alter meta to view', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(1);
|
|
expect(statements[0]).toStrictEqual({
|
|
algorithm: 'merge',
|
|
columns: {},
|
|
definition: 'SELECT * FROM `users`',
|
|
isExisting: false,
|
|
name: 'some_view',
|
|
sqlSecurity: 'definer',
|
|
type: 'alter_mysql_view',
|
|
withCheckOption: 'cascaded',
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(1);
|
|
expect(sqlStatements[0]).toBe(`ALTER ALGORITHM = merge
|
|
SQL SECURITY definer
|
|
VIEW \`some_view\` AS SELECT * FROM \`users\`
|
|
WITH cascaded CHECK OPTION;`);
|
|
});
|
|
|
|
test('alter meta to view with existing flag', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(0);
|
|
expect(sqlStatements.length).toBe(0);
|
|
});
|
|
|
|
test('drop meta from view', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(1);
|
|
expect(statements[0]).toStrictEqual({
|
|
algorithm: 'undefined',
|
|
columns: {},
|
|
definition: 'SELECT * FROM `users`',
|
|
isExisting: false,
|
|
name: 'some_view',
|
|
sqlSecurity: 'definer',
|
|
type: 'alter_mysql_view',
|
|
withCheckOption: undefined,
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(1);
|
|
expect(sqlStatements[0]).toBe(`ALTER ALGORITHM = undefined
|
|
SQL SECURITY definer
|
|
VIEW \`some_view\` AS SELECT * FROM \`users\`;`);
|
|
});
|
|
|
|
test('drop meta from view existing flag', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
|
|
view: mysqlView('some_view', {}).algorithm('merge').sqlSecurity('definer')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).existing(),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(0);
|
|
expect(sqlStatements.length).toBe(0);
|
|
});
|
|
|
|
test('alter view ".as" value', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users} WHERE ${users.id} = 1`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []);
|
|
|
|
expect(statements.length).toBe(1);
|
|
expect(statements[0]).toStrictEqual({
|
|
algorithm: 'temptable',
|
|
definition: 'SELECT * FROM `users` WHERE `users`.`id` = 1',
|
|
name: 'some_view',
|
|
sqlSecurity: 'invoker',
|
|
type: 'mysql_create_view',
|
|
withCheckOption: 'cascaded',
|
|
replace: true,
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(1);
|
|
expect(sqlStatements[0]).toBe(`CREATE OR REPLACE ALGORITHM = temptable
|
|
SQL SECURITY invoker
|
|
VIEW \`some_view\` AS (SELECT * FROM \`users\` WHERE \`users\`.\`id\` = 1)
|
|
WITH cascaded CHECK OPTION;`);
|
|
});
|
|
|
|
test('rename and alter view ".as" value', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('new_some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users} WHERE ${users.id} = 1`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, [
|
|
'public.some_view->public.new_some_view',
|
|
]);
|
|
|
|
expect(statements.length).toBe(2);
|
|
expect(statements[0]).toStrictEqual({
|
|
nameFrom: 'some_view',
|
|
nameTo: 'new_some_view',
|
|
type: 'rename_view',
|
|
});
|
|
expect(statements[1]).toStrictEqual({
|
|
algorithm: 'temptable',
|
|
definition: 'SELECT * FROM `users` WHERE `users`.`id` = 1',
|
|
name: 'new_some_view',
|
|
sqlSecurity: 'invoker',
|
|
type: 'mysql_create_view',
|
|
withCheckOption: 'cascaded',
|
|
replace: true,
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(2);
|
|
expect(sqlStatements[0]).toBe(`RENAME TABLE \`some_view\` TO \`new_some_view\`;`);
|
|
expect(sqlStatements[1]).toBe(`CREATE OR REPLACE ALGORITHM = temptable
|
|
SQL SECURITY invoker
|
|
VIEW \`new_some_view\` AS (SELECT * FROM \`users\` WHERE \`users\`.\`id\` = 1)
|
|
WITH cascaded CHECK OPTION;`);
|
|
});
|
|
|
|
test('set existing', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users}`),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('new_some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, [
|
|
'public.some_view->public.new_some_view',
|
|
]);
|
|
|
|
expect(statements.length).toBe(0);
|
|
expect(sqlStatements.length).toBe(0);
|
|
});
|
|
|
|
test('drop existing', async () => {
|
|
const users = mysqlTable('users', {
|
|
id: int('id').primaryKey().notNull(),
|
|
});
|
|
|
|
const from = {
|
|
users: users,
|
|
view: mysqlView('some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').existing(),
|
|
};
|
|
const to = {
|
|
users: users,
|
|
view: mysqlView('new_some_view', {}).algorithm('temptable').sqlSecurity('invoker')
|
|
.withCheckOption('cascaded').as(sql`SELECT * FROM ${users} WHERE ${users.id} = 1`),
|
|
};
|
|
|
|
const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, [
|
|
'public.some_view->public.new_some_view',
|
|
]);
|
|
|
|
expect(statements.length).toBe(2);
|
|
expect(statements[0]).toStrictEqual({
|
|
name: 'new_some_view',
|
|
type: 'drop_view',
|
|
});
|
|
expect(statements[1]).toStrictEqual({
|
|
algorithm: 'temptable',
|
|
definition: 'SELECT * FROM `users` WHERE `users`.`id` = 1',
|
|
name: 'new_some_view',
|
|
sqlSecurity: 'invoker',
|
|
type: 'mysql_create_view',
|
|
withCheckOption: 'cascaded',
|
|
replace: false,
|
|
});
|
|
|
|
expect(sqlStatements.length).toBe(2);
|
|
expect(sqlStatements[0]).toBe(`DROP VIEW \`new_some_view\`;`);
|
|
expect(sqlStatements[1]).toBe(`CREATE ALGORITHM = temptable
|
|
SQL SECURITY invoker
|
|
VIEW \`new_some_view\` AS (SELECT * FROM \`users\` WHERE \`users\`.\`id\` = 1)
|
|
WITH cascaded CHECK OPTION;`);
|
|
});
|