tspace-mysql 1.0.8 → 1.1.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 CHANGED
@@ -4,7 +4,7 @@
4
4
  [![NPM downloads](https://img.shields.io/npm/dm/tspace-mysql.svg)](https://www.npmjs.com)
5
5
 
6
6
  TspaceMySQL is an ORM that can run in NodeJs and can be used with TypeScript.
7
- Its goal is to always support the latest TypeScript and JavaScript features and provide additional features that help you to develop.
7
+ The goal is to always support the latest TypeScript and JavaScript features and provide additional features that help you to develop.
8
8
 
9
9
  ## Install
10
10
 
@@ -14,6 +14,7 @@ Install with [npm](https://www.npmjs.com/):
14
14
  npm install tspace-mysql --save
15
15
  ```
16
16
  ## Basic Usage
17
+ - [Install](#install)
17
18
  - [Configuration](#configuration)
18
19
  - [Running Queries](#running-queryies)
19
20
  - [Database Transactions](#database-transactions)
@@ -24,27 +25,33 @@ npm install tspace-mysql --save
24
25
  - [Relationships](#relationships)
25
26
  - [One To One](#one-to-one)
26
27
  - [One To Many](#one-to-many)
27
- - [One To One & One To Many (Inverse) / Belongs To](#inverse-belongs-to)
28
+ - [Belongs To](#belongs-to)
28
29
  - [Many To Many](#many-to-many)
30
+ - [Deep Relationships](#deep-relationships)
29
31
  - [Query Builder](#query-builder)
30
32
  - [Cli](#cli)
31
33
  - [Make Model](#make-model)
32
34
  - [Make Migration](#make-migration)
33
35
  - [Migrate](#migrate)
34
36
  - [Blueprint](#blueprint)
37
+ - [Types](#types)
38
+ - [Attrbuites](#attrbuites)
35
39
 
36
40
  ## Configuration
37
41
  Created your environment variables is to use a .env file, you may establish a connection is this:
42
+
38
43
  ```js
39
- DB_HOST = localhost
40
- DB_PORT = 3306
44
+ DB_HOST = localhost
45
+ DB_PORT = 3306
41
46
  DB_USERNAME = root
42
47
  DB_PASSWORD = password
43
48
  DB_DATABASE = database
44
49
  ```
45
50
  ## Running Queries
46
51
  Once you have configured your database connection, you may run queries is this :
52
+
47
53
  ```js
54
+
48
55
  +-------------+--------------+----------------------------+
49
56
  | table users |
50
57
  +-------------+--------------+----------------------------+
@@ -60,14 +67,18 @@ import { DB } from 'tspace-mysql'
60
67
  await new DB('users').findOne() // SELECT * FROM users LIMIT 1 => Object
61
68
  })()
62
69
  ```
70
+
63
71
  Running A Select Query
72
+
64
73
  ```js
65
74
  const selectQuery = await new DB('users').select('id','username').findOne()
66
75
  // selectQuery => { id : 1, username : 'tspace'}
67
76
  const selectQueries = await new DB('users').select('id','username').findMany()
68
77
  // selectQueries => [{ id : 1, username : 'tspace' } , { id : 2, username : 'tspace2'}]
69
78
  ```
79
+
70
80
  Running A Where Query
81
+
71
82
  ```js
72
83
  const user = await new DB('users').where('id',1).findOne()
73
84
  // user => { id : 1 , username : 'tspace', email : 'tspace@gmail.com'}
@@ -75,6 +86,7 @@ const users = await new DB('users').where('id','!=',1).findMany()
75
86
  // users => [{ id : 2 , username : 'tspace2' , email : 'tspace2@gmail.com' }]
76
87
  ```
77
88
  Running A Insert Query
89
+
78
90
  ```js
79
91
  const user = await new DB('users').create({
80
92
  name : 'tspace3',
@@ -92,6 +104,7 @@ const { result } = reposity
92
104
  // result => { id : 4 , username : 'tspace4', email : 'tspace4@gmail.com'}
93
105
  ```
94
106
  Running A Update Query
107
+
95
108
  ```js
96
109
  const user = await new DB('users').where('id',1)
97
110
  .update({
@@ -110,6 +123,7 @@ const { result } = reposity
110
123
  // result => { id : 1 , username : 'tspace1++', email : 'tspace1++@gmail.com'}
111
124
  ```
112
125
  Running A Delete Query
126
+
113
127
  ```js
114
128
  const deleted = await new DB('users').where('id',1).delete()
115
129
  // deleted => true
@@ -146,14 +160,15 @@ try {
146
160
 
147
161
  ## Connection
148
162
  When establishing a connection, you may establish options is this:
163
+
149
164
  ```js
150
165
  const users = await new DB('users')
151
166
  .connection({
152
- host: 'localhost..',
153
- port : 3306,
154
- database: 'database'
155
- username: 'username',
156
- password: 'password',
167
+ host : 'localhost..',
168
+ port : 3306,
169
+ database : 'database'
170
+ username : 'username',
171
+ password : 'password',
157
172
  })
158
173
  .findMany()
159
174
  // users => [{ .... }]
@@ -161,34 +176,35 @@ const users = await new DB('users')
161
176
 
162
177
  ## Backup
163
178
  Backup database, you may backup is this:
179
+
164
180
  ```js
165
181
  /**
166
- *
167
- * @param conection defalut current connection
182
+ * @param {string} database created new database
183
+ * @param {object?} connection [connection=defalut current connection]
168
184
  */
169
185
  const backup = await new DB().backup({
170
186
  database: 'try-to-backup',
171
- connection ?: {
172
- host: 'localhost..',
173
- port : 3306,
174
- database: 'database'
175
- username: 'username',
176
- password: 'password',
187
+ connection : {
188
+ host : 'localhost..',
189
+ port : 3306,
190
+ database : 'database'
191
+ username : 'username',
192
+ password : 'password',
177
193
  }
178
194
  })
179
195
  /**
180
- *
181
- * @param conection defalut current connection
196
+ * @param {string} database new database
197
+ * @param {object?} connection [connection=defalut current connection]
182
198
  */
183
199
  const backupToFile = await new DB().backupToFile({
184
200
  database: 'try-to-backup',
185
201
  filePath: 'backup.sql',
186
- connection ?: {
187
- host: 'localhost..',
188
- port : 3306,
189
- database: 'database'
190
- username: 'username',
191
- password: 'password',
202
+ connection : {
203
+ host : 'localhost..',
204
+ port : 3306,
205
+ database : 'database'
206
+ username : 'username',
207
+ password : 'password',
192
208
  }
193
209
  })
194
210
  // backupToFile => backup.sql
@@ -214,20 +230,31 @@ import { Model } from 'tspace-mysql'
214
230
  class User extends Model {
215
231
  constructor(){
216
232
  super()
217
- this.useTimestamp()
218
- /*
219
- * the "snake case", plural name of the class will be used as the table name
233
+ /**
234
+ * The "snake case", plural name of the class will be used as the table name // => users
220
235
  *
221
- * @param {string} name The table associated with the model.
222
- */
223
- this.useTable('users')
236
+ * Assign setting global in your model
237
+ * @useMethod
238
+ *
239
+ * this.useDebug() // => runing a uuid (universally unique identifier) when insert new data
240
+ * this.usePrimaryKey('id') // => runing a uuid (universally unique identifier) when insert new data
241
+ * this.useTimestamp({ createdAt : 'created_at' , updatedAt : 'updated_at' }) // runing a timestamp when insert or update
242
+ * this.useSoftDelete()
243
+ * this.useDisableSoftDeleteInRelations()
244
+ * this.useTable('users')
245
+ * this.useTableSingular()
246
+ * this.useTablePlural()
247
+ * this.usePattern('snake_case')
248
+ * this.useUUID('uuid')
249
+ * this.useRegistry()
250
+ */
224
251
  }
225
252
  }
226
253
  export { User }
227
254
  export default User
228
255
  ```
229
256
  ## Relationships
230
- Relationships are defined as methods on your Model classes
257
+ Relationships are defined as methods on your Model classes.
231
258
  Let's examine a basic relations :
232
259
 
233
260
  ## One To One
@@ -269,6 +296,7 @@ const userUsingFunction = await new User().phone().findOne()
269
296
 
270
297
  ## One To Many
271
298
  A one-to-many relationship is used to define relationships where a single model is the parent to one or more child models.
299
+
272
300
  ```js
273
301
  import { Model } from 'tspace-mysql'
274
302
  import Comment from '../Comment'
@@ -304,7 +332,7 @@ const postsUsingFunction = await new Post().comments().findOne()
304
332
  // postsUsingFunction?.comments => [{...}]
305
333
  ```
306
334
 
307
- ## One To One & One To Many (Inverse) / Belongs To
335
+ ## Belongs To
308
336
  ```js
309
337
  import { Model } from 'tspace-mysql'
310
338
  import User from '../User'
@@ -341,7 +369,8 @@ const phoneUsingFunction = await new Phone().user().findOne()
341
369
  ```
342
370
 
343
371
  ## Many To Many
344
- Many-to-many relations are slightly more complicated than hasOne and hasMany relationships.
372
+ Many-to-many relationships are slightly more complicated than hasOne and hasMany relationships.
373
+
345
374
  ```js
346
375
  import { Model } from 'tspace-mysql'
347
376
  import Role from '../Role'
@@ -376,8 +405,82 @@ const user = await new User().with('roles').findOne()
376
405
  const userUsingFunction = await new User().roles().findOne()
377
406
  // user?.roles => [{...}]
378
407
  ```
408
+
409
+ ## Deep Relationships
410
+ Deep Relationships using methods on your child Model classes.
411
+ Let's examine a basic relations :
412
+
413
+ ```js
414
+ import { Model } from 'tspace-mysql'
415
+ import Post from '../Post'
416
+ class User extends Model {
417
+ constructor(){
418
+ super()
419
+ this.hasMany({ name : 'posts' , model : Post })
420
+ }
421
+ }
422
+ export default User
423
+
424
+ +--------------------------------------------------------------------------+
425
+
426
+ import { Model } from 'tspace-mysql'
427
+ import User from '../User'
428
+ class Comment extends Model {
429
+ constructor(){
430
+ super()
431
+ this.belongsTo({ name : 'user' , model : User })
432
+ }
433
+ }
434
+ export default Comment
435
+
436
+ +--------------------------------------------------------------------------+
437
+
438
+ import { Model } from 'tspace-mysql'
439
+ import Comment from '../Comment'
440
+ class Post extends Model {
441
+ constructor(){
442
+ super()
443
+ this.hasMany({ name : 'comments' , model : Comment })
444
+ }
445
+ }
446
+ export default Post
447
+
448
+ +--------------------------------------------------------------------------+
449
+
450
+ import Post from '../Post'
451
+ const post = await new Post()
452
+ .with('comments','user') // => has many comments in posts , => write by user ...
453
+ .withQuery('comments',(query) => {
454
+ /**
455
+ *
456
+ * @callback query registry in Comment classes
457
+ */
458
+ return query
459
+ .with('user') // relation this comment by user?
460
+ .withQuery('user' , (query) => {
461
+ return query
462
+ .with('posts') // relation this user has many posts ...
463
+ })
464
+ })
465
+ .findOne()
466
+ /* post => {
467
+ * ....post details,
468
+ * comments : [
469
+ * {
470
+ * ...comment details,
471
+ * user : {
472
+ * ...user detils
473
+ * posts : [{ ...post details }]
474
+ * }
475
+ * }
476
+ * ],
477
+ * user : { ...user detils }
478
+ * }
479
+ */
480
+ ```
481
+
379
482
  ## Query Builder
380
- method chaining for queries
483
+ Method chaining for queries
381
484
  ```js
382
485
  where(column , operator , value)
383
486
  whereSensitive(column , operator , value)
@@ -416,13 +519,19 @@ backupToFile({ filePath, database , connection })
416
519
  /**
417
520
  * registry relation in your models
418
521
  * @relationship
419
- */
420
- hasOne({ name , model , localKey , foreignKey , freezeTable , as }
421
- hasMany({ name , model , localKey , foreignKey , freezeTable , as }
422
- belongsTo({ name , model , localKey , foreignKey , freezeTable , as }
423
- belongsToMany({ name , model , localKey , foreignKey , freezeTable , as }
522
+ * @param {string} relation.name
523
+ * @param {class} relation.model
524
+ * @param {string?} relation.as
525
+ * @param {string?} relation.localKey
526
+ * @param {string?} relation.foreignKey
527
+ * @param {string?} relation.freezeTable
528
+ */
529
+ hasOne({ name , model , localKey , foreignKey , freezeTable , as })
530
+ hasMany({ name , model , localKey , foreignKey , freezeTable , as })
531
+ belongsTo({ name , model , localKey , foreignKey , freezeTable , as })
532
+ belongsToMany({ name , model , localKey , foreignKey , freezeTable , as })
424
533
  /**
425
- * @relation using registry in your models
534
+ * @relation using registry lists in your models
426
535
  */
427
536
  with(name1 , name2,...nameN)
428
537
  /**
@@ -430,7 +539,7 @@ with(name1 , name2,...nameN)
430
539
  */
431
540
  withExists(name1 , name2,...nameN)
432
541
  /**
433
- * @relation call a relation in registry, callback query of parent data
542
+ * @relation call name relation in registry, callback query this relation
434
543
  */
435
544
  withQuery('relation registry',(callback query))
436
545
 
@@ -440,6 +549,7 @@ withQuery('relation registry',(callback query))
440
549
  */
441
550
  findMany()
442
551
  findOne()
552
+ findOneOrError(message , options?)
443
553
  find(id)
444
554
  delelte()
445
555
  exists ()
@@ -514,7 +624,7 @@ tspace-mysql migrate --dir=App/Models/Migrations
514
624
  ```
515
625
 
516
626
  ## Blueprint
517
- Schema table created by command make:migration, you may use the:
627
+ Schema table created by command make:migration. you may use the:
518
628
  ```js
519
629
  import { Schema , Blueprint , DB } from 'tspace-mysql'
520
630
  (async () => {
@@ -533,11 +643,11 @@ import { Schema , Blueprint , DB } from 'tspace-mysql'
533
643
  * await new DB().table('users').faker(5)
534
644
  */
535
645
  })()
536
- /**
537
- *
538
- * @Types
539
- *
540
- */
646
+ ```
647
+
648
+ ## Types
649
+
650
+ ```js
541
651
  int ()
542
652
  tinyInt (number)
543
653
  bigInt (number)
@@ -552,18 +662,18 @@ text()
552
662
  enum(...n)
553
663
  date()
554
664
  dateTime()
555
- timestamp ()
556
- /**
557
- *
558
- * @Attrbuites
559
- *
560
- */
665
+ timestamp()
666
+ ```
667
+
668
+ ## Attrbuites
669
+
670
+ ```js
561
671
  unsigned ()
562
672
  unique ()
563
673
  null ()
564
674
  notNull ()
565
675
  primary()
566
- default (string)
567
- defaultTimestamp ()
568
- autoIncrement ()
676
+ default(string)
677
+ defaultTimestamp()
678
+ autoIncrement()
569
679
  ```
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var Model = function (model, npm) {
4
- return "import { Model } from '".concat(npm, "'\nclass ").concat(model, " extends Model {\n constructor(){\n super()\n this.useUUID()\n this.useTimestamp()\n }\n}\nexport { ").concat(model, " }\nexport default ").concat(model, "\n");
4
+ return "import { Model } from '".concat(npm, "'\nclass ").concat(model, " extends Model {\n constructor(){\n super()\n /**\n * \n * Assign setting global in your model\n * @useMethod\n *\n * this.useDebug() // => runing a uuid (universally unique identifier) when insert new data\n * this.usePrimaryKey('id') // => runing a uuid (universally unique identifier) when insert new data\n * this.useTimestamp({ createdAt : 'created_at' , updatedAt : 'updated_at' }) // runing a timestamp when insert or update\n * this.useSoftDelete()\n * this.useDisableSoftDeleteInRelations()\n * this.useTable('Users')\n * this.useTableSingular()\n * this.useTablePlural()\n * this.usePattern('snake_case') \n * this.useUUID('uuid')\n * this.useRegistry()\n */\n }\n}\nexport { ").concat(model, " }\nexport default ").concat(model, "\n");
5
5
  };
6
6
  exports.default = Model;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var Table = function (table, npm) {
4
- return "import { Schema , Blueprint , DB } from '".concat(npm, "'\n(async () => {\n await new Schema().table('").concat(table, "',{ \n id : new Blueprint().int().notNull().primary().autoIncrement(),\n name : new Blueprint().varchar(120).default('my name'),\n uuid : new Blueprint().varchar(50),\n email : new Blueprint().varchar(120).unique(),\n email_verify : new Blueprint().tinyInt(),\n password : new Blueprint().varchar(120),\n birthdate : new Blueprint().date(),\n created_at : new Blueprint().null().timestamp(),\n updated_at : new Blueprint().null().timestamp()\n })\n\n /**\n * \n * @Faker data\n * await new DB().table('").concat(table, "').faker(5)\n */\n})()\n");
4
+ return "import { Schema , Blueprint , DB } from '".concat(npm, "'\n(async () => {\n await new Schema().table('").concat(table, "',{ \n id : new Blueprint().int().notNull().primary().autoIncrement(),\n uuid : new Blueprint().varchar(50),\n name : new Blueprint().varchar(120).default('my name'),\n email : new Blueprint().varchar(120).unique(),\n email_verify : new Blueprint().tinyInt(),\n password : new Blueprint().varchar(120),\n birthdate : new Blueprint().date(),\n created_at : new Blueprint().null().timestamp(),\n updated_at : new Blueprint().null().timestamp()\n })\n\n /**\n * \n * @Faker data\n * await new DB().table('").concat(table, "').faker(5)\n */\n})()\n");
5
5
  };
6
6
  exports.default = Table;
@@ -132,6 +132,7 @@ var constant = {
132
132
  DEBUG: false,
133
133
  UUID: false,
134
134
  SOFT_DELETE: false,
135
+ SOFT_DELETE_FORMAT: 'deleted_at',
135
136
  SOFT_DELETE_RELATIONS: false,
136
137
  RELATION: [],
137
138
  WITH: [],
@@ -82,6 +82,12 @@ declare abstract class AbstractDatabase {
82
82
  page: number;
83
83
  }): Promise<Pagination>;
84
84
  abstract first(): Promise<any>;
85
+ abstract firstOrError(message: string, options?: {
86
+ [key: string]: any;
87
+ }): Promise<any>;
88
+ abstract findOneOrError(message: string, options?: {
89
+ [key: string]: any;
90
+ }): Promise<any>;
85
91
  abstract get(): Promise<any>;
86
92
  abstract findOne(): Promise<any>;
87
93
  abstract findMany(): Promise<any>;
@@ -1,21 +1,36 @@
1
- import { Relation } from './Interface';
1
+ import { Relation, RelationQuery } from './Interface';
2
2
  import Database from './Database';
3
3
  declare abstract class AbstractModel extends Database {
4
- abstract useDebug(): void;
5
- abstract useTable(table: string): void;
6
- abstract useTimestamp(): void;
7
- abstract useSoftDelete(): void;
8
- abstract usePattern(pattern: string): void;
9
- abstract onlyTrashed(): void;
10
- abstract trashed(): void;
11
- abstract restore(): void;
12
- abstract with(...nameRelations: string[]): void;
13
- abstract withQuery(nameRelations: string, callback: Function): void;
14
- abstract withExists(...nameRelations: string[]): void;
15
- abstract hasOne({ name, model, localKey, foreignKey, freezeTable, as }: Relation): void;
16
- abstract hasMany({ name, model, localKey, foreignKey, freezeTable, as }: Relation): void;
17
- abstract belongsTo({ name, model, localKey, foreignKey, freezeTable, as }: Relation): void;
18
- abstract belongsToMany({ name, model, localKey, foreignKey, freezeTable, as }: Relation): void;
4
+ abstract useUUID(): this;
5
+ abstract usePrimaryKey(primaryKey: string): this;
6
+ abstract useDisableSoftDeleteInRelations(): this;
7
+ abstract useRegistry(): this;
8
+ abstract useDebug(): this;
9
+ abstract useTable(table: string): this;
10
+ abstract useTablePlural(): this;
11
+ abstract useTableSingular(): this;
12
+ abstract useTimestamp(): this;
13
+ abstract useSoftDelete(): this;
14
+ abstract usePattern(pattern: string): this;
15
+ abstract onlyTrashed(): Promise<any>;
16
+ abstract trashed(): Promise<any>;
17
+ abstract restore(): Promise<any>;
18
+ abstract ignoreSoftDelete(): this;
19
+ abstract disableSoftDelete(): this;
20
+ abstract registry(func: {
21
+ [key: string]: Function;
22
+ }): this;
23
+ abstract with(...nameRelations: string[]): this;
24
+ abstract withQuery(nameRelations: string, callback: Function): this;
25
+ abstract withExists(...nameRelations: string[]): this;
26
+ abstract hasOne({ name, model, localKey, foreignKey, freezeTable, as }: Relation): this;
27
+ abstract hasMany({ name, model, localKey, foreignKey, freezeTable, as }: Relation): this;
28
+ abstract belongsTo({ name, model, localKey, foreignKey, freezeTable, as }: Relation): this;
29
+ abstract belongsToMany({ name, model, localKey, foreignKey, freezeTable, as }: Relation): this;
30
+ abstract hasOneQuery({ name, model, localKey, foreignKey, freezeTable, as }: RelationQuery, callback: Function): this;
31
+ abstract hasManyQuery({ name, model, localKey, foreignKey, freezeTable, as }: RelationQuery, callback: Function): this;
32
+ abstract belongsToQuery({ name, model, localKey, foreignKey, freezeTable, as }: RelationQuery, callback: Function): this;
33
+ abstract belongsToManyQuery({ name, model, localKey, foreignKey, freezeTable, as }: RelationQuery, callback: Function): this;
19
34
  }
20
35
  export { AbstractModel };
21
36
  export default AbstractModel;
@@ -446,6 +446,26 @@ declare class Database extends AbstractDatabase {
446
446
  findOne(): Promise<{
447
447
  [key: string]: any;
448
448
  } | null>;
449
+ /**
450
+ *
451
+ * execute data return object | null
452
+ * @return {promise<object | null>}
453
+ */
454
+ firstOrError(message: string, options?: {
455
+ [key: string]: any;
456
+ }): Promise<{
457
+ [key: string]: any;
458
+ }>;
459
+ /**
460
+ *
461
+ * execute data return object | null
462
+ * @return {promise<object | null>}
463
+ */
464
+ findOneOrError(message: string, options?: {
465
+ [key: string]: any;
466
+ }): Promise<{
467
+ [key: string]: any;
468
+ }>;
449
469
  /**
450
470
  *
451
471
  * execute data return Array