@axiosleo/orm-mysql 0.9.6 → 0.9.8
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/orm-mysql.js +1 -1
- package/examples/migration/1706764048.init.js +8 -18
- package/index.d.ts +16 -3
- package/package.json +1 -1
- package/src/builder.js +37 -21
- package/src/migration.js +4 -4
- package/src/query.js +37 -29
package/bin/orm-mysql.js
CHANGED
|
@@ -69,10 +69,18 @@ function up(migration) {
|
|
|
69
69
|
account_id: {
|
|
70
70
|
type: 'int',
|
|
71
71
|
allowNull: false,
|
|
72
|
+
references: {
|
|
73
|
+
table: 'account',
|
|
74
|
+
column: 'id'
|
|
75
|
+
}
|
|
72
76
|
},
|
|
73
77
|
org_id: {
|
|
74
78
|
type: 'int',
|
|
75
79
|
allowNull: false,
|
|
80
|
+
references: {
|
|
81
|
+
table: 'orgs',
|
|
82
|
+
column: 'id'
|
|
83
|
+
}
|
|
76
84
|
},
|
|
77
85
|
type: {
|
|
78
86
|
type: 'varchar',
|
|
@@ -83,24 +91,6 @@ function up(migration) {
|
|
|
83
91
|
}
|
|
84
92
|
});
|
|
85
93
|
migration.createColumn('created_at', 'TIMESTAMP', 'account_orgs');
|
|
86
|
-
migration.createForeignKey({
|
|
87
|
-
tableName: 'account_orgs',
|
|
88
|
-
columnName: 'account_id',
|
|
89
|
-
reference: {
|
|
90
|
-
tableName: 'account',
|
|
91
|
-
columnName: 'id',
|
|
92
|
-
onDelete: 'CASCADE'
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
migration.createForeignKey({
|
|
96
|
-
tableName: 'account_orgs',
|
|
97
|
-
columnName: 'org_id',
|
|
98
|
-
reference: {
|
|
99
|
-
tableName: 'orgs',
|
|
100
|
-
columnName: 'id',
|
|
101
|
-
onDelete: 'CASCADE'
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
94
|
}
|
|
105
95
|
|
|
106
96
|
/**
|
package/index.d.ts
CHANGED
|
@@ -38,13 +38,14 @@ export interface OrderByOptions {
|
|
|
38
38
|
|
|
39
39
|
export type OperatorType = 'select' | 'find' | 'insert' | 'update' | 'delete' | 'count';
|
|
40
40
|
export type CascadeType = 'RESTRICT' | 'CASCADE' | 'SET NULL' | 'NO ACTION' | 'restrict' | 'cascade' | 'set null' | 'no action';
|
|
41
|
+
export type JoinType = 'left' | 'right' | 'inner' | 'LEFT' | 'RIGHT' | 'INNER';
|
|
41
42
|
|
|
42
43
|
export interface JoinOption {
|
|
43
44
|
table: string | Query;
|
|
44
45
|
table_alias?: string;
|
|
45
46
|
self_column?: string;
|
|
46
47
|
foreign_column?: string;
|
|
47
|
-
join_type?:
|
|
48
|
+
join_type?: JoinType;
|
|
48
49
|
on?: string;
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -113,6 +114,12 @@ export declare class Query {
|
|
|
113
114
|
set(data: any): this;
|
|
114
115
|
|
|
115
116
|
join(opt: JoinOption): this;
|
|
117
|
+
|
|
118
|
+
leftJoin(table: string, on: string, options?: { alias?: string }): this;
|
|
119
|
+
|
|
120
|
+
rightJoin(table: string, on: string, options?: { alias?: string }): this;
|
|
121
|
+
|
|
122
|
+
innerJoin(table: string, on: string, options?: { alias?: string }): this;
|
|
116
123
|
}
|
|
117
124
|
|
|
118
125
|
export type QueryResult = any | undefined | RowDataPacket[] | RowDataPacket | MySQLQueryResult;
|
|
@@ -304,7 +311,13 @@ interface ColumnItem {
|
|
|
304
311
|
comment?: string,
|
|
305
312
|
autoIncrement?: boolean,
|
|
306
313
|
primaryKey?: boolean,
|
|
307
|
-
uniqIndex?: boolean
|
|
314
|
+
uniqIndex?: boolean,
|
|
315
|
+
references?: {
|
|
316
|
+
table: string,
|
|
317
|
+
column: string,
|
|
318
|
+
onDelete?: CascadeType,
|
|
319
|
+
onUpdate?: CascadeType
|
|
320
|
+
}
|
|
308
321
|
}
|
|
309
322
|
|
|
310
323
|
interface CreateColumnOptions {
|
|
@@ -352,7 +365,7 @@ export declare class MigrationInterface {
|
|
|
352
365
|
autoIncrement?: boolean,
|
|
353
366
|
primaryKey?: boolean,
|
|
354
367
|
uniqIndex?: boolean,
|
|
355
|
-
after?: string
|
|
368
|
+
after?: string,
|
|
356
369
|
}): void;
|
|
357
370
|
|
|
358
371
|
createIndex(tableName: string, columns: string[], options?: {
|
package/package.json
CHANGED
package/src/builder.js
CHANGED
|
@@ -98,11 +98,7 @@ class Builder {
|
|
|
98
98
|
break;
|
|
99
99
|
}
|
|
100
100
|
case 'count': {
|
|
101
|
-
|
|
102
|
-
if (!is.empty(options.attrs)) {
|
|
103
|
-
fieldName = this._buildFieldKey(options.attrs[0]);
|
|
104
|
-
}
|
|
105
|
-
emit(tmp, `SELECT COUNT(*) AS ${fieldName} FROM ${this._buildTables(options.tables)}`);
|
|
101
|
+
emit(tmp, `SELECT COUNT(*) AS count FROM ${this._buildTables(options.tables)}`);
|
|
106
102
|
emit(tmp, this._buildJoins(options.joins));
|
|
107
103
|
emit(tmp, this._buildCondition(options.conditions));
|
|
108
104
|
if (options.having && options.having.length && !options.groupField.length) {
|
|
@@ -154,6 +150,7 @@ class Builder {
|
|
|
154
150
|
table = `\`${table}\``;
|
|
155
151
|
}
|
|
156
152
|
let sql = '';
|
|
153
|
+
join_type = join_type.toLowerCase();
|
|
157
154
|
switch (join_type) {
|
|
158
155
|
case 'left':
|
|
159
156
|
sql = 'LEFT JOIN ';
|
|
@@ -384,26 +381,15 @@ class ManageSQLBuilder extends Builder {
|
|
|
384
381
|
engine: 'InnoDB',
|
|
385
382
|
charset: 'utf8mb4'
|
|
386
383
|
}, options, {
|
|
387
|
-
columns: this.createColumns(columns)
|
|
384
|
+
columns: this.createColumns(columns, options.name)
|
|
388
385
|
});
|
|
389
386
|
return _render('CREATE TABLE `${name}` ( ${columns} ) ENGINE=${engine} DEFAULT CHARSET=${charset}', options);
|
|
390
387
|
}
|
|
391
388
|
|
|
392
389
|
createColumn(options) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
type: 'required|string',
|
|
397
|
-
length: 'integer',
|
|
398
|
-
unsigned: 'boolean',
|
|
399
|
-
allowNull: 'boolean',
|
|
400
|
-
default: 'string',
|
|
401
|
-
comment: 'string',
|
|
402
|
-
autoIncrement: 'boolean',
|
|
403
|
-
primaryKey: 'boolean',
|
|
404
|
-
uniqIndex: 'boolean',
|
|
405
|
-
after: 'string'
|
|
406
|
-
});
|
|
390
|
+
if (!options.table) {
|
|
391
|
+
throw new Error('Table name is required');
|
|
392
|
+
}
|
|
407
393
|
return `ALTER TABLE \`${options.table}\` ADD COLUMN ` + this.renderSingleColumn(options);
|
|
408
394
|
}
|
|
409
395
|
|
|
@@ -434,6 +420,8 @@ class ManageSQLBuilder extends Builder {
|
|
|
434
420
|
}
|
|
435
421
|
|
|
436
422
|
createForeignKey(options) {
|
|
423
|
+
options.reference.onDelete = options.reference.onDelete ? options.reference.onDelete.toUpperCase() : 'NO ACTION';
|
|
424
|
+
options.reference.onUpdate = options.reference.onUpdate ? options.reference.onUpdate.toUpperCase() : 'NO ACTION';
|
|
437
425
|
_validate(options, {
|
|
438
426
|
name: 'required|string',
|
|
439
427
|
table: 'required|string',
|
|
@@ -486,9 +474,10 @@ class ManageSQLBuilder extends Builder {
|
|
|
486
474
|
return _render('ALTER TABLE `${table}` DROP FOREIGN KEY `${name}`', options);
|
|
487
475
|
}
|
|
488
476
|
|
|
489
|
-
createColumns(columns) {
|
|
477
|
+
createColumns(columns, table) {
|
|
490
478
|
let primaryColumn = null;
|
|
491
479
|
let indexColumns = [];
|
|
480
|
+
let referenceColumns = [];
|
|
492
481
|
let strs = columns.map(column => {
|
|
493
482
|
let str = this.renderSingleColumn(column);
|
|
494
483
|
if (column.primaryKey === true) {
|
|
@@ -496,6 +485,28 @@ class ManageSQLBuilder extends Builder {
|
|
|
496
485
|
} else if (column.uniqIndex === true) {
|
|
497
486
|
indexColumns.push(column);
|
|
498
487
|
}
|
|
488
|
+
if (column.reference) {
|
|
489
|
+
column.reference.onDelete = column.reference.onDelete ? column.reference.onDelete.toUpperCase() : 'NO ACTION';
|
|
490
|
+
column.reference.onUpdate = column.reference.onUpdate ? column.reference.onUpdate.toUpperCase() : 'NO ACTION';
|
|
491
|
+
|
|
492
|
+
_validate(column.reference, {
|
|
493
|
+
table: 'required|string',
|
|
494
|
+
column: 'required|string',
|
|
495
|
+
onDelete: [{ in: ['RESTRICT', 'CASCADE', 'SET NULL', 'NO ACTION'] }],
|
|
496
|
+
onUpdate: [{ in: ['RESTRICT', 'CASCADE', 'SET NULL', 'NO ACTION'] }]
|
|
497
|
+
});
|
|
498
|
+
referenceColumns.push({
|
|
499
|
+
name: 'fk_' + table + '_' + column.name,
|
|
500
|
+
table,
|
|
501
|
+
column: column.name,
|
|
502
|
+
reference: {
|
|
503
|
+
tableName: column.reference.table,
|
|
504
|
+
columnName: column.reference.column,
|
|
505
|
+
onDelete: column.reference.onDelete,
|
|
506
|
+
onUpdate: column.reference.onUpdate
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
}
|
|
499
510
|
return str;
|
|
500
511
|
});
|
|
501
512
|
if (primaryColumn) {
|
|
@@ -507,6 +518,11 @@ class ManageSQLBuilder extends Builder {
|
|
|
507
518
|
strs.push(`UNIQUE INDEX \`${i.name}\` (\`${i.name}\` ASC) VISIBLE`);
|
|
508
519
|
});
|
|
509
520
|
}
|
|
521
|
+
if (referenceColumns.length) {
|
|
522
|
+
referenceColumns.forEach((r) => {
|
|
523
|
+
strs.push(this.createForeignKey(r));
|
|
524
|
+
});
|
|
525
|
+
}
|
|
510
526
|
return strs.join(', ');
|
|
511
527
|
}
|
|
512
528
|
|
package/src/migration.js
CHANGED
|
@@ -114,16 +114,16 @@ async function _exec(context, queries) {
|
|
|
114
114
|
try {
|
|
115
115
|
const files = Object.keys(queries);
|
|
116
116
|
await _foreach(files, async (file) => {
|
|
117
|
-
const
|
|
117
|
+
const hasMigrated = await transaction.table(context.task_key)
|
|
118
118
|
.where('migration_key', context.task_key)
|
|
119
119
|
.where('filename', file)
|
|
120
120
|
.count();
|
|
121
|
-
if (context.action === 'up' &&
|
|
122
|
-
if (
|
|
121
|
+
if (context.action === 'up' && hasMigrated) {
|
|
122
|
+
if (hasMigrated) {
|
|
123
123
|
printer.yellow(`Migration file "${file}" has been migrated.`).println();
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
|
-
} else if (context.action === 'down' && !
|
|
126
|
+
} else if (context.action === 'down' && !hasMigrated) {
|
|
127
127
|
return;
|
|
128
128
|
}
|
|
129
129
|
|
package/src/query.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { _assign } = require('@axiosleo/cli-tool/src/helper/obj');
|
|
4
|
+
const { _validate } = require('./utils');
|
|
5
|
+
const is = require('@axiosleo/cli-tool/src/helper/is');
|
|
6
|
+
|
|
7
|
+
function joinOn(table, on, options = {}) {
|
|
8
|
+
let o = _assign({ alias: null, join_type: 'INNER', table, on }, options);
|
|
9
|
+
if (!table) {
|
|
10
|
+
throw new Error('table is required');
|
|
11
|
+
}
|
|
12
|
+
if (!on) {
|
|
13
|
+
throw new Error('on is required');
|
|
14
|
+
}
|
|
15
|
+
this.options.joins.push(o);
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
|
|
3
19
|
class Query {
|
|
4
20
|
constructor(operator = 'select', alias = null) {
|
|
5
21
|
this.options = {
|
|
@@ -109,6 +125,10 @@ class Query {
|
|
|
109
125
|
}
|
|
110
126
|
|
|
111
127
|
attr(...attr) {
|
|
128
|
+
if (attr.length === 1 && is.array(attr)) {
|
|
129
|
+
this.options.attrs = attr;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
112
132
|
if (!attr.length) {
|
|
113
133
|
return this;
|
|
114
134
|
}
|
|
@@ -164,44 +184,32 @@ class Query {
|
|
|
164
184
|
* @returns
|
|
165
185
|
*/
|
|
166
186
|
join(opt = {}) {
|
|
187
|
+
let types = ['left', 'right', 'inner'];
|
|
188
|
+
opt.join_type = opt.join_type ? opt.join_type.toLowerCase() : 'inner';
|
|
189
|
+
if (types.indexOf(opt.join_type) === -1) {
|
|
190
|
+
throw new Error('Invalid join type : ' + opt.join_type + '; only supported ' + types.join(', '));
|
|
191
|
+
}
|
|
192
|
+
_validate(opt, {
|
|
193
|
+
table: 'required',
|
|
194
|
+
self_column: 'required',
|
|
195
|
+
foreign_column: 'required_if:on',
|
|
196
|
+
join_type: [{ in: types }]
|
|
197
|
+
});
|
|
167
198
|
let { table, table_alias, self_column, foreign_column, join_type } = opt;
|
|
168
|
-
if (!table) {
|
|
169
|
-
throw new Error('table is required');
|
|
170
|
-
}
|
|
171
|
-
if (!self_column) {
|
|
172
|
-
throw new Error('self_column is required');
|
|
173
|
-
}
|
|
174
|
-
if (!foreign_column) {
|
|
175
|
-
throw new Error('foreign_column is required');
|
|
176
|
-
}
|
|
177
|
-
if (join_type && ['left', 'right', 'inner'].indexOf(join_type) === -1) {
|
|
178
|
-
throw new Error('Invalid join type : ' + join_type + '; only supported left, right, inner');
|
|
179
|
-
}
|
|
180
199
|
this.options.joins.push({ table, alias: table_alias, self_column, foreign_column, join_type });
|
|
181
200
|
return this;
|
|
182
201
|
}
|
|
183
202
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
throw new Error('table is required');
|
|
187
|
-
}
|
|
188
|
-
if (!on) {
|
|
189
|
-
throw new Error('on is required');
|
|
190
|
-
}
|
|
191
|
-
this.options.joins.push({ table, alias, on, join_type: type });
|
|
192
|
-
return this;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
leftJoin(table, alias, on) {
|
|
196
|
-
return this.joinOn(table, alias, on, 'LEFT');
|
|
203
|
+
leftJoin(table, on, options = {}) {
|
|
204
|
+
return joinOn.call(this, table, on, { ...options, join_type: 'LEFT' });
|
|
197
205
|
}
|
|
198
206
|
|
|
199
|
-
rightJoin(table,
|
|
200
|
-
return
|
|
207
|
+
rightJoin(table, on, options = {}) {
|
|
208
|
+
return joinOn.call(this, table, on, { ...options, join_type: 'RIGHT' });
|
|
201
209
|
}
|
|
202
210
|
|
|
203
|
-
innerJoin(table,
|
|
204
|
-
return
|
|
211
|
+
innerJoin(table, on, options = {}) {
|
|
212
|
+
return joinOn.call(this, table, on, { ...options, join_type: 'INNER' });
|
|
205
213
|
}
|
|
206
214
|
}
|
|
207
215
|
|