1
1
import { db } from '@stacksjs/database'
2
+ import type { Collection } from '@stacksjs/collections'
3
+ import { collect } from '@stacksjs/collections'
2
4
3
5
export interface User {
4
6
id : number
5
-
6
7
name : string
7
8
email : string
8
-
9
9
password : string
10
-
11
10
created_at : Date
12
11
}
13
12
@@ -17,23 +16,36 @@ export class UserModel {
17
16
private _isSelectInvoked = false
18
17
public _id : number | undefined = undefined
19
18
private cols : string [ ] = [ ]
19
+ private useSoftDeletes = true
20
20
21
21
queryBuilder = db . selectFrom ( 'users' ) // Initialize queryBuilder
22
22
queryBuilderStore = db . insertInto ( 'users' ) // Initialize queryBuilder
23
23
queryBuilderUpdate = db . updateTable ( 'users' ) // Initialize queryBuilder
24
24
queryBuilderDelete = db . deleteFrom ( 'users' ) // Initialize queryBuilder
25
25
26
- public async find ( id : number ) : Promise < User > {
27
- this . _data = await this . queryBuilder . selectAll ( )
28
- . where ( 'id' , '=' , id )
29
- . executeTakeFirst ( )
26
+ private getKeyName ( ) : string {
27
+ return 'id'
28
+ }
30
29
31
- if ( this . _data === undefined )
32
- throw new Error ( 'User not found!' )
30
+ public async find ( id : number | number [ ] ) : Promise < User | Collection < User > > {
31
+ if ( Array . isArray ( id ) )
32
+ return await this . findMany ( id )
33
+
34
+ let query = this . queryBuilder . selectAll ( )
35
+ . where ( this . getKeyName ( ) , '=' , id )
36
+
37
+ if ( this . useSoftDeletes )
38
+ query = query . where ( 'deleted_at' , 'is' , null )
39
+
40
+ this . _data = await query . executeTakeFirst ( )
33
41
34
42
return this . _createProxy ( )
35
43
}
36
44
45
+ public async findMany ( id : number [ ] | string [ ] ) : Promise < User | Collection < User > > {
46
+ return await this . whereIn ( this . getKeyName ( ) , id ) . get ( )
47
+ }
48
+
37
49
private _createProxy ( ) : User & { [ key : string ] : Function } {
38
50
return new Proxy ( this . _data || { } , {
39
51
get : ( target , prop : keyof User | string ) : any => {
@@ -51,10 +63,10 @@ export class UserModel {
51
63
} )
52
64
}
53
65
54
- public update ( obj : Partial < User > ) {
66
+ public update ( obj : Partial < User > ) : any {
55
67
if ( this . _data && this . _data ?. id ) {
56
68
return this . queryBuilderUpdate . set ( obj )
57
- . where ( 'id' , '=' , this . _data ?. id )
69
+ . where ( this . getKeyName ( ) , '=' , this . _data ?. id )
58
70
. executeTakeFirst ( )
59
71
}
60
72
}
@@ -64,18 +76,73 @@ export class UserModel {
64
76
. execute ( )
65
77
}
66
78
67
- public async get ( ) {
79
+ public async get ( ) : Promise < Collection < User > > {
80
+ if ( this . useSoftDeletes )
81
+ return collect ( await this . getSoftDeletes ( ) )
82
+
68
83
if ( this . _isSelectInvoked )
69
- return await this . queryBuilder . select ( this . cols ) . execute ( )
84
+ return collect ( await this . queryBuilder . select ( this . cols ) . execute ( ) )
70
85
71
- return await this . queryBuilder . selectAll ( ) . execute ( )
86
+ return collect ( await this . queryBuilder . selectAll ( ) . execute ( ) )
72
87
}
73
88
74
- public where ( ...args : ( string | number | boolean ) [ ] ) {
75
- // TODO: resolve this
76
- // @ts -expect-error resolve this
89
+ public async trashed ( ) {
90
+ if ( this . _isSelectInvoked )
91
+ return await this . queryBuilder . where ( 'deleted_at' , 'is not' , null ) . select ( this . cols ) . execute ( )
92
+
93
+ return await this . queryBuilder . where ( 'deleted_at' , 'is not' , null ) . selectAll ( ) . execute ( )
94
+ }
95
+
96
+ private async getSoftDeletes ( ) {
97
+ if ( this . _isSelectInvoked )
98
+ return await this . queryBuilder . where ( 'deleted_at' , 'is' , null ) . select ( this . cols ) . execute ( )
99
+
100
+ return await this . queryBuilder . where ( 'deleted_at' , 'is' , null ) . selectAll ( ) . execute ( )
101
+ }
102
+
103
+ public where ( ...args : ( string | number | boolean ) [ ] ) : this {
104
+ if ( args . length === 2 ) {
105
+ const [ column , value ] = args
106
+ this . queryBuilder = this . queryBuilder . where ( column , '=' , value )
107
+ }
108
+ else { this . queryBuilder = this . queryBuilder . where ( ...args ) }
109
+
110
+ return this
111
+ }
112
+
113
+ public orWhere ( ...args : ( string | number | boolean ) [ ] ) : this {
114
+ this . queryBuilder = this . queryBuilder . where ( eb => eb . or ( [
115
+ eb ( ...args ) ,
116
+ ] ) )
117
+
118
+ return this
119
+ }
120
+
121
+ public whereIn ( ...args : ( string [ ] | string | number [ ] | boolean [ ] ) [ ] ) : this {
122
+ if ( args . length === 2 ) {
123
+ const [ column , value ] = args
124
+ this . queryBuilder = this . queryBuilder . where ( column , 'in' , value )
125
+ }
126
+ else { this . queryBuilder = this . queryBuilder . where ( ...args ) }
127
+
128
+ return this
129
+ }
130
+
131
+ public whereNull ( col : string ) : this {
132
+ this . queryBuilder = this . queryBuilder . where ( col , 'is' , null )
133
+
134
+ return this
135
+ }
77
136
78
- this . queryBuilder = this . queryBuilder . where ( ...args )
137
+ public when ( condition : boolean , callback : ( instance : this) => any ) : this {
138
+ if ( condition )
139
+ callback ( this )
140
+
141
+ return this
142
+ }
143
+
144
+ public whereNotNull ( col : string ) : this {
145
+ this . queryBuilder = this . queryBuilder . where ( col , 'is not' , null )
79
146
80
147
return this
81
148
}
@@ -86,13 +153,13 @@ export class UserModel {
86
153
return this
87
154
}
88
155
89
- public distinctOn ( col : string ) {
156
+ public distinctOn ( col : string ) : this {
90
157
this . queryBuilder = this . queryBuilder . distinctOn ( col )
91
158
92
159
return this
93
160
}
94
161
95
- public limit ( limit : number ) {
162
+ public limit ( limit : number ) : this {
96
163
this . queryBuilder = this . queryBuilder . limit ( limit )
97
164
98
165
return this
@@ -110,82 +177,123 @@ export class UserModel {
110
177
return this
111
178
}
112
179
113
- public innerJoin ( ...args : ( string ) [ ] ) {
180
+ public innerJoin ( ...args : string [ ] ) : this {
114
181
this . queryBuilder = this . queryBuilder . innerJoin ( ...args )
115
182
116
183
return this
117
184
}
118
185
119
- public join ( ...args : string [ ] ) {
186
+ public join ( ...args : string [ ] ) : this {
120
187
this . queryBuilder = this . queryBuilder . innerJoin ( ...args )
121
188
122
189
return this
123
190
}
124
191
125
- public rightJoin ( ...args : string [ ] ) {
192
+ public having ( ...args : string [ ] ) : this {
193
+ this . queryBuilder = this . queryBuilder . having ( ...args )
194
+
195
+ return this
196
+ }
197
+
198
+ public rightJoin ( ...args : string [ ] ) : this {
126
199
this . queryBuilder = this . queryBuilder . rightJoin ( ...args )
127
200
128
201
return this
129
202
}
130
203
131
- public leftJoin ( ...args : string [ ] ) {
204
+ public leftJoin ( ...args : string [ ] ) : this {
132
205
this . queryBuilder = this . queryBuilder . leftJoin ( ...args )
133
206
134
207
return this
135
208
}
136
209
137
- public offset ( offset : number ) {
210
+ public offset ( offset : number ) : this {
138
211
this . queryBuilder = this . queryBuilder . offset ( offset )
139
212
140
213
return this
141
214
}
142
215
143
- public fullJoin ( ...args : string [ ] ) {
216
+ public fullJoin ( ...args : string [ ] ) : this {
144
217
this . queryBuilder = this . queryBuilder . fullJoin ( ...args )
145
218
146
219
return this
147
220
}
148
221
149
- public orderByDesc ( col : string ) {
222
+ public innerJoinLateral ( ...args : string [ ] ) {
223
+ this . queryBuilder . innerJoinLateral ( ...args )
224
+
225
+ return this
226
+ }
227
+
228
+ public leftJoinLateral ( ...args ) {
229
+ this . queryBuilder . leftJoinLateral ( ...args )
230
+
231
+ return this
232
+ }
233
+
234
+ public orderByDesc ( col : string ) : this {
150
235
this . queryBuilder = this . queryBuilder . orderBy ( col , 'desc' )
151
236
152
237
return this
153
238
}
154
239
155
- public select ( ...args : string [ ] ) {
240
+ public select ( ...args : string [ ] ) : this {
156
241
this . cols = args
157
242
this . _isSelectInvoked = true
243
+
158
244
// TODO: resolve this
159
245
// @ts -expect-error resolve this
160
-
161
246
this . queryBuilder = this . queryBuilder . select ( ...args )
162
247
163
248
return this
164
249
}
165
250
166
- public first ( ) : Promise < any > {
251
+ public async first ( ) : Promise < User > {
167
252
// Execute the query using queryBuilder
168
- return this . queryBuilder . executeTakeFirst ( )
253
+ if ( this . _isSelectInvoked )
254
+ this . _data = await this . queryBuilder . select ( this . cols ) . executeTakeFirst ( )
255
+ else
256
+ this . _data = await this . queryBuilder . selectAll ( ) . executeTakeFirst ( )
257
+
258
+ return this . _createProxy ( )
169
259
}
170
260
171
- public store ( obj : any [ ] ) {
261
+ public store ( obj : any [ ] ) : User {
172
262
// Execute the query using queryBuilder
173
263
return this . queryBuilderStore . values ( obj )
174
264
. executeTakeFirst ( )
175
265
}
176
266
177
- public createMany ( obj : any [ ] ) {
267
+ public createMany ( obj : any [ ] ) : User [ ] {
178
268
// Execute the query using queryBuilder
179
269
return this . queryBuilderStore . values ( obj )
180
270
. executeTakeFirst ( )
181
271
}
182
272
183
- public delete ( ) {
184
- // Execute the query using queryBuilder
185
- return this . queryBuilderDelete
186
- . where ( 'id' , '=' , 1 )
187
- . executeTakeFirst ( )
273
+ public async delete ( ) : Promise < any > {
274
+ if ( this . _data && this . _data ?. id ) {
275
+ if ( this . useSoftDeletes )
276
+ return await this . update ( { deleted_at : new Date ( ) } )
277
+
278
+ return this . forceDelete ( )
279
+ }
280
+ }
281
+
282
+ public forceDelete ( ) : any {
283
+ if ( this . _data && this . _data ?. id ) {
284
+ return this . queryBuilderDelete . where ( this . getKeyName ( ) , '=' , this . _data ?. id )
285
+ . executeTakeFirst ( )
286
+ }
188
287
}
189
288
}
190
289
290
+ const UserInstance = new UserModel ( )
291
+
292
+ const user = await UserInstance . when ( true , ( query ) => {
293
+ // Modify the query as needed
294
+ return query . where ( 'id' , 1 )
295
+ } ) . get ( )
296
+
297
+ console . log ( user )
298
+
191
299
process . exit ( 0 )
0 commit comments