millas 0.2.28 → 0.2.30
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/bin/millas.js +12 -2
- package/package.json +2 -1
- package/src/cli.js +117 -20
- package/src/commands/call.js +1 -1
- package/src/commands/createsuperuser.js +137 -182
- package/src/commands/key.js +61 -83
- package/src/commands/lang.js +423 -515
- package/src/commands/make.js +88 -62
- package/src/commands/migrate.js +200 -279
- package/src/commands/new.js +55 -50
- package/src/commands/route.js +78 -80
- package/src/commands/schedule.js +52 -150
- package/src/commands/serve.js +158 -191
- package/src/console/AppCommand.js +106 -0
- package/src/console/BaseCommand.js +726 -0
- package/src/console/CommandContext.js +66 -0
- package/src/console/CommandRegistry.js +88 -0
- package/src/console/Style.js +123 -0
- package/src/console/index.js +12 -3
- package/src/container/AppInitializer.js +10 -0
- package/src/facades/DB.js +195 -0
- package/src/index.js +2 -1
- package/src/scaffold/maker.js +102 -42
- package/src/schematics/Collection.js +28 -0
- package/src/schematics/SchematicEngine.js +122 -0
- package/src/schematics/Template.js +99 -0
- package/src/schematics/index.js +7 -0
- package/src/templates/command/default.template.js +14 -0
- package/src/templates/command/schema.json +19 -0
- package/src/templates/controller/default.template.js +10 -0
- package/src/templates/controller/resource.template.js +59 -0
- package/src/templates/controller/schema.json +30 -0
- package/src/templates/job/default.template.js +11 -0
- package/src/templates/job/schema.json +19 -0
- package/src/templates/middleware/default.template.js +11 -0
- package/src/templates/middleware/schema.json +19 -0
- package/src/templates/migration/default.template.js +14 -0
- package/src/templates/migration/schema.json +19 -0
- package/src/templates/model/default.template.js +14 -0
- package/src/templates/model/migration.template.js +17 -0
- package/src/templates/model/schema.json +30 -0
- package/src/templates/service/default.template.js +12 -0
- package/src/templates/service/schema.json +19 -0
- package/src/templates/shape/default.template.js +11 -0
- package/src/templates/shape/schema.json +19 -0
- package/src/validation/BaseValidator.js +3 -0
- package/src/validation/types.js +3 -3
package/src/commands/migrate.js
CHANGED
|
@@ -1,273 +1,186 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const BaseCommand = require('../console/BaseCommand');
|
|
6
|
+
const DB = require('../facades/DB');
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
class MigrateCommand extends BaseCommand {
|
|
9
|
+
static description = 'Database migration commands';
|
|
10
|
+
static namespace = 'db';
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const ctx = getProjectContext();
|
|
18
|
-
const Mk = require('../orm/migration/Makemigrations');
|
|
19
|
-
const mk = new Mk(ctx.modelsPath, ctx.appMigPath, ctx.systemMigPath, {
|
|
20
|
-
nonInteractive: options.noinput || false,
|
|
12
|
+
async onInit(register) {
|
|
13
|
+
// makemigrations
|
|
14
|
+
register
|
|
15
|
+
.command(async (dryRun, noinput) => {
|
|
16
|
+
const ctx = this.getProjectContext();
|
|
17
|
+
const Mk = require('../orm/migration/Makemigrations');
|
|
18
|
+
const mk = new Mk(ctx.modelsPath, ctx.appMigPath, ctx.systemMigPath, {
|
|
19
|
+
nonInteractive: noinput || false,
|
|
21
20
|
});
|
|
22
|
-
const result = await mk.run({ dryRun
|
|
21
|
+
const result = await mk.run({ dryRun });
|
|
23
22
|
|
|
24
23
|
if (result.files.length === 0) {
|
|
25
|
-
|
|
24
|
+
this.warn('No changes detected.');
|
|
26
25
|
} else {
|
|
27
|
-
if (
|
|
28
|
-
|
|
26
|
+
if (dryRun) {
|
|
27
|
+
this.info('\nWould generate:');
|
|
29
28
|
} else {
|
|
30
|
-
|
|
29
|
+
this.success('Migrations generated:');
|
|
31
30
|
}
|
|
32
|
-
result.files.forEach(f =>
|
|
33
|
-
result.ops.forEach(op =>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
switch (op.type) {
|
|
37
|
-
case 'CreateModel': {
|
|
38
|
-
const idxLines = [];
|
|
39
|
-
for (const idx of (op.indexes || [])) {
|
|
40
|
-
const l = idx.name
|
|
41
|
-
? `${idx.name} on ${op.table}`
|
|
42
|
-
: `on field(s) ${idx.fields.join(', ')} of model ${op.table}`;
|
|
43
|
-
idxLines.push(` ${chalk.green('+')} Create index ${l}`);
|
|
44
|
-
}
|
|
45
|
-
for (const ut of (op.uniqueTogether || [])) {
|
|
46
|
-
idxLines.push(` ${chalk.green('+')} Create constraint on ${op.table} (${ut.join(', ')})`);
|
|
47
|
-
}
|
|
48
|
-
prefix = chalk.green('+'); label = `Create model ${op.table}`;
|
|
49
|
-
console.log(chalk.gray(` ${prefix} ${label}`));
|
|
50
|
-
idxLines.forEach(l => console.log(chalk.gray(l)));
|
|
51
|
-
return; // return from forEach callback
|
|
52
|
-
}
|
|
53
|
-
case 'DeleteModel':
|
|
54
|
-
prefix = chalk.red('-'); label = `Delete model ${op.table}`; break;
|
|
55
|
-
case 'AddField':
|
|
56
|
-
prefix = chalk.green('+'); label = `Add field ${op.column} to ${op.table}`; break;
|
|
57
|
-
case 'RemoveField':
|
|
58
|
-
prefix = chalk.red('-'); label = `Remove field ${op.column} from ${op.table}`; break;
|
|
59
|
-
case 'AlterField':
|
|
60
|
-
prefix = chalk.yellow('~'); label = `Alter field ${op.column} on ${op.table}`; break;
|
|
61
|
-
case 'RenameField':
|
|
62
|
-
prefix = chalk.yellow('~'); label = `Rename field ${op.oldColumn} on ${op.table} to ${op.newColumn}`; break;
|
|
63
|
-
case 'RenameModel':
|
|
64
|
-
prefix = chalk.yellow('~'); label = `Rename model ${op.oldTable} to ${op.newTable}`; break;
|
|
65
|
-
case 'AddIndex': {
|
|
66
|
-
const idx = op.index;
|
|
67
|
-
const idxLabel = idx.name
|
|
68
|
-
? `${idx.name} on ${op.table}`
|
|
69
|
-
: `on field(s) ${idx.fields.join(', ')} of model ${op.table}`;
|
|
70
|
-
prefix = chalk.green('+'); label = `Create index ${idxLabel}`; break;
|
|
71
|
-
}
|
|
72
|
-
case 'RemoveIndex': {
|
|
73
|
-
const idx = op.index;
|
|
74
|
-
const idxLabel = idx.name
|
|
75
|
-
? `${idx.name} from ${op.table}`
|
|
76
|
-
: `on field(s) ${idx.fields.join(', ')} of model ${op.table}`;
|
|
77
|
-
prefix = chalk.red('-'); label = `Remove index ${idxLabel}`; break;
|
|
78
|
-
}
|
|
79
|
-
case 'RenameIndex':
|
|
80
|
-
prefix = chalk.yellow('~'); label = `Rename index ${op.oldName} on ${op.table} to ${op.newName}`; break;
|
|
81
|
-
case 'AlterUniqueTogether':
|
|
82
|
-
prefix = chalk.yellow('~'); label = `Alter unique_together on ${op.table}`; break;
|
|
83
|
-
default:
|
|
84
|
-
prefix = chalk.gray(' '); label = op.type;
|
|
85
|
-
}
|
|
86
|
-
console.log(chalk.gray(` ${prefix} ${label}`));
|
|
87
|
-
});
|
|
88
|
-
if (!options.dryRun) {
|
|
89
|
-
console.log(chalk.gray('\n Run: millas migrate to apply.\n'));
|
|
90
|
-
} else {
|
|
91
|
-
console.log();
|
|
31
|
+
result.files.forEach(f => this.info(` + ${f}`));
|
|
32
|
+
result.ops.forEach(op => this.printOperation(op));
|
|
33
|
+
if (!dryRun) {
|
|
34
|
+
this.info('\nRun: millas migrate to apply.\n');
|
|
92
35
|
}
|
|
93
36
|
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
37
|
+
})
|
|
38
|
+
.name('makemigrations')
|
|
39
|
+
.bool('dry-run', 'Show what would be generated without writing files')
|
|
40
|
+
.bool('noinput', 'Non-interactive mode — fails if dangerous fields need resolution')
|
|
41
|
+
.description('Detect model changes and generate migration files (never touches DB)');
|
|
98
42
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
43
|
+
// migrate
|
|
44
|
+
register
|
|
45
|
+
.command(async (fakeAll, fake) => {
|
|
46
|
+
const runner = await this.getRunner();
|
|
47
|
+
|
|
48
|
+
if (fakeAll === true) {
|
|
49
|
+
const pending = await runner.plan();
|
|
50
|
+
if (pending.length === 0) {
|
|
51
|
+
this.warn('No pending migrations to fake.');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (const mig of pending) {
|
|
56
|
+
await runner.fake(mig.source, mig.name);
|
|
57
|
+
this.success(`Marked "${mig.key}" as applied (fake).`);
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
107
61
|
|
|
108
|
-
if (
|
|
109
|
-
const [source, name] =
|
|
110
|
-
? options.fake.split(':')
|
|
111
|
-
: ['app', options.fake];
|
|
62
|
+
if (fake) {
|
|
63
|
+
const [source, name] = fake.includes(':') ? fake.split(':') : ['app', fake];
|
|
112
64
|
const result = await runner.fake(source, name);
|
|
113
|
-
|
|
65
|
+
this.success(`Marked "${result.key}" as applied (fake).`);
|
|
114
66
|
return;
|
|
115
67
|
}
|
|
116
68
|
|
|
117
69
|
const result = await runner.migrate();
|
|
118
|
-
printResult(result.ran, 'Applying');
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
70
|
+
this.printResult(result.ran, 'Applying');
|
|
71
|
+
})
|
|
72
|
+
.name('migrate')
|
|
73
|
+
.bool('fake-all', 'Mark all pending migrations as applied without running them')
|
|
74
|
+
.str('--fake', v => v.optional(), 'Mark a migration as applied without running it')
|
|
75
|
+
.description('Apply pending migrations in dependency order (never generates migrations)')
|
|
76
|
+
.after(async () => await DB.closeAll());
|
|
125
77
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
.action(async () => {
|
|
131
|
-
try {
|
|
132
|
-
const runner = await getRunner();
|
|
78
|
+
// migrate:plan
|
|
79
|
+
register
|
|
80
|
+
.command(async () => {
|
|
81
|
+
const runner = await this.getRunner();
|
|
133
82
|
const pending = await runner.plan();
|
|
134
83
|
|
|
135
84
|
if (pending.length === 0) {
|
|
136
|
-
|
|
85
|
+
this.warn('Nothing to migrate.');
|
|
137
86
|
return;
|
|
138
87
|
}
|
|
139
88
|
|
|
140
|
-
|
|
89
|
+
this.info('\nMigration plan:\n');
|
|
141
90
|
pending.forEach(p => {
|
|
142
|
-
const
|
|
143
|
-
|
|
91
|
+
const prefix = p.source === 'system' ? ' [system]' : ' ';
|
|
92
|
+
this.info(`${prefix} ${p.key}`);
|
|
144
93
|
});
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
await closeDb();
|
|
150
|
-
}
|
|
151
|
-
});
|
|
94
|
+
})
|
|
95
|
+
.name('plan')
|
|
96
|
+
.description('Preview which migrations would run without applying them')
|
|
97
|
+
.after(async () => await DB.closeAll());
|
|
152
98
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
const runner = await getRunner();
|
|
160
|
-
const rows = await runner.status();
|
|
99
|
+
// migrate:status
|
|
100
|
+
register
|
|
101
|
+
.command(async () => {
|
|
102
|
+
const runner = await this.getRunner();
|
|
103
|
+
const rows = await runner.status();
|
|
161
104
|
|
|
162
105
|
if (rows.length === 0) {
|
|
163
|
-
|
|
106
|
+
this.warn('No migrations found.');
|
|
164
107
|
return;
|
|
165
108
|
}
|
|
166
109
|
|
|
167
110
|
const colW = Math.max(...rows.map(r => r.key.length)) + 2;
|
|
168
|
-
|
|
169
|
-
|
|
111
|
+
this.info(`\n${'Migration'.padEnd(colW)} ${'Status'.padEnd(10)} Batch`);
|
|
112
|
+
this.info('─'.repeat(colW + 20));
|
|
170
113
|
|
|
171
114
|
let lastSource = null;
|
|
172
115
|
for (const row of rows) {
|
|
173
116
|
if (row.source !== lastSource) {
|
|
174
|
-
if (lastSource !== null)
|
|
117
|
+
if (lastSource !== null) this.info('');
|
|
175
118
|
lastSource = row.source;
|
|
176
119
|
}
|
|
177
|
-
const status = row.status
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const label = row.source === 'system'
|
|
182
|
-
? chalk.gray(row.key.padEnd(colW))
|
|
183
|
-
: chalk.cyan(row.key.padEnd(colW));
|
|
184
|
-
console.log(` ${label} ${status} ${batch}`);
|
|
120
|
+
const status = row.status.padEnd(10);
|
|
121
|
+
const batch = row.batch ? String(row.batch) : '—';
|
|
122
|
+
const prefix = row.source === 'system' ? '[system]' : '';
|
|
123
|
+
this.info(`${row.key.padEnd(colW)} ${status} ${batch} ${prefix}`);
|
|
185
124
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
await closeDb();
|
|
191
|
-
}
|
|
192
|
-
});
|
|
125
|
+
})
|
|
126
|
+
.name('status')
|
|
127
|
+
.description('Show the status of all migrations')
|
|
128
|
+
.after(async () => await DB.closeAll());
|
|
193
129
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
bail('migrate:rollback', err);
|
|
206
|
-
} finally {
|
|
207
|
-
await closeDb();
|
|
208
|
-
}
|
|
209
|
-
});
|
|
130
|
+
// migrate:rollback
|
|
131
|
+
register
|
|
132
|
+
.command(async (steps) => {
|
|
133
|
+
const runner = await this.getRunner();
|
|
134
|
+
const result = await runner.rollback(Number(steps));
|
|
135
|
+
this.printResult(result.rolledBack, 'Reverting');
|
|
136
|
+
})
|
|
137
|
+
.name('rollback')
|
|
138
|
+
.num('--steps', v => v.optional().default(1), 'Number of batches to rollback')
|
|
139
|
+
.description('Rollback the last batch of migrations')
|
|
140
|
+
.after(async () => await DB.closeAll());
|
|
210
141
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
try {
|
|
217
|
-
console.log(chalk.yellow('\n ⚠ Dropping all tables…\n'));
|
|
218
|
-
const runner = await getRunner();
|
|
142
|
+
// migrate:fresh
|
|
143
|
+
register
|
|
144
|
+
.command(async () => {
|
|
145
|
+
this.warn('⚠ Dropping all tables…');
|
|
146
|
+
const runner = await this.getRunner();
|
|
219
147
|
const result = await runner.fresh();
|
|
220
|
-
printResult(result.ran, 'Applying');
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
});
|
|
148
|
+
this.printResult(result.ran, 'Applying');
|
|
149
|
+
})
|
|
150
|
+
.name('fresh')
|
|
151
|
+
.description('Drop all tables and re-run every migration from scratch')
|
|
152
|
+
.after(async () => await DB.closeAll());
|
|
227
153
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
.action(async () => {
|
|
233
|
-
try {
|
|
234
|
-
const runner = await getRunner();
|
|
154
|
+
// migrate:reset
|
|
155
|
+
register
|
|
156
|
+
.command(async () => {
|
|
157
|
+
const runner = await this.getRunner();
|
|
235
158
|
const result = await runner.reset();
|
|
236
|
-
printResult(result.rolledBack, 'Reverting');
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
});
|
|
159
|
+
this.printResult(result.rolledBack, 'Reverting');
|
|
160
|
+
})
|
|
161
|
+
.name('reset')
|
|
162
|
+
.description('Rollback ALL migrations')
|
|
163
|
+
.after(async () => await DB.closeAll());
|
|
243
164
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
.action(async () => {
|
|
249
|
-
try {
|
|
250
|
-
const runner = await getRunner();
|
|
165
|
+
// migrate:refresh
|
|
166
|
+
register
|
|
167
|
+
.command(async () => {
|
|
168
|
+
const runner = await this.getRunner();
|
|
251
169
|
const result = await runner.refresh();
|
|
252
|
-
printResult(result.ran, 'Applying');
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
});
|
|
170
|
+
this.printResult(result.ran, 'Applying');
|
|
171
|
+
})
|
|
172
|
+
.name('refresh')
|
|
173
|
+
.description('Rollback all then re-run all migrations')
|
|
174
|
+
.after(async () => await DB.closeAll());
|
|
259
175
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
.action(async () => {
|
|
265
|
-
try {
|
|
266
|
-
const ctx = getProjectContext();
|
|
176
|
+
// db:seed
|
|
177
|
+
register
|
|
178
|
+
.command(async () => {
|
|
179
|
+
const ctx = this.getProjectContext();
|
|
267
180
|
const seedersDir = ctx.seedersPath;
|
|
268
181
|
|
|
269
182
|
if (!fs.existsSync(seedersDir)) {
|
|
270
|
-
|
|
183
|
+
this.warn('No seeders directory found.');
|
|
271
184
|
return;
|
|
272
185
|
}
|
|
273
186
|
|
|
@@ -276,80 +189,88 @@ module.exports = function (program) {
|
|
|
276
189
|
.sort();
|
|
277
190
|
|
|
278
191
|
if (files.length === 0) {
|
|
279
|
-
|
|
192
|
+
this.warn('No seeder files found.');
|
|
280
193
|
return;
|
|
281
194
|
}
|
|
282
195
|
|
|
283
|
-
const db =
|
|
284
|
-
console.log();
|
|
196
|
+
const db = DB.connection();
|
|
285
197
|
for (const file of files) {
|
|
286
198
|
const seeder = require(path.join(seedersDir, file));
|
|
287
199
|
await seeder.run(db);
|
|
288
|
-
|
|
200
|
+
this.success(`Seeded: ${file}`);
|
|
289
201
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
await closeDb();
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
300
|
-
|
|
301
|
-
function getProjectContext() {
|
|
302
|
-
const cwd = process.cwd();
|
|
303
|
-
return {
|
|
304
|
-
appMigPath: path.join(cwd, 'database/migrations'),
|
|
305
|
-
systemMigPath: path.join(__dirname, '../migrations/system'),
|
|
306
|
-
seedersPath: path.join(cwd, 'database/seeders'),
|
|
307
|
-
modelsPath: path.join(cwd, 'app/models'),
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
async function getDbConnection() {
|
|
312
|
-
const configPath = path.join(process.cwd(), 'config/database');
|
|
313
|
-
if (!fs.existsSync(configPath + '.js')) {
|
|
314
|
-
throw new Error('config/database.js not found. Are you inside a Millas project?');
|
|
202
|
+
})
|
|
203
|
+
.name('seed')
|
|
204
|
+
.description('Run all database seeders')
|
|
205
|
+
.after(async () => await DB.closeAll());
|
|
315
206
|
}
|
|
316
|
-
const config = require(configPath);
|
|
317
|
-
const DatabaseManager = require('../orm/drivers/DatabaseManager');
|
|
318
|
-
DatabaseManager.configure(config);
|
|
319
|
-
return DatabaseManager.connection();
|
|
320
|
-
}
|
|
321
207
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
208
|
+
getProjectContext() {
|
|
209
|
+
return {
|
|
210
|
+
appMigPath: path.join(this.cwd, 'database/migrations'),
|
|
211
|
+
systemMigPath: path.join(__dirname, '../migrations/system'),
|
|
212
|
+
seedersPath: path.join(this.cwd, 'database/seeders'),
|
|
213
|
+
modelsPath: path.join(this.cwd, 'app/models'),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
328
216
|
|
|
329
|
-
async
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
217
|
+
async getRunner() {
|
|
218
|
+
const MigrationRunner = require('../orm/migration/MigrationRunner');
|
|
219
|
+
const ctx = this.getProjectContext();
|
|
220
|
+
const db = DB.connection();
|
|
221
|
+
return new MigrationRunner(db, ctx.appMigPath, ctx.systemMigPath);
|
|
222
|
+
}
|
|
335
223
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
224
|
+
printOperation(op) {
|
|
225
|
+
let prefix, label;
|
|
226
|
+
switch (op.type) {
|
|
227
|
+
case 'CreateModel': {
|
|
228
|
+
this.info(` + Create model ${op.table}`);
|
|
229
|
+
for (const idx of (op.indexes || [])) {
|
|
230
|
+
const l = idx.name ? `${idx.name} on ${op.table}` : `on field(s) ${idx.fields.join(', ')} of model ${op.table}`;
|
|
231
|
+
this.info(` + Create index ${l}`);
|
|
232
|
+
}
|
|
233
|
+
for (const ut of (op.uniqueTogether || [])) {
|
|
234
|
+
this.info(` + Create constraint on ${op.table} (${ut.join(', ')})`);
|
|
235
|
+
}
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
case 'DeleteModel': prefix = '-'; label = `Delete model ${op.table}`; break;
|
|
239
|
+
case 'AddField': prefix = '+'; label = `Add field ${op.column} to ${op.table}`; break;
|
|
240
|
+
case 'RemoveField': prefix = '-'; label = `Remove field ${op.column} from ${op.table}`; break;
|
|
241
|
+
case 'AlterField': prefix = '~'; label = `Alter field ${op.column} on ${op.table}`; break;
|
|
242
|
+
case 'RenameField': prefix = '~'; label = `Rename field ${op.oldColumn} on ${op.table} to ${op.newColumn}`; break;
|
|
243
|
+
case 'RenameModel': prefix = '~'; label = `Rename model ${op.oldTable} to ${op.newTable}`; break;
|
|
244
|
+
case 'AddIndex': {
|
|
245
|
+
const idx = op.index;
|
|
246
|
+
const idxLabel = idx.name ? `${idx.name} on ${op.table}` : `on field(s) ${idx.fields.join(', ')} of model ${op.table}`;
|
|
247
|
+
prefix = '+'; label = `Create index ${idxLabel}`; break;
|
|
248
|
+
}
|
|
249
|
+
case 'RemoveIndex': {
|
|
250
|
+
const idx = op.index;
|
|
251
|
+
const idxLabel = idx.name ? `${idx.name} from ${op.table}` : `on field(s) ${idx.fields.join(', ')} of model ${op.table}`;
|
|
252
|
+
prefix = '-'; label = `Remove index ${idxLabel}`; break;
|
|
253
|
+
}
|
|
254
|
+
case 'RenameIndex': prefix = '~'; label = `Rename index ${op.oldName} on ${op.table} to ${op.newName}`; break;
|
|
255
|
+
case 'AlterUniqueTogether': prefix = '~'; label = `Alter unique_together on ${op.table}`; break;
|
|
256
|
+
default: prefix = ' '; label = op.type;
|
|
257
|
+
}
|
|
258
|
+
this.info(` ${prefix} ${label}`);
|
|
340
259
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
260
|
+
|
|
261
|
+
printResult(list, verb) {
|
|
262
|
+
if (!list || list.length === 0) {
|
|
263
|
+
this.warn('Nothing to do.');
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
this.success('Running migrations:');
|
|
267
|
+
for (const entry of list) {
|
|
268
|
+
const label = typeof entry === 'object' ? entry.label || entry.key : entry;
|
|
269
|
+
const source = typeof entry === 'object' ? entry.source : null;
|
|
270
|
+
const prefix = source === 'system' ? '[system]' : '';
|
|
271
|
+
this.info(` ${verb} ${label}... OK ${prefix}`);
|
|
272
|
+
}
|
|
347
273
|
}
|
|
348
|
-
console.log();
|
|
349
274
|
}
|
|
350
275
|
|
|
351
|
-
|
|
352
|
-
console.error(chalk.red(`\n ✖ ${cmd} failed: ${err.message}\n`));
|
|
353
|
-
if (process.env.DEBUG) console.error(err.stack);
|
|
354
|
-
closeDb().finally(() => process.exit(1));
|
|
355
|
-
}
|
|
276
|
+
module.exports = MigrateCommand;
|