@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 CHANGED
@@ -9,7 +9,7 @@ const app = new App({
9
9
  name: 'MySQL ORM CLI',
10
10
  desc: 'migrate, model, seed, etc.',
11
11
  bin: 'orm-mysql',
12
- version: '0.9.6',
12
+ version: '0.9.8',
13
13
  commands_dir: path.join(__dirname, '../commands'),
14
14
  });
15
15
 
@@ -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?: 'left' | 'right' | 'inner';
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiosleo/orm-mysql",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
4
4
  "description": "MySQL ORM tool",
5
5
  "keywords": [
6
6
  "mysql",
package/src/builder.js CHANGED
@@ -98,11 +98,7 @@ class Builder {
98
98
  break;
99
99
  }
100
100
  case 'count': {
101
- let fieldName = 'count';
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
- _validate(options, {
394
- table: 'required|string',
395
- name: 'required|string',
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 hasMigarated = await transaction.table(context.task_key)
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' && hasMigarated) {
122
- if (hasMigarated) {
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' && !hasMigarated) {
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
- joinOn(table, alias, on, type = 'LEFT') {
185
- if (!table) {
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, alias, on) {
200
- return this.joinOn(table, alias, on, 'RIGHT');
207
+ rightJoin(table, on, options = {}) {
208
+ return joinOn.call(this, table, on, { ...options, join_type: 'RIGHT' });
201
209
  }
202
210
 
203
- innerJoin(table, alias, on) {
204
- return this.joinOn(table, alias, on, 'INNER');
211
+ innerJoin(table, on, options = {}) {
212
+ return joinOn.call(this, table, on, { ...options, join_type: 'INNER' });
205
213
  }
206
214
  }
207
215