@@ -28,9 +28,28 @@ export interface UsersTable {
28
28
deleted_at : ColumnType < Date , string | undefined , never >
29
29
}
30
30
31
+ interface UserResponse {
32
+ data : Users
33
+ paging : {
34
+ total_records : number
35
+ page : number
36
+ total_pages : number
37
+ }
38
+ next_cursor : number | null
39
+ }
40
+
31
41
export type UserType = Selectable < UsersTable >
32
42
export type NewUser = Insertable < UsersTable >
33
43
export type UserUpdate = Updateable < UsersTable >
44
+ export type Users = UserType [ ]
45
+
46
+ // Define a type for the options parameter
47
+ interface QueryOptions {
48
+ sort ?: { column : keyof UserType , order : 'asc' | 'desc' }
49
+ limit ?: number
50
+ offset ?: number
51
+ page ?: number // New
52
+ }
34
53
35
54
export class UserModel {
36
55
private user : Partial < UserType >
@@ -73,15 +92,34 @@ export class UserModel {
73
92
}
74
93
75
94
// Method to get all users
76
- static async all ( limit : number = 10 , offset : number = 0 ) : Promise < UserModel [ ] > {
77
- const users = await db . selectFrom ( 'users' )
95
+ static async all ( options : QueryOptions = { limit : 10 , offset : 0 , page : 1 } ) : Promise < UserResponse > {
96
+ const totalRecordsResult = await db . selectFrom ( 'users' )
97
+ . select ( db . fn . count ( 'id' ) . as ( 'total' ) ) // Use 'id' or another actual column name
98
+ . executeTakeFirst ( )
99
+
100
+ const totalRecords = Number ( totalRecordsResult ?. total ) || 0
101
+ const totalPages = Math . ceil ( totalRecords / ( options . limit ?? 10 ) )
102
+
103
+ const usersWithExtra = await db . selectFrom ( 'users' )
78
104
. selectAll ( )
79
- . orderBy ( 'created_at ' , 'desc' )
80
- . limit ( limit )
81
- . offset ( offset )
105
+ . orderBy ( 'id ' , 'asc' ) // Assuming 'id' is used for cursor-based pagination
106
+ . limit ( ( options . limit ?? 10 ) + 1 ) // Fetch one extra record
107
+ . offset ( ( options . page ! - 1 ) * ( options . limit ?? 10 ) )
82
108
. execute ( )
83
109
84
- return users . map ( user => new UserModel ( user ) )
110
+ let nextCursor = null
111
+ if ( usersWithExtra . length > ( options . limit ?? 10 ) )
112
+ nextCursor = usersWithExtra . pop ( ) ! . id // Use the ID of the extra record as the next cursor
113
+
114
+ return {
115
+ data : usersWithExtra ,
116
+ paging : {
117
+ total_records : totalRecords ,
118
+ page : options . page ! ,
119
+ total_pages : totalPages ,
120
+ } ,
121
+ next_cursor : nextCursor ,
122
+ }
85
123
}
86
124
87
125
// Method to create a new user
@@ -128,27 +166,47 @@ export class UserModel {
128
166
return new UserModel ( user )
129
167
}
130
168
131
- async where ( criteria : Partial < UserType > ) {
169
+ async where ( criteria : Partial < UserType > , options : QueryOptions = { } ) {
132
170
let query = db . selectFrom ( 'users' )
171
+
172
+ // Existing criteria checks
133
173
if ( criteria . id )
134
174
query = query . where ( 'id' , '=' , criteria . id ) // Kysely is immutable, we must re-assign
175
+
135
176
if ( criteria . email )
136
177
query = query . where ( 'email' , '=' , criteria . email )
178
+
137
179
if ( criteria . name !== undefined ) {
138
180
query = query . where (
139
181
'name' ,
140
182
criteria . name === null ? 'is' : '=' ,
141
183
criteria . name ,
142
184
)
143
185
}
186
+
144
187
if ( criteria . password )
145
188
query = query . where ( 'password' , '=' , criteria . password )
189
+
146
190
if ( criteria . created_at )
147
191
query = query . where ( 'created_at' , '=' , criteria . created_at )
192
+
148
193
if ( criteria . updated_at )
149
194
query = query . where ( 'updated_at' , '=' , criteria . updated_at )
195
+
150
196
if ( criteria . deleted_at )
151
197
query = query . where ( 'deleted_at' , '=' , criteria . deleted_at )
198
+
199
+ // Apply sorting from options
200
+ if ( options . sort )
201
+ query = query . orderBy ( options . sort . column , options . sort . order )
202
+
203
+ // Apply pagination from options
204
+ if ( options . limit !== undefined )
205
+ query = query . limit ( options . limit )
206
+
207
+ if ( options . offset !== undefined )
208
+ query = query . offset ( options . offset )
209
+
152
210
return await query . selectAll ( ) . execute ( )
153
211
}
154
212
@@ -359,11 +417,15 @@ export async function findByEmail(email: string) {
359
417
. executeTakeFirst ( )
360
418
}
361
419
362
- export async function where ( criteria : Partial < UserType > , sort : { column : keyof UserType , order : 'asc' | 'desc' } = { column : 'created_at' , order : 'desc' } ) {
420
+ export async function where (
421
+ criteria : Partial < UserType > ,
422
+ options : QueryOptions = { } ,
423
+ ) {
363
424
let query = db . selectFrom ( 'users' )
364
425
426
+ // Apply criteria
365
427
if ( criteria . id )
366
- query = query . where ( 'id' , '=' , criteria . id ) // Kysely is immutable, we must re-assign
428
+ query = query . where ( 'id' , '=' , criteria . id )
367
429
368
430
if ( criteria . email )
369
431
query = query . where ( 'email' , '=' , criteria . email )
@@ -388,8 +450,16 @@ export async function where(criteria: Partial<UserType>, sort: { column: keyof U
388
450
if ( criteria . deleted_at )
389
451
query = query . where ( 'deleted_at' , '=' , criteria . deleted_at )
390
452
391
- // Apply sorting
392
- query = query . orderBy ( sort . column , sort . order )
453
+ // Apply sorting from options
454
+ if ( options . sort )
455
+ query = query . orderBy ( options . sort . column , options . sort . order )
456
+
457
+ // Apply pagination from options
458
+ if ( options . limit !== undefined )
459
+ query = query . limit ( options . limit )
460
+
461
+ if ( options . offset !== undefined )
462
+ query = query . offset ( options . offset )
393
463
394
464
return await query . selectAll ( ) . execute ( )
395
465
}
@@ -407,3 +477,5 @@ export const User = {
407
477
last,
408
478
where,
409
479
}
480
+
481
+ export default User
0 commit comments