@@ -7,6 +7,13 @@ import Route from '@ember/routing/route';
77import { service } from '@ember/service' ;
88import { action } from '@ember/object' ;
99import { restartableTask , timeout } from 'ember-concurrency' ;
10+ import chunk from 'lodash/chunk' ;
11+
12+ // Maximum expression tree depth is 1000 so
13+ // we limit the number of expressions in a query.
14+ // See "Maximum Depth Of An Expression Tree" in
15+ // https://www.sqlite.org/limits.html
16+ const MAX_EXPR_NUM = 999 ;
1017
1118export default class ScopesScopeSessionsIndexRoute extends Route {
1219 // =services
@@ -114,10 +121,11 @@ export default class ScopesScopeSessionsIndexRoute extends Route {
114121 const totalItems = sessions . meta ?. totalItems ;
115122
116123 const allSessions = await this . getAllSessions ( scope_id ) ;
117- const [ associatedUsers , associatedTargets ] = await Promise . all ( [
118- this . getAssociatedUsers ( scope , allSessions ) ,
119- this . getAssociatedTargets ( scope , allSessions ) ,
120- ] ) ;
124+ const associatedUsers = await this . getAssociatedUsers ( scope , allSessions ) ;
125+ const associatedTargets = await this . getAssociatedTargets (
126+ scope ,
127+ allSessions ,
128+ ) ;
121129
122130 return {
123131 sessions,
@@ -159,24 +167,45 @@ export default class ScopesScopeSessionsIndexRoute extends Route {
159167 this . can . can ( 'list model' , globalScope , { collection : 'users' } ) &&
160168 this . can . can ( 'list model' , orgScope , { collection : 'users' } )
161169 ) {
162- const uniqueSessionUserIds = new Set (
163- allSessions
164- . filter ( ( session ) => session . user_id )
165- . map ( ( session ) => session . user_id ) ,
170+ const users = await this . store . query (
171+ 'user' ,
172+ {
173+ scope_id : 'global' ,
174+ recursive : true ,
175+ page : 1 ,
176+ pageSize : 1 ,
177+ } ,
178+ { pushToStore : false } ,
166179 ) ;
167- const filters = {
168- id : { values : [ ] } ,
169- } ;
170- uniqueSessionUserIds . forEach ( ( userId ) => {
171- filters . id . values . push ( { equals : userId } ) ;
172- } ) ;
173- const associatedUsersQuery = {
174- scope_id : 'global' ,
175- recursive : true ,
176- query : { filters } ,
177- } ;
178180
179- return this . store . query ( 'user' , associatedUsersQuery ) ;
181+ if ( ! users . length ) {
182+ return [ ] ;
183+ }
184+
185+ const uniqueSessionUserIds = [
186+ ...new Set (
187+ allSessions
188+ . filter ( ( session ) => session . user_id )
189+ . map ( ( session ) => session . user_id ) ,
190+ ) ,
191+ ] ;
192+ const chunkedUserIds = chunk ( uniqueSessionUserIds , MAX_EXPR_NUM ) ;
193+ const associatedUsersPromises = chunkedUserIds . map ( ( userIds ) =>
194+ this . store . query (
195+ 'user' ,
196+ {
197+ scope_id : 'global' ,
198+ query : {
199+ filters : {
200+ id : { values : userIds . map ( ( userId ) => ( { equals : userId } ) ) } ,
201+ } ,
202+ } ,
203+ } ,
204+ { peekDb : true } ,
205+ ) ,
206+ ) ;
207+ const usersArray = await Promise . all ( associatedUsersPromises ) ;
208+ return usersArray . flat ( ) ;
180209 }
181210
182211 return [ ] ;
@@ -189,21 +218,52 @@ export default class ScopesScopeSessionsIndexRoute extends Route {
189218 */
190219 async getAssociatedTargets ( scope , allSessions ) {
191220 if ( this . can . can ( 'list model' , scope , { collection : 'targets' } ) ) {
192- const uniqueSessionTargetIds = new Set (
193- allSessions
194- . filter ( ( session ) => session . target_id )
195- . map ( ( session ) => session . target_id ) ,
221+ const targets = await this . store . query (
222+ 'target' ,
223+ {
224+ scope_id : scope . id ,
225+ query : {
226+ filters : {
227+ scope_id : [ { equals : scope . id } ] ,
228+ } ,
229+ } ,
230+ page : 1 ,
231+ pageSize : 1 ,
232+ } ,
233+ { pushToStore : false } ,
196234 ) ;
197- const filters = { id : { values : [ ] } } ;
198- uniqueSessionTargetIds . forEach ( ( targetId ) => {
199- filters . id . values . push ( { equals : targetId } ) ;
200- } ) ;
201- const associatedTargetsQuery = {
202- scope_id : scope . id ,
203- query : { filters } ,
204- } ;
205235
206- return this . store . query ( 'target' , associatedTargetsQuery ) ;
236+ if ( ! targets . length ) {
237+ return [ ] ;
238+ }
239+
240+ const uniqueSessionTargetIds = [
241+ ...new Set (
242+ allSessions
243+ . filter ( ( session ) => session . target_id )
244+ . map ( ( session ) => session . target_id ) ,
245+ ) ,
246+ ] ;
247+
248+ const chunkedTargetIds = chunk ( uniqueSessionTargetIds , MAX_EXPR_NUM ) ;
249+ const associatedTargetsPromises = chunkedTargetIds . map ( ( targetIds ) =>
250+ this . store . query (
251+ 'target' ,
252+ {
253+ scope_id : scope . id ,
254+ query : {
255+ filters : {
256+ id : {
257+ values : targetIds . map ( ( targetId ) => ( { equals : targetId } ) ) ,
258+ } ,
259+ } ,
260+ } ,
261+ } ,
262+ { peekDb : true } ,
263+ ) ,
264+ ) ;
265+ const targetsArray = await Promise . all ( associatedTargetsPromises ) ;
266+ return targetsArray . flat ( ) ;
207267 }
208268
209269 return [ ] ;
0 commit comments