rake-db 2.4.7 → 2.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +21 -4
- package/dist/index.js +279 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +281 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ColumnType, EnumColumn, ColumnTypes, ColumnsShape, DbResult, DefaultColumnTypes, TransactionAdapter, QueryLogObject, IndexColumnOptions, IndexOptions, ForeignKeyOptions, TextColumn, NoPrimaryKeyOption, TableData, SingleColumnIndexOptions, AdapterOptions, QueryLogOptions, Adapter } from 'pqb';
|
|
1
|
+
import { ColumnType, EnumColumn, UnknownColumn, ColumnTypes, ColumnsShape, DbResult, DefaultColumnTypes, TransactionAdapter, QueryLogObject, IndexColumnOptions, IndexOptions, ForeignKeyOptions, TextColumn, NoPrimaryKeyOption, TableData, SingleColumnIndexOptions, AdapterOptions, QueryLogOptions, Adapter } from 'pqb';
|
|
2
|
+
import * as orchid_core from 'orchid-core';
|
|
2
3
|
import { EmptyObject, RawExpression, ColumnTypesBase, raw, MaybeArray } from 'orchid-core';
|
|
3
4
|
|
|
4
5
|
declare function add(this: ColumnTypesBase, item: ColumnType, options?: {
|
|
@@ -24,6 +25,7 @@ declare const tableChangeMethods: {
|
|
|
24
25
|
comment(comment: string | null): Change;
|
|
25
26
|
rename(name: string): RakeDbAst.ChangeTableItem.Rename;
|
|
26
27
|
enum(this: ColumnTypesBase, name: string): EnumColumn<string, [string, ...string[]]>;
|
|
28
|
+
check(this: ColumnTypesBase, value: RawExpression<orchid_core.ColumnTypeBase<unknown, orchid_core.BaseOperators, unknown, orchid_core.ColumnDataBase>>): UnknownColumn;
|
|
27
29
|
};
|
|
28
30
|
declare type TableChanger = MigrationColumnTypes & TableChangeMethods;
|
|
29
31
|
declare type TableChangeData = Record<string, RakeDbAst.ChangeTableItem.Column | RakeDbAst.ChangeTableItem.Rename | Change | EmptyObject>;
|
|
@@ -83,14 +85,16 @@ declare class MigrationBase {
|
|
|
83
85
|
dropSchema(schemaName: string): Promise<void>;
|
|
84
86
|
createExtension(name: string, options?: Omit<RakeDbAst.Extension, 'type' | 'action' | 'name'>): Promise<void>;
|
|
85
87
|
dropExtension(name: string, options?: Omit<RakeDbAst.Extension, 'type' | 'action' | 'name' | 'values'>): Promise<void>;
|
|
86
|
-
createEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values'>): Promise<void>;
|
|
87
|
-
dropEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values'>): Promise<void>;
|
|
88
|
+
createEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values' | 'schema'>): Promise<void>;
|
|
89
|
+
dropEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values' | 'schema'>): Promise<void>;
|
|
90
|
+
createDomain(name: string, fn: (t: ColumnTypes) => ColumnType, options?: Omit<RakeDbAst.Domain, 'type' | 'action' | 'schema' | 'name' | 'baseType'>): Promise<void>;
|
|
91
|
+
dropDomain(name: string, fn: (t: ColumnTypes) => ColumnType, options?: Omit<RakeDbAst.Domain, 'type' | 'action' | 'schema' | 'name' | 'baseType'>): Promise<void>;
|
|
88
92
|
tableExists(tableName: string): Promise<boolean>;
|
|
89
93
|
columnExists(tableName: string, columnName: string): Promise<boolean>;
|
|
90
94
|
constraintExists(constraintName: string): Promise<boolean>;
|
|
91
95
|
}
|
|
92
96
|
|
|
93
|
-
declare type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameTable | RakeDbAst.Schema | RakeDbAst.Extension | RakeDbAst.Enum | RakeDbAst.ForeignKey;
|
|
97
|
+
declare type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameTable | RakeDbAst.Schema | RakeDbAst.Extension | RakeDbAst.Enum | RakeDbAst.Domain | RakeDbAst.ForeignKey;
|
|
94
98
|
declare namespace RakeDbAst {
|
|
95
99
|
type Table = {
|
|
96
100
|
type: 'table';
|
|
@@ -139,6 +143,7 @@ declare namespace RakeDbAst {
|
|
|
139
143
|
comment?: string | null;
|
|
140
144
|
compression?: string;
|
|
141
145
|
primaryKey?: boolean;
|
|
146
|
+
check?: RawExpression;
|
|
142
147
|
foreignKeys?: ({
|
|
143
148
|
table: string;
|
|
144
149
|
columns: string[];
|
|
@@ -176,6 +181,18 @@ declare namespace RakeDbAst {
|
|
|
176
181
|
cascade?: boolean;
|
|
177
182
|
dropIfExists?: boolean;
|
|
178
183
|
};
|
|
184
|
+
type Domain = {
|
|
185
|
+
type: 'domain';
|
|
186
|
+
action: 'create' | 'drop';
|
|
187
|
+
schema?: string;
|
|
188
|
+
name: string;
|
|
189
|
+
baseType: ColumnType;
|
|
190
|
+
notNull?: boolean;
|
|
191
|
+
collation?: string;
|
|
192
|
+
default?: RawExpression;
|
|
193
|
+
check?: RawExpression;
|
|
194
|
+
cascade?: boolean;
|
|
195
|
+
};
|
|
179
196
|
type EnumOptions = {
|
|
180
197
|
createIfNotExists?: boolean;
|
|
181
198
|
dropIfExists?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -302,8 +302,11 @@ var __spreadValues$5 = (a, b) => {
|
|
|
302
302
|
return a;
|
|
303
303
|
};
|
|
304
304
|
var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
|
|
305
|
+
const columnTypeToSql = (item) => {
|
|
306
|
+
return item.data.isOfCustomType ? `"${item.toSQL()}"` : item.toSQL();
|
|
307
|
+
};
|
|
305
308
|
const columnToSql = (key, item, values, hasMultiplePrimaryKeys) => {
|
|
306
|
-
const line = [`"${item.data.name || key}" ${item
|
|
309
|
+
const line = [`"${item.data.name || key}" ${columnTypeToSql(item)}`];
|
|
307
310
|
if (item.data.compression) {
|
|
308
311
|
line.push(`COMPRESSION ${item.data.compression}`);
|
|
309
312
|
}
|
|
@@ -315,6 +318,9 @@ const columnToSql = (key, item, values, hasMultiplePrimaryKeys) => {
|
|
|
315
318
|
} else if (!item.data.isNullable) {
|
|
316
319
|
line.push("NOT NULL");
|
|
317
320
|
}
|
|
321
|
+
if (item.data.check) {
|
|
322
|
+
line.push(`CHECK (${pqb.getRaw(item.data.check, values)})`);
|
|
323
|
+
}
|
|
318
324
|
if (item.data.default !== void 0) {
|
|
319
325
|
if (typeof item.data.default === "object" && item.data.default && orchidCore.isRaw(item.data.default)) {
|
|
320
326
|
line.push(`DEFAULT ${pqb.getRaw(item.data.default, values)}`);
|
|
@@ -475,6 +481,9 @@ const primaryKeyToSql = (primaryKey) => {
|
|
|
475
481
|
const tableMethods = {
|
|
476
482
|
enum(name) {
|
|
477
483
|
return new pqb.EnumColumn(this, name, []);
|
|
484
|
+
},
|
|
485
|
+
check(value) {
|
|
486
|
+
return new pqb.UnknownColumn(this).check(value);
|
|
478
487
|
}
|
|
479
488
|
};
|
|
480
489
|
|
|
@@ -502,7 +511,7 @@ var __spreadValues$4 = (a, b) => {
|
|
|
502
511
|
return a;
|
|
503
512
|
};
|
|
504
513
|
var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
|
|
505
|
-
var __objRest = (source, exclude) => {
|
|
514
|
+
var __objRest$1 = (source, exclude) => {
|
|
506
515
|
var target = {};
|
|
507
516
|
for (var prop in source)
|
|
508
517
|
if (__hasOwnProp$4.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
@@ -530,7 +539,7 @@ const createTable$1 = async (migration, up, tableName, options, fn) => {
|
|
|
530
539
|
validatePrimaryKey(ast);
|
|
531
540
|
const queries = astToQueries$1(ast);
|
|
532
541
|
for (const _a of queries) {
|
|
533
|
-
const _b = _a, { then } = _b, query = __objRest(_b, ["then"]);
|
|
542
|
+
const _b = _a, { then } = _b, query = __objRest$1(_b, ["then"]);
|
|
534
543
|
const result = await migration.adapter.arrays(query);
|
|
535
544
|
then == null ? void 0 : then(result);
|
|
536
545
|
}
|
|
@@ -676,14 +685,7 @@ const mergeTableData = (a, b) => {
|
|
|
676
685
|
};
|
|
677
686
|
function add(item, options) {
|
|
678
687
|
if (item instanceof pqb.ColumnType) {
|
|
679
|
-
|
|
680
|
-
item.data.name = this[orchidCore.nameKey];
|
|
681
|
-
}
|
|
682
|
-
return {
|
|
683
|
-
type: "add",
|
|
684
|
-
item,
|
|
685
|
-
dropMode: options == null ? void 0 : options.dropMode
|
|
686
|
-
};
|
|
688
|
+
return addOrDrop(this, "add", item, options);
|
|
687
689
|
} else if (item === orchidCore.emptyObject) {
|
|
688
690
|
mergeTableData(changeTableData.add, pqb.getTableData());
|
|
689
691
|
pqb.resetTableData();
|
|
@@ -702,14 +704,7 @@ function add(item, options) {
|
|
|
702
704
|
}
|
|
703
705
|
const drop = function(item, options) {
|
|
704
706
|
if (item instanceof pqb.ColumnType) {
|
|
705
|
-
|
|
706
|
-
item.data.name = this[orchidCore.nameKey];
|
|
707
|
-
}
|
|
708
|
-
return {
|
|
709
|
-
type: "drop",
|
|
710
|
-
item,
|
|
711
|
-
dropMode: options == null ? void 0 : options.dropMode
|
|
712
|
-
};
|
|
707
|
+
return addOrDrop(this, "drop", item, options);
|
|
713
708
|
} else if (item === orchidCore.emptyObject) {
|
|
714
709
|
mergeTableData(changeTableData.drop, pqb.getTableData());
|
|
715
710
|
pqb.resetTableData();
|
|
@@ -726,6 +721,35 @@ const drop = function(item, options) {
|
|
|
726
721
|
return result;
|
|
727
722
|
}
|
|
728
723
|
};
|
|
724
|
+
const addOrDrop = (types, type, item, options) => {
|
|
725
|
+
if (types[orchidCore.nameKey]) {
|
|
726
|
+
item.data.name = types[orchidCore.nameKey];
|
|
727
|
+
}
|
|
728
|
+
if (item instanceof pqb.UnknownColumn) {
|
|
729
|
+
const empty = columnTypeToColumnChange({
|
|
730
|
+
type: "change",
|
|
731
|
+
from: {},
|
|
732
|
+
to: {}
|
|
733
|
+
});
|
|
734
|
+
const add2 = columnTypeToColumnChange({
|
|
735
|
+
type: "change",
|
|
736
|
+
from: {},
|
|
737
|
+
to: {
|
|
738
|
+
check: item.data.check
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
return __spreadValues$3({
|
|
742
|
+
type: "change",
|
|
743
|
+
from: type === "add" ? empty : add2,
|
|
744
|
+
to: type === "add" ? add2 : empty
|
|
745
|
+
}, options);
|
|
746
|
+
}
|
|
747
|
+
return {
|
|
748
|
+
type,
|
|
749
|
+
item,
|
|
750
|
+
dropMode: options == null ? void 0 : options.dropMode
|
|
751
|
+
};
|
|
752
|
+
};
|
|
729
753
|
const columnTypeToColumnChange = (item) => {
|
|
730
754
|
if (item instanceof pqb.ColumnType) {
|
|
731
755
|
const foreignKeys = item.data.foreignKeys;
|
|
@@ -877,12 +901,13 @@ const astToQueries = (ast) => {
|
|
|
877
901
|
for (const key in ast.shape) {
|
|
878
902
|
const item = ast.shape[key];
|
|
879
903
|
if (item.type === "add") {
|
|
880
|
-
|
|
881
|
-
|
|
904
|
+
const column = item.item;
|
|
905
|
+
addColumnIndex(addIndexes, key, column);
|
|
906
|
+
addColumnComment(comments, key, column);
|
|
882
907
|
alterTable.push(
|
|
883
908
|
`ADD COLUMN ${columnToSql(
|
|
884
909
|
key,
|
|
885
|
-
|
|
910
|
+
column,
|
|
886
911
|
values,
|
|
887
912
|
addPrimaryKeys.columns.length > 1
|
|
888
913
|
)}`
|
|
@@ -894,9 +919,10 @@ const astToQueries = (ast) => {
|
|
|
894
919
|
);
|
|
895
920
|
} else if (item.type === "change") {
|
|
896
921
|
const { from, to } = item;
|
|
897
|
-
if (from.type !== to.type || from.collate !== to.collate) {
|
|
922
|
+
if (to.type && (from.type !== to.type || from.collate !== to.collate)) {
|
|
923
|
+
const type = !to.column || to.column.data.isOfCustomType ? `"${to.type}"` : to.type;
|
|
898
924
|
alterTable.push(
|
|
899
|
-
`ALTER COLUMN "${item.name || key}" TYPE ${
|
|
925
|
+
`ALTER COLUMN "${item.name || key}" TYPE ${type}${to.collate ? ` COLLATE ${pqb.quote(to.collate)}` : ""}${item.using ? ` USING ${pqb.getRaw(item.using, values)}` : ""}`
|
|
900
926
|
);
|
|
901
927
|
}
|
|
902
928
|
if (from.default !== to.default) {
|
|
@@ -914,6 +940,18 @@ const astToQueries = (ast) => {
|
|
|
914
940
|
`ALTER COLUMN "${item.name || key}" SET COMPRESSION ${to.compression || "DEFAULT"}`
|
|
915
941
|
);
|
|
916
942
|
}
|
|
943
|
+
if (from.check !== to.check) {
|
|
944
|
+
const name = `${ast.name}_${item.name || key}_check`;
|
|
945
|
+
if (from.check) {
|
|
946
|
+
alterTable.push(`DROP CONSTRAINT "${name}"`);
|
|
947
|
+
}
|
|
948
|
+
if (to.check) {
|
|
949
|
+
alterTable.push(
|
|
950
|
+
`ADD CONSTRAINT "${name}"
|
|
951
|
+
CHECK (${pqb.getRaw(to.check, values)})`
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
917
955
|
const foreignKeysLen = Math.max(
|
|
918
956
|
((_a = from.foreignKeys) == null ? void 0 : _a.length) || 0,
|
|
919
957
|
((_b = to.foreignKeys) == null ? void 0 : _b.length) || 0
|
|
@@ -1152,6 +1190,12 @@ class MigrationBase {
|
|
|
1152
1190
|
dropEnum(name, values, options) {
|
|
1153
1191
|
return createEnum$1(this, !this.up, name, values, options);
|
|
1154
1192
|
}
|
|
1193
|
+
createDomain(name, fn, options) {
|
|
1194
|
+
return createDomain$1(this, this.up, name, fn, options);
|
|
1195
|
+
}
|
|
1196
|
+
dropDomain(name, fn, options) {
|
|
1197
|
+
return createDomain$1(this, !this.up, name, fn, options);
|
|
1198
|
+
}
|
|
1155
1199
|
async tableExists(tableName) {
|
|
1156
1200
|
return queryExists(this, {
|
|
1157
1201
|
text: `SELECT 1 FROM "information_schema"."tables" WHERE "table_name" = $1`,
|
|
@@ -1246,6 +1290,34 @@ const createEnum$1 = async (migration, up, name, values, options = {}) => {
|
|
|
1246
1290
|
await migration.adapter.query(query);
|
|
1247
1291
|
migration.migratedAsts.push(ast);
|
|
1248
1292
|
};
|
|
1293
|
+
const createDomain$1 = async (migration, up, name, fn, options) => {
|
|
1294
|
+
const [schema, domainName] = getSchemaAndTableFromName(name);
|
|
1295
|
+
const ast = __spreadValues$2({
|
|
1296
|
+
type: "domain",
|
|
1297
|
+
action: up ? "create" : "drop",
|
|
1298
|
+
schema,
|
|
1299
|
+
name: domainName,
|
|
1300
|
+
baseType: fn(pqb.columnTypes)
|
|
1301
|
+
}, options);
|
|
1302
|
+
let query;
|
|
1303
|
+
const values = [];
|
|
1304
|
+
const quotedName = quoteWithSchema(ast);
|
|
1305
|
+
if (ast.action === "create") {
|
|
1306
|
+
query = `CREATE DOMAIN ${quotedName} AS ${columnTypeToSql(ast.baseType)}${ast.collation ? `
|
|
1307
|
+
COLLATION ${orchidCore.singleQuote(ast.collation)}` : ""}${ast.default ? `
|
|
1308
|
+
DEFAULT ${pqb.getRaw(ast.default, values)}` : ""}${ast.notNull || ast.check ? "\n" : ""}${[
|
|
1309
|
+
ast.notNull && "NOT NULL",
|
|
1310
|
+
ast.check && `CHECK ${pqb.getRaw(ast.check, values)}`
|
|
1311
|
+
].filter(Boolean).join(" ")}`;
|
|
1312
|
+
} else {
|
|
1313
|
+
query = `DROP DOMAIN ${quotedName}${ast.cascade ? " CASCADE" : ""}`;
|
|
1314
|
+
}
|
|
1315
|
+
await migration.adapter.query({
|
|
1316
|
+
text: query,
|
|
1317
|
+
values
|
|
1318
|
+
});
|
|
1319
|
+
migration.migratedAsts.push(ast);
|
|
1320
|
+
};
|
|
1249
1321
|
const queryExists = (db, sql) => {
|
|
1250
1322
|
return db.adapter.query(sql).then(({ rowCount }) => rowCount > 0);
|
|
1251
1323
|
};
|
|
@@ -1864,6 +1936,63 @@ GROUP BY n.nspname, t.typname`
|
|
|
1864
1936
|
);
|
|
1865
1937
|
return rows;
|
|
1866
1938
|
}
|
|
1939
|
+
async getChecks() {
|
|
1940
|
+
const { rows } = await this.db.query(`SELECT
|
|
1941
|
+
s.nspname AS "schemaName",
|
|
1942
|
+
t.relname AS "tableName",
|
|
1943
|
+
c.conname AS "name",
|
|
1944
|
+
(
|
|
1945
|
+
SELECT json_agg(ccu.column_name)
|
|
1946
|
+
FROM information_schema.constraint_column_usage ccu
|
|
1947
|
+
WHERE ccu.constraint_name = c.conname
|
|
1948
|
+
AND ccu.table_schema = cs.nspname
|
|
1949
|
+
) AS "columnNames",
|
|
1950
|
+
pg_get_expr(conbin, conrelid) AS "expression"
|
|
1951
|
+
FROM pg_catalog.pg_constraint c
|
|
1952
|
+
JOIN pg_class t ON t.oid = conrelid
|
|
1953
|
+
JOIN pg_catalog.pg_namespace s ON s.oid = t.relnamespace
|
|
1954
|
+
JOIN pg_catalog.pg_namespace cs ON cs.oid = c.connamespace
|
|
1955
|
+
WHERE contype = 'c'
|
|
1956
|
+
ORDER BY c.conname`);
|
|
1957
|
+
for (const row of rows) {
|
|
1958
|
+
if (row.expression[0] === "(" && row.expression[row.expression.length - 1] === ")") {
|
|
1959
|
+
row.expression = row.expression.slice(1, -1);
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
return rows;
|
|
1963
|
+
}
|
|
1964
|
+
async getDomains() {
|
|
1965
|
+
const { rows } = await this.db.query(`SELECT
|
|
1966
|
+
n.nspname AS "schemaName",
|
|
1967
|
+
d.typname AS "name",
|
|
1968
|
+
t.typname AS "type",
|
|
1969
|
+
s.nspname AS "typeSchema",
|
|
1970
|
+
.typnotnull AS "notNull",
|
|
1971
|
+
d.typcategory = 'A' AS "isArray",
|
|
1972
|
+
character_maximum_length AS "maxChars",
|
|
1973
|
+
numeric_precision AS "numericPrecision",
|
|
1974
|
+
numeric_scale AS "numericScale",
|
|
1975
|
+
datetime_precision AS "dateTimePrecision",
|
|
1976
|
+
collation_name AS "collation",
|
|
1977
|
+
domain_default AS "default",
|
|
1978
|
+
pg_get_expr(conbin, conrelid) AS "expression"
|
|
1979
|
+
FROM pg_catalog.pg_type d
|
|
1980
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = d.typnamespace
|
|
1981
|
+
JOIN information_schema.domains i
|
|
1982
|
+
ON i.domain_schema = nspname
|
|
1983
|
+
AND i.domain_name = d.typname
|
|
1984
|
+
JOIN pg_catalog.pg_type t
|
|
1985
|
+
ON (
|
|
1986
|
+
CASE WHEN d.typcategory = 'A'
|
|
1987
|
+
THEN t.typarray
|
|
1988
|
+
ELSE t.oid
|
|
1989
|
+
END
|
|
1990
|
+
) = d.typbasetype
|
|
1991
|
+
JOIN pg_catalog.pg_namespace s ON s.oid = t.typnamespace
|
|
1992
|
+
LEFT JOIN pg_catalog.pg_constraint c ON c.contypid = d.oid
|
|
1993
|
+
WHERE d.typtype = 'd' AND ${filterSchema("n.nspname")}`);
|
|
1994
|
+
return rows;
|
|
1995
|
+
}
|
|
1867
1996
|
}
|
|
1868
1997
|
|
|
1869
1998
|
var __defProp = Object.defineProperty;
|
|
@@ -1885,6 +2014,18 @@ var __spreadValues = (a, b) => {
|
|
|
1885
2014
|
return a;
|
|
1886
2015
|
};
|
|
1887
2016
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
2017
|
+
var __objRest = (source, exclude) => {
|
|
2018
|
+
var target = {};
|
|
2019
|
+
for (var prop in source)
|
|
2020
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
2021
|
+
target[prop] = source[prop];
|
|
2022
|
+
if (source != null && __getOwnPropSymbols)
|
|
2023
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
2024
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
2025
|
+
target[prop] = source[prop];
|
|
2026
|
+
}
|
|
2027
|
+
return target;
|
|
2028
|
+
};
|
|
1888
2029
|
class RakeDbEnumColumn extends pqb.EnumColumn {
|
|
1889
2030
|
toCode(t) {
|
|
1890
2031
|
return pqb.columnCode(this, t, `enum('${this.enumName}')`);
|
|
@@ -1928,10 +2069,21 @@ const structureToAst = async (db) => {
|
|
|
1928
2069
|
}
|
|
1929
2070
|
pendingTables[key] = { table, dependsOn };
|
|
1930
2071
|
}
|
|
2072
|
+
const domains = {};
|
|
2073
|
+
for (const it of data.domains) {
|
|
2074
|
+
domains[`${it.schemaName}.${it.name}`] = getColumn(data, domains, {
|
|
2075
|
+
schemaName: it.schemaName,
|
|
2076
|
+
name: it.name,
|
|
2077
|
+
type: it.type,
|
|
2078
|
+
typeSchema: it.typeSchema,
|
|
2079
|
+
isArray: it.isArray,
|
|
2080
|
+
isSerial: false
|
|
2081
|
+
});
|
|
2082
|
+
}
|
|
1931
2083
|
for (const key in pendingTables) {
|
|
1932
2084
|
const { table, dependsOn } = pendingTables[key];
|
|
1933
2085
|
if (!dependsOn.size) {
|
|
1934
|
-
pushTableAst(ast, data, table, pendingTables);
|
|
2086
|
+
pushTableAst(ast, data, domains, table, pendingTables);
|
|
1935
2087
|
}
|
|
1936
2088
|
}
|
|
1937
2089
|
const outerFKeys = [];
|
|
@@ -1953,6 +2105,19 @@ const structureToAst = async (db) => {
|
|
|
1953
2105
|
values: it.values
|
|
1954
2106
|
});
|
|
1955
2107
|
}
|
|
2108
|
+
for (const it of data.domains) {
|
|
2109
|
+
ast.push({
|
|
2110
|
+
type: "domain",
|
|
2111
|
+
action: "create",
|
|
2112
|
+
schema: it.schemaName === "public" ? void 0 : it.schemaName,
|
|
2113
|
+
name: it.name,
|
|
2114
|
+
baseType: domains[`${it.schemaName}.${it.name}`],
|
|
2115
|
+
notNull: it.notNull,
|
|
2116
|
+
collation: it.collation,
|
|
2117
|
+
default: it.default ? orchidCore.raw(it.default) : void 0,
|
|
2118
|
+
check: it.check ? orchidCore.raw(it.check) : void 0
|
|
2119
|
+
});
|
|
2120
|
+
}
|
|
1956
2121
|
for (const key in pendingTables) {
|
|
1957
2122
|
const innerFKeys = [];
|
|
1958
2123
|
const { table } = pendingTables[key];
|
|
@@ -1966,7 +2131,7 @@ const structureToAst = async (db) => {
|
|
|
1966
2131
|
outerFKeys.push([fkey, table]);
|
|
1967
2132
|
}
|
|
1968
2133
|
}
|
|
1969
|
-
pushTableAst(ast, data, table, pendingTables, innerFKeys);
|
|
2134
|
+
pushTableAst(ast, data, domains, table, pendingTables, innerFKeys);
|
|
1970
2135
|
}
|
|
1971
2136
|
for (const [fkey, table] of outerFKeys) {
|
|
1972
2137
|
ast.push(__spreadProps(__spreadValues({}, foreignKeyToAst(fkey)), {
|
|
@@ -1987,7 +2152,9 @@ const getData = async (db) => {
|
|
|
1987
2152
|
indexes,
|
|
1988
2153
|
foreignKeys,
|
|
1989
2154
|
extensions,
|
|
1990
|
-
enums
|
|
2155
|
+
enums,
|
|
2156
|
+
checks,
|
|
2157
|
+
domains
|
|
1991
2158
|
] = await Promise.all([
|
|
1992
2159
|
db.getSchemas(),
|
|
1993
2160
|
db.getTables(),
|
|
@@ -1996,7 +2163,9 @@ const getData = async (db) => {
|
|
|
1996
2163
|
db.getIndexes(),
|
|
1997
2164
|
db.getForeignKeys(),
|
|
1998
2165
|
db.getExtensions(),
|
|
1999
|
-
db.getEnums()
|
|
2166
|
+
db.getEnums(),
|
|
2167
|
+
db.getChecks(),
|
|
2168
|
+
db.getDomains()
|
|
2000
2169
|
]);
|
|
2001
2170
|
return {
|
|
2002
2171
|
schemas,
|
|
@@ -2006,7 +2175,9 @@ const getData = async (db) => {
|
|
|
2006
2175
|
indexes,
|
|
2007
2176
|
foreignKeys,
|
|
2008
2177
|
extensions,
|
|
2009
|
-
enums
|
|
2178
|
+
enums,
|
|
2179
|
+
checks,
|
|
2180
|
+
domains
|
|
2010
2181
|
};
|
|
2011
2182
|
};
|
|
2012
2183
|
const makeBelongsToTable = (schema, table) => (item) => item.schemaName === schema && item.tableName === table;
|
|
@@ -2020,12 +2191,52 @@ const getIsSerial = (item) => {
|
|
|
2020
2191
|
}
|
|
2021
2192
|
return false;
|
|
2022
2193
|
};
|
|
2194
|
+
const getColumn = (data, domains, _a) => {
|
|
2195
|
+
var _b = _a, {
|
|
2196
|
+
schemaName,
|
|
2197
|
+
tableName,
|
|
2198
|
+
name,
|
|
2199
|
+
type,
|
|
2200
|
+
typeSchema,
|
|
2201
|
+
isArray,
|
|
2202
|
+
isSerial
|
|
2203
|
+
} = _b, params = __objRest(_b, [
|
|
2204
|
+
"schemaName",
|
|
2205
|
+
"tableName",
|
|
2206
|
+
"name",
|
|
2207
|
+
"type",
|
|
2208
|
+
"typeSchema",
|
|
2209
|
+
"isArray",
|
|
2210
|
+
"isSerial"
|
|
2211
|
+
]);
|
|
2212
|
+
let column;
|
|
2213
|
+
const klass = pqb.columnsByType[getColumnType(type, isSerial)];
|
|
2214
|
+
if (klass) {
|
|
2215
|
+
column = pqb.instantiateColumn(klass, params);
|
|
2216
|
+
} else {
|
|
2217
|
+
const domainColumn = domains[`${typeSchema}.${type}`];
|
|
2218
|
+
if (domainColumn) {
|
|
2219
|
+
column = new pqb.DomainColumn({}, type).as(domainColumn);
|
|
2220
|
+
} else {
|
|
2221
|
+
const enumType = data.enums.find(
|
|
2222
|
+
(item) => item.name === type && item.schemaName === typeSchema
|
|
2223
|
+
);
|
|
2224
|
+
if (!enumType) {
|
|
2225
|
+
throw new Error(
|
|
2226
|
+
`Cannot handle ${tableName ? "column" : "domain"} ${schemaName}${tableName ? `.${tableName}` : ""}.${name}: column type \`${type}\` is not supported`
|
|
2227
|
+
);
|
|
2228
|
+
}
|
|
2229
|
+
column = new RakeDbEnumColumn({}, type, enumType.values);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
return isArray ? new pqb.ArrayColumn({}, column) : column;
|
|
2233
|
+
};
|
|
2023
2234
|
const getColumnType = (type, isSerial) => {
|
|
2024
2235
|
if (!isSerial)
|
|
2025
2236
|
return type;
|
|
2026
2237
|
return type === "int2" ? "smallserial" : type === "int4" ? "serial" : "bigserial";
|
|
2027
2238
|
};
|
|
2028
|
-
const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreignKeys) => {
|
|
2239
|
+
const pushTableAst = (ast, data, domains, table, pendingTables, innerFKeys = data.foreignKeys) => {
|
|
2029
2240
|
const { schemaName, name } = table;
|
|
2030
2241
|
const key = `${schemaName}.${table.name}`;
|
|
2031
2242
|
delete pendingTables[key];
|
|
@@ -2036,32 +2247,24 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
|
|
|
2036
2247
|
const primaryKey = data.primaryKeys.find(belongsToTable);
|
|
2037
2248
|
const tableIndexes = data.indexes.filter(belongsToTable);
|
|
2038
2249
|
const tableForeignKeys = innerFKeys.filter(belongsToTable);
|
|
2250
|
+
const columnChecks = {};
|
|
2251
|
+
for (const check of data.checks) {
|
|
2252
|
+
if (check.columnNames.length === 1) {
|
|
2253
|
+
columnChecks[check.columnNames[0]] = check;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2039
2256
|
const shape = {};
|
|
2040
2257
|
for (let item of columns) {
|
|
2041
2258
|
const isSerial = getIsSerial(item);
|
|
2042
2259
|
if (isSerial) {
|
|
2043
2260
|
item = __spreadProps(__spreadValues({}, item), { default: void 0 });
|
|
2044
2261
|
}
|
|
2045
|
-
let column;
|
|
2046
2262
|
const isArray = item.dataType === "ARRAY";
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
}
|
|
2052
|
-
const { type: type2, typeSchema } = item;
|
|
2053
|
-
const enumType = data.enums.find(
|
|
2054
|
-
(item2) => item2.name === type2 && item2.schemaName === typeSchema
|
|
2055
|
-
);
|
|
2056
|
-
if (!enumType) {
|
|
2057
|
-
throw new Error(
|
|
2058
|
-
`Cannot handle column ${item.schemaName}.${item.tableName}.${item.name}: column type \`${item.type}\` is not supported`
|
|
2059
|
-
);
|
|
2060
|
-
}
|
|
2061
|
-
column = new RakeDbEnumColumn({}, type2, enumType.values);
|
|
2062
|
-
}
|
|
2063
|
-
if (isArray)
|
|
2064
|
-
column = new pqb.ArrayColumn({}, column);
|
|
2263
|
+
let column = getColumn(data, domains, __spreadProps(__spreadValues({}, item), {
|
|
2264
|
+
type: isArray ? item.type.slice(1) : item.type,
|
|
2265
|
+
isArray,
|
|
2266
|
+
isSerial
|
|
2267
|
+
}));
|
|
2065
2268
|
if ((primaryKey == null ? void 0 : primaryKey.columnNames.length) === 1 && (primaryKey == null ? void 0 : primaryKey.columnNames[0]) === item.name) {
|
|
2066
2269
|
column = column.primaryKey();
|
|
2067
2270
|
}
|
|
@@ -2098,6 +2301,10 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
|
|
|
2098
2301
|
}
|
|
2099
2302
|
);
|
|
2100
2303
|
}
|
|
2304
|
+
const check = columnChecks[item.name];
|
|
2305
|
+
if (check) {
|
|
2306
|
+
column.data.check = orchidCore.raw(check.expression);
|
|
2307
|
+
}
|
|
2101
2308
|
delete column.data.name;
|
|
2102
2309
|
shape[item.name] = column;
|
|
2103
2310
|
}
|
|
@@ -2136,7 +2343,7 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
|
|
|
2136
2343
|
for (const otherKey in pendingTables) {
|
|
2137
2344
|
const item = pendingTables[otherKey];
|
|
2138
2345
|
if (item.dependsOn.delete(key) && item.dependsOn.size === 0) {
|
|
2139
|
-
pushTableAst(ast, data, item.table, pendingTables);
|
|
2346
|
+
pushTableAst(ast, data, domains, item.table, pendingTables);
|
|
2140
2347
|
}
|
|
2141
2348
|
}
|
|
2142
2349
|
};
|
|
@@ -2166,7 +2373,11 @@ const astToMigration = (config, ast) => {
|
|
|
2166
2373
|
} else if (item.type === "enum" && item.action === "create") {
|
|
2167
2374
|
if (first.length)
|
|
2168
2375
|
first.push([]);
|
|
2169
|
-
first.push(
|
|
2376
|
+
first.push(createEnum(item));
|
|
2377
|
+
} else if (item.type === "domain" && item.action === "create") {
|
|
2378
|
+
if (first.length)
|
|
2379
|
+
first.push([]);
|
|
2380
|
+
first.push(...createDomain(item));
|
|
2170
2381
|
} else if (item.type === "table" && item.action === "create") {
|
|
2171
2382
|
tables.push(createTable(config, item));
|
|
2172
2383
|
} else if (item.type === "foreignKey") {
|
|
@@ -2223,12 +2434,26 @@ const createExtension = (ast) => {
|
|
|
2223
2434
|
return code;
|
|
2224
2435
|
};
|
|
2225
2436
|
const createEnum = (ast) => {
|
|
2437
|
+
return `await db.createEnum(${quoteSchemaTable(ast)}, [${ast.values.map(orchidCore.singleQuote).join(", ")}]);`;
|
|
2438
|
+
};
|
|
2439
|
+
const createDomain = (ast) => {
|
|
2226
2440
|
const code = [
|
|
2227
|
-
`await db.
|
|
2441
|
+
`await db.createDomain(${quoteSchemaTable(
|
|
2442
|
+
ast
|
|
2443
|
+
)}, (t) => ${ast.baseType.toCode("t")}`
|
|
2228
2444
|
];
|
|
2229
|
-
if (ast.
|
|
2445
|
+
if (ast.notNull || ast.collation || ast.default || ast.check) {
|
|
2446
|
+
const props = [];
|
|
2447
|
+
if (ast.notNull)
|
|
2448
|
+
props.push(`notNull: true,`);
|
|
2449
|
+
if (ast.collation)
|
|
2450
|
+
props.push(`collation: ${orchidCore.singleQuote(ast.collation)},`);
|
|
2451
|
+
if (ast.default)
|
|
2452
|
+
props.push(`default: ${pqb.rawToCode("db", ast.default)},`);
|
|
2453
|
+
if (ast.check)
|
|
2454
|
+
props.push(`check: ${pqb.rawToCode("db", ast.check)},`);
|
|
2230
2455
|
orchidCore.addCode(code, ", {");
|
|
2231
|
-
code.push(
|
|
2456
|
+
code.push(props);
|
|
2232
2457
|
orchidCore.addCode(code, "}");
|
|
2233
2458
|
}
|
|
2234
2459
|
orchidCore.addCode(code, ");");
|