rake-db 2.30.9 → 2.31.0
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 +161 -87
- package/dist/index.js +987 -922
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +871 -806
- package/dist/index.mjs.map +1 -1
- package/dist/node-postgres.d.ts +1 -1
- package/dist/node-postgres.js +2 -2
- package/dist/node-postgres.js.map +1 -1
- package/dist/node-postgres.mjs +1 -1
- package/dist/node-postgres.mjs.map +1 -1
- package/dist/postgres-js.d.ts +1 -1
- package/dist/postgres-js.js +2 -2
- package/dist/postgres-js.js.map +1 -1
- package/dist/postgres-js.mjs +1 -1
- package/dist/postgres-js.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,249 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var internal = require('pqb/internal');
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var node_url = require('node:url');
|
|
6
6
|
var fs = require('fs/promises');
|
|
7
|
-
|
|
8
|
-
const ESC = "\x1B";
|
|
9
|
-
const CSI = `${ESC}[`;
|
|
10
|
-
const cursorShow = `${CSI}?25h`;
|
|
11
|
-
const cursorHide = `${CSI}?25l`;
|
|
12
|
-
const { stdin, stdout } = process;
|
|
13
|
-
const visibleChars = (s) => s.replace(
|
|
14
|
-
// eslint-disable-next-line no-control-regex
|
|
15
|
-
/[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d/#&.:=?%@~_]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PRZcf-ntqry=><~]))/g,
|
|
16
|
-
""
|
|
17
|
-
).length;
|
|
18
|
-
const clear = (text) => {
|
|
19
|
-
const rows = text.split(/\r?\n/).reduce(
|
|
20
|
-
(rows2, line) => rows2 + 1 + Math.floor(Math.max(visibleChars(line) - 1, 0) / stdout.columns),
|
|
21
|
-
0
|
|
22
|
-
);
|
|
23
|
-
let clear2 = "";
|
|
24
|
-
for (let i = 0; i < rows; i++) {
|
|
25
|
-
clear2 += `${CSI}2K`;
|
|
26
|
-
if (i < rows - 1) {
|
|
27
|
-
clear2 += `${CSI}${i < rows - 1 ? "1A" : "G"}`;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return clear2;
|
|
31
|
-
};
|
|
32
|
-
const prompt = async ({
|
|
33
|
-
render,
|
|
34
|
-
onKeyPress,
|
|
35
|
-
validate,
|
|
36
|
-
value,
|
|
37
|
-
cursor: showCursor
|
|
38
|
-
}) => {
|
|
39
|
-
stdin.resume();
|
|
40
|
-
if (stdin.isTTY) stdin.setRawMode(true);
|
|
41
|
-
stdin.setEncoding("utf-8");
|
|
42
|
-
if (!showCursor) stdout.write(cursorHide);
|
|
43
|
-
return new Promise((res) => {
|
|
44
|
-
let prevText;
|
|
45
|
-
const ctx = {
|
|
46
|
-
value,
|
|
47
|
-
submitted: false,
|
|
48
|
-
render() {
|
|
49
|
-
let text = (ctx.submitted ? pqb.colors.greenBold("\u2714") : pqb.colors.yellowBold("?")) + " " + render(ctx);
|
|
50
|
-
if (ctx.submitted) text += "\n";
|
|
51
|
-
stdout.write(prevText ? clear(prevText) + "\r" + text : text);
|
|
52
|
-
prevText = text;
|
|
53
|
-
},
|
|
54
|
-
submit(value2) {
|
|
55
|
-
if (value2 !== void 0) ctx.value = value2;
|
|
56
|
-
if (ctx.value === void 0 || validate && !validate?.(ctx)) return;
|
|
57
|
-
ctx.submitted = true;
|
|
58
|
-
ctx.render();
|
|
59
|
-
close();
|
|
60
|
-
res(ctx.value);
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
const close = () => {
|
|
64
|
-
if (!showCursor) stdout.write(cursorShow);
|
|
65
|
-
if (stdin.isTTY) stdin.setRawMode(false);
|
|
66
|
-
stdin.off("data", keypress);
|
|
67
|
-
stdin.pause();
|
|
68
|
-
};
|
|
69
|
-
const keypress = (s) => {
|
|
70
|
-
if (s === "" || s === "") {
|
|
71
|
-
close?.();
|
|
72
|
-
process.exit(0);
|
|
73
|
-
}
|
|
74
|
-
if (s === "\r" || s === "\n" || s === "\r\n") {
|
|
75
|
-
ctx.submit();
|
|
76
|
-
} else {
|
|
77
|
-
onKeyPress(ctx, s);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
stdin.on("data", keypress);
|
|
81
|
-
ctx.render();
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
|
-
const defaultActive = (s) => `${pqb.colors.blueBold("\u276F")} ${s}`;
|
|
85
|
-
const defaultInactive = (s) => ` ${s}`;
|
|
86
|
-
const promptSelect = ({
|
|
87
|
-
message,
|
|
88
|
-
options,
|
|
89
|
-
active = defaultActive,
|
|
90
|
-
inactive = defaultInactive
|
|
91
|
-
}) => prompt({
|
|
92
|
-
value: 0,
|
|
93
|
-
render(ctx) {
|
|
94
|
-
let text = `${message} ${pqb.colors.pale(
|
|
95
|
-
"Use arrows or jk. Press enter to submit."
|
|
96
|
-
)}
|
|
97
|
-
`;
|
|
98
|
-
for (let i = 0; i < options.length; i++) {
|
|
99
|
-
text += (ctx.value === i ? active : inactive)(options[i]) + "\n";
|
|
100
|
-
}
|
|
101
|
-
return text;
|
|
102
|
-
},
|
|
103
|
-
onKeyPress(ctx, s) {
|
|
104
|
-
ctx.value = s === "\x1B[H" ? 0 : s === "\x1B[F" ? options.length - 1 : s === "\x1B[A" || s === "k" ? ctx.value === 0 ? options.length - 1 : ctx.value - 1 : s === "\x1B[B" || s === "j" || s === " " ? ctx.value === options.length - 1 ? 0 : ctx.value + 1 : ctx.value;
|
|
105
|
-
ctx.render();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
const promptConfirm = ({
|
|
109
|
-
message
|
|
110
|
-
}) => prompt({
|
|
111
|
-
value: true,
|
|
112
|
-
render(ctx) {
|
|
113
|
-
return `${pqb.colors.bright(message)}
|
|
114
|
-
${ctx.submitted ? `> ${ctx.value ? pqb.colors.greenBold("Yes") : pqb.colors.yellowBold("No")}` : pqb.colors.pale(`> (Y/n)`)}
|
|
115
|
-
`;
|
|
116
|
-
},
|
|
117
|
-
onKeyPress(ctx, s) {
|
|
118
|
-
let ok;
|
|
119
|
-
if (s === "y" || s === "Y") ok = true;
|
|
120
|
-
else if (s === "n" || s === "N") ok = false;
|
|
121
|
-
if (ok !== void 0) {
|
|
122
|
-
ctx.submit(ok);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
const promptText = ({
|
|
127
|
-
message,
|
|
128
|
-
default: def = "",
|
|
129
|
-
password,
|
|
130
|
-
min
|
|
131
|
-
}) => {
|
|
132
|
-
let showDefault = true;
|
|
133
|
-
let x = 0;
|
|
134
|
-
const renderValue = (ctx) => password ? "*".repeat(ctx.value.length) : ctx.value;
|
|
135
|
-
return prompt({
|
|
136
|
-
value: def,
|
|
137
|
-
cursor: true,
|
|
138
|
-
validate: (ctx) => !min || ctx.value.length >= min,
|
|
139
|
-
render(ctx) {
|
|
140
|
-
let text = `${pqb.colors.bright(message)}
|
|
141
|
-
> ${ctx.submitted ? renderValue(ctx) : showDefault ? pqb.colors.pale(def) + "\b".repeat(def.length) : ctx.value}`;
|
|
142
|
-
if (ctx.submitted) text += "\n";
|
|
143
|
-
return text;
|
|
144
|
-
},
|
|
145
|
-
onKeyPress(ctx, s) {
|
|
146
|
-
let value = showDefault ? "" : ctx.value;
|
|
147
|
-
if (s === "\x1B[D" && x > 0) {
|
|
148
|
-
x--;
|
|
149
|
-
stdout.write("\b");
|
|
150
|
-
} else if (s === "\x1B[C" && x < value.length) {
|
|
151
|
-
stdout.write(value[x]);
|
|
152
|
-
x++;
|
|
153
|
-
}
|
|
154
|
-
if (s !== "\x7F" && s !== "\x1B[3~" && !visibleChars(s)) return;
|
|
155
|
-
if (showDefault) {
|
|
156
|
-
showDefault = false;
|
|
157
|
-
stdout.write(" ".repeat(def.length) + "\b".repeat(def.length));
|
|
158
|
-
}
|
|
159
|
-
const prev = value;
|
|
160
|
-
const prevX = x;
|
|
161
|
-
if (s === "\x7F") {
|
|
162
|
-
if (x > 0) {
|
|
163
|
-
value = value.slice(0, x - 1) + value.slice(x);
|
|
164
|
-
x--;
|
|
165
|
-
}
|
|
166
|
-
} else if (s === "\x1B[3~") {
|
|
167
|
-
if (x < value.length) {
|
|
168
|
-
value = value.slice(0, x) + value.slice(x + 1);
|
|
169
|
-
}
|
|
170
|
-
} else {
|
|
171
|
-
value = value.slice(0, x) + s + value.slice(x);
|
|
172
|
-
x++;
|
|
173
|
-
}
|
|
174
|
-
ctx.value = value;
|
|
175
|
-
const spaces = prev.length - value.length;
|
|
176
|
-
stdout.write(
|
|
177
|
-
"\b".repeat(prevX) + renderValue(ctx) + (spaces > 0 ? " ".repeat(spaces) + "\b".repeat(spaces) : "") + "\b".repeat(value.length - x)
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const getMaybeTransactionAdapter = (db) => "$getAdapter" in db ? db.$getAdapter() : db;
|
|
184
|
-
const runSqlInSavePoint = async (db, sql, code) => {
|
|
185
|
-
const adapter = getMaybeTransactionAdapter(db);
|
|
186
|
-
try {
|
|
187
|
-
await adapter.query(
|
|
188
|
-
adapter.isInTransaction() ? `SAVEPOINT s; ${sql}; RELEASE SAVEPOINT s` : sql
|
|
189
|
-
);
|
|
190
|
-
return "done";
|
|
191
|
-
} catch (err) {
|
|
192
|
-
if (err.code === code) {
|
|
193
|
-
if (adapter.isInTransaction()) {
|
|
194
|
-
await adapter.query(`ROLLBACK TO SAVEPOINT s`);
|
|
195
|
-
}
|
|
196
|
-
return "already";
|
|
197
|
-
}
|
|
198
|
-
throw err;
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
class CreateOrDropError extends Error {
|
|
203
|
-
constructor(message, status, cause) {
|
|
204
|
-
super(message);
|
|
205
|
-
this.status = status;
|
|
206
|
-
this.cause = cause;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
const createDatabase = async (db, {
|
|
210
|
-
database,
|
|
211
|
-
owner
|
|
212
|
-
}) => {
|
|
213
|
-
return createOrDrop(
|
|
214
|
-
db,
|
|
215
|
-
`CREATE DATABASE "${database}"${owner ? ` OWNER "${owner}"` : ""}`
|
|
216
|
-
);
|
|
217
|
-
};
|
|
218
|
-
const dropDatabase = async (db, { database }) => {
|
|
219
|
-
return createOrDrop(db, `DROP DATABASE "${database}"`);
|
|
220
|
-
};
|
|
221
|
-
const createOrDrop = async (db, sql) => {
|
|
222
|
-
try {
|
|
223
|
-
const adapter = getMaybeTransactionAdapter(db);
|
|
224
|
-
await adapter.query(sql);
|
|
225
|
-
return "done";
|
|
226
|
-
} catch (error) {
|
|
227
|
-
const err = error;
|
|
228
|
-
if (typeof err.message === "string" && err.message.includes("sslmode=require")) {
|
|
229
|
-
throw new CreateOrDropError("SSL required", "ssl-required", err);
|
|
230
|
-
}
|
|
231
|
-
if (err.code === "42P04" || err.code === "3D000") {
|
|
232
|
-
return "already";
|
|
233
|
-
}
|
|
234
|
-
if (err.code === "42501") {
|
|
235
|
-
throw new CreateOrDropError("Insufficient privilege", "forbidden", err);
|
|
236
|
-
}
|
|
237
|
-
if (typeof err.message === "string" && err.message.includes("password authentication failed")) {
|
|
238
|
-
throw new CreateOrDropError("Authentication failed", "auth-failed", err);
|
|
239
|
-
}
|
|
240
|
-
throw err;
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
const createSchema$1 = async (db, sql) => runSqlInSavePoint(db, `CREATE SCHEMA ${sql}`, "42P06");
|
|
244
|
-
const dropSchema = async (db, sql) => runSqlInSavePoint(db, `DROP SCHEMA ${sql}`, "3F000");
|
|
245
|
-
const createTable$1 = async (db, sql) => runSqlInSavePoint(db, `CREATE TABLE ${sql}`, "42P07");
|
|
246
|
-
const dropTable = async (db, sql) => runSqlInSavePoint(db, `DROP TABLE ${sql}`, "42P01");
|
|
7
|
+
var path$1 = require('node:path');
|
|
247
8
|
|
|
248
9
|
const RAKE_DB_LOCK_KEY = "8582141715823621641";
|
|
249
10
|
const getFirstWordAndRest = (input) => {
|
|
@@ -291,7 +52,7 @@ const quoteCustomType = (schema, type) => {
|
|
|
291
52
|
return s ? '"' + s + '".' + t : t;
|
|
292
53
|
};
|
|
293
54
|
const quoteSchemaTable = (arg, excludeCurrentSchema) => {
|
|
294
|
-
return
|
|
55
|
+
return internal.singleQuote(concatSchemaAndName(arg, excludeCurrentSchema));
|
|
295
56
|
};
|
|
296
57
|
const concatSchemaAndName = ({
|
|
297
58
|
schema,
|
|
@@ -332,10 +93,13 @@ const getCliParam = (args, name) => {
|
|
|
332
93
|
return;
|
|
333
94
|
};
|
|
334
95
|
|
|
335
|
-
const
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
96
|
+
const createMigrationChangeFn = (config) => {
|
|
97
|
+
const conf = config.columnTypes ? config : { columnTypes: internal.makeColumnTypes(internal.defaultSchemaConfig) };
|
|
98
|
+
return (fn) => {
|
|
99
|
+
const change = { fn, config: conf };
|
|
100
|
+
pushChange(change);
|
|
101
|
+
return change;
|
|
102
|
+
};
|
|
339
103
|
};
|
|
340
104
|
let currentChanges = [];
|
|
341
105
|
const clearChanges = () => {
|
|
@@ -346,10 +110,10 @@ const pushChange = (change) => currentChanges.push(change);
|
|
|
346
110
|
|
|
347
111
|
const versionToString = (config, version) => config.migrationId === "timestamp" ? `${version}` : `${version}`.padStart(config.migrationId.serial, "0");
|
|
348
112
|
const columnTypeToSql = (schema, item) => {
|
|
349
|
-
return item.data.isOfCustomType ? item instanceof
|
|
113
|
+
return item.data.isOfCustomType ? item instanceof internal.DomainColumn ? quoteNameFromString(schema, item.dataType) : quoteCustomType(schema, item.toSQL()) : item.toSQL();
|
|
350
114
|
};
|
|
351
115
|
const getColumnName = (item, key, snakeCase) => {
|
|
352
|
-
return item.data.name || (snakeCase ?
|
|
116
|
+
return item.data.name || (snakeCase ? internal.toSnakeCase(key) : key);
|
|
353
117
|
};
|
|
354
118
|
const columnToSql = (schema, name, item, values, hasMultiplePrimaryKeys, snakeCase) => {
|
|
355
119
|
const line = [`"${name}" ${columnTypeToSql(schema, item)}`];
|
|
@@ -408,11 +172,11 @@ const columnToSql = (schema, name, item, values, hasMultiplePrimaryKeys, snakeCa
|
|
|
408
172
|
};
|
|
409
173
|
const encodeColumnDefault = (def, values, column) => {
|
|
410
174
|
if (def !== void 0 && def !== null && typeof def !== "function") {
|
|
411
|
-
if (
|
|
175
|
+
if (internal.isRawSQL(def)) {
|
|
412
176
|
return `(${def.toSQL({ values })})`;
|
|
413
177
|
} else {
|
|
414
|
-
return
|
|
415
|
-
column instanceof
|
|
178
|
+
return internal.escapeForMigration(
|
|
179
|
+
column instanceof internal.ArrayColumn && Array.isArray(def) ? "{" + (column.data.item.data.encode ? def.map((x) => column.data.item.data.encode(x)) : def).join(",") + "}" : column?.data.encode ? column.data.encode(def) : def
|
|
416
180
|
);
|
|
417
181
|
}
|
|
418
182
|
}
|
|
@@ -473,7 +237,7 @@ const getConstraintName = (table, constraint, snakeCase) => {
|
|
|
473
237
|
if (constraint.references) {
|
|
474
238
|
let { columns } = constraint.references;
|
|
475
239
|
if (snakeCase) {
|
|
476
|
-
columns = columns.map(
|
|
240
|
+
columns = columns.map(internal.toSnakeCase);
|
|
477
241
|
}
|
|
478
242
|
return makeConstraintName(table, columns, "fkey");
|
|
479
243
|
}
|
|
@@ -501,14 +265,14 @@ const checkToSql = (check, values) => {
|
|
|
501
265
|
};
|
|
502
266
|
const foreignKeyToSql = (schema, item, snakeCase) => {
|
|
503
267
|
return `FOREIGN KEY (${joinColumns(
|
|
504
|
-
snakeCase ? item.columns.map(
|
|
268
|
+
snakeCase ? item.columns.map(internal.toSnakeCase) : item.columns
|
|
505
269
|
)}) ${referencesToSql(schema, item, snakeCase)}`;
|
|
506
270
|
};
|
|
507
271
|
const referencesToSql = (schema, references, snakeCase) => {
|
|
508
272
|
const [s, table] = getForeignKeyTable(schema, references.fnOrTable);
|
|
509
273
|
const sql = [
|
|
510
274
|
`REFERENCES ${quoteTable(s, table)}(${joinColumns(
|
|
511
|
-
snakeCase ? references.foreignColumns.map(
|
|
275
|
+
snakeCase ? references.foreignColumns.map(internal.toSnakeCase) : references.foreignColumns
|
|
512
276
|
)})`
|
|
513
277
|
];
|
|
514
278
|
const { options } = references;
|
|
@@ -528,10 +292,10 @@ const makeConstraintName = (table, columns, suffix) => {
|
|
|
528
292
|
const long = `${table}_${columns.join("_")}_${suffix}`;
|
|
529
293
|
if (long.length <= MAX_CONSTRAINT_NAME_LEN) return long;
|
|
530
294
|
for (let partLen = 3; partLen > 0; partLen--) {
|
|
531
|
-
const shorter = `${
|
|
532
|
-
|
|
295
|
+
const shorter = `${internal.toCamelCase(
|
|
296
|
+
internal.toSnakeCase(table).split("_").map((p) => p.slice(0, partLen)).join("_")
|
|
533
297
|
)}_${columns.map(
|
|
534
|
-
(c) =>
|
|
298
|
+
(c) => internal.toCamelCase(
|
|
535
299
|
c.split("_").map((p) => p.slice(0, partLen)).join("_")
|
|
536
300
|
)
|
|
537
301
|
).join("_")}_${suffix}`;
|
|
@@ -540,8 +304,8 @@ const makeConstraintName = (table, columns, suffix) => {
|
|
|
540
304
|
const short = `${table}_${columns.length}columns_${suffix}`;
|
|
541
305
|
if (short.length <= MAX_CONSTRAINT_NAME_LEN) return short;
|
|
542
306
|
for (let partLen = 3; partLen > 0; partLen--) {
|
|
543
|
-
const short2 = `${
|
|
544
|
-
|
|
307
|
+
const short2 = `${internal.toCamelCase(
|
|
308
|
+
internal.toSnakeCase(table).split("_").map((p) => p.slice(0, partLen)).join("_")
|
|
545
309
|
)}_${columns.length}columns_${suffix}`;
|
|
546
310
|
if (short2.length <= MAX_CONSTRAINT_NAME_LEN) return short2;
|
|
547
311
|
}
|
|
@@ -623,7 +387,7 @@ const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, lan
|
|
|
623
387
|
}
|
|
624
388
|
if (options.where) {
|
|
625
389
|
sql.push(
|
|
626
|
-
`WHERE ${
|
|
390
|
+
`WHERE ${internal.isRawSQL(options.where) ? options.where.toSQL({ values }) : options.where}`
|
|
627
391
|
);
|
|
628
392
|
}
|
|
629
393
|
return { text: sql.join(" "), values };
|
|
@@ -666,19 +430,19 @@ const excludesToQuery = (up, { schema, name: tableName }, excludes, snakeCase) =
|
|
|
666
430
|
include?.length && `INCLUDE (${include.map((column) => `"${column}"`).join(", ")})`,
|
|
667
431
|
options.with && `WITH (${options.with})`,
|
|
668
432
|
options.tablespace && `USING INDEX TABLESPACE ${options.tablespace}`,
|
|
669
|
-
options.where && `WHERE ${
|
|
433
|
+
options.where && `WHERE ${internal.isRawSQL(options.where) ? options.where.toSQL({ values }) : options.where}`
|
|
670
434
|
].filter((x) => !!x).join(" ");
|
|
671
435
|
return { text, values };
|
|
672
436
|
});
|
|
673
437
|
};
|
|
674
438
|
const getIndexOrExcludeMainOptions = (tableName, item, getName, snakeCase) => {
|
|
675
|
-
let include = item.options.include ?
|
|
439
|
+
let include = item.options.include ? internal.toArray(item.options.include) : void 0;
|
|
676
440
|
let { columns } = item;
|
|
677
441
|
if (snakeCase) {
|
|
678
442
|
columns = columns.map(
|
|
679
|
-
(c) => "column" in c ? { ...c, column:
|
|
443
|
+
(c) => "column" in c ? { ...c, column: internal.toSnakeCase(c.column) } : c
|
|
680
444
|
);
|
|
681
|
-
if (include) include = include.map(
|
|
445
|
+
if (include) include = include.map(internal.toSnakeCase);
|
|
682
446
|
}
|
|
683
447
|
return {
|
|
684
448
|
columns,
|
|
@@ -690,7 +454,7 @@ const commentsToQuery = (schemaTable, comments) => {
|
|
|
690
454
|
return comments.map(({ column, comment }) => ({
|
|
691
455
|
text: `COMMENT ON COLUMN ${quoteWithSchema(
|
|
692
456
|
schemaTable
|
|
693
|
-
)}."${column}" IS ${
|
|
457
|
+
)}."${column}" IS ${internal.escapeForMigration(comment)}`,
|
|
694
458
|
values: []
|
|
695
459
|
}));
|
|
696
460
|
};
|
|
@@ -700,7 +464,7 @@ const primaryKeyToSql = (primaryKey) => {
|
|
|
700
464
|
const interpolateSqlValues = ({ text, values }) => {
|
|
701
465
|
return values?.length ? text.replace(/\$(\d+)/g, (_, n) => {
|
|
702
466
|
const i = +n - 1;
|
|
703
|
-
return
|
|
467
|
+
return internal.escapeForMigration(values[i]);
|
|
704
468
|
}) : text;
|
|
705
469
|
};
|
|
706
470
|
const nameColumnChecks = (table, column, checks) => checks.map((check, i) => ({
|
|
@@ -738,8 +502,8 @@ const migrationsSchemaTableSql = (adapter, config) => {
|
|
|
738
502
|
|
|
739
503
|
const tableMethods = {
|
|
740
504
|
enum(name) {
|
|
741
|
-
return new
|
|
742
|
-
|
|
505
|
+
return new internal.EnumColumn(
|
|
506
|
+
internal.defaultSchemaConfig,
|
|
743
507
|
name,
|
|
744
508
|
[],
|
|
745
509
|
void 0
|
|
@@ -752,7 +516,7 @@ class RakeDbError extends Error {
|
|
|
752
516
|
class NoPrimaryKey extends RakeDbError {
|
|
753
517
|
}
|
|
754
518
|
|
|
755
|
-
const createTable = async (migration, up, tableName, first, second, third) => {
|
|
519
|
+
const createTable$1 = async (migration, up, tableName, first, second, third) => {
|
|
756
520
|
let options;
|
|
757
521
|
let fn;
|
|
758
522
|
let dataFn;
|
|
@@ -761,7 +525,7 @@ const createTable = async (migration, up, tableName, first, second, third) => {
|
|
|
761
525
|
fn = second;
|
|
762
526
|
dataFn = third;
|
|
763
527
|
} else {
|
|
764
|
-
options =
|
|
528
|
+
options = internal.emptyObject;
|
|
765
529
|
fn = first;
|
|
766
530
|
dataFn = second;
|
|
767
531
|
}
|
|
@@ -771,23 +535,23 @@ const createTable = async (migration, up, tableName, first, second, third) => {
|
|
|
771
535
|
Object.create(migration.columnTypes),
|
|
772
536
|
tableMethods
|
|
773
537
|
);
|
|
774
|
-
types[
|
|
538
|
+
types[internal.snakeCaseKey] = snakeCase;
|
|
775
539
|
let shape;
|
|
776
540
|
let tableData;
|
|
777
541
|
if (fn) {
|
|
778
|
-
shape =
|
|
542
|
+
shape = internal.getColumnTypes(
|
|
779
543
|
types,
|
|
780
544
|
fn,
|
|
781
545
|
migration.options.baseTable?.nowSQL,
|
|
782
546
|
language
|
|
783
547
|
);
|
|
784
|
-
tableData =
|
|
548
|
+
tableData = internal.parseTableData(dataFn);
|
|
785
549
|
tableData.constraints?.forEach((x, i) => {
|
|
786
550
|
if (x.name || !x.check) return;
|
|
787
551
|
x.name = `${tableName}_check${i === 0 ? "" : i}`;
|
|
788
552
|
});
|
|
789
553
|
} else {
|
|
790
|
-
shape = tableData =
|
|
554
|
+
shape = tableData = internal.emptyObject;
|
|
791
555
|
}
|
|
792
556
|
const schema = migration.adapter.getSchema();
|
|
793
557
|
const ast = makeAst$4(
|
|
@@ -874,7 +638,7 @@ const astToQueries$1 = (schema, ast, snakeCase, language) => {
|
|
|
874
638
|
const { shape } = ast;
|
|
875
639
|
for (const key in shape) {
|
|
876
640
|
const item = shape[key];
|
|
877
|
-
if (!(item instanceof
|
|
641
|
+
if (!(item instanceof internal.EnumColumn)) continue;
|
|
878
642
|
queries.push(makePopulateEnumQuery(schema, item));
|
|
879
643
|
}
|
|
880
644
|
if (ast.action === "drop") {
|
|
@@ -952,7 +716,7 @@ const astToQueries$1 = (schema, ast, snakeCase, language) => {
|
|
|
952
716
|
);
|
|
953
717
|
if (ast.comment) {
|
|
954
718
|
queries.push({
|
|
955
|
-
text: `COMMENT ON TABLE ${quoteWithSchema(ast)} IS ${
|
|
719
|
+
text: `COMMENT ON TABLE ${quoteWithSchema(ast)} IS ${internal.escapeString(
|
|
956
720
|
ast.comment
|
|
957
721
|
)}`
|
|
958
722
|
});
|
|
@@ -983,16 +747,16 @@ const resetChangeTableData = () => {
|
|
|
983
747
|
};
|
|
984
748
|
const addOrDropChanges = [];
|
|
985
749
|
function add(item, options) {
|
|
986
|
-
|
|
750
|
+
internal.consumeColumnName();
|
|
987
751
|
setName(this, item);
|
|
988
|
-
if (item instanceof
|
|
752
|
+
if (item instanceof internal.Column) {
|
|
989
753
|
const result = addOrDrop("add", item, options);
|
|
990
754
|
if (result.type === "change") return result;
|
|
991
755
|
addOrDropChanges.push(result);
|
|
992
756
|
return addOrDropChanges.length - 1;
|
|
993
757
|
}
|
|
994
758
|
for (const key in item) {
|
|
995
|
-
if (item[key] instanceof
|
|
759
|
+
if (item[key] instanceof internal.Column) {
|
|
996
760
|
const result = {};
|
|
997
761
|
for (const key2 in item) {
|
|
998
762
|
result[key2] = {
|
|
@@ -1003,22 +767,22 @@ function add(item, options) {
|
|
|
1003
767
|
}
|
|
1004
768
|
return result;
|
|
1005
769
|
}
|
|
1006
|
-
|
|
770
|
+
internal.parseTableDataInput(changeTableData.add, item);
|
|
1007
771
|
break;
|
|
1008
772
|
}
|
|
1009
773
|
return void 0;
|
|
1010
774
|
}
|
|
1011
775
|
const drop = function(item, options) {
|
|
1012
|
-
|
|
776
|
+
internal.consumeColumnName();
|
|
1013
777
|
setName(this, item);
|
|
1014
|
-
if (item instanceof
|
|
778
|
+
if (item instanceof internal.Column) {
|
|
1015
779
|
const result = addOrDrop("drop", item, options);
|
|
1016
780
|
if (result.type === "change") return result;
|
|
1017
781
|
addOrDropChanges.push(result);
|
|
1018
782
|
return addOrDropChanges.length - 1;
|
|
1019
783
|
}
|
|
1020
784
|
for (const key in item) {
|
|
1021
|
-
if (item[key] instanceof
|
|
785
|
+
if (item[key] instanceof internal.Column) {
|
|
1022
786
|
const result = {};
|
|
1023
787
|
for (const key2 in item) {
|
|
1024
788
|
result[key2] = {
|
|
@@ -1029,13 +793,13 @@ const drop = function(item, options) {
|
|
|
1029
793
|
}
|
|
1030
794
|
return result;
|
|
1031
795
|
}
|
|
1032
|
-
|
|
796
|
+
internal.parseTableDataInput(changeTableData.drop, item);
|
|
1033
797
|
break;
|
|
1034
798
|
}
|
|
1035
799
|
return void 0;
|
|
1036
800
|
};
|
|
1037
801
|
const addOrDrop = (type, item, options) => {
|
|
1038
|
-
if (item instanceof
|
|
802
|
+
if (item instanceof internal.UnknownColumn) {
|
|
1039
803
|
const empty = columnTypeToColumnChange({
|
|
1040
804
|
type: "change",
|
|
1041
805
|
to: {}
|
|
@@ -1060,7 +824,7 @@ const addOrDrop = (type, item, options) => {
|
|
|
1060
824
|
};
|
|
1061
825
|
};
|
|
1062
826
|
const columnTypeToColumnChange = (item, name) => {
|
|
1063
|
-
if (item instanceof
|
|
827
|
+
if (item instanceof internal.Column) {
|
|
1064
828
|
let column = item;
|
|
1065
829
|
const foreignKeys = column.data.foreignKeys;
|
|
1066
830
|
if (foreignKeys?.some((it) => "fn" in it)) {
|
|
@@ -1082,9 +846,9 @@ const setName = (self, item) => {
|
|
|
1082
846
|
var _a, _b;
|
|
1083
847
|
const name = self[nameKey];
|
|
1084
848
|
if (!name) return;
|
|
1085
|
-
if ("column" in item && item.column instanceof
|
|
849
|
+
if ("column" in item && item.column instanceof internal.Column) {
|
|
1086
850
|
(_a = item.column.data).name ?? (_a.name = name);
|
|
1087
|
-
} else if (item instanceof
|
|
851
|
+
} else if (item instanceof internal.Column) {
|
|
1088
852
|
(_b = item.data).name ?? (_b.name = name);
|
|
1089
853
|
} else {
|
|
1090
854
|
item.name ?? (item.name = name);
|
|
@@ -1092,9 +856,9 @@ const setName = (self, item) => {
|
|
|
1092
856
|
};
|
|
1093
857
|
const tableChangeMethods = {
|
|
1094
858
|
...tableMethods,
|
|
1095
|
-
...
|
|
859
|
+
...internal.tableDataMethods,
|
|
1096
860
|
name(name) {
|
|
1097
|
-
|
|
861
|
+
internal.setCurrentColumnName(name);
|
|
1098
862
|
const types = Object.create(this);
|
|
1099
863
|
types[nameKey] = name;
|
|
1100
864
|
return types;
|
|
@@ -1102,7 +866,7 @@ const tableChangeMethods = {
|
|
|
1102
866
|
add,
|
|
1103
867
|
drop,
|
|
1104
868
|
change(from, to, using) {
|
|
1105
|
-
|
|
869
|
+
internal.consumeColumnName();
|
|
1106
870
|
const f = columnTypeToColumnChange(from);
|
|
1107
871
|
const t = columnTypeToColumnChange(to);
|
|
1108
872
|
setName(this, f);
|
|
@@ -1160,13 +924,13 @@ const tableChangeMethods = {
|
|
|
1160
924
|
const changeTable = async (migration, up, tableName, options, fn) => {
|
|
1161
925
|
const snakeCase = "snakeCase" in options ? options.snakeCase : migration.options.snakeCase;
|
|
1162
926
|
const language = "language" in options ? options.language : migration.options.language;
|
|
1163
|
-
|
|
927
|
+
internal.setDefaultLanguage(language);
|
|
1164
928
|
resetChangeTableData();
|
|
1165
929
|
const tableChanger = Object.create(
|
|
1166
930
|
migration.columnTypes
|
|
1167
931
|
);
|
|
1168
932
|
Object.assign(tableChanger, tableChangeMethods);
|
|
1169
|
-
tableChanger[
|
|
933
|
+
tableChanger[internal.snakeCaseKey] = snakeCase;
|
|
1170
934
|
addOrDropChanges.length = 0;
|
|
1171
935
|
const changeData = fn?.(tableChanger) || {};
|
|
1172
936
|
const schema = migration.adapter.getSchema();
|
|
@@ -1193,7 +957,7 @@ const makeAst$3 = (schema, up, name, changeData, changeTableData2, options) => {
|
|
|
1193
957
|
if (typeof item === "number") {
|
|
1194
958
|
consumedChanges[item] = true;
|
|
1195
959
|
item = addOrDropChanges[item];
|
|
1196
|
-
} else if (item instanceof
|
|
960
|
+
} else if (item instanceof internal.Column) {
|
|
1197
961
|
item = addOrDrop("add", item);
|
|
1198
962
|
}
|
|
1199
963
|
if ("type" in item) {
|
|
@@ -1223,7 +987,7 @@ const makeAst$3 = (schema, up, name, changeData, changeTableData2, options) => {
|
|
|
1223
987
|
if (!name2) {
|
|
1224
988
|
throw new Error(`Column in ...t.${change.type}() must have a name`);
|
|
1225
989
|
}
|
|
1226
|
-
const arr = shape[name2] ?
|
|
990
|
+
const arr = shape[name2] ? internal.toArray(shape[name2]) : [];
|
|
1227
991
|
arr[up ? "push" : "unshift"](
|
|
1228
992
|
up ? change : { ...change, type: change.type === "add" ? "drop" : "add" }
|
|
1229
993
|
);
|
|
@@ -1243,7 +1007,7 @@ const astToQueries = (schema, ast, snakeCase, language) => {
|
|
|
1243
1007
|
const queries = [];
|
|
1244
1008
|
if (ast.comment !== void 0) {
|
|
1245
1009
|
queries.push({
|
|
1246
|
-
text: `COMMENT ON TABLE ${quoteWithSchema(ast)} IS ${ast.comment === null ? "NULL" :
|
|
1010
|
+
text: `COMMENT ON TABLE ${quoteWithSchema(ast)} IS ${ast.comment === null ? "NULL" : internal.escapeString(
|
|
1247
1011
|
typeof ast.comment === "string" ? ast.comment : ast.comment[1]
|
|
1248
1012
|
)}`
|
|
1249
1013
|
});
|
|
@@ -1284,14 +1048,14 @@ const astToQueries = (schema, ast, snakeCase, language) => {
|
|
|
1284
1048
|
addPrimaryKeys.name = ast.add.primaryKey.name;
|
|
1285
1049
|
const { columns } = ast.add.primaryKey;
|
|
1286
1050
|
addPrimaryKeys.columns.push(
|
|
1287
|
-
...snakeCase ? columns.map(
|
|
1051
|
+
...snakeCase ? columns.map(internal.toSnakeCase) : columns
|
|
1288
1052
|
);
|
|
1289
1053
|
}
|
|
1290
1054
|
if (ast.drop.primaryKey) {
|
|
1291
1055
|
dropPrimaryKeys.name = ast.drop.primaryKey.name;
|
|
1292
1056
|
const { columns } = ast.drop.primaryKey;
|
|
1293
1057
|
dropPrimaryKeys.columns.push(
|
|
1294
|
-
...snakeCase ? columns.map(
|
|
1058
|
+
...snakeCase ? columns.map(internal.toSnakeCase) : columns
|
|
1295
1059
|
);
|
|
1296
1060
|
}
|
|
1297
1061
|
const alterTable = [];
|
|
@@ -1379,7 +1143,7 @@ const astToQueries = (schema, ast, snakeCase, language) => {
|
|
|
1379
1143
|
`ADD ${primaryKeyToSql(
|
|
1380
1144
|
snakeCase ? {
|
|
1381
1145
|
name: addPrimaryKeys.name,
|
|
1382
|
-
columns: addPrimaryKeys.columns.map(
|
|
1146
|
+
columns: addPrimaryKeys.columns.map(internal.toSnakeCase)
|
|
1383
1147
|
} : addPrimaryKeys
|
|
1384
1148
|
)}`
|
|
1385
1149
|
);
|
|
@@ -1425,7 +1189,7 @@ const alterTableSql = (tableName, lines, values) => ({
|
|
|
1425
1189
|
const handlePrerequisitesForTableItem = (schema, key, item, queries, addPrimaryKeys, dropPrimaryKeys, snakeCase) => {
|
|
1426
1190
|
if ("item" in item) {
|
|
1427
1191
|
const { item: column } = item;
|
|
1428
|
-
if (column instanceof
|
|
1192
|
+
if (column instanceof internal.EnumColumn) {
|
|
1429
1193
|
queries.push(makePopulateEnumQuery(schema, column));
|
|
1430
1194
|
}
|
|
1431
1195
|
}
|
|
@@ -1438,21 +1202,21 @@ const handlePrerequisitesForTableItem = (schema, key, item, queries, addPrimaryK
|
|
|
1438
1202
|
dropPrimaryKeys.columns.push(getColumnName(item.item, key, snakeCase));
|
|
1439
1203
|
}
|
|
1440
1204
|
} else if (item.type === "change") {
|
|
1441
|
-
if (item.from.column instanceof
|
|
1205
|
+
if (item.from.column instanceof internal.EnumColumn) {
|
|
1442
1206
|
queries.push(makePopulateEnumQuery(schema, item.from.column));
|
|
1443
1207
|
}
|
|
1444
|
-
if (item.to.column instanceof
|
|
1208
|
+
if (item.to.column instanceof internal.EnumColumn) {
|
|
1445
1209
|
queries.push(makePopulateEnumQuery(schema, item.to.column));
|
|
1446
1210
|
}
|
|
1447
1211
|
if (item.from.primaryKey) {
|
|
1448
1212
|
dropPrimaryKeys.columns.push(
|
|
1449
|
-
item.from.column ? getColumnName(item.from.column, key, snakeCase) : snakeCase ?
|
|
1213
|
+
item.from.column ? getColumnName(item.from.column, key, snakeCase) : snakeCase ? internal.toSnakeCase(key) : key
|
|
1450
1214
|
);
|
|
1451
1215
|
dropPrimaryKeys.change = true;
|
|
1452
1216
|
}
|
|
1453
1217
|
if (item.to.primaryKey) {
|
|
1454
1218
|
addPrimaryKeys.columns.push(
|
|
1455
|
-
item.to.column ? getColumnName(item.to.column, key, snakeCase) : snakeCase ?
|
|
1219
|
+
item.to.column ? getColumnName(item.to.column, key, snakeCase) : snakeCase ? internal.toSnakeCase(key) : key
|
|
1456
1220
|
);
|
|
1457
1221
|
addPrimaryKeys.change = true;
|
|
1458
1222
|
}
|
|
@@ -1490,13 +1254,13 @@ const handleTableItemChange = (schema, key, item, ast, alterTable, renameItems,
|
|
|
1490
1254
|
let changeType = false;
|
|
1491
1255
|
if (to.type && (from.type !== to.type || from.collate !== to.collate)) {
|
|
1492
1256
|
changeType = true;
|
|
1493
|
-
const type = !to.column || to.column.data.isOfCustomType ? to.column && to.column instanceof
|
|
1494
|
-
const using = item.using?.usingUp ? ` USING ${item.using.usingUp.toSQL({ values })}` : to.column instanceof
|
|
1257
|
+
const type = !to.column || to.column.data.isOfCustomType ? to.column && to.column instanceof internal.DomainColumn ? quoteNameFromString(schema, to.type) : quoteCustomType(schema, to.type) : to.type;
|
|
1258
|
+
const using = item.using?.usingUp ? ` USING ${item.using.usingUp.toSQL({ values })}` : to.column instanceof internal.EnumColumn ? ` USING "${name}"::text::${type}` : to.column instanceof internal.ArrayColumn ? ` USING "${name}"::text[]::${type}` : "";
|
|
1495
1259
|
alterTable.push(
|
|
1496
1260
|
`ALTER COLUMN "${name}" TYPE ${type}${to.collate ? ` COLLATE ${quoteNameFromString(schema, to.collate)}` : ""}${using}`
|
|
1497
1261
|
);
|
|
1498
1262
|
}
|
|
1499
|
-
if (typeof from.identity !== typeof to.identity || !
|
|
1263
|
+
if (typeof from.identity !== typeof to.identity || !internal.deepCompare(from.identity, to.identity)) {
|
|
1500
1264
|
if (from.identity) {
|
|
1501
1265
|
alterTable.push(`ALTER COLUMN "${name}" DROP IDENTITY`);
|
|
1502
1266
|
}
|
|
@@ -1556,7 +1320,7 @@ const handleTableItemChange = (schema, key, item, ast, alterTable, renameItems,
|
|
|
1556
1320
|
references: {
|
|
1557
1321
|
columns: [name],
|
|
1558
1322
|
...fromFkey,
|
|
1559
|
-
foreignColumns: snakeCase ? fromFkey.foreignColumns.map(
|
|
1323
|
+
foreignColumns: snakeCase ? fromFkey.foreignColumns.map(internal.toSnakeCase) : fromFkey.foreignColumns
|
|
1560
1324
|
}
|
|
1561
1325
|
});
|
|
1562
1326
|
}
|
|
@@ -1567,7 +1331,7 @@ const handleTableItemChange = (schema, key, item, ast, alterTable, renameItems,
|
|
|
1567
1331
|
references: {
|
|
1568
1332
|
columns: [name],
|
|
1569
1333
|
...toFkey,
|
|
1570
|
-
foreignColumns: snakeCase ? toFkey.foreignColumns.map(
|
|
1334
|
+
foreignColumns: snakeCase ? toFkey.foreignColumns.map(internal.toSnakeCase) : toFkey.foreignColumns
|
|
1571
1335
|
}
|
|
1572
1336
|
});
|
|
1573
1337
|
}
|
|
@@ -1587,7 +1351,7 @@ const handleTableItemChange = (schema, key, item, ast, alterTable, renameItems,
|
|
|
1587
1351
|
}
|
|
1588
1352
|
} else if (item.type === "rename") {
|
|
1589
1353
|
renameItems.push(
|
|
1590
|
-
snakeCase ? renameColumnSql(
|
|
1354
|
+
snakeCase ? renameColumnSql(internal.toSnakeCase(key), internal.toSnakeCase(item.name)) : renameColumnSql(key, item.name)
|
|
1591
1355
|
);
|
|
1592
1356
|
}
|
|
1593
1357
|
};
|
|
@@ -1596,7 +1360,7 @@ const pushIndexesOrExcludes = (key, from, to, name, add2, drop2) => {
|
|
|
1596
1360
|
for (let i = 0; i < len; i++) {
|
|
1597
1361
|
const fromItem = from[key]?.[i];
|
|
1598
1362
|
const toItem = to[key]?.[i];
|
|
1599
|
-
if ((fromItem || toItem) && (!fromItem || !toItem || !
|
|
1363
|
+
if ((fromItem || toItem) && (!fromItem || !toItem || !internal.deepCompare(fromItem, toItem))) {
|
|
1600
1364
|
if (fromItem) {
|
|
1601
1365
|
drop2.push({
|
|
1602
1366
|
...fromItem,
|
|
@@ -1628,7 +1392,7 @@ const getChangeColumnName = (what, change, key, snakeCase) => {
|
|
|
1628
1392
|
return change.name || (change[what].column ? (
|
|
1629
1393
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1630
1394
|
getColumnName(change[what].column, key, snakeCase)
|
|
1631
|
-
) : snakeCase ?
|
|
1395
|
+
) : snakeCase ? internal.toSnakeCase(key) : key);
|
|
1632
1396
|
};
|
|
1633
1397
|
const renameColumnSql = (from, to) => {
|
|
1634
1398
|
return `RENAME COLUMN "${from}" TO "${to}"`;
|
|
@@ -1642,7 +1406,7 @@ const createView = async (migration, up, name, options, sql) => {
|
|
|
1642
1406
|
};
|
|
1643
1407
|
const makeAst$2 = (schema, up, fullName, options, sql) => {
|
|
1644
1408
|
if (typeof sql === "string") {
|
|
1645
|
-
sql =
|
|
1409
|
+
sql = internal.raw({ raw: sql });
|
|
1646
1410
|
}
|
|
1647
1411
|
const [s, name] = getSchemaAndTableFromName(schema, fullName);
|
|
1648
1412
|
return {
|
|
@@ -1675,7 +1439,7 @@ const astToQuery$1 = (ast) => {
|
|
|
1675
1439
|
if (options?.with) {
|
|
1676
1440
|
const list = [];
|
|
1677
1441
|
if (options.with.checkOption)
|
|
1678
|
-
list.push(`check_option = ${
|
|
1442
|
+
list.push(`check_option = ${internal.singleQuote(options.with.checkOption)}`);
|
|
1679
1443
|
if (options.with.securityBarrier) list.push(`security_barrier = true`);
|
|
1680
1444
|
if (options.with.securityInvoker) list.push(`security_invoker = true`);
|
|
1681
1445
|
sql.push(`WITH ( ${list.join(", ")} )`);
|
|
@@ -1965,7 +1729,7 @@ const buildQuery = (ast, objectType, privileges, grantable, action) => {
|
|
|
1965
1729
|
const createMigrationInterface = (tx, up, config) => {
|
|
1966
1730
|
const adapter = Object.create(tx);
|
|
1967
1731
|
const { query, arrays } = adapter;
|
|
1968
|
-
const log =
|
|
1732
|
+
const log = internal.logParamToLogObject(config.logger || console, config.log);
|
|
1969
1733
|
adapter.query = (text, values) => {
|
|
1970
1734
|
return wrapWithEnhancingError(
|
|
1971
1735
|
text,
|
|
@@ -1981,27 +1745,37 @@ const createMigrationInterface = (tx, up, config) => {
|
|
|
1981
1745
|
);
|
|
1982
1746
|
};
|
|
1983
1747
|
Object.assign(adapter, { silentQuery: query, silentArrays: arrays });
|
|
1984
|
-
const
|
|
1985
|
-
|
|
1986
|
-
columnTypes: config.columnTypes
|
|
1987
|
-
});
|
|
1988
|
-
const { prototype: proto } = Migration;
|
|
1989
|
-
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
1990
|
-
db[key] = proto[key];
|
|
1991
|
-
}
|
|
1992
|
-
return Object.assign(db, {
|
|
1748
|
+
const dbPerColumnTypes = /* @__PURE__ */ new Map();
|
|
1749
|
+
return {
|
|
1993
1750
|
adapter,
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1751
|
+
getDb(columnTypes) {
|
|
1752
|
+
let db = dbPerColumnTypes.get(columnTypes);
|
|
1753
|
+
if (!db) {
|
|
1754
|
+
db = internal.createDbWithAdapter({
|
|
1755
|
+
adapter,
|
|
1756
|
+
columnTypes
|
|
1757
|
+
});
|
|
1758
|
+
const { prototype: proto } = Migration;
|
|
1759
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
1760
|
+
db[key] = proto[key];
|
|
1761
|
+
}
|
|
1762
|
+
return Object.assign(db, {
|
|
1763
|
+
adapter,
|
|
1764
|
+
log,
|
|
1765
|
+
up,
|
|
1766
|
+
options: config
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
return db;
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1998
1772
|
};
|
|
1999
1773
|
class Migration {
|
|
2000
1774
|
createTable(tableName, first, second, third) {
|
|
2001
|
-
return createTable(this, this.up, tableName, first, second, third);
|
|
1775
|
+
return createTable$1(this, this.up, tableName, first, second, third);
|
|
2002
1776
|
}
|
|
2003
1777
|
dropTable(tableName, first, second, third) {
|
|
2004
|
-
return createTable(this, !this.up, tableName, first, second, third);
|
|
1778
|
+
return createTable$1(this, !this.up, tableName, first, second, third);
|
|
2005
1779
|
}
|
|
2006
1780
|
changeTable(tableName, cbOrOptions, cb) {
|
|
2007
1781
|
const [fn, options] = typeof cbOrOptions === "function" ? [cbOrOptions, {}] : [cb, cbOrOptions];
|
|
@@ -2334,7 +2108,7 @@ class Migration {
|
|
|
2334
2108
|
* @param schemaName - name of the schema
|
|
2335
2109
|
*/
|
|
2336
2110
|
createSchema(schemaName) {
|
|
2337
|
-
return createSchema(this, this.up, schemaName);
|
|
2111
|
+
return createSchema$1(this, this.up, schemaName);
|
|
2338
2112
|
}
|
|
2339
2113
|
/**
|
|
2340
2114
|
* Renames a database schema, renames it backwards on roll back.
|
|
@@ -2361,7 +2135,7 @@ class Migration {
|
|
|
2361
2135
|
* @param schemaName - name of the schema
|
|
2362
2136
|
*/
|
|
2363
2137
|
dropSchema(schemaName) {
|
|
2364
|
-
return createSchema(this, !this.up, schemaName);
|
|
2138
|
+
return createSchema$1(this, !this.up, schemaName);
|
|
2365
2139
|
}
|
|
2366
2140
|
/**
|
|
2367
2141
|
* `createExtension` creates a database extension, and removes it on rollback.
|
|
@@ -2735,7 +2509,7 @@ class Migration {
|
|
|
2735
2509
|
return createCollation(this, !this.up, name, options);
|
|
2736
2510
|
}
|
|
2737
2511
|
createView(name, ...args) {
|
|
2738
|
-
const [options, sql] = args.length === 2 ? args : [
|
|
2512
|
+
const [options, sql] = args.length === 2 ? args : [internal.emptyObject, args[0]];
|
|
2739
2513
|
return createView(
|
|
2740
2514
|
this,
|
|
2741
2515
|
this.up,
|
|
@@ -2745,7 +2519,7 @@ class Migration {
|
|
|
2745
2519
|
);
|
|
2746
2520
|
}
|
|
2747
2521
|
dropView(name, ...args) {
|
|
2748
|
-
const [options, sql] = args.length === 2 ? args : [
|
|
2522
|
+
const [options, sql] = args.length === 2 ? args : [internal.emptyObject, args[0]];
|
|
2749
2523
|
return createView(
|
|
2750
2524
|
this,
|
|
2751
2525
|
!this.up,
|
|
@@ -2811,7 +2585,7 @@ class Migration {
|
|
|
2811
2585
|
);
|
|
2812
2586
|
const values = [
|
|
2813
2587
|
table,
|
|
2814
|
-
this.options.snakeCase ?
|
|
2588
|
+
this.options.snakeCase ? internal.toSnakeCase(columnName) : columnName
|
|
2815
2589
|
];
|
|
2816
2590
|
if (schema) {
|
|
2817
2591
|
text += ' AND "table_schema" = $3';
|
|
@@ -2857,7 +2631,7 @@ class Migration {
|
|
|
2857
2631
|
this,
|
|
2858
2632
|
this.up,
|
|
2859
2633
|
name,
|
|
2860
|
-
params.from ||
|
|
2634
|
+
params.from || internal.emptyObject,
|
|
2861
2635
|
params.to
|
|
2862
2636
|
);
|
|
2863
2637
|
}
|
|
@@ -2922,7 +2696,7 @@ const addCheck = (migration, up, tableName, check) => {
|
|
|
2922
2696
|
...t.add(t.check(check))
|
|
2923
2697
|
}));
|
|
2924
2698
|
};
|
|
2925
|
-
const createSchema = async (migration, up, name) => {
|
|
2699
|
+
const createSchema$1 = async (migration, up, name) => {
|
|
2926
2700
|
const ast = {
|
|
2927
2701
|
type: "schema",
|
|
2928
2702
|
action: up ? "create" : "drop",
|
|
@@ -2968,7 +2742,7 @@ const createEnum = async (migration, up, name, values, options = {}) => {
|
|
|
2968
2742
|
let query;
|
|
2969
2743
|
const quotedName = quoteWithSchema(ast);
|
|
2970
2744
|
if (ast.action === "create") {
|
|
2971
|
-
query = `CREATE TYPE ${quotedName} AS ENUM (${values.map(
|
|
2745
|
+
query = `CREATE TYPE ${quotedName} AS ENUM (${values.map(internal.escapeForMigration).join(", ")})`;
|
|
2972
2746
|
} else {
|
|
2973
2747
|
query = `DROP TYPE${ast.dropIfExists ? " IF EXISTS" : ""} ${quotedName}${ast.cascade ? " CASCADE" : ""}`;
|
|
2974
2748
|
}
|
|
@@ -3111,7 +2885,7 @@ const addOrDropEnumValues = async (migration, up, enumName, values, options) =>
|
|
|
3111
2885
|
await Promise.all(
|
|
3112
2886
|
(ast.place === "after" ? [...ast.values].reverse() : ast.values).map(
|
|
3113
2887
|
(value) => migration.adapter.query(
|
|
3114
|
-
`ALTER TYPE ${quoteTable(ast.schema, ast.name)} ADD VALUE${ast.ifNotExists ? " IF NOT EXISTS" : ""} ${
|
|
2888
|
+
`ALTER TYPE ${quoteTable(ast.schema, ast.name)} ADD VALUE${ast.ifNotExists ? " IF NOT EXISTS" : ""} ${internal.singleQuote(value)}${ast.place && ast.relativeTo ? ` ${ast.place.toUpperCase()} ${internal.singleQuote(ast.relativeTo)}` : ""}`
|
|
3115
2889
|
)
|
|
3116
2890
|
)
|
|
3117
2891
|
);
|
|
@@ -3125,7 +2899,7 @@ const addOrDropEnumValues = async (migration, up, enumName, values, options) =>
|
|
|
3125
2899
|
migration,
|
|
3126
2900
|
ast,
|
|
3127
2901
|
existingValues.filter((v) => !ast.values.includes(v)),
|
|
3128
|
-
(quotedName2, table, column) => `Cannot drop ${quotedName2} enum values [${ast.values.map(
|
|
2902
|
+
(quotedName2, table, column) => `Cannot drop ${quotedName2} enum values [${ast.values.map(internal.singleQuote).join(
|
|
3129
2903
|
", "
|
|
3130
2904
|
)}]: table ${table} has a row with such value in the column "${column}"`
|
|
3131
2905
|
);
|
|
@@ -3151,7 +2925,7 @@ const changeEnumValues = async (migration, enumName, fromValues, toValues) => {
|
|
|
3151
2925
|
migration,
|
|
3152
2926
|
ast,
|
|
3153
2927
|
ast.toValues,
|
|
3154
|
-
(quotedName, table, column) => `Cannot change ${quotedName} enum values from [${fromValues.map(
|
|
2928
|
+
(quotedName, table, column) => `Cannot change ${quotedName} enum values from [${fromValues.map(internal.singleQuote).join(", ")}] to [${toValues.map(internal.singleQuote).join(
|
|
3155
2929
|
", "
|
|
3156
2930
|
)}]: table ${table} has a row with removed value in the column "${column}"`
|
|
3157
2931
|
);
|
|
@@ -3170,10 +2944,10 @@ const recreateEnum = async (migration, { schema, name }, values, errorMessage) =
|
|
|
3170
2944
|
) AS "columns"
|
|
3171
2945
|
FROM pg_class c
|
|
3172
2946
|
JOIN pg_catalog.pg_namespace n ON n.oid = relnamespace
|
|
3173
|
-
JOIN pg_type bt ON bt.typname = ${
|
|
2947
|
+
JOIN pg_type bt ON bt.typname = ${internal.singleQuote(name)}
|
|
3174
2948
|
JOIN pg_type t ON t.oid = bt.oid OR t.typelem = bt.oid
|
|
3175
2949
|
JOIN pg_attribute a ON a.attrelid = c.oid AND a.atttypid = t.oid
|
|
3176
|
-
JOIN pg_namespace tn ON tn.oid = t.typnamespace AND tn.nspname = ${
|
|
2950
|
+
JOIN pg_namespace tn ON tn.oid = t.typnamespace AND tn.nspname = ${internal.singleQuote(
|
|
3177
2951
|
schema ?? defaultSchema
|
|
3178
2952
|
)}
|
|
3179
2953
|
WHERE c.relkind IN (${relKinds.map((c) => `'${c}'`).join(", ")})
|
|
@@ -3187,7 +2961,7 @@ GROUP BY n.nspname, c.relname`
|
|
|
3187
2961
|
);
|
|
3188
2962
|
sql.push(
|
|
3189
2963
|
`DROP TYPE ${quotedName}`,
|
|
3190
|
-
`CREATE TYPE ${quotedName} AS ENUM (${values.map(
|
|
2964
|
+
`CREATE TYPE ${quotedName} AS ENUM (${values.map(internal.singleQuote).join(", ")})`
|
|
3191
2965
|
);
|
|
3192
2966
|
await migration.adapter.query(sql.join(";\n"));
|
|
3193
2967
|
for (const t of tables) {
|
|
@@ -3217,7 +2991,7 @@ const writeMigrationFile = async (config, version, name, migrationCode) => {
|
|
|
3217
2991
|
config.migrationsPath,
|
|
3218
2992
|
`${version}_${name.replaceAll(" ", "-")}.ts`
|
|
3219
2993
|
);
|
|
3220
|
-
const importPath =
|
|
2994
|
+
const importPath = internal.getImportPath(
|
|
3221
2995
|
filePath,
|
|
3222
2996
|
path.join(config.basePath, config.dbScript)
|
|
3223
2997
|
);
|
|
@@ -3226,7 +3000,7 @@ const writeMigrationFile = async (config, version, name, migrationCode) => {
|
|
|
3226
3000
|
`import { change } from '${importPath}';
|
|
3227
3001
|
${migrationCode}`
|
|
3228
3002
|
);
|
|
3229
|
-
config.logger?.log(`Created ${
|
|
3003
|
+
config.logger?.log(`Created ${internal.pathToLog(filePath)}`);
|
|
3230
3004
|
};
|
|
3231
3005
|
const newMigration = async (config, name) => {
|
|
3232
3006
|
const version = await makeFileVersion({}, config);
|
|
@@ -3408,7 +3182,7 @@ const getMigrations = async (ctx, config, up, allowDuplicates, getVersion = getM
|
|
|
3408
3182
|
function getMigrationsFromConfig(config, allowDuplicates, getVersion = getMigrationVersionOrThrow) {
|
|
3409
3183
|
const result = [];
|
|
3410
3184
|
const versions = {};
|
|
3411
|
-
const { migrations
|
|
3185
|
+
const { migrations } = config;
|
|
3412
3186
|
for (const key in migrations) {
|
|
3413
3187
|
const version = getVersion(config, path.basename(key));
|
|
3414
3188
|
if (versions[version] && !allowDuplicates) {
|
|
@@ -3418,7 +3192,7 @@ function getMigrationsFromConfig(config, allowDuplicates, getVersion = getMigrat
|
|
|
3418
3192
|
}
|
|
3419
3193
|
versions[version] = key;
|
|
3420
3194
|
result.push({
|
|
3421
|
-
path:
|
|
3195
|
+
path: key,
|
|
3422
3196
|
version,
|
|
3423
3197
|
load: migrations[key]
|
|
3424
3198
|
});
|
|
@@ -3468,7 +3242,7 @@ async function getMigrationsFromFiles(config, allowDuplicates, getVersion = getM
|
|
|
3468
3242
|
}
|
|
3469
3243
|
data.renameTo = {
|
|
3470
3244
|
to: config.migrationId,
|
|
3471
|
-
map: () => renameMigrationsMap(
|
|
3245
|
+
map: () => renameMigrationsMap(migrationsPath, file.name)
|
|
3472
3246
|
};
|
|
3473
3247
|
return data;
|
|
3474
3248
|
} else {
|
|
@@ -3507,8 +3281,8 @@ Run \`**db command** rebase\` to reorganize files with duplicated versions.`
|
|
|
3507
3281
|
result.migrations.sort(sortMigrationsAsc);
|
|
3508
3282
|
return result;
|
|
3509
3283
|
}
|
|
3510
|
-
const renameMigrationsMap = async (
|
|
3511
|
-
const filePath = path.join(
|
|
3284
|
+
const renameMigrationsMap = async (migrationsPath, fileName) => {
|
|
3285
|
+
const filePath = path.join(migrationsPath, fileName);
|
|
3512
3286
|
const json = await fs.readFile(filePath, "utf-8");
|
|
3513
3287
|
let data;
|
|
3514
3288
|
try {
|
|
@@ -3559,25 +3333,90 @@ function getDigitsPrefix(name) {
|
|
|
3559
3333
|
return value;
|
|
3560
3334
|
}
|
|
3561
3335
|
|
|
3562
|
-
const
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
}
|
|
3571
|
-
|
|
3572
|
-
|
|
3336
|
+
const getMaybeTransactionAdapter = (db) => "$getAdapter" in db ? db.$getAdapter() : db;
|
|
3337
|
+
const runSqlInSavePoint = async (db, sql, code) => {
|
|
3338
|
+
const adapter = getMaybeTransactionAdapter(db);
|
|
3339
|
+
try {
|
|
3340
|
+
await adapter.query(
|
|
3341
|
+
adapter.isInTransaction() ? `SAVEPOINT s; ${sql}; RELEASE SAVEPOINT s` : sql
|
|
3342
|
+
);
|
|
3343
|
+
return "done";
|
|
3344
|
+
} catch (err) {
|
|
3345
|
+
if (err.code === code) {
|
|
3346
|
+
if (adapter.isInTransaction()) {
|
|
3347
|
+
await adapter.query(`ROLLBACK TO SAVEPOINT s`);
|
|
3348
|
+
}
|
|
3349
|
+
return "already";
|
|
3350
|
+
}
|
|
3351
|
+
throw err;
|
|
3352
|
+
}
|
|
3353
|
+
};
|
|
3354
|
+
|
|
3355
|
+
class CreateOrDropError extends Error {
|
|
3356
|
+
constructor(message, status, cause) {
|
|
3357
|
+
super(message);
|
|
3358
|
+
this.status = status;
|
|
3359
|
+
this.cause = cause;
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
const createDatabase = async (db, {
|
|
3363
|
+
database,
|
|
3364
|
+
owner
|
|
3365
|
+
}) => {
|
|
3366
|
+
return createOrDrop(
|
|
3367
|
+
db,
|
|
3368
|
+
`CREATE DATABASE "${database}"${owner ? ` OWNER "${owner}"` : ""}`
|
|
3369
|
+
);
|
|
3370
|
+
};
|
|
3371
|
+
const dropDatabase = async (db, { database }) => {
|
|
3372
|
+
return createOrDrop(db, `DROP DATABASE "${database}"`);
|
|
3373
|
+
};
|
|
3374
|
+
const createOrDrop = async (db, sql) => {
|
|
3375
|
+
try {
|
|
3376
|
+
const adapter = getMaybeTransactionAdapter(db);
|
|
3377
|
+
await adapter.query(sql);
|
|
3378
|
+
return "done";
|
|
3379
|
+
} catch (error) {
|
|
3380
|
+
const err = error;
|
|
3381
|
+
if (typeof err.message === "string" && err.message.includes("sslmode=require")) {
|
|
3382
|
+
throw new CreateOrDropError("SSL required", "ssl-required", err);
|
|
3383
|
+
}
|
|
3384
|
+
if (err.code === "42P04" || err.code === "3D000") {
|
|
3385
|
+
return "already";
|
|
3386
|
+
}
|
|
3387
|
+
if (err.code === "42501") {
|
|
3388
|
+
throw new CreateOrDropError("Insufficient privilege", "forbidden", err);
|
|
3389
|
+
}
|
|
3390
|
+
if (typeof err.message === "string" && err.message.includes("password authentication failed")) {
|
|
3391
|
+
throw new CreateOrDropError("Authentication failed", "auth-failed", err);
|
|
3392
|
+
}
|
|
3393
|
+
throw err;
|
|
3394
|
+
}
|
|
3395
|
+
};
|
|
3396
|
+
const createSchema = async (db, sql) => runSqlInSavePoint(db, `CREATE SCHEMA ${sql}`, "42P06");
|
|
3397
|
+
const dropSchema = async (db, sql) => runSqlInSavePoint(db, `DROP SCHEMA ${sql}`, "3F000");
|
|
3398
|
+
const createTable = async (db, sql) => runSqlInSavePoint(db, `CREATE TABLE ${sql}`, "42P07");
|
|
3399
|
+
const dropTable = async (db, sql) => runSqlInSavePoint(db, `DROP TABLE ${sql}`, "42P01");
|
|
3400
|
+
|
|
3401
|
+
const saveMigratedVersion = async (db, version, name, config) => {
|
|
3402
|
+
await db.silentArrays(
|
|
3403
|
+
`INSERT INTO ${migrationsSchemaTableSql(
|
|
3404
|
+
db,
|
|
3405
|
+
config
|
|
3406
|
+
)}(version, name) VALUES ($1, $2)`,
|
|
3407
|
+
[version, name]
|
|
3408
|
+
);
|
|
3409
|
+
};
|
|
3410
|
+
const createMigrationsSchemaAndTable = async (db, config) => {
|
|
3411
|
+
const adapter = getMaybeTransactionAdapter(db);
|
|
3573
3412
|
const { schema, table } = getMigrationsSchemaAndTable(adapter, config);
|
|
3574
3413
|
if (schema) {
|
|
3575
|
-
const res2 = await createSchema
|
|
3414
|
+
const res2 = await createSchema(db, schema);
|
|
3576
3415
|
if (res2 === "done") {
|
|
3577
3416
|
config.logger?.log(`Created schema "${schema}"`);
|
|
3578
3417
|
}
|
|
3579
3418
|
}
|
|
3580
|
-
const res = await createTable
|
|
3419
|
+
const res = await createTable(
|
|
3581
3420
|
db,
|
|
3582
3421
|
`${schema ? `"${schema}"."${table}"` : `"${table}"`} (version TEXT NOT NULL, name TEXT NOT NULL)`
|
|
3583
3422
|
);
|
|
@@ -3602,53 +3441,62 @@ const deleteMigratedVersion = async (adapter, version, name, config) => {
|
|
|
3602
3441
|
class NoMigrationsTableError extends Error {
|
|
3603
3442
|
}
|
|
3604
3443
|
const getMigratedVersionsMap = async (ctx, adapter, config, renameTo) => {
|
|
3444
|
+
const table = migrationsSchemaTableSql(adapter, config);
|
|
3445
|
+
const inTransaction = "isInTransaction" in adapter && adapter.isInTransaction();
|
|
3446
|
+
let result;
|
|
3605
3447
|
try {
|
|
3606
|
-
|
|
3607
|
-
|
|
3448
|
+
if (inTransaction) {
|
|
3449
|
+
await adapter.query(`SAVEPOINT check_migrations_table`);
|
|
3450
|
+
}
|
|
3451
|
+
result = await adapter.arrays(
|
|
3608
3452
|
`SELECT * FROM ${table} ORDER BY version`
|
|
3609
3453
|
);
|
|
3610
|
-
if (
|
|
3611
|
-
|
|
3612
|
-
const map = {};
|
|
3613
|
-
for (const item of migrations) {
|
|
3614
|
-
const name = path.basename(item.path);
|
|
3615
|
-
map[item.version] = name.slice(getDigitsPrefix(name).length + 1);
|
|
3616
|
-
}
|
|
3617
|
-
for (const row of result.rows) {
|
|
3618
|
-
const [version] = row;
|
|
3619
|
-
const name = map[version];
|
|
3620
|
-
if (!name) {
|
|
3621
|
-
throw new Error(
|
|
3622
|
-
`Migration for version ${version} is stored in db but is not found among available migrations`
|
|
3623
|
-
);
|
|
3624
|
-
}
|
|
3625
|
-
row[1] = name;
|
|
3626
|
-
}
|
|
3627
|
-
await adapter.arrays(`ALTER TABLE ${table} ADD COLUMN name TEXT`);
|
|
3628
|
-
await Promise.all(
|
|
3629
|
-
result.rows.map(
|
|
3630
|
-
([version, name]) => adapter.arrays(`UPDATE ${table} SET name = $2 WHERE version = $1`, [
|
|
3631
|
-
version,
|
|
3632
|
-
name
|
|
3633
|
-
])
|
|
3634
|
-
)
|
|
3635
|
-
);
|
|
3636
|
-
await adapter.arrays(
|
|
3637
|
-
`ALTER TABLE ${table} ALTER COLUMN name SET NOT NULL`
|
|
3638
|
-
);
|
|
3639
|
-
}
|
|
3640
|
-
let versions = Object.fromEntries(result.rows);
|
|
3641
|
-
if (renameTo) {
|
|
3642
|
-
versions = await renameMigrations(config, adapter, versions, renameTo);
|
|
3454
|
+
if (inTransaction) {
|
|
3455
|
+
await adapter.query(`RELEASE SAVEPOINT check_migrations_table`);
|
|
3643
3456
|
}
|
|
3644
|
-
return { map: versions, sequence: result.rows.map((row) => +row[0]) };
|
|
3645
3457
|
} catch (err) {
|
|
3646
3458
|
if (err.code === "42P01") {
|
|
3459
|
+
if (inTransaction) {
|
|
3460
|
+
await adapter.query(`ROLLBACK TO SAVEPOINT check_migrations_table`);
|
|
3461
|
+
}
|
|
3647
3462
|
throw new NoMigrationsTableError();
|
|
3648
3463
|
} else {
|
|
3649
3464
|
throw err;
|
|
3650
3465
|
}
|
|
3651
3466
|
}
|
|
3467
|
+
if (!result.fields[1]) {
|
|
3468
|
+
const { migrations } = await getMigrations(ctx, config, true);
|
|
3469
|
+
const map = {};
|
|
3470
|
+
for (const item of migrations) {
|
|
3471
|
+
const name = path.basename(item.path);
|
|
3472
|
+
map[item.version] = name.slice(getDigitsPrefix(name).length + 1);
|
|
3473
|
+
}
|
|
3474
|
+
for (const row of result.rows) {
|
|
3475
|
+
const [version] = row;
|
|
3476
|
+
const name = map[version];
|
|
3477
|
+
if (!name) {
|
|
3478
|
+
throw new Error(
|
|
3479
|
+
`Migration for version ${version} is stored in db but is not found among available migrations`
|
|
3480
|
+
);
|
|
3481
|
+
}
|
|
3482
|
+
row[1] = name;
|
|
3483
|
+
}
|
|
3484
|
+
await adapter.arrays(`ALTER TABLE ${table} ADD COLUMN name TEXT`);
|
|
3485
|
+
await Promise.all(
|
|
3486
|
+
result.rows.map(
|
|
3487
|
+
([version, name]) => adapter.arrays(`UPDATE ${table} SET name = $2 WHERE version = $1`, [
|
|
3488
|
+
version,
|
|
3489
|
+
name
|
|
3490
|
+
])
|
|
3491
|
+
)
|
|
3492
|
+
);
|
|
3493
|
+
await adapter.arrays(`ALTER TABLE ${table} ALTER COLUMN name SET NOT NULL`);
|
|
3494
|
+
}
|
|
3495
|
+
let versions = Object.fromEntries(result.rows);
|
|
3496
|
+
if (renameTo) {
|
|
3497
|
+
versions = await renameMigrations(config, adapter, versions, renameTo);
|
|
3498
|
+
}
|
|
3499
|
+
return { map: versions, sequence: result.rows.map((row) => +row[0]) };
|
|
3652
3500
|
};
|
|
3653
3501
|
async function renameMigrations(config, trx, versions, renameTo) {
|
|
3654
3502
|
let first;
|
|
@@ -3679,11 +3527,35 @@ async function renameMigrations(config, trx, versions, renameTo) {
|
|
|
3679
3527
|
return updatedVersions;
|
|
3680
3528
|
}
|
|
3681
3529
|
|
|
3530
|
+
const migrateConfigDefaults = {
|
|
3531
|
+
migrationId: { serial: 4 },
|
|
3532
|
+
migrationsTable: "schemaMigrations",
|
|
3533
|
+
transaction: "single"
|
|
3534
|
+
};
|
|
3535
|
+
const handleConfigLogger = (config) => {
|
|
3536
|
+
return config.log === true ? config.logger || console : config.log === false ? void 0 : config.logger;
|
|
3537
|
+
};
|
|
3538
|
+
const processMigrateConfig = (config) => {
|
|
3539
|
+
let migrationsPath;
|
|
3540
|
+
if (!("migrations" in config)) {
|
|
3541
|
+
migrationsPath = config.migrationsPath ? config.migrationsPath : path$1.join("src", "db", "migrations");
|
|
3542
|
+
if (config.basePath && !path$1.isAbsolute(migrationsPath)) {
|
|
3543
|
+
migrationsPath = path$1.resolve(config.basePath, migrationsPath);
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
return {
|
|
3547
|
+
...migrateConfigDefaults,
|
|
3548
|
+
...config,
|
|
3549
|
+
migrationsPath,
|
|
3550
|
+
logger: handleConfigLogger(config)
|
|
3551
|
+
};
|
|
3552
|
+
};
|
|
3682
3553
|
const transactionIfSingle = (adapter, config, fn) => {
|
|
3683
3554
|
return config.transaction === "single" ? transaction(adapter, config, fn) : fn(adapter);
|
|
3684
3555
|
};
|
|
3685
3556
|
function makeMigrateFn(up, defaultCount, fn) {
|
|
3686
|
-
return async (db,
|
|
3557
|
+
return async (db, publicConfig, params) => {
|
|
3558
|
+
const config = processMigrateConfig(publicConfig);
|
|
3687
3559
|
const ctx = params?.ctx || {};
|
|
3688
3560
|
const set = await getMigrations(ctx, config, up);
|
|
3689
3561
|
const count = params?.count ?? defaultCount;
|
|
@@ -3726,7 +3598,16 @@ function makeMigrateFn(up, defaultCount, fn) {
|
|
|
3726
3598
|
const migrate = makeMigrateFn(
|
|
3727
3599
|
true,
|
|
3728
3600
|
Infinity,
|
|
3729
|
-
(trx, config, set, versions, count, force) => migrateOrRollback(
|
|
3601
|
+
(trx, config, set, versions, count, force) => migrateOrRollback(
|
|
3602
|
+
trx,
|
|
3603
|
+
config,
|
|
3604
|
+
set,
|
|
3605
|
+
versions,
|
|
3606
|
+
count,
|
|
3607
|
+
true,
|
|
3608
|
+
false,
|
|
3609
|
+
force
|
|
3610
|
+
)
|
|
3730
3611
|
);
|
|
3731
3612
|
const migrateAndClose = async (db, config, params) => {
|
|
3732
3613
|
const adapter = getMaybeTransactionAdapter(db);
|
|
@@ -3734,26 +3615,46 @@ const migrateAndClose = async (db, config, params) => {
|
|
|
3734
3615
|
await adapter.close();
|
|
3735
3616
|
};
|
|
3736
3617
|
async function runMigration(db, ...args) {
|
|
3737
|
-
const [
|
|
3618
|
+
const [rawConfig, migration] = args.length === 1 ? [{}, args[0]] : [args[0], args[1]];
|
|
3619
|
+
const config = {
|
|
3620
|
+
...rawConfig,
|
|
3621
|
+
logger: handleConfigLogger(rawConfig)
|
|
3622
|
+
};
|
|
3738
3623
|
const adapter = getMaybeTransactionAdapter(db);
|
|
3739
3624
|
await transaction(adapter, config, async (trx) => {
|
|
3740
3625
|
clearChanges();
|
|
3741
3626
|
const changes = await getChanges({ load: migration });
|
|
3742
|
-
|
|
3743
|
-
await applyMigration(trx, true, changes, config2);
|
|
3627
|
+
await applyMigration(trx, true, changes, config);
|
|
3744
3628
|
});
|
|
3745
3629
|
}
|
|
3746
3630
|
const rollback = makeMigrateFn(
|
|
3747
3631
|
false,
|
|
3748
3632
|
1,
|
|
3749
|
-
(trx, config, set, versions, count, force) => migrateOrRollback(
|
|
3633
|
+
(trx, config, set, versions, count, force) => migrateOrRollback(
|
|
3634
|
+
trx,
|
|
3635
|
+
config,
|
|
3636
|
+
set,
|
|
3637
|
+
versions,
|
|
3638
|
+
count,
|
|
3639
|
+
false,
|
|
3640
|
+
false,
|
|
3641
|
+
force
|
|
3642
|
+
)
|
|
3750
3643
|
);
|
|
3751
3644
|
const redo = makeMigrateFn(
|
|
3752
3645
|
true,
|
|
3753
3646
|
1,
|
|
3754
3647
|
async (trx, config, set, versions, count, force) => {
|
|
3755
3648
|
set.migrations.reverse();
|
|
3756
|
-
await migrateOrRollback(
|
|
3649
|
+
await migrateOrRollback(
|
|
3650
|
+
trx,
|
|
3651
|
+
config,
|
|
3652
|
+
set,
|
|
3653
|
+
versions,
|
|
3654
|
+
count,
|
|
3655
|
+
false,
|
|
3656
|
+
true
|
|
3657
|
+
);
|
|
3757
3658
|
set.migrations.reverse();
|
|
3758
3659
|
return migrateOrRollback(
|
|
3759
3660
|
trx,
|
|
@@ -3768,7 +3669,7 @@ const redo = makeMigrateFn(
|
|
|
3768
3669
|
);
|
|
3769
3670
|
}
|
|
3770
3671
|
);
|
|
3771
|
-
const getDb = (adapter) =>
|
|
3672
|
+
const getDb = (adapter) => internal.createDbWithAdapter({ adapter });
|
|
3772
3673
|
const migrateOrRollback = async (trx, config, set, versions, count, up, redo2, force, skipLock) => {
|
|
3773
3674
|
const { sequence, map: versionsMap } = versions;
|
|
3774
3675
|
if (up) {
|
|
@@ -3824,7 +3725,7 @@ const migrateOrRollback = async (trx, config, set, versions, count, up, redo2, f
|
|
|
3824
3725
|
await changeMigratedVersion(adapter, up, file, config);
|
|
3825
3726
|
(migrations ?? (migrations = [])).push(file);
|
|
3826
3727
|
if (up) {
|
|
3827
|
-
const name = path.basename(file.path);
|
|
3728
|
+
const name = path$1.basename(file.path);
|
|
3828
3729
|
versionsMap[file.version] = name;
|
|
3829
3730
|
sequence.push(+file.version);
|
|
3830
3731
|
} else {
|
|
@@ -3832,11 +3733,11 @@ const migrateOrRollback = async (trx, config, set, versions, count, up, redo2, f
|
|
|
3832
3733
|
sequence.pop();
|
|
3833
3734
|
}
|
|
3834
3735
|
config.logger?.log(
|
|
3835
|
-
`${up ? "Migrated" : "Rolled back"} ${
|
|
3736
|
+
`${up ? "Migrated" : "Rolled back"} ${internal.pathToLog(file.path)}
|
|
3836
3737
|
`
|
|
3837
3738
|
);
|
|
3838
3739
|
}
|
|
3839
|
-
migrations ?? (migrations =
|
|
3740
|
+
migrations ?? (migrations = internal.emptyArray);
|
|
3840
3741
|
const afterMigrate = config[up ? "afterMigrate" : "afterRollback"];
|
|
3841
3742
|
if (config.afterChange || afterMigrate) {
|
|
3842
3743
|
db ?? (db = getDb(trx));
|
|
@@ -3871,7 +3772,7 @@ const checkMigrationOrder = (config, set, { sequence, map }, force) => {
|
|
|
3871
3772
|
if (version > last || map[file.version]) continue;
|
|
3872
3773
|
if (!force) {
|
|
3873
3774
|
throw new Error(
|
|
3874
|
-
`Cannot migrate ${path.basename(
|
|
3775
|
+
`Cannot migrate ${path$1.basename(
|
|
3875
3776
|
file.path
|
|
3876
3777
|
)} because the higher position ${map[versionToString(config, last)]} was already migrated.
|
|
3877
3778
|
Run \`**db command** up force\` to rollback the above migrations and migrate all`
|
|
@@ -3888,7 +3789,7 @@ const getChanges = async (file, config) => {
|
|
|
3888
3789
|
let changes = file.path ? changeCache[file.path] : void 0;
|
|
3889
3790
|
if (!changes) {
|
|
3890
3791
|
const module = await file.load();
|
|
3891
|
-
const exported = module?.default &&
|
|
3792
|
+
const exported = module?.default && internal.toArray(module.default);
|
|
3892
3793
|
if (config?.forceDefaultExports && !exported) {
|
|
3893
3794
|
throw new RakeDbError(
|
|
3894
3795
|
`Missing a default export in ${file.path} migration`
|
|
@@ -3907,146 +3808,337 @@ const runMigrationInOwnTransaction = (adapter, up, changes, config) => {
|
|
|
3907
3808
|
);
|
|
3908
3809
|
};
|
|
3909
3810
|
const applyMigration = async (trx, up, changes, config) => {
|
|
3910
|
-
const
|
|
3811
|
+
const { adapter, getDb: getDb2 } = createMigrationInterface(trx, up, config);
|
|
3911
3812
|
if (changes.length) {
|
|
3912
3813
|
const from = up ? 0 : changes.length - 1;
|
|
3913
3814
|
const to = up ? changes.length : -1;
|
|
3914
3815
|
const step = up ? 1 : -1;
|
|
3915
3816
|
for (let i = from; i !== to; i += step) {
|
|
3916
|
-
|
|
3817
|
+
const change = changes[i];
|
|
3818
|
+
const db = getDb2(change.config.columnTypes);
|
|
3819
|
+
await change.fn(db, up);
|
|
3917
3820
|
}
|
|
3918
3821
|
}
|
|
3919
|
-
return
|
|
3822
|
+
return adapter;
|
|
3920
3823
|
};
|
|
3921
3824
|
const changeMigratedVersion = async (adapter, up, file, config) => {
|
|
3922
3825
|
await (up ? saveMigratedVersion : deleteMigratedVersion)(
|
|
3923
3826
|
adapter,
|
|
3924
3827
|
file.version,
|
|
3925
|
-
path.basename(file.path).slice(file.version.length + 1),
|
|
3828
|
+
path$1.basename(file.path).slice(file.version.length + 1),
|
|
3926
3829
|
config
|
|
3927
3830
|
);
|
|
3928
3831
|
};
|
|
3929
3832
|
|
|
3930
|
-
const
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
})
|
|
3941
|
-
);
|
|
3942
|
-
});
|
|
3943
|
-
if (files > 0) {
|
|
3944
|
-
config.logger?.log(
|
|
3945
|
-
`Applied ${files} recurrent migration file${files > 1 ? "s" : ""}`
|
|
3833
|
+
const rakeDbConfigDefaults = {
|
|
3834
|
+
...migrateConfigDefaults,
|
|
3835
|
+
schemaConfig: internal.defaultSchemaConfig,
|
|
3836
|
+
snakeCase: false,
|
|
3837
|
+
commands: {},
|
|
3838
|
+
log: true,
|
|
3839
|
+
logger: console,
|
|
3840
|
+
import() {
|
|
3841
|
+
throw new Error(
|
|
3842
|
+
"Add `import: (path) => import(path),` setting to `rakeDb` config"
|
|
3946
3843
|
);
|
|
3947
3844
|
}
|
|
3948
3845
|
};
|
|
3949
|
-
const readdirRecursive = async (dirPath, cb) => {
|
|
3950
|
-
const list = await fs.readdir(dirPath).catch((err) => {
|
|
3951
|
-
if (err.code !== "ENOENT") throw err;
|
|
3952
|
-
return;
|
|
3953
|
-
});
|
|
3954
|
-
if (!list) return;
|
|
3955
|
-
await Promise.all(
|
|
3956
|
-
list.map(async (item) => {
|
|
3957
|
-
const path$1 = path.join(dirPath, item);
|
|
3958
|
-
const info = await fs.stat(path$1);
|
|
3959
|
-
if (info.isDirectory()) {
|
|
3960
|
-
await readdirRecursive(path$1, cb);
|
|
3961
|
-
} else if (info.isFile() && path$1.endsWith(".sql")) {
|
|
3962
|
-
await cb(path$1);
|
|
3963
|
-
}
|
|
3964
|
-
})
|
|
3965
|
-
);
|
|
3966
|
-
};
|
|
3967
3846
|
|
|
3968
|
-
const
|
|
3969
|
-
const
|
|
3970
|
-
const
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
}
|
|
3988
|
-
);
|
|
3989
|
-
if (!res) continue;
|
|
3990
|
-
if (action === "create") {
|
|
3991
|
-
await adapter.transaction(async (tx) => {
|
|
3992
|
-
const schema = tx.getSchema();
|
|
3993
|
-
if (schema) {
|
|
3994
|
-
const quoted = `"${typeof schema === "function" ? schema() : schema}"`;
|
|
3995
|
-
const res2 = await createSchema$1(tx, quoted);
|
|
3996
|
-
if (res2 === "done") {
|
|
3997
|
-
config.logger?.log(`Created schema ${quoted}`);
|
|
3998
|
-
}
|
|
3999
|
-
}
|
|
4000
|
-
await createMigrationsSchemaAndTable(tx, config);
|
|
4001
|
-
});
|
|
4002
|
-
if (!dontClose) {
|
|
4003
|
-
await adapter.close();
|
|
4004
|
-
}
|
|
3847
|
+
const ESC = "\x1B";
|
|
3848
|
+
const CSI = `${ESC}[`;
|
|
3849
|
+
const cursorShow = `${CSI}?25h`;
|
|
3850
|
+
const cursorHide = `${CSI}?25l`;
|
|
3851
|
+
const { stdin, stdout } = process;
|
|
3852
|
+
const visibleChars = (s) => s.replace(
|
|
3853
|
+
// eslint-disable-next-line no-control-regex
|
|
3854
|
+
/[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d/#&.:=?%@~_]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PRZcf-ntqry=><~]))/g,
|
|
3855
|
+
""
|
|
3856
|
+
).length;
|
|
3857
|
+
const clear = (text) => {
|
|
3858
|
+
const rows = text.split(/\r?\n/).reduce(
|
|
3859
|
+
(rows2, line) => rows2 + 1 + Math.floor(Math.max(visibleChars(line) - 1, 0) / stdout.columns),
|
|
3860
|
+
0
|
|
3861
|
+
);
|
|
3862
|
+
let clear2 = "";
|
|
3863
|
+
for (let i = 0; i < rows; i++) {
|
|
3864
|
+
clear2 += `${CSI}2K`;
|
|
3865
|
+
if (i < rows - 1) {
|
|
3866
|
+
clear2 += `${CSI}${i < rows - 1 ? "1A" : "G"}`;
|
|
4005
3867
|
}
|
|
4006
3868
|
}
|
|
3869
|
+
return clear2;
|
|
4007
3870
|
};
|
|
4008
|
-
const
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
const
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
);
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
3871
|
+
const prompt = async ({
|
|
3872
|
+
render,
|
|
3873
|
+
onKeyPress,
|
|
3874
|
+
validate,
|
|
3875
|
+
value,
|
|
3876
|
+
cursor: showCursor
|
|
3877
|
+
}) => {
|
|
3878
|
+
stdin.resume();
|
|
3879
|
+
if (stdin.isTTY) stdin.setRawMode(true);
|
|
3880
|
+
stdin.setEncoding("utf-8");
|
|
3881
|
+
if (!showCursor) stdout.write(cursorHide);
|
|
3882
|
+
return new Promise((res) => {
|
|
3883
|
+
let prevText;
|
|
3884
|
+
const ctx = {
|
|
3885
|
+
value,
|
|
3886
|
+
submitted: false,
|
|
3887
|
+
render() {
|
|
3888
|
+
let text = (ctx.submitted ? internal.colors.greenBold("\u2714") : internal.colors.yellowBold("?")) + " " + render(ctx);
|
|
3889
|
+
if (ctx.submitted) text += "\n";
|
|
3890
|
+
stdout.write(prevText ? clear(prevText) + "\r" + text : text);
|
|
3891
|
+
prevText = text;
|
|
3892
|
+
},
|
|
3893
|
+
submit(value2) {
|
|
3894
|
+
if (value2 !== void 0) ctx.value = value2;
|
|
3895
|
+
if (ctx.value === void 0 || validate && !validate?.(ctx)) return;
|
|
3896
|
+
ctx.submitted = true;
|
|
3897
|
+
ctx.render();
|
|
3898
|
+
close();
|
|
3899
|
+
res(ctx.value);
|
|
3900
|
+
}
|
|
3901
|
+
};
|
|
3902
|
+
const close = () => {
|
|
3903
|
+
if (!showCursor) stdout.write(cursorShow);
|
|
3904
|
+
if (stdin.isTTY) stdin.setRawMode(false);
|
|
3905
|
+
stdin.off("data", keypress);
|
|
3906
|
+
stdin.pause();
|
|
3907
|
+
};
|
|
3908
|
+
const keypress = (s) => {
|
|
3909
|
+
if (s === "" || s === "") {
|
|
3910
|
+
close?.();
|
|
3911
|
+
process.exit(0);
|
|
3912
|
+
}
|
|
3913
|
+
if (s === "\r" || s === "\n" || s === "\r\n") {
|
|
3914
|
+
ctx.submit();
|
|
3915
|
+
} else {
|
|
3916
|
+
onKeyPress(ctx, s);
|
|
3917
|
+
}
|
|
3918
|
+
};
|
|
3919
|
+
stdin.on("data", keypress);
|
|
3920
|
+
ctx.render();
|
|
3921
|
+
});
|
|
3922
|
+
};
|
|
3923
|
+
const defaultActive = (s) => `${internal.colors.blueBold("\u276F")} ${s}`;
|
|
3924
|
+
const defaultInactive = (s) => ` ${s}`;
|
|
3925
|
+
const promptSelect = ({
|
|
3926
|
+
message,
|
|
3927
|
+
options,
|
|
3928
|
+
active = defaultActive,
|
|
3929
|
+
inactive = defaultInactive
|
|
3930
|
+
}) => prompt({
|
|
3931
|
+
value: 0,
|
|
3932
|
+
render(ctx) {
|
|
3933
|
+
let text = `${message} ${internal.colors.pale(
|
|
3934
|
+
"Use arrows or jk. Press enter to submit."
|
|
3935
|
+
)}
|
|
3936
|
+
`;
|
|
3937
|
+
for (let i = 0; i < options.length; i++) {
|
|
3938
|
+
text += (ctx.value === i ? active : inactive)(options[i]) + "\n";
|
|
3939
|
+
}
|
|
3940
|
+
return text;
|
|
3941
|
+
},
|
|
3942
|
+
onKeyPress(ctx, s) {
|
|
3943
|
+
ctx.value = s === "\x1B[H" ? 0 : s === "\x1B[F" ? options.length - 1 : s === "\x1B[A" || s === "k" ? ctx.value === 0 ? options.length - 1 : ctx.value - 1 : s === "\x1B[B" || s === "j" || s === " " ? ctx.value === options.length - 1 ? 0 : ctx.value + 1 : ctx.value;
|
|
3944
|
+
ctx.render();
|
|
3945
|
+
}
|
|
3946
|
+
});
|
|
3947
|
+
const promptConfirm = ({
|
|
3948
|
+
message
|
|
3949
|
+
}) => prompt({
|
|
3950
|
+
value: true,
|
|
3951
|
+
render(ctx) {
|
|
3952
|
+
return `${internal.colors.bright(message)}
|
|
3953
|
+
${ctx.submitted ? `> ${ctx.value ? internal.colors.greenBold("Yes") : internal.colors.yellowBold("No")}` : internal.colors.pale(`> (Y/n)`)}
|
|
3954
|
+
`;
|
|
3955
|
+
},
|
|
3956
|
+
onKeyPress(ctx, s) {
|
|
3957
|
+
let ok;
|
|
3958
|
+
if (s === "y" || s === "Y") ok = true;
|
|
3959
|
+
else if (s === "n" || s === "N") ok = false;
|
|
3960
|
+
if (ok !== void 0) {
|
|
3961
|
+
ctx.submit(ok);
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
});
|
|
3965
|
+
const promptText = ({
|
|
3966
|
+
message,
|
|
3967
|
+
default: def = "",
|
|
3968
|
+
password,
|
|
3969
|
+
min
|
|
3970
|
+
}) => {
|
|
3971
|
+
let showDefault = true;
|
|
3972
|
+
let x = 0;
|
|
3973
|
+
const renderValue = (ctx) => password ? "*".repeat(ctx.value.length) : ctx.value;
|
|
3974
|
+
return prompt({
|
|
3975
|
+
value: def,
|
|
3976
|
+
cursor: true,
|
|
3977
|
+
validate: (ctx) => !min || ctx.value.length >= min,
|
|
3978
|
+
render(ctx) {
|
|
3979
|
+
let text = `${internal.colors.bright(message)}
|
|
3980
|
+
> ${ctx.submitted ? renderValue(ctx) : showDefault ? internal.colors.pale(def) + "\b".repeat(def.length) : ctx.value}`;
|
|
3981
|
+
if (ctx.submitted) text += "\n";
|
|
3982
|
+
return text;
|
|
3983
|
+
},
|
|
3984
|
+
onKeyPress(ctx, s) {
|
|
3985
|
+
let value = showDefault ? "" : ctx.value;
|
|
3986
|
+
if (s === "\x1B[D" && x > 0) {
|
|
3987
|
+
x--;
|
|
3988
|
+
stdout.write("\b");
|
|
3989
|
+
} else if (s === "\x1B[C" && x < value.length) {
|
|
3990
|
+
stdout.write(value[x]);
|
|
3991
|
+
x++;
|
|
3992
|
+
}
|
|
3993
|
+
if (s !== "\x7F" && s !== "\x1B[3~" && !visibleChars(s)) return;
|
|
3994
|
+
if (showDefault) {
|
|
3995
|
+
showDefault = false;
|
|
3996
|
+
stdout.write(" ".repeat(def.length) + "\b".repeat(def.length));
|
|
3997
|
+
}
|
|
3998
|
+
const prev = value;
|
|
3999
|
+
const prevX = x;
|
|
4000
|
+
if (s === "\x7F") {
|
|
4001
|
+
if (x > 0) {
|
|
4002
|
+
value = value.slice(0, x - 1) + value.slice(x);
|
|
4003
|
+
x--;
|
|
4004
|
+
}
|
|
4005
|
+
} else if (s === "\x1B[3~") {
|
|
4006
|
+
if (x < value.length) {
|
|
4007
|
+
value = value.slice(0, x) + value.slice(x + 1);
|
|
4008
|
+
}
|
|
4009
|
+
} else {
|
|
4010
|
+
value = value.slice(0, x) + s + value.slice(x);
|
|
4011
|
+
x++;
|
|
4012
|
+
}
|
|
4013
|
+
ctx.value = value;
|
|
4014
|
+
const spaces = prev.length - value.length;
|
|
4015
|
+
stdout.write(
|
|
4016
|
+
"\b".repeat(prevX) + renderValue(ctx) + (spaces > 0 ? " ".repeat(spaces) + "\b".repeat(spaces) : "") + "\b".repeat(value.length - x)
|
|
4017
|
+
);
|
|
4018
|
+
}
|
|
4019
|
+
});
|
|
4020
|
+
};
|
|
4021
|
+
|
|
4022
|
+
const runRecurrentMigrations = async (adapters, config) => {
|
|
4023
|
+
let dbs;
|
|
4024
|
+
let files = 0;
|
|
4025
|
+
await readdirRecursive(config.recurrentPath, async (path) => {
|
|
4026
|
+
files++;
|
|
4027
|
+
dbs ?? (dbs = adapters.map((adapter) => internal.createDbWithAdapter({ adapter })));
|
|
4028
|
+
const sql = await fs.readFile(path, "utf-8");
|
|
4029
|
+
await Promise.all(
|
|
4030
|
+
dbs.map(async (db) => {
|
|
4031
|
+
await db.adapter.arrays(sql);
|
|
4032
|
+
})
|
|
4033
|
+
);
|
|
4034
|
+
});
|
|
4035
|
+
if (files > 0) {
|
|
4036
|
+
config.logger?.log(
|
|
4037
|
+
`Applied ${files} recurrent migration file${files > 1 ? "s" : ""}`
|
|
4038
|
+
);
|
|
4039
|
+
}
|
|
4040
|
+
};
|
|
4041
|
+
const readdirRecursive = async (dirPath, cb) => {
|
|
4042
|
+
const list = await fs.readdir(dirPath).catch((err) => {
|
|
4043
|
+
if (err.code !== "ENOENT") throw err;
|
|
4044
|
+
return;
|
|
4045
|
+
});
|
|
4046
|
+
if (!list) return;
|
|
4047
|
+
await Promise.all(
|
|
4048
|
+
list.map(async (item) => {
|
|
4049
|
+
const path$1 = path.join(dirPath, item);
|
|
4050
|
+
const info = await fs.stat(path$1);
|
|
4051
|
+
if (info.isDirectory()) {
|
|
4052
|
+
await readdirRecursive(path$1, cb);
|
|
4053
|
+
} else if (info.isFile() && path$1.endsWith(".sql")) {
|
|
4054
|
+
await cb(path$1);
|
|
4055
|
+
}
|
|
4056
|
+
})
|
|
4057
|
+
);
|
|
4058
|
+
};
|
|
4059
|
+
|
|
4060
|
+
const createDatabaseCommand = (adapters, config, dontClose) => createOrDropDatabase("create", adapters, config, dontClose);
|
|
4061
|
+
const dropDatabaseCommand = (adapters, config) => createOrDropDatabase("drop", adapters, config);
|
|
4062
|
+
const createOrDropDatabase = async (action, adapters, config, dontClose) => {
|
|
4063
|
+
const fn = action === "create" ? createDatabase : dropDatabase;
|
|
4064
|
+
for (const adapter of adapters) {
|
|
4065
|
+
const database = adapter.getDatabase();
|
|
4066
|
+
const owner = adapter.getUser();
|
|
4067
|
+
const res = await run(
|
|
4068
|
+
adapter.reconfigure({ database: "postgres" }),
|
|
4069
|
+
config,
|
|
4070
|
+
{
|
|
4071
|
+
command: (adapter2) => fn(adapter2, {
|
|
4072
|
+
database,
|
|
4073
|
+
owner
|
|
4074
|
+
}),
|
|
4075
|
+
doneMessage: () => `Database ${database} successfully ${action === "create" ? "created" : "dropped"}`,
|
|
4076
|
+
alreadyMessage: () => `Database ${database} ${action === "create" ? "already exists" : "does not exist"}`,
|
|
4077
|
+
deniedMessage: () => `Permission denied to ${action} database.`,
|
|
4078
|
+
askAdminCreds: () => askForAdminCredentials(action === "create")
|
|
4079
|
+
}
|
|
4080
|
+
);
|
|
4081
|
+
if (!res) continue;
|
|
4082
|
+
if (action === "create") {
|
|
4083
|
+
await adapter.transaction(async (tx) => {
|
|
4084
|
+
const schema = tx.getSchema();
|
|
4085
|
+
if (schema) {
|
|
4086
|
+
const quoted = `"${typeof schema === "function" ? schema() : schema}"`;
|
|
4087
|
+
const res2 = await createSchema(tx, quoted);
|
|
4088
|
+
if (res2 === "done") {
|
|
4089
|
+
config.logger?.log(`Created schema ${quoted}`);
|
|
4090
|
+
}
|
|
4091
|
+
}
|
|
4092
|
+
await createMigrationsSchemaAndTable(tx, config);
|
|
4093
|
+
});
|
|
4094
|
+
if (!dontClose) {
|
|
4095
|
+
await adapter.close();
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4099
|
+
};
|
|
4100
|
+
const resetDatabaseCommand = async (adapters, config) => {
|
|
4101
|
+
await createOrDropDatabase("drop", adapters, config);
|
|
4102
|
+
await createOrDropDatabase("create", adapters, config, true);
|
|
4103
|
+
for (const adapter of adapters) {
|
|
4104
|
+
await migrate(adapter, config);
|
|
4105
|
+
}
|
|
4106
|
+
if (config.recurrentPath) {
|
|
4107
|
+
await runRecurrentMigrations(adapters, config);
|
|
4108
|
+
}
|
|
4109
|
+
await Promise.all(adapters.map((adapter) => adapter.close()));
|
|
4110
|
+
};
|
|
4111
|
+
const run = async (adapter, config, params) => {
|
|
4112
|
+
try {
|
|
4113
|
+
const res = await params.command(adapter);
|
|
4114
|
+
config.logger?.log(
|
|
4115
|
+
res === "done" ? params.doneMessage() : params.alreadyMessage()
|
|
4116
|
+
);
|
|
4117
|
+
await adapter.close();
|
|
4118
|
+
return true;
|
|
4119
|
+
} catch (err) {
|
|
4120
|
+
if (err instanceof CreateOrDropError) {
|
|
4121
|
+
if (err.status === "ssl-required") {
|
|
4122
|
+
config.logger?.log(
|
|
4123
|
+
"SSL is required: append ?ssl=true to the database url string"
|
|
4124
|
+
);
|
|
4125
|
+
return false;
|
|
4126
|
+
}
|
|
4127
|
+
if (err.status === "forbidden" || err.status === "auth-failed") {
|
|
4128
|
+
let message = params.deniedMessage();
|
|
4129
|
+
const host = adapter.getHost();
|
|
4130
|
+
const isLocal = host === "localhost";
|
|
4131
|
+
if (!isLocal) {
|
|
4132
|
+
message += `
|
|
4133
|
+
Don't use this command for database service providers, only for a local db.`;
|
|
4134
|
+
}
|
|
4135
|
+
config.logger?.log(message);
|
|
4136
|
+
const creds = await params.askAdminCreds();
|
|
4137
|
+
if (!creds) return false;
|
|
4138
|
+
return run(adapter.reconfigure(creds), config, params);
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
throw err;
|
|
4050
4142
|
}
|
|
4051
4143
|
};
|
|
4052
4144
|
const askForAdminCredentials = async (create) => {
|
|
@@ -4152,7 +4244,7 @@ const astToGenerateItem = (config, ast, currentSchema) => {
|
|
|
4152
4244
|
deps.push(table);
|
|
4153
4245
|
const columns = [];
|
|
4154
4246
|
for (const name in ast.shape) {
|
|
4155
|
-
const arr =
|
|
4247
|
+
const arr = internal.toArray(ast.shape[name]);
|
|
4156
4248
|
for (const item of arr) {
|
|
4157
4249
|
if (item.type === "add") {
|
|
4158
4250
|
columns.push([add, name, { column: item.item }]);
|
|
@@ -4268,7 +4360,7 @@ const astToGenerateItem = (config, ast, currentSchema) => {
|
|
|
4268
4360
|
break;
|
|
4269
4361
|
}
|
|
4270
4362
|
default:
|
|
4271
|
-
|
|
4363
|
+
internal.exhaustive(ast);
|
|
4272
4364
|
}
|
|
4273
4365
|
return {
|
|
4274
4366
|
ast,
|
|
@@ -4478,7 +4570,7 @@ const astToMigration = (currentSchema, config, asts) => {
|
|
|
4478
4570
|
code += `
|
|
4479
4571
|
change(async (db) => {
|
|
4480
4572
|
${group.map(
|
|
4481
|
-
(ast) =>
|
|
4573
|
+
(ast) => internal.codeToString(
|
|
4482
4574
|
astEncoders[ast.type](ast, config, currentSchema),
|
|
4483
4575
|
" ",
|
|
4484
4576
|
" "
|
|
@@ -4499,7 +4591,7 @@ const astEncoders = {
|
|
|
4499
4591
|
);
|
|
4500
4592
|
const isShifted = hasOptions || hasTableData;
|
|
4501
4593
|
if (isShifted) {
|
|
4502
|
-
|
|
4594
|
+
internal.addCode(code, `await db.${ast.action}Table(`);
|
|
4503
4595
|
const inner = [`${quoteSchemaTable(ast, currentSchema)},`];
|
|
4504
4596
|
code.push(inner);
|
|
4505
4597
|
code = inner;
|
|
@@ -4512,7 +4604,7 @@ const astEncoders = {
|
|
|
4512
4604
|
}
|
|
4513
4605
|
code.push("(t) => ({");
|
|
4514
4606
|
} else {
|
|
4515
|
-
|
|
4607
|
+
internal.addCode(
|
|
4516
4608
|
code,
|
|
4517
4609
|
`await db.${ast.action}Table(${quoteSchemaTable(
|
|
4518
4610
|
ast,
|
|
@@ -4534,23 +4626,23 @@ const astEncoders = {
|
|
|
4534
4626
|
for (const key in ast.shape) {
|
|
4535
4627
|
if (timestamps.hasAnyTimestamps && (key === "createdAt" || key === "updatedAt"))
|
|
4536
4628
|
continue;
|
|
4537
|
-
const line = [`${
|
|
4629
|
+
const line = [`${internal.quoteObjectKey(key, config.snakeCase)}: `];
|
|
4538
4630
|
const columnCode = ast.shape[key].toCode(toCodeCtx, key);
|
|
4539
4631
|
for (const part of columnCode) {
|
|
4540
|
-
|
|
4632
|
+
internal.addCode(line, part);
|
|
4541
4633
|
}
|
|
4542
|
-
|
|
4634
|
+
internal.addCode(line, ",");
|
|
4543
4635
|
code.push(line);
|
|
4544
4636
|
}
|
|
4545
4637
|
if (timestamps.hasAnyTimestamps) {
|
|
4546
4638
|
code.push([`...${timestampsToCode(timestamps)},`]);
|
|
4547
4639
|
}
|
|
4548
4640
|
if (isShifted) {
|
|
4549
|
-
|
|
4550
|
-
if (hasTableData)
|
|
4551
|
-
|
|
4641
|
+
internal.addCode(code, "}),");
|
|
4642
|
+
if (hasTableData) internal.pushTableDataCode(code, ast);
|
|
4643
|
+
internal.addCode(result, ");");
|
|
4552
4644
|
} else {
|
|
4553
|
-
|
|
4645
|
+
internal.addCode(result, "}));");
|
|
4554
4646
|
}
|
|
4555
4647
|
return result;
|
|
4556
4648
|
},
|
|
@@ -4563,7 +4655,7 @@ const astEncoders = {
|
|
|
4563
4655
|
});
|
|
4564
4656
|
const { comment } = ast;
|
|
4565
4657
|
if (comment !== void 0) {
|
|
4566
|
-
|
|
4658
|
+
internal.addCode(code, `await db.changeTable(`);
|
|
4567
4659
|
const inner = [
|
|
4568
4660
|
`${schemaTable},`,
|
|
4569
4661
|
`{ comment: ${JSON.stringify(ast.comment)} },`,
|
|
@@ -4572,7 +4664,7 @@ const astEncoders = {
|
|
|
4572
4664
|
code.push(inner);
|
|
4573
4665
|
code = inner;
|
|
4574
4666
|
} else {
|
|
4575
|
-
|
|
4667
|
+
internal.addCode(code, `await db.changeTable(${schemaTable}, (t) => ({`);
|
|
4576
4668
|
}
|
|
4577
4669
|
const [addTimestamps, dropTimestamps] = ["add", "drop"].map(
|
|
4578
4670
|
(type) => getHasTimestamps(
|
|
@@ -4588,29 +4680,29 @@ const astEncoders = {
|
|
|
4588
4680
|
snakeCase: config.snakeCase
|
|
4589
4681
|
};
|
|
4590
4682
|
for (const key in ast.shape) {
|
|
4591
|
-
const changes =
|
|
4683
|
+
const changes = internal.toArray(ast.shape[key]);
|
|
4592
4684
|
for (const change of changes) {
|
|
4593
4685
|
if (change.type === "add" || change.type === "drop") {
|
|
4594
4686
|
if ((addTimestamps.hasAnyTimestamps || dropTimestamps.hasAnyTimestamps) && (key === "createdAt" || key === "updatedAt"))
|
|
4595
4687
|
continue;
|
|
4596
4688
|
const recreate = changes.length > 1;
|
|
4597
4689
|
const line = [
|
|
4598
|
-
recreate ? `...t.${change.type}(t.name(${
|
|
4690
|
+
recreate ? `...t.${change.type}(t.name(${internal.singleQuote(
|
|
4599
4691
|
change.item.data.name ?? key
|
|
4600
|
-
)})` : `${
|
|
4692
|
+
)})` : `${internal.quoteObjectKey(key, config.snakeCase)}: t.${change.type}(`
|
|
4601
4693
|
];
|
|
4602
4694
|
const columnCode = change.item.toCode(toCodeCtx, key);
|
|
4603
4695
|
for (let i = 0; i < columnCode.length; i++) {
|
|
4604
4696
|
let part = columnCode[i];
|
|
4605
4697
|
if (recreate && !i) part = part.slice(1);
|
|
4606
|
-
|
|
4698
|
+
internal.addCode(line, part);
|
|
4607
4699
|
}
|
|
4608
|
-
|
|
4700
|
+
internal.addCode(line, "),");
|
|
4609
4701
|
code.push(line);
|
|
4610
4702
|
} else if (change.type === "change") {
|
|
4611
4703
|
if (!change.from.column || !change.to.column) continue;
|
|
4612
4704
|
const line = [
|
|
4613
|
-
`${
|
|
4705
|
+
`${internal.quoteObjectKey(key, config.snakeCase)}: t${change.name ? `.name(${internal.singleQuote(change.name)})` : ""}.change(`
|
|
4614
4706
|
];
|
|
4615
4707
|
const fromCode = change.from.column.toCode(
|
|
4616
4708
|
{
|
|
@@ -4623,76 +4715,76 @@ const astEncoders = {
|
|
|
4623
4715
|
key
|
|
4624
4716
|
);
|
|
4625
4717
|
for (const part of fromCode) {
|
|
4626
|
-
|
|
4718
|
+
internal.addCode(line, part);
|
|
4627
4719
|
}
|
|
4628
|
-
|
|
4720
|
+
internal.addCode(line, ", ");
|
|
4629
4721
|
const toCode = change.to.column.toCode(toCodeCtx, key);
|
|
4630
4722
|
for (const part of toCode) {
|
|
4631
|
-
|
|
4723
|
+
internal.addCode(line, part);
|
|
4632
4724
|
}
|
|
4633
4725
|
if (change.using) {
|
|
4634
|
-
|
|
4726
|
+
internal.addCode(line, ", {");
|
|
4635
4727
|
const u = [];
|
|
4636
4728
|
if (change.using.usingUp) {
|
|
4637
|
-
u.push(`usingUp: ${
|
|
4729
|
+
u.push(`usingUp: ${internal.rawSqlToCode(change.using.usingUp, "t")},`);
|
|
4638
4730
|
}
|
|
4639
4731
|
if (change.using.usingDown) {
|
|
4640
4732
|
u.push(
|
|
4641
|
-
`usingDown: ${
|
|
4733
|
+
`usingDown: ${internal.rawSqlToCode(change.using.usingDown, "t")},`
|
|
4642
4734
|
);
|
|
4643
4735
|
}
|
|
4644
|
-
|
|
4645
|
-
|
|
4736
|
+
internal.addCode(line, u);
|
|
4737
|
+
internal.addCode(line, "}");
|
|
4646
4738
|
}
|
|
4647
|
-
|
|
4739
|
+
internal.addCode(line, "),");
|
|
4648
4740
|
code.push(line);
|
|
4649
4741
|
} else if (change.type === "rename") {
|
|
4650
4742
|
code.push([
|
|
4651
|
-
`${
|
|
4743
|
+
`${internal.quoteObjectKey(key, config.snakeCase)}: t.rename(${internal.singleQuote(
|
|
4652
4744
|
change.name
|
|
4653
4745
|
)}),`
|
|
4654
4746
|
]);
|
|
4655
4747
|
} else {
|
|
4656
|
-
|
|
4748
|
+
internal.exhaustive(change.type);
|
|
4657
4749
|
}
|
|
4658
4750
|
}
|
|
4659
4751
|
}
|
|
4660
4752
|
for (const key of ["drop", "add"]) {
|
|
4661
4753
|
const timestamps = key === "add" ? addTimestamps : dropTimestamps;
|
|
4662
4754
|
if (timestamps.hasAnyTimestamps) {
|
|
4663
|
-
|
|
4755
|
+
internal.addCode(code, [`...t.${key}(${timestampsToCode(timestamps)}),`]);
|
|
4664
4756
|
}
|
|
4665
4757
|
const { primaryKey, indexes, excludes, constraints } = ast[key];
|
|
4666
4758
|
if (primaryKey) {
|
|
4667
|
-
|
|
4668
|
-
`...t.${key}(${
|
|
4759
|
+
internal.addCode(code, [
|
|
4760
|
+
`...t.${key}(${internal.primaryKeyInnerToCode(primaryKey, "t")}),`
|
|
4669
4761
|
]);
|
|
4670
4762
|
}
|
|
4671
4763
|
if (indexes) {
|
|
4672
4764
|
for (const item of indexes) {
|
|
4673
|
-
|
|
4765
|
+
internal.addCode(code, [`...t.${key}(`, internal.indexInnerToCode(item, "t"), "),"]);
|
|
4674
4766
|
}
|
|
4675
4767
|
}
|
|
4676
4768
|
if (excludes) {
|
|
4677
4769
|
for (const item of excludes) {
|
|
4678
|
-
|
|
4770
|
+
internal.addCode(code, [`...t.${key}(`, internal.excludeInnerToCode(item, "t"), "),"]);
|
|
4679
4771
|
}
|
|
4680
4772
|
}
|
|
4681
4773
|
if (constraints) {
|
|
4682
4774
|
for (const item of constraints) {
|
|
4683
|
-
|
|
4775
|
+
internal.addCode(code, [
|
|
4684
4776
|
`...t.${key}(`,
|
|
4685
|
-
|
|
4777
|
+
internal.constraintInnerToCode(item, "t", true),
|
|
4686
4778
|
"),"
|
|
4687
4779
|
]);
|
|
4688
4780
|
}
|
|
4689
4781
|
}
|
|
4690
4782
|
}
|
|
4691
4783
|
if (ast.comment !== void 0) {
|
|
4692
|
-
|
|
4693
|
-
|
|
4784
|
+
internal.addCode(code, "}),");
|
|
4785
|
+
internal.addCode(result, ");");
|
|
4694
4786
|
} else {
|
|
4695
|
-
|
|
4787
|
+
internal.addCode(result, "}));");
|
|
4696
4788
|
}
|
|
4697
4789
|
return result;
|
|
4698
4790
|
},
|
|
@@ -4700,14 +4792,14 @@ const astEncoders = {
|
|
|
4700
4792
|
const code = [];
|
|
4701
4793
|
const kind = ast.kind === "TABLE" ? "Table" : "Type";
|
|
4702
4794
|
if (ast.from === ast.to) {
|
|
4703
|
-
|
|
4795
|
+
internal.addCode(
|
|
4704
4796
|
code,
|
|
4705
|
-
`await db.change${kind}Schema(${
|
|
4797
|
+
`await db.change${kind}Schema(${internal.singleQuote(ast.to)}, ${internal.singleQuote(
|
|
4706
4798
|
ast.fromSchema ?? currentSchema
|
|
4707
|
-
)}, ${
|
|
4799
|
+
)}, ${internal.singleQuote(ast.toSchema ?? currentSchema)});`
|
|
4708
4800
|
);
|
|
4709
4801
|
} else {
|
|
4710
|
-
|
|
4802
|
+
internal.addCode(
|
|
4711
4803
|
code,
|
|
4712
4804
|
`await db.rename${kind}(${quoteSchemaTable({
|
|
4713
4805
|
schema: ast.fromSchema === currentSchema ? void 0 : ast.fromSchema,
|
|
@@ -4721,10 +4813,10 @@ const astEncoders = {
|
|
|
4721
4813
|
return code;
|
|
4722
4814
|
},
|
|
4723
4815
|
schema(ast) {
|
|
4724
|
-
return `await db.${ast.action === "create" ? "createSchema" : "dropSchema"}(${
|
|
4816
|
+
return `await db.${ast.action === "create" ? "createSchema" : "dropSchema"}(${internal.singleQuote(ast.name)});`;
|
|
4725
4817
|
},
|
|
4726
4818
|
renameSchema(ast) {
|
|
4727
|
-
return `await db.renameSchema(${
|
|
4819
|
+
return `await db.renameSchema(${internal.singleQuote(ast.from)}, ${internal.singleQuote(
|
|
4728
4820
|
ast.to
|
|
4729
4821
|
)});`;
|
|
4730
4822
|
},
|
|
@@ -4733,34 +4825,34 @@ const astEncoders = {
|
|
|
4733
4825
|
`await db.${ast.action}Extension(${quoteSchemaTable(ast, currentSchema)}`
|
|
4734
4826
|
];
|
|
4735
4827
|
if (ast.version) {
|
|
4736
|
-
|
|
4737
|
-
code.push([`version: ${
|
|
4828
|
+
internal.addCode(code, ", {");
|
|
4829
|
+
code.push([`version: ${internal.singleQuote(ast.version)},`], "}");
|
|
4738
4830
|
}
|
|
4739
|
-
|
|
4831
|
+
internal.addCode(code, ");");
|
|
4740
4832
|
return code;
|
|
4741
4833
|
},
|
|
4742
4834
|
enum(ast, _, currentSchema) {
|
|
4743
|
-
return `await db.${ast.action === "create" ? "createEnum" : "dropEnum"}(${quoteSchemaTable(ast, currentSchema)}, [${ast.values.map(
|
|
4835
|
+
return `await db.${ast.action === "create" ? "createEnum" : "dropEnum"}(${quoteSchemaTable(ast, currentSchema)}, [${ast.values.map(internal.singleQuote).join(", ")}]);`;
|
|
4744
4836
|
},
|
|
4745
4837
|
enumValues(ast, _, currentSchema) {
|
|
4746
4838
|
return `await db.${ast.action}EnumValues(${quoteSchemaTable(
|
|
4747
4839
|
ast,
|
|
4748
4840
|
currentSchema
|
|
4749
|
-
)}, [${ast.values.map(
|
|
4841
|
+
)}, [${ast.values.map(internal.singleQuote).join(", ")}]);`;
|
|
4750
4842
|
},
|
|
4751
4843
|
renameEnumValues(ast, config, currentSchema) {
|
|
4752
4844
|
return `await db.renameEnumValues(${quoteSchemaTable(
|
|
4753
4845
|
ast,
|
|
4754
4846
|
currentSchema
|
|
4755
4847
|
)}, { ${Object.entries(ast.values).map(
|
|
4756
|
-
([from, to]) => `${
|
|
4848
|
+
([from, to]) => `${internal.quoteObjectKey(from, config.snakeCase)}: ${internal.singleQuote(to)}`
|
|
4757
4849
|
).join(", ")} });`;
|
|
4758
4850
|
},
|
|
4759
4851
|
changeEnumValues(ast, _, currentSchema) {
|
|
4760
4852
|
return `await db.changeEnumValues(${quoteSchemaTable(
|
|
4761
4853
|
ast,
|
|
4762
4854
|
currentSchema
|
|
4763
|
-
)}, [${ast.fromValues.map(
|
|
4855
|
+
)}, [${ast.fromValues.map(internal.singleQuote).join(", ")}], [${ast.toValues.map(internal.singleQuote).join(", ")}]);`;
|
|
4764
4856
|
},
|
|
4765
4857
|
domain(ast, _, currentSchema) {
|
|
4766
4858
|
return `await db.${ast.action}Domain(${quoteSchemaTable(
|
|
@@ -4793,13 +4885,13 @@ const astEncoders = {
|
|
|
4793
4885
|
if (ast.references) {
|
|
4794
4886
|
return [
|
|
4795
4887
|
`await db.addForeignKey(`,
|
|
4796
|
-
[`${table},`, ...
|
|
4888
|
+
[`${table},`, ...internal.referencesArgsToCode(ast.references, ast.name, true)],
|
|
4797
4889
|
");"
|
|
4798
4890
|
];
|
|
4799
4891
|
}
|
|
4800
4892
|
const check = ast.check;
|
|
4801
4893
|
return [
|
|
4802
|
-
`await db.addCheck(${table}, ${
|
|
4894
|
+
`await db.addCheck(${table}, ${internal.rawSqlToCode(check, "t")}${ast.name ? `, ${internal.singleQuote(ast.name)}` : ""});`
|
|
4803
4895
|
];
|
|
4804
4896
|
},
|
|
4805
4897
|
renameTableItem(ast) {
|
|
@@ -4807,7 +4899,7 @@ const astEncoders = {
|
|
|
4807
4899
|
`await db.rename${ast.kind === "INDEX" ? "Index" : "Constraint"}(${quoteSchemaTable({
|
|
4808
4900
|
schema: ast.tableSchema,
|
|
4809
4901
|
name: ast.tableName
|
|
4810
|
-
})}, ${
|
|
4902
|
+
})}, ${internal.singleQuote(ast.from)}, ${internal.singleQuote(ast.to)});`
|
|
4811
4903
|
];
|
|
4812
4904
|
},
|
|
4813
4905
|
view(ast, _, currentSchema) {
|
|
@@ -4823,10 +4915,10 @@ const astEncoders = {
|
|
|
4823
4915
|
if (w?.securityInvoker)
|
|
4824
4916
|
options.push(`securityInvoker: ${w.securityInvoker},`);
|
|
4825
4917
|
if (options.length) {
|
|
4826
|
-
|
|
4918
|
+
internal.addCode(code, ", {");
|
|
4827
4919
|
code.push(options, "}");
|
|
4828
4920
|
}
|
|
4829
|
-
|
|
4921
|
+
internal.addCode(code, ", ");
|
|
4830
4922
|
if (!ast.sql._values) {
|
|
4831
4923
|
const raw = ast.sql._sql;
|
|
4832
4924
|
let sql;
|
|
@@ -4841,17 +4933,17 @@ const astEncoders = {
|
|
|
4841
4933
|
}
|
|
4842
4934
|
sql += parts[last];
|
|
4843
4935
|
}
|
|
4844
|
-
|
|
4936
|
+
internal.addCode(code, internal.backtickQuote(sql));
|
|
4845
4937
|
} else {
|
|
4846
|
-
|
|
4938
|
+
internal.addCode(code, internal.rawSqlToCode(ast.sql, "db"));
|
|
4847
4939
|
}
|
|
4848
|
-
|
|
4940
|
+
internal.addCode(code, ");");
|
|
4849
4941
|
return code;
|
|
4850
4942
|
},
|
|
4851
4943
|
role(ast) {
|
|
4852
4944
|
const params = roleParams(ast.name, ast);
|
|
4853
4945
|
const arr = [
|
|
4854
|
-
`await db.${ast.action}Role(${
|
|
4946
|
+
`await db.${ast.action}Role(${internal.singleQuote(ast.name)}${params.length ? ", {" : ");"}`
|
|
4855
4947
|
];
|
|
4856
4948
|
if (params.length) {
|
|
4857
4949
|
arr.push(params);
|
|
@@ -4860,7 +4952,7 @@ const astEncoders = {
|
|
|
4860
4952
|
return arr;
|
|
4861
4953
|
},
|
|
4862
4954
|
renameRole(ast) {
|
|
4863
|
-
return `await db.renameRole(${
|
|
4955
|
+
return `await db.renameRole(${internal.singleQuote(ast.from)}, ${internal.singleQuote(
|
|
4864
4956
|
ast.to
|
|
4865
4957
|
)});`;
|
|
4866
4958
|
},
|
|
@@ -4868,7 +4960,7 @@ const astEncoders = {
|
|
|
4868
4960
|
const from = roleParams(ast.name, ast.from, ast.to);
|
|
4869
4961
|
const to = roleParams(ast.name, ast.to, ast.from, true);
|
|
4870
4962
|
return [
|
|
4871
|
-
`await db.changeRole(${
|
|
4963
|
+
`await db.changeRole(${internal.singleQuote(ast.name)}, {`,
|
|
4872
4964
|
[...from.length ? ["from: {", from, "},"] : [], "to: {", to, "},"],
|
|
4873
4965
|
"});"
|
|
4874
4966
|
];
|
|
@@ -4877,11 +4969,11 @@ const astEncoders = {
|
|
|
4877
4969
|
const code = [`await db.changeDefaultPrivileges({`];
|
|
4878
4970
|
const props = [];
|
|
4879
4971
|
if (ast.owner) {
|
|
4880
|
-
props.push(`owner: ${
|
|
4972
|
+
props.push(`owner: ${internal.singleQuote(ast.owner)},`);
|
|
4881
4973
|
}
|
|
4882
|
-
props.push(`grantee: ${
|
|
4974
|
+
props.push(`grantee: ${internal.singleQuote(ast.grantee)},`);
|
|
4883
4975
|
if (ast.schema) {
|
|
4884
|
-
props.push(`schema: ${
|
|
4976
|
+
props.push(`schema: ${internal.singleQuote(ast.schema)},`);
|
|
4885
4977
|
}
|
|
4886
4978
|
const objectConfigToCode = (config) => {
|
|
4887
4979
|
const result = [];
|
|
@@ -4903,12 +4995,12 @@ const astEncoders = {
|
|
|
4903
4995
|
const lines = [];
|
|
4904
4996
|
if (hasPrivileges) {
|
|
4905
4997
|
lines.push(
|
|
4906
|
-
`privileges: [${privileges.map(
|
|
4998
|
+
`privileges: [${privileges.map(internal.singleQuote).join(", ")}],`
|
|
4907
4999
|
);
|
|
4908
5000
|
}
|
|
4909
5001
|
if (hasGrantable) {
|
|
4910
5002
|
lines.push(
|
|
4911
|
-
`grantablePrivileges: [${grantablePrivileges.map(
|
|
5003
|
+
`grantablePrivileges: [${grantablePrivileges.map(internal.singleQuote).join(", ")}],`
|
|
4912
5004
|
);
|
|
4913
5005
|
}
|
|
4914
5006
|
result.push(lines);
|
|
@@ -4933,7 +5025,7 @@ const astEncoders = {
|
|
|
4933
5025
|
}
|
|
4934
5026
|
}
|
|
4935
5027
|
code.push(props);
|
|
4936
|
-
|
|
5028
|
+
internal.addCode(code, "});");
|
|
4937
5029
|
return code;
|
|
4938
5030
|
}
|
|
4939
5031
|
};
|
|
@@ -4957,7 +5049,7 @@ const roleParams = (name, ast, compare, to) => {
|
|
|
4957
5049
|
if (!compare && (!value || key === "connLimit" && value === -1)) {
|
|
4958
5050
|
continue;
|
|
4959
5051
|
}
|
|
4960
|
-
value = value instanceof Date ? `'${value.toISOString()}'` : key === "config" ? JSON.stringify(value) : typeof value === "string" ?
|
|
5052
|
+
value = value instanceof Date ? `'${value.toISOString()}'` : key === "config" ? JSON.stringify(value) : typeof value === "string" ? internal.singleQuote(value) : value;
|
|
4961
5053
|
if (compare) {
|
|
4962
5054
|
const a = value === -1 || value === false ? void 0 : value;
|
|
4963
5055
|
const other = compare[key];
|
|
@@ -4974,15 +5066,15 @@ const isTimestamp = (column, type) => {
|
|
|
4974
5066
|
if (!column) return false;
|
|
4975
5067
|
const { default: def } = column.data;
|
|
4976
5068
|
return Boolean(
|
|
4977
|
-
column instanceof type && !column.data.isNullable && def && typeof def === "object" &&
|
|
5069
|
+
column instanceof type && !column.data.isNullable && def && typeof def === "object" && internal.isRawSQL(def) && (typeof def._sql === "object" ? def._sql[0][0] : def._sql) === "now()"
|
|
4978
5070
|
);
|
|
4979
5071
|
};
|
|
4980
5072
|
const getHasTimestamps = (createdAt, updatedAt) => {
|
|
4981
|
-
const timestamps = getTimestampsInfo(createdAt, updatedAt,
|
|
5073
|
+
const timestamps = getTimestampsInfo(createdAt, updatedAt, internal.TimestampTZColumn);
|
|
4982
5074
|
const timestampsNoTZ = getTimestampsInfo(
|
|
4983
5075
|
createdAt,
|
|
4984
5076
|
updatedAt,
|
|
4985
|
-
|
|
5077
|
+
internal.TimestampColumn
|
|
4986
5078
|
);
|
|
4987
5079
|
return {
|
|
4988
5080
|
hasTZTimestamps: timestamps,
|
|
@@ -5594,7 +5686,7 @@ const makeStructureToAstCtx = (config, currentSchema) => ({
|
|
|
5594
5686
|
unsupportedTypes: {},
|
|
5595
5687
|
currentSchema,
|
|
5596
5688
|
columnSchemaConfig: config.schemaConfig,
|
|
5597
|
-
columnsByType:
|
|
5689
|
+
columnsByType: internal.makeColumnsByType(config.schemaConfig)
|
|
5598
5690
|
});
|
|
5599
5691
|
const structureToAst = async (ctx, adapter, config) => {
|
|
5600
5692
|
const ast = [];
|
|
@@ -5693,7 +5785,7 @@ const makeDomainsMap = (ctx, data) => {
|
|
|
5693
5785
|
});
|
|
5694
5786
|
if (it.checks) {
|
|
5695
5787
|
column.data.checks = it.checks.map((check) => ({
|
|
5696
|
-
sql: new
|
|
5788
|
+
sql: new internal.RawSql([[check]])
|
|
5697
5789
|
}));
|
|
5698
5790
|
}
|
|
5699
5791
|
domains[`${it.schemaName}.${it.name}`] = column;
|
|
@@ -5704,7 +5796,7 @@ const getDbColumnIsSerial = (item) => {
|
|
|
5704
5796
|
if (item.type === "int2" || item.type === "int4" || item.type === "int8") {
|
|
5705
5797
|
const { default: def, schemaName, tableName, name } = item;
|
|
5706
5798
|
const seq = `${tableName}_${name}_seq`;
|
|
5707
|
-
if (def && (def === `nextval(${
|
|
5799
|
+
if (def && (def === `nextval(${internal.singleQuote(`${seq}`)}::regclass)` || def === `nextval(${internal.singleQuote(`"${seq}"`)}::regclass)` || def === `nextval(${internal.singleQuote(`${schemaName}.${seq}`)}::regclass)` || def === `nextval(${internal.singleQuote(`"${schemaName}".${seq}`)}::regclass)` || def === `nextval(${internal.singleQuote(`${schemaName}."${seq}"`)}::regclass)` || def === `nextval(${internal.singleQuote(`"${schemaName}"."${seq}"`)}::regclass)`)) {
|
|
5708
5800
|
return true;
|
|
5709
5801
|
}
|
|
5710
5802
|
}
|
|
@@ -5725,7 +5817,7 @@ const instantiateDbColumn = (ctx, data, domains, dbColumn) => {
|
|
|
5725
5817
|
const typeId = typeSchema === "pg_catalog" ? typeName : `${typeSchema}.${typeName}`;
|
|
5726
5818
|
const domainColumn = domains[typeId];
|
|
5727
5819
|
if (domainColumn) {
|
|
5728
|
-
column = new
|
|
5820
|
+
column = new internal.DomainColumn(
|
|
5729
5821
|
ctx.columnSchemaConfig,
|
|
5730
5822
|
typeName,
|
|
5731
5823
|
typeSchema,
|
|
@@ -5736,14 +5828,14 @@ const instantiateDbColumn = (ctx, data, domains, dbColumn) => {
|
|
|
5736
5828
|
(x) => x.name === typeName && x.schemaName === typeSchema
|
|
5737
5829
|
);
|
|
5738
5830
|
if (enumType) {
|
|
5739
|
-
column = new
|
|
5831
|
+
column = new internal.EnumColumn(
|
|
5740
5832
|
ctx.columnSchemaConfig,
|
|
5741
5833
|
typeSchema === ctx.currentSchema ? typeName : typeId,
|
|
5742
5834
|
enumType.values,
|
|
5743
5835
|
ctx.columnSchemaConfig.type
|
|
5744
5836
|
);
|
|
5745
5837
|
} else {
|
|
5746
|
-
column = new
|
|
5838
|
+
column = new internal.CustomTypeColumn(
|
|
5747
5839
|
ctx.columnSchemaConfig,
|
|
5748
5840
|
typeName,
|
|
5749
5841
|
typeSchema === "pg_catalog" ? void 0 : typeSchema,
|
|
@@ -5753,13 +5845,13 @@ const instantiateDbColumn = (ctx, data, domains, dbColumn) => {
|
|
|
5753
5845
|
`${dbColumn.schemaName}${dbColumn.tableName ? `.${dbColumn.tableName}` : ""}.${dbColumn.name}`
|
|
5754
5846
|
);
|
|
5755
5847
|
}
|
|
5756
|
-
|
|
5848
|
+
internal.assignDbDataToColumn(column, dbColumn);
|
|
5757
5849
|
}
|
|
5758
5850
|
}
|
|
5759
5851
|
column.data.name = void 0;
|
|
5760
5852
|
if (!column.data.isNullable) column.data.isNullable = void 0;
|
|
5761
5853
|
if (dbColumn.arrayDims) {
|
|
5762
|
-
const arr = new
|
|
5854
|
+
const arr = new internal.ArrayColumn(
|
|
5763
5855
|
ctx.columnSchemaConfig,
|
|
5764
5856
|
column,
|
|
5765
5857
|
ctx.columnSchemaConfig.type
|
|
@@ -5772,10 +5864,10 @@ const instantiateDbColumn = (ctx, data, domains, dbColumn) => {
|
|
|
5772
5864
|
};
|
|
5773
5865
|
const instantiateColumnByDbType = (ctx, type, isSerial, params) => {
|
|
5774
5866
|
let columnFn = ctx.columnsByType[!isSerial ? type : type === "int2" ? "smallserial" : type === "int4" ? "serial" : "bigserial"];
|
|
5775
|
-
if (!columnFn && params.extension === "postgis" && type === "geography" &&
|
|
5867
|
+
if (!columnFn && params.extension === "postgis" && type === "geography" && internal.PostgisGeographyPointColumn.isDefaultPoint(params.typmod)) {
|
|
5776
5868
|
columnFn = ctx.columnsByType.geographyDefaultPoint;
|
|
5777
5869
|
}
|
|
5778
|
-
return columnFn ?
|
|
5870
|
+
return columnFn ? internal.assignDbDataToColumn(columnFn(), params) : void 0;
|
|
5779
5871
|
};
|
|
5780
5872
|
const tableToAst = (ctx, data, table, action, domains) => {
|
|
5781
5873
|
const { schemaName, name: tableName } = table;
|
|
@@ -5789,7 +5881,7 @@ const tableToAst = (ctx, data, table, action, domains) => {
|
|
|
5789
5881
|
name: tableName,
|
|
5790
5882
|
shape: makeDbStructureColumnsShape(ctx, data, domains, table, tableData),
|
|
5791
5883
|
noPrimaryKey: tableData.primaryKey ? "error" : "ignore",
|
|
5792
|
-
primaryKey: primaryKey && primaryKey.columns.length > 1 ? { ...primaryKey, columns: primaryKey.columns.map(
|
|
5884
|
+
primaryKey: primaryKey && primaryKey.columns.length > 1 ? { ...primaryKey, columns: primaryKey.columns.map(internal.toCamelCase) } : void 0,
|
|
5793
5885
|
indexes: indexesOrExcludesToAst(
|
|
5794
5886
|
tableName,
|
|
5795
5887
|
tableData,
|
|
@@ -5815,14 +5907,14 @@ const indexesOrExcludesToAst = (tableName, tableData, key) => {
|
|
|
5815
5907
|
acc.push({
|
|
5816
5908
|
columns: item.columns.map((it, i) => ({
|
|
5817
5909
|
with: "exclude" in item && item.exclude ? item.exclude[i] : void 0,
|
|
5818
|
-
..."expression" in it ? { expression: it.expression } : { column:
|
|
5910
|
+
..."expression" in it ? { expression: it.expression } : { column: internal.toCamelCase(it.column) },
|
|
5819
5911
|
collate: it.collate,
|
|
5820
5912
|
opclass: it.opclass,
|
|
5821
5913
|
order: it.order
|
|
5822
5914
|
})),
|
|
5823
5915
|
options: {
|
|
5824
5916
|
...options,
|
|
5825
|
-
include: item.include?.map(
|
|
5917
|
+
include: item.include?.map(internal.toCamelCase)
|
|
5826
5918
|
}
|
|
5827
5919
|
});
|
|
5828
5920
|
}
|
|
@@ -5864,7 +5956,7 @@ const constraintToAst = (ctx, item) => {
|
|
|
5864
5956
|
if (onDelete) options.onDelete = onDelete;
|
|
5865
5957
|
}
|
|
5866
5958
|
if (check) {
|
|
5867
|
-
result.check =
|
|
5959
|
+
result.check = internal.raw({ raw: check.expression });
|
|
5868
5960
|
}
|
|
5869
5961
|
if (item.name && item.name !== getConstraintName(item.tableName, result, ctx.snakeCase)) {
|
|
5870
5962
|
result.name = item.name;
|
|
@@ -5889,7 +5981,7 @@ const viewToAst = (ctx, data, domains, view) => {
|
|
|
5889
5981
|
options.with = withOptions;
|
|
5890
5982
|
for (const pair of view.with) {
|
|
5891
5983
|
const [key, value] = pair.split("=");
|
|
5892
|
-
withOptions[
|
|
5984
|
+
withOptions[internal.toCamelCase(key)] = value === "true" ? true : value === "false" ? false : value;
|
|
5893
5985
|
}
|
|
5894
5986
|
}
|
|
5895
5987
|
return {
|
|
@@ -5898,7 +5990,7 @@ const viewToAst = (ctx, data, domains, view) => {
|
|
|
5898
5990
|
schema: view.schemaName === ctx.currentSchema ? void 0 : view.schemaName,
|
|
5899
5991
|
name: view.name,
|
|
5900
5992
|
shape,
|
|
5901
|
-
sql:
|
|
5993
|
+
sql: internal.raw({ raw: view.sql }),
|
|
5902
5994
|
options,
|
|
5903
5995
|
deps: view.deps
|
|
5904
5996
|
};
|
|
@@ -5962,12 +6054,12 @@ const dbColumnToAst = (ctx, data, domains, tableName, item, table, tableData, ch
|
|
|
5962
6054
|
const columnChecks = checks?.[item.name];
|
|
5963
6055
|
if (columnChecks) {
|
|
5964
6056
|
column.data.checks = columnChecks.map((check) => ({
|
|
5965
|
-
sql: new
|
|
6057
|
+
sql: new internal.RawSql([[check]])
|
|
5966
6058
|
}));
|
|
5967
6059
|
}
|
|
5968
|
-
const camelCaseName =
|
|
6060
|
+
const camelCaseName = internal.toCamelCase(item.name);
|
|
5969
6061
|
if (ctx.snakeCase) {
|
|
5970
|
-
const snakeCaseName =
|
|
6062
|
+
const snakeCaseName = internal.toSnakeCase(camelCaseName);
|
|
5971
6063
|
if (snakeCaseName !== item.name) column.data.name = item.name;
|
|
5972
6064
|
} else if (camelCaseName !== item.name) {
|
|
5973
6065
|
column.data.name = item.name;
|
|
@@ -6013,7 +6105,7 @@ const dbConstraintToTableConstraint = (ctx, table, item) => {
|
|
|
6013
6105
|
onDelete: fkeyActionMap[references.onDelete]
|
|
6014
6106
|
}
|
|
6015
6107
|
} : void 0,
|
|
6016
|
-
check: check ?
|
|
6108
|
+
check: check ? internal.raw({ raw: check.expression }) : void 0
|
|
6017
6109
|
};
|
|
6018
6110
|
const name = item.name && item.name !== getConstraintName(table.name, constraint, ctx.snakeCase) ? item.name : void 0;
|
|
6019
6111
|
if (name) {
|
|
@@ -6085,118 +6177,6 @@ Append \`as\` method manually to ${count > 1 ? "these" : "this"} column${count >
|
|
|
6085
6177
|
config.logger?.log("Database pulled successfully");
|
|
6086
6178
|
};
|
|
6087
6179
|
|
|
6088
|
-
const migrationConfigDefaults = {
|
|
6089
|
-
schemaConfig: pqb.defaultSchemaConfig,
|
|
6090
|
-
migrationsPath: path.join("src", "db", "migrations"),
|
|
6091
|
-
migrationId: { serial: 4 },
|
|
6092
|
-
migrationsTable: "schemaMigrations",
|
|
6093
|
-
snakeCase: false,
|
|
6094
|
-
commands: {},
|
|
6095
|
-
log: true,
|
|
6096
|
-
logger: console,
|
|
6097
|
-
import() {
|
|
6098
|
-
throw new Error(
|
|
6099
|
-
"Add `import: (path) => import(path),` setting to `rakeDb` config"
|
|
6100
|
-
);
|
|
6101
|
-
}
|
|
6102
|
-
};
|
|
6103
|
-
const ensureMigrationsPath = (config) => {
|
|
6104
|
-
if (!config.migrationsPath) {
|
|
6105
|
-
config.migrationsPath = migrationConfigDefaults.migrationsPath;
|
|
6106
|
-
}
|
|
6107
|
-
if (!path.isAbsolute(config.migrationsPath)) {
|
|
6108
|
-
config.migrationsPath = path.resolve(
|
|
6109
|
-
config.basePath,
|
|
6110
|
-
config.migrationsPath
|
|
6111
|
-
);
|
|
6112
|
-
}
|
|
6113
|
-
return config;
|
|
6114
|
-
};
|
|
6115
|
-
const ensureBasePathAndDbScript = (config, intermediateCallers2 = 0) => {
|
|
6116
|
-
if (config.basePath && config.dbScript) return config;
|
|
6117
|
-
let filePath = pqb.getStackTrace()?.[3 + intermediateCallers2]?.getFileName();
|
|
6118
|
-
if (!filePath) {
|
|
6119
|
-
throw new Error(
|
|
6120
|
-
"Failed to determine path to db script. Please set basePath option of rakeDb"
|
|
6121
|
-
);
|
|
6122
|
-
}
|
|
6123
|
-
if (filePath.startsWith("file://")) {
|
|
6124
|
-
filePath = node_url.fileURLToPath(filePath);
|
|
6125
|
-
}
|
|
6126
|
-
const ext = path.extname(filePath);
|
|
6127
|
-
if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
|
|
6128
|
-
throw new Error(
|
|
6129
|
-
`Add a .ts suffix to the "${path.basename(filePath)}" when calling it`
|
|
6130
|
-
);
|
|
6131
|
-
}
|
|
6132
|
-
config.basePath = path.dirname(filePath);
|
|
6133
|
-
config.dbScript = path.basename(filePath);
|
|
6134
|
-
return config;
|
|
6135
|
-
};
|
|
6136
|
-
let intermediateCallers = 0;
|
|
6137
|
-
const incrementIntermediateCaller = () => {
|
|
6138
|
-
intermediateCallers++;
|
|
6139
|
-
};
|
|
6140
|
-
const makeRakeDbConfig = (config, args) => {
|
|
6141
|
-
const ic = intermediateCallers;
|
|
6142
|
-
intermediateCallers = 0;
|
|
6143
|
-
const result = {
|
|
6144
|
-
...migrationConfigDefaults,
|
|
6145
|
-
...config,
|
|
6146
|
-
__rakeDbConfig: true
|
|
6147
|
-
};
|
|
6148
|
-
if (!result.log) {
|
|
6149
|
-
delete result.logger;
|
|
6150
|
-
}
|
|
6151
|
-
ensureBasePathAndDbScript(result, ic);
|
|
6152
|
-
ensureMigrationsPath(result);
|
|
6153
|
-
if (!result.recurrentPath) {
|
|
6154
|
-
result.recurrentPath = path.join(
|
|
6155
|
-
result.migrationsPath,
|
|
6156
|
-
"recurrent"
|
|
6157
|
-
);
|
|
6158
|
-
}
|
|
6159
|
-
if ("recurrentPath" in result && !path.isAbsolute(result.recurrentPath)) {
|
|
6160
|
-
result.recurrentPath = path.resolve(result.basePath, result.recurrentPath);
|
|
6161
|
-
}
|
|
6162
|
-
if ("baseTable" in config && config.baseTable) {
|
|
6163
|
-
const { types, snakeCase, language } = config.baseTable.prototype;
|
|
6164
|
-
result.columnTypes = types || pqb.makeColumnTypes(pqb.defaultSchemaConfig);
|
|
6165
|
-
if (snakeCase) result.snakeCase = true;
|
|
6166
|
-
if (language) result.language = language;
|
|
6167
|
-
} else {
|
|
6168
|
-
const ct = "columnTypes" in config && config.columnTypes;
|
|
6169
|
-
result.columnTypes = (typeof ct === "function" ? ct(
|
|
6170
|
-
pqb.makeColumnTypes(pqb.defaultSchemaConfig)
|
|
6171
|
-
) : ct) || pqb.makeColumnTypes(pqb.defaultSchemaConfig);
|
|
6172
|
-
}
|
|
6173
|
-
if (config.migrationId === "serial") {
|
|
6174
|
-
result.migrationId = { serial: 4 };
|
|
6175
|
-
}
|
|
6176
|
-
const transaction = getCliParam(args, "transaction");
|
|
6177
|
-
if (transaction) {
|
|
6178
|
-
if (transaction !== "single" && transaction !== "per-migration") {
|
|
6179
|
-
throw new Error(
|
|
6180
|
-
`Unsupported transaction param ${transaction}, expected single or per-migration`
|
|
6181
|
-
);
|
|
6182
|
-
}
|
|
6183
|
-
result.transaction = transaction;
|
|
6184
|
-
} else if (!result.transaction) {
|
|
6185
|
-
result.transaction = "single";
|
|
6186
|
-
}
|
|
6187
|
-
let c = rakeDbCommands;
|
|
6188
|
-
if (config.commands) {
|
|
6189
|
-
c = { ...c };
|
|
6190
|
-
const commands = config.commands;
|
|
6191
|
-
for (const key in commands) {
|
|
6192
|
-
const command = commands[key];
|
|
6193
|
-
c[key] = typeof command === "function" ? { run: command } : command;
|
|
6194
|
-
}
|
|
6195
|
-
}
|
|
6196
|
-
result.commands = c;
|
|
6197
|
-
return result;
|
|
6198
|
-
};
|
|
6199
|
-
|
|
6200
6180
|
const listMigrationsStatuses = async (adapters, config, params) => {
|
|
6201
6181
|
const ctx = {};
|
|
6202
6182
|
const [{ migrations }, ...migrated] = await Promise.all([
|
|
@@ -6243,7 +6223,7 @@ const listMigrationsStatuses = async (adapters, config, params) => {
|
|
|
6243
6223
|
green: asIs,
|
|
6244
6224
|
red: asIs,
|
|
6245
6225
|
blue: asIs
|
|
6246
|
-
} :
|
|
6226
|
+
} : internal.colors;
|
|
6247
6227
|
const log = Object.values(map).map(({ databases, migrations: migrations2 }) => {
|
|
6248
6228
|
let log2 = ` ${c.yellow("Database:")} ${databases.join(", ")}`;
|
|
6249
6229
|
if (migrations2.length === 0) {
|
|
@@ -6345,7 +6325,7 @@ const rebase = async (adapters, config) => {
|
|
|
6345
6325
|
const result = await promptSelect({
|
|
6346
6326
|
message: "Which should go first?",
|
|
6347
6327
|
options: [prev.name, file.name],
|
|
6348
|
-
active: (s) => `${
|
|
6328
|
+
active: (s) => `${internal.colors.yellow("\u276F")} ${internal.colors.yellow(s)}`
|
|
6349
6329
|
});
|
|
6350
6330
|
moveFile = result ? file : prev;
|
|
6351
6331
|
}
|
|
@@ -6360,85 +6340,275 @@ const rebase = async (adapters, config) => {
|
|
|
6360
6340
|
renames.push(values);
|
|
6361
6341
|
renamesMap[file.path] = values;
|
|
6362
6342
|
}
|
|
6363
|
-
if (moveFile === prev) {
|
|
6364
|
-
if (prev.serial < minVersionToMigrate)
|
|
6365
|
-
minVersionToMigrate = prev.serial;
|
|
6366
|
-
newVersion = prev.serial + move;
|
|
6367
|
-
let item = [prev.path, newVersion];
|
|
6368
|
-
if (renamesMap[prev.path]) {
|
|
6369
|
-
renamesMap[prev.path] = item;
|
|
6370
|
-
for (let i2 = renames.length - 1; i2 >= 0; i2--) {
|
|
6371
|
-
const rename = renames[i2];
|
|
6372
|
-
rename[1]--;
|
|
6373
|
-
renames[i2] = item;
|
|
6374
|
-
if (rename[0] === prev.path) break;
|
|
6375
|
-
renamesMap[item[0]] = item;
|
|
6376
|
-
item = rename;
|
|
6377
|
-
}
|
|
6378
|
-
} else {
|
|
6379
|
-
renames.push(item);
|
|
6380
|
-
renamesMap[prev.path] = item;
|
|
6381
|
-
}
|
|
6343
|
+
if (moveFile === prev) {
|
|
6344
|
+
if (prev.serial < minVersionToMigrate)
|
|
6345
|
+
minVersionToMigrate = prev.serial;
|
|
6346
|
+
newVersion = prev.serial + move;
|
|
6347
|
+
let item = [prev.path, newVersion];
|
|
6348
|
+
if (renamesMap[prev.path]) {
|
|
6349
|
+
renamesMap[prev.path] = item;
|
|
6350
|
+
for (let i2 = renames.length - 1; i2 >= 0; i2--) {
|
|
6351
|
+
const rename = renames[i2];
|
|
6352
|
+
rename[1]--;
|
|
6353
|
+
renames[i2] = item;
|
|
6354
|
+
if (rename[0] === prev.path) break;
|
|
6355
|
+
renamesMap[item[0]] = item;
|
|
6356
|
+
item = rename;
|
|
6357
|
+
}
|
|
6358
|
+
} else {
|
|
6359
|
+
renames.push(item);
|
|
6360
|
+
renamesMap[prev.path] = item;
|
|
6361
|
+
}
|
|
6362
|
+
}
|
|
6363
|
+
}
|
|
6364
|
+
if (file.name !== migratedName && newVersion > maxNewVersion) {
|
|
6365
|
+
maxNewVersion = newVersion;
|
|
6366
|
+
}
|
|
6367
|
+
}
|
|
6368
|
+
if (!renames.length && !migratedFiles.length) return;
|
|
6369
|
+
maxNewVersion++;
|
|
6370
|
+
renames.push(
|
|
6371
|
+
...migratedFiles.map((file, i) => {
|
|
6372
|
+
const rename = [file.path, maxNewVersion + i];
|
|
6373
|
+
renamesMap[file.path] = rename;
|
|
6374
|
+
return rename;
|
|
6375
|
+
})
|
|
6376
|
+
);
|
|
6377
|
+
if (!renames.length) return;
|
|
6378
|
+
const migrationsDown = files.filter(
|
|
6379
|
+
(file) => combinedVersionsMap[file.version] === file.name && file.serial >= minVersionToMigrate
|
|
6380
|
+
);
|
|
6381
|
+
const migrationsUp = files.reduce((files2, file) => {
|
|
6382
|
+
const rename = renamesMap[file.path];
|
|
6383
|
+
if (rename) {
|
|
6384
|
+
const version = String(rename[1]).padStart(4, "0");
|
|
6385
|
+
files2.push({
|
|
6386
|
+
...file,
|
|
6387
|
+
path: path.join(
|
|
6388
|
+
path.dirname(rename[0]),
|
|
6389
|
+
version + path.basename(rename[0]).slice(version.length)
|
|
6390
|
+
),
|
|
6391
|
+
version
|
|
6392
|
+
});
|
|
6393
|
+
} else if (!combinedVersionsMap[file.version] || file.serial >= minVersionToMigrate) {
|
|
6394
|
+
files2.push(file);
|
|
6395
|
+
}
|
|
6396
|
+
return files2;
|
|
6397
|
+
}, []).sort((a, b) => +b.version - +a.version);
|
|
6398
|
+
set.migrations = migrationsDown;
|
|
6399
|
+
const redoConfig = {
|
|
6400
|
+
...config,
|
|
6401
|
+
async afterRollback() {
|
|
6402
|
+
set.migrations = migrationsUp;
|
|
6403
|
+
},
|
|
6404
|
+
async afterMigrate() {
|
|
6405
|
+
set.migrations = migrationsDown;
|
|
6406
|
+
}
|
|
6407
|
+
};
|
|
6408
|
+
for (const adapter of adapters) {
|
|
6409
|
+
await redo(adapter, redoConfig, { ctx, count: Infinity });
|
|
6410
|
+
}
|
|
6411
|
+
for (let i = renames.length - 1; i >= 0; i--) {
|
|
6412
|
+
const [from, version] = renames[i];
|
|
6413
|
+
const prefix = String(version).padStart(4, "0");
|
|
6414
|
+
await fs.rename(
|
|
6415
|
+
from,
|
|
6416
|
+
path.join(
|
|
6417
|
+
path.dirname(from),
|
|
6418
|
+
prefix + path.basename(from).slice(prefix.length)
|
|
6419
|
+
)
|
|
6420
|
+
);
|
|
6421
|
+
}
|
|
6422
|
+
};
|
|
6423
|
+
|
|
6424
|
+
const close = (adapters) => Promise.all(adapters.map((adapter) => adapter.close()));
|
|
6425
|
+
const maybeRunRecurrent = async (adapters, config) => {
|
|
6426
|
+
config.recurrentPath && await runRecurrentMigrations(
|
|
6427
|
+
adapters,
|
|
6428
|
+
config
|
|
6429
|
+
);
|
|
6430
|
+
};
|
|
6431
|
+
const rakeDbAliases$1 = {
|
|
6432
|
+
migrate: "up",
|
|
6433
|
+
rollback: "down",
|
|
6434
|
+
s: "status",
|
|
6435
|
+
rec: "recurrent"
|
|
6436
|
+
};
|
|
6437
|
+
const upCommand = {
|
|
6438
|
+
run: (adapters, config, args) => migrateCommand(adapters, config, args).then(() => maybeRunRecurrent(adapters, config)).then(() => close(adapters)),
|
|
6439
|
+
help: "migrate pending migrations",
|
|
6440
|
+
helpArguments: {
|
|
6441
|
+
"no arguments": "migrate all pending",
|
|
6442
|
+
"a number": "run a specific number of pending migrations",
|
|
6443
|
+
force: "enforce migrating a pending file in the middle"
|
|
6444
|
+
}
|
|
6445
|
+
};
|
|
6446
|
+
const downCommand = {
|
|
6447
|
+
run: (adapters, config, args) => rollbackCommand(adapters, config, args).then(() => close(adapters)),
|
|
6448
|
+
help: "rollback migrated migrations",
|
|
6449
|
+
helpArguments: {
|
|
6450
|
+
"no arguments": "rollback one last migration",
|
|
6451
|
+
"a number": "rollback a specified number",
|
|
6452
|
+
all: "rollback all migrations"
|
|
6453
|
+
}
|
|
6454
|
+
};
|
|
6455
|
+
const statusCommand = {
|
|
6456
|
+
run(adapters, config, args) {
|
|
6457
|
+
const showUrl = args.includes("p") || args.includes("path");
|
|
6458
|
+
return listMigrationsStatuses(adapters, config, { showUrl });
|
|
6459
|
+
},
|
|
6460
|
+
help: "list migrations statuses",
|
|
6461
|
+
helpArguments: {
|
|
6462
|
+
"no arguments": `does not print file paths`,
|
|
6463
|
+
"p, path": "also print file paths"
|
|
6464
|
+
}
|
|
6465
|
+
};
|
|
6466
|
+
const recurrent = {
|
|
6467
|
+
async run(adapters, config) {
|
|
6468
|
+
if (!config.recurrentPath) return;
|
|
6469
|
+
await maybeRunRecurrent(adapters, config).then(() => close(adapters));
|
|
6470
|
+
},
|
|
6471
|
+
help: "run recurrent migrations"
|
|
6472
|
+
};
|
|
6473
|
+
const rakeDbCommands = {
|
|
6474
|
+
create: {
|
|
6475
|
+
run: (adapters, config) => createDatabaseCommand(adapters, config),
|
|
6476
|
+
help: "create databases"
|
|
6477
|
+
},
|
|
6478
|
+
drop: {
|
|
6479
|
+
run: dropDatabaseCommand,
|
|
6480
|
+
help: "drop databases"
|
|
6481
|
+
},
|
|
6482
|
+
reset: {
|
|
6483
|
+
run: (adapters, config) => resetDatabaseCommand(adapters, config),
|
|
6484
|
+
help: "drop, create and migrate databases"
|
|
6485
|
+
},
|
|
6486
|
+
up: upCommand,
|
|
6487
|
+
down: downCommand,
|
|
6488
|
+
redo: {
|
|
6489
|
+
run: (adapters, config, args) => redoCommand(adapters, config, args).then(() => maybeRunRecurrent(adapters, config)).then(() => close(adapters)),
|
|
6490
|
+
help: "rollback and migrate, run recurrent"
|
|
6491
|
+
},
|
|
6492
|
+
pull: {
|
|
6493
|
+
run: ([adapter], config) => pullDbStructure(adapter, config).then(() => close([adapter])),
|
|
6494
|
+
help: "generate a combined migration for an existing database"
|
|
6495
|
+
},
|
|
6496
|
+
new: {
|
|
6497
|
+
run(_, config, args) {
|
|
6498
|
+
const [name] = args;
|
|
6499
|
+
if (!name) throw new Error("Migration name is missing");
|
|
6500
|
+
return newMigration(config, name);
|
|
6501
|
+
},
|
|
6502
|
+
help: "create new migration file"
|
|
6503
|
+
},
|
|
6504
|
+
status: statusCommand,
|
|
6505
|
+
recurrent,
|
|
6506
|
+
rebase: {
|
|
6507
|
+
run: (adapters, config) => rebase(adapters, config).then(() => close(adapters)),
|
|
6508
|
+
help: "move local migrations below the new ones from upstream"
|
|
6509
|
+
},
|
|
6510
|
+
"change-ids": {
|
|
6511
|
+
run(adapters, config, [format, digitsArg]) {
|
|
6512
|
+
if (format !== "serial" && format !== "timestamp") {
|
|
6513
|
+
throw new Error(
|
|
6514
|
+
`Pass "serial" or "timestamp" argument to the "change-ids" command`
|
|
6515
|
+
);
|
|
6516
|
+
}
|
|
6517
|
+
const digits = digitsArg ? parseInt(digitsArg) : void 0;
|
|
6518
|
+
if (digits && isNaN(digits)) {
|
|
6519
|
+
throw new Error(`Second argument is optional and must be an integer`);
|
|
6382
6520
|
}
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6521
|
+
return changeIds(adapters, config, { format, digits });
|
|
6522
|
+
},
|
|
6523
|
+
help: "change migrations ids format",
|
|
6524
|
+
helpArguments: {
|
|
6525
|
+
serial: "change ids to 4 digit serial",
|
|
6526
|
+
"serial *number*": "change ids to serial number of custom length",
|
|
6527
|
+
timestamp: "change timestamps"
|
|
6386
6528
|
}
|
|
6387
6529
|
}
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
)
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
const
|
|
6530
|
+
};
|
|
6531
|
+
for (const key in rakeDbAliases$1) {
|
|
6532
|
+
const command = rakeDbAliases$1[key];
|
|
6533
|
+
if (command) rakeDbCommands[key] = rakeDbCommands[command];
|
|
6534
|
+
}
|
|
6535
|
+
let intermediateCallers = 0;
|
|
6536
|
+
const incrementIntermediateCaller = () => {
|
|
6537
|
+
intermediateCallers++;
|
|
6538
|
+
};
|
|
6539
|
+
const ensureBasePathAndDbScript = (config, intermediateCallers2 = 0) => {
|
|
6540
|
+
if (config.basePath && config.dbScript) return config;
|
|
6541
|
+
let filePath = internal.getStackTrace()?.[3 + intermediateCallers2]?.getFileName();
|
|
6542
|
+
if (!filePath) {
|
|
6543
|
+
throw new Error(
|
|
6544
|
+
"Failed to determine path to db script. Please set basePath option of rakeDb"
|
|
6545
|
+
);
|
|
6546
|
+
}
|
|
6547
|
+
if (filePath.startsWith("file://")) {
|
|
6548
|
+
filePath = node_url.fileURLToPath(filePath);
|
|
6549
|
+
}
|
|
6550
|
+
const ext = path.extname(filePath);
|
|
6551
|
+
if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
|
|
6552
|
+
throw new Error(
|
|
6553
|
+
`Add a .ts suffix to the "${path.basename(filePath)}" when calling it`
|
|
6554
|
+
);
|
|
6555
|
+
}
|
|
6556
|
+
config.basePath = path.dirname(filePath);
|
|
6557
|
+
config.dbScript = path.basename(filePath);
|
|
6558
|
+
return config;
|
|
6559
|
+
};
|
|
6560
|
+
const makeRakeDbConfig = (config, args) => {
|
|
6561
|
+
const ic = intermediateCallers;
|
|
6562
|
+
intermediateCallers = 0;
|
|
6563
|
+
const result = {
|
|
6564
|
+
...rakeDbConfigDefaults,
|
|
6420
6565
|
...config,
|
|
6421
|
-
|
|
6422
|
-
set.migrations = migrationsUp;
|
|
6423
|
-
},
|
|
6424
|
-
async afterMigrate() {
|
|
6425
|
-
set.migrations = migrationsDown;
|
|
6426
|
-
}
|
|
6566
|
+
__rakeDbConfig: true
|
|
6427
6567
|
};
|
|
6428
|
-
|
|
6429
|
-
|
|
6568
|
+
ensureBasePathAndDbScript(result, ic);
|
|
6569
|
+
Object.assign(result, processMigrateConfig(result));
|
|
6570
|
+
if (!result.recurrentPath && result.migrationsPath) {
|
|
6571
|
+
result.recurrentPath = path.join(result.migrationsPath, "recurrent");
|
|
6430
6572
|
}
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6573
|
+
if (result.recurrentPath && !path.isAbsolute(result.recurrentPath)) {
|
|
6574
|
+
result.recurrentPath = path.resolve(result.basePath, result.recurrentPath);
|
|
6575
|
+
}
|
|
6576
|
+
if ("baseTable" in config && config.baseTable) {
|
|
6577
|
+
const { types, snakeCase, language } = config.baseTable.prototype;
|
|
6578
|
+
result.columnTypes = types || internal.makeColumnTypes(internal.defaultSchemaConfig);
|
|
6579
|
+
if (snakeCase) result.snakeCase = true;
|
|
6580
|
+
if (language) result.language = language;
|
|
6581
|
+
} else {
|
|
6582
|
+
const ct = "columnTypes" in config && config.columnTypes;
|
|
6583
|
+
result.columnTypes = (typeof ct === "function" ? ct(
|
|
6584
|
+
internal.makeColumnTypes(internal.defaultSchemaConfig)
|
|
6585
|
+
) : ct) || internal.makeColumnTypes(internal.defaultSchemaConfig);
|
|
6586
|
+
}
|
|
6587
|
+
if (config.migrationId === "serial") {
|
|
6588
|
+
result.migrationId = { serial: 4 };
|
|
6589
|
+
}
|
|
6590
|
+
const transaction = getCliParam(args, "transaction");
|
|
6591
|
+
if (transaction) {
|
|
6592
|
+
if (transaction !== "single" && transaction !== "per-migration") {
|
|
6593
|
+
throw new Error(
|
|
6594
|
+
`Unsupported transaction param ${transaction}, expected single or per-migration`
|
|
6595
|
+
);
|
|
6596
|
+
}
|
|
6597
|
+
result.transaction = transaction;
|
|
6598
|
+
} else if (!result.transaction) {
|
|
6599
|
+
result.transaction = "single";
|
|
6600
|
+
}
|
|
6601
|
+
let c = rakeDbCommands;
|
|
6602
|
+
if (config.commands) {
|
|
6603
|
+
c = { ...c };
|
|
6604
|
+
const commands = config.commands;
|
|
6605
|
+
for (const key in commands) {
|
|
6606
|
+
const command = commands[key];
|
|
6607
|
+
c[key] = typeof command === "function" ? { run: command } : command;
|
|
6608
|
+
}
|
|
6441
6609
|
}
|
|
6610
|
+
result.commands = c;
|
|
6611
|
+
return result;
|
|
6442
6612
|
};
|
|
6443
6613
|
|
|
6444
6614
|
const rakeDbAliases = {
|
|
@@ -6456,9 +6626,9 @@ const rakeDbCliWithAdapter = (inputConfig, args = process.argv.slice(2)) => {
|
|
|
6456
6626
|
config = makeRakeDbConfig(inputConfig, args);
|
|
6457
6627
|
}
|
|
6458
6628
|
return {
|
|
6459
|
-
change:
|
|
6629
|
+
change: createMigrationChangeFn(config),
|
|
6460
6630
|
async run(adapter, runArgs) {
|
|
6461
|
-
const adapters =
|
|
6631
|
+
const adapters = internal.toArray(adapter);
|
|
6462
6632
|
try {
|
|
6463
6633
|
await runCommand(adapters, config, runArgs || args);
|
|
6464
6634
|
} catch (err) {
|
|
@@ -6550,120 +6720,16 @@ ${Object.entries(helpArguments).map(
|
|
|
6550
6720
|
`);
|
|
6551
6721
|
}
|
|
6552
6722
|
};
|
|
6553
|
-
const close = (adapters) => Promise.all(adapters.map((adapter) => adapter.close()));
|
|
6554
|
-
const maybeRunRecurrent = async (adapters, config) => {
|
|
6555
|
-
config.recurrentPath && await runRecurrentMigrations(
|
|
6556
|
-
adapters,
|
|
6557
|
-
config
|
|
6558
|
-
);
|
|
6559
|
-
};
|
|
6560
|
-
const upCommand = {
|
|
6561
|
-
run: (adapters, config, args) => migrateCommand(adapters, config, args).then(() => maybeRunRecurrent(adapters, config)).then(() => close(adapters)),
|
|
6562
|
-
help: "migrate pending migrations",
|
|
6563
|
-
helpArguments: {
|
|
6564
|
-
"no arguments": "migrate all pending",
|
|
6565
|
-
"a number": "run a specific number of pending migrations",
|
|
6566
|
-
force: "enforce migrating a pending file in the middle"
|
|
6567
|
-
}
|
|
6568
|
-
};
|
|
6569
|
-
const downCommand = {
|
|
6570
|
-
run: (adapters, config, args) => rollbackCommand(adapters, config, args).then(() => close(adapters)),
|
|
6571
|
-
help: "rollback migrated migrations",
|
|
6572
|
-
helpArguments: {
|
|
6573
|
-
"no arguments": "rollback one last migration",
|
|
6574
|
-
"a number": "rollback a specified number",
|
|
6575
|
-
all: "rollback all migrations"
|
|
6576
|
-
}
|
|
6577
|
-
};
|
|
6578
|
-
const statusCommand = {
|
|
6579
|
-
run(adapters, config, args) {
|
|
6580
|
-
const showUrl = args.includes("p") || args.includes("path");
|
|
6581
|
-
return listMigrationsStatuses(adapters, config, { showUrl });
|
|
6582
|
-
},
|
|
6583
|
-
help: "list migrations statuses",
|
|
6584
|
-
helpArguments: {
|
|
6585
|
-
"no arguments": `does not print file paths`,
|
|
6586
|
-
"p, path": "also print file paths"
|
|
6587
|
-
}
|
|
6588
|
-
};
|
|
6589
|
-
const recurrent = {
|
|
6590
|
-
async run(adapters, config) {
|
|
6591
|
-
if (!config.recurrentPath) return;
|
|
6592
|
-
await maybeRunRecurrent(adapters, config).then(() => close(adapters));
|
|
6593
|
-
},
|
|
6594
|
-
help: "run recurrent migrations"
|
|
6595
|
-
};
|
|
6596
|
-
const rakeDbCommands = {
|
|
6597
|
-
create: {
|
|
6598
|
-
run: (adapters, config) => createDatabaseCommand(adapters, config),
|
|
6599
|
-
help: "create databases"
|
|
6600
|
-
},
|
|
6601
|
-
drop: {
|
|
6602
|
-
run: dropDatabaseCommand,
|
|
6603
|
-
help: "drop databases"
|
|
6604
|
-
},
|
|
6605
|
-
reset: {
|
|
6606
|
-
run: (adapters, config) => resetDatabaseCommand(adapters, config),
|
|
6607
|
-
help: "drop, create and migrate databases"
|
|
6608
|
-
},
|
|
6609
|
-
up: upCommand,
|
|
6610
|
-
down: downCommand,
|
|
6611
|
-
redo: {
|
|
6612
|
-
run: (adapters, config, args) => redoCommand(adapters, config, args).then(() => maybeRunRecurrent(adapters, config)).then(() => close(adapters)),
|
|
6613
|
-
help: "rollback and migrate, run recurrent"
|
|
6614
|
-
},
|
|
6615
|
-
pull: {
|
|
6616
|
-
run: ([adapter], config) => pullDbStructure(adapter, config).then(() => close([adapter])),
|
|
6617
|
-
help: "generate a combined migration for an existing database"
|
|
6618
|
-
},
|
|
6619
|
-
new: {
|
|
6620
|
-
run(_, config, args) {
|
|
6621
|
-
const [name] = args;
|
|
6622
|
-
if (!name) throw new Error("Migration name is missing");
|
|
6623
|
-
return newMigration(config, name);
|
|
6624
|
-
},
|
|
6625
|
-
help: "create new migration file"
|
|
6626
|
-
},
|
|
6627
|
-
status: statusCommand,
|
|
6628
|
-
recurrent,
|
|
6629
|
-
rebase: {
|
|
6630
|
-
run: (adapters, config) => rebase(adapters, config).then(() => close(adapters)),
|
|
6631
|
-
help: "move local migrations below the new ones from upstream"
|
|
6632
|
-
},
|
|
6633
|
-
"change-ids": {
|
|
6634
|
-
run(adapters, config, [format, digitsArg]) {
|
|
6635
|
-
if (format !== "serial" && format !== "timestamp") {
|
|
6636
|
-
throw new Error(
|
|
6637
|
-
`Pass "serial" or "timestamp" argument to the "change-ids" command`
|
|
6638
|
-
);
|
|
6639
|
-
}
|
|
6640
|
-
const digits = digitsArg ? parseInt(digitsArg) : void 0;
|
|
6641
|
-
if (digits && isNaN(digits)) {
|
|
6642
|
-
throw new Error(`Second argument is optional and must be an integer`);
|
|
6643
|
-
}
|
|
6644
|
-
return changeIds(adapters, config, { format, digits });
|
|
6645
|
-
},
|
|
6646
|
-
help: "change migrations ids format",
|
|
6647
|
-
helpArguments: {
|
|
6648
|
-
serial: "change ids to 4 digit serial",
|
|
6649
|
-
"serial *number*": "change ids to serial number of custom length",
|
|
6650
|
-
timestamp: "change ids to timestamps"
|
|
6651
|
-
}
|
|
6652
|
-
}
|
|
6653
|
-
};
|
|
6654
|
-
for (const key in rakeDbAliases) {
|
|
6655
|
-
const command = rakeDbAliases[key];
|
|
6656
|
-
if (command) rakeDbCommands[key] = rakeDbCommands[command];
|
|
6657
|
-
}
|
|
6658
6723
|
|
|
6659
6724
|
exports.RakeDbError = RakeDbError;
|
|
6660
6725
|
exports.astToMigration = astToMigration;
|
|
6661
6726
|
exports.concatSchemaAndName = concatSchemaAndName;
|
|
6662
6727
|
exports.createDatabase = createDatabase;
|
|
6728
|
+
exports.createMigrationChangeFn = createMigrationChangeFn;
|
|
6663
6729
|
exports.createMigrationInterface = createMigrationInterface;
|
|
6664
6730
|
exports.createMigrationsSchemaAndTable = createMigrationsSchemaAndTable;
|
|
6665
|
-
exports.createSchema = createSchema
|
|
6666
|
-
exports.createTable = createTable
|
|
6731
|
+
exports.createSchema = createSchema;
|
|
6732
|
+
exports.createTable = createTable;
|
|
6667
6733
|
exports.dbColumnToAst = dbColumnToAst;
|
|
6668
6734
|
exports.dropDatabase = dropDatabase;
|
|
6669
6735
|
exports.dropSchema = dropSchema;
|
|
@@ -6682,14 +6748,13 @@ exports.instantiateDbColumn = instantiateDbColumn;
|
|
|
6682
6748
|
exports.introspectDbSchema = introspectDbSchema;
|
|
6683
6749
|
exports.makeDomainsMap = makeDomainsMap;
|
|
6684
6750
|
exports.makeFileVersion = makeFileVersion;
|
|
6685
|
-
exports.makeRakeDbConfig = makeRakeDbConfig;
|
|
6686
6751
|
exports.makeStructureToAstCtx = makeStructureToAstCtx;
|
|
6687
6752
|
exports.migrate = migrate;
|
|
6688
6753
|
exports.migrateAndClose = migrateAndClose;
|
|
6689
|
-
exports.migrationConfigDefaults = migrationConfigDefaults;
|
|
6690
6754
|
exports.promptSelect = promptSelect;
|
|
6691
6755
|
exports.rakeDbCliWithAdapter = rakeDbCliWithAdapter;
|
|
6692
6756
|
exports.rakeDbCommands = rakeDbCommands;
|
|
6757
|
+
exports.rakeDbConfigDefaults = rakeDbConfigDefaults;
|
|
6693
6758
|
exports.redo = redo;
|
|
6694
6759
|
exports.rollback = rollback;
|
|
6695
6760
|
exports.runMigration = runMigration;
|