|
|
@@ -175,55 +175,97 @@ klass.parseCommand = function parseCommand(cmdObj, ctx){
|
|
|
return pipelineInst;
|
|
|
};
|
|
|
|
|
|
+// sync callback for Pipeline#run if omitted
|
|
|
+klass.SYNC_CALLBACK = function(err, results){
|
|
|
+ if (err) throw err;
|
|
|
+ return results.result;
|
|
|
+};
|
|
|
+
|
|
|
+function ifError(err) {
|
|
|
+ if (err) throw err;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Run the pipeline
|
|
|
* @method run
|
|
|
* @param inputSource {DocumentSource} The input document source for the pipeline
|
|
|
- * @param callback {Function} The callback function
|
|
|
+ * @param [callback] {Function} Optional callback function if using async extensions
|
|
|
**/
|
|
|
proto.run = function run(inputSource, callback){
|
|
|
if (inputSource && !(inputSource instanceof DocumentSource)) throw new Error("arg `inputSource` must be an instance of DocumentSource");
|
|
|
- if (!callback) throw new Error("arg `callback` required");
|
|
|
+ if (!callback) callback = klass.SYNC_CALLBACK;
|
|
|
var self = this;
|
|
|
- inputSource.setSource(undefined, function(err){ //TODO: HACK: temp solution to the fact that we need to initialize our source since we're using setSource as a workaround for the lack of real async cursors
|
|
|
- if (err) return callback(err);
|
|
|
- // chain together the sources we found
|
|
|
+ if (callback === klass.SYNC_CALLBACK) { // SYNCHRONOUS MODE
|
|
|
+ inputSource.setSource(undefined, ifError); //TODO: HACK: temp solution to the fact that we need to initialize our source since we're using setSource as a workaround for the lack of real async cursors
|
|
|
var source = inputSource;
|
|
|
- async.eachSeries(
|
|
|
- self.sourceVector,
|
|
|
- function eachSrc(temp, next){
|
|
|
- temp.setSource(source, function(err){
|
|
|
- if (err) return next(err);
|
|
|
- source = temp;
|
|
|
- return next();
|
|
|
- });
|
|
|
- },
|
|
|
- function doneSrcs(err){ //source is left pointing at the last source in the chain
|
|
|
- if (err) return callback(err);
|
|
|
- /*
|
|
|
- Iterate through the resulting documents, and add them to the result.
|
|
|
- We do this even if we're doing an explain, in order to capture the document counts and other stats.
|
|
|
- However, we don't capture the result documents for explain.
|
|
|
- */
|
|
|
- // the array in which the aggregation results reside
|
|
|
- var resultArray = [];
|
|
|
- try{
|
|
|
- for(var hasDoc = !source.eof(); hasDoc; hasDoc = source.advance()) {
|
|
|
- var document = source.getCurrent();
|
|
|
- resultArray.push(document); // add the document to the result set
|
|
|
- //Commenting out this assertion for munge. MUHAHAHA!!!
|
|
|
- // object will be too large, assert. the extra 1KB is for headers
|
|
|
- //if(resultArray.len() < BSONObjMaxUserSize - 1024) throw new Error("aggregation result exceeds maximum document size (" + BSONObjMaxUserSize / (1024 * 1024) + "MB); code 16389");
|
|
|
+ for(var i = 0, l = self.sourceVector.length; i < l; i++){
|
|
|
+ var temp = self.sourceVector[i];
|
|
|
+ temp.setSource(source, ifError);
|
|
|
+ source = temp;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ Iterate through the resulting documents, and add them to the result.
|
|
|
+ We do this even if we're doing an explain, in order to capture the document counts and other stats.
|
|
|
+ However, we don't capture the result documents for explain.
|
|
|
+ */
|
|
|
+ var resultArray = [];
|
|
|
+ try{
|
|
|
+ for(var hasDoc = !source.eof(); hasDoc; hasDoc = source.advance()) {
|
|
|
+ var document = source.getCurrent();
|
|
|
+ resultArray.push(document); // add the document to the result set
|
|
|
+ //Commenting out this assertion for munge. MUHAHAHA!!!
|
|
|
+ // object will be too large, assert. the extra 1KB is for headers
|
|
|
+ //if(resultArray.len() < BSONObjMaxUserSize - 1024) throw new Error("aggregation result exceeds maximum document size (" + BSONObjMaxUserSize / (1024 * 1024) + "MB); code 16389");
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ return callback(err);
|
|
|
+ }
|
|
|
+ var result = {
|
|
|
+ result: resultArray
|
|
|
+// ,ok: true; //not actually in here... where does this come from?
|
|
|
+ };
|
|
|
+ return callback(null, result);
|
|
|
+ } else { // ASYNCHRONOUS MODE //TODO: move this up to a higher level package?
|
|
|
+ return inputSource.setSource(undefined, function(err){ //TODO: HACK: temp solution to the fact that we need to initialize our source since we're using setSource as a workaround for the lack of real async cursors
|
|
|
+ if (err) return callback(err);
|
|
|
+ // chain together the sources we found
|
|
|
+ var source = inputSource;
|
|
|
+ async.eachSeries(
|
|
|
+ self.sourceVector,
|
|
|
+ function eachSrc(temp, next){
|
|
|
+ temp.setSource(source, function(err){
|
|
|
+ if (err) return next(err);
|
|
|
+ source = temp;
|
|
|
+ return next();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ function doneSrcs(err){ //source is left pointing at the last source in the chain
|
|
|
+ if (err) return callback(err);
|
|
|
+ /*
|
|
|
+ Iterate through the resulting documents, and add them to the result.
|
|
|
+ We do this even if we're doing an explain, in order to capture the document counts and other stats.
|
|
|
+ However, we don't capture the result documents for explain.
|
|
|
+ */
|
|
|
+ // the array in which the aggregation results reside
|
|
|
+ var resultArray = [];
|
|
|
+ try{
|
|
|
+ for(var hasDoc = !source.eof(); hasDoc; hasDoc = source.advance()) {
|
|
|
+ var document = source.getCurrent();
|
|
|
+ resultArray.push(document); // add the document to the result set
|
|
|
+ //Commenting out this assertion for munge. MUHAHAHA!!!
|
|
|
+ // object will be too large, assert. the extra 1KB is for headers
|
|
|
+ //if(resultArray.len() < BSONObjMaxUserSize - 1024) throw new Error("aggregation result exceeds maximum document size (" + BSONObjMaxUserSize / (1024 * 1024) + "MB); code 16389");
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ return callback(err);
|
|
|
}
|
|
|
- } catch (err) {
|
|
|
- return callback(err);
|
|
|
+ var result = {
|
|
|
+ result: resultArray
|
|
|
+ // ,ok: true; //not actually in here... where does this come from?
|
|
|
+ };
|
|
|
+ return callback(null, result);
|
|
|
}
|
|
|
- var result = {
|
|
|
- result: resultArray
|
|
|
-// ,ok: true; //not actually in here... where does this come from?
|
|
|
- };
|
|
|
- return callback(null, result);
|
|
|
- }
|
|
|
- );
|
|
|
- });
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }
|
|
|
};
|