-
Notifications
You must be signed in to change notification settings - Fork 194
Expand file tree
/
Copy pathshared.ts
More file actions
101 lines (87 loc) · 2.75 KB
/
Copy pathshared.ts
File metadata and controls
101 lines (87 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import type { MigrationOptions } from '../../migrationOptions';
import { isPgLiteral } from '../../utils';
import type { Literal } from '../../utils/createTransformer';
import type { Name } from '../generalTypes';
import { isNameObject, isSchemaNameObject } from '../generalTypes';
import type { CreateIndexOptions } from './createIndex';
import type { DropIndexOptions } from './dropIndex';
export interface IndexColumn {
name: string;
opclass?: Name;
sort?: 'ASC' | 'DESC';
}
function isIndexColumn(value: unknown): value is IndexColumn {
return (
typeof value === 'object' &&
value !== null &&
'name' in value &&
typeof (value as { name?: unknown }).name === 'string'
);
}
export function generateIndexName(
table: Name,
columns: Array<string | IndexColumn>,
options: CreateIndexOptions | DropIndexOptions,
schemalize: Literal
): Name {
if (options.name) {
return isSchemaNameObject(table)
? { schema: table.schema, name: options.name }
: options.name;
}
const cols = columns
.map((col, idx) => {
if (isIndexColumn(col)) return schemalize(col.name);
if (isPgLiteral(col)) {
const literalValue = 'value' in col ? col.value : String(col);
throw new Error(
`Index name must be provided when using PgLiteral columns (column #${idx + 1}: ${literalValue})`
);
}
return schemalize(col);
})
.join('_');
const uniq = 'unique' in options && options.unique ? '_unique' : '';
return isNameObject(table)
? {
schema: table.schema,
name: `${table.name}_${cols}${uniq}_index`,
}
: `${table}_${cols}${uniq}_index`;
}
export function generateColumnString(
column: Name,
mOptions: MigrationOptions
): string {
if (isPgLiteral(column)) {
return column.toString();
}
const name = mOptions.schemalize(column);
const isExpression = /[^\w".]/.test(name);
if (!isExpression) {
return mOptions.literal(name);
}
// Expressions need parentheses in index definitions, unless they're already
// wrapped (we consider any expression ending with ')' as already wrapped).
const alreadyWrapped = /\)$/.test(name);
return alreadyWrapped ? name : `(${name})`;
}
export function generateColumnsString(
columns: Array<string | IndexColumn>,
mOptions: MigrationOptions
): string {
return columns
.map((column) => {
if (typeof column === 'string' || isPgLiteral(column)) {
return generateColumnString(column as unknown as Name, mOptions);
}
return [
generateColumnString(column.name, mOptions),
column.opclass ? mOptions.literal(column.opclass) : undefined,
column.sort,
]
.filter((s) => typeof s === 'string' && s !== '')
.join(' ');
})
.join(', ');
}