tspace-mysql 1.8.3 → 1.8.4

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.
Files changed (71) hide show
  1. package/README.md +372 -62
  2. package/build/cli/generate/model.js +3 -3
  3. package/build/cli/generate/model.js.map +1 -1
  4. package/build/lib/constants/index.d.ts +7 -1
  5. package/build/lib/constants/index.js +7 -1
  6. package/build/lib/constants/index.js.map +1 -1
  7. package/build/lib/core/Abstracts/AbstractBuilder.d.ts +1 -1
  8. package/build/lib/core/Abstracts/AbstractBuilder.js.map +1 -1
  9. package/build/lib/core/Abstracts/AbstractDB.d.ts +1 -1
  10. package/build/lib/core/Abstracts/AbstractDB.js.map +1 -1
  11. package/build/lib/core/Abstracts/AbstractView.d.ts +10 -0
  12. package/build/lib/core/Abstracts/AbstractView.js +9 -0
  13. package/build/lib/core/Abstracts/AbstractView.js.map +1 -0
  14. package/build/lib/core/Blueprint.d.ts +24 -4
  15. package/build/lib/core/Blueprint.js +78 -87
  16. package/build/lib/core/Blueprint.js.map +1 -1
  17. package/build/lib/core/Builder.d.ts +13 -4
  18. package/build/lib/core/Builder.js +12 -40
  19. package/build/lib/core/Builder.js.map +1 -1
  20. package/build/lib/core/Cache/DBCache.js +15 -16
  21. package/build/lib/core/Cache/DBCache.js.map +1 -1
  22. package/build/lib/core/DB.js +1 -1
  23. package/build/lib/core/DB.js.map +1 -1
  24. package/build/lib/core/Decorator.d.ts +1 -1
  25. package/build/lib/core/Decorator.js.map +1 -1
  26. package/build/lib/core/Handlers/Relation.d.ts +2 -1
  27. package/build/lib/core/Handlers/Relation.js +51 -8
  28. package/build/lib/core/Handlers/Relation.js.map +1 -1
  29. package/build/lib/core/Handlers/State.d.ts +1 -0
  30. package/build/lib/core/Handlers/State.js +1 -1
  31. package/build/lib/core/Handlers/State.js.map +1 -1
  32. package/build/lib/core/JoinModel.d.ts +1 -1
  33. package/build/lib/core/JoinModel.js.map +1 -1
  34. package/build/lib/core/Meta.d.ts +55 -0
  35. package/build/lib/core/Meta.js +175 -0
  36. package/build/lib/core/Meta.js.map +1 -0
  37. package/build/lib/core/Model.d.ts +20 -6
  38. package/build/lib/core/Model.js +187 -11
  39. package/build/lib/core/Model.js.map +1 -1
  40. package/build/lib/core/Repository.js.map +1 -1
  41. package/build/lib/core/Schema.d.ts +2 -2
  42. package/build/lib/core/Schema.js +113 -78
  43. package/build/lib/core/Schema.js.map +1 -1
  44. package/build/lib/core/SqlLike.js.map +1 -1
  45. package/build/lib/core/StoredProcedure.d.ts +120 -0
  46. package/build/lib/core/StoredProcedure.js +161 -0
  47. package/build/lib/core/StoredProcedure.js.map +1 -0
  48. package/build/lib/core/UtilityTypes.d.ts +25 -44
  49. package/build/lib/core/View.d.ts +96 -0
  50. package/build/lib/core/View.js +141 -0
  51. package/build/lib/core/View.js.map +1 -0
  52. package/build/lib/core/index.d.ts +5 -0
  53. package/build/lib/core/index.js +7 -2
  54. package/build/lib/core/index.js.map +1 -1
  55. package/build/lib/types/index.d.ts +4 -0
  56. package/build/lib/utils/index.js +5 -2
  57. package/build/lib/utils/index.js.map +1 -1
  58. package/build/tests/04-Model-pattern.test.js +1 -1
  59. package/build/tests/04-Model-pattern.test.js.map +1 -1
  60. package/build/tests/05-View.test.d.ts +1 -0
  61. package/build/tests/05-View.test.js +83 -0
  62. package/build/tests/05-View.test.js.map +1 -0
  63. package/build/tests/06-Meta.test.d.ts +1 -0
  64. package/build/tests/06-Meta.test.js +103 -0
  65. package/build/tests/06-Meta.test.js.map +1 -0
  66. package/build/tests/07-Virtual-column.test.d.ts +1 -0
  67. package/build/tests/07-Virtual-column.test.js +160 -0
  68. package/build/tests/07-Virtual-column.test.js.map +1 -0
  69. package/build/tests/schema-spec.js +25 -25
  70. package/build/tests/schema-spec.js.map +1 -1
  71. package/package.json +1 -1
