@@ -59,19 +59,16 @@ CompositeDatasource.prototype._getExactCount = function (datasource, query, call
59
59
// Otherwise, count all the triples manually
60
60
var emptyQuery = { offset : 0 , subject : query . subject , predicate : query . predicate , object : query . object } ;
61
61
var exactCount = 0 ;
62
- var countingTripleStream = {
63
- push : function ( triple ) {
64
- if ( triple )
65
- exactCount ++ ;
66
- else {
67
- // Cache large values; small ones are calculated fast anyway
68
- if ( exactCount > 1000 )
69
- cache . set ( cacheKey , exactCount ) ;
70
- callback ( exactCount ) ;
71
- }
62
+ var triplesCounter = {
63
+ _push : function ( triple ) { exactCount ++ ; } ,
64
+ close : function ( ) {
65
+ // Cache large values; small ones are calculated fast anyway
66
+ if ( exactCount > 1000 )
67
+ cache . set ( cacheKey , exactCount ) ;
68
+ callback ( exactCount ) ;
72
69
} ,
73
70
} ;
74
- datasource . _executeQuery ( emptyQuery , countingTripleStream , noop ) ;
71
+ datasource . _executeQuery ( emptyQuery , triplesCounter , noop ) ;
75
72
} ;
76
73
77
74
// Recursively find all required datasource composition info to perform a query.
@@ -92,61 +89,65 @@ CompositeDatasource.prototype._getDatasourceInfo = function (query, absoluteOffs
92
89
// We checked all datasources, return our accumulated information
93
90
callback ( chosenDatasource , chosenOffset , totalCount , hasExactCount ) ;
94
91
else {
95
- var emptyTripleStream = { push : noop } ;
96
92
var datasource = self . _getDatasourceById ( datasourceIndex ) ;
97
- datasource . _executeQuery ( emptyQuery , emptyTripleStream , function ( metadata ) {
98
- var count = metadata . totalCount ;
99
- var exact = metadata . hasExactCount ;
100
- // If we are still looking for an appropriate datasource, we need exact counts!
101
- if ( offset > 0 && ! exact ) {
102
- self . _getExactCount ( datasource , query , function ( exactCount ) {
103
- count = exactCount ;
104
- exact = true ;
105
- continueRecursion ( ) ;
106
- } ) ;
107
- }
108
- else
109
- continueRecursion ( ) ;
110
-
111
- function continueRecursion ( ) {
112
- if ( chosenDatasource < 0 && offset < count ) {
113
- // We can start querying from this datasource
114
- setImmediate ( function ( ) {
115
- findRecursive ( datasourceIndex + 1 , offset - count , datasourceIndex , offset ,
116
- totalCount + count , hasExactCount && exact ) ;
93
+ var metadataReader = {
94
+ _push : noop ,
95
+ close : noop ,
96
+ setProperty : function ( name , metadata ) {
97
+ if ( name !== 'metadata' ) return ;
98
+ // If we are still looking for an appropriate datasource, we need exact counts
99
+ var count = metadata . totalCount , exact = metadata . hasExactCount ;
100
+ if ( offset > 0 && ! exact ) {
101
+ self . _getExactCount ( datasource , query , function ( exactCount ) {
102
+ count = exactCount ;
103
+ exact = true ;
104
+ continueRecursion ( ) ;
117
105
} ) ;
118
106
}
119
- else {
120
- // We forward our accumulated information and go check the next datasource
121
- setImmediate ( function ( ) {
122
- findRecursive ( datasourceIndex + 1 , offset - count , chosenDatasource , chosenOffset ,
123
- totalCount + count , hasExactCount && exact ) ;
124
- } ) ;
107
+ else
108
+ continueRecursion ( ) ;
109
+
110
+ function continueRecursion ( ) {
111
+ if ( chosenDatasource < 0 && offset < count ) {
112
+ // We can start querying from this datasource
113
+ setImmediate ( function ( ) {
114
+ findRecursive ( datasourceIndex + 1 , offset - count , datasourceIndex , offset ,
115
+ totalCount + count , hasExactCount && exact ) ;
116
+ } ) ;
117
+ }
118
+ else {
119
+ // We forward our accumulated information and go check the next datasource
120
+ setImmediate ( function ( ) {
121
+ findRecursive ( datasourceIndex + 1 , offset - count , chosenDatasource , chosenOffset ,
122
+ totalCount + count , hasExactCount && exact ) ;
123
+ } ) ;
124
+ }
125
125
}
126
- }
127
- } ) ;
126
+ } ,
127
+ } ;
128
+ datasource . _executeQuery ( emptyQuery , metadataReader ) ;
128
129
}
129
130
}
130
131
} ;
131
132
132
133
// Writes the results of the query to the given triple stream
133
- CompositeDatasource . prototype . _executeQuery = function ( query , tripleStream , metadataCallback ) {
134
+ CompositeDatasource . prototype . _executeQuery = function ( query , destination ) {
134
135
var offset = query . offset || 0 , limit = query . limit || Infinity ;
135
136
var self = this ;
136
137
this . _getDatasourceInfo ( query , offset , function ( datasourceIndex , relativeOffset , totalCount , hasExactCount ) {
137
138
if ( datasourceIndex < 0 ) {
138
139
// No valid datasource has been found
139
- metadataCallback ( { totalCount : totalCount , hasExactCount : hasExactCount } ) ;
140
- tripleStream . push ( null ) ;
140
+ destination . setProperty ( 'metadata' , { totalCount : totalCount , hasExactCount : hasExactCount } ) ;
141
+ destination . close ( ) ;
141
142
}
142
143
else {
143
144
// Send query to first applicable datasource and optionally emit triples from consecutive datasources
144
- metadataCallback ( { totalCount : totalCount , hasExactCount : hasExactCount } ) ;
145
- var emitted = 0 ;
145
+ destination . setProperty ( 'metadata' , { totalCount : totalCount , hasExactCount : hasExactCount } ) ;
146
146
147
147
// Modify our triple stream so that if all results from one datasource have arrived,
148
148
// check if we haven't reached the limit and if so, trigger a new query for the next datasource.
149
- tripleStream . push = makeSmartPush ( tripleStream , function ( localEmittedCount ) {
149
+ var emitted = 0 ;
150
+ countItems ( destination , function ( localEmittedCount ) {
150
151
// This is called after the last element has been pushed
151
152
152
153
// If we haven't reached our limit, try to fill it with other datasource query results.
@@ -156,36 +157,31 @@ CompositeDatasource.prototype._executeQuery = function (query, tripleStream, met
156
157
var localLimit = limit - emitted ;
157
158
var subQuery = { offset : 0 , limit : localLimit ,
158
159
subject : query . subject , predicate : query . predicate , object : query . object } ;
159
- self . _getDatasourceById ( datasourceIndex ) . _executeQuery ( subQuery , tripleStream , noop ) ;
160
- return true ;
160
+ self . _getDatasourceById ( datasourceIndex ) . _executeQuery ( subQuery , destination , noop ) ;
161
+ return false ;
161
162
}
162
163
else
163
- return false ;
164
+ return true ;
164
165
} ) ;
165
166
166
167
// Initiate query to the first datasource.
167
168
var subQuery = { offset : relativeOffset , limit : limit ,
168
169
subject : query . subject , predicate : query . predicate , object : query . object } ;
169
- self . _getDatasourceById ( datasourceIndex ) . _executeQuery ( subQuery , tripleStream , noop ) ;
170
+ self . _getDatasourceById ( datasourceIndex ) . _executeQuery ( subQuery , destination , noop ) ;
170
171
}
171
172
} ) ;
172
173
173
- // Replaces a tripleStream.push
174
- // It takes the tripleStream as first argument and a callback as second argument.
175
- // The callback will be called when the push function is called with a falsy value.
176
- // Returning a falsy value inside the callback will delegate the falsy value to the original
177
- // push function anyways.
178
- function makeSmartPush ( self , nullCb ) {
179
- var count = 0 , originalPush = self . push ;
180
- return function ( element ) {
181
- if ( ! element ) {
182
- if ( ! nullCb ( count ) )
183
- originalPush . call ( self , element ) ;
184
- }
185
- else {
186
- count ++ ;
187
- originalPush . call ( self , element ) ;
188
- }
174
+ // Counts the number of triples and sends them through the callback,
175
+ // only closing the iterator when the callback returns true.
176
+ function countItems ( destination , closeCallback ) {
177
+ var count = 0 , originalPush = destination . _push , originalClose = destination . close ;
178
+ destination . _push = function ( element ) {
179
+ count ++ ;
180
+ originalPush . call ( destination , element ) ;
181
+ } ;
182
+ destination . close = function ( ) {
183
+ if ( closeCallback ( count ) )
184
+ originalClose . call ( destination ) ;
189
185
} ;
190
186
}
191
187
} ;
0 commit comments