tspace-mysql 1.2.1 → 1.2.3
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/README.md +28 -12
- package/dist/cli/generate/make.js +1 -1
- package/dist/cli/generate/model.d.ts +2 -0
- package/dist/cli/generate/model.js +30 -0
- package/dist/lib/connection/index.js +1 -1
- package/dist/lib/connection/options.js +3 -3
- package/dist/lib/constants/index.js +1 -0
- package/dist/lib/tspace/Database.js +14 -21
- package/dist/lib/tspace/Interface.d.ts +2 -0
- package/dist/lib/tspace/Model.d.ts +17 -7
- package/dist/lib/tspace/Model.js +154 -109
- package/dist/lib/utils/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,12 +45,13 @@ DB_USERNAME = root
|
|
|
45
45
|
DB_PASSWORD = password
|
|
46
46
|
DB_DATABASE = database
|
|
47
47
|
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
/**
|
|
49
|
+
* @default
|
|
50
|
+
* DB_CONNECTION_LIMIT = 10
|
|
51
|
+
* DB_CONNECTION_ERROR = true
|
|
52
|
+
* DB_QUEUE_LIMIT = 0
|
|
53
|
+
* DB_TIMEOUT = 60000
|
|
54
|
+
* DB_DATE_STRINGS = true
|
|
54
55
|
*/
|
|
55
56
|
|
|
56
57
|
```
|
|
@@ -358,16 +359,31 @@ import { Model } from 'tspace-mysql'
|
|
|
358
359
|
class User extends Model {
|
|
359
360
|
constructor(){
|
|
360
361
|
super()
|
|
361
|
-
this.useTimestamp() /** created_at , updated_at
|
|
362
362
|
/**
|
|
363
363
|
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
364
|
+
* Assign setting global in your model
|
|
365
|
+
* @useMethod
|
|
366
|
+
*
|
|
367
|
+
* this.useDebug()
|
|
368
|
+
* this.usePrimaryKey('id')
|
|
366
369
|
* this.useTimestamp({
|
|
367
370
|
* createdAt : 'created_at',
|
|
368
371
|
* updatedAt : 'updated_at'
|
|
369
|
-
* })
|
|
370
|
-
|
|
372
|
+
* }) // runing a timestamp when insert or update
|
|
373
|
+
* this.useSoftDelete()
|
|
374
|
+
* this.useTable('users')
|
|
375
|
+
* this.useTableSingular() // 'user'
|
|
376
|
+
* this.useTablePlural() // 'users'
|
|
377
|
+
* this.usePattern('snake_case')
|
|
378
|
+
* this.useUUID('uuid') // => runing a uuid (universally unique identifier) when insert new data
|
|
379
|
+
* this.useRegistry()
|
|
380
|
+
* this.useSchema({
|
|
381
|
+
* id : Number,
|
|
382
|
+
* username : String
|
|
383
|
+
* created_at : Date,
|
|
384
|
+
* updated_at : Date,
|
|
385
|
+
* }) // validate type of schema when return result
|
|
386
|
+
*/
|
|
371
387
|
|
|
372
388
|
/*
|
|
373
389
|
* the "snake case", plural name of the class will be used as the table name
|
|
@@ -624,7 +640,7 @@ hook((result) => ...) // callback result to function
|
|
|
624
640
|
hasOne({ name , model , localKey , foreignKey , freezeTable , as })
|
|
625
641
|
hasMany({ name , model , localKey , foreignKey , freezeTable , as })
|
|
626
642
|
belongsTo({ name , model , localKey , foreignKey , freezeTable , as })
|
|
627
|
-
belongsToMany({ name , model , localKey , foreignKey , freezeTable , as })
|
|
643
|
+
belongsToMany({ name , model , localKey , foreignKey , freezeTable , as , pivot })
|
|
628
644
|
/**
|
|
629
645
|
* @relation using registry in your models
|
|
630
646
|
*/
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const model_1 = __importDefault(require("
|
|
6
|
+
const model_1 = __importDefault(require("./model"));
|
|
7
7
|
const pluralize_1 = __importDefault(require("pluralize"));
|
|
8
8
|
const lib_1 = require("../../lib");
|
|
9
9
|
exports.default = (cmd) => {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Model = (model, npm) => {
|
|
4
|
+
return `import { Model } from '${npm}'
|
|
5
|
+
class ${model} extends Model {
|
|
6
|
+
constructor(){
|
|
7
|
+
super()
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* Assign setting global in your model
|
|
11
|
+
* @useMethod
|
|
12
|
+
*
|
|
13
|
+
* this.useDebug() // => runing a uuid (universally unique identifier) when insert new data
|
|
14
|
+
* this.usePrimaryKey('id') // => runing a uuid (universally unique identifier) when insert new data
|
|
15
|
+
* this.useTimestamp({ createdAt : 'created_at' , updatedAt : 'updated_at' }) // runing a timestamp when insert or update
|
|
16
|
+
* this.useSoftDelete()
|
|
17
|
+
* this.useTable('users')
|
|
18
|
+
* this.useTableSingular() // 'user'
|
|
19
|
+
* this.useTablePlural() // 'users'
|
|
20
|
+
* this.usePattern('snake_case')
|
|
21
|
+
* this.useUUID('uuid')
|
|
22
|
+
* this.useRegistry()
|
|
23
|
+
*/
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export { ${model} }
|
|
27
|
+
export default ${model}
|
|
28
|
+
`;
|
|
29
|
+
};
|
|
30
|
+
exports.default = Model;
|
|
@@ -24,9 +24,9 @@ const env = {
|
|
|
24
24
|
USERNAME: process.env.DB_USERNAME || process.env.TSPACE_USERNAME,
|
|
25
25
|
PASSWORD: process.env.DB_PASSWORD || process.env.TSPACE_PASSWORD || '',
|
|
26
26
|
DATABASE: process.env.DB_DATABASE || process.env.TSPACE_DATABASE,
|
|
27
|
-
CONNECTION_LIMIT: process.env.DB_CONNECTION_LIMIT || process.env.TSPACE_CONNECTION_LIMIT ||
|
|
28
|
-
QUEUE_LIMIT: process.env.DB_QUEUE_LIMIT || process.env.TSPACE_QUEUE_LIMIT ||
|
|
29
|
-
TIMEOUT: process.env.DB_TIMEOUT || process.env.TSPACE_TIMEOUT || 1000 *
|
|
27
|
+
CONNECTION_LIMIT: process.env.DB_CONNECTION_LIMIT || process.env.TSPACE_CONNECTION_LIMIT || 10,
|
|
28
|
+
QUEUE_LIMIT: process.env.DB_QUEUE_LIMIT || process.env.TSPACE_QUEUE_LIMIT || 0,
|
|
29
|
+
TIMEOUT: process.env.DB_TIMEOUT || process.env.TSPACE_TIMEOUT || 1000 * 60,
|
|
30
30
|
CHARSET: process.env.DB_CHARSET || process.env.TSPACE_CHARSET || 'utf8mb4',
|
|
31
31
|
CONNECTION_ERROR: process.env.DB_CONNECTION_ERROR || process.env.TSPACE_CONNECTION_ERROR || true,
|
|
32
32
|
WAIT_FOR_CONNECTIONS: process.env.DB_WAIT_FOR_CONNECTIONS || process.env.TSPACE_WAIT_FOR_CONNECTIONS || true,
|
|
@@ -1283,16 +1283,14 @@ class Database extends AbstractDatabase_1.default {
|
|
|
1283
1283
|
throw new Error(`can't find property '${pluck}' of result`);
|
|
1284
1284
|
const r = newData[pluck] || null;
|
|
1285
1285
|
const hook = this.$state.get('HOOK');
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
yield hook[i](r);
|
|
1286
|
+
for (let i in hook)
|
|
1287
|
+
yield hook[i](r);
|
|
1289
1288
|
return r;
|
|
1290
1289
|
}
|
|
1291
1290
|
const r = (result === null || result === void 0 ? void 0 : result.shift()) || null;
|
|
1292
1291
|
const hook = this.$state.get('HOOK');
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
yield hook[i](r);
|
|
1292
|
+
for (let i in hook)
|
|
1293
|
+
yield hook[i](r);
|
|
1296
1294
|
return r;
|
|
1297
1295
|
});
|
|
1298
1296
|
}
|
|
@@ -1338,9 +1336,8 @@ class Database extends AbstractDatabase_1.default {
|
|
|
1338
1336
|
throw Object.assign({ message }, options);
|
|
1339
1337
|
}
|
|
1340
1338
|
const hook = this.$state.get('HOOK');
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
yield hook[i](data);
|
|
1339
|
+
for (let i in hook)
|
|
1340
|
+
yield hook[i](data);
|
|
1344
1341
|
return data;
|
|
1345
1342
|
}
|
|
1346
1343
|
const data = (result === null || result === void 0 ? void 0 : result.shift()) || null;
|
|
@@ -1351,9 +1348,8 @@ class Database extends AbstractDatabase_1.default {
|
|
|
1351
1348
|
throw Object.assign({ message }, options);
|
|
1352
1349
|
}
|
|
1353
1350
|
const hook = this.$state.get('HOOK');
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
yield hook[i](data);
|
|
1351
|
+
for (let i in hook)
|
|
1352
|
+
yield hook[i](data);
|
|
1357
1353
|
return data;
|
|
1358
1354
|
});
|
|
1359
1355
|
}
|
|
@@ -1390,9 +1386,8 @@ class Database extends AbstractDatabase_1.default {
|
|
|
1390
1386
|
return resultArray;
|
|
1391
1387
|
}, []);
|
|
1392
1388
|
const hook = this.$state.get('HOOK');
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
yield hook[i](data || []);
|
|
1389
|
+
for (let i in hook)
|
|
1390
|
+
yield hook[i](data || []);
|
|
1396
1391
|
return data || [];
|
|
1397
1392
|
}
|
|
1398
1393
|
if (this.$state.get('PLUCK')) {
|
|
@@ -1402,15 +1397,13 @@ class Database extends AbstractDatabase_1.default {
|
|
|
1402
1397
|
throw new Error(`can't find property '${pluck}' of result`);
|
|
1403
1398
|
}
|
|
1404
1399
|
const hook = this.$state.get('HOOK');
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
yield hook[i](newData || []);
|
|
1400
|
+
for (let i in hook)
|
|
1401
|
+
yield hook[i](newData || []);
|
|
1408
1402
|
return newData || [];
|
|
1409
1403
|
}
|
|
1410
1404
|
const hook = this.$state.get('HOOK');
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
yield hook[i](result || []);
|
|
1405
|
+
for (let i in hook)
|
|
1406
|
+
yield hook[i](result || []);
|
|
1414
1407
|
return result || [];
|
|
1415
1408
|
});
|
|
1416
1409
|
}
|
|
@@ -5,6 +5,7 @@ export interface Relation {
|
|
|
5
5
|
localKey?: string | undefined;
|
|
6
6
|
foreignKey?: string | undefined;
|
|
7
7
|
freezeTable?: string | undefined;
|
|
8
|
+
pivot?: string | undefined;
|
|
8
9
|
query?: any | undefined;
|
|
9
10
|
relation?: Object | undefined;
|
|
10
11
|
}
|
|
@@ -15,6 +16,7 @@ export interface RelationQuery {
|
|
|
15
16
|
localKey?: string | undefined;
|
|
16
17
|
foreignKey?: string | undefined;
|
|
17
18
|
freezeTable?: string | undefined;
|
|
19
|
+
pivot?: string | undefined;
|
|
18
20
|
query?: any | undefined;
|
|
19
21
|
relation?: Object | undefined;
|
|
20
22
|
}
|
|
@@ -15,10 +15,10 @@ declare class Model extends AbstractModel {
|
|
|
15
15
|
*/
|
|
16
16
|
protected useRegistry(): this;
|
|
17
17
|
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
*
|
|
19
|
+
* Assign primary column in model
|
|
20
|
+
* @return {this} this
|
|
21
|
+
*/
|
|
22
22
|
protected usePrimaryKey(primary: string): this;
|
|
23
23
|
/**
|
|
24
24
|
* Assign generate uuid when creating in model
|
|
@@ -77,6 +77,15 @@ declare class Model extends AbstractModel {
|
|
|
77
77
|
* @return {this} this
|
|
78
78
|
*/
|
|
79
79
|
protected useTablePlural(): this;
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
* Assign schema column in model
|
|
83
|
+
* @param {Object<Function>} schema type String Number and Date
|
|
84
|
+
* @return {this} this
|
|
85
|
+
*/
|
|
86
|
+
protected useSchema(schema: {
|
|
87
|
+
[key: string]: Function;
|
|
88
|
+
}): this;
|
|
80
89
|
/**
|
|
81
90
|
* Build method for relation in model
|
|
82
91
|
* @param {string} name name relation registry in your model
|
|
@@ -222,7 +231,7 @@ declare class Model extends AbstractModel {
|
|
|
222
231
|
* @property {string} relation.freezeTable
|
|
223
232
|
* @return {this} this
|
|
224
233
|
*/
|
|
225
|
-
protected belongsToMany({ name, as, model, localKey, foreignKey, freezeTable }: Relation): this;
|
|
234
|
+
protected belongsToMany({ name, as, model, localKey, foreignKey, freezeTable, pivot }: Relation): this;
|
|
226
235
|
/**
|
|
227
236
|
* Assign the relation in model Objects
|
|
228
237
|
* @param {object} relation registry relation in your model
|
|
@@ -278,7 +287,7 @@ declare class Model extends AbstractModel {
|
|
|
278
287
|
* @param {function?} callback callback of query
|
|
279
288
|
* @return {this} this
|
|
280
289
|
*/
|
|
281
|
-
protected belongsToManyBuilder({ name, as, model, localKey, foreignKey, freezeTable }: RelationQuery, callback?: Function): this;
|
|
290
|
+
protected belongsToManyBuilder({ name, as, model, localKey, foreignKey, freezeTable, pivot }: RelationQuery, callback?: Function): this;
|
|
282
291
|
/**
|
|
283
292
|
* return only in trashed (data has been remove)
|
|
284
293
|
* @return {promise}
|
|
@@ -540,6 +549,7 @@ declare class Model extends AbstractModel {
|
|
|
540
549
|
* @return {this} this this
|
|
541
550
|
*/
|
|
542
551
|
createNotExists(data: object): this;
|
|
552
|
+
getSchema(): Promise<any>;
|
|
543
553
|
/**
|
|
544
554
|
*
|
|
545
555
|
* @override Method
|
|
@@ -566,13 +576,13 @@ declare class Model extends AbstractModel {
|
|
|
566
576
|
private _handleSoftDelete;
|
|
567
577
|
private _buildQueryModel;
|
|
568
578
|
private _showOnly;
|
|
579
|
+
private _validateSchema;
|
|
569
580
|
private _execute;
|
|
570
581
|
private _executeGroup;
|
|
571
582
|
private _relationMapData;
|
|
572
583
|
private _handleRelationsExists;
|
|
573
584
|
private _queryRelationsExists;
|
|
574
585
|
private _relation;
|
|
575
|
-
private _handleBelongsToMany;
|
|
576
586
|
private _belongsToMany;
|
|
577
587
|
private _pagination;
|
|
578
588
|
private _result;
|
package/dist/lib/tspace/Model.js
CHANGED
|
@@ -37,8 +37,7 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
37
37
|
* define for initialize of models
|
|
38
38
|
* @return {void} void
|
|
39
39
|
*/
|
|
40
|
-
define() {
|
|
41
|
-
}
|
|
40
|
+
define() { }
|
|
42
41
|
/**
|
|
43
42
|
*
|
|
44
43
|
* Assign function callback in model
|
|
@@ -49,10 +48,10 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
49
48
|
return this;
|
|
50
49
|
}
|
|
51
50
|
/**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
*
|
|
52
|
+
* Assign primary column in model
|
|
53
|
+
* @return {this} this
|
|
54
|
+
*/
|
|
56
55
|
usePrimaryKey(primary) {
|
|
57
56
|
this.$state.set('PRIMARY_KEY', primary);
|
|
58
57
|
return this;
|
|
@@ -154,6 +153,16 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
154
153
|
this.$state.set('TABLE_NAME', `\`${pluralize_1.default.plural(table)}\``);
|
|
155
154
|
return this;
|
|
156
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
*
|
|
158
|
+
* Assign schema column in model
|
|
159
|
+
* @param {Object<Function>} schema type String Number and Date
|
|
160
|
+
* @return {this} this
|
|
161
|
+
*/
|
|
162
|
+
useSchema(schema) {
|
|
163
|
+
this.$state.set('SCHEMA', schema);
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
157
166
|
/**
|
|
158
167
|
* Build method for relation in model
|
|
159
168
|
* @param {string} name name relation registry in your model
|
|
@@ -444,7 +453,7 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
444
453
|
* @property {string} relation.freezeTable
|
|
445
454
|
* @return {this} this
|
|
446
455
|
*/
|
|
447
|
-
belongsToMany({ name, as, model, localKey, foreignKey, freezeTable }) {
|
|
456
|
+
belongsToMany({ name, as, model, localKey, foreignKey, freezeTable, pivot }) {
|
|
448
457
|
const relation = {
|
|
449
458
|
name,
|
|
450
459
|
model,
|
|
@@ -453,6 +462,7 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
453
462
|
localKey,
|
|
454
463
|
foreignKey,
|
|
455
464
|
freezeTable,
|
|
465
|
+
pivot,
|
|
456
466
|
query: null
|
|
457
467
|
};
|
|
458
468
|
this.$state.set('RELATION', [...this.$state.get('RELATION'), relation]);
|
|
@@ -576,7 +586,7 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
576
586
|
* @param {function?} callback callback of query
|
|
577
587
|
* @return {this} this
|
|
578
588
|
*/
|
|
579
|
-
belongsToManyBuilder({ name, as, model, localKey, foreignKey, freezeTable }, callback) {
|
|
589
|
+
belongsToManyBuilder({ name, as, model, localKey, foreignKey, freezeTable, pivot }, callback) {
|
|
580
590
|
const nameRelation = name == null
|
|
581
591
|
? this._functionRelationName()
|
|
582
592
|
: String(name);
|
|
@@ -588,6 +598,7 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
588
598
|
localKey,
|
|
589
599
|
foreignKey,
|
|
590
600
|
freezeTable,
|
|
601
|
+
pivot,
|
|
591
602
|
query: null
|
|
592
603
|
};
|
|
593
604
|
const r = this._handleRelationsQuery(nameRelation, relation);
|
|
@@ -1307,6 +1318,54 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1307
1318
|
this.$state.set('SAVE', 'INSERT_NOT_EXISTS');
|
|
1308
1319
|
return this;
|
|
1309
1320
|
}
|
|
1321
|
+
getSchema() {
|
|
1322
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1323
|
+
const sql = [
|
|
1324
|
+
`${this.$constants('SHOW')}`,
|
|
1325
|
+
`${this.$constants('COLUMNS')}`,
|
|
1326
|
+
`${this.$constants('FROM')}`,
|
|
1327
|
+
`\`${this.$state.get('TABLE_NAME').replace(/\`/g, '')}\``
|
|
1328
|
+
].join(' ');
|
|
1329
|
+
const raw = yield this.queryStatement(sql);
|
|
1330
|
+
const schemas = raw.map((r) => {
|
|
1331
|
+
let schema = { [r.Field]: String };
|
|
1332
|
+
const numberLists = [
|
|
1333
|
+
'tinyint',
|
|
1334
|
+
'smallint',
|
|
1335
|
+
'mediumint',
|
|
1336
|
+
'int',
|
|
1337
|
+
'bigint',
|
|
1338
|
+
'float',
|
|
1339
|
+
'double',
|
|
1340
|
+
'decimal',
|
|
1341
|
+
'real',
|
|
1342
|
+
'bit',
|
|
1343
|
+
'boolean',
|
|
1344
|
+
'serial'
|
|
1345
|
+
];
|
|
1346
|
+
const dateAndTimeLists = [
|
|
1347
|
+
'date',
|
|
1348
|
+
'datetime',
|
|
1349
|
+
'time',
|
|
1350
|
+
'timestamp',
|
|
1351
|
+
'year'
|
|
1352
|
+
];
|
|
1353
|
+
if (numberLists.includes(r.Type)) {
|
|
1354
|
+
schema = {
|
|
1355
|
+
[r.Field]: Number
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
if (dateAndTimeLists.includes(r.Type)) {
|
|
1359
|
+
schema = {
|
|
1360
|
+
[r.Field]: Date
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
return schema;
|
|
1364
|
+
});
|
|
1365
|
+
const result = Object.assign({}, ...schemas);
|
|
1366
|
+
return result;
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1310
1369
|
/**
|
|
1311
1370
|
*
|
|
1312
1371
|
* @override Method
|
|
@@ -1314,6 +1373,7 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1314
1373
|
*/
|
|
1315
1374
|
save() {
|
|
1316
1375
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1376
|
+
this._validateMethod('save');
|
|
1317
1377
|
const attributes = this.$attributes;
|
|
1318
1378
|
if (attributes != null) {
|
|
1319
1379
|
while (true) {
|
|
@@ -1418,12 +1478,13 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1418
1478
|
return (_a = this.$state.get('TABLE_NAME')) === null || _a === void 0 ? void 0 : _a.replace(/`/g, '');
|
|
1419
1479
|
}
|
|
1420
1480
|
_valueInRelation(relationModel) {
|
|
1421
|
-
var _a, _b;
|
|
1481
|
+
var _a, _b, _c, _d;
|
|
1422
1482
|
const relation = relationModel.relation;
|
|
1423
1483
|
const model = (_a = relationModel.model) === null || _a === void 0 ? void 0 : _a.name;
|
|
1424
1484
|
const table = relationModel.freezeTable
|
|
1425
1485
|
? relationModel.freezeTable
|
|
1426
1486
|
: (_b = relationModel.query) === null || _b === void 0 ? void 0 : _b._tableName();
|
|
1487
|
+
let pivot = null;
|
|
1427
1488
|
const name = relationModel.name;
|
|
1428
1489
|
const as = relationModel.as;
|
|
1429
1490
|
this._assertError(!model || model == null, 'not found model');
|
|
@@ -1459,8 +1520,12 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1459
1520
|
`${this.$state.get('PRIMARY_KEY')}`
|
|
1460
1521
|
].join('_'));
|
|
1461
1522
|
foreignKey = 'id';
|
|
1523
|
+
pivot = (_c = relationModel.pivot) !== null && _c !== void 0 ? _c : this._valuePattern([
|
|
1524
|
+
pluralize_1.default.singular(this === null || this === void 0 ? void 0 : this._tableName()),
|
|
1525
|
+
pluralize_1.default.singular((_d = relationModel.query) === null || _d === void 0 ? void 0 : _d._tableName())
|
|
1526
|
+
].sort().join('_'));
|
|
1462
1527
|
}
|
|
1463
|
-
return { name, as, relation, table, localKey, foreignKey, model };
|
|
1528
|
+
return { name, as, relation, table, localKey, foreignKey, model, pivot };
|
|
1464
1529
|
}
|
|
1465
1530
|
_handleSoftDelete() {
|
|
1466
1531
|
if (this.$state.get('SOFT_DELETE')) {
|
|
@@ -1527,9 +1592,36 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1527
1592
|
});
|
|
1528
1593
|
return result;
|
|
1529
1594
|
}
|
|
1595
|
+
_validateSchema(results) {
|
|
1596
|
+
const schema = this.$state.get('SCHEMA');
|
|
1597
|
+
if (schema == null)
|
|
1598
|
+
return;
|
|
1599
|
+
if (!results.length)
|
|
1600
|
+
return;
|
|
1601
|
+
const typeOf = (data) => Object.prototype.toString.apply(data).slice(8, -1).toLocaleLowerCase();
|
|
1602
|
+
for (const result of results) {
|
|
1603
|
+
for (const key in result) {
|
|
1604
|
+
const s = schema[key];
|
|
1605
|
+
if (s == null)
|
|
1606
|
+
this._assertError(`not found this column [${key}] in schema`);
|
|
1607
|
+
const regexDate = /[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/;
|
|
1608
|
+
const regexDateTime = /[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]/;
|
|
1609
|
+
if (regexDate.test(result[key]) || regexDateTime.test(result[key])) {
|
|
1610
|
+
if (typeOf(new Date(result[key])) === typeOf(new s()))
|
|
1611
|
+
continue;
|
|
1612
|
+
this._assertError(`this column [${key}] is invalid schema field type`);
|
|
1613
|
+
}
|
|
1614
|
+
if (typeOf(result[key]) === typeOf(new s()))
|
|
1615
|
+
continue;
|
|
1616
|
+
this._assertError(`this column [${key}] is invalid schema field type`);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
return this;
|
|
1620
|
+
}
|
|
1530
1621
|
_execute({ sql, type, message, options }) {
|
|
1531
1622
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1532
1623
|
let result = yield this.queryStatement(sql);
|
|
1624
|
+
this._validateSchema(result);
|
|
1533
1625
|
if (!result.length)
|
|
1534
1626
|
return this._returnEmpty(type, result, message, options);
|
|
1535
1627
|
const relations = this.$state.get('WITH');
|
|
@@ -1629,7 +1721,7 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1629
1721
|
const relation = relations[index];
|
|
1630
1722
|
if (!((_a = Object.keys(relation)) === null || _a === void 0 ? void 0 : _a.length))
|
|
1631
1723
|
continue;
|
|
1632
|
-
const { localKey, foreignKey } = this._valueInRelation(relation);
|
|
1724
|
+
const { localKey, foreignKey, pivot } = this._valueInRelation(relation);
|
|
1633
1725
|
const query = relation.query;
|
|
1634
1726
|
this._assertError(query == null, `unknown callback query in [relation : '${relation.name}']`);
|
|
1635
1727
|
let clone = new Model().clone(query);
|
|
@@ -1641,6 +1733,21 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1641
1733
|
clone.whereExists(sql);
|
|
1642
1734
|
}
|
|
1643
1735
|
}
|
|
1736
|
+
if (relation.relation === this.$constants('RELATIONSHIP').belongsToMany) {
|
|
1737
|
+
const sql = clone
|
|
1738
|
+
.bind(this.$pool.get())
|
|
1739
|
+
.whereReference(`\`${this._tableName()}\`.\`${localKey}\``, `\`${query._tableName()}\`.\`${foreignKey}\``)
|
|
1740
|
+
.toString();
|
|
1741
|
+
this.whereExists(sql);
|
|
1742
|
+
const thisPivot = new Model();
|
|
1743
|
+
thisPivot.$state.set('TABLE_NAME', `\`${pivot}\``);
|
|
1744
|
+
const sqlPivot = thisPivot
|
|
1745
|
+
.bind(this.$pool.get())
|
|
1746
|
+
.whereReference(`\`${this._tableName()}\`.\`${foreignKey}\``, `\`${pivot}\`.\`${this._valuePattern([pluralize_1.default.singular(this._tableName()), foreignKey].join("_"))}\``)
|
|
1747
|
+
.toString();
|
|
1748
|
+
this.whereExists(sqlPivot);
|
|
1749
|
+
continue;
|
|
1750
|
+
}
|
|
1644
1751
|
const sql = clone
|
|
1645
1752
|
.bind(this.$pool.get())
|
|
1646
1753
|
.whereReference(`\`${this._tableName()}\`.\`${localKey}\``, `\`${query._tableName()}\`.\`${foreignKey}\``)
|
|
@@ -1676,66 +1783,15 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1676
1783
|
return dataFromRelation;
|
|
1677
1784
|
});
|
|
1678
1785
|
}
|
|
1679
|
-
|
|
1786
|
+
_belongsToMany(dataFromParent, relation) {
|
|
1787
|
+
var _a;
|
|
1680
1788
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
const localKeyId = dataFromParent.map((parent) => {
|
|
1684
|
-
const data = parent[localKey];
|
|
1685
|
-
if (!parent.hasOwnProperty(localKey)) {
|
|
1686
|
-
this._assertError(data == null, "unknown relationship without primary or foreign key");
|
|
1687
|
-
}
|
|
1688
|
-
return data;
|
|
1689
|
-
}).filter((data) => data != null);
|
|
1690
|
-
const dataPerentId = Array.from(new Set(localKeyId)).join(',') || [];
|
|
1691
|
-
if (!dataPerentId.length && this.$state.get('WITH_EXISTS'))
|
|
1692
|
-
return [];
|
|
1693
|
-
const modelOther = new relation.model();
|
|
1694
|
-
const other = this._classToTableName(modelOther.constructor.name, { singular: true });
|
|
1695
|
-
const otherlocalKey = 'id';
|
|
1696
|
-
const otherforeignKey = this._valuePattern(`${other}Id`);
|
|
1697
|
-
const sqldataChilds = [
|
|
1698
|
-
`${this.$constants('SELECT')}`,
|
|
1699
|
-
`*`,
|
|
1700
|
-
`${this.$constants('FROM')}`,
|
|
1701
|
-
`${pivotTable}`,
|
|
1702
|
-
`${this.$constants('WHERE')}`,
|
|
1703
|
-
`${otherforeignKey} ${this.$constants('IN')} (${dataPerentId})`
|
|
1704
|
-
].join(' ');
|
|
1705
|
-
let dataChilds = yield this.queryStatement(sqldataChilds);
|
|
1706
|
-
const otherId = dataChilds.map((sub) => sub[otherforeignKey]).filter((data) => data != null);
|
|
1707
|
-
const otherArrId = Array.from(new Set(otherId)) || [];
|
|
1708
|
-
const otherdataChilds = yield this.queryStatement(modelOther
|
|
1709
|
-
.bind(this.$pool.get())
|
|
1710
|
-
.whereIn(otherlocalKey, otherArrId)
|
|
1711
|
-
.debug(this.$state.get('DEBUG'))
|
|
1712
|
-
.toString());
|
|
1713
|
-
dataChilds.forEach((sub) => {
|
|
1714
|
-
sub[other] = [];
|
|
1715
|
-
otherdataChilds.forEach((otherSub) => {
|
|
1716
|
-
if (otherSub[otherlocalKey] === sub[otherforeignKey]) {
|
|
1717
|
-
sub[other] = otherSub;
|
|
1718
|
-
}
|
|
1719
|
-
});
|
|
1720
|
-
});
|
|
1721
|
-
dataFromParent.forEach((dataPerent) => {
|
|
1722
|
-
if (dataPerent[name] == null)
|
|
1723
|
-
dataPerent[name] = [];
|
|
1724
|
-
dataChilds.forEach((sub) => {
|
|
1725
|
-
if (sub[localKey] === dataPerent[otherforeignKey]) {
|
|
1726
|
-
dataPerent[name].push(sub);
|
|
1727
|
-
}
|
|
1728
|
-
});
|
|
1729
|
-
});
|
|
1730
|
-
if (this.$state.get('HIDDEN').length)
|
|
1731
|
-
this._hiddenColumnModel(dataFromParent);
|
|
1732
|
-
return dataFromParent;
|
|
1733
|
-
}
|
|
1734
|
-
let { name, localKey, foreignKey } = this._valueInRelation(relation);
|
|
1789
|
+
const { name, foreignKey, pivot } = this._valueInRelation(relation);
|
|
1790
|
+
const pivotTable = String(((_a = relation.pivot) !== null && _a !== void 0 ? _a : pivot));
|
|
1735
1791
|
const localKeyId = dataFromParent.map((parent) => {
|
|
1736
|
-
const data = parent[
|
|
1737
|
-
if (!parent.hasOwnProperty(
|
|
1738
|
-
this._assertError(data == null,
|
|
1792
|
+
const data = parent[foreignKey];
|
|
1793
|
+
if (!parent.hasOwnProperty(foreignKey)) {
|
|
1794
|
+
this._assertError(data == null, `unknown relationship without primary or foreign key in relation : [${relation === null || relation === void 0 ? void 0 : relation.name}]`);
|
|
1739
1795
|
}
|
|
1740
1796
|
return data;
|
|
1741
1797
|
}).filter((data) => data != null);
|
|
@@ -1746,13 +1802,14 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1746
1802
|
const other = this._classToTableName(modelOther.constructor.name, { singular: true });
|
|
1747
1803
|
const otherlocalKey = 'id';
|
|
1748
1804
|
const otherforeignKey = this._valuePattern(`${other}Id`);
|
|
1805
|
+
const localKeyPivotTable = this._valuePattern([pluralize_1.default.singular(this._tableName()), foreignKey].join("_"));
|
|
1749
1806
|
const sqldataChilds = [
|
|
1750
1807
|
`${this.$constants('SELECT')}`,
|
|
1751
1808
|
`*`,
|
|
1752
1809
|
`${this.$constants('FROM')}`,
|
|
1753
1810
|
`${pivotTable}`,
|
|
1754
1811
|
`${this.$constants('WHERE')}`,
|
|
1755
|
-
`${
|
|
1812
|
+
`${localKeyPivotTable} ${this.$constants('IN')} (${dataPerentId})`
|
|
1756
1813
|
].join(' ');
|
|
1757
1814
|
let dataChilds = yield this.queryStatement(sqldataChilds);
|
|
1758
1815
|
const otherId = dataChilds.map((sub) => sub[otherforeignKey]).filter((data) => data != null);
|
|
@@ -1763,7 +1820,6 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1763
1820
|
.debug(this.$state.get('DEBUG'))
|
|
1764
1821
|
.toString());
|
|
1765
1822
|
dataChilds.forEach((sub) => {
|
|
1766
|
-
sub[other] = [];
|
|
1767
1823
|
otherdataChilds.forEach((otherSub) => {
|
|
1768
1824
|
if (otherSub[otherlocalKey] === sub[otherforeignKey]) {
|
|
1769
1825
|
sub[other] = otherSub;
|
|
@@ -1774,7 +1830,7 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1774
1830
|
if (dataPerent[name] == null)
|
|
1775
1831
|
dataPerent[name] = [];
|
|
1776
1832
|
dataChilds.forEach((sub) => {
|
|
1777
|
-
if (sub[
|
|
1833
|
+
if (sub[localKeyPivotTable] === dataPerent[foreignKey]) {
|
|
1778
1834
|
dataPerent[name].push(sub);
|
|
1779
1835
|
}
|
|
1780
1836
|
});
|
|
@@ -1784,27 +1840,6 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1784
1840
|
return dataFromParent;
|
|
1785
1841
|
});
|
|
1786
1842
|
}
|
|
1787
|
-
_belongsToMany(dataFromParent, relation) {
|
|
1788
|
-
var _a, _b;
|
|
1789
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1790
|
-
const local = this._classToTableName(this.constructor.name, { singular: true });
|
|
1791
|
-
const modelOther = new relation.model();
|
|
1792
|
-
const other = this._classToTableName(modelOther.constructor.name, { singular: true });
|
|
1793
|
-
try {
|
|
1794
|
-
const pivotTable = (_a = relation.freezeTable) !== null && _a !== void 0 ? _a : `${local}_${other}`;
|
|
1795
|
-
return yield this._handleBelongsToMany(dataFromParent, relation, pivotTable);
|
|
1796
|
-
}
|
|
1797
|
-
catch (err) {
|
|
1798
|
-
try {
|
|
1799
|
-
const pivotTable = (_b = relation.freezeTable) !== null && _b !== void 0 ? _b : `${other}_${local}`;
|
|
1800
|
-
return yield this._handleBelongsToMany(dataFromParent, relation, pivotTable);
|
|
1801
|
-
}
|
|
1802
|
-
catch (e) {
|
|
1803
|
-
throw new Error(err.message);
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
});
|
|
1807
|
-
}
|
|
1808
1843
|
_pagination(data) {
|
|
1809
1844
|
var _a, _b;
|
|
1810
1845
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1896,16 +1931,14 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1896
1931
|
if (this._isPatternSnakeCase()) {
|
|
1897
1932
|
const empty = this.$utils.snakeCase(this._result(emptyData));
|
|
1898
1933
|
const hook = this.$state.get('HOOK');
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
yield hook[i](empty);
|
|
1934
|
+
for (let i in hook)
|
|
1935
|
+
yield hook[i](empty);
|
|
1902
1936
|
return empty;
|
|
1903
1937
|
}
|
|
1904
1938
|
const empty = this._result(emptyData);
|
|
1905
1939
|
const hook = this.$state.get('HOOK');
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
yield hook[i](empty);
|
|
1940
|
+
for (let i in hook)
|
|
1941
|
+
yield hook[i](empty);
|
|
1909
1942
|
return empty;
|
|
1910
1943
|
});
|
|
1911
1944
|
}
|
|
@@ -1980,9 +2013,8 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
1980
2013
|
}
|
|
1981
2014
|
}
|
|
1982
2015
|
const hook = this.$state.get('HOOK');
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
yield hook[i](result);
|
|
2016
|
+
for (let i in hook)
|
|
2017
|
+
yield hook[i](result);
|
|
1986
2018
|
return result;
|
|
1987
2019
|
});
|
|
1988
2020
|
}
|
|
@@ -2222,15 +2254,13 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
2222
2254
|
const result = (data === null || data === void 0 ? void 0 : data.shift()) || null;
|
|
2223
2255
|
this.$state.set('RESULT', result);
|
|
2224
2256
|
const hook = this.$state.get('HOOK');
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
yield hook[i](result);
|
|
2257
|
+
for (let i in hook)
|
|
2258
|
+
yield hook[i](result);
|
|
2228
2259
|
return result;
|
|
2229
2260
|
}
|
|
2230
2261
|
const hook = this.$state.get('HOOK');
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
yield hook[i](result || []);
|
|
2262
|
+
for (let i in hook)
|
|
2263
|
+
yield hook[i](result || []);
|
|
2234
2264
|
return null;
|
|
2235
2265
|
});
|
|
2236
2266
|
}
|
|
@@ -2373,12 +2403,27 @@ class Model extends AbstractModel_1.AbstractModel {
|
|
|
2373
2403
|
'updateOrCreate',
|
|
2374
2404
|
'updateOrInsert',
|
|
2375
2405
|
'insertOrUpdate',
|
|
2376
|
-
'update'
|
|
2406
|
+
'update',
|
|
2407
|
+
'delete'
|
|
2377
2408
|
];
|
|
2378
2409
|
const findMethodNotAllowed = methodCallings.find((methodCalling) => methodsNotAllowed.includes(methodCalling));
|
|
2379
2410
|
this._assertError(methodCallings.some((methodCalling) => methodsNotAllowed.includes(methodCalling)), `this method ${method} can't using method : [ ${findMethodNotAllowed} ]`);
|
|
2380
2411
|
break;
|
|
2381
2412
|
}
|
|
2413
|
+
case 'save': {
|
|
2414
|
+
const methodCallings = this.$logger.get();
|
|
2415
|
+
const methodsSomeAllowed = [
|
|
2416
|
+
'create',
|
|
2417
|
+
'createNotExists',
|
|
2418
|
+
'updateOrCreate',
|
|
2419
|
+
'updateOrInsert',
|
|
2420
|
+
'insertOrUpdate',
|
|
2421
|
+
'update',
|
|
2422
|
+
'delete'
|
|
2423
|
+
];
|
|
2424
|
+
this._assertError(!methodCallings.some((methodCalling) => methodsSomeAllowed.includes(methodCalling)), `this ${method} method need some : [ ${methodsSomeAllowed.join(', ')} ] methods`);
|
|
2425
|
+
break;
|
|
2426
|
+
}
|
|
2382
2427
|
}
|
|
2383
2428
|
}
|
|
2384
2429
|
_initialModel() {
|
package/dist/lib/utils/index.js
CHANGED
|
@@ -123,7 +123,7 @@ const camelCase = (obj) => {
|
|
|
123
123
|
const consoleDebug = (debug) => {
|
|
124
124
|
if (debug == null)
|
|
125
125
|
return;
|
|
126
|
-
console.log(
|
|
126
|
+
console.log(`\n\x1b[33m${debug.replace(/(\r\n|\n|\r|\t)/gm, "").trim()};\x1b[0m`);
|
|
127
127
|
};
|
|
128
128
|
const faker = (value) => {
|
|
129
129
|
if (!value.search('timestamp'))
|