mirror of
https://github.com/immich-app/immich.git
synced 2025-12-27 09:14:55 +03:00
feat: naming strategy (#19848)
* feat: naming strategy * feat: detect renames
This commit is contained in:
50
server/src/sql-tools/naming/default.naming.ts
Normal file
50
server/src/sql-tools/naming/default.naming.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { sha1 } from 'src/sql-tools/helpers';
|
||||
import { NamingItem } from 'src/sql-tools/naming/naming.interface';
|
||||
|
||||
const asSnakeCase = (name: string): string => name.replaceAll(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
|
||||
|
||||
export class DefaultNamingStrategy {
|
||||
getName(item: NamingItem): string {
|
||||
switch (item.type) {
|
||||
case 'database': {
|
||||
return asSnakeCase(item.name);
|
||||
}
|
||||
|
||||
case 'table': {
|
||||
return asSnakeCase(item.name);
|
||||
}
|
||||
|
||||
case 'column': {
|
||||
return item.name;
|
||||
}
|
||||
|
||||
case 'primaryKey': {
|
||||
return `${item.tableName}_pkey`;
|
||||
}
|
||||
|
||||
case 'foreignKey': {
|
||||
return `${item.tableName}_${item.columnNames.join('_')}_fkey`;
|
||||
}
|
||||
|
||||
case 'check': {
|
||||
return `${item.tableName}_${sha1(item.expression).slice(0, 8)}_chk`;
|
||||
}
|
||||
|
||||
case 'unique': {
|
||||
return `${item.tableName}_${item.columnNames.join('_')}_uq`;
|
||||
}
|
||||
|
||||
case 'index': {
|
||||
if (item.columnNames) {
|
||||
return `${item.tableName}_${item.columnNames.join('_')}_idx`;
|
||||
}
|
||||
|
||||
return `${item.tableName}_${sha1(item.expression || item.where || '').slice(0, 8)}_idx`;
|
||||
}
|
||||
|
||||
case 'trigger': {
|
||||
return `${item.tableName}_${item.functionName}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
server/src/sql-tools/naming/hash.naming.ts
Normal file
51
server/src/sql-tools/naming/hash.naming.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { sha1 } from 'src/sql-tools/helpers';
|
||||
import { DefaultNamingStrategy } from 'src/sql-tools/naming/default.naming';
|
||||
import { NamingInterface, NamingItem } from 'src/sql-tools/naming/naming.interface';
|
||||
|
||||
const fallback = new DefaultNamingStrategy();
|
||||
|
||||
const asKey = (prefix: string, tableName: string, values: string[]) =>
|
||||
(prefix + sha1(`${tableName}_${values.toSorted().join('_')}`)).slice(0, 30);
|
||||
|
||||
export class HashNamingStrategy implements NamingInterface {
|
||||
getName(item: NamingItem): string {
|
||||
switch (item.type) {
|
||||
case 'primaryKey': {
|
||||
return asKey('PK_', item.tableName, item.columnNames);
|
||||
}
|
||||
|
||||
case 'foreignKey': {
|
||||
return asKey('FK_', item.tableName, item.columnNames);
|
||||
}
|
||||
|
||||
case 'check': {
|
||||
return asKey('CHK_', item.tableName, [item.expression]);
|
||||
}
|
||||
|
||||
case 'unique': {
|
||||
return asKey('UQ_', item.tableName, item.columnNames);
|
||||
}
|
||||
|
||||
case 'index': {
|
||||
const items: string[] = [];
|
||||
for (const columnName of item.columnNames ?? []) {
|
||||
items.push(columnName);
|
||||
}
|
||||
|
||||
if (item.where) {
|
||||
items.push(item.where);
|
||||
}
|
||||
|
||||
return asKey('IDX_', item.tableName, items);
|
||||
}
|
||||
|
||||
case 'trigger': {
|
||||
return asKey('TR_', item.tableName, [...item.actions, item.scope, item.timing, item.functionName]);
|
||||
}
|
||||
|
||||
default: {
|
||||
return fallback.getName(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
server/src/sql-tools/naming/naming.interface.ts
Normal file
59
server/src/sql-tools/naming/naming.interface.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { TriggerAction, TriggerScope, TriggerTiming } from 'src/sql-tools/types';
|
||||
|
||||
export type NamingItem =
|
||||
| {
|
||||
type: 'database';
|
||||
name: string;
|
||||
}
|
||||
| {
|
||||
type: 'table';
|
||||
name: string;
|
||||
}
|
||||
| {
|
||||
type: 'column';
|
||||
name: string;
|
||||
}
|
||||
| {
|
||||
type: 'primaryKey';
|
||||
tableName: string;
|
||||
columnNames: string[];
|
||||
}
|
||||
| {
|
||||
type: 'foreignKey';
|
||||
tableName: string;
|
||||
columnNames: string[];
|
||||
referenceTableName: string;
|
||||
referenceColumnNames: string[];
|
||||
}
|
||||
| {
|
||||
type: 'check';
|
||||
tableName: string;
|
||||
expression: string;
|
||||
}
|
||||
| {
|
||||
type: 'unique';
|
||||
tableName: string;
|
||||
columnNames: string[];
|
||||
}
|
||||
| {
|
||||
type: 'index';
|
||||
tableName: string;
|
||||
columnNames?: string[];
|
||||
expression?: string;
|
||||
where?: string;
|
||||
}
|
||||
| {
|
||||
type: 'trigger';
|
||||
tableName: string;
|
||||
functionName: string;
|
||||
actions: TriggerAction[];
|
||||
scope: TriggerScope;
|
||||
timing: TriggerTiming;
|
||||
columnNames?: string[];
|
||||
expression?: string;
|
||||
where?: string;
|
||||
};
|
||||
|
||||
export interface NamingInterface {
|
||||
getName(item: NamingItem): string;
|
||||
}
|
||||
Reference in New Issue
Block a user