@axiosleo/orm-mysql 0.9.17 → 0.10.0-alpha

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.
@@ -8,7 +8,6 @@
8
8
  "eamodio.gitlens",
9
9
  "esbenp.prettier-vscode",
10
10
  "wayou.vscode-todo-highlight",
11
- "vue.vscode-typescript-vue-plugin",
12
11
  "octref.vetur",
13
12
  "pflannery.vscode-versionlens"
14
13
  ]
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.17',
12
+ version: '0.10.0-alpha',
13
13
  commands_dir: path.join(__dirname, '../commands'),
14
14
  });
15
15
 
package/index.d.ts CHANGED
@@ -84,32 +84,65 @@ export type QueryOperatorOptions = QueryOperatorBaseOptions & {
84
84
  explain?: boolean;
85
85
  }
86
86
 
87
- export declare class Query {
88
- options: QueryOperatorOptions;
87
+ export declare class QueryCondition {
88
+ where(logicOpt: 'OR' | 'or' | 'AND' | 'and'): this;
89
89
 
90
- constructor(operator?: OperatorType, alias?: string | null);
90
+ where(key: string, value: ConditionValueType | WhereOptions[]): this;
91
91
 
92
- table(table: string, alias?: string | null): this;
92
+ where(key: string, opt: OptType, value: ConditionValueType | WhereOptions[]): this;
93
93
 
94
- tables(...tables: TableOption[]): this;
94
+ /**
95
+ * @deprecated will deprecated on v1.0+ version
96
+ */
97
+ where(key: string | null, value: ConditionValueType | WhereOptions[], opt?: OptType): this;
95
98
 
96
- keys(...keys: string[]): this;
99
+ where(key: string, opt: OptType, value: ConditionValueType | WhereOptions[], isOr?: boolean): this;
97
100
 
98
- limit(limit: number): this;
101
+ whereIn(key: string, value: string | string[] | number[] | Query): this;
99
102
 
100
- offset(offset: number): this;
103
+ whereNotIn(key: string, value: string | string[] | number[] | Query): this;
101
104
 
102
- where(key: string | null, value: ConditionValueType | WhereOptions[], opt?: OptType): this;
105
+ whereContain(key: string, value: string | number): this;
106
+
107
+ whereNotContain(key: string, value: string | number): this;
108
+
109
+ whereBetween(key: string, value: any[]): this;
110
+
111
+ whereNotBetween(key: string, value: any[]): this;
112
+
113
+ whereOverlaps(key: string, value: any[]): this;
114
+
115
+ whereNotOverlaps(key: string, value: any[]): this;
116
+
117
+ whereLike(key: string, value: string | string[]): this;
118
+
119
+ whereNotLike(key: string, value: string | string[]): this;
120
+
121
+ whereCondition(condition: QueryCondition): this;
103
122
 
104
123
  whereObject(obj: Record<string, ConditionValueType>): this;
124
+ }
105
125
 
106
- whereConditions(...condition: WhereItem[]): this;
126
+ export type JoinOptions = {
127
+ alias?: string,
128
+ conditions: WhereItem[]
129
+ };
107
130
 
108
- groupWhere(...condition: WhereItem[]): this;
131
+ export declare class Query extends QueryCondition {
109
132
 
110
- orWhere(key: string | null, opt: OptType, value: ConditionValueType | WhereOptions[]): this;
133
+ options: QueryOperatorOptions;
111
134
 
112
- andWhere(key: string | null, opt: OptType, value: ConditionValueType | WhereOptions[]): this;
135
+ constructor(operator?: OperatorType, alias?: string | null);
136
+
137
+ table(table: string, alias?: string | null): this;
138
+
139
+ tables(...tables: TableOption[]): this;
140
+
141
+ keys(...keys: string[]): this;
142
+
143
+ limit(limit: number): this;
144
+
145
+ offset(offset: number): this;
113
146
 
114
147
  attr(...attr: Attr[]): this;
115
148
 
@@ -125,11 +158,31 @@ export declare class Query {
125
158
 
126
159
  join(opt: JoinOption): this;
127
160
 
128
- leftJoin(table: string, on: string, options?: { alias?: string }): this;
161
+ leftJoin(table: string | Query, on: string, options?: { alias?: string }): this;
162
+
163
+ rightJoin(table: string | Query, on: string, options?: { alias?: string }): this;
164
+
165
+ innerJoin(table: string | Query, on: string, options?: { alias?: string }): this;
166
+
167
+ /**
168
+ * @deprecated will deprecated on v1.0+ version
169
+ */
170
+ whereConditions(...condition: WhereItem[]): this;
129
171
 
130
- rightJoin(table: string, on: string, options?: { alias?: string }): this;
172
+ /**
173
+ * @deprecated will deprecated on v1.0+ version
174
+ */
175
+ groupWhere(...condition: WhereItem[]): this;
131
176
 
132
- innerJoin(table: string, on: string, options?: { alias?: string }): this;
177
+ /**
178
+ * @deprecated will deprecated on v1.0+ version
179
+ */
180
+ orWhere(key: string | null, opt: OptType, value: ConditionValueType | WhereOptions[]): this;
181
+
182
+ /**
183
+ * @deprecated will deprecated on v1.0+ version
184
+ */
185
+ andWhere(key: string | null, opt: OptType, value: ConditionValueType | WhereOptions[]): this;
133
186
  }
134
187
 
135
188
  export type QueryResult = any | undefined | RowDataPacket[] | RowDataPacket | MySQLQueryResult;
@@ -183,7 +236,7 @@ export declare class QueryOperator extends Query {
183
236
 
184
237
  insertAll<T extends Object>(rows: T[]): Promise<MySQLQueryResult[]>;
185
238
 
186
- upsertRow(row: any, ...conditions: WhereItem[]): Promise<MySQLQueryResult>;
239
+ upsertRow(row: any, condition: QueryCondition): Promise<MySQLQueryResult>;
187
240
 
188
241
  upsertRow<T extends Object>(row: T, ...conditions: WhereItem[]): Promise<MySQLQueryResult>;
189
242
  }
package/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  const {
4
4
  QueryHandler,
5
5
  QueryOperator,
6
+ QueryCondition,
6
7
  Query
7
8
  } = require('./src/operator');
8
9
 
@@ -30,6 +31,7 @@ module.exports = {
30
31
  Query,
31
32
  QueryHandler,
32
33
  QueryOperator,
34
+ QueryCondition,
33
35
 
34
36
  TransactionOperator,
35
37
  TransactionHandler,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiosleo/orm-mysql",
3
- "version": "0.9.17",
3
+ "version": "0.10.0-alpha",
4
4
  "description": "MySQL ORM tool",
5
5
  "keywords": [
6
6
  "mysql",
package/src/builder.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const { debug } = require('@axiosleo/cli-tool');
4
- const Query = require('./query');
4
+ const { Query } = require('./query');
5
5
  const is = require('@axiosleo/cli-tool/src/helper/is');
6
6
  const { _caml_case, _render } = require('@axiosleo/cli-tool/src/helper/str');
7
7
  const { _validate } = require('./utils');
@@ -144,7 +144,7 @@ class Builder {
144
144
  _buildJoins(joins = []) {
145
145
  return joins.map((j) => {
146
146
  let { table, alias, self_column, foreign_column, join_type } = j;
147
- if (table instanceof Query) {
147
+ if (table instanceof Query || table.options) {
148
148
  if (!alias) {
149
149
  throw new Error('Alias is required for subQuery');
150
150
  }
package/src/client.js CHANGED
@@ -5,7 +5,7 @@ const mysqlPromise = require('mysql2/promise');
5
5
  const { _validate } = require('./utils');
6
6
  const { _query } = require('./core');
7
7
  const { QueryHandler } = require('./operator');
8
- const Query = require('./query');
8
+ const { Query } = require('./query');
9
9
 
10
10
  const clients = {};
11
11
 
package/src/operator.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const os = require('os');
4
4
  const { Builder } = require('./builder');
5
- const Query = require('./query');
5
+ const { Query, QueryCondition } = require('./query');
6
6
  const Hook = require('./hook');
7
7
  const { _query } = require('./core');
8
8
  const { printer } = require('@axiosleo/cli-tool');
@@ -142,23 +142,22 @@ class QueryOperator extends Query {
142
142
  return await this.exec();
143
143
  }
144
144
 
145
- async upsertRow(data, ...conditions) {
146
- if (conditions.length === 0) {
147
- throw new Error('conditions is required');
148
- }
145
+ async upsertRow(data, condition) {
149
146
  if (!this.options.tables[0]) {
150
147
  throw new Error('table is required');
151
148
  }
152
149
  const query = new QueryOperator(this.conn, this.options);
153
150
  const table = this.options.tables[0].table;
154
151
  const alias = this.options.tables[0].alias;
155
- const count = await query.table(table, alias)
156
- .whereConditions(...conditions)
157
- .count();
152
+ const q = query.table(table, alias);
153
+ if (condition instanceof QueryCondition) {
154
+ q.whereCondition(condition);
155
+ } else {
156
+ q.whereObject(condition);
157
+ }
158
+ const count = await q.count();
158
159
  if (count) {
159
- return await query
160
- .whereConditions(...conditions)
161
- .update(data);
160
+ return await q.update(data);
162
161
  }
163
162
  return await query.insert(data);
164
163
  }
@@ -230,5 +229,6 @@ class QueryHandler {
230
229
  module.exports = {
231
230
  QueryOperator,
232
231
  QueryHandler,
232
+ QueryCondition,
233
233
  Query
234
234
  };
package/src/query.js CHANGED
@@ -4,6 +4,11 @@ const { _assign } = require('@axiosleo/cli-tool/src/helper/obj');
4
4
  const { _validate } = require('./utils');
5
5
  const is = require('@axiosleo/cli-tool/src/helper/is');
6
6
 
7
+ const optType = [
8
+ '=', '!=', '>', '<', '>=', '<=',
9
+ 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'IS', 'IS NOT', 'REGEXP', 'NOT REGEXP', 'AND', 'OR', 'GROUP', 'CONTAIN', 'NOT CONTAIN', 'OVERLAPS', 'NOT OVERLAPS'
10
+ ];
11
+
7
12
  function joinOn(table, on, options = {}) {
8
13
  let o = _assign({ alias: null, join_type: 'INNER', table, on }, options);
9
14
  if (!table) {
@@ -16,8 +21,141 @@ function joinOn(table, on, options = {}) {
16
21
  return this;
17
22
  }
18
23
 
19
- class Query {
24
+ class QueryCondition {
25
+ constructor() {
26
+ this.options = {
27
+ conditions: []
28
+ };
29
+ }
30
+
31
+ where(...args) {
32
+ if (this.options.conditions.length !== 0 && args.length > 1) {
33
+ const last = this.options.conditions[this.options.conditions.length - 1];
34
+ if (last.opt) {
35
+ const opt = last.opt.toUpperCase();
36
+ if (opt !== 'AND' && opt !== 'OR') {
37
+ this.options.conditions.push({ key: null, opt: args[3] === true ? 'OR' : 'AND', value: null });
38
+ }
39
+ }
40
+ }
41
+ switch (args.length) {
42
+ case 4:
43
+ case 3: {
44
+ const [key, opt, value] = args;
45
+ if (is.string(value) && optType.includes(value.toUpperCase()) >= -1) {
46
+ this.options.conditions.push({ key, opt: value, value: opt });
47
+ break;
48
+ }
49
+ this.options.conditions.push({ key, opt, value });
50
+ break;
51
+ }
52
+ case 2: {
53
+ const [key, value] = args;
54
+ this.options.conditions.push({ key, opt: '=', value });
55
+ break;
56
+ }
57
+ case 1: {
58
+ const [opt] = args;
59
+ this.options.conditions.push({ key: null, opt, value: null });
60
+ break;
61
+ }
62
+ default: {
63
+ throw new Error('Invalid arguments');
64
+ }
65
+ }
66
+ return this;
67
+ }
68
+
69
+ whereAnd() {
70
+ this.options.conditions.push({ key: null, opt: 'AND', value: null });
71
+ return this;
72
+ }
73
+
74
+ whereOr() {
75
+ this.options.conditions.push({ key: null, opt: 'OR', value: null });
76
+ return this;
77
+ }
78
+
79
+ whereIn(key, value) {
80
+ if (is.string(value)) {
81
+ value = value.split(',').map(v => v.trim());
82
+ }
83
+ this.options.conditions.push({ key, opt: 'IN', value });
84
+ return this;
85
+ }
86
+
87
+ whereNotIn(key, value) {
88
+ if (is.string(value)) {
89
+ value = value.split(',').map(v => v.trim());
90
+ }
91
+ this.options.conditions.push({ key, opt: 'NOT IN', value });
92
+ return this;
93
+ }
94
+
95
+ whereContain(key, value) {
96
+ this.options.conditions.push({ key, opt: 'CONTAIN', value });
97
+ return this;
98
+ }
99
+
100
+ whereNotContain(key, value) {
101
+ this.options.conditions.push({ key, opt: 'NOT CONTAIN', value });
102
+ return this;
103
+ }
104
+
105
+ whereBetween(key, value) {
106
+ this.options.conditions.push({ key, opt: 'BETWEEN', value });
107
+ return this;
108
+ }
109
+
110
+ whereNotBetween(key, value) {
111
+ this.options.conditions.push({ key, opt: 'NOT BETWEEN', value });
112
+ return this;
113
+ }
114
+
115
+ whereOverlaps(key, value) {
116
+ this.options.conditions.push({ key, opt: 'OVERLAPS', value });
117
+ return this;
118
+ }
119
+
120
+ whereNotOverlaps(key, value) {
121
+ this.options.conditions.push({ key, opt: 'NOT OVERLAPS', value });
122
+ return this;
123
+ }
124
+
125
+ whereLike(key, value) {
126
+ if (is.array(value)) {
127
+ value = value.join('');
128
+ }
129
+ this.options.conditions.push({ key, opt: 'LIKE', value });
130
+ return this;
131
+ }
132
+
133
+ whereNotLike(key, value) {
134
+ if (is.array(value)) {
135
+ value = value.join('');
136
+ }
137
+ this.options.conditions.push({ key, opt: 'NOT LIKE', value });
138
+ return this;
139
+ }
140
+
141
+ /**
142
+ * @param {QueryCondition} condition
143
+ * @returns
144
+ */
145
+ whereCondition(condition) {
146
+ this.options.conditions.push({ key: null, opt: 'GROUP', value: condition.options.conditions });
147
+ return this;
148
+ }
149
+
150
+ whereObject(object = {}) {
151
+ Object.keys(object).forEach((key) => this.where(key, object[key]));
152
+ return this;
153
+ }
154
+ }
155
+
156
+ class Query extends QueryCondition {
20
157
  constructor(operator = 'select', alias = null) {
158
+ super();
21
159
  this.options = {
22
160
  driver: 'mysql',
23
161
  queryHandler: null,
@@ -63,31 +201,93 @@ class Query {
63
201
  return this;
64
202
  }
65
203
 
204
+ attr(...attrs) {
205
+ if (!attrs.length) {
206
+ this.options.attrs = [];
207
+ return this;
208
+ }
209
+ this.options.attrs = attrs;
210
+ return this;
211
+ }
212
+
213
+ orderBy(sortField, sortOrder = 'asc') {
214
+ this.options.orders.push({ sortField, sortOrder });
215
+ return this;
216
+ }
217
+
218
+ groupBy(...groupField) {
219
+ this.options.groupField = groupField;
220
+ return this;
221
+ }
222
+
223
+ having(key, opt = '=', value = null) {
224
+ let optUpper = opt.toUpperCase();
225
+ if (optUpper === 'AND' || optUpper === 'OR') {
226
+ this.options.having.push({ key: null, opt: optUpper, value: null });
227
+ return this;
228
+ }
229
+ if (this.options.having.length) {
230
+ let lastOpt = this.options.having[this.options.having.length - 1].opt.toUpperCase();
231
+ if (lastOpt !== 'AND' && lastOpt !== 'OR') {
232
+ this.options.having.push({ key: null, opt: 'AND', value: null });
233
+ }
234
+ }
235
+ this.options.having.push({ key, opt, value });
236
+ return this;
237
+ }
238
+
239
+ page(limit, offset = 0) {
240
+ this.options.pageLimit = limit;
241
+ this.options.pageOffset = offset;
242
+ return this;
243
+ }
244
+
245
+ set(data) {
246
+ if (is.invalid(data)) {
247
+ throw new Error('data is required');
248
+ }
249
+ this.options.data = data;
250
+ return this;
251
+ }
252
+
66
253
  /**
67
- *
68
- * @param {string} key
69
- * @param {any} value
70
- * @param {*} opt
254
+ * @param {{table:string,table_alias?:string,self_column: string,foreign_column: string,join_type?: 'left' | 'right' | 'inner'}} opt
71
255
  * @returns
72
256
  */
73
- where(key, value, opt = '=') {
74
- if (!key) {
75
- throw new Error('key is required');
76
- }
77
- if (this.options.conditions.length) {
78
- this.options.conditions.push({ key: null, opt: 'AND', value: null });
257
+ join(opt = {}) {
258
+ let types = ['left', 'right', 'inner'];
259
+ opt.join_type = opt.join_type ? opt.join_type.toLowerCase() : 'inner';
260
+ if (types.indexOf(opt.join_type) === -1) {
261
+ throw new Error('Invalid join type : ' + opt.join_type + '; only supported ' + types.join(', '));
79
262
  }
80
- this.options.conditions.push({
81
- key, opt, value,
263
+ _validate(opt, {
264
+ table: 'required',
265
+ self_column: 'required',
266
+ foreign_column: 'required_if:on',
267
+ join_type: [{ in: types }]
82
268
  });
269
+ let { table, table_alias, self_column, foreign_column, join_type } = opt;
270
+ this.options.joins.push({ table, alias: table_alias, self_column, foreign_column, join_type });
83
271
  return this;
84
272
  }
85
273
 
86
- whereObject(object = {}) {
87
- Object.keys(object).forEach((key) => this.where(key, object[key]));
88
- return this;
274
+ leftJoin(table, on, options = {}) {
275
+ return joinOn.call(this, table, on, { ...options, join_type: 'LEFT' });
276
+ }
277
+
278
+ rightJoin(table, on, options = {}) {
279
+ return joinOn.call(this, table, on, { ...options, join_type: 'RIGHT' });
89
280
  }
90
281
 
282
+ innerJoin(table, on, options = {}) {
283
+ return joinOn.call(this, table, on, { ...options, join_type: 'INNER' });
284
+ }
285
+
286
+ /**
287
+ * @deprecated
288
+ * @param {...any} conditions
289
+ * @returns
290
+ */
91
291
  whereConditions(...conditions) {
92
292
  if (!conditions.length) {
93
293
  return this;
@@ -121,6 +321,11 @@ class Query {
121
321
  return this;
122
322
  }
123
323
 
324
+ /**
325
+ * @deprecated
326
+ * @param {...any} conditions
327
+ * @returns
328
+ */
124
329
  groupWhere(...conditions) {
125
330
  if (!conditions.length) {
126
331
  return this;
@@ -153,6 +358,13 @@ class Query {
153
358
  return this;
154
359
  }
155
360
 
361
+ /**
362
+ * @deprecated
363
+ * @param {*} key
364
+ * @param {*} opt
365
+ * @param {*} value
366
+ * @returns
367
+ */
156
368
  orWhere(key, opt, value) {
157
369
  if (!this.options.conditions.length) {
158
370
  throw new Error('At least one where condition is required');
@@ -165,6 +377,13 @@ class Query {
165
377
  return this;
166
378
  }
167
379
 
380
+ /**
381
+ * @deprecated
382
+ * @param {*} key
383
+ * @param {*} opt
384
+ * @param {*} value
385
+ * @returns
386
+ */
168
387
  andWhere(key, opt, value) {
169
388
  if (!this.options.conditions.length) {
170
389
  throw new Error('At least one where condition is required');
@@ -176,88 +395,6 @@ class Query {
176
395
  }, { key, opt, value });
177
396
  return this;
178
397
  }
179
-
180
- attr(...attrs) {
181
- if (!attrs.length) {
182
- this.options.attrs = [];
183
- return this;
184
- }
185
- this.options.attrs = attrs;
186
- return this;
187
- }
188
-
189
- orderBy(sortField, sortOrder = 'asc') {
190
- this.options.orders.push({ sortField, sortOrder });
191
- return this;
192
- }
193
-
194
- groupBy(...groupField) {
195
- this.options.groupField = groupField;
196
- return this;
197
- }
198
-
199
- having(key, opt = '=', value = null) {
200
- let optUpper = opt.toUpperCase();
201
- if (optUpper === 'AND' || optUpper === 'OR') {
202
- this.options.having.push({ key: null, opt: optUpper, value: null });
203
- return this;
204
- }
205
- if (this.options.having.length) {
206
- let lastOpt = this.options.having[this.options.having.length - 1].opt.toUpperCase();
207
- if (lastOpt !== 'AND' && lastOpt !== 'OR') {
208
- this.options.having.push({ key: null, opt: 'AND', value: null });
209
- }
210
- }
211
- this.options.having.push({ key, opt, value });
212
- return this;
213
- }
214
-
215
- page(limit, offset = 0) {
216
- this.options.pageLimit = limit;
217
- this.options.pageOffset = offset;
218
- return this;
219
- }
220
-
221
- set(data) {
222
- if (is.invalid(data)) {
223
- throw new Error('data is required');
224
- }
225
- this.options.data = data;
226
- return this;
227
- }
228
-
229
- /**
230
- * @param {{table:string,table_alias?:string,self_column: string,foreign_column: string,join_type?: 'left' | 'right' | 'inner'}} opt
231
- * @returns
232
- */
233
- join(opt = {}) {
234
- let types = ['left', 'right', 'inner'];
235
- opt.join_type = opt.join_type ? opt.join_type.toLowerCase() : 'inner';
236
- if (types.indexOf(opt.join_type) === -1) {
237
- throw new Error('Invalid join type : ' + opt.join_type + '; only supported ' + types.join(', '));
238
- }
239
- _validate(opt, {
240
- table: 'required',
241
- self_column: 'required',
242
- foreign_column: 'required_if:on',
243
- join_type: [{ in: types }]
244
- });
245
- let { table, table_alias, self_column, foreign_column, join_type } = opt;
246
- this.options.joins.push({ table, alias: table_alias, self_column, foreign_column, join_type });
247
- return this;
248
- }
249
-
250
- leftJoin(table, on, options = {}) {
251
- return joinOn.call(this, table, on, { ...options, join_type: 'LEFT' });
252
- }
253
-
254
- rightJoin(table, on, options = {}) {
255
- return joinOn.call(this, table, on, { ...options, join_type: 'RIGHT' });
256
- }
257
-
258
- innerJoin(table, on, options = {}) {
259
- return joinOn.call(this, table, on, { ...options, join_type: 'INNER' });
260
- }
261
398
  }
262
399
 
263
- module.exports = Query;
400
+ module.exports = { Query, QueryCondition };