tspace-mysql 1.4.9 → 1.5.0
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 +148 -37
- package/build/cli/generate/make.js +145 -0
- package/build/cli/generate/model.js +20 -0
- package/build/cli/generate/modelDecorator.d.ts +2 -0
- package/build/cli/generate/modelDecorator.js +15 -0
- package/{dist → build}/cli/index.js +4 -1
- package/{dist → build}/lib/Interface.d.ts +5 -0
- package/{dist → build}/lib/constants/index.js +10 -3
- package/{dist → build}/lib/tspace/Abstracts/AbstractModel.d.ts +7 -1
- package/{dist → build}/lib/tspace/Builder.d.ts +1 -75
- package/{dist → build}/lib/tspace/Builder.js +46 -282
- package/{dist → build}/lib/tspace/DB.d.ts +179 -2
- package/build/lib/tspace/DB.js +766 -0
- package/{dist → build}/lib/tspace/Decorator.d.ts +6 -0
- package/{dist → build}/lib/tspace/Decorator.js +10 -2
- package/{dist → build}/lib/tspace/Handlers/State.js +1 -1
- package/{dist → build}/lib/tspace/Model.d.ts +13 -4
- package/{dist → build}/lib/tspace/Model.js +66 -36
- package/package.json +6 -6
- package/dist/cli/generate/make.js +0 -83
- package/dist/cli/generate/model.js +0 -37
- package/dist/lib/tspace/DB.js +0 -340
- /package/{dist → build}/cli/dump/db.d.ts +0 -0
- /package/{dist → build}/cli/dump/db.js +0 -0
- /package/{dist → build}/cli/dump/table.d.ts +0 -0
- /package/{dist → build}/cli/dump/table.js +0 -0
- /package/{dist → build}/cli/generate/make.d.ts +0 -0
- /package/{dist → build}/cli/generate/model.d.ts +0 -0
- /package/{dist → build}/cli/index.d.ts +0 -0
- /package/{dist → build}/cli/migrate/make.d.ts +0 -0
- /package/{dist → build}/cli/migrate/make.js +0 -0
- /package/{dist → build}/cli/models/make.d.ts +0 -0
- /package/{dist → build}/cli/models/make.js +0 -0
- /package/{dist → build}/cli/models/model.d.ts +0 -0
- /package/{dist → build}/cli/models/model.js +0 -0
- /package/{dist → build}/cli/query/index.d.ts +0 -0
- /package/{dist → build}/cli/query/index.js +0 -0
- /package/{dist → build}/cli/tables/make.d.ts +0 -0
- /package/{dist → build}/cli/tables/make.js +0 -0
- /package/{dist → build}/cli/tables/table.d.ts +0 -0
- /package/{dist → build}/cli/tables/table.js +0 -0
- /package/{dist → build}/lib/Interface.js +0 -0
- /package/{dist → build}/lib/connection/index.d.ts +0 -0
- /package/{dist → build}/lib/connection/index.js +0 -0
- /package/{dist → build}/lib/connection/options.d.ts +0 -0
- /package/{dist → build}/lib/connection/options.js +0 -0
- /package/{dist → build}/lib/constants/index.d.ts +0 -0
- /package/{dist → build}/lib/index.d.ts +0 -0
- /package/{dist → build}/lib/index.js +0 -0
- /package/{dist → build}/lib/tspace/Abstracts/AbstractBuilder.d.ts +0 -0
- /package/{dist → build}/lib/tspace/Abstracts/AbstractBuilder.js +0 -0
- /package/{dist → build}/lib/tspace/Abstracts/AbstractDB.d.ts +0 -0
- /package/{dist → build}/lib/tspace/Abstracts/AbstractDB.js +0 -0
- /package/{dist → build}/lib/tspace/Abstracts/AbstractModel.js +0 -0
- /package/{dist → build}/lib/tspace/Blueprint.d.ts +0 -0
- /package/{dist → build}/lib/tspace/Blueprint.js +0 -0
- /package/{dist → build}/lib/tspace/Handlers/Proxy.d.ts +0 -0
- /package/{dist → build}/lib/tspace/Handlers/Proxy.js +0 -0
- /package/{dist → build}/lib/tspace/Handlers/Relation.d.ts +0 -0
- /package/{dist → build}/lib/tspace/Handlers/Relation.js +0 -0
- /package/{dist → build}/lib/tspace/Handlers/State.d.ts +0 -0
- /package/{dist → build}/lib/tspace/Logger.d.ts +0 -0
- /package/{dist → build}/lib/tspace/Logger.js +0 -0
- /package/{dist → build}/lib/tspace/Schema.d.ts +0 -0
- /package/{dist → build}/lib/tspace/Schema.js +0 -0
- /package/{dist → build}/lib/tspace/index.d.ts +0 -0
- /package/{dist → build}/lib/tspace/index.js +0 -0
- /package/{dist → build}/lib/utils/index.d.ts +0 -0
- /package/{dist → build}/lib/utils/index.js +0 -0
- /package/{dist → build}/tests/01-Pool.test.d.ts +0 -0
- /package/{dist → build}/tests/01-Pool.test.js +0 -0
- /package/{dist → build}/tests/02-DB.test.d.ts +0 -0
- /package/{dist → build}/tests/02-DB.test.js +0 -0
- /package/{dist → build}/tests/03-Model.test.d.ts +0 -0
- /package/{dist → build}/tests/03-Model.test.js +0 -0
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ npm install tspace-mysql --save
|
|
|
18
18
|
- [Database Transactions](#database-transactions)
|
|
19
19
|
- [Connection](#connection)
|
|
20
20
|
- [Backup](#backup)
|
|
21
|
+
- [Injection](#injection)
|
|
21
22
|
- [Generating Model Classes](#generating-model-classes)
|
|
22
23
|
- [Model Conventions](#model-conventions)
|
|
23
24
|
- [Relationships](#relationships)
|
|
@@ -100,50 +101,78 @@ Once you have configured your database connection, you can execute queries using
|
|
|
100
101
|
|
|
101
102
|
import { DB } from 'tspace-mysql'
|
|
102
103
|
(async () => {
|
|
103
|
-
await new DB('users').findMany()
|
|
104
|
-
|
|
104
|
+
await new DB('users').findMany()
|
|
105
|
+
// SELECT * FROM users => Array
|
|
106
|
+
await new DB('users').findOne()
|
|
107
|
+
// SELECT * FROM users LIMIT 1 => Object
|
|
105
108
|
})()
|
|
106
109
|
|
|
107
110
|
```
|
|
108
111
|
Running A Raw Query
|
|
109
112
|
```js
|
|
110
|
-
const rawQuery = await new DB().query('SELECT * FROM users')
|
|
113
|
+
const rawQuery = await new DB().query('SELECT * FROM users')
|
|
114
|
+
// SELECT * FROM users;
|
|
111
115
|
|
|
112
116
|
```
|
|
113
117
|
Running A Select Query
|
|
114
118
|
```js
|
|
115
119
|
const select = await new DB('users').select('id','username').findOne()
|
|
120
|
+
// SELECT `users`.`id`, `users`.`username` FROM `users` LIMIT 1;
|
|
116
121
|
|
|
117
122
|
const selectRaw = await new DB('users').selectRaw('COUNT(id)').findMany()
|
|
123
|
+
// SELECT COUNT(id) FROM `users`;
|
|
118
124
|
|
|
119
125
|
const selectObject = await new DB('posts')
|
|
120
126
|
.join('posts.user_id', 'users.id')
|
|
121
127
|
.select('posts.*')
|
|
122
|
-
.selectObject({ id : 'users.id', name : 'users.name' , email : 'users.email'},'user')
|
|
128
|
+
.selectObject({ id : 'users.id', name : 'users.name' , email : 'users.email'} , 'user')
|
|
123
129
|
.findOne()
|
|
124
130
|
|
|
131
|
+
// SELECT posts.*, JSON_OBJECT('id' , `users`.`id` , 'name' , `users`.`name` , 'email' , `users`.`email`) AS `user`
|
|
132
|
+
// FROM `posts` INNER JOIN `users` ON `posts`.`user_id` = `users`.`id` LIMIT 1;
|
|
133
|
+
|
|
125
134
|
/**
|
|
126
135
|
* @example except
|
|
127
136
|
*/
|
|
128
|
-
await new DB('users').except('id'
|
|
137
|
+
await new DB('users').except('id').findOne()
|
|
138
|
+
// SELECT `users`.`email`, `users`.`username` FROM `users` LIMIT 1;
|
|
129
139
|
```
|
|
130
140
|
|
|
131
141
|
Running A OrderBy & GroupBy Query
|
|
132
142
|
```js
|
|
133
143
|
await new DB('users').orderBy('id','asc').findOne()
|
|
144
|
+
// SELECT * FROM `users` ORDER BY `id` ASC LIMIT 1;
|
|
145
|
+
|
|
134
146
|
await new DB('users').orderBy('id','desc').findOne()
|
|
147
|
+
// SELECT * FROM `users` ORDER BY `id` DESC LIMIT 1;
|
|
148
|
+
|
|
135
149
|
await new DB('users').oldest('id').findOne()
|
|
150
|
+
// SELECT * FROM `users` ORDER BY `id` ASC LIMIT 1;
|
|
151
|
+
|
|
136
152
|
await new DB('users').latest('id').findOne()
|
|
153
|
+
// SELECT * FROM `users` ORDER BY `id` DESC LIMIT 1;
|
|
137
154
|
|
|
138
155
|
await new DB('users').groupBy('id').findOne()
|
|
139
|
-
|
|
156
|
+
// SELECT * FROM `users` GROUP BY `id` LIMIT 1;
|
|
157
|
+
|
|
158
|
+
await new DB('users').groupBy('id','username').findOne()
|
|
159
|
+
// SELECT * FROM `users` GROUP BY `id`, `username` LIMIT 1;
|
|
160
|
+
|
|
161
|
+
await new DB('users').orderBy('id').groupBy('id','username').findOne()
|
|
162
|
+
// SELECT * FROM `users` GROUP BY `id`, `username` ORDER BY `id` ASC LIMIT 1;
|
|
163
|
+
|
|
140
164
|
```
|
|
141
165
|
|
|
142
166
|
Running A Join Query
|
|
143
167
|
```js
|
|
144
168
|
await new DB('posts').join('posts.user_id' , 'users.id').findMany()
|
|
169
|
+
// SELECT * FROM `posts` INNER JOIN `users` ON `posts`.`user_id` = `users`.`id`;
|
|
170
|
+
|
|
145
171
|
await new DB('posts').leftJoin('posts.user_id' , 'users.id').findMany()
|
|
172
|
+
// SELECT * FROM `posts` LEFT JOIN `users` ON `posts`.`user_id` = `users`.`id`;
|
|
173
|
+
|
|
146
174
|
await new DB('posts').rightJoin('posts.user_id' , 'users.id').findMany()
|
|
175
|
+
// SELECT * FROM `posts` RIGHT JOIN `users` ON `posts`.`user_id` = `users`.`id`;
|
|
147
176
|
```
|
|
148
177
|
|
|
149
178
|
Running A Where Query
|
|
@@ -162,7 +191,7 @@ const whereBetween = await new DB('users').whereBetween('id',[1,2]).findMany()
|
|
|
162
191
|
|
|
163
192
|
const whereSubQuery = await new DB('users').whereSubQuery('id','SELECT id FROM users').findMany()
|
|
164
193
|
// SELECT * FROM `users` WHERE `users`.`id` IN (SELECT id FROM users);
|
|
165
|
-
//
|
|
194
|
+
// also you can use -> await new DB('users').whereSubQuery('id',new DB('users').select('id').toString()).findMany()
|
|
166
195
|
|
|
167
196
|
const whereNull = await new DB('users').whereNull('username').findOne()
|
|
168
197
|
// SELECT * FROM `users` WHERE `users`.`username` IS NULL LIMIT 1;
|
|
@@ -189,15 +218,16 @@ const whereWhenIsFalse = await new DB('users').where('id',1).when(false, (query)
|
|
|
189
218
|
Running A Hook Query
|
|
190
219
|
```js
|
|
191
220
|
const hookResult = (result) => console.log('hook!! result => ',result)
|
|
192
|
-
const user = await new DB('users').where('id',1).hook(hookResult).
|
|
221
|
+
const user = await new DB('users').where('id',1).hook(hookResult).findMany()
|
|
193
222
|
```
|
|
194
223
|
|
|
195
224
|
Running A Faker
|
|
196
225
|
```js
|
|
197
226
|
|
|
198
|
-
await new DB('users').faker(
|
|
199
|
-
|
|
200
|
-
|
|
227
|
+
await new DB('users').faker(10)
|
|
228
|
+
|
|
229
|
+
// custom faker
|
|
230
|
+
await new DB('users').faker(10 , (row , index) => {
|
|
201
231
|
return {
|
|
202
232
|
...row,
|
|
203
233
|
custom : 'custom' + index
|
|
@@ -213,7 +243,7 @@ const user = await new DB('users')
|
|
|
213
243
|
email : 'tspace3@gmail.com'
|
|
214
244
|
})
|
|
215
245
|
.save()
|
|
216
|
-
//
|
|
246
|
+
// INSERT INTO `users` (`name`,`email`) VALUES ('tspace3','tspace3@gmail.com');
|
|
217
247
|
|
|
218
248
|
+--------------------------------------------------------------------------+
|
|
219
249
|
const users = await new DB('users')
|
|
@@ -233,6 +263,8 @@ const users = await new DB('users')
|
|
|
233
263
|
])
|
|
234
264
|
.save()
|
|
235
265
|
|
|
266
|
+
// INSERT INTO `users` (`name`,`email`) VALUES ('tspace4','tspace4@gmail.com'),('tspace5','tspace5@gmail.com'),('tspace6','tspace6@gmail.com');
|
|
267
|
+
|
|
236
268
|
const users = await new DB('users')
|
|
237
269
|
.where('name','tspace4')
|
|
238
270
|
.where('email','tspace4@gmail.com')
|
|
@@ -241,7 +273,10 @@ const users = await new DB('users')
|
|
|
241
273
|
email : 'tspace4@gmail.com'
|
|
242
274
|
})
|
|
243
275
|
.save()
|
|
244
|
-
// if
|
|
276
|
+
// if exists return null, if not exists created new data
|
|
277
|
+
// SELECT EXISTS(SELECT 1 FROM `users` WHERE `users`.`name` = 'tspace4' AND `users`.`email` = 'tspace4@gmail.com' LIMIT 1) AS 'exists';
|
|
278
|
+
// INSERT INTO `users` (`name`,`email`) VALUES ('tspace4','tspace4@gmail.com');
|
|
279
|
+
|
|
245
280
|
|
|
246
281
|
const users = await new DB('users')
|
|
247
282
|
.where('name','tspace4')
|
|
@@ -252,6 +287,9 @@ const users = await new DB('users')
|
|
|
252
287
|
})
|
|
253
288
|
.save()
|
|
254
289
|
// if has exists return data, if not exists created new data
|
|
290
|
+
// SELECT EXISTS(SELECT 1 FROM `users` WHERE `users`.`name` = 'tspace4' AND `users`.`email` = 'tspace4@gmail.com' LIMIT 1) AS 'exists';
|
|
291
|
+
// SELECT * FROM `users` WHERE `users`.`name` = 'tspace4' AND `users`.`email` = 'tspace4@gmail.com';
|
|
292
|
+
// INSERT INTO `users` (`name`,`email`) VALUES ('tspace4','tspace4@gmail.com');
|
|
255
293
|
|
|
256
294
|
```
|
|
257
295
|
Running A Update Query
|
|
@@ -308,17 +346,17 @@ try {
|
|
|
308
346
|
await connection.startTransaction()
|
|
309
347
|
|
|
310
348
|
const user = await new User()
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
349
|
+
.create({
|
|
350
|
+
name : `tspace`,
|
|
351
|
+
email : 'tspace@example.com'
|
|
352
|
+
})
|
|
353
|
+
/**
|
|
354
|
+
*
|
|
355
|
+
* bind method for make sure this connection has same transaction in connection
|
|
356
|
+
* @params {Function} connection
|
|
357
|
+
*/
|
|
358
|
+
.bind(connection)
|
|
359
|
+
.save()
|
|
322
360
|
|
|
323
361
|
const posts = await new Post()
|
|
324
362
|
.createMultiple([
|
|
@@ -366,9 +404,8 @@ const connection = await new DB().getConnection({
|
|
|
366
404
|
})
|
|
367
405
|
|
|
368
406
|
const users = await new DB('users')
|
|
369
|
-
.bind(connection)
|
|
407
|
+
.bind(connection) // don't forget this
|
|
370
408
|
.findMany()
|
|
371
|
-
// users => [{ .... }]
|
|
372
409
|
```
|
|
373
410
|
|
|
374
411
|
## Backup
|
|
@@ -376,14 +413,14 @@ To backup a database, you can perform the following steps:
|
|
|
376
413
|
```js
|
|
377
414
|
/**
|
|
378
415
|
*
|
|
379
|
-
* @param
|
|
416
|
+
* @param {string} database Database selected
|
|
417
|
+
* @param {object | null} to defalut new current connection
|
|
380
418
|
*/
|
|
381
419
|
const backup = await new DB().backup({
|
|
382
|
-
|
|
383
|
-
|
|
420
|
+
database: 'try-to-backup', // clone current database to this database
|
|
421
|
+
to ?: {
|
|
384
422
|
host: 'localhost',
|
|
385
423
|
port : 3306,
|
|
386
|
-
database: 'database'
|
|
387
424
|
username: 'username',
|
|
388
425
|
password: 'password',
|
|
389
426
|
}
|
|
@@ -406,6 +443,28 @@ const backupToFile = await new DB().backupToFile({
|
|
|
406
443
|
}
|
|
407
444
|
})
|
|
408
445
|
// backupToFile => backup.sql
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
*
|
|
449
|
+
* @param {string} database new db name
|
|
450
|
+
*/
|
|
451
|
+
await new DB().cloneDB('try-to-clone')
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Injection
|
|
456
|
+
The 'tspace-mysql' library is configured to automatically escape SQL injection by default.
|
|
457
|
+
Let's example a escape SQL injection and XSs injection:
|
|
458
|
+
```js
|
|
459
|
+
const input = "admin' OR '1'='1"
|
|
460
|
+
DB.escape(input)
|
|
461
|
+
// admin OR 1=1
|
|
462
|
+
|
|
463
|
+
//XSS
|
|
464
|
+
const input = "text hello!<script>alert('XSS attack');</script>"
|
|
465
|
+
DB.escapeXSS(input)
|
|
466
|
+
// text hello!
|
|
467
|
+
|
|
409
468
|
```
|
|
410
469
|
|
|
411
470
|
## Generating Model Classes
|
|
@@ -425,14 +484,41 @@ npm install tspace-mysql -g
|
|
|
425
484
|
tspace-mysql make:model <model name> --dir=< directory >
|
|
426
485
|
|
|
427
486
|
# tspace-mysql make:model User --dir=App/Models
|
|
428
|
-
#
|
|
487
|
+
# App/Models/User.ts
|
|
429
488
|
```
|
|
430
489
|
## Model Conventions
|
|
431
490
|
Models generated by the make:model command will be placed in the specific directory.
|
|
432
|
-
Let's
|
|
491
|
+
Let's example a basic model class:
|
|
433
492
|
|
|
434
493
|
```js
|
|
435
494
|
import { Model } from 'tspace-mysql'
|
|
495
|
+
// If you want to specify a global setting for the 'Model'
|
|
496
|
+
Model.global({
|
|
497
|
+
uuid: true,
|
|
498
|
+
softDelete: true,
|
|
499
|
+
timestamp: true
|
|
500
|
+
})
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
class Observe {
|
|
504
|
+
|
|
505
|
+
public selected(results : unknown) {
|
|
506
|
+
console.log({ results , selected : true })
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
public created(results : unknown) {
|
|
510
|
+
console.log({ results , created : true })
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
public updated(results : unknown) {
|
|
514
|
+
console.log({ results , updated : true })
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
public deleted(results : unknown) {
|
|
518
|
+
console.log({ results , deleted : true })
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
*/
|
|
436
522
|
class User extends Model {
|
|
437
523
|
constructor(){
|
|
438
524
|
super()
|
|
@@ -456,6 +542,7 @@ class User extends Model {
|
|
|
456
542
|
* this.useLoadRelationsInRegistry() // => auto generated result from relationship to results
|
|
457
543
|
* this.useBuiltInRelationFunctions() // => build-in functions relationships to results
|
|
458
544
|
* this.useHooks([(r) => console.log(r)])
|
|
545
|
+
* this.useObserver(Observe)
|
|
459
546
|
* this.useSchema ({
|
|
460
547
|
* id : new Blueprint().int().notNull().primary().autoIncrement(),
|
|
461
548
|
* uuid : new Blueprint().varchar(50).null(),
|
|
@@ -864,22 +951,42 @@ for (const post of posts) {
|
|
|
864
951
|
|
|
865
952
|
## Decorator
|
|
866
953
|
Decorators can be used in a Model.
|
|
867
|
-
Let's illustrate this with an example of a
|
|
954
|
+
Let's illustrate this with an example of a decorators:
|
|
868
955
|
```js
|
|
869
956
|
|
|
870
957
|
import {
|
|
871
|
-
Blueprint,
|
|
872
|
-
Model ,
|
|
958
|
+
Blueprint, Model ,
|
|
873
959
|
Table ,TableSingular, TablePlural,
|
|
874
960
|
UUID, SoftDelete, Timestamp,
|
|
875
|
-
|
|
961
|
+
Pattern, CamelCase , snakeCase ,
|
|
962
|
+
Column, Validate, Observer,
|
|
876
963
|
HasMany, HasOne, BelongsTo, BelongsToMany
|
|
877
964
|
|
|
878
965
|
} from 'tspace-mysql'
|
|
879
966
|
import { Post } from './Post'
|
|
880
967
|
import { PostUser } from './PostUser'
|
|
881
968
|
|
|
969
|
+
class UserObserve {
|
|
970
|
+
|
|
971
|
+
public selected(results : any) {
|
|
972
|
+
console.log({ results , selected : true })
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
public created(results : unknown) {
|
|
976
|
+
console.log({ results , created : true })
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
public updated(results : unknown) {
|
|
980
|
+
console.log({ results , updated : true })
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
public deleted(results : unknown) {
|
|
984
|
+
console.log({ results , deleted : true })
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
882
988
|
@Pattern('camelCase')
|
|
989
|
+
@Observer(UserObserve)
|
|
883
990
|
@UUID()
|
|
884
991
|
@SoftDelete()
|
|
885
992
|
@Timestamp()
|
|
@@ -1040,6 +1147,9 @@ class Post extends Model {
|
|
|
1040
1147
|
}
|
|
1041
1148
|
await Schema.sync(`src/Models` , { force : true })
|
|
1042
1149
|
|
|
1150
|
+
// also you can sync by Model
|
|
1151
|
+
await new User().sync({ force : true })
|
|
1152
|
+
|
|
1043
1153
|
```
|
|
1044
1154
|
## Query Builder
|
|
1045
1155
|
Methods builder for queries
|
|
@@ -1065,7 +1175,6 @@ orWhereRaw(sql)
|
|
|
1065
1175
|
orWhereIn(column , [])
|
|
1066
1176
|
orWhereSubQuery(colmn , rawSQL)
|
|
1067
1177
|
when(contition , callback)
|
|
1068
|
-
if(contition , callback)
|
|
1069
1178
|
select(column1 ,column2 ,...N)
|
|
1070
1179
|
distinct()
|
|
1071
1180
|
selectRaw(column1 ,column2 ,...N)
|
|
@@ -1261,6 +1370,8 @@ Command will be generate models from table in database
|
|
|
1261
1370
|
tspace-mysql generate:models --dir=<folder for creating>
|
|
1262
1371
|
or
|
|
1263
1372
|
tspace-mysql gen:models --dir=<folder for creating> --env=development
|
|
1373
|
+
or
|
|
1374
|
+
tspace-mysql generate:models --dir=app/Models --env=development --decorators
|
|
1264
1375
|
|
|
1265
1376
|
```
|
|
1266
1377
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const model_1 = __importDefault(require("./model"));
|
|
7
|
+
const modelDecorator_1 = __importDefault(require("./modelDecorator"));
|
|
8
|
+
const pluralize_1 = __importDefault(require("pluralize"));
|
|
9
|
+
const lib_1 = require("../../lib");
|
|
10
|
+
const snakeCaseToPascal = (data) => {
|
|
11
|
+
let str = data.split('_');
|
|
12
|
+
for (let i = 0; i < str.length; i++) {
|
|
13
|
+
str[i] = str[i].slice(0, 1).toUpperCase() + str[i].slice(1, str[i].length);
|
|
14
|
+
}
|
|
15
|
+
return str.join('');
|
|
16
|
+
};
|
|
17
|
+
const formatSchema = (data) => {
|
|
18
|
+
const formattedCode = {};
|
|
19
|
+
for (const field of data) {
|
|
20
|
+
const [key, value] = field.split(":").map((item) => item.trim());
|
|
21
|
+
formattedCode[key] = value;
|
|
22
|
+
}
|
|
23
|
+
return formattedCode;
|
|
24
|
+
};
|
|
25
|
+
exports.default = (cmd) => {
|
|
26
|
+
const { dir, cwd, type, fs, decorator, env, npm } = cmd;
|
|
27
|
+
if (dir) {
|
|
28
|
+
try {
|
|
29
|
+
fs.accessSync(`${cwd}/${dir}`, fs.F_OK, {
|
|
30
|
+
recursive: true
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
fs.mkdirSync(`${cwd}/${dir}`, {
|
|
35
|
+
recursive: true
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (decorator) {
|
|
40
|
+
new lib_1.DB()
|
|
41
|
+
.loadEnv(env)
|
|
42
|
+
.rawQuery('SHOW TABLES')
|
|
43
|
+
.then(tables => {
|
|
44
|
+
var _a;
|
|
45
|
+
for (let i = 0; i < tables.length; i++) {
|
|
46
|
+
const table = String((_a = Object.values(tables[i])) === null || _a === void 0 ? void 0 : _a.shift());
|
|
47
|
+
const model = snakeCaseToPascal(pluralize_1.default.singular(table));
|
|
48
|
+
new lib_1.DB().loadEnv(env).rawQuery(`SHOW COLUMNS FROM \`${table}\``).then(raws => {
|
|
49
|
+
let schema = [];
|
|
50
|
+
for (const raw of raws) {
|
|
51
|
+
const schemaColumn = [
|
|
52
|
+
`@Column(() => `,
|
|
53
|
+
`new Blueprint().${/^[^()]*$/.test(raw.Type)
|
|
54
|
+
? raw.Type === raw.Type.includes('unsigned')
|
|
55
|
+
? 'int().unsigned()'
|
|
56
|
+
: `${raw.Type.toLocaleLowerCase()}()`
|
|
57
|
+
: raw.Type.toLocaleLowerCase()}`,
|
|
58
|
+
`${raw.Null === 'YES' ? '.null()' : '.notNull()'}`,
|
|
59
|
+
raw.Key === 'PRI' ? '.primary()' : raw.Key === 'UNI' ? '.unique()' : '',
|
|
60
|
+
raw.Default != null ? `.default('${raw.Default}')` : '',
|
|
61
|
+
`${raw.Extra === 'auto_increment' ? '.autoIncrement()' : ''}`,
|
|
62
|
+
`)`
|
|
63
|
+
].join('');
|
|
64
|
+
const detectType = (type) => {
|
|
65
|
+
const t = type.toLowerCase();
|
|
66
|
+
const typeForNumber = ['INT', 'TINYINT', 'BIGINT', 'DOUBLE', 'FLOAT'].map(r => r.toLowerCase());
|
|
67
|
+
const typeForDate = ['DATE', 'DATETIME', 'TIMESTAMP'].map(r => r.toLowerCase());
|
|
68
|
+
if (typeForNumber.some(v => t.includes(v)))
|
|
69
|
+
return 'number';
|
|
70
|
+
if (typeForDate.some(v => t.includes(v)))
|
|
71
|
+
return 'Date';
|
|
72
|
+
return 'string';
|
|
73
|
+
};
|
|
74
|
+
const publicColumn = `public ${raw.Field} !: ${detectType(raw.Type)}`;
|
|
75
|
+
schema.push({
|
|
76
|
+
schemaColumn,
|
|
77
|
+
publicColumn
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
let str = '';
|
|
81
|
+
for (const i in schema) {
|
|
82
|
+
const s = schema[i];
|
|
83
|
+
const isLast = +i === schema.length - 1;
|
|
84
|
+
str += ` ${s.schemaColumn} \n`;
|
|
85
|
+
str += ` ${s.publicColumn} ${isLast ? '' : '\n\n'}`;
|
|
86
|
+
}
|
|
87
|
+
const data = (0, modelDecorator_1.default)(model, npm, str, table);
|
|
88
|
+
fs.writeFile(`mock/${model}${'.ts'}`, data, (err) => {
|
|
89
|
+
if (err)
|
|
90
|
+
throw err;
|
|
91
|
+
});
|
|
92
|
+
console.log(`Model : '${model}' created successfully`);
|
|
93
|
+
}).catch(err => console.log(err));
|
|
94
|
+
}
|
|
95
|
+
console.log('\nGenerate Models has completed');
|
|
96
|
+
})
|
|
97
|
+
.catch(err => console.log(err));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
new lib_1.DB()
|
|
101
|
+
.loadEnv(env)
|
|
102
|
+
.rawQuery('SHOW TABLES')
|
|
103
|
+
.then(tables => {
|
|
104
|
+
var _a;
|
|
105
|
+
for (let i = 0; i < tables.length; i++) {
|
|
106
|
+
const table = String((_a = Object.values(tables[i])) === null || _a === void 0 ? void 0 : _a.shift());
|
|
107
|
+
const model = snakeCaseToPascal(pluralize_1.default.singular(table));
|
|
108
|
+
new lib_1.DB().loadEnv(env).rawQuery(`SHOW COLUMNS FROM \`${table}\``).then(raws => {
|
|
109
|
+
let schema = [];
|
|
110
|
+
for (const index in raws) {
|
|
111
|
+
const raw = raws[index];
|
|
112
|
+
const str = [
|
|
113
|
+
`${raw.Field} : `,
|
|
114
|
+
`new Blueprint().${/^[^()]*$/.test(raw.Type)
|
|
115
|
+
? raw.Type === raw.Type.includes('unsigned')
|
|
116
|
+
? 'int().unsigned()'
|
|
117
|
+
: `${raw.Type.toLocaleLowerCase()}()`
|
|
118
|
+
: raw.Type.toLocaleLowerCase()}`,
|
|
119
|
+
`${raw.Null === 'YES' ? '.null()' : '.notNull()'}`,
|
|
120
|
+
raw.Key === 'PRI' ? '.primary()' : raw.Key === 'UNI' ? '.unique()' : '',
|
|
121
|
+
raw.Default != null ? `.default('${raw.Default}')` : '',
|
|
122
|
+
`${raw.Extra === 'auto_increment' ? '.autoIncrement()' : ''},`
|
|
123
|
+
].join('');
|
|
124
|
+
const isLast = Number(index) + 1 === raws.length;
|
|
125
|
+
schema.push(isLast ? str.replace(/,\s*$/, "") : str);
|
|
126
|
+
}
|
|
127
|
+
const formattedSchema = formatSchema(schema);
|
|
128
|
+
let str = "this.useSchema({\n";
|
|
129
|
+
for (const formatKey in formattedSchema) {
|
|
130
|
+
str += ` ${formatKey} : ${formattedSchema[formatKey]} \n`;
|
|
131
|
+
}
|
|
132
|
+
str += " })";
|
|
133
|
+
const data = (0, model_1.default)(model, npm, `${str}`);
|
|
134
|
+
fs.writeFile(`${cwd}/${dir}/${model}${type !== null && type !== void 0 ? type : '.ts'}`, data, (err) => {
|
|
135
|
+
if (err)
|
|
136
|
+
throw err;
|
|
137
|
+
});
|
|
138
|
+
console.log(`Model : '${model}' created successfully`);
|
|
139
|
+
})
|
|
140
|
+
.catch(err => console.log(err));
|
|
141
|
+
}
|
|
142
|
+
console.log('\nGenerate Models has completed');
|
|
143
|
+
})
|
|
144
|
+
.catch(err => console.log(err));
|
|
145
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Model = (model, npm, schema) => {
|
|
4
|
+
return `import { Model , Blueprint } from '${npm}'
|
|
5
|
+
class ${model} extends Model {
|
|
6
|
+
constructor(){
|
|
7
|
+
super()
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @Schema table
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
${schema}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export { ${model} }
|
|
17
|
+
export default ${model}
|
|
18
|
+
`;
|
|
19
|
+
};
|
|
20
|
+
exports.default = Model;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Model = (model, npm, schema, table) => {
|
|
4
|
+
return `import { Model , Blueprint , Column, Table } from '${npm}'
|
|
5
|
+
|
|
6
|
+
@Table('${table}')
|
|
7
|
+
class ${model} extends Model {
|
|
8
|
+
|
|
9
|
+
${schema}
|
|
10
|
+
}
|
|
11
|
+
export { ${model} }
|
|
12
|
+
export default ${model}
|
|
13
|
+
`;
|
|
14
|
+
};
|
|
15
|
+
exports.default = Model;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
6
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const make_1 = __importDefault(require("./models/make"));
|
|
@@ -48,6 +48,7 @@ try {
|
|
|
48
48
|
return data === null || data === void 0 ? void 0 : data.includes('--env=');
|
|
49
49
|
})) === null || _w === void 0 ? void 0 : _w.replace('--env=', '')) !== null && _x !== void 0 ? _x : null;
|
|
50
50
|
const values = (_0 = (((_y = process.argv.slice(2)) === null || _y === void 0 ? void 0 : _y.includes('--values')) || ((_z = process.argv.slice(2)) === null || _z === void 0 ? void 0 : _z.includes('--v')))) !== null && _0 !== void 0 ? _0 : false;
|
|
51
|
+
const decorator = (_3 = (((_1 = process.argv.slice(2)) === null || _1 === void 0 ? void 0 : _1.includes('--decorator')) || ((_2 = process.argv.slice(2)) === null || _2 === void 0 ? void 0 : _2.includes('--decorators')))) !== null && _3 !== void 0 ? _3 : false;
|
|
51
52
|
if (env != null)
|
|
52
53
|
process.env.NODE_ENV = env;
|
|
53
54
|
const cmd = {
|
|
@@ -62,6 +63,7 @@ try {
|
|
|
62
63
|
db,
|
|
63
64
|
table,
|
|
64
65
|
values,
|
|
66
|
+
decorator,
|
|
65
67
|
env,
|
|
66
68
|
npm: 'tspace-mysql'
|
|
67
69
|
};
|
|
@@ -75,6 +77,7 @@ catch (err) {
|
|
|
75
77
|
tspace-mysql migrate --dir=App/Models/Migrations --type=js
|
|
76
78
|
tspace-mysql query "SELECT * FROM users" --env=development
|
|
77
79
|
tspace-mysql generate:models --dir=app/Models --env=development
|
|
80
|
+
tspace-mysql generate:models --dir=app/Models --env=development --decorators
|
|
78
81
|
tspace-mysql dump:db "database" --dir=app/db --v --env=development
|
|
79
82
|
tspace-mysql dump:table "table" --dir=app/table --v --env=development
|
|
80
83
|
\x1b[0m
|
|
@@ -62,14 +62,21 @@ const CONSTANTS = Object.freeze({
|
|
|
62
62
|
DROP_TABLE: 'DROP TABLE',
|
|
63
63
|
TRUNCATE_TABLE: 'TRUNCATE TABLE',
|
|
64
64
|
CREATE_DATABASE: 'CREATE DATABASE',
|
|
65
|
+
SHOW_DATABASES: 'SHOW DATABASES',
|
|
66
|
+
SHOW_TABLES: 'SHOW TABLES',
|
|
65
67
|
CREATE_DATABASE_NOT_EXISTS: 'CREATE DATABASE IF NOT EXISTS',
|
|
66
68
|
CREATE_TABLE: 'CREATE TABLE',
|
|
67
69
|
CREATE_TABLE_NOT_EXISTS: 'CREATE TABLE IF NOT EXISTS',
|
|
68
70
|
ENGINE: 'ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4',
|
|
69
71
|
RAND: 'RAND()',
|
|
70
|
-
|
|
72
|
+
FOREIGN_KEY: 'FOREIGN KEY',
|
|
73
|
+
REFERENCES: 'REFERENCES',
|
|
74
|
+
ON_DELETE: 'ON DELETE',
|
|
75
|
+
ON_UPDATE: 'ON UPDATE',
|
|
71
76
|
ADD: 'ADD',
|
|
77
|
+
ADD_CONSTRAINT: 'ADD CONSTRAINT',
|
|
72
78
|
AFTER: 'AFTER',
|
|
79
|
+
ALTER_TABLE: 'ALTER TABLE',
|
|
73
80
|
JSON_OBJECT: 'JSON_OBJECT',
|
|
74
81
|
RELATIONSHIP: {
|
|
75
82
|
hasOne: 'hasOne',
|
|
@@ -103,7 +110,7 @@ const CONSTANTS = Object.freeze({
|
|
|
103
110
|
JOIN: [],
|
|
104
111
|
WHERE: [],
|
|
105
112
|
GROUP_BY: '',
|
|
106
|
-
ORDER_BY:
|
|
113
|
+
ORDER_BY: [],
|
|
107
114
|
LIMIT: '',
|
|
108
115
|
OFFSET: '',
|
|
109
116
|
HAVING: '',
|
|
@@ -131,7 +138,7 @@ const CONSTANTS = Object.freeze({
|
|
|
131
138
|
JOIN: [],
|
|
132
139
|
WHERE: [],
|
|
133
140
|
GROUP_BY: '',
|
|
134
|
-
ORDER_BY:
|
|
141
|
+
ORDER_BY: [],
|
|
135
142
|
LIMIT: '',
|
|
136
143
|
OFFSET: '',
|
|
137
144
|
HAVING: '',
|
|
@@ -12,15 +12,21 @@ declare abstract class AbstractModel extends Builder {
|
|
|
12
12
|
protected $hasOne: RelationQuery[] | undefined;
|
|
13
13
|
protected $belongsTo: RelationQuery[] | undefined;
|
|
14
14
|
protected $belongsToMany: RelationQuery[] | undefined;
|
|
15
|
-
protected $uuid: boolean | undefined;
|
|
16
15
|
protected $timestamp: boolean | undefined;
|
|
17
16
|
protected $softDelete: boolean | undefined;
|
|
17
|
+
protected $uuid: boolean | undefined;
|
|
18
18
|
protected $uuidColumn: string | undefined;
|
|
19
19
|
protected $timestampColumns: {
|
|
20
20
|
createdAt: string;
|
|
21
21
|
updatedAt: string;
|
|
22
22
|
} | undefined;
|
|
23
23
|
protected $softDeleteColumn: string | undefined;
|
|
24
|
+
protected $observer: (new () => {
|
|
25
|
+
selected: Function;
|
|
26
|
+
created: Function;
|
|
27
|
+
updated: Function;
|
|
28
|
+
deleted: Function;
|
|
29
|
+
}) | undefined;
|
|
24
30
|
protected abstract useUUID(): this;
|
|
25
31
|
protected abstract usePrimaryKey(primaryKey: string): this;
|
|
26
32
|
protected abstract useRegistry(): this;
|