package/README.md CHANGED
@@ -18,6 +18,7 @@ tspace-mysql is an Object-Relational Mapping (ORM) tool designed to run seamless
18
18
  | **Soft Deletes** | Marks records as deleted without removing them from the database. This allows for recovery and auditing later. |
19
19
  | **Relationships** | Set up connections between models, such as one-to-one, one-to-many, belongs-to, and many-to-many. Supports nested relationships and checks. |
20
20
  | **Type Safety** | Ensures that queries are safer by checking the types of statements like `SELECT`, `ORDER BY`, `GROUP BY`, and `WHERE`. |
21
+ | **Metadata** | Get the metadata of a Model. |
21
22
  | **Repository** | Follows a pattern for managing database operations like `SELECT`, `INSERT`, `UPDATE`, and `DELETE`. It helps keep the code organized. |
22
23
  | **Decorators** | Use decorators to add extra functionality or information to model classes and methods, making the code easier to read. |
23
24
  | **Caching** | Improves performance by storing frequently requested data. Supports in-memory caching (like memory DB) and Redis for distributed caching. |
@@ -91,6 +92,7 @@ npm install tspace-mysql -g
91
92
  - [Global Scope](#global-scope)
92
93
  - [Schema](#schema)
93
94
  - [Schema Model](#schema-model)
95
+ - [Virtual Column](#virtual-column)
94
96
  - [Validation](#validation)
95
97
  - [Sync](#sync)
96
98
  - [SoftDelete](#softdelete)
@@ -112,15 +114,16 @@ npm install tspace-mysql -g
112
114
  - [Cache](#cache)
113
115
  - [Decorator](#decorator)
114
116
  - [Type Safety](#type-safety)
115
- - [Safety Select](#safety-select)
116
- - [Safety OrderBy](#safety-order-by)
117
- - [Safety GroupBy](#safety-group-by)
118
- - [Safety Where](#safety-where)
119
- - [Safety Insert](#safety-insert)
120
- - [Safety Update](#safety-update)
121
- - [Safety Delete](#safety-delete)
122
- - [Safety Relationships](#safety-relationships)
123
- - [Safety Result](#safety-result)
117
+ - [Type Safety Select](#type-safety-select)
118
+ - [Type Safety OrderBy](#type-safety-order-by)
119
+ - [Type Safety GroupBy](#type-safety-group-by)
120
+ - [Type Safety Where](#type-safety-where)
121
+ - [Type Safety Insert](#type-safety-insert)
122
+ - [Type Safety Update](#type-safety-update)
123
+ - [Type Safety Delete](#type-safety-delete)
124
+ - [Type Safety Relationships](#type-safety-relationships)
125
+ - [Type Safety Results](#type-safety-results)
126
+ - [Metadata](#metadata)
124
127
  - [Repository](#repository)
125
128
  - [Repository Select Statements](#repository-select-statements)
126
129
  - [Repository Insert Statements](#repository-insert-statements)
@@ -128,6 +131,8 @@ npm install tspace-mysql -g
128
131
  - [Repository Delete Statements](#repository-delete-statements)
129
132
  - [Repository Transactions](#repository-transactions)
130
133
  - [Repository Relations](#repository-relations)
134
+ - [View](#view)
135
+ - [Stored Procedure](#stored-procedure)
131
136
  - [Blueprint](#blueprint)
132
137
  - [Cli](#cli)
133
138
  - [Make Model](#make-model)
@@ -2478,7 +2483,7 @@ using the following:
2478
2483
  #### Schema Model
2479
2484
 
2480
2485
  ```js
2481
- import { Model, Blueprint , TSchema } from "tspace-mysql";
2486
+ import { Model, Blueprint , type T } from "tspace-mysql";
2482
2487
 
2483
2488
  const schema = {
2484
2489
  id: Blueprint.int().notNull().primary().autoIncrement(),
@@ -2492,7 +2497,7 @@ const schema = {
2492
2497
 
2493
2498
 
2494
2499
  // make type in TS
2495
- type TS = TSchema<typeof Schema>
2500
+ type TS = T.Schema<typeof Schema>
2496
2501
 
2497
2502
  // the TSchemaUser will be created like that
2498
2503
  /**
@@ -2519,6 +2524,60 @@ class User extends Model<TS> // use the schema for this User model
2519
2524
 
2520
2525
  ```
2521
2526
 
2527
+ #### Virtual Column
2528
+ ```js
2529
+
2530
+ import { Model, Blueprint , type T } from "tspace-mysql";
2531
+
2532
+ const schema = {
2533
+ id: Blueprint.int().notNull().primary().autoIncrement(),
2534
+ uuid: Blueprint.varchar(50).null().index(),
2535
+ firstName: Blueprint.varchar(191).notNull(),
2536
+ lastName : Blueprint.varchar(191).notNull(),
2537
+ email: Blueprint.varchar(191).notNull(),
2538
+ createdAt: Blueprint.timestamp().null(),
2539
+ updatedAt: Blueprint.timestamp().null(),
2540
+ deletedAt: Blueprint.timestamp().null(),
2541
+
2542
+ // Define you virtual column to schema
2543
+ fullName : new Blueprint().virtual(`CONCAT(firstName,' ', lastName)`),
2544
+ countPosts : new Blueprint().virtual(`(SELECT COUNT(*) FROM posts WHERE posts.userid = users.id)`)
2545
+
2546
+ // if you need to custom the virtual column for some method.
2547
+ // fullName : new Blueprint().virtual({
2548
+ // select : `CONCAT(firstName,' ', lastName)`,
2549
+ // where : `CONCAT(firstName,' ', lastName)`,
2550
+ // orderBy : `CONCAT(firstName,' ', lastName)`,
2551
+ // groupBy : `CONCAT(firstName,' ', lastName)`,
2552
+ // }),
2553
+ }
2554
+
2555
+ type TS = T.Schema<typeof Schema>
2556
+
2557
+ class User extends Model<TS> {
2558
+ constructor() {
2559
+ super();
2560
+ this.useSchema(schema)
2561
+ }
2562
+ }
2563
+ const users = await new User()
2564
+ .select('id','firstName','lastName','fullName','countPosts')
2565
+ .where('fullName','LIKE',`%tspace-mysql%`)
2566
+ .orderBy('fullName','desc')
2567
+ .groupBy('fullName')
2568
+ .findMany()
2569
+
2570
+ // SELECT
2571
+ // `users`.`id`, `users`.`firstName`, `users`.`lastName`,
2572
+ // CONCAT(firstName,' ', lastName) AS fullName ,
2573
+ // (SELECT COUNT(*) FROM posts WHERE posts.userid = users.id) AS countPosts
2574
+ // FROM `users`
2575
+ // WHERE CONCAT(firstName,' ', lastName) LIKE '%tspace-mysql%'
2576
+ // GROUP BY CONCAT(firstName,' ', lastName)
2577
+ // ORDER BY CONCAT(firstName,' ', lastName) DESC
2578
+
2579
+ ```
2580
+
2522
2581
  #### Validation
2523
2582
 
2524
2583
  Validate the schema of Model
@@ -2677,12 +2736,12 @@ const user = await new User().trashed().findMany()
2677
2736
  ```
2678
2737
 
2679
2738
  ### Type Safety
2680
- Type safety in TypeScript refers to the ability of the language to detect and prevent type errors during compile-time.
2681
- Type safety still works when you add additional types to your model, using the following:
2739
+ Type Type Safety in TypeScript refers to the ability of the language to detect and prevent type errors during compile-time.
2740
+ Type Type Safety still works when you add additional types to your model, using the following:
2682
2741
 
2683
2742
  ```js
2684
2743
  // in file User.ts
2685
- import { Model , Blueprint , TSchema , TSchemaStatic } from 'tspace-mysql'
2744
+ import { Model , Blueprint , type T } from 'tspace-mysql'
2686
2745
  import Phone from '../Phone'
2687
2746
 
2688
2747
  const schemaUser = {
@@ -2696,8 +2755,8 @@ const schemaUser = {
2696
2755
  updatedAt :Blueprint.timestamp().null()
2697
2756
  }
2698
2757
 
2699
- type TSchemaUser = TSchemaStatic<typeof schemaUser>
2700
- // TSchemaUser = TSchema<typeof schemaUser>
2758
+ type TSchemaUser = T.SchemaStatic<typeof schemaUser>
2759
+ // TSchemaUser = T.Schema<typeof schemaUser>
2701
2760
 
2702
2761
  // TSchema allowed to set any new keys without in the schema to results
2703
2762
  // TSchemaStatic not allowed to set any new keys without in the schema to results
@@ -2717,7 +2776,7 @@ export default User
2717
2776
  +--------------------------------------------------------------------------+
2718
2777
 
2719
2778
  // in file Phone.ts
2720
- import { Model , Blueprint , TSchema , TSchemaStatic } from 'tspace-mysql'
2779
+ import { Model , Blueprint , type T } from 'tspace-mysql'
2721
2780
  import { User } from './User.ts'
2722
2781
  const schemaPhone = {
2723
2782
  id :Blueprint.int().notNull().primary().autoIncrement(),
@@ -2728,7 +2787,7 @@ const schemaPhone = {
2728
2787
  updatedAt :Blueprint.timestamp().null()
2729
2788
  }
2730
2789
 
2731
- type TSchemaPhone = TSchemaStatic<typeof schemaPhone>
2790
+ type TSchemaPhone = T.SchemaStatic<typeof schemaPhone>
2732
2791
 
2733
2792
  class Phone extends Model<TSchemaPhone> {
2734
2793
  constructor() {
@@ -2741,10 +2800,25 @@ class Phone extends Model<TSchemaPhone> {
2741
2800
  export { Phone }
2742
2801
  export default Phone
2743
2802
 
2803
+ // example basic
2804
+ type TS = T.Schema<typeof TSchemaUser>
2805
+ type TR = T.Relation<{ phone : Phone }>
2806
+
2807
+ type TSM = T.SchemaModel<User>
2808
+ type TRM = T.RelationModel<User>
2809
+
2810
+ type TColumn = T.Column<User>
2811
+
2812
+ type TResults = T.Results<User>
2813
+ type TPaginateResults = T.Results<User, { paginate : true }>
2814
+
2815
+ type TRepository = T.Repository<User>
2816
+ type TRepositoryTypeOf = T.RepositoryTypeOf<User>
2817
+
2744
2818
  +--------------------------------------------------------------------------+
2745
2819
  ```
2746
2820
 
2747
- ### Safety Select
2821
+ ### Type Safety Select
2748
2822
 
2749
2823
  ```js
2750
2824
  import { User } from './User.ts'
@@ -2756,18 +2830,17 @@ const user = await new User().select('idx','username').findOne() ❌
2756
2830
  const user = await new User().except('id','username').findOne() ✅
2757
2831
  const user = await new User().except('idx','username').findOne() ❌
2758
2832
 
2759
- // TSchemaStatic not allowed to set any new keys without in the schema to results
2760
- user.withoutSchema = 1 ✅ // TSchema<User>
2761
- user.withoutSchema = 1 ❌ // TSchemaStatic<User>
2833
+ // T.SchemaStatic not allowed to set any new keys without in the schema to results
2834
+ user.withoutSchema = 1 ✅ // T.Schema<User>
2835
+ user.withoutSchema = 1 ❌ // T.SchemaStatic<User>
2762
2836
  // But can you make like this for cases
2763
2837
  const user = await new User().except('idx','username').findOne<{ withoutSchema : number }>()
2764
2838
  user.withoutSchema = 1 ✅
2765
2839
  ```
2766
2840
 
2767
- ### Safety OrderBy
2841
+ ### Type Safety OrderBy
2768
2842
 
2769
2843
  ```js
2770
-
2771
2844
  import { User } from './User.ts'
2772
2845
  import { Phone } from './Phone.ts'
2773
2846
 
@@ -2782,7 +2855,7 @@ const users = await new User().oldest('idx').findMany() ❌
2782
2855
 
2783
2856
  ```
2784
2857
 
2785
- ### Safety GroupBy
2858
+ ### Type Safety GroupBy
2786
2859
 
2787
2860
  ```js
2788
2861
  import { User } from './User.ts'
@@ -2793,7 +2866,7 @@ const users = await new User().groupBy('idx').findMany() ❌
2793
2866
 
2794
2867
  ```
2795
2868
 
2796
- ### Safety Where
2869
+ ### Type Safety Where
2797
2870
 
2798
2871
  ```js
2799
2872
  import { User } from './User.ts'
@@ -2831,7 +2904,7 @@ const users = await new User()
2831
2904
 
2832
2905
  ```
2833
2906
 
2834
- ### Safety Insert
2907
+ ### Type Safety Insert
2835
2908
 
2836
2909
  ```js
2837
2910
  import { User } from './User.ts'
@@ -2845,7 +2918,7 @@ const users = await new User().create({ idx : 10 }).save() ❌
2845
2918
 
2846
2919
  ```
2847
2920
 
2848
- ### Safety Update
2921
+ ### Type Safety Update
2849
2922
 
2850
2923
  ```js
2851
2924
  import { User } from './User.ts'
@@ -2858,7 +2931,7 @@ const users = await new User().update({ idx : 10 }).where('idx',1).save() ❌
2858
2931
 
2859
2932
  ```
2860
2933
 
2861
- ### Safety Delete
2934
+ ### Type Safety Delete
2862
2935
 
2863
2936
  ```js
2864
2937
  import { User } from './User.ts'
@@ -2869,10 +2942,10 @@ const users = await new User().where('idx',1).delete() ❌
2869
2942
 
2870
2943
  ```
2871
2944
 
2872
- ### Safety Relationships
2945
+ ### Type Safety Relationships
2873
2946
 
2874
2947
  ```js
2875
- import { TSchemaModel } from 'tspace-mysql'
2948
+ import { type T } from 'tspace-mysql'
2876
2949
  import { User } from './User.ts'
2877
2950
  import { Phone } from './Phone.ts'
2878
2951
  // Case #1 : Relationship with 2 relations 'phone' and 'phones'
@@ -2903,7 +2976,7 @@ import { Phone } from './Phone.ts'
2903
2976
  // good 👍👍👍
2904
2977
  const users = await new User()
2905
2978
  .relations('phone','phones')
2906
- .findMany<{ phone : TSchemaModel<Phone> , phones : TSchemaModel<Phone>[] }>()
2979
+ .findMany<{ phone : T.SchemaModel<Phone> , phones : T.SchemaModel<Phone>[] }>()
2907
2980
 
2908
2981
  for(const user of users) {
2909
2982
  user.phone ✅
@@ -2921,7 +2994,7 @@ for(const user of users) {
2921
2994
  .relations('phone','phones')
2922
2995
  .relationQuery('phone' , (query : Phone) => query.relations('user'))
2923
2996
  .relationQuery('phones' , (query : Phone) => query.relations('user'))
2924
- .findMany<{ phone : TSchemaModel<Phone> , phones : TSchemaModel<Phone>[] }>()
2997
+ .findMany<{ phone : T.SchemaModel<Phone> , phones : T.SchemaModel<Phone>[] }>()
2925
2998
 
2926
2999
  for(const user of users) {
2927
3000
  user.phone.user ❌
@@ -2949,8 +3022,8 @@ for(const user of users) {
2949
3022
  .relationQuery('phone' , (query : Phone) => query.relations('user'))
2950
3023
  .relationQuery('phones' , (query : Phone) => query.relations('user'))
2951
3024
  .findMany<{
2952
- phone : Partial<TSchemaModel<Phone>> & { user : TSchemaModel<User>};
2953
- phones : (Partial<TSchemaModel<Phone>> & { user : TSchemaModel<User>})[];
3025
+ phone : Partial<T.SchemaModel<Phone>> & { user : T.SchemaModel<User>};
3026
+ phones : (Partial<T.SchemaModel<Phone>> & { user : T.SchemaModel<User>})[];
2954
3027
  }>()
2955
3028
 
2956
3029
  for(const user of users) {
@@ -2965,23 +3038,23 @@ for(const user of users) {
2965
3038
  +--------------------------------------------------------------------------+
2966
3039
  // If you don't want to set types for every returning method such as 'findOne', 'findMany', and so on...
2967
3040
 
2968
- import { Model , Blueprint , TSchema , TSchemaStatic , TRelation } from 'tspace-mysql'
3041
+ import { Model , Blueprint , type T } from 'tspace-mysql'
2969
3042
  import { Phone } from '../Phone'
2970
3043
 
2971
3044
  const schemaUser = {
2972
- id :Blueprint.int().notNull().primary().autoIncrement(),
2973
- uuid :Blueprint.varchar(50).null(),
2974
- email :Blueprint.varchar(50).null(),
2975
- name :Blueprint.varchar(255).null(),
2976
- username : Blueprint.varchar(255).null(),
2977
- password : Blueprint.varchar(255).null(),
3045
+ id :Blueprint.int().notNull().primary().autoIncrement(),
3046
+ uuid :Blueprint.varchar(50).null(),
3047
+ email :Blueprint.varchar(50).null(),
3048
+ name :Blueprint.varchar(255).null(),
3049
+ username :Blueprint.varchar(255).null(),
3050
+ password :Blueprint.varchar(255).null(),
2978
3051
  createdAt :Blueprint.timestamp().null(),
2979
3052
  updatedAt :Blueprint.timestamp().null()
2980
3053
  }
2981
3054
 
2982
- type TSchemaUser = TSchemaStatic<typeof schemaUser>
3055
+ type TSchemaUser = T.SchemaStatic<typeof schemaUser>
2983
3056
 
2984
- type TRelationUser = TRelation<{
3057
+ type TRelationUser = T.Relation<{
2985
3058
  phones : Phone[]
2986
3059
  phone : Phone
2987
3060
  }>
@@ -3003,28 +3076,25 @@ export { User }
3003
3076
  +--------------------------------------------------------------------------+
3004
3077
 
3005
3078
  // in file Phone.ts
3006
- import { Model , Blueprint , TSchema , TRelation } from 'tspace-mysql'
3079
+ import { Model , Blueprint , type T } from 'tspace-mysql'
3007
3080
  import { User } from './User.ts'
3008
3081
 
3009
3082
  const schemaPhone = {
3010
- id :Blueprint.int().notNull().primary().autoIncrement(),
3011
- uuid :Blueprint.varchar(50).null(),
3012
- userId : Blueprint.int().notNull(),
3013
- number :Blueprint.varchar(50).notNull(),
3083
+ id :Blueprint.int().notNull().primary().autoIncrement(),
3084
+ uuid :Blueprint.varchar(50).null(),
3085
+ userId :Blueprint.int().notNull(),
3086
+ number :Blueprint.varchar(50).notNull(),
3014
3087
  createdAt :Blueprint.timestamp().null(),
3015
3088
  updatedAt :Blueprint.timestamp().null()
3016
3089
  }
3017
3090
 
3018
- type TSchemaPhone = TSchema<typeof schemaPhone>
3091
+ type TSchemaPhone = T.Schema<typeof schemaPhone>
3019
3092
 
3020
- type TRelationPhone = TRelation<{
3093
+ type TRelationPhone = T.Relation<{
3021
3094
  user : User[]
3022
3095
  }>
3023
3096
 
3024
- class Phone extends Model<
3025
- TSchemaPhone,
3026
- TRelationPhone
3027
- > {
3097
+ class Phone extends Model<TSchemaPhone,TRelationPhone> {
3028
3098
  constructor() {
3029
3099
  super()
3030
3100
  this.useSchema(schemaPhone)
@@ -3074,11 +3144,11 @@ const users = await new User()
3074
3144
 
3075
3145
  ```
3076
3146
 
3077
- ## Safety Result
3147
+ ## Type Safety Results
3078
3148
  ```js
3079
- import type { TResult } from 'tspace-mysql'
3149
+ import { type T } from 'tspace-mysql'
3080
3150
 
3081
- const fError = async () : Promise<TResult<User>[]> => {
3151
+ const fError = async () : Promise<T.Results<User>[]> => {
3082
3152
 
3083
3153
  const users = [{
3084
3154
  id : 1,
@@ -3089,7 +3159,7 @@ const fError = async () : Promise<TResult<User>[]> => {
3089
3159
  return users // ❌
3090
3160
  }
3091
3161
 
3092
- const fCorrect = async () : Promise<TResult<User>[]> => {
3162
+ const fCorrect = async () : Promise<T.Results<User>[]> => {
3093
3163
 
3094
3164
  const users = await new User().findMany()
3095
3165
 
@@ -3098,17 +3168,76 @@ const fCorrect = async () : Promise<TResult<User>[]> => {
3098
3168
 
3099
3169
  ```
3100
3170
 
3171
+ ## Metadata
3172
+ Get the metadata of a Model works only when a schema is added to the Model.
3173
+
3174
+ ```js
3175
+ import { Meta, Model , Blueprint , type T } from 'tspace-mysql';
3176
+
3177
+ const schema = {
3178
+ id : Blueprint.int().notNull().primary().autoIncrement(),
3179
+ uuid : Blueprint.varchar(50).null(),
3180
+ email : Blueprint.varchar(255).notNull().index('users.email@index'),
3181
+ name : Blueprint.varchar(255).null(),
3182
+ username : Blueprint.varchar(255).notNull(),
3183
+ password : Blueprint.varchar(255).notNull(),
3184
+ status : Blueprint.tinyInt().notNull().default(0),
3185
+ createdAt : Blueprint.timestamp().null(),
3186
+ updatedAt : Blueprint.timestamp().null()
3187
+ }
3188
+
3189
+ type TS = T.Schema<typeof schema>
3190
+
3191
+ class User extends Model<TS> {
3192
+ constructor() {
3193
+ super()
3194
+ this.useSchema(schema)
3195
+ this.useUUID()
3196
+ this.useTimestamp()
3197
+ }
3198
+ }
3199
+
3200
+ const meta = Meta(User)
3201
+
3202
+ const table = meta.table() // 'users'
3203
+ const column = meta.column('id') // 'id'
3204
+ const columnRef = meta.columnReference('id') // `users`.`id`
3205
+ const columnTypeOf = meta.columnTypeOf('id') // number
3206
+ const columnType = meta.columnType('id') // Int
3207
+ const columns = meta.columns() // ['id','uuid',...'updatedAt']
3208
+ const hasColumn = meta.hasColumn('idx') // false
3209
+ const primaryKey = meta.primaryKey() // 'id'
3210
+ const indexes = meta.indexes() // ['users.email@index']
3211
+ const nullable = meta.nullable() // ['uuid','name','createdAt','updatedAt']
3212
+ const defaults = meta.defaults() // { status : 0 }
3213
+
3214
+ console.log({
3215
+ table,
3216
+ column,
3217
+ columnRef,
3218
+ columnTypeOf,
3219
+ columnType,
3220
+ columns,
3221
+ hasColumn,
3222
+ primaryKey,
3223
+ indexes,
3224
+ nullable,
3225
+ defaults
3226
+ })
3227
+
3228
+ ```
3229
+
3101
3230
  ## Repository
3102
3231
  ```js
3103
3232
  Repository is a mechanism that encapsulates all database operations related to a specific model.
3104
3233
  It provides methods for querying, inserting, updating, and deleting records in the database associated with the model.
3105
3234
 
3106
- ** The Repository check always type safety if model is used the type of schema
3235
+ ** The Repository check always type Type Safety if model is used the type of schema
3107
3236
 
3108
3237
  ```
3109
3238
  ### Repository Select Statements
3110
3239
  ```js
3111
- import { Repository , TRepository , OP } from 'tspace-mysql'
3240
+ import { Repository, OP , type T } from 'tspace-mysql'
3112
3241
  import { User } from '../Models/User'
3113
3242
 
3114
3243
  const userRepository = Repository(User)
@@ -3316,7 +3445,7 @@ try {
3316
3445
 
3317
3446
  ### Repository Relations
3318
3447
  ```js
3319
- import { Repository , TRepository , OP } from 'tspace-mysql'
3448
+ import { Repository , OP } from 'tspace-mysql'
3320
3449
  import { User } from '../Models/User'
3321
3450
  import { Phone } from '../Models/Phone'
3322
3451
 
@@ -3357,6 +3486,187 @@ const phoneBelongUser = await phoneRepository.findOne({
3357
3486
 
3358
3487
  ```
3359
3488
 
3489
+ ## View
3490
+
3491
+ Your database schema can also use views. These views are represented by classes that behave similarly to models,
3492
+ but they are based on stored SQL queries instead of actual tables.
3493
+ Let's look at a basic view class example:
3494
+ ```js
3495
+
3496
+ import { type T, Blueprint, Model , View , Meta } from 'tspace-mysql'
3497
+
3498
+ const schemaUser = {
3499
+ id: Blueprint.int().notNull().primary().autoIncrement(),
3500
+ uuid: Blueprint.varchar(50).null().index(),
3501
+ name: Blueprint.varchar(191).notNull(),
3502
+ email: Blueprint.varchar(191).notNull()
3503
+ }
3504
+
3505
+ type TUser = T.Schema<typeof schemaUser>
3506
+
3507
+ class User extends Model<TUser> {
3508
+ protected boot(): void {
3509
+ this.useSchema(schemaUser)
3510
+ }
3511
+ }
3512
+
3513
+ const schemaPost = {
3514
+ id: Blueprint.int().notNull().primary().autoIncrement(),
3515
+ uuid: Blueprint.varchar(50).null().index(),
3516
+ user_id :Blueprint.int().notnull(),
3517
+ title: Blueprint.varchar(191).notNull(),
3518
+ content: Blueprint.varchar(191).notNull()
3519
+ }
3520
+
3521
+ type TPost = T.Schema<typeof schemaPost>
3522
+
3523
+ class Post extends Model<TPost> {
3524
+ protected boot(): void {
3525
+ this.useSchema(schemaPost)
3526
+ }
3527
+ }
3528
+
3529
+ const schemaUserPostCountView = {
3530
+ id :Blueprint.int().notNull().primary().autoIncrement(),
3531
+ user_id :Blueprint.int().notnull(),
3532
+ name :Blueprint.varchar(255).null(),
3533
+ post_count : Blueprint.int().notnull()
3534
+ }
3535
+
3536
+ type TSUserPostCountView = T.Schema<typeof schemaUserPostCountView>
3537
+ type TRUserPostCountView = T.Relation<{
3538
+ user: User
3539
+ }>
3540
+
3541
+ class UserPostCountView extends View<TSUserPostCountView,TRUserPostCountView> {
3542
+
3543
+ protected boot(): void {
3544
+ this.useSchema(schemaUserPostCountView)
3545
+ const metaUser = Meta(User)
3546
+ const metaPost = Meta(Post)
3547
+
3548
+ this.createView({
3549
+ synchronize: true,
3550
+ expression : new User()
3551
+ .selectRaw(`ROW_NUMBER() OVER (ORDER BY ${metaUser.columnRef('id')}) AS id`)
3552
+ .selectRaw(`${metaUser.columnRef('id')} AS user_id`)
3553
+ .selectRaw(metaUser.columnRef('name'))
3554
+ .select(metaUser.columnRef('email'))
3555
+ .selectRaw(`COUNT(${metaPost.columnRef('id')}) AS post_count`)
3556
+ .leftJoin(metaUser.columnRef('id'),metaPost.columnRef('user_id'))
3557
+ .groupBy(metaUser.columnRef('id'))
3558
+ .groupBy(metaUser.columnRef('name'))
3559
+ .toString()
3560
+
3561
+ // Look like this
3562
+ // expression :
3563
+ // SELECT
3564
+ // ROW_NUMBER() OVER (ORDER BY `users`.`id`) AS id,
3565
+ // `users`.`id` AS user_id, `users`.`name`, `users`.`email`,
3566
+ // COUNT(`posts`.`id`) AS post_count
3567
+ // FROM `users`
3568
+ // LEFT JOIN `posts` ON `users`.`id` = `posts`.`user_id`
3569
+ // GROUP BY `users`.`id`, `users`.`name`
3570
+ })
3571
+
3572
+ this.belongsTo({ name : 'user' , model : User })
3573
+ }
3574
+ }
3575
+
3576
+ new UserPostCountView()
3577
+ .with('user')
3578
+ .get()
3579
+ .then( v=> {
3580
+ console.log(v)
3581
+ })
3582
+
3583
+ ```
3584
+
3585
+ ## Stored Procedure
3586
+ StoredProcedure is a predefined set of SQL statements stored in the database that you can call (execute) by name.
3587
+ ```js
3588
+
3589
+ import { StoredProcedure } from 'tspace-mysql'
3590
+
3591
+ type T = {
3592
+ AddUser: {
3593
+ params: {
3594
+ name : string;
3595
+ email: string;
3596
+ } | [string,string];
3597
+ result: {
3598
+ fieldCount: number;
3599
+ affectedRows: number;
3600
+ insertId: number;
3601
+ info: string;
3602
+ serverStatus: number;
3603
+ warningStatus: number;
3604
+ changedRows: number;
3605
+ }
3606
+ };
3607
+ GetUser: {
3608
+ params: [number];
3609
+ result: any[]
3610
+ },
3611
+ GetUsers: {
3612
+ params: [];
3613
+ result: any[]
3614
+ }
3615
+ };
3616
+
3617
+ class MyStoreProcedure extends StoredProcedure<T> {
3618
+ protected boot(): void {
3619
+
3620
+ this.createProcedure({
3621
+ name: 'AddUser',
3622
+ expression: `
3623
+ CREATE PROCEDURE AddUser(IN name VARCHAR(255), IN email VARCHAR(255))
3624
+ BEGIN
3625
+ INSERT INTO users (name, email) VALUES (name, email);
3626
+ END;
3627
+ `,
3628
+ synchronize: true
3629
+ });
3630
+
3631
+ this.createProcedure({
3632
+ name: 'GetUsers',
3633
+ expression: `
3634
+ CREATE PROCEDURE GetUsers()
3635
+ BEGIN
3636
+ SELECT * FROM users LIMIT 5;
3637
+ END;
3638
+ `,
3639
+ synchronize: true
3640
+ });
3641
+
3642
+ this.createProcedure({
3643
+ name: 'GetUser',
3644
+ expression: `
3645
+ CREATE PROCEDURE GetUser(IN userId INT)
3646
+ BEGIN
3647
+ SELECT * FROM users WHERE id = userId LIMIT 1;
3648
+ END;
3649
+ `,
3650
+ synchronize: true
3651
+ })
3652
+ }
3653
+ }
3654
+
3655
+ const storeProcedure = new MyStoreProcedure()
3656
+
3657
+ storeProcedure.call('AddUser', { name : 'tspace-mysql' , email : 'tspace-mysql@example.com'})
3658
+ .then(r => console.log(r))
3659
+ .catch(e => console.log(e))
3660
+
3661
+ storeProcedure.call('GetUser',[1])
3662
+ .then(r => console.log(r))
3663
+ .catch(e => console.log(e))
3664
+
3665
+ storeProcedure.call('GetUsers',[])
3666
+ .then(r => console.log(r))
3667
+ .catch(e => console.log(e))
3668
+
3669
+ ```
3360
3670
  ## Blueprint
3361
3671
 
3362
3672
  Blueprint is a tool used for defining database schemas programmatically.
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const Model = (model, npm, schema) => {
4
- return `import { Model , Blueprint , TSchema , TRelation } from '${npm}'
4
+ return `import { Model , Blueprint , type T } from '${npm}'
5
5
 
6
6
  const schema = ${schema}
7
7
 
8
- type TS = TSchema<typeof schema>
8
+ type TS = T.Schema<typeof schema>
9
9
 
10
- type TR = TRelation<{
10
+ type TR = T.Relation<{
11
11
  // ... name your relationship
12
12
  }>
13
13
 
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/cli/generate/model.ts"],"names":[],"mappings":";;AAAA,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,MAAe,EAAE,EAAE;IAC9D,OAAO,4DAA4D,GAAG;;iBAErD,MAAM;;;;;;;;QAQf,KAAK;;;;;;;;;;;;WAYF,KAAK;iBACC,KAAK;CACrB,CAAA;AACD,CAAC,CAAA;AAED,kBAAe,KAAK,CAAA"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/cli/generate/model.ts"],"names":[],"mappings":";;AAAA,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,MAAe,EAAE,EAAE;IAC9D,OAAO,+CAA+C,GAAG;;iBAExC,MAAM;;;;;;;;QAQf,KAAK;;;;;;;;;;;;WAYF,KAAK;iBACC,KAAK;CACrB,CAAA;AACD,CAAC,CAAA;AAED,kBAAe,KAAK,CAAA"}