@@ -46,8 +46,10 @@ export module Services {
46
46
47
47
protected _exportedMethods : any = [
48
48
"bootstrap" ,
49
+ "getNamedQueryConfig" ,
49
50
"performNamedQuery" ,
50
- "getNamedQueryConfig"
51
+ "performNamedQueryFromConfig" ,
52
+ "performNamedQueryFromConfigResults" ,
51
53
] ;
52
54
53
55
public async bootstrap ( defBrand ) {
@@ -83,7 +85,8 @@ export module Services {
83
85
queryParams : JSON . stringify ( config . queryParams ) ,
84
86
collectionName : config . collectionName ,
85
87
resultObjectMapping : JSON . stringify ( config . resultObjectMapping ) ,
86
- brandIdFieldPath : config . brandIdFieldPath
88
+ brandIdFieldPath : config . brandIdFieldPath ,
89
+ sort : ( config . sort !== undefined && Array . isArray ( config . sort ) && config . sort . length > 0 ) ? JSON . stringify ( config . sort ) : "" ,
87
90
} ) ) ;
88
91
}
89
92
@@ -95,47 +98,47 @@ export module Services {
95
98
return new NamedQueryConfig ( nQDBEntry )
96
99
}
97
100
98
- async performNamedQuery ( brandIdFieldPath , resultObjectMapping , collectionName , mongoQuery , queryParams , paramMap , brand , start , rows , user = undefined ) : Promise < ListAPIResponse < Object > > {
99
-
101
+ async performNamedQuery ( brandIdFieldPath , resultObjectMapping , collectionName , mongoQuery , queryParams , paramMap , brand , start , rows , user = undefined , sort : NamedQuerySortConfig | undefined = undefined ) : Promise < ListAPIResponse < Object > > {
102
+ const criteriaMeta = { enableExperimentalDeepTargets : true } ;
100
103
this . setParamsInQuery ( mongoQuery , queryParams , paramMap ) ;
101
104
102
105
let that = this ;
103
-
106
+
107
+ // Add branding
104
108
if ( brandIdFieldPath != '' ) {
105
109
mongoQuery [ brandIdFieldPath ] = brand . id ;
106
110
}
107
- sails . log . debug ( "Mongo query to be executed" ) ;
108
- sails . log . debug ( mongoQuery ) ;
109
-
111
+ sails . log . debug ( "Mongo query to be executed" , mongoQuery ) ;
112
+
113
+ // Get the total count of matching records
110
114
let totalItems = 0 ;
111
115
if ( collectionName == 'user' ) {
112
- totalItems = await User . count ( mongoQuery ) . meta ( {
113
- enableExperimentalDeepTargets : true
114
- } ) ;
116
+ totalItems = await User . count ( mongoQuery ) . meta ( criteriaMeta ) ;
115
117
} else {
116
- totalItems = await Record . count ( mongoQuery ) . meta ( {
117
- enableExperimentalDeepTargets : true
118
- } ) ;
118
+ totalItems = await Record . count ( mongoQuery ) . meta ( criteriaMeta ) ;
119
+ }
120
+
121
+ // Build query criteria
122
+ const criteria = {
123
+ where : mongoQuery ,
124
+ skip : start ,
125
+ limit : rows
126
+ } ;
127
+
128
+ // Add sorting
129
+ if ( sort !== undefined && Array . isArray ( sort ) && ( sort ?. length ?? 0 ) > 0 ) {
130
+ // e.g. [{ name: 'ASC'}, { age: 'DESC' }]
131
+ criteria [ 'sort' ] = sort ;
119
132
}
120
133
134
+ // Run query
135
+ sails . log . debug ( "Mongo query criteria" , criteria ) ;
121
136
let results = [ ] ;
122
137
if ( totalItems > 0 ) {
123
138
if ( collectionName == 'user' ) {
124
- results = await User . find ( {
125
- where : mongoQuery ,
126
- skip : start ,
127
- limit : rows
128
- } ) . meta ( {
129
- enableExperimentalDeepTargets : true
130
- } ) ;
139
+ results = await User . find ( criteria ) . meta ( criteriaMeta ) ;
131
140
} else {
132
- results = await Record . find ( {
133
- where : mongoQuery ,
134
- skip : start ,
135
- limit : rows
136
- } ) . meta ( {
137
- enableExperimentalDeepTargets : true
138
- } ) ;
141
+ results = await Record . find ( criteria ) . meta ( criteriaMeta ) ;
139
142
}
140
143
}
141
144
@@ -299,6 +302,69 @@ export module Services {
299
302
return _ . get ( variables , templateOrPath ) ;
300
303
}
301
304
305
+ public async performNamedQueryFromConfig ( config : NamedQueryConfig , paramMap , brand , start , rows , user ?) {
306
+ sails . log . debug ( "performNamedQueryFromConfig with parameters" , {
307
+ config : config ,
308
+ paramMap : paramMap ,
309
+ brand : brand ,
310
+ start : start ,
311
+ rows : rows ,
312
+ user : user
313
+ } ) ;
314
+ const collectionName = _ . get ( config , 'collectionName' , '' ) ?? '' ;
315
+ const resultObjectMapping = _ . get ( config , 'resultObjectMapping' , { } ) ?? { } ;
316
+ const brandIdFieldPath = _ . get ( config , 'brandIdFieldPath' , '' ) ?? '' ;
317
+ const mongoQuery = _ . clone ( _ . get ( config , 'mongoQuery' , { } ) ?? { } ) ;
318
+ const queryParams = _ . get ( config , 'queryParams' , { } ) ?? { } ;
319
+ const sort = _ . get ( config , 'sort' , [ ] ) ?? [ ] ;
320
+ return await this . performNamedQuery ( brandIdFieldPath , resultObjectMapping , collectionName , mongoQuery , queryParams , paramMap , brand , start , rows , user , sort ) ;
321
+ }
322
+
323
+ public async performNamedQueryFromConfigResults ( config : NamedQueryConfig , paramMap : Record < string , string > , brand , queryName : string , start : number = 0 , rows : number = 30 , maxRecords : number = 100 , user = undefined ) {
324
+ const records = [ ] ;
325
+ let requestCount = 0 ;
326
+ sails . log . debug ( `All named query results: start query with name '${ queryName } ' brand ${ JSON . stringify ( brand ) } start ${ start } rows ${ rows } paramMap ${ JSON . stringify ( paramMap ) } ` ) ;
327
+
328
+ while ( true ) {
329
+ // Keep going while there are more results.
330
+
331
+ const response = await this . performNamedQueryFromConfig ( config , paramMap , brand , start , rows , user ) ;
332
+ requestCount += 1 ;
333
+
334
+ if ( ! response ) {
335
+ // stop if there is no response
336
+ sails . log . warn ( `All named query results: invalid query response for '${ queryName } '` ) ;
337
+ break ;
338
+ }
339
+
340
+ // add the new records to the collected records
341
+ sails . log . debug ( `All named query results: add results for '${ queryName } ': start ${ start } rows ${ rows } new results ${ response . records . length } summary ${ JSON . stringify ( response . summary ) } ` ) ;
342
+ for ( const record of response . records ) {
343
+ records . push ( record ) ;
344
+ }
345
+
346
+ const currentRetrievedCount = start + rows ;
347
+ if ( response . summary . numFound <= currentRetrievedCount ) {
348
+ // stop if the total count is less than or equal to the number of records retrieved so far
349
+ sails . log . debug ( `All named query results: reached end of results for '${ queryName } ': start ${ start } rows ${ rows } total results ${ records . length } ` ) ;
350
+ break ;
351
+ }
352
+
353
+ // update the start point
354
+ start = currentRetrievedCount ;
355
+
356
+ // Check the number of records and fail if it is more than maxRecords.
357
+ if ( records . length > maxRecords ) {
358
+ sails . log . warn ( `All named query results: returning early before finished with ${ records . length } results for '${ queryName } ' from ${ requestCount } requests because the number of records is more than max records ${ maxRecords } ` ) ;
359
+ }
360
+
361
+ // continue the while loop
362
+ }
363
+
364
+ sails . log . log ( `All named query results: returning ${ records . length } results for '${ queryName } ' from ${ requestCount } requests` ) ;
365
+ return records ;
366
+ }
367
+
302
368
}
303
369
}
304
370
module . exports = new Services . NamedQueryService ( ) . exports ( ) ;
@@ -319,6 +385,8 @@ enum NamedQueryFormatOptions {
319
385
ISODate = 'ISODate'
320
386
}
321
387
388
+ type NamedQuerySortConfig = Record < string , "ASC" | "DESC" > [ ] ;
389
+
322
390
class QueryParameterDefinition {
323
391
required :boolean
324
392
type :DataType
@@ -342,6 +410,7 @@ export class NamedQueryConfig {
342
410
collectionName : string ;
343
411
resultObjectMapping : any ;
344
412
brandIdFieldPath : string ;
413
+ sort : NamedQuerySortConfig | undefined ;
345
414
346
415
constructor ( values :any ) {
347
416
this . name = values . name ;
@@ -355,6 +424,7 @@ export class NamedQueryConfig {
355
424
this . collectionName = values . collectionName ;
356
425
this . resultObjectMapping = JSON . parse ( values . resultObjectMapping ) ;
357
426
this . brandIdFieldPath = values . brandIdFieldPath ;
427
+ this . sort = ( values . sort !== undefined && values . sort . length > 0 ) ? JSON . parse ( values . sort ) : [ ] ;
358
428
}
359
429
}
360
430
0 commit comments