relq 1.0.113 → 1.0.115
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/cjs/cli/commands/push.cjs +81 -6
- package/dist/cjs/cli/utils/schema-loader.cjs +18 -0
- package/dist/cjs/cli/utils/snapshot-manager.cjs +34 -2
- package/dist/esm/cli/commands/push.js +81 -6
- package/dist/esm/cli/utils/schema-loader.js +18 -0
- package/dist/esm/cli/utils/snapshot-manager.js +34 -2
- package/package.json +1 -1
|
@@ -57,6 +57,7 @@ const schema_hash_1 = require("../utils/schema-hash.cjs");
|
|
|
57
57
|
const migration_generator_1 = require("../utils/migration-generator.cjs");
|
|
58
58
|
const migration_helpers_1 = require("../utils/migration-helpers.cjs");
|
|
59
59
|
const ast_transformer_1 = require("../utils/ast-transformer.cjs");
|
|
60
|
+
const types_manager_1 = require("../utils/types-manager.cjs");
|
|
60
61
|
function formatColumnProps(col) {
|
|
61
62
|
if (!col)
|
|
62
63
|
return '';
|
|
@@ -110,6 +111,20 @@ function mergeTrackingIds(introspected, desired) {
|
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
}
|
|
114
|
+
const desiredFuncMap = new Map((desired.functions || []).map(f => [f.name, f]));
|
|
115
|
+
for (const func of introspected.functions || []) {
|
|
116
|
+
const desiredFunc = desiredFuncMap.get(func.name);
|
|
117
|
+
if (desiredFunc?.trackingId) {
|
|
118
|
+
func.trackingId = desiredFunc.trackingId;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const desiredTrigMap = new Map((desired.triggers || []).map(t => [t.name, t]));
|
|
122
|
+
for (const trig of introspected.triggers || []) {
|
|
123
|
+
const desiredTrig = desiredTrigMap.get(trig.name);
|
|
124
|
+
if (desiredTrig?.trackingId) {
|
|
125
|
+
trig.trackingId = desiredTrig.trackingId;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
113
128
|
return introspected;
|
|
114
129
|
}
|
|
115
130
|
async function runPush(config, projectRoot, opts = {}) {
|
|
@@ -187,14 +202,17 @@ async function runPush(config, projectRoot, opts = {}) {
|
|
|
187
202
|
}
|
|
188
203
|
}
|
|
189
204
|
const desiredASTCopy = { ...desiredAST };
|
|
190
|
-
if (!includeFunctions) {
|
|
205
|
+
if (!includeFunctions || desiredASTCopy.functions.length === 0) {
|
|
191
206
|
dbParsedSchema.functions = [];
|
|
192
207
|
desiredASTCopy.functions = [];
|
|
193
208
|
}
|
|
194
|
-
if (!includeTriggers) {
|
|
209
|
+
if (!includeTriggers || desiredASTCopy.triggers.length === 0) {
|
|
195
210
|
dbParsedSchema.triggers = [];
|
|
196
211
|
desiredASTCopy.triggers = [];
|
|
197
212
|
}
|
|
213
|
+
if (desiredASTCopy.sequences.length === 0) {
|
|
214
|
+
dbParsedSchema.sequences = [];
|
|
215
|
+
}
|
|
198
216
|
const comparison = (0, schema_diff_1.compareSchemas)(dbParsedSchema, desiredASTCopy);
|
|
199
217
|
spin.stop('Diff computed');
|
|
200
218
|
if (!comparison.hasChanges && !filteredDiff.hasChanges) {
|
|
@@ -235,6 +253,13 @@ async function runPush(config, projectRoot, opts = {}) {
|
|
|
235
253
|
for (const rename of comparison.renamed.indexes) {
|
|
236
254
|
console.log(` ${colors_1.colors.cyan('→')} index ${rename.from} → ${rename.to} ${colors_1.colors.muted('(rename index)')}`);
|
|
237
255
|
}
|
|
256
|
+
const modifiedIndexesByTable = new Map();
|
|
257
|
+
for (const idx of comparison.modified.indexes) {
|
|
258
|
+
const list = modifiedIndexesByTable.get(idx.table) || [];
|
|
259
|
+
list.push(idx);
|
|
260
|
+
modifiedIndexesByTable.set(idx.table, list);
|
|
261
|
+
}
|
|
262
|
+
const shownModifiedIndexTables = new Set();
|
|
238
263
|
for (const table of filteredDiff.tables) {
|
|
239
264
|
if (renamedFromNames.has(table.name) || renamedToNames.has(table.name))
|
|
240
265
|
continue;
|
|
@@ -265,12 +290,29 @@ async function runPush(config, projectRoot, opts = {}) {
|
|
|
265
290
|
const prefix = idx.type === 'added' ? colors_1.colors.green('+') : idx.type === 'removed' ? colors_1.colors.red('-') : colors_1.colors.yellow('~');
|
|
266
291
|
console.log(` ${prefix} index ${idx.name}`);
|
|
267
292
|
}
|
|
293
|
+
const tableModifiedIndexes = modifiedIndexesByTable.get(table.name);
|
|
294
|
+
if (tableModifiedIndexes) {
|
|
295
|
+
for (const midx of tableModifiedIndexes) {
|
|
296
|
+
console.log(` ${colors_1.colors.yellow('~')} index ${midx.newIndex.name} ${colors_1.colors.muted(`(${midx.changes.join(', ')})`)}`);
|
|
297
|
+
}
|
|
298
|
+
shownModifiedIndexTables.add(table.name);
|
|
299
|
+
}
|
|
268
300
|
for (const con of table.constraints || []) {
|
|
269
301
|
const prefix = con.type === 'added' ? colors_1.colors.green('+') : con.type === 'removed' ? colors_1.colors.red('-') : colors_1.colors.yellow('~');
|
|
270
302
|
console.log(` ${prefix} constraint ${con.name}`);
|
|
271
303
|
}
|
|
272
304
|
}
|
|
273
305
|
}
|
|
306
|
+
for (const [tableName, indexes] of modifiedIndexesByTable) {
|
|
307
|
+
if (shownModifiedIndexTables.has(tableName))
|
|
308
|
+
continue;
|
|
309
|
+
if (renamedFromNames.has(tableName) || renamedToNames.has(tableName))
|
|
310
|
+
continue;
|
|
311
|
+
console.log(` ${colors_1.colors.yellow('~')} ${colors_1.colors.bold(tableName)}`);
|
|
312
|
+
for (const midx of indexes) {
|
|
313
|
+
console.log(` ${colors_1.colors.yellow('~')} index ${midx.newIndex.name} ${colors_1.colors.muted(`(${midx.changes.join(', ')})`)}`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
274
316
|
for (const e of comparison.added.enums) {
|
|
275
317
|
console.log(` ${colors_1.colors.green('+')} ${colors_1.colors.bold(e.name)} ${colors_1.colors.muted('(new enum)')}`);
|
|
276
318
|
}
|
|
@@ -282,9 +324,6 @@ async function runPush(config, projectRoot, opts = {}) {
|
|
|
282
324
|
const removed = e.changes.removed.length > 0 ? `-${e.changes.removed.join(',')}` : '';
|
|
283
325
|
console.log(` ${colors_1.colors.yellow('~')} ${colors_1.colors.bold(e.name)} ${colors_1.colors.muted(`(enum: ${[added, removed].filter(Boolean).join(' ')})`)}`);
|
|
284
326
|
}
|
|
285
|
-
for (const idx of comparison.modified.indexes) {
|
|
286
|
-
console.log(` ${colors_1.colors.yellow('~')} index ${colors_1.colors.bold(idx.newIndex.name)} ${colors_1.colors.muted(`(${idx.changes.join(', ')})`)}`);
|
|
287
|
-
}
|
|
288
327
|
for (const d of comparison.added.domains) {
|
|
289
328
|
console.log(` ${colors_1.colors.green('+')} ${colors_1.colors.bold(d.name)} ${colors_1.colors.muted('(new domain)')}`);
|
|
290
329
|
}
|
|
@@ -446,6 +485,35 @@ async function runPush(config, projectRoot, opts = {}) {
|
|
|
446
485
|
}
|
|
447
486
|
}
|
|
448
487
|
}
|
|
488
|
+
const modifiedIdxCount = comparison.modified.indexes.length;
|
|
489
|
+
if (modifiedIdxCount > 0) {
|
|
490
|
+
let regIdxAdded = 0, regIdxRemoved = 0;
|
|
491
|
+
for (const t of summaryDiff.tables) {
|
|
492
|
+
for (const idx of t.indexes || []) {
|
|
493
|
+
if (idx.type === 'added')
|
|
494
|
+
regIdxAdded++;
|
|
495
|
+
else if (idx.type === 'removed')
|
|
496
|
+
regIdxRemoved++;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
const idxParts = [];
|
|
500
|
+
if (regIdxAdded)
|
|
501
|
+
idxParts.push(colors_1.colors.green(`${regIdxAdded} added`));
|
|
502
|
+
if (modifiedIdxCount)
|
|
503
|
+
idxParts.push(colors_1.colors.yellow(`${modifiedIdxCount} modified`));
|
|
504
|
+
if (regIdxRemoved)
|
|
505
|
+
idxParts.push(colors_1.colors.red(`${regIdxRemoved} removed`));
|
|
506
|
+
if (idxParts.length > 0) {
|
|
507
|
+
const idxLine = ` ${colors_1.colors.muted('indexes:')} ${idxParts.join(', ')}`;
|
|
508
|
+
const idxLineIdx = summaryLines.findIndex(l => l.includes('indexes:'));
|
|
509
|
+
if (idxLineIdx >= 0) {
|
|
510
|
+
summaryLines[idxLineIdx] = idxLine;
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
summaryLines.push(idxLine);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
449
517
|
const allSummaryLines = [...renameParts, ...summaryLines];
|
|
450
518
|
if (allSummaryLines.length > 0) {
|
|
451
519
|
for (const line of allSummaryLines)
|
|
@@ -587,6 +655,12 @@ async function runPush(config, projectRoot, opts = {}) {
|
|
|
587
655
|
mergeTrackingIds(updatedSchema, desiredSchema);
|
|
588
656
|
(0, snapshot_manager_1.saveSnapshot)(updatedSchema, snapshotPath, connection.database);
|
|
589
657
|
spin.stop('Snapshot updated');
|
|
658
|
+
const typesFilePath = (0, types_manager_1.getTypesFilePath)(schemaPath);
|
|
659
|
+
try {
|
|
660
|
+
await (0, types_manager_1.syncTypesToDb)(connection, typesFilePath, schemaPath);
|
|
661
|
+
}
|
|
662
|
+
catch {
|
|
663
|
+
}
|
|
590
664
|
const duration = Date.now() - startTime;
|
|
591
665
|
console.log('');
|
|
592
666
|
console.log(`Push completed in ${(0, format_1.formatDuration)(duration)}`);
|
|
@@ -623,12 +697,13 @@ async function runPush(config, projectRoot, opts = {}) {
|
|
|
623
697
|
+ comparison.removed.sequences.length + comparison.removed.compositeTypes.length
|
|
624
698
|
+ comparison.removed.views.length + comparison.removed.functions.length
|
|
625
699
|
+ comparison.removed.triggers.length + comparison.removed.extensions.length;
|
|
700
|
+
const sIdxModified = comparison.modified.indexes.length;
|
|
626
701
|
const ddlModified = comparison.modified.enums.length;
|
|
627
702
|
const totalRenamed = comparison.renamed.tables.length + comparison.renamed.columns.length
|
|
628
703
|
+ comparison.renamed.indexes.length + comparison.renamed.enums.length
|
|
629
704
|
+ comparison.renamed.sequences.length + comparison.renamed.functions.length;
|
|
630
705
|
const totalAdded = sTablesAdded + sColsAdded + sIdxAdded + ddlAdded + renColAdded;
|
|
631
|
-
const totalModified = sTablesModified + sColsModified + ddlModified + renColModified;
|
|
706
|
+
const totalModified = sTablesModified + sColsModified + sIdxModified + ddlModified + renColModified;
|
|
632
707
|
const totalRemoved = sTablesRemoved + sColsRemoved + sIdxRemoved + ddlRemoved + renColRemoved;
|
|
633
708
|
const parts = [];
|
|
634
709
|
if (totalAdded > 0 || totalModified > 0 || totalRemoved > 0 || totalRenamed > 0) {
|
|
@@ -111,6 +111,24 @@ async function loadSchemaFile(schemaPath, projectRoot) {
|
|
|
111
111
|
});
|
|
112
112
|
const schemaModule = await jiti.import(absolutePath);
|
|
113
113
|
const ast = (0, schema_to_ast_1.schemaToAST)(schemaModule);
|
|
114
|
+
const ext = path.extname(absolutePath);
|
|
115
|
+
const baseName = absolutePath.slice(0, -ext.length);
|
|
116
|
+
for (const suffix of ['functions', 'triggers', 'views']) {
|
|
117
|
+
const companionPath = `${baseName}.${suffix}${ext}`;
|
|
118
|
+
if (!fs.existsSync(companionPath))
|
|
119
|
+
continue;
|
|
120
|
+
const companionModule = await jiti.import(companionPath);
|
|
121
|
+
const companionAST = (0, schema_to_ast_1.schemaToAST)(companionModule);
|
|
122
|
+
ast.tables.push(...companionAST.tables);
|
|
123
|
+
ast.enums.push(...companionAST.enums);
|
|
124
|
+
ast.domains.push(...companionAST.domains);
|
|
125
|
+
ast.compositeTypes.push(...companionAST.compositeTypes);
|
|
126
|
+
ast.sequences.push(...companionAST.sequences);
|
|
127
|
+
ast.views.push(...companionAST.views);
|
|
128
|
+
ast.functions.push(...companionAST.functions);
|
|
129
|
+
ast.triggers.push(...companionAST.triggers);
|
|
130
|
+
ast.extensions.push(...companionAST.extensions);
|
|
131
|
+
}
|
|
114
132
|
const tables = ast.tables.map(schema_to_ast_1.parsedTableToTableInfo);
|
|
115
133
|
const schema = {
|
|
116
134
|
tables,
|
|
@@ -78,11 +78,32 @@ function databaseSchemaToSnapshot(schema, database) {
|
|
|
78
78
|
for (const table of schema.tables) {
|
|
79
79
|
tables[table.name] = tableToSnapshot(table);
|
|
80
80
|
}
|
|
81
|
+
const functions = (schema.functions || []).map(f => ({
|
|
82
|
+
name: f.name,
|
|
83
|
+
schema: f.schema || 'public',
|
|
84
|
+
returnType: f.returnType,
|
|
85
|
+
argTypes: f.argTypes || [],
|
|
86
|
+
language: f.language,
|
|
87
|
+
definition: f.definition || '',
|
|
88
|
+
volatility: f.volatility || 'VOLATILE',
|
|
89
|
+
...(f.trackingId ? { trackingId: f.trackingId } : {}),
|
|
90
|
+
}));
|
|
91
|
+
const triggers = (schema.triggers || []).map(t => ({
|
|
92
|
+
name: t.name,
|
|
93
|
+
tableName: t.tableName,
|
|
94
|
+
event: t.event,
|
|
95
|
+
timing: t.timing,
|
|
96
|
+
forEach: t.forEach,
|
|
97
|
+
functionName: t.functionName,
|
|
98
|
+
...(t.trackingId ? { trackingId: t.trackingId } : {}),
|
|
99
|
+
}));
|
|
81
100
|
return {
|
|
82
101
|
version: SNAPSHOT_VERSION,
|
|
83
102
|
generatedAt: new Date().toISOString(),
|
|
84
103
|
database,
|
|
85
104
|
tables,
|
|
105
|
+
functions,
|
|
106
|
+
triggers,
|
|
86
107
|
appliedMigrations: [],
|
|
87
108
|
extensions: schema.extensions || [],
|
|
88
109
|
};
|
|
@@ -151,6 +172,17 @@ function snapshotToDatabaseSchema(snapshot) {
|
|
|
151
172
|
for (const [, tableSnapshot] of Object.entries(snapshot.tables)) {
|
|
152
173
|
tables.push(snapshotToTable(tableSnapshot));
|
|
153
174
|
}
|
|
175
|
+
const functions = (snapshot.functions || []).map(f => ({
|
|
176
|
+
...f,
|
|
177
|
+
argTypes: f.argTypes || [],
|
|
178
|
+
isAggregate: false,
|
|
179
|
+
}));
|
|
180
|
+
const triggers = (snapshot.triggers || []).map(t => ({
|
|
181
|
+
...t,
|
|
182
|
+
forEach: (t.forEach || 'ROW'),
|
|
183
|
+
definition: '',
|
|
184
|
+
isEnabled: true,
|
|
185
|
+
}));
|
|
154
186
|
return {
|
|
155
187
|
tables,
|
|
156
188
|
enums: [],
|
|
@@ -158,8 +190,8 @@ function snapshotToDatabaseSchema(snapshot) {
|
|
|
158
190
|
compositeTypes: [],
|
|
159
191
|
sequences: [],
|
|
160
192
|
collations: [],
|
|
161
|
-
functions
|
|
162
|
-
triggers
|
|
193
|
+
functions,
|
|
194
|
+
triggers,
|
|
163
195
|
policies: [],
|
|
164
196
|
partitions: [],
|
|
165
197
|
foreignServers: [],
|
|
@@ -21,6 +21,7 @@ import { normalizeSchema } from "../utils/schema-hash.js";
|
|
|
21
21
|
import { generateTimestampedName, generateMigrationFromComparison, generateMigrationNameFromComparison } from "../utils/migration-generator.js";
|
|
22
22
|
import { getMigrationTableDDL } from "../utils/migration-helpers.js";
|
|
23
23
|
import { introspectedToParsedSchema } from "../utils/ast-transformer.js";
|
|
24
|
+
import { syncTypesToDb, getTypesFilePath } from "../utils/types-manager.js";
|
|
24
25
|
function formatColumnProps(col) {
|
|
25
26
|
if (!col)
|
|
26
27
|
return '';
|
|
@@ -74,6 +75,20 @@ function mergeTrackingIds(introspected, desired) {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
}
|
|
78
|
+
const desiredFuncMap = new Map((desired.functions || []).map(f => [f.name, f]));
|
|
79
|
+
for (const func of introspected.functions || []) {
|
|
80
|
+
const desiredFunc = desiredFuncMap.get(func.name);
|
|
81
|
+
if (desiredFunc?.trackingId) {
|
|
82
|
+
func.trackingId = desiredFunc.trackingId;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const desiredTrigMap = new Map((desired.triggers || []).map(t => [t.name, t]));
|
|
86
|
+
for (const trig of introspected.triggers || []) {
|
|
87
|
+
const desiredTrig = desiredTrigMap.get(trig.name);
|
|
88
|
+
if (desiredTrig?.trackingId) {
|
|
89
|
+
trig.trackingId = desiredTrig.trackingId;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
77
92
|
return introspected;
|
|
78
93
|
}
|
|
79
94
|
export async function runPush(config, projectRoot, opts = {}) {
|
|
@@ -151,14 +166,17 @@ export async function runPush(config, projectRoot, opts = {}) {
|
|
|
151
166
|
}
|
|
152
167
|
}
|
|
153
168
|
const desiredASTCopy = { ...desiredAST };
|
|
154
|
-
if (!includeFunctions) {
|
|
169
|
+
if (!includeFunctions || desiredASTCopy.functions.length === 0) {
|
|
155
170
|
dbParsedSchema.functions = [];
|
|
156
171
|
desiredASTCopy.functions = [];
|
|
157
172
|
}
|
|
158
|
-
if (!includeTriggers) {
|
|
173
|
+
if (!includeTriggers || desiredASTCopy.triggers.length === 0) {
|
|
159
174
|
dbParsedSchema.triggers = [];
|
|
160
175
|
desiredASTCopy.triggers = [];
|
|
161
176
|
}
|
|
177
|
+
if (desiredASTCopy.sequences.length === 0) {
|
|
178
|
+
dbParsedSchema.sequences = [];
|
|
179
|
+
}
|
|
162
180
|
const comparison = compareSchemas(dbParsedSchema, desiredASTCopy);
|
|
163
181
|
spin.stop('Diff computed');
|
|
164
182
|
if (!comparison.hasChanges && !filteredDiff.hasChanges) {
|
|
@@ -199,6 +217,13 @@ export async function runPush(config, projectRoot, opts = {}) {
|
|
|
199
217
|
for (const rename of comparison.renamed.indexes) {
|
|
200
218
|
console.log(` ${colors.cyan('→')} index ${rename.from} → ${rename.to} ${colors.muted('(rename index)')}`);
|
|
201
219
|
}
|
|
220
|
+
const modifiedIndexesByTable = new Map();
|
|
221
|
+
for (const idx of comparison.modified.indexes) {
|
|
222
|
+
const list = modifiedIndexesByTable.get(idx.table) || [];
|
|
223
|
+
list.push(idx);
|
|
224
|
+
modifiedIndexesByTable.set(idx.table, list);
|
|
225
|
+
}
|
|
226
|
+
const shownModifiedIndexTables = new Set();
|
|
202
227
|
for (const table of filteredDiff.tables) {
|
|
203
228
|
if (renamedFromNames.has(table.name) || renamedToNames.has(table.name))
|
|
204
229
|
continue;
|
|
@@ -229,12 +254,29 @@ export async function runPush(config, projectRoot, opts = {}) {
|
|
|
229
254
|
const prefix = idx.type === 'added' ? colors.green('+') : idx.type === 'removed' ? colors.red('-') : colors.yellow('~');
|
|
230
255
|
console.log(` ${prefix} index ${idx.name}`);
|
|
231
256
|
}
|
|
257
|
+
const tableModifiedIndexes = modifiedIndexesByTable.get(table.name);
|
|
258
|
+
if (tableModifiedIndexes) {
|
|
259
|
+
for (const midx of tableModifiedIndexes) {
|
|
260
|
+
console.log(` ${colors.yellow('~')} index ${midx.newIndex.name} ${colors.muted(`(${midx.changes.join(', ')})`)}`);
|
|
261
|
+
}
|
|
262
|
+
shownModifiedIndexTables.add(table.name);
|
|
263
|
+
}
|
|
232
264
|
for (const con of table.constraints || []) {
|
|
233
265
|
const prefix = con.type === 'added' ? colors.green('+') : con.type === 'removed' ? colors.red('-') : colors.yellow('~');
|
|
234
266
|
console.log(` ${prefix} constraint ${con.name}`);
|
|
235
267
|
}
|
|
236
268
|
}
|
|
237
269
|
}
|
|
270
|
+
for (const [tableName, indexes] of modifiedIndexesByTable) {
|
|
271
|
+
if (shownModifiedIndexTables.has(tableName))
|
|
272
|
+
continue;
|
|
273
|
+
if (renamedFromNames.has(tableName) || renamedToNames.has(tableName))
|
|
274
|
+
continue;
|
|
275
|
+
console.log(` ${colors.yellow('~')} ${colors.bold(tableName)}`);
|
|
276
|
+
for (const midx of indexes) {
|
|
277
|
+
console.log(` ${colors.yellow('~')} index ${midx.newIndex.name} ${colors.muted(`(${midx.changes.join(', ')})`)}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
238
280
|
for (const e of comparison.added.enums) {
|
|
239
281
|
console.log(` ${colors.green('+')} ${colors.bold(e.name)} ${colors.muted('(new enum)')}`);
|
|
240
282
|
}
|
|
@@ -246,9 +288,6 @@ export async function runPush(config, projectRoot, opts = {}) {
|
|
|
246
288
|
const removed = e.changes.removed.length > 0 ? `-${e.changes.removed.join(',')}` : '';
|
|
247
289
|
console.log(` ${colors.yellow('~')} ${colors.bold(e.name)} ${colors.muted(`(enum: ${[added, removed].filter(Boolean).join(' ')})`)}`);
|
|
248
290
|
}
|
|
249
|
-
for (const idx of comparison.modified.indexes) {
|
|
250
|
-
console.log(` ${colors.yellow('~')} index ${colors.bold(idx.newIndex.name)} ${colors.muted(`(${idx.changes.join(', ')})`)}`);
|
|
251
|
-
}
|
|
252
291
|
for (const d of comparison.added.domains) {
|
|
253
292
|
console.log(` ${colors.green('+')} ${colors.bold(d.name)} ${colors.muted('(new domain)')}`);
|
|
254
293
|
}
|
|
@@ -410,6 +449,35 @@ export async function runPush(config, projectRoot, opts = {}) {
|
|
|
410
449
|
}
|
|
411
450
|
}
|
|
412
451
|
}
|
|
452
|
+
const modifiedIdxCount = comparison.modified.indexes.length;
|
|
453
|
+
if (modifiedIdxCount > 0) {
|
|
454
|
+
let regIdxAdded = 0, regIdxRemoved = 0;
|
|
455
|
+
for (const t of summaryDiff.tables) {
|
|
456
|
+
for (const idx of t.indexes || []) {
|
|
457
|
+
if (idx.type === 'added')
|
|
458
|
+
regIdxAdded++;
|
|
459
|
+
else if (idx.type === 'removed')
|
|
460
|
+
regIdxRemoved++;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
const idxParts = [];
|
|
464
|
+
if (regIdxAdded)
|
|
465
|
+
idxParts.push(colors.green(`${regIdxAdded} added`));
|
|
466
|
+
if (modifiedIdxCount)
|
|
467
|
+
idxParts.push(colors.yellow(`${modifiedIdxCount} modified`));
|
|
468
|
+
if (regIdxRemoved)
|
|
469
|
+
idxParts.push(colors.red(`${regIdxRemoved} removed`));
|
|
470
|
+
if (idxParts.length > 0) {
|
|
471
|
+
const idxLine = ` ${colors.muted('indexes:')} ${idxParts.join(', ')}`;
|
|
472
|
+
const idxLineIdx = summaryLines.findIndex(l => l.includes('indexes:'));
|
|
473
|
+
if (idxLineIdx >= 0) {
|
|
474
|
+
summaryLines[idxLineIdx] = idxLine;
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
summaryLines.push(idxLine);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
413
481
|
const allSummaryLines = [...renameParts, ...summaryLines];
|
|
414
482
|
if (allSummaryLines.length > 0) {
|
|
415
483
|
for (const line of allSummaryLines)
|
|
@@ -551,6 +619,12 @@ export async function runPush(config, projectRoot, opts = {}) {
|
|
|
551
619
|
mergeTrackingIds(updatedSchema, desiredSchema);
|
|
552
620
|
saveSnapshot(updatedSchema, snapshotPath, connection.database);
|
|
553
621
|
spin.stop('Snapshot updated');
|
|
622
|
+
const typesFilePath = getTypesFilePath(schemaPath);
|
|
623
|
+
try {
|
|
624
|
+
await syncTypesToDb(connection, typesFilePath, schemaPath);
|
|
625
|
+
}
|
|
626
|
+
catch {
|
|
627
|
+
}
|
|
554
628
|
const duration = Date.now() - startTime;
|
|
555
629
|
console.log('');
|
|
556
630
|
console.log(`Push completed in ${formatDuration(duration)}`);
|
|
@@ -587,12 +661,13 @@ export async function runPush(config, projectRoot, opts = {}) {
|
|
|
587
661
|
+ comparison.removed.sequences.length + comparison.removed.compositeTypes.length
|
|
588
662
|
+ comparison.removed.views.length + comparison.removed.functions.length
|
|
589
663
|
+ comparison.removed.triggers.length + comparison.removed.extensions.length;
|
|
664
|
+
const sIdxModified = comparison.modified.indexes.length;
|
|
590
665
|
const ddlModified = comparison.modified.enums.length;
|
|
591
666
|
const totalRenamed = comparison.renamed.tables.length + comparison.renamed.columns.length
|
|
592
667
|
+ comparison.renamed.indexes.length + comparison.renamed.enums.length
|
|
593
668
|
+ comparison.renamed.sequences.length + comparison.renamed.functions.length;
|
|
594
669
|
const totalAdded = sTablesAdded + sColsAdded + sIdxAdded + ddlAdded + renColAdded;
|
|
595
|
-
const totalModified = sTablesModified + sColsModified + ddlModified + renColModified;
|
|
670
|
+
const totalModified = sTablesModified + sColsModified + sIdxModified + ddlModified + renColModified;
|
|
596
671
|
const totalRemoved = sTablesRemoved + sColsRemoved + sIdxRemoved + ddlRemoved + renColRemoved;
|
|
597
672
|
const parts = [];
|
|
598
673
|
if (totalAdded > 0 || totalModified > 0 || totalRemoved > 0 || totalRenamed > 0) {
|
|
@@ -75,6 +75,24 @@ export async function loadSchemaFile(schemaPath, projectRoot) {
|
|
|
75
75
|
});
|
|
76
76
|
const schemaModule = await jiti.import(absolutePath);
|
|
77
77
|
const ast = schemaToAST(schemaModule);
|
|
78
|
+
const ext = path.extname(absolutePath);
|
|
79
|
+
const baseName = absolutePath.slice(0, -ext.length);
|
|
80
|
+
for (const suffix of ['functions', 'triggers', 'views']) {
|
|
81
|
+
const companionPath = `${baseName}.${suffix}${ext}`;
|
|
82
|
+
if (!fs.existsSync(companionPath))
|
|
83
|
+
continue;
|
|
84
|
+
const companionModule = await jiti.import(companionPath);
|
|
85
|
+
const companionAST = schemaToAST(companionModule);
|
|
86
|
+
ast.tables.push(...companionAST.tables);
|
|
87
|
+
ast.enums.push(...companionAST.enums);
|
|
88
|
+
ast.domains.push(...companionAST.domains);
|
|
89
|
+
ast.compositeTypes.push(...companionAST.compositeTypes);
|
|
90
|
+
ast.sequences.push(...companionAST.sequences);
|
|
91
|
+
ast.views.push(...companionAST.views);
|
|
92
|
+
ast.functions.push(...companionAST.functions);
|
|
93
|
+
ast.triggers.push(...companionAST.triggers);
|
|
94
|
+
ast.extensions.push(...companionAST.extensions);
|
|
95
|
+
}
|
|
78
96
|
const tables = ast.tables.map(parsedTableToTableInfo);
|
|
79
97
|
const schema = {
|
|
80
98
|
tables,
|
|
@@ -34,11 +34,32 @@ export function databaseSchemaToSnapshot(schema, database) {
|
|
|
34
34
|
for (const table of schema.tables) {
|
|
35
35
|
tables[table.name] = tableToSnapshot(table);
|
|
36
36
|
}
|
|
37
|
+
const functions = (schema.functions || []).map(f => ({
|
|
38
|
+
name: f.name,
|
|
39
|
+
schema: f.schema || 'public',
|
|
40
|
+
returnType: f.returnType,
|
|
41
|
+
argTypes: f.argTypes || [],
|
|
42
|
+
language: f.language,
|
|
43
|
+
definition: f.definition || '',
|
|
44
|
+
volatility: f.volatility || 'VOLATILE',
|
|
45
|
+
...(f.trackingId ? { trackingId: f.trackingId } : {}),
|
|
46
|
+
}));
|
|
47
|
+
const triggers = (schema.triggers || []).map(t => ({
|
|
48
|
+
name: t.name,
|
|
49
|
+
tableName: t.tableName,
|
|
50
|
+
event: t.event,
|
|
51
|
+
timing: t.timing,
|
|
52
|
+
forEach: t.forEach,
|
|
53
|
+
functionName: t.functionName,
|
|
54
|
+
...(t.trackingId ? { trackingId: t.trackingId } : {}),
|
|
55
|
+
}));
|
|
37
56
|
return {
|
|
38
57
|
version: SNAPSHOT_VERSION,
|
|
39
58
|
generatedAt: new Date().toISOString(),
|
|
40
59
|
database,
|
|
41
60
|
tables,
|
|
61
|
+
functions,
|
|
62
|
+
triggers,
|
|
42
63
|
appliedMigrations: [],
|
|
43
64
|
extensions: schema.extensions || [],
|
|
44
65
|
};
|
|
@@ -107,6 +128,17 @@ export function snapshotToDatabaseSchema(snapshot) {
|
|
|
107
128
|
for (const [, tableSnapshot] of Object.entries(snapshot.tables)) {
|
|
108
129
|
tables.push(snapshotToTable(tableSnapshot));
|
|
109
130
|
}
|
|
131
|
+
const functions = (snapshot.functions || []).map(f => ({
|
|
132
|
+
...f,
|
|
133
|
+
argTypes: f.argTypes || [],
|
|
134
|
+
isAggregate: false,
|
|
135
|
+
}));
|
|
136
|
+
const triggers = (snapshot.triggers || []).map(t => ({
|
|
137
|
+
...t,
|
|
138
|
+
forEach: (t.forEach || 'ROW'),
|
|
139
|
+
definition: '',
|
|
140
|
+
isEnabled: true,
|
|
141
|
+
}));
|
|
110
142
|
return {
|
|
111
143
|
tables,
|
|
112
144
|
enums: [],
|
|
@@ -114,8 +146,8 @@ export function snapshotToDatabaseSchema(snapshot) {
|
|
|
114
146
|
compositeTypes: [],
|
|
115
147
|
sequences: [],
|
|
116
148
|
collations: [],
|
|
117
|
-
functions
|
|
118
|
-
triggers
|
|
149
|
+
functions,
|
|
150
|
+
triggers,
|
|
119
151
|
policies: [],
|
|
120
152
|
partitions: [],
|
|
121
153
|
foreignServers: [],
|