mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:04:16 -04:00
feat(server): sql-tools support for class level composite fk (#19242)
* feat: support for class level composite fk * chore: clean up --------- Co-authored-by: Jason Rasmussen <jason@rasm.me>
This commit is contained in:
parent
de81006367
commit
0a9a520ed2
@ -1,11 +1,10 @@
|
|||||||
import { ColumnBaseOptions } from 'src/sql-tools/from-code/decorators/column.decorator';
|
import { ColumnBaseOptions } from 'src/sql-tools/from-code/decorators/column.decorator';
|
||||||
|
import { ForeignKeyAction } from 'src/sql-tools/from-code/decorators/foreign-key-constraint.decorator';
|
||||||
import { register } from 'src/sql-tools/from-code/register';
|
import { register } from 'src/sql-tools/from-code/register';
|
||||||
|
|
||||||
type Action = 'CASCADE' | 'SET NULL' | 'SET DEFAULT' | 'RESTRICT' | 'NO ACTION';
|
|
||||||
|
|
||||||
export type ForeignKeyColumnOptions = ColumnBaseOptions & {
|
export type ForeignKeyColumnOptions = ColumnBaseOptions & {
|
||||||
onUpdate?: Action;
|
onUpdate?: ForeignKeyAction;
|
||||||
onDelete?: Action;
|
onDelete?: ForeignKeyAction;
|
||||||
constraintName?: string;
|
constraintName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
import { register } from 'src/sql-tools/from-code/register';
|
||||||
|
|
||||||
|
export type ForeignKeyAction = 'CASCADE' | 'SET NULL' | 'SET DEFAULT' | 'RESTRICT' | 'NO ACTION';
|
||||||
|
|
||||||
|
export type ForeignKeyConstraintOptions = {
|
||||||
|
name?: string;
|
||||||
|
index?: boolean;
|
||||||
|
indexName?: string;
|
||||||
|
columns: string[];
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||||
|
referenceTable: () => Function;
|
||||||
|
referenceColumns?: string[];
|
||||||
|
onUpdate?: ForeignKeyAction;
|
||||||
|
onDelete?: ForeignKeyAction;
|
||||||
|
synchronize?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ForeignKeyConstraint = (options: ForeignKeyConstraintOptions): ClassDecorator => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||||
|
return (target: Function) => {
|
||||||
|
register({ type: 'foreignKeyConstraint', item: { object: target, options } });
|
||||||
|
};
|
||||||
|
};
|
@ -5,7 +5,8 @@ import { processConfigurationParameters } from 'src/sql-tools/from-code/processo
|
|||||||
import { processDatabases } from 'src/sql-tools/from-code/processors/database.processor';
|
import { processDatabases } from 'src/sql-tools/from-code/processors/database.processor';
|
||||||
import { processEnums } from 'src/sql-tools/from-code/processors/enum.processor';
|
import { processEnums } from 'src/sql-tools/from-code/processors/enum.processor';
|
||||||
import { processExtensions } from 'src/sql-tools/from-code/processors/extension.processor';
|
import { processExtensions } from 'src/sql-tools/from-code/processors/extension.processor';
|
||||||
import { processForeignKeyConstraints } from 'src/sql-tools/from-code/processors/foreign-key-constriant.processor';
|
import { processForeignKeyColumns } from 'src/sql-tools/from-code/processors/foreign-key-column.processor';
|
||||||
|
import { processForeignKeyConstraints } from 'src/sql-tools/from-code/processors/foreign-key-constraint.processor';
|
||||||
import { processFunctions } from 'src/sql-tools/from-code/processors/function.processor';
|
import { processFunctions } from 'src/sql-tools/from-code/processors/function.processor';
|
||||||
import { processIndexes } from 'src/sql-tools/from-code/processors/index.processor';
|
import { processIndexes } from 'src/sql-tools/from-code/processors/index.processor';
|
||||||
import { processPrimaryKeyConstraints } from 'src/sql-tools/from-code/processors/primary-key-contraint.processor';
|
import { processPrimaryKeyConstraints } from 'src/sql-tools/from-code/processors/primary-key-contraint.processor';
|
||||||
@ -32,10 +33,11 @@ const processors: Processor[] = [
|
|||||||
processFunctions,
|
processFunctions,
|
||||||
processTables,
|
processTables,
|
||||||
processColumns,
|
processColumns,
|
||||||
|
processForeignKeyColumns,
|
||||||
|
processForeignKeyConstraints,
|
||||||
processUniqueConstraints,
|
processUniqueConstraints,
|
||||||
processCheckConstraints,
|
processCheckConstraints,
|
||||||
processPrimaryKeyConstraints,
|
processPrimaryKeyConstraints,
|
||||||
processForeignKeyConstraints,
|
|
||||||
processIndexes,
|
processIndexes,
|
||||||
processTriggers,
|
processTriggers,
|
||||||
];
|
];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ColumnOptions } from 'src/sql-tools/from-code/decorators/column.decorator';
|
import { ColumnOptions } from 'src/sql-tools/from-code/decorators/column.decorator';
|
||||||
import { onMissingTable, resolveTable } from 'src/sql-tools/from-code/processors/table.processor';
|
import { onMissingTable, resolveTable } from 'src/sql-tools/from-code/processors/table.processor';
|
||||||
import { Processor, SchemaBuilder } from 'src/sql-tools/from-code/processors/type';
|
import { Processor, SchemaBuilder } from 'src/sql-tools/from-code/processors/type';
|
||||||
import { asMetadataKey, fromColumnValue } from 'src/sql-tools/helpers';
|
import { addWarning, asMetadataKey, fromColumnValue } from 'src/sql-tools/helpers';
|
||||||
import { DatabaseColumn } from 'src/sql-tools/types';
|
import { DatabaseColumn } from 'src/sql-tools/types';
|
||||||
|
|
||||||
export const processColumns: Processor = (builder, items) => {
|
export const processColumns: Processor = (builder, items) => {
|
||||||
@ -81,7 +81,7 @@ export const onMissingColumn = (
|
|||||||
propertyName?: symbol | string,
|
propertyName?: symbol | string,
|
||||||
) => {
|
) => {
|
||||||
const label = object.constructor.name + (propertyName ? '.' + String(propertyName) : '');
|
const label = object.constructor.name + (propertyName ? '.' + String(propertyName) : '');
|
||||||
builder.warnings.push(`[${context}] Unable to find column (${label})`);
|
addWarning(builder, context, `Unable to find column (${label})`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const METADATA_KEY = asMetadataKey('table-metadata');
|
const METADATA_KEY = asMetadataKey('table-metadata');
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { onMissingColumn, resolveColumn } from 'src/sql-tools/from-code/processors/column.processor';
|
import { onMissingColumn, resolveColumn } from 'src/sql-tools/from-code/processors/column.processor';
|
||||||
import { onMissingTable, resolveTable } from 'src/sql-tools/from-code/processors/table.processor';
|
import { onMissingTable, resolveTable } from 'src/sql-tools/from-code/processors/table.processor';
|
||||||
import { Processor } from 'src/sql-tools/from-code/processors/type';
|
import { Processor } from 'src/sql-tools/from-code/processors/type';
|
||||||
import { asKey } from 'src/sql-tools/helpers';
|
import { asForeignKeyConstraintName, asKey } from 'src/sql-tools/helpers';
|
||||||
import { DatabaseActionType, DatabaseConstraintType } from 'src/sql-tools/types';
|
import { DatabaseActionType, DatabaseConstraintType } from 'src/sql-tools/types';
|
||||||
|
|
||||||
export const processForeignKeyConstraints: Processor = (builder, items) => {
|
export const processForeignKeyColumns: Processor = (builder, items) => {
|
||||||
for (const {
|
for (const {
|
||||||
item: { object, propertyName, options, target },
|
item: { object, propertyName, options, target },
|
||||||
} of items.filter((item) => item.type === 'foreignKeyColumn')) {
|
} of items.filter((item) => item.type === 'foreignKeyColumn')) {
|
||||||
@ -34,13 +34,16 @@ export const processForeignKeyConstraints: Processor = (builder, items) => {
|
|||||||
column.type = referenceColumns[0].type;
|
column.type = referenceColumns[0].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const referenceColumnNames = referenceColumns.map((column) => column.name);
|
||||||
|
const name = options.constraintName || asForeignKeyConstraintName(table.name, columnNames);
|
||||||
|
|
||||||
table.constraints.push({
|
table.constraints.push({
|
||||||
name: options.constraintName || asForeignKeyConstraintName(table.name, columnNames),
|
name,
|
||||||
tableName: table.name,
|
tableName: table.name,
|
||||||
columnNames,
|
columnNames,
|
||||||
type: DatabaseConstraintType.FOREIGN_KEY,
|
type: DatabaseConstraintType.FOREIGN_KEY,
|
||||||
referenceTableName: referenceTable.name,
|
referenceTableName: referenceTable.name,
|
||||||
referenceColumnNames: referenceColumns.map((column) => column.name),
|
referenceColumnNames,
|
||||||
onUpdate: options.onUpdate as DatabaseActionType,
|
onUpdate: options.onUpdate as DatabaseActionType,
|
||||||
onDelete: options.onDelete as DatabaseActionType,
|
onDelete: options.onDelete as DatabaseActionType,
|
||||||
synchronize: options.synchronize ?? true,
|
synchronize: options.synchronize ?? true,
|
||||||
@ -58,5 +61,4 @@ export const processForeignKeyConstraints: Processor = (builder, items) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const asForeignKeyConstraintName = (table: string, columns: string[]) => asKey('FK_', table, columns);
|
|
||||||
const asRelationKeyConstraintName = (table: string, columns: string[]) => asKey('REL_', table, columns);
|
const asRelationKeyConstraintName = (table: string, columns: string[]) => asKey('REL_', table, columns);
|
@ -0,0 +1,86 @@
|
|||||||
|
import { onMissingTable, resolveTable } from 'src/sql-tools/from-code/processors/table.processor';
|
||||||
|
import { Processor } from 'src/sql-tools/from-code/processors/type';
|
||||||
|
import { addWarning, asForeignKeyConstraintName, asIndexName } from 'src/sql-tools/helpers';
|
||||||
|
import { DatabaseActionType, DatabaseConstraintType } from 'src/sql-tools/types';
|
||||||
|
|
||||||
|
export const processForeignKeyConstraints: Processor = (builder, items, config) => {
|
||||||
|
for (const {
|
||||||
|
item: { object, options },
|
||||||
|
} of items.filter((item) => item.type === 'foreignKeyConstraint')) {
|
||||||
|
const table = resolveTable(builder, object);
|
||||||
|
if (!table) {
|
||||||
|
onMissingTable(builder, '@ForeignKeyConstraint', { name: 'referenceTable' });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const referenceTable = resolveTable(builder, options.referenceTable());
|
||||||
|
if (!referenceTable) {
|
||||||
|
const referenceTableName = options.referenceTable()?.name;
|
||||||
|
addWarning(
|
||||||
|
builder,
|
||||||
|
'@ForeignKeyConstraint.referenceTable',
|
||||||
|
`Unable to find table` + (referenceTableName ? ` (${referenceTableName})` : ''),
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let missingColumn = false;
|
||||||
|
|
||||||
|
for (const columnName of options.columns) {
|
||||||
|
if (!table.columns.some(({ name }) => name === columnName)) {
|
||||||
|
addWarning(
|
||||||
|
builder,
|
||||||
|
'@ForeignKeyConstraint.columns',
|
||||||
|
`Unable to find column (${table.metadata.object.name}.${columnName})`,
|
||||||
|
);
|
||||||
|
missingColumn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const columnName of options.referenceColumns || []) {
|
||||||
|
if (!referenceTable.columns.some(({ name }) => name === columnName)) {
|
||||||
|
addWarning(
|
||||||
|
builder,
|
||||||
|
'@ForeignKeyConstraint.referenceColumns',
|
||||||
|
`Unable to find column (${referenceTable.metadata.object.name}.${columnName})`,
|
||||||
|
);
|
||||||
|
missingColumn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingColumn) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const referenceColumns =
|
||||||
|
options.referenceColumns || referenceTable.columns.filter(({ primary }) => primary).map(({ name }) => name);
|
||||||
|
|
||||||
|
const name = options.name || asForeignKeyConstraintName(table.name, options.columns);
|
||||||
|
|
||||||
|
table.constraints.push({
|
||||||
|
type: DatabaseConstraintType.FOREIGN_KEY,
|
||||||
|
name,
|
||||||
|
tableName: table.name,
|
||||||
|
columnNames: options.columns,
|
||||||
|
referenceTableName: referenceTable.name,
|
||||||
|
referenceColumnNames: referenceColumns,
|
||||||
|
onUpdate: options.onUpdate as DatabaseActionType,
|
||||||
|
onDelete: options.onDelete as DatabaseActionType,
|
||||||
|
synchronize: options.synchronize ?? true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (options.index === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.index || options.indexName || config.createForeignKeyIndexes) {
|
||||||
|
table.indexes.push({
|
||||||
|
name: options.indexName || asIndexName(table.name, options.columns),
|
||||||
|
tableName: table.name,
|
||||||
|
columnNames: options.columns,
|
||||||
|
unique: false,
|
||||||
|
synchronize: options.synchronize ?? true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
import { onMissingColumn, resolveColumn } from 'src/sql-tools/from-code/processors/column.processor';
|
import { onMissingColumn, resolveColumn } from 'src/sql-tools/from-code/processors/column.processor';
|
||||||
import { onMissingTable, resolveTable } from 'src/sql-tools/from-code/processors/table.processor';
|
import { onMissingTable, resolveTable } from 'src/sql-tools/from-code/processors/table.processor';
|
||||||
import { Processor } from 'src/sql-tools/from-code/processors/type';
|
import { Processor } from 'src/sql-tools/from-code/processors/type';
|
||||||
import { asKey } from 'src/sql-tools/helpers';
|
import { asIndexName } from 'src/sql-tools/helpers';
|
||||||
|
|
||||||
export const processIndexes: Processor = (builder, items, config) => {
|
export const processIndexes: Processor = (builder, items, config) => {
|
||||||
for (const {
|
for (const {
|
||||||
@ -75,16 +75,3 @@ export const processIndexes: Processor = (builder, items, config) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const asIndexName = (table: string, columns?: string[], where?: string) => {
|
|
||||||
const items: string[] = [];
|
|
||||||
for (const columnName of columns ?? []) {
|
|
||||||
items.push(columnName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (where) {
|
|
||||||
items.push(where);
|
|
||||||
}
|
|
||||||
|
|
||||||
return asKey('IDX_', table, items);
|
|
||||||
};
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { TableOptions } from 'src/sql-tools/from-code/decorators/table.decorator';
|
import { TableOptions } from 'src/sql-tools/from-code/decorators/table.decorator';
|
||||||
import { Processor, SchemaBuilder } from 'src/sql-tools/from-code/processors/type';
|
import { Processor, SchemaBuilder } from 'src/sql-tools/from-code/processors/type';
|
||||||
import { asMetadataKey, asSnakeCase } from 'src/sql-tools/helpers';
|
import { addWarning, asMetadataKey, asSnakeCase } from 'src/sql-tools/helpers';
|
||||||
|
|
||||||
export const processTables: Processor = (builder, items) => {
|
export const processTables: Processor = (builder, items) => {
|
||||||
for (const {
|
for (const {
|
||||||
@ -45,7 +45,7 @@ export const onMissingTable = (
|
|||||||
propertyName?: symbol | string,
|
propertyName?: symbol | string,
|
||||||
) => {
|
) => {
|
||||||
const label = object.constructor.name + (propertyName ? '.' + String(propertyName) : '');
|
const label = object.constructor.name + (propertyName ? '.' + String(propertyName) : '');
|
||||||
builder.warnings.push(`[${context}] Unable to find table (${label})`);
|
addWarning(builder, context, `Unable to find table (${label})`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const METADATA_KEY = asMetadataKey('table-metadata');
|
const METADATA_KEY = asMetadataKey('table-metadata');
|
||||||
|
@ -4,6 +4,7 @@ import { ConfigurationParameterOptions } from 'src/sql-tools/from-code/decorator
|
|||||||
import { DatabaseOptions } from 'src/sql-tools/from-code/decorators/database.decorator';
|
import { DatabaseOptions } from 'src/sql-tools/from-code/decorators/database.decorator';
|
||||||
import { ExtensionOptions } from 'src/sql-tools/from-code/decorators/extension.decorator';
|
import { ExtensionOptions } from 'src/sql-tools/from-code/decorators/extension.decorator';
|
||||||
import { ForeignKeyColumnOptions } from 'src/sql-tools/from-code/decorators/foreign-key-column.decorator';
|
import { ForeignKeyColumnOptions } from 'src/sql-tools/from-code/decorators/foreign-key-column.decorator';
|
||||||
|
import { ForeignKeyConstraintOptions } from 'src/sql-tools/from-code/decorators/foreign-key-constraint.decorator';
|
||||||
import { IndexOptions } from 'src/sql-tools/from-code/decorators/index.decorator';
|
import { IndexOptions } from 'src/sql-tools/from-code/decorators/index.decorator';
|
||||||
import { TableOptions } from 'src/sql-tools/from-code/decorators/table.decorator';
|
import { TableOptions } from 'src/sql-tools/from-code/decorators/table.decorator';
|
||||||
import { TriggerOptions } from 'src/sql-tools/from-code/decorators/trigger.decorator';
|
import { TriggerOptions } from 'src/sql-tools/from-code/decorators/trigger.decorator';
|
||||||
@ -25,5 +26,6 @@ export type RegisterItem =
|
|||||||
| { type: 'trigger'; item: ClassBased<{ options: TriggerOptions }> }
|
| { type: 'trigger'; item: ClassBased<{ options: TriggerOptions }> }
|
||||||
| { type: 'extension'; item: ClassBased<{ options: ExtensionOptions }> }
|
| { type: 'extension'; item: ClassBased<{ options: ExtensionOptions }> }
|
||||||
| { type: 'configurationParameter'; item: ClassBased<{ options: ConfigurationParameterOptions }> }
|
| { type: 'configurationParameter'; item: ClassBased<{ options: ConfigurationParameterOptions }> }
|
||||||
| { type: 'foreignKeyColumn'; item: PropertyBased<{ options: ForeignKeyColumnOptions; target: () => object }> };
|
| { type: 'foreignKeyColumn'; item: PropertyBased<{ options: ForeignKeyColumnOptions; target: () => object }> }
|
||||||
|
| { type: 'foreignKeyConstraint'; item: ClassBased<{ options: ForeignKeyConstraintOptions }> };
|
||||||
export type RegisterItemType<T extends RegisterItem['type']> = Extract<RegisterItem, { type: T }>['item'];
|
export type RegisterItemType<T extends RegisterItem['type']> = Extract<RegisterItem, { type: T }>['item'];
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { createHash } from 'node:crypto';
|
import { createHash } from 'node:crypto';
|
||||||
import { ColumnValue } from 'src/sql-tools/from-code/decorators/column.decorator';
|
import { ColumnValue } from 'src/sql-tools/from-code/decorators/column.decorator';
|
||||||
|
import { SchemaBuilder } from 'src/sql-tools/from-code/processors/type';
|
||||||
import {
|
import {
|
||||||
Comparer,
|
Comparer,
|
||||||
DatabaseColumn,
|
DatabaseColumn,
|
||||||
@ -211,3 +212,22 @@ export const asColumnComment = (tableName: string, columnName: string, comment:
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const asColumnList = (columns: string[]) => columns.map((column) => `"${column}"`).join(', ');
|
export const asColumnList = (columns: string[]) => columns.map((column) => `"${column}"`).join(', ');
|
||||||
|
|
||||||
|
export const asForeignKeyConstraintName = (table: string, columns: string[]) => asKey('FK_', table, [...columns]);
|
||||||
|
|
||||||
|
export const asIndexName = (table: string, columns?: string[], where?: string) => {
|
||||||
|
const items: string[] = [];
|
||||||
|
for (const columnName of columns ?? []) {
|
||||||
|
items.push(columnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (where) {
|
||||||
|
items.push(where);
|
||||||
|
}
|
||||||
|
|
||||||
|
return asKey('IDX_', table, items);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addWarning = (builder: SchemaBuilder, context: string, message: string) => {
|
||||||
|
builder.warnings.push(`[${context}] ${message}`);
|
||||||
|
};
|
||||||
|
@ -12,6 +12,7 @@ export * from 'src/sql-tools/from-code/decorators/delete-date-column.decorator';
|
|||||||
export * from 'src/sql-tools/from-code/decorators/extension.decorator';
|
export * from 'src/sql-tools/from-code/decorators/extension.decorator';
|
||||||
export * from 'src/sql-tools/from-code/decorators/extensions.decorator';
|
export * from 'src/sql-tools/from-code/decorators/extensions.decorator';
|
||||||
export * from 'src/sql-tools/from-code/decorators/foreign-key-column.decorator';
|
export * from 'src/sql-tools/from-code/decorators/foreign-key-column.decorator';
|
||||||
|
export * from 'src/sql-tools/from-code/decorators/foreign-key-constraint.decorator';
|
||||||
export * from 'src/sql-tools/from-code/decorators/generated-column.decorator';
|
export * from 'src/sql-tools/from-code/decorators/generated-column.decorator';
|
||||||
export * from 'src/sql-tools/from-code/decorators/index.decorator';
|
export * from 'src/sql-tools/from-code/decorators/index.decorator';
|
||||||
export * from 'src/sql-tools/from-code/decorators/primary-column.decorator';
|
export * from 'src/sql-tools/from-code/decorators/primary-column.decorator';
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
DatabaseConstraintType,
|
||||||
|
DatabaseSchema,
|
||||||
|
ForeignKeyConstraint,
|
||||||
|
PrimaryColumn,
|
||||||
|
Table,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
export class Table1 {
|
||||||
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
|
id1!: string;
|
||||||
|
|
||||||
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
|
id2!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
@ForeignKeyConstraint({
|
||||||
|
columns: ['parentId1', 'parentId2'],
|
||||||
|
referenceTable: () => Table1,
|
||||||
|
referenceColumns: ['id2', 'id1'],
|
||||||
|
})
|
||||||
|
export class Table2 {
|
||||||
|
@Column({ type: 'uuid' })
|
||||||
|
parentId1!: string;
|
||||||
|
|
||||||
|
@Column({ type: 'uuid' })
|
||||||
|
parentId2!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const description = 'should create a foreign key constraint to the target table';
|
||||||
|
export const schema: DatabaseSchema = {
|
||||||
|
name: 'postgres',
|
||||||
|
schemaName: 'public',
|
||||||
|
functions: [],
|
||||||
|
enums: [],
|
||||||
|
extensions: [],
|
||||||
|
parameters: [],
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
name: 'table1',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id1',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: true,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'id2',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: true,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.PRIMARY_KEY,
|
||||||
|
name: 'PK_e457e8b1301b7bc06ef78188ee4',
|
||||||
|
tableName: 'table1',
|
||||||
|
columnNames: ['id1', 'id2'],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'table2',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'parentId1',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parentId2',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'IDX_aed36d04470eba20161aa8b1dc',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['parentId1', 'parentId2'],
|
||||||
|
unique: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.FOREIGN_KEY,
|
||||||
|
name: 'FK_aed36d04470eba20161aa8b1dc6',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['parentId1', 'parentId2'],
|
||||||
|
referenceColumnNames: ['id2', 'id1'],
|
||||||
|
referenceTableName: 'table1',
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
warnings: [],
|
||||||
|
};
|
@ -0,0 +1,78 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
DatabaseConstraintType,
|
||||||
|
DatabaseSchema,
|
||||||
|
ForeignKeyConstraint,
|
||||||
|
PrimaryColumn,
|
||||||
|
Table,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
export class Table1 {
|
||||||
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
|
id!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
@ForeignKeyConstraint({ columns: ['parentId2'], referenceTable: () => Table1 })
|
||||||
|
export class Table2 {
|
||||||
|
@Column({ type: 'uuid' })
|
||||||
|
parentId!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const description = 'should warn against missing column in foreign key constraint';
|
||||||
|
export const schema: DatabaseSchema = {
|
||||||
|
name: 'postgres',
|
||||||
|
schemaName: 'public',
|
||||||
|
functions: [],
|
||||||
|
enums: [],
|
||||||
|
extensions: [],
|
||||||
|
parameters: [],
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
name: 'table1',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: true,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.PRIMARY_KEY,
|
||||||
|
name: 'PK_b249cc64cf63b8a22557cdc8537',
|
||||||
|
tableName: 'table1',
|
||||||
|
columnNames: ['id'],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'table2',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'parentId',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
warnings: ['[@ForeignKeyConstraint.columns] Unable to find column (Table2.parentId2)'],
|
||||||
|
};
|
@ -0,0 +1,78 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
DatabaseConstraintType,
|
||||||
|
DatabaseSchema,
|
||||||
|
ForeignKeyConstraint,
|
||||||
|
PrimaryColumn,
|
||||||
|
Table,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
export class Table1 {
|
||||||
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
|
id!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
@ForeignKeyConstraint({ columns: ['parentId'], referenceTable: () => Table1, referenceColumns: ['foo'] })
|
||||||
|
export class Table2 {
|
||||||
|
@Column({ type: 'uuid' })
|
||||||
|
parentId!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const description = 'should warn against missing reference column in foreign key constraint';
|
||||||
|
export const schema: DatabaseSchema = {
|
||||||
|
name: 'postgres',
|
||||||
|
schemaName: 'public',
|
||||||
|
functions: [],
|
||||||
|
enums: [],
|
||||||
|
extensions: [],
|
||||||
|
parameters: [],
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
name: 'table1',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: true,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.PRIMARY_KEY,
|
||||||
|
name: 'PK_b249cc64cf63b8a22557cdc8537',
|
||||||
|
tableName: 'table1',
|
||||||
|
columnNames: ['id'],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'table2',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'parentId',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
warnings: ['[@ForeignKeyConstraint.referenceColumns] Unable to find column (Table1.foo)'],
|
||||||
|
};
|
@ -0,0 +1,44 @@
|
|||||||
|
import { Column, DatabaseSchema, ForeignKeyConstraint, Table } from 'src/sql-tools';
|
||||||
|
|
||||||
|
class Foo {}
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
@ForeignKeyConstraint({
|
||||||
|
columns: ['parentId'],
|
||||||
|
referenceTable: () => Foo,
|
||||||
|
})
|
||||||
|
export class Table1 {
|
||||||
|
@Column()
|
||||||
|
parentId!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const description = 'should warn against missing reference table';
|
||||||
|
export const schema: DatabaseSchema = {
|
||||||
|
name: 'postgres',
|
||||||
|
schemaName: 'public',
|
||||||
|
functions: [],
|
||||||
|
enums: [],
|
||||||
|
extensions: [],
|
||||||
|
parameters: [],
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
name: 'table1',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'parentId',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'character varying',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
warnings: ['[@ForeignKeyConstraint.referenceTable] Unable to find table (Foo)'],
|
||||||
|
};
|
@ -0,0 +1,120 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
DatabaseConstraintType,
|
||||||
|
DatabaseSchema,
|
||||||
|
ForeignKeyConstraint,
|
||||||
|
PrimaryColumn,
|
||||||
|
Table,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
export class Table1 {
|
||||||
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
|
id1!: string;
|
||||||
|
|
||||||
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
|
id2!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
@ForeignKeyConstraint({ columns: ['parentId1', 'parentId2'], referenceTable: () => Table1 })
|
||||||
|
export class Table2 {
|
||||||
|
@Column({ type: 'uuid' })
|
||||||
|
parentId1!: string;
|
||||||
|
|
||||||
|
@Column({ type: 'uuid' })
|
||||||
|
parentId2!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const description = 'should create a foreign key constraint to the target table';
|
||||||
|
export const schema: DatabaseSchema = {
|
||||||
|
name: 'postgres',
|
||||||
|
schemaName: 'public',
|
||||||
|
functions: [],
|
||||||
|
enums: [],
|
||||||
|
extensions: [],
|
||||||
|
parameters: [],
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
name: 'table1',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id1',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: true,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'id2',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: true,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.PRIMARY_KEY,
|
||||||
|
name: 'PK_e457e8b1301b7bc06ef78188ee4',
|
||||||
|
tableName: 'table1',
|
||||||
|
columnNames: ['id1', 'id2'],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'table2',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'parentId1',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parentId2',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'IDX_aed36d04470eba20161aa8b1dc',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['parentId1', 'parentId2'],
|
||||||
|
unique: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.FOREIGN_KEY,
|
||||||
|
name: 'FK_aed36d04470eba20161aa8b1dc6',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['parentId1', 'parentId2'],
|
||||||
|
referenceColumnNames: ['id1', 'id2'],
|
||||||
|
referenceTableName: 'table1',
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
warnings: [],
|
||||||
|
};
|
@ -0,0 +1,88 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
DatabaseConstraintType,
|
||||||
|
DatabaseSchema,
|
||||||
|
ForeignKeyConstraint,
|
||||||
|
PrimaryColumn,
|
||||||
|
Table,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
export class Table1 {
|
||||||
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
|
id!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
@ForeignKeyConstraint({ columns: ['parentId'], referenceTable: () => Table1, index: false })
|
||||||
|
export class Table2 {
|
||||||
|
@Column({ type: 'uuid' })
|
||||||
|
parentId!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const description = 'should create a foreign key constraint to the target table without an index';
|
||||||
|
export const schema: DatabaseSchema = {
|
||||||
|
name: 'postgres',
|
||||||
|
schemaName: 'public',
|
||||||
|
functions: [],
|
||||||
|
enums: [],
|
||||||
|
extensions: [],
|
||||||
|
parameters: [],
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
name: 'table1',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: true,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.PRIMARY_KEY,
|
||||||
|
name: 'PK_b249cc64cf63b8a22557cdc8537',
|
||||||
|
tableName: 'table1',
|
||||||
|
columnNames: ['id'],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'table2',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'parentId',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.FOREIGN_KEY,
|
||||||
|
name: 'FK_3fcca5cc563abf256fc346e3ff4',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['parentId'],
|
||||||
|
referenceColumnNames: ['id'],
|
||||||
|
referenceTableName: 'table1',
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
warnings: [],
|
||||||
|
};
|
@ -0,0 +1,85 @@
|
|||||||
|
import { Column, DatabaseConstraintType, DatabaseSchema, ForeignKeyConstraint, Table } from 'src/sql-tools';
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
export class Table1 {
|
||||||
|
@Column()
|
||||||
|
foo!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
@ForeignKeyConstraint({
|
||||||
|
columns: ['bar'],
|
||||||
|
referenceTable: () => Table1,
|
||||||
|
referenceColumns: ['foo'],
|
||||||
|
})
|
||||||
|
export class Table2 {
|
||||||
|
@Column()
|
||||||
|
bar!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const description = 'should create a foreign key constraint to the target table without a primary key';
|
||||||
|
export const schema: DatabaseSchema = {
|
||||||
|
name: 'postgres',
|
||||||
|
schemaName: 'public',
|
||||||
|
functions: [],
|
||||||
|
enums: [],
|
||||||
|
extensions: [],
|
||||||
|
parameters: [],
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
name: 'table1',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'foo',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'character varying',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'table2',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'bar',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'character varying',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'IDX_7d9c784c98d12365d198d52e4e',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['bar'],
|
||||||
|
unique: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.FOREIGN_KEY,
|
||||||
|
name: 'FK_7d9c784c98d12365d198d52e4e6',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['bar'],
|
||||||
|
referenceTableName: 'table1',
|
||||||
|
referenceColumnNames: ['foo'],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
warnings: [],
|
||||||
|
};
|
96
server/test/sql-tools/foreign-key-constraint.stub.ts
Normal file
96
server/test/sql-tools/foreign-key-constraint.stub.ts
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
DatabaseConstraintType,
|
||||||
|
DatabaseSchema,
|
||||||
|
ForeignKeyConstraint,
|
||||||
|
PrimaryColumn,
|
||||||
|
Table,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
export class Table1 {
|
||||||
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
|
id!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table()
|
||||||
|
@ForeignKeyConstraint({ columns: ['parentId'], referenceTable: () => Table1 })
|
||||||
|
export class Table2 {
|
||||||
|
@Column({ type: 'uuid' })
|
||||||
|
parentId!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const description = 'should create a foreign key constraint to the target table';
|
||||||
|
export const schema: DatabaseSchema = {
|
||||||
|
name: 'postgres',
|
||||||
|
schemaName: 'public',
|
||||||
|
functions: [],
|
||||||
|
enums: [],
|
||||||
|
extensions: [],
|
||||||
|
parameters: [],
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
name: 'table1',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
tableName: 'table1',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: true,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.PRIMARY_KEY,
|
||||||
|
name: 'PK_b249cc64cf63b8a22557cdc8537',
|
||||||
|
tableName: 'table1',
|
||||||
|
columnNames: ['id'],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'table2',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'parentId',
|
||||||
|
tableName: 'table2',
|
||||||
|
type: 'uuid',
|
||||||
|
nullable: false,
|
||||||
|
isArray: false,
|
||||||
|
primary: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'IDX_3fcca5cc563abf256fc346e3ff',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['parentId'],
|
||||||
|
unique: false,
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
triggers: [],
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
type: DatabaseConstraintType.FOREIGN_KEY,
|
||||||
|
name: 'FK_3fcca5cc563abf256fc346e3ff4',
|
||||||
|
tableName: 'table2',
|
||||||
|
columnNames: ['parentId'],
|
||||||
|
referenceColumnNames: ['id'],
|
||||||
|
referenceTableName: 'table1',
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
synchronize: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
warnings: [],
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user