feat: sql-tools overrides (#19796)

This commit is contained in:
Jason Rasmussen
2025-07-08 08:17:40 -04:00
committed by GitHub
parent 1f9813a28e
commit df4a27e8a7
114 changed files with 775 additions and 289 deletions

View File

@@ -1,11 +1,14 @@
import { BaseContext } from 'src/sql-tools/contexts/base-context';
import { transformColumns } from 'src/sql-tools/transformers/column.transformer';
import { describe, expect, it } from 'vitest';
const ctx = new BaseContext({});
describe(transformColumns.name, () => {
describe('ColumnAdd', () => {
it('should work', () => {
expect(
transformColumns({
transformColumns(ctx, {
type: 'ColumnAdd',
column: {
name: 'column1',
@@ -22,7 +25,7 @@ describe(transformColumns.name, () => {
it('should add a nullable column', () => {
expect(
transformColumns({
transformColumns(ctx, {
type: 'ColumnAdd',
column: {
name: 'column1',
@@ -39,7 +42,7 @@ describe(transformColumns.name, () => {
it('should add a column with an enum type', () => {
expect(
transformColumns({
transformColumns(ctx, {
type: 'ColumnAdd',
column: {
name: 'column1',
@@ -57,7 +60,7 @@ describe(transformColumns.name, () => {
it('should add a column that is an array type', () => {
expect(
transformColumns({
transformColumns(ctx, {
type: 'ColumnAdd',
column: {
name: 'column1',
@@ -76,7 +79,7 @@ describe(transformColumns.name, () => {
describe('ColumnAlter', () => {
it('should make a column nullable', () => {
expect(
transformColumns({
transformColumns(ctx, {
type: 'ColumnAlter',
tableName: 'table1',
columnName: 'column1',
@@ -88,7 +91,7 @@ describe(transformColumns.name, () => {
it('should make a column non-nullable', () => {
expect(
transformColumns({
transformColumns(ctx, {
type: 'ColumnAlter',
tableName: 'table1',
columnName: 'column1',
@@ -100,7 +103,7 @@ describe(transformColumns.name, () => {
it('should update the default value', () => {
expect(
transformColumns({
transformColumns(ctx, {
type: 'ColumnAlter',
tableName: 'table1',
columnName: 'column1',
@@ -114,7 +117,7 @@ describe(transformColumns.name, () => {
describe('ColumnDrop', () => {
it('should work', () => {
expect(
transformColumns({
transformColumns(ctx, {
type: 'ColumnDrop',
tableName: 'table1',
columnName: 'column1',

View File

@@ -1,8 +1,8 @@
import { asColumnComment, getColumnModifiers, getColumnType } from 'src/sql-tools/helpers';
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { ColumnChanges, DatabaseColumn, SchemaDiff } from 'src/sql-tools/types';
import { ColumnChanges, DatabaseColumn } from 'src/sql-tools/types';
export const transformColumns: SqlTransformer = (item: SchemaDiff) => {
export const transformColumns: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'ColumnAdd': {
return asColumnAdd(item.column);

View File

@@ -1,13 +1,16 @@
import { BaseContext } from 'src/sql-tools/contexts/base-context';
import { transformConstraints } from 'src/sql-tools/transformers/constraint.transformer';
import { ConstraintType } from 'src/sql-tools/types';
import { describe, expect, it } from 'vitest';
const ctx = new BaseContext({});
describe(transformConstraints.name, () => {
describe('ConstraintAdd', () => {
describe('primary keys', () => {
it('should work', () => {
expect(
transformConstraints({
transformConstraints(ctx, {
type: 'ConstraintAdd',
constraint: {
type: ConstraintType.PRIMARY_KEY,
@@ -25,7 +28,7 @@ describe(transformConstraints.name, () => {
describe('foreign keys', () => {
it('should work', () => {
expect(
transformConstraints({
transformConstraints(ctx, {
type: 'ConstraintAdd',
constraint: {
type: ConstraintType.FOREIGN_KEY,
@@ -47,7 +50,7 @@ describe(transformConstraints.name, () => {
describe('unique', () => {
it('should work', () => {
expect(
transformConstraints({
transformConstraints(ctx, {
type: 'ConstraintAdd',
constraint: {
type: ConstraintType.UNIQUE,
@@ -65,7 +68,7 @@ describe(transformConstraints.name, () => {
describe('check', () => {
it('should work', () => {
expect(
transformConstraints({
transformConstraints(ctx, {
type: 'ConstraintAdd',
constraint: {
type: ConstraintType.CHECK,
@@ -84,7 +87,7 @@ describe(transformConstraints.name, () => {
describe('ConstraintDrop', () => {
it('should work', () => {
expect(
transformConstraints({
transformConstraints(ctx, {
type: 'ConstraintDrop',
tableName: 'table1',
constraintName: 'PK_test',

View File

@@ -1,8 +1,8 @@
import { asColumnList } from 'src/sql-tools/helpers';
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { ActionType, ConstraintType, DatabaseConstraint, SchemaDiff } from 'src/sql-tools/types';
import { ActionType, ConstraintType, DatabaseConstraint } from 'src/sql-tools/types';
export const transformConstraints: SqlTransformer = (item: SchemaDiff) => {
export const transformConstraints: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'ConstraintAdd': {
return asConstraintAdd(item.constraint);

View File

@@ -1,7 +1,7 @@
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { DatabaseEnum, SchemaDiff } from 'src/sql-tools/types';
import { DatabaseEnum } from 'src/sql-tools/types';
export const transformEnums: SqlTransformer = (item: SchemaDiff) => {
export const transformEnums: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'EnumCreate': {
return asEnumCreate(item.enum);

View File

@@ -1,11 +1,14 @@
import { BaseContext } from 'src/sql-tools/contexts/base-context';
import { transformExtensions } from 'src/sql-tools/transformers/extension.transformer';
import { describe, expect, it } from 'vitest';
const ctx = new BaseContext({});
describe(transformExtensions.name, () => {
describe('ExtensionDrop', () => {
it('should work', () => {
expect(
transformExtensions({
transformExtensions(ctx, {
type: 'ExtensionDrop',
extensionName: 'cube',
reason: 'unknown',
@@ -17,7 +20,7 @@ describe(transformExtensions.name, () => {
describe('ExtensionCreate', () => {
it('should work', () => {
expect(
transformExtensions({
transformExtensions(ctx, {
type: 'ExtensionCreate',
extension: {
name: 'cube',

View File

@@ -1,7 +1,7 @@
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { DatabaseExtension, SchemaDiff } from 'src/sql-tools/types';
import { DatabaseExtension } from 'src/sql-tools/types';
export const transformExtensions: SqlTransformer = (item: SchemaDiff) => {
export const transformExtensions: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'ExtensionCreate': {
return asExtensionCreate(item.extension);

View File

@@ -1,11 +1,14 @@
import { BaseContext } from 'src/sql-tools/contexts/base-context';
import { transformFunctions } from 'src/sql-tools/transformers/function.transformer';
import { describe, expect, it } from 'vitest';
const ctx = new BaseContext({});
describe(transformFunctions.name, () => {
describe('FunctionDrop', () => {
it('should work', () => {
expect(
transformFunctions({
transformFunctions(ctx, {
type: 'FunctionDrop',
functionName: 'test_func',
reason: 'unknown',

View File

@@ -1,7 +1,7 @@
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { DatabaseFunction, SchemaDiff } from 'src/sql-tools/types';
import { DatabaseFunction } from 'src/sql-tools/types';
export const transformFunctions: SqlTransformer = (item: SchemaDiff) => {
export const transformFunctions: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'FunctionCreate': {
return asFunctionCreate(item.function);
@@ -17,7 +17,7 @@ export const transformFunctions: SqlTransformer = (item: SchemaDiff) => {
}
};
const asFunctionCreate = (func: DatabaseFunction): string => {
export const asFunctionCreate = (func: DatabaseFunction): string => {
return func.expression;
};

View File

@@ -1,11 +1,14 @@
import { BaseContext } from 'src/sql-tools/contexts/base-context';
import { transformIndexes } from 'src/sql-tools/transformers/index.transformer';
import { describe, expect, it } from 'vitest';
const ctx = new BaseContext({});
describe(transformIndexes.name, () => {
describe('IndexCreate', () => {
it('should work', () => {
expect(
transformIndexes({
transformIndexes(ctx, {
type: 'IndexCreate',
index: {
name: 'IDX_test',
@@ -21,7 +24,7 @@ describe(transformIndexes.name, () => {
it('should create an unique index', () => {
expect(
transformIndexes({
transformIndexes(ctx, {
type: 'IndexCreate',
index: {
name: 'IDX_test',
@@ -37,7 +40,7 @@ describe(transformIndexes.name, () => {
it('should create an index with a custom expression', () => {
expect(
transformIndexes({
transformIndexes(ctx, {
type: 'IndexCreate',
index: {
name: 'IDX_test',
@@ -53,7 +56,7 @@ describe(transformIndexes.name, () => {
it('should create an index with a where clause', () => {
expect(
transformIndexes({
transformIndexes(ctx, {
type: 'IndexCreate',
index: {
name: 'IDX_test',
@@ -70,7 +73,7 @@ describe(transformIndexes.name, () => {
it('should create an index with a custom expression', () => {
expect(
transformIndexes({
transformIndexes(ctx, {
type: 'IndexCreate',
index: {
name: 'IDX_test',
@@ -89,7 +92,7 @@ describe(transformIndexes.name, () => {
describe('IndexDrop', () => {
it('should work', () => {
expect(
transformIndexes({
transformIndexes(ctx, {
type: 'IndexDrop',
indexName: 'IDX_test',
reason: 'unknown',

View File

@@ -1,8 +1,8 @@
import { asColumnList } from 'src/sql-tools/helpers';
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { DatabaseIndex, SchemaDiff } from 'src/sql-tools/types';
import { DatabaseIndex } from 'src/sql-tools/types';
export const transformIndexes: SqlTransformer = (item: SchemaDiff) => {
export const transformIndexes: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'IndexCreate': {
return asIndexCreate(item.index);

View File

@@ -4,6 +4,7 @@ import { transformEnums } from 'src/sql-tools/transformers/enum.transformer';
import { transformExtensions } from 'src/sql-tools/transformers/extension.transformer';
import { transformFunctions } from 'src/sql-tools/transformers/function.transformer';
import { transformIndexes } from 'src/sql-tools/transformers/index.transformer';
import { transformOverrides } from 'src/sql-tools/transformers/override.transformer';
import { transformParameters } from 'src/sql-tools/transformers/parameter.transformer';
import { transformTables } from 'src/sql-tools/transformers/table.transformer';
import { transformTriggers } from 'src/sql-tools/transformers/trigger.transformer';
@@ -19,4 +20,5 @@ export const transformers: SqlTransformer[] = [
transformParameters,
transformTables,
transformTriggers,
transformOverrides,
];

View File

@@ -0,0 +1,37 @@
import { asJsonString } from 'src/sql-tools/helpers';
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { DatabaseOverride } from 'src/sql-tools/types';
export const transformOverrides: SqlTransformer = (ctx, item) => {
const tableName = ctx.overrideTableName;
switch (item.type) {
case 'OverrideCreate': {
return asOverrideCreate(tableName, item.override);
}
case 'OverrideUpdate': {
return asOverrideUpdate(tableName, item.override);
}
case 'OverrideDrop': {
return asOverrideDrop(tableName, item.overrideName);
}
default: {
return false;
}
}
};
export const asOverrideCreate = (tableName: string, override: DatabaseOverride): string => {
return `INSERT INTO "${tableName}" ("name", "value") VALUES ('${override.name}', ${asJsonString(override.value)});`;
};
export const asOverrideUpdate = (tableName: string, override: DatabaseOverride): string => {
return `UPDATE "${tableName}" SET "value" = ${asJsonString(override.value)} WHERE "name" = '${override.name}';`;
};
export const asOverrideDrop = (tableName: string, overrideName: string): string => {
return `DELETE FROM "${tableName}" WHERE "name" = '${overrideName}';`;
};

View File

@@ -1,7 +1,7 @@
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { DatabaseParameter, SchemaDiff } from 'src/sql-tools/types';
import { DatabaseParameter } from 'src/sql-tools/types';
export const transformParameters: SqlTransformer = (item: SchemaDiff) => {
export const transformParameters: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'ParameterSet': {
return asParameterSet(item.parameter);

View File

@@ -1,11 +1,14 @@
import { BaseContext } from 'src/sql-tools/contexts/base-context';
import { transformTables } from 'src/sql-tools/transformers/table.transformer';
import { describe, expect, it } from 'vitest';
const ctx = new BaseContext({});
describe(transformTables.name, () => {
describe('TableDrop', () => {
it('should work', () => {
expect(
transformTables({
transformTables(ctx, {
type: 'TableDrop',
tableName: 'table1',
reason: 'unknown',
@@ -17,7 +20,7 @@ describe(transformTables.name, () => {
describe('TableCreate', () => {
it('should work', () => {
expect(
transformTables({
transformTables(ctx, {
type: 'TableCreate',
table: {
name: 'table1',
@@ -43,7 +46,7 @@ describe(transformTables.name, () => {
it('should handle a non-nullable column', () => {
expect(
transformTables({
transformTables(ctx, {
type: 'TableCreate',
table: {
name: 'table1',
@@ -69,7 +72,7 @@ describe(transformTables.name, () => {
it('should handle a default value', () => {
expect(
transformTables({
transformTables(ctx, {
type: 'TableCreate',
table: {
name: 'table1',
@@ -96,7 +99,7 @@ describe(transformTables.name, () => {
it('should handle a string with a fixed length', () => {
expect(
transformTables({
transformTables(ctx, {
type: 'TableCreate',
table: {
name: 'table1',
@@ -123,7 +126,7 @@ describe(transformTables.name, () => {
it('should handle an array type', () => {
expect(
transformTables({
transformTables(ctx, {
type: 'TableCreate',
table: {
name: 'table1',

View File

@@ -1,9 +1,9 @@
import { asColumnComment, getColumnModifiers, getColumnType } from 'src/sql-tools/helpers';
import { asColumnAlter } from 'src/sql-tools/transformers/column.transformer';
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { DatabaseTable, SchemaDiff } from 'src/sql-tools/types';
import { DatabaseTable } from 'src/sql-tools/types';
export const transformTables: SqlTransformer = (item: SchemaDiff) => {
export const transformTables: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'TableCreate': {
return asTableCreate(item.table);

View File

@@ -1,11 +1,14 @@
import { BaseContext } from 'src/sql-tools/contexts/base-context';
import { transformTriggers } from 'src/sql-tools/transformers/trigger.transformer';
import { describe, expect, it } from 'vitest';
const ctx = new BaseContext({});
describe(transformTriggers.name, () => {
describe('TriggerCreate', () => {
it('should work', () => {
expect(
transformTriggers({
transformTriggers(ctx, {
type: 'TriggerCreate',
trigger: {
name: 'trigger1',
@@ -28,7 +31,7 @@ describe(transformTriggers.name, () => {
it('should work with multiple actions', () => {
expect(
transformTriggers({
transformTriggers(ctx, {
type: 'TriggerCreate',
trigger: {
name: 'trigger1',
@@ -51,7 +54,7 @@ describe(transformTriggers.name, () => {
it('should work with old/new reference table aliases', () => {
expect(
transformTriggers({
transformTriggers(ctx, {
type: 'TriggerCreate',
trigger: {
name: 'trigger1',
@@ -79,7 +82,7 @@ describe(transformTriggers.name, () => {
describe('TriggerDrop', () => {
it('should work', () => {
expect(
transformTriggers({
transformTriggers(ctx, {
type: 'TriggerDrop',
tableName: 'table1',
triggerName: 'trigger1',

View File

@@ -1,7 +1,7 @@
import { SqlTransformer } from 'src/sql-tools/transformers/types';
import { DatabaseTrigger, SchemaDiff } from 'src/sql-tools/types';
import { DatabaseTrigger } from 'src/sql-tools/types';
export const transformTriggers: SqlTransformer = (item: SchemaDiff) => {
export const transformTriggers: SqlTransformer = (ctx, item) => {
switch (item.type) {
case 'TriggerCreate': {
return asTriggerCreate(item.trigger);

View File

@@ -1,3 +1,4 @@
import { BaseContext } from 'src/sql-tools/contexts/base-context';
import { SchemaDiff } from 'src/sql-tools/types';
export type SqlTransformer = (item: SchemaDiff) => string | string[] | false;
export type SqlTransformer = (ctx: BaseContext, item: SchemaDiff) => string | string[] | false;