rake-db 2.3.10 → 2.3.13
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/CHANGELOG.md +22 -0
- package/dist/index.d.ts +111 -7
- package/dist/index.js +221 -120
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +222 -121
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/ast.ts +9 -1
- package/src/commands/migrateOrRollback.ts +3 -3
- package/src/common.ts +2 -2
- package/src/migration/migration.ts +3 -3
- package/src/pull/astToMigration.test.ts +56 -0
- package/src/pull/astToMigration.ts +37 -0
- package/src/pull/structureToAst.test.ts +156 -22
- package/src/pull/structureToAst.ts +256 -150
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# rake-db
|
|
2
2
|
|
|
3
|
+
## 2.3.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ee1961e: Make columnTypes optional in configs
|
|
8
|
+
- Updated dependencies [ee1961e]
|
|
9
|
+
- pqb@0.9.8
|
|
10
|
+
|
|
11
|
+
## 2.3.12
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Handle table ordering by foreign key when pulling db
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- pqb@0.9.7
|
|
18
|
+
|
|
19
|
+
## 2.3.11
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Add generating extension to db pull
|
|
24
|
+
|
|
3
25
|
## 2.3.10
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as pqb from 'pqb';
|
|
2
|
-
import { EmptyObject, RawExpression, ColumnType, ColumnTypes, raw, ColumnsShape, DbResult,
|
|
2
|
+
import { EmptyObject, RawExpression, ColumnType, ColumnTypes, raw, ColumnsShape, DbResult, DefaultColumnTypes, TransactionAdapter, AdapterOptions, TextColumn, MaybeArray, IndexColumnOptions, IndexOptions, ForeignKeyOptions, QueryLogObject, NoPrimaryKeyOption, TableData, SingleColumnIndexOptions, QueryLogOptions } from 'pqb';
|
|
3
3
|
|
|
4
4
|
declare function add(item: ColumnType, options?: {
|
|
5
5
|
dropMode?: DropMode;
|
|
@@ -60,7 +60,7 @@ declare type ExtensionOptions = {
|
|
|
60
60
|
version?: string;
|
|
61
61
|
cascade?: boolean;
|
|
62
62
|
};
|
|
63
|
-
declare type Migration = DbResult<
|
|
63
|
+
declare type Migration = DbResult<DefaultColumnTypes> & MigrationBase;
|
|
64
64
|
declare const createMigrationInterface: (tx: TransactionAdapter, up: boolean, options: RakeDbConfig, adapterOptions: AdapterOptions, appCodeUpdaterCache: object) => pqb.Db<string, Record<string, never>, pqb.RelationsBase, {
|
|
65
65
|
smallint: () => pqb.SmallIntColumn;
|
|
66
66
|
integer: () => pqb.IntegerColumn;
|
|
@@ -105,7 +105,7 @@ declare const createMigrationInterface: (tx: TransactionAdapter, up: boolean, op
|
|
|
105
105
|
xml: () => pqb.XMLColumn;
|
|
106
106
|
json: <Type extends pqb.JSONTypeAny>(schemaOrFn: Type | ((j: {
|
|
107
107
|
set: <Value extends pqb.JSONTypeAny>(valueType: Value) => pqb.JSONSet<Value>;
|
|
108
|
-
tuple: <T_1 extends
|
|
108
|
+
tuple: <T_1 extends pqb.JSONTupleItems | [], Rest extends pqb.JSONTypeAny | null = null>(items: T_1, rest?: Rest) => pqb.JSONTuple<T_1, Rest>;
|
|
109
109
|
union: <T_2 extends [pqb.JSONTypeAny, pqb.JSONTypeAny, ...pqb.JSONTypeAny[]]>(types: T_2) => pqb.JSONUnion<T_2>;
|
|
110
110
|
any: () => pqb.JSONAny;
|
|
111
111
|
bigint: () => pqb.JSONBigInt;
|
|
@@ -204,7 +204,7 @@ declare const createMigrationInterface: (tx: TransactionAdapter, up: boolean, op
|
|
|
204
204
|
xml: () => pqb.XMLColumn;
|
|
205
205
|
json: <Type extends pqb.JSONTypeAny>(schemaOrFn: Type | ((j: {
|
|
206
206
|
set: <Value extends pqb.JSONTypeAny>(valueType: Value) => pqb.JSONSet<Value>;
|
|
207
|
-
tuple: <T_1 extends
|
|
207
|
+
tuple: <T_1 extends pqb.JSONTupleItems | [], Rest extends pqb.JSONTypeAny | null = null>(items: T_1, rest?: Rest) => pqb.JSONTuple<T_1, Rest>;
|
|
208
208
|
union: <T_2 extends [pqb.JSONTypeAny, pqb.JSONTypeAny, ...pqb.JSONTypeAny[]]>(types: T_2) => pqb.JSONUnion<T_2>;
|
|
209
209
|
any: () => pqb.JSONAny;
|
|
210
210
|
bigint: () => pqb.JSONBigInt;
|
|
@@ -258,7 +258,105 @@ declare const createMigrationInterface: (tx: TransactionAdapter, up: boolean, op
|
|
|
258
258
|
<Table extends pqb.ForeignKeyTableWithColumns, Columns extends [Exclude<keyof InstanceType<Table>["columns"]["shape"], number | symbol>, ...Exclude<keyof InstanceType<Table>["columns"]["shape"], number | symbol>[]]>(columns: string[], fn: () => Table, foreignColumns: Columns, options?: ForeignKeyOptions | undefined): {};
|
|
259
259
|
<Table_1 extends string, Columns_1 extends [string, ...string[]]>(columns: string[], table: Table_1, foreignColumns: Columns_1, options?: ForeignKeyOptions | undefined): {};
|
|
260
260
|
};
|
|
261
|
-
}) => Shape) | undefined, options?: pqb.DbTableOptions | undefined): pqb.Db<Table_2, Shape, pqb.RelationsBase,
|
|
261
|
+
}) => Shape) | undefined, options?: pqb.DbTableOptions | undefined): pqb.Db<Table_2, Shape, pqb.RelationsBase, {
|
|
262
|
+
smallint: () => pqb.SmallIntColumn;
|
|
263
|
+
integer: () => pqb.IntegerColumn;
|
|
264
|
+
bigint: () => pqb.BigIntColumn;
|
|
265
|
+
numeric: <Precision extends number | undefined = undefined, Scale extends number | undefined = undefined>(precision?: Precision | undefined, scale?: Scale | undefined) => pqb.DecimalColumn<Precision, Scale>;
|
|
266
|
+
decimal: <Precision_1 extends number | undefined = undefined, Scale_1 extends number | undefined = undefined>(precision?: Precision_1 | undefined, scale?: Scale_1 | undefined) => pqb.DecimalColumn<Precision_1, Scale_1>;
|
|
267
|
+
real: () => pqb.RealColumn;
|
|
268
|
+
doublePrecision: () => pqb.DoublePrecisionColumn;
|
|
269
|
+
smallSerial: () => pqb.SmallSerialColumn;
|
|
270
|
+
serial: () => pqb.SerialColumn;
|
|
271
|
+
bigSerial: () => pqb.BigSerialColumn;
|
|
272
|
+
money: () => pqb.MoneyColumn;
|
|
273
|
+
varchar: <Limit extends number | undefined = undefined>(limit?: Limit | undefined) => pqb.VarCharColumn<Limit>;
|
|
274
|
+
char: <Limit_1 extends number | undefined = undefined>(limit?: Limit_1 | undefined) => pqb.CharColumn<Limit_1>;
|
|
275
|
+
text: (min: number, max: number) => TextColumn;
|
|
276
|
+
string: (min: number, max: number) => TextColumn;
|
|
277
|
+
bytea: () => pqb.ByteaColumn;
|
|
278
|
+
date: () => pqb.DateColumn;
|
|
279
|
+
timestamp: <Precision_2 extends number | undefined = undefined>(precision?: Precision_2 | undefined) => pqb.TimestampColumn<Precision_2>;
|
|
280
|
+
timestampWithTimeZone: <Precision_3 extends number | undefined = undefined>(precision?: Precision_3 | undefined) => pqb.TimestampWithTimeZoneColumn<Precision_3>;
|
|
281
|
+
time: <Precision_4 extends number | undefined = undefined>(precision?: Precision_4 | undefined) => pqb.TimeColumn<Precision_4>;
|
|
282
|
+
timeWithTimeZone: <Precision_5 extends number | undefined = undefined>(precision?: Precision_5 | undefined) => pqb.TimeWithTimeZoneColumn<Precision_5>;
|
|
283
|
+
interval: <Fields extends string | undefined = undefined, Precision_6 extends number | undefined = undefined>(fields?: Fields | undefined, precision?: Precision_6 | undefined) => pqb.IntervalColumn<Fields, Precision_6>;
|
|
284
|
+
boolean: () => pqb.BooleanColumn;
|
|
285
|
+
enum: <U extends string, T extends [U, ...U[]]>(dataType: string, type: T) => pqb.EnumColumn<U, T>;
|
|
286
|
+
point: () => pqb.PointColumn;
|
|
287
|
+
line: () => pqb.LineColumn;
|
|
288
|
+
lseg: () => pqb.LsegColumn;
|
|
289
|
+
box: () => pqb.BoxColumn;
|
|
290
|
+
path: () => pqb.PathColumn;
|
|
291
|
+
polygon: () => pqb.PolygonColumn;
|
|
292
|
+
circle: () => pqb.CircleColumn;
|
|
293
|
+
cidr: () => pqb.CidrColumn;
|
|
294
|
+
inet: () => pqb.InetColumn;
|
|
295
|
+
macaddr: () => pqb.MacAddrColumn;
|
|
296
|
+
macaddr8: () => pqb.MacAddr8Column;
|
|
297
|
+
bit: <Length extends number>(length: Length) => pqb.BitColumn<Length>;
|
|
298
|
+
bitVarying: <Length_1 extends number | undefined = undefined>(length?: Length_1 | undefined) => pqb.BitVaryingColumn<Length_1>;
|
|
299
|
+
tsvector: () => pqb.TsVectorColumn;
|
|
300
|
+
tsquery: () => pqb.TsQueryColumn;
|
|
301
|
+
uuid: () => pqb.UUIDColumn;
|
|
302
|
+
xml: () => pqb.XMLColumn;
|
|
303
|
+
json: <Type extends pqb.JSONTypeAny>(schemaOrFn: Type | ((j: {
|
|
304
|
+
set: <Value extends pqb.JSONTypeAny>(valueType: Value) => pqb.JSONSet<Value>;
|
|
305
|
+
tuple: <T_1 extends pqb.JSONTupleItems | [], Rest extends pqb.JSONTypeAny | null = null>(items: T_1, rest?: Rest) => pqb.JSONTuple<T_1, Rest>;
|
|
306
|
+
union: <T_2 extends [pqb.JSONTypeAny, pqb.JSONTypeAny, ...pqb.JSONTypeAny[]]>(types: T_2) => pqb.JSONUnion<T_2>;
|
|
307
|
+
any: () => pqb.JSONAny;
|
|
308
|
+
bigint: () => pqb.JSONBigInt;
|
|
309
|
+
boolean: () => pqb.JSONBoolean;
|
|
310
|
+
date: () => pqb.JSONDate;
|
|
311
|
+
nan: () => pqb.JSONNaN;
|
|
312
|
+
never: () => pqb.JSONNever;
|
|
313
|
+
null: () => pqb.JSONNull;
|
|
314
|
+
number: () => pqb.JSONNumber;
|
|
315
|
+
string: () => pqb.JSONString;
|
|
316
|
+
undefined: () => pqb.JSONUndefined;
|
|
317
|
+
unknown: () => pqb.JSONUnknown;
|
|
318
|
+
void: () => pqb.JSONVoid;
|
|
319
|
+
array: <Type_1 extends pqb.JSONTypeAny>(element: Type_1) => pqb.JSONArray<Type_1, "many">;
|
|
320
|
+
discriminatedUnion: <Discriminator extends string, DiscriminatorValue extends pqb.Primitive, Types extends [pqb.JSONDiscriminatedObject<Discriminator, DiscriminatorValue>, pqb.JSONDiscriminatedObject<Discriminator, DiscriminatorValue>, ...pqb.JSONDiscriminatedObject<Discriminator, DiscriminatorValue>[]]>(discriminator: Discriminator, options: Types) => pqb.JSONDiscriminatedUnion<Discriminator, DiscriminatorValue, Types[number]>;
|
|
321
|
+
enum: <U_1 extends string, T_3 extends [U_1, ...U_1[]]>(options: T_3) => pqb.JSONEnum<U_1, T_3>;
|
|
322
|
+
instanceOf: <T_4 extends new (...args: any[]) => any>(cls: T_4) => pqb.JSONInstanceOf<T_4>;
|
|
323
|
+
intersection: <Left extends pqb.JSONTypeAny, Right extends pqb.JSONTypeAny>(left: Left, right: Right) => pqb.JSONIntersection<Left, Right>;
|
|
324
|
+
lazy: <T_5 extends pqb.JSONTypeAny>(fn: () => T_5) => pqb.JSONLazy<T_5>;
|
|
325
|
+
literal: <T_6 extends pqb.Primitive>(value: T_6) => pqb.JSONLiteral<T_6>;
|
|
326
|
+
map: <Key extends pqb.JSONTypeAny, Value_1 extends pqb.JSONTypeAny>(keyType: Key, valueType: Value_1) => pqb.JSONMap<Key, Value_1>;
|
|
327
|
+
nativeEnum: <T_7 extends pqb.EnumLike>(givenEnum: T_7) => pqb.JSONNativeEnum<T_7>;
|
|
328
|
+
nullable: <T_8 extends pqb.JSONTypeAny>(type: T_8) => pqb.JSONNullable<T_8>;
|
|
329
|
+
nullish: <T_9 extends pqb.JSONTypeAny>(type: T_9) => pqb.JSONNullish<T_9>;
|
|
330
|
+
object: <T_10 extends pqb.JSONObjectShape, UnknownKeys extends pqb.UnknownKeysParam = "strip", Catchall extends pqb.JSONTypeAny = pqb.JSONTypeAny>(shape: T_10) => pqb.JSONObject<T_10, UnknownKeys, Catchall, pqb.JSONTypeAny extends Catchall ? pqb.addQuestionMarks<{ [k_1 in keyof T_10]: T_10[k_1]["type"]; }> extends infer T_11 extends object ? { [k in keyof T_11]: pqb.addQuestionMarks<{ [k_1 in keyof T_10]: T_10[k_1]["type"]; }>[k]; } : never : (pqb.addQuestionMarks<{ [k_1 in keyof T_10]: T_10[k_1]["type"]; }> extends infer T_11 extends object ? { [k in keyof T_11]: pqb.addQuestionMarks<{ [k_1 in keyof T_10]: T_10[k_1]["type"]; }>[k]; } : never) & {
|
|
331
|
+
[k: string]: Catchall["type"];
|
|
332
|
+
} extends infer T_12 extends object ? { [k_2 in keyof T_12]: ((pqb.addQuestionMarks<{ [k_1 in keyof T_10]: T_10[k_1]["type"]; }> extends infer T_11 extends object ? { [k in keyof T_11]: pqb.addQuestionMarks<{ [k_1 in keyof T_10]: T_10[k_1]["type"]; }>[k]; } : never) & {
|
|
333
|
+
[k: string]: Catchall["type"];
|
|
334
|
+
})[k_2]; } : never>;
|
|
335
|
+
optional: <T_13 extends pqb.JSONTypeAny>(type: T_13) => pqb.JSONOptional<T_13>;
|
|
336
|
+
record: typeof pqb.record;
|
|
337
|
+
}) => Type)) => pqb.JSONColumn<Type>;
|
|
338
|
+
jsonText: () => pqb.JSONTextColumn;
|
|
339
|
+
array: <Item extends ColumnType<unknown, pqb.Operators, unknown>>(item: Item) => pqb.ArrayColumn<Item>;
|
|
340
|
+
timestamps: <T_14 extends ColumnType<unknown, pqb.Operators, unknown>>(this: {
|
|
341
|
+
timestamp(): T_14;
|
|
342
|
+
}) => {
|
|
343
|
+
createdAt: T_14 & {
|
|
344
|
+
hasDefault: true;
|
|
345
|
+
};
|
|
346
|
+
updatedAt: T_14 & {
|
|
347
|
+
hasDefault: true;
|
|
348
|
+
};
|
|
349
|
+
};
|
|
350
|
+
primaryKey(columns: string[], options?: {
|
|
351
|
+
name?: string | undefined;
|
|
352
|
+
} | undefined): {};
|
|
353
|
+
index(columns: MaybeArray<string | IndexColumnOptions>, options?: IndexOptions): {};
|
|
354
|
+
unique(columns: MaybeArray<string | IndexColumnOptions>, options?: IndexOptions): {};
|
|
355
|
+
foreignKey: {
|
|
356
|
+
<Table extends pqb.ForeignKeyTableWithColumns, Columns extends [Exclude<keyof InstanceType<Table>["columns"]["shape"], number | symbol>, ...Exclude<keyof InstanceType<Table>["columns"]["shape"], number | symbol>[]]>(columns: string[], fn: () => Table, foreignColumns: Columns, options?: ForeignKeyOptions | undefined): {};
|
|
357
|
+
<Table_1 extends string, Columns_1 extends [string, ...string[]]>(columns: string[], table: Table_1, foreignColumns: Columns_1, options?: ForeignKeyOptions | undefined): {};
|
|
358
|
+
};
|
|
359
|
+
}>;
|
|
262
360
|
adapter: pqb.Adapter;
|
|
263
361
|
close: () => Promise<void>;
|
|
264
362
|
} & MigrationBase & {
|
|
@@ -311,7 +409,7 @@ declare class MigrationBase {
|
|
|
311
409
|
}
|
|
312
410
|
declare const runCodeUpdater: (migration: MigrationBase, ast: RakeDbAst) => Promise<void> | undefined;
|
|
313
411
|
|
|
314
|
-
declare type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameTable | RakeDbAst.Schema | RakeDbAst.Extension;
|
|
412
|
+
declare type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameTable | RakeDbAst.Schema | RakeDbAst.Extension | RakeDbAst.ForeignKey;
|
|
315
413
|
declare namespace RakeDbAst {
|
|
316
414
|
type Table = {
|
|
317
415
|
type: 'table';
|
|
@@ -387,9 +485,15 @@ declare namespace RakeDbAst {
|
|
|
387
485
|
ifExists?: boolean;
|
|
388
486
|
ifNotExists?: boolean;
|
|
389
487
|
};
|
|
488
|
+
type ForeignKey = {
|
|
489
|
+
type: 'foreignKey';
|
|
490
|
+
action: 'create';
|
|
491
|
+
tableSchema?: string;
|
|
492
|
+
tableName: string;
|
|
493
|
+
} & TableData.ForeignKey;
|
|
390
494
|
}
|
|
391
495
|
|
|
392
|
-
declare type Db = DbResult<
|
|
496
|
+
declare type Db = DbResult<DefaultColumnTypes>;
|
|
393
497
|
declare type RakeDbConfig = {
|
|
394
498
|
migrationsPath: string;
|
|
395
499
|
migrationsTable: string;
|
package/dist/index.js
CHANGED
|
@@ -928,7 +928,7 @@ const createMigrationInterface = (tx, up, options, adapterOptions, appCodeUpdate
|
|
|
928
928
|
adapter.arrays = (q, types) => {
|
|
929
929
|
return wrapWithLog(log, q, () => arrays.call(adapter, q, types));
|
|
930
930
|
};
|
|
931
|
-
const db = pqb.createDb({ adapter
|
|
931
|
+
const db = pqb.createDb({ adapter });
|
|
932
932
|
const { prototype: proto } = MigrationBase;
|
|
933
933
|
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
934
934
|
db[key] = proto[key];
|
|
@@ -1030,10 +1030,10 @@ class MigrationBase {
|
|
|
1030
1030
|
return createSchema$1(this, !this.up, schemaName);
|
|
1031
1031
|
}
|
|
1032
1032
|
createExtension(name, options = {}) {
|
|
1033
|
-
return createExtension(this, this.up, name, options);
|
|
1033
|
+
return createExtension$1(this, this.up, name, options);
|
|
1034
1034
|
}
|
|
1035
1035
|
dropExtension(name, options = {}) {
|
|
1036
|
-
return createExtension(this, !this.up, name, options);
|
|
1036
|
+
return createExtension$1(this, !this.up, name, options);
|
|
1037
1037
|
}
|
|
1038
1038
|
async tableExists(tableName) {
|
|
1039
1039
|
return queryExists(this, {
|
|
@@ -1095,7 +1095,7 @@ const createSchema$1 = async (migration, up, name) => {
|
|
|
1095
1095
|
);
|
|
1096
1096
|
await runCodeUpdater(migration, ast);
|
|
1097
1097
|
};
|
|
1098
|
-
const createExtension = async (migration, up, name, options) => {
|
|
1098
|
+
const createExtension$1 = async (migration, up, name, options) => {
|
|
1099
1099
|
const ast = __spreadValues$2({
|
|
1100
1100
|
type: "extension",
|
|
1101
1101
|
action: up ? "create" : "drop",
|
|
@@ -1138,7 +1138,7 @@ var __spreadValues$1 = (a, b) => {
|
|
|
1138
1138
|
}
|
|
1139
1139
|
return a;
|
|
1140
1140
|
};
|
|
1141
|
-
const getDb = (adapter) => pqb.createDb({ adapter
|
|
1141
|
+
const getDb = (adapter) => pqb.createDb({ adapter });
|
|
1142
1142
|
const migrateOrRollback = async (options, config, args, up) => {
|
|
1143
1143
|
var _a, _b, _c, _d, _e;
|
|
1144
1144
|
config = __spreadValues$1({}, config);
|
|
@@ -1718,24 +1718,8 @@ const fkeyActionMap = {
|
|
|
1718
1718
|
};
|
|
1719
1719
|
const structureToAst = async (db) => {
|
|
1720
1720
|
const ast = [];
|
|
1721
|
-
const
|
|
1722
|
-
|
|
1723
|
-
tables,
|
|
1724
|
-
allColumns,
|
|
1725
|
-
allPrimaryKeys,
|
|
1726
|
-
allIndexes,
|
|
1727
|
-
allForeignKeys,
|
|
1728
|
-
extensions
|
|
1729
|
-
] = await Promise.all([
|
|
1730
|
-
db.getSchemas(),
|
|
1731
|
-
db.getTables(),
|
|
1732
|
-
db.getColumns(),
|
|
1733
|
-
db.getPrimaryKeys(),
|
|
1734
|
-
db.getIndexes(),
|
|
1735
|
-
db.getForeignKeys(),
|
|
1736
|
-
db.getExtensions()
|
|
1737
|
-
]);
|
|
1738
|
-
for (const name of schemas) {
|
|
1721
|
+
const data = await getData(db);
|
|
1722
|
+
for (const name of data.schemas) {
|
|
1739
1723
|
if (name === "public")
|
|
1740
1724
|
continue;
|
|
1741
1725
|
ast.push({
|
|
@@ -1744,108 +1728,51 @@ const structureToAst = async (db) => {
|
|
|
1744
1728
|
name
|
|
1745
1729
|
});
|
|
1746
1730
|
}
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
for (let item of columns) {
|
|
1758
|
-
const isSerial = getIsSerial(item);
|
|
1759
|
-
if (isSerial) {
|
|
1760
|
-
item = __spreadProps(__spreadValues({}, item), { default: void 0 });
|
|
1761
|
-
}
|
|
1762
|
-
const klass = pqb.columnsByType[getColumnType(item, isSerial)];
|
|
1763
|
-
if (!klass) {
|
|
1764
|
-
throw new Error(`Column type \`${item.type}\` is not supported`);
|
|
1731
|
+
const pendingTables = {};
|
|
1732
|
+
for (const table of data.tables) {
|
|
1733
|
+
const key = `${table.schemaName}.${table.name}`;
|
|
1734
|
+
const dependsOn = /* @__PURE__ */ new Set();
|
|
1735
|
+
for (const fk of data.foreignKeys) {
|
|
1736
|
+
if (fk.schemaName !== table.schemaName || fk.tableName !== table.name)
|
|
1737
|
+
continue;
|
|
1738
|
+
const otherKey = `${fk.foreignTableSchemaName}.${fk.foreignTableName}`;
|
|
1739
|
+
if (otherKey !== key) {
|
|
1740
|
+
dependsOn.add(otherKey);
|
|
1765
1741
|
}
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
);
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
}
|
|
1788
|
-
const foreignKeys = tableForeignKeys.filter(
|
|
1789
|
-
(it) => it.columnNames.length === 1 && it.columnNames[0] === item.name
|
|
1790
|
-
);
|
|
1791
|
-
for (const foreignKey of foreignKeys) {
|
|
1792
|
-
column = column.foreignKey(
|
|
1793
|
-
foreignKey.foreignTableName,
|
|
1794
|
-
foreignKey.foreignColumnNames[0],
|
|
1795
|
-
{
|
|
1796
|
-
name: foreignKey.name && foreignKey.name !== getForeignKeyName(name, foreignKey.columnNames) ? foreignKey.name : void 0,
|
|
1797
|
-
match: matchMap[foreignKey.match],
|
|
1798
|
-
onUpdate: fkeyActionMap[foreignKey.onUpdate],
|
|
1799
|
-
onDelete: fkeyActionMap[foreignKey.onDelete]
|
|
1800
|
-
}
|
|
1801
|
-
);
|
|
1742
|
+
}
|
|
1743
|
+
pendingTables[key] = { table, dependsOn };
|
|
1744
|
+
}
|
|
1745
|
+
for (const key in pendingTables) {
|
|
1746
|
+
const { table, dependsOn } = pendingTables[key];
|
|
1747
|
+
if (!dependsOn.size) {
|
|
1748
|
+
pushTableAst(ast, data, table, pendingTables);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
const outerFKeys = [];
|
|
1752
|
+
for (const key in pendingTables) {
|
|
1753
|
+
const innerFKeys = [];
|
|
1754
|
+
const { table } = pendingTables[key];
|
|
1755
|
+
for (const fkey of data.foreignKeys) {
|
|
1756
|
+
if (fkey.schemaName !== table.schemaName || fkey.tableName !== table.name)
|
|
1757
|
+
continue;
|
|
1758
|
+
const otherKey = `${fkey.foreignTableSchemaName}.${fkey.foreignTableName}`;
|
|
1759
|
+
if (!pendingTables[otherKey] || otherKey === key) {
|
|
1760
|
+
innerFKeys.push(fkey);
|
|
1761
|
+
} else {
|
|
1762
|
+
outerFKeys.push([fkey, table]);
|
|
1802
1763
|
}
|
|
1803
|
-
shape[item.name] = column;
|
|
1804
1764
|
}
|
|
1805
|
-
ast
|
|
1806
|
-
|
|
1765
|
+
pushTableAst(ast, data, table, pendingTables, innerFKeys);
|
|
1766
|
+
}
|
|
1767
|
+
for (const [fkey, table] of outerFKeys) {
|
|
1768
|
+
ast.push(__spreadProps(__spreadValues({}, foreignKeyToAst(fkey)), {
|
|
1769
|
+
type: "foreignKey",
|
|
1807
1770
|
action: "create",
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
shape,
|
|
1812
|
-
noPrimaryKey: primaryKey ? "error" : "ignore",
|
|
1813
|
-
primaryKey: primaryKey && primaryKey.columnNames.length > 1 ? {
|
|
1814
|
-
columns: primaryKey.columnNames,
|
|
1815
|
-
options: primaryKey.name === `${name}_pkey` ? void 0 : { name: primaryKey.name }
|
|
1816
|
-
} : void 0,
|
|
1817
|
-
indexes: tableIndexes.filter(
|
|
1818
|
-
(index) => index.columns.length > 1 || index.columns.some((it) => "expression" in it)
|
|
1819
|
-
).map((index) => ({
|
|
1820
|
-
columns: index.columns.map((it) => __spreadProps(__spreadValues({}, "column" in it ? { column: it.column } : { expression: it.expression }), {
|
|
1821
|
-
collate: it.collate,
|
|
1822
|
-
opclass: it.opclass,
|
|
1823
|
-
order: it.order
|
|
1824
|
-
})),
|
|
1825
|
-
options: {
|
|
1826
|
-
name: index.name !== getIndexName(name, index.columns) ? index.name : void 0,
|
|
1827
|
-
using: index.using === "btree" ? void 0 : index.using,
|
|
1828
|
-
unique: index.isUnique,
|
|
1829
|
-
include: index.include,
|
|
1830
|
-
with: index.with,
|
|
1831
|
-
tablespace: index.tablespace,
|
|
1832
|
-
where: index.where
|
|
1833
|
-
}
|
|
1834
|
-
})),
|
|
1835
|
-
foreignKeys: tableForeignKeys.filter((it) => it.columnNames.length > 1).map((it) => ({
|
|
1836
|
-
columns: it.columnNames,
|
|
1837
|
-
fnOrTable: it.foreignTableName,
|
|
1838
|
-
foreignColumns: it.foreignColumnNames,
|
|
1839
|
-
options: {
|
|
1840
|
-
name: it.name && it.name !== getForeignKeyName(name, it.columnNames) ? it.name : void 0,
|
|
1841
|
-
match: matchMap[it.match],
|
|
1842
|
-
onUpdate: fkeyActionMap[it.onUpdate],
|
|
1843
|
-
onDelete: fkeyActionMap[it.onDelete]
|
|
1844
|
-
}
|
|
1845
|
-
}))
|
|
1846
|
-
});
|
|
1771
|
+
tableSchema: table.schemaName === "public" ? void 0 : table.schemaName,
|
|
1772
|
+
tableName: fkey.tableName
|
|
1773
|
+
}));
|
|
1847
1774
|
}
|
|
1848
|
-
for (const it of extensions) {
|
|
1775
|
+
for (const it of data.extensions) {
|
|
1849
1776
|
ast.push({
|
|
1850
1777
|
type: "extension",
|
|
1851
1778
|
action: "create",
|
|
@@ -1856,6 +1783,34 @@ const structureToAst = async (db) => {
|
|
|
1856
1783
|
}
|
|
1857
1784
|
return ast;
|
|
1858
1785
|
};
|
|
1786
|
+
const getData = async (db) => {
|
|
1787
|
+
const [
|
|
1788
|
+
schemas,
|
|
1789
|
+
tables,
|
|
1790
|
+
columns,
|
|
1791
|
+
primaryKeys,
|
|
1792
|
+
indexes,
|
|
1793
|
+
foreignKeys,
|
|
1794
|
+
extensions
|
|
1795
|
+
] = await Promise.all([
|
|
1796
|
+
db.getSchemas(),
|
|
1797
|
+
db.getTables(),
|
|
1798
|
+
db.getColumns(),
|
|
1799
|
+
db.getPrimaryKeys(),
|
|
1800
|
+
db.getIndexes(),
|
|
1801
|
+
db.getForeignKeys(),
|
|
1802
|
+
db.getExtensions()
|
|
1803
|
+
]);
|
|
1804
|
+
return {
|
|
1805
|
+
schemas,
|
|
1806
|
+
tables,
|
|
1807
|
+
columns,
|
|
1808
|
+
primaryKeys,
|
|
1809
|
+
indexes,
|
|
1810
|
+
foreignKeys,
|
|
1811
|
+
extensions
|
|
1812
|
+
};
|
|
1813
|
+
};
|
|
1859
1814
|
const makeBelongsToTable = (schema, table) => (item) => item.schemaName === schema && item.tableName === table;
|
|
1860
1815
|
const getIsSerial = (item) => {
|
|
1861
1816
|
if (item.type === "int2" || item.type === "int4" || item.type === "int8") {
|
|
@@ -1873,16 +1828,134 @@ const getColumnType = (item, isSerial) => {
|
|
|
1873
1828
|
}
|
|
1874
1829
|
return item.type;
|
|
1875
1830
|
};
|
|
1831
|
+
const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreignKeys) => {
|
|
1832
|
+
const { schemaName, name } = table;
|
|
1833
|
+
const key = `${schemaName}.${table.name}`;
|
|
1834
|
+
delete pendingTables[key];
|
|
1835
|
+
if (name === "schemaMigrations")
|
|
1836
|
+
return;
|
|
1837
|
+
const belongsToTable = makeBelongsToTable(schemaName, name);
|
|
1838
|
+
const columns = data.columns.filter(belongsToTable);
|
|
1839
|
+
const primaryKey = data.primaryKeys.find(belongsToTable);
|
|
1840
|
+
const tableIndexes = data.indexes.filter(belongsToTable);
|
|
1841
|
+
const tableForeignKeys = innerFKeys.filter(belongsToTable);
|
|
1842
|
+
const shape = {};
|
|
1843
|
+
for (let item of columns) {
|
|
1844
|
+
const isSerial = getIsSerial(item);
|
|
1845
|
+
if (isSerial) {
|
|
1846
|
+
item = __spreadProps(__spreadValues({}, item), { default: void 0 });
|
|
1847
|
+
}
|
|
1848
|
+
const klass = pqb.columnsByType[getColumnType(item, isSerial)];
|
|
1849
|
+
if (!klass) {
|
|
1850
|
+
throw new Error(`Column type \`${item.type}\` is not supported`);
|
|
1851
|
+
}
|
|
1852
|
+
let column = pqb.instantiateColumn(klass, item);
|
|
1853
|
+
if ((primaryKey == null ? void 0 : primaryKey.columnNames.length) === 1 && (primaryKey == null ? void 0 : primaryKey.columnNames[0]) === item.name) {
|
|
1854
|
+
column = column.primaryKey();
|
|
1855
|
+
}
|
|
1856
|
+
const indexes = tableIndexes.filter(
|
|
1857
|
+
(it) => it.columns.length === 1 && "column" in it.columns[0] && it.columns[0].column === item.name
|
|
1858
|
+
);
|
|
1859
|
+
for (const index of indexes) {
|
|
1860
|
+
const options = index.columns[0];
|
|
1861
|
+
column = column.index({
|
|
1862
|
+
collate: options.collate,
|
|
1863
|
+
opclass: options.opclass,
|
|
1864
|
+
order: options.order,
|
|
1865
|
+
name: index.name !== getIndexName(name, index.columns) ? index.name : void 0,
|
|
1866
|
+
using: index.using === "btree" ? void 0 : index.using,
|
|
1867
|
+
unique: index.isUnique,
|
|
1868
|
+
include: index.include,
|
|
1869
|
+
with: index.with,
|
|
1870
|
+
tablespace: index.tablespace,
|
|
1871
|
+
where: index.where
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
const foreignKeys = tableForeignKeys.filter(
|
|
1875
|
+
(it) => it.columnNames.length === 1 && it.columnNames[0] === item.name
|
|
1876
|
+
);
|
|
1877
|
+
for (const foreignKey of foreignKeys) {
|
|
1878
|
+
column = column.foreignKey(
|
|
1879
|
+
foreignKey.foreignTableName,
|
|
1880
|
+
foreignKey.foreignColumnNames[0],
|
|
1881
|
+
{
|
|
1882
|
+
name: foreignKey.name && foreignKey.name !== getForeignKeyName(name, foreignKey.columnNames) ? foreignKey.name : void 0,
|
|
1883
|
+
match: matchMap[foreignKey.match],
|
|
1884
|
+
onUpdate: fkeyActionMap[foreignKey.onUpdate],
|
|
1885
|
+
onDelete: fkeyActionMap[foreignKey.onDelete]
|
|
1886
|
+
}
|
|
1887
|
+
);
|
|
1888
|
+
}
|
|
1889
|
+
shape[item.name] = column;
|
|
1890
|
+
}
|
|
1891
|
+
ast.push({
|
|
1892
|
+
type: "table",
|
|
1893
|
+
action: "create",
|
|
1894
|
+
schema: schemaName === "public" ? void 0 : schemaName,
|
|
1895
|
+
comment: table.comment,
|
|
1896
|
+
name,
|
|
1897
|
+
shape,
|
|
1898
|
+
noPrimaryKey: primaryKey ? "error" : "ignore",
|
|
1899
|
+
primaryKey: primaryKey && primaryKey.columnNames.length > 1 ? {
|
|
1900
|
+
columns: primaryKey.columnNames,
|
|
1901
|
+
options: primaryKey.name === `${name}_pkey` ? void 0 : { name: primaryKey.name }
|
|
1902
|
+
} : void 0,
|
|
1903
|
+
indexes: tableIndexes.filter(
|
|
1904
|
+
(index) => index.columns.length > 1 || index.columns.some((it) => "expression" in it)
|
|
1905
|
+
).map((index) => ({
|
|
1906
|
+
columns: index.columns.map((it) => __spreadProps(__spreadValues({}, "column" in it ? { column: it.column } : { expression: it.expression }), {
|
|
1907
|
+
collate: it.collate,
|
|
1908
|
+
opclass: it.opclass,
|
|
1909
|
+
order: it.order
|
|
1910
|
+
})),
|
|
1911
|
+
options: {
|
|
1912
|
+
name: index.name !== getIndexName(name, index.columns) ? index.name : void 0,
|
|
1913
|
+
using: index.using === "btree" ? void 0 : index.using,
|
|
1914
|
+
unique: index.isUnique,
|
|
1915
|
+
include: index.include,
|
|
1916
|
+
with: index.with,
|
|
1917
|
+
tablespace: index.tablespace,
|
|
1918
|
+
where: index.where
|
|
1919
|
+
}
|
|
1920
|
+
})),
|
|
1921
|
+
foreignKeys: tableForeignKeys.filter((it) => it.columnNames.length > 1).map(foreignKeyToAst)
|
|
1922
|
+
});
|
|
1923
|
+
for (const otherKey in pendingTables) {
|
|
1924
|
+
const item = pendingTables[otherKey];
|
|
1925
|
+
if (item.dependsOn.delete(key) && item.dependsOn.size === 0) {
|
|
1926
|
+
pushTableAst(ast, data, item.table, pendingTables);
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
};
|
|
1930
|
+
const foreignKeyToAst = (fkey) => ({
|
|
1931
|
+
columns: fkey.columnNames,
|
|
1932
|
+
fnOrTable: fkey.foreignTableName,
|
|
1933
|
+
foreignColumns: fkey.foreignColumnNames,
|
|
1934
|
+
options: {
|
|
1935
|
+
name: fkey.name && fkey.name !== getForeignKeyName(fkey.tableName, fkey.columnNames) ? fkey.name : void 0,
|
|
1936
|
+
match: matchMap[fkey.match],
|
|
1937
|
+
onUpdate: fkeyActionMap[fkey.onUpdate],
|
|
1938
|
+
onDelete: fkeyActionMap[fkey.onDelete]
|
|
1939
|
+
}
|
|
1940
|
+
});
|
|
1876
1941
|
|
|
1877
1942
|
const astToMigration = (ast) => {
|
|
1878
1943
|
const code = [];
|
|
1879
1944
|
for (const item of ast) {
|
|
1880
1945
|
if (item.type === "schema" && item.action === "create") {
|
|
1881
1946
|
code.push(createSchema(item));
|
|
1947
|
+
} else if (item.type === "extension" && item.action === "create") {
|
|
1948
|
+
if (code.length)
|
|
1949
|
+
code.push([]);
|
|
1950
|
+
code.push(...createExtension(item));
|
|
1882
1951
|
} else if (item.type === "table" && item.action === "create") {
|
|
1883
1952
|
if (code.length)
|
|
1884
1953
|
code.push([]);
|
|
1885
1954
|
code.push(...createTable(item));
|
|
1955
|
+
} else if (item.type === "foreignKey") {
|
|
1956
|
+
if (code.length)
|
|
1957
|
+
code.push([]);
|
|
1958
|
+
code.push(...createForeignKey(item));
|
|
1886
1959
|
}
|
|
1887
1960
|
}
|
|
1888
1961
|
if (!code.length)
|
|
@@ -1897,6 +1970,21 @@ ${pqb.codeToString(code, " ", " ")}
|
|
|
1897
1970
|
const createSchema = (ast) => {
|
|
1898
1971
|
return `await db.createSchema(${pqb.singleQuote(ast.name)});`;
|
|
1899
1972
|
};
|
|
1973
|
+
const createExtension = (ast) => {
|
|
1974
|
+
const code = [`await db.createExtension(${pqb.singleQuote(ast.name)}`];
|
|
1975
|
+
if (ast.schema || ast.version) {
|
|
1976
|
+
pqb.addCode(code, ", {");
|
|
1977
|
+
if (ast.schema) {
|
|
1978
|
+
code.push([`schema: ${pqb.singleQuote(ast.schema)},`]);
|
|
1979
|
+
}
|
|
1980
|
+
if (ast.version) {
|
|
1981
|
+
code.push([`version: ${pqb.singleQuote(ast.version)},`]);
|
|
1982
|
+
}
|
|
1983
|
+
pqb.addCode(code, "}");
|
|
1984
|
+
}
|
|
1985
|
+
pqb.addCode(code, ")");
|
|
1986
|
+
return code;
|
|
1987
|
+
};
|
|
1900
1988
|
const createTable = (ast) => {
|
|
1901
1989
|
const code = [];
|
|
1902
1990
|
pqb.addCode(code, `await db.createTable(${quoteSchemaTable(ast)}, (t) => ({`);
|
|
@@ -1932,6 +2020,19 @@ const isTimestamp = (column) => {
|
|
|
1932
2020
|
const { default: def } = column.data;
|
|
1933
2021
|
return column instanceof pqb.TimestampColumn && !column.data.isNullable && def && typeof def === "object" && pqb.isRaw(def) && def.__raw === "now()";
|
|
1934
2022
|
};
|
|
2023
|
+
const createForeignKey = (item) => {
|
|
2024
|
+
return [
|
|
2025
|
+
`await db.addForeignKey(`,
|
|
2026
|
+
[
|
|
2027
|
+
`${quoteSchemaTable({
|
|
2028
|
+
schema: item.tableSchema,
|
|
2029
|
+
name: item.tableName
|
|
2030
|
+
})},`,
|
|
2031
|
+
...pqb.foreignKeyArgsToCode(item)
|
|
2032
|
+
],
|
|
2033
|
+
");"
|
|
2034
|
+
];
|
|
2035
|
+
};
|
|
1935
2036
|
|
|
1936
2037
|
const pullDbStructure = async (options, config) => {
|
|
1937
2038
|
const adapter = new pqb.Adapter(options);
|