BVB Source Codes

waterline Show stream.js Source code

Return Download waterline: download stream.js Source code - Download waterline Source code - Type:.js
  1. /**
  2.  * Module dependencies
  3.  */
  4.  
  5. var util = require('util');
  6. var _ = require('@sailshq/lodash');
  7. var async = require('async');
  8. var flaverr = require('flaverr');
  9. var forgeStageTwoQuery = require('../utils/query/forge-stage-two-query');
  10. var Deferred = require('../utils/query/deferred');
  11.  
  12.  
  13. /**
  14.  * stream()
  15.  *
  16.  * Iterate over individual records (or batches of records) that match
  17.  * the specified criteria, populating associations if instructed.
  18.  *
  19.  * ```
  20.  * BlogPost.stream()
  21.  *   .limit(50000)
  22.  *   .sort('title ASC')
  23.  *   .eachRecord(function (blogPost, next){ ... })
  24.  *   .exec(function (err){ ... });
  25.  *
  26.  * // For more usage info (/history), see:
  27.  * // https://gist.github.com/mikermcneil/d1e612cd1a8564a79f61e1f556fc49a6#examples
  28.  * ```
  29.  *
  30.  *  ----------------------------------
  31.  *  ~鈥 This is the "new .stream()". 鈥
  32.  *  ----------------------------------
  33.  *
  34.  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  35.  *
  36.  * Usage without deferred object:
  37.  * ================================================
  38.  *
  39.  * @param {Dictionary?} criteria
  40.  *
  41.  * @param {Function?} eachRecordFn
  42.  *
  43.  * @param {Dictionary} moreQueryKeys
  44.  *        For internal use.
  45.  *        (A dictionary of query keys.)
  46.  *
  47.  * @param {Function?} done
  48.  *        Callback function to run when query has either finished successfully or errored.
  49.  *        (If unspecified, will return a Deferred object instead of actually doing anything.)
  50.  *
  51.  * @param {Ref?} meta
  52.  *     For internal use.
  53.  *
  54.  * @returns {Ref?} Deferred object if no `done` callback was provided
  55.  *
  56.  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  57.  *
  58.  * The underlying query keys:
  59.  * ==============================
  60.  *
  61.  * @qkey {Dictionary?} criteria
  62.  *
  63.  * @qkey {Dictionary?} populates
  64.  *
  65.  * @qkey {Function?} eachRecordFn
  66.  *        An iteratee function to run for each record.
  67.  *        (If specified, then `eachBatchFn` should not ALSO be set.)
  68.  *
  69.  * @qkey {Function?} eachBatchFn
  70.  *        An iteratee function to run for each batch of records.
  71.  *        (If specified, then `eachRecordFn` should not ALSO be set.)
  72.  *
  73.  * @qkey {Dictionary?} meta
  74.  * @qkey {String} using
  75.  * @qkey {String} method
  76.  *
  77.  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  78.  */
  79.  
  80. module.exports = function stream( /* criteria?, eachRecordFn?, moreQueryKeys?, done?, meta? */ ) {
  81.  
  82.   // Set up a few, common local vars for convenience / familiarity.
  83.   var WLModel = this;
  84.   var orm = this.waterline;
  85.   var modelIdentity = this.identity;
  86.  
  87.   // Build query w/ initial, universal keys.
  88.   var query = {
  89.     method: 'stream',
  90.     using: modelIdentity
  91.   };
  92.  
  93.  
  94.   //  鈻堚枅鈺   鈻堚枅鈺 鈻堚枅鈻堚枅鈻堚晽 鈻堚枅鈻堚枅鈻堚枅鈺 鈻堚枅鈺 鈻堚枅鈻堚枅鈻堚晽 鈻堚枅鈻堚枅鈻堚枅鈺 鈻堚枅鈺 鈻堚枅鈻堚枅鈻堚枅鈺椻枅鈻堚枅鈻堚枅鈻堚枅鈺
  95.   //  鈻堚枅鈺   鈻堚枅鈺戔枅鈻堚晹鈺愨晲鈻堚枅鈺椻枅鈻堚晹鈺愨晲鈻堚枅鈺椻枅鈻堚晳鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺戔枅鈻堚晹鈺愨晲鈺愨晲鈺濃枅鈻堚晹鈺愨晲鈺愨晲鈺
  96.   //  鈻堚枅鈺   鈻堚枅鈺戔枅鈻堚枅鈻堚枅鈻堚枅鈺戔枅鈻堚枅鈻堚枅鈻堚晹鈺濃枅鈻堚晳鈻堚枅鈻堚枅鈻堚枅鈻堚晳鈻堚枅鈺  鈻堚枅鈺戔枅鈻堚晳鈻堚枅鈺     鈻堚枅鈻堚枅鈻堚枅鈻堚晽
  97.   //  鈺氣枅鈻堚晽 鈻堚枅鈺斺暆鈻堚枅鈺斺晲鈺愨枅鈻堚晳鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺戔枅鈻堚晹鈺愨晲鈻堚枅鈺戔枅鈻堚晳  鈻堚枅鈺戔枅鈻堚晳鈻堚枅鈺     鈺氣晲鈺愨晲鈺愨枅鈻堚晳
  98.   //   鈺氣枅鈻堚枅鈻堚晹鈺 鈻堚枅鈺  鈻堚枅鈺戔枅鈻堚晳  鈻堚枅鈺戔枅鈻堚晳鈻堚枅鈺  鈻堚枅鈺戔枅鈻堚枅鈻堚枅鈻堚晹鈺濃枅鈻堚晳鈺氣枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈻堚枅鈻堚枅鈻堚晳
  99.   //    鈺氣晲鈺愨晲鈺  鈺氣晲鈺  鈺氣晲鈺濃暁鈺愨暆  鈺氣晲鈺濃暁鈺愨暆鈺氣晲鈺  鈺氣晲鈺濃暁鈺愨晲鈺愨晲鈺愨暆 鈺氣晲鈺 鈺氣晲鈺愨晲鈺愨晲鈺濃暁鈺愨晲鈺愨晲鈺愨晲鈺
  100.   //
  101.  
  102.   // The `done` callback, if one was provided.
  103.   var done;
  104.  
  105.   // Handle the various supported usage possibilities
  106.   // (locate the `done` callback, and extend the `query` dictionary)
  107.   //
  108.   // > Note that we define `args` so that we can insulate access
  109.   // > to the arguments provided to this function.
  110.   var args = arguments;
  111.   (function _handleVariadicUsage(){
  112.  
  113.     // Additional query keys.
  114.     var _moreQueryKeys;
  115.  
  116.     // The metadata container, if one was provided.
  117.     var _meta;
  118.  
  119.  
  120.     // Handle double meaning of first argument:
  121.     //
  122.     // 鈥 stream(criteria, ...)
  123.     var is1stArgDictionary = (_.isObject(args[0]) && !_.isFunction(args[0]) && !_.isArray(args[0]));
  124.     if (is1stArgDictionary) {
  125.       query.criteria = args[0];
  126.     }
  127.     // 鈥 stream(eachRecordFn, ...)
  128.     else {
  129.       query.eachRecordFn = args[0];
  130.     }
  131.  
  132.  
  133.     // Handle double meaning of second argument:
  134.     //
  135.     // 鈥 stream(..., _moreQueryKeys, done, _meta)
  136.     var is2ndArgDictionary = (_.isObject(args[1]) && !_.isFunction(args[1]) && !_.isArray(args[1]));
  137.     if (is2ndArgDictionary) {
  138.       _moreQueryKeys = args[1];
  139.       done = args[2];
  140.       _meta = args[3];
  141.     }
  142.     // 鈥 stream(..., eachRecordFn, ...)
  143.     else {
  144.       query.eachRecordFn = args[1];
  145.     }
  146.  
  147.  
  148.     // Handle double meaning of third argument:
  149.     //
  150.     // 鈥 stream(..., ..., _moreQueryKeys, done, _meta)
  151.     var is3rdArgDictionary = (_.isObject(args[2]) && !_.isFunction(args[2]) && !_.isArray(args[2]));
  152.     if (is3rdArgDictionary) {
  153.       _moreQueryKeys = args[2];
  154.       done = args[3];
  155.       _meta = args[4];
  156.     }
  157.     // 鈥 stream(..., ..., done, _meta)
  158.     else {
  159.       done = args[2];
  160.       _meta = args[3];
  161.     }
  162.  
  163.  
  164.     // Fold in `_moreQueryKeys`, if provided.
  165.     //
  166.     // > Userland is prevented from overriding any of the universal keys this way.
  167.     if (_moreQueryKeys) {
  168.       delete _moreQueryKeys.method;
  169.       delete _moreQueryKeys.using;
  170.       delete _moreQueryKeys.meta;
  171.       _.extend(query, _moreQueryKeys);
  172.     }//>-
  173.  
  174.  
  175.     // Fold in `_meta`, if provided.
  176.     if (_meta) {
  177.       query.meta = _meta;
  178.     }//>-
  179.  
  180.   })();//</self-calling function :: handleVariadicUsage()>
  181.  
  182.  
  183.  
  184.  
  185.   //  鈻堚枅鈻堚枅鈻堚枅鈺 鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈻堚枅鈻堚枅鈺
  186.   //  鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺斺晲鈺愨晲鈺愨暆鈻堚枅鈺斺晲鈺愨晲鈺愨暆鈻堚枅鈺斺晲鈺愨晲鈺愨暆鈻堚枅鈺斺晲鈺愨枅鈻堚晽
  187.   //  鈻堚枅鈺  鈻堚枅鈺戔枅鈻堚枅鈻堚枅鈺  鈻堚枅鈻堚枅鈻堚晽  鈻堚枅鈻堚枅鈻堚晽  鈻堚枅鈻堚枅鈻堚枅鈺斺暆
  188.   //  鈻堚枅鈺  鈻堚枅鈺戔枅鈻堚晹鈺愨晲鈺  鈻堚枅鈺斺晲鈺愨暆  鈻堚枅鈺斺晲鈺愨暆  鈻堚枅鈺斺晲鈺愨枅鈻堚晽
  189.   //  鈻堚枅鈻堚枅鈻堚枅鈺斺暆鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈺     鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈺  鈻堚枅鈺
  190.   //  鈺氣晲鈺愨晲鈺愨晲鈺 鈺氣晲鈺愨晲鈺愨晲鈺愨暆鈺氣晲鈺     鈺氣晲鈺愨晲鈺愨晲鈺愨暆鈺氣晲鈺  鈺氣晲鈺
  191.   //
  192.   //   鈻堚枅鈺椻枅鈻堚枅鈺   鈻堚枅鈻堚晽 鈻堚枅鈻堚枅鈻堚晽 鈻堚枅鈺   鈻堚枅鈺椻枅鈻堚枅鈻堚枅鈻堚晽 鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈺
  193.   //  鈻堚枅鈺斺暆鈻堚枅鈻堚枅鈺 鈻堚枅鈻堚枅鈺戔枅鈻堚晹鈺愨晲鈻堚枅鈺椻暁鈻堚枅鈺 鈻堚枅鈺斺暆鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺斺晲鈺愨晲鈺愨暆鈺氣枅鈻堚晽
  194.   //  鈻堚枅鈺 鈻堚枅鈺斺枅鈻堚枅鈻堚晹鈻堚枅鈺戔枅鈻堚枅鈻堚枅鈻堚枅鈺 鈺氣枅鈻堚枅鈻堚晹鈺 鈻堚枅鈻堚枅鈻堚枅鈺斺暆鈻堚枅鈻堚枅鈻堚晽   鈻堚枅鈺
  195.   //  鈻堚枅鈺 鈻堚枅鈺戔暁鈻堚枅鈺斺暆鈻堚枅鈺戔枅鈻堚晹鈺愨晲鈻堚枅鈺  鈺氣枅鈻堚晹鈺  鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺斺晲鈺愨暆   鈻堚枅鈺
  196.   //  鈺氣枅鈻堚晽鈻堚枅鈺 鈺氣晲鈺 鈻堚枅鈺戔枅鈻堚晳  鈻堚枅鈺   鈻堚枅鈺   鈻堚枅鈻堚枅鈻堚枅鈺斺暆鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈺斺暆
  197.   //   鈺氣晲鈺濃暁鈺愨暆     鈺氣晲鈺濃暁鈺愨暆  鈺氣晲鈺   鈺氣晲鈺   鈺氣晲鈺愨晲鈺愨晲鈺 鈺氣晲鈺愨晲鈺愨晲鈺愨暆鈺氣晲鈺
  198.   //
  199.   //  鈹屸攼 鈹 鈹敩鈹  鈹屸敩鈹   鈹   鈹攢鈹愨攲鈹€鈹愨攲鈹攼鈹 鈹敩鈹€鈹愨攲鈹愨攲  鈹屸攼鈹屸攲鈹€鈹愨敩 鈹  鈹屸敩鈹愨攲鈹€鈹愨攲鈹€鈹愨攲鈹€鈹愨敩鈹€鈹愨敩鈹€鈹愨攲鈹€鈹愨攲鈹攼
  200.   //  鈹溾敶鈹愨攤 鈹傗攤鈹   鈹傗攤  鈹屸敿鈹€  鈹溾敩鈹樷敎鈹  鈹 鈹 鈹傗敎鈹敇鈹傗攤鈹  鈹傗攤鈹傗敎鈹 鈹傗攤鈹   鈹傗攤鈹溾敜 鈹溾敜 鈹溾敜 鈹溾敩鈹樷敎鈹敇鈹溾敜  鈹傗攤
  201.   //  鈹斺攢鈹樷敂鈹€鈹樷敶鈹粹攢鈹樷攢鈹粹敇  鈹斺敇   鈹粹敂鈹€鈹斺攢鈹 鈹 鈹斺攢鈹樷敶鈹斺攢鈹樷敂鈹  鈹樷敂鈹樷敂鈹€鈹樷敂鈹粹敇  鈹€鈹粹敇鈹斺攢鈹樷敂  鈹斺攢鈹樷敶鈹斺攢鈹粹敂鈹€鈹斺攢鈹樷攢鈹粹敇
  202.   //  鈹屸攢    鈹攲鈹€鈹  鈹攢鈹愨攲鈹€鈹愨敩  鈹屸攢鈹愨敩  鈹攲鈹€鈹愨攲鈹愨攲鈹屸敩鈹    鈹€鈹
  203.   //  鈹傗攢鈹€鈹€  鈹傗敎鈹   鈹溾敩鈹樷敎鈹 鈹  鈹溾敜 鈹斺攼鈹屸敇鈹溾攢鈹も攤鈹傗攤 鈹   鈹€鈹€鈹€鈹
  204.   //  鈹斺攢    鈹粹敂    鈹粹敂鈹€鈹斺攢鈹樷敶鈹€鈹樷敂鈹€鈹 鈹斺敇 鈹 鈹粹敇鈹斺敇 鈹     鈹€鈹
  205.   // If a callback function was not specified, then build a new `Deferred` and bail now.
  206.   //
  207.   // > This method will be called AGAIN automatically when the Deferred is executed.
  208.   // > and next time, it'll have a callback.
  209.   if (!done) {
  210.     return new Deferred(WLModel, stream, query);
  211.   }//--鈥
  212.  
  213.  
  214.  
  215.   // Otherwise, IWMIH, we know that a callback was specified.
  216.   // So...
  217.   //
  218.   //  鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈺  鈻堚枅鈺椻枅鈻堚枅鈻堚枅鈻堚枅鈺 鈻堚枅鈻堚枅鈻堚枅鈺椻枅鈻堚晽   鈻堚枅鈺椻枅鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈻堚枅鈻堚枅鈻堚晽
  219.   //  鈻堚枅鈺斺晲鈺愨晲鈺愨暆鈺氣枅鈻堚晽鈻堚枅鈺斺暆鈻堚枅鈺斺晲鈺愨晲鈺愨暆鈻堚枅鈺斺晲鈺愨晲鈺愨暆鈻堚枅鈺   鈻堚枅鈺戔暁鈺愨晲鈻堚枅鈺斺晲鈺愨暆鈻堚枅鈺斺晲鈺愨晲鈺愨暆
  220.   //  鈻堚枅鈻堚枅鈻堚晽   鈺氣枅鈻堚枅鈺斺暆 鈻堚枅鈻堚枅鈻堚晽  鈻堚枅鈺     鈻堚枅鈺   鈻堚枅鈺   鈻堚枅鈺   鈻堚枅鈻堚枅鈻堚晽
  221.   //  鈻堚枅鈺斺晲鈺愨暆   鈻堚枅鈺斺枅鈻堚晽 鈻堚枅鈺斺晲鈺愨暆  鈻堚枅鈺     鈻堚枅鈺   鈻堚枅鈺   鈻堚枅鈺   鈻堚枅鈺斺晲鈺愨暆
  222.   //  鈻堚枅鈻堚枅鈻堚枅鈻堚晽鈻堚枅鈺斺暆 鈻堚枅鈺椻枅鈻堚枅鈻堚枅鈻堚枅鈺椻暁鈻堚枅鈻堚枅鈻堚枅鈺椻暁鈻堚枅鈻堚枅鈻堚枅鈺斺暆   鈻堚枅鈺   鈻堚枅鈻堚枅鈻堚枅鈻堚晽
  223.   //  鈺氣晲鈺愨晲鈺愨晲鈺愨暆鈺氣晲鈺  鈺氣晲鈺濃暁鈺愨晲鈺愨晲鈺愨晲鈺 鈺氣晲鈺愨晲鈺愨晲鈺 鈺氣晲鈺愨晲鈺愨晲鈺    鈺氣晲鈺   鈺氣晲鈺愨晲鈺愨晲鈺愨暆
  224.  
  225.  
  226.   //  鈺斺晲鈺椻晹鈺愨晽鈺︹晲鈺椻晹鈺愨晽鈺斺晲鈺  鈹屸攢鈹愨攲鈹攼鈹屸攢鈹愨攲鈹€鈹愨攲鈹€鈹  鈹屸敩鈹愨敩 鈹攲鈹€鈹  鈹屸攢鈹 鈹 鈹攲鈹€鈹愨敩鈹€鈹愨敩 鈹
  227.   //  鈺犫暎 鈺 鈺戔暊鈺︹暆鈺 鈺︹晳鈺   鈹斺攢鈹 鈹 鈹溾攢鈹も攤 鈹敎鈹    鈹 鈹傗攤鈹傗攤 鈹  鈹傗攢鈹尖攼鈹 鈹傗敎鈹 鈹溾敩鈹樷敂鈹敇
  228.   //  鈺  鈺氣晲鈺濃暕鈺氣晲鈺氣晲鈺濃暁鈺愨暆  鈹斺攢鈹 鈹 鈹 鈹粹敂鈹€鈹樷敂鈹€鈹   鈹 鈹斺敶鈹樷敂鈹€鈹  鈹斺攢鈹樷敂鈹斺攢鈹樷敂鈹€鈹樷敶鈹斺攢 鈹
  229.   //
  230.   // Forge a stage 2 query (aka logical protostatement)
  231.   try {
  232.     forgeStageTwoQuery(query, orm);
  233.   } catch (e) {
  234.     switch (e.code) {
  235.  
  236.       case 'E_INVALID_STREAM_ITERATEE':
  237.         return done(
  238.           flaverr(
  239.             { name: 'UsageError' },
  240.             new Error(
  241.               'Invalid iteratee function passed in to `.stream()` via `.eachRecord()` or `.eachBatch()`.\n'+
  242.               'Details:\n' +
  243.               '  ' + e.details + '\n'
  244.             )
  245.           )
  246.         );
  247.  
  248.       case 'E_INVALID_CRITERIA':
  249.       case 'E_INVALID_POPULATES':
  250.       case 'E_INVALID_META':
  251.         return done(e);
  252.         // ^ when the standard usage error is good enough as-is, without any further customization
  253.  
  254.       case 'E_NOOP':
  255.         return done();
  256.  
  257.       default:
  258.         return done(e);
  259.         // ^ when an internal, miscellaneous, or unexpected error occurs
  260.  
  261.     }
  262.   } //>-鈥
  263.  
  264.  
  265.  
  266.   //  鈹屸攼鈹屸攲鈹€鈹愨敩 鈹  鈺斺晲鈺椻晹鈺愨晽鈺斺暒鈺椻暒 鈺︹晹鈺愨晽鈺  鈺 鈺 鈺  鈹屸敩鈹愨攲鈹€鈹愨敩  鈹攲鈹€  鈹屸敩鈹愨攲鈹€鈹  鈹屸敩鈹愨敩 鈹攲鈹€鈹  鈹屸敩鈹愨攲鈹 鈹屸攢鈹
  267.   //  鈹傗攤鈹傗攤 鈹傗攤鈹傗攤  鈺犫晲鈺b晳   鈺 鈺 鈺戔暊鈺愨暎鈺  鈺 鈺氣暒鈺   鈹 鈹溾攢鈹も攤  鈹溾敶鈹   鈹 鈹 鈹   鈹 鈹溾攢鈹も敎鈹    鈹傗攤鈹溾敶鈹愨敂鈹€鈹
  268.   //  鈹樷敂鈹樷敂鈹€鈹樷敂鈹粹敇  鈺 鈺┾暁鈺愨暆 鈺 鈺氣晲鈺濃暕 鈺┾暕鈺愨暆鈺┾晲鈺濃暕    鈹 鈹 鈹粹敶鈹€鈹樷敶 鈹   鈹 鈹斺攢鈹   鈹 鈹 鈹粹敂鈹€鈹  鈹€鈹粹敇鈹斺攢鈹樷敂鈹€鈹
  269.   //
  270.   // When running a `.stream()`, Waterline grabs pages (batches) of like 30 records at a time.
  271.   // This is not currently configurable.
  272.   //
  273.   // > If you have a use case for changing this page size (batch size) dynamically, please
  274.   // > create an issue with a detailed explanation.  Wouldn't be hard to add, we just
  275.   // > haven't run across a need to change it yet.
  276.   var BATCH_SIZE = 30;
  277.  
  278.   // A flag that will be set to true after we've reached the VERY last batch.
  279.   var reachedLastBatch;
  280.  
  281.   // The index of the current batch.
  282.   var i = 0;
  283.  
  284.  
  285.   async.whilst(function _checkHasntReachedLastBatchYet(){
  286.     if (!reachedLastBatch) { return true; }
  287.     else { return false; }
  288.   },// ~鈭?掳
  289.   function _beginBatchMaybe(next) {
  290.  
  291.     // 0   => 15
  292.     // 15  => 15
  293.     // 30  => 15
  294.     // 45  => 5
  295.     // 50
  296.     var numRecordsLeftUntilAbsLimit = query.criteria.limit - ( i*BATCH_SIZE );
  297.     var limitForThisBatch = Math.min(numRecordsLeftUntilAbsLimit, BATCH_SIZE);
  298.     var skipForThisBatch = query.criteria.skip +  ( i*BATCH_SIZE );
  299.     //                     |_initial offset    +  |_relative offset from end of previous batch
  300.  
  301.  
  302.     // If we've exceeded the absolute limit, then we go ahead and stop.
  303.     if (limitForThisBatch <= 0) {
  304.       reachedLastBatch = true;
  305.       return next();
  306.     }//-鈥
  307.  
  308.     // Build the criteria + deferred object to do a `.find()` for this batch.
  309.     var criteriaForThisBatch = {
  310.       skip: skipForThisBatch,
  311.       limit: limitForThisBatch,
  312.       sort: query.criteria.sort,
  313.       select: query.criteria.select,
  314.       omit: query.criteria.omit,
  315.       where: query.criteria.where
  316.     };
  317.     // console.log('---iterating---');
  318.     // console.log('i:',i);
  319.     // console.log('   BATCH_SIZE:',BATCH_SIZE);
  320.     // console.log('   query.criteria.limit:',query.criteria.limit);
  321.     // console.log('   query.criteria.skip:',query.criteria.skip);
  322.     // console.log('   query.criteria.sort:',query.criteria.sort);
  323.     // console.log('   query.criteria.where:',query.criteria.where);
  324.     // console.log('   query.criteria.select:',query.criteria.select);
  325.     // console.log('   query.criteria.omit:',query.criteria.omit);
  326.     // console.log('   --');
  327.     // console.log('   criteriaForThisBatch.limit:',criteriaForThisBatch.limit);
  328.     // console.log('   criteriaForThisBatch.skip:',criteriaForThisBatch.skip);
  329.     // console.log('   criteriaForThisBatch.sort:',criteriaForThisBatch.sort);
  330.     // console.log('   criteriaForThisBatch.where:',criteriaForThisBatch.where);
  331.     // console.log('   criteriaForThisBatch.select:',criteriaForThisBatch.select);
  332.     // console.log('   criteriaForThisBatch.omit:',criteriaForThisBatch.omit);
  333.     // console.log('---鈥⑩€⑩€⑩€⑩€⑩€⑩€⑩€⑩€?--');
  334.     var deferredForThisBatch = WLModel.find(criteriaForThisBatch);
  335.  
  336.     _.each(query.populates, function (assocCriteria, assocName){
  337.       deferredForThisBatch = deferredForThisBatch.populate(assocName, assocCriteria);
  338.     });
  339.  
  340.     // Pass through `meta` so we're sure to use the same db connection
  341.     // and settings (i.e. esp. relevant if we happen to be inside a transaction)
  342.     deferredForThisBatch.meta(query.meta);
  343.  
  344.     deferredForThisBatch.exec(function (err, batchOfRecords){
  345.       if (err) { return next(err); }
  346.  
  347.       // If there were no records returned, then we have already reached the last batch of results.
  348.       // (i.e. it was the previous batch-- since this batch was empty)
  349.       // In this case, we'll set the `reachedLastBatch` flag and trigger our callback,
  350.       // allowing `async.whilst()` to call _its_ callback, which will pass control back
  351.       // to userland.
  352.       if (batchOfRecords.length === 0) {
  353.         reachedLastBatch = true;
  354.         return next();
  355.       }// --鈥
  356.  
  357.       // But otherwise, we need to go ahead and call the appropriate
  358.       // iteratee for this batch.  If it's eachBatchFn, we'll call it
  359.       // once.  If it's eachRecordFn, we'll call it once per record.
  360.       (function _makeCallOrCallsToAppropriateIteratee(proceed){
  361.  
  362.         // If an `eachBatchFn` iteratee was provided, we'll call it.
  363.         // > At this point we already know it's a function, because
  364.         // > we validated usage at the very beginning.
  365.         if (query.eachBatchFn) {
  366.  
  367.           // Note that, if you try to call next() more than once in the iteratee, Waterline
  368.           // logs a warning explaining what's up, ignoring all subsequent calls to next()
  369.           // that occur after the first.
  370.           var didIterateeAlreadyHalt;
  371.           try {
  372.             query.eachBatchFn(batchOfRecords, function (err) {
  373.               if (err) { return proceed(err); }
  374.  
  375.               if (didIterateeAlreadyHalt) {
  376.                 console.warn(
  377.                   'Warning: The per-batch iteratee provided to `.stream()` triggered its callback \n'+
  378.                   'again-- after already triggering it once!  Please carefully check your iteratee\'s \n'+
  379.                   'code to figure out why this is happening.  (Ignoring this subsequent invocation...)'
  380.                 );
  381.                 return;
  382.               }//-鈥
  383.  
  384.               didIterateeAlreadyHalt = true;
  385.  
  386.               return proceed();
  387.             });//</ invoked per-batch iteratee >
  388.           } catch (e) { return proceed(e); }//>-鈥
  389.  
  390.           return;
  391.         }//_鈭廮.
  392.  
  393.  
  394.         // Otherwise `eachRecordFn` iteratee must have been provided.
  395.         // We'll call it once per record in this batch.
  396.         // > We validated usage at the very beginning, so we know that
  397.         // > one or the other iteratee must have been provided as a
  398.         // > valid function if we made it here.
  399.         async.eachSeries(batchOfRecords, function _eachRecordInBatch(record, next) {
  400.           // Note that, if you try to call next() more than once in the iteratee, Waterline
  401.           // logs a warning explaining what's up, ignoring all subsequent calls to next()
  402.           // that occur after the first.
  403.           var didIterateeAlreadyHalt;
  404.           try {
  405.             query.eachRecordFn(batchOfRecords, function (err) {
  406.               if (err) { return next(err); }
  407.  
  408.               if (didIterateeAlreadyHalt) {
  409.                 console.warn(
  410.                   'Warning: The per-record iteratee provided to `.stream()` triggered its callback\n'+
  411.                   'again-- after already triggering it once!  Please carefully check your iteratee\'s\n'+
  412.                   'code to figure out why this is happening.  (Ignoring this subsequent invocation...)'
  413.                 );
  414.                 return;
  415.               }//-鈥
  416.  
  417.               didIterateeAlreadyHalt = true;
  418.  
  419.               return next();
  420.  
  421.             });//</ invoked per-record iteratee >
  422.           } catch (e) { return next(e); }
  423.  
  424.         },// ~鈭?掳
  425.         function _afterIteratingOverRecordsInBatch(err) {
  426.           if (err) { return proceed(err); }
  427.  
  428.           return proceed();
  429.  
  430.         });//</async.eachSeries()>
  431.  
  432.       })(function _afterCallingIteratee(err){
  433.         if (err) {
  434.  
  435.           // Since this `err` might have come from the userland iteratee,
  436.           // we can't completely trust it.  So check it out, and if it's
  437.           // not one already, convert `err` into Error instance.
  438.           if (!_.isError(err)) {
  439.             if (_.isString(err)) {
  440.               err = new Error(err);
  441.             }
  442.             else {
  443.               err = new Error(util.inspect(err, {depth:5}));
  444.             }
  445.           }//>-
  446.  
  447.           return next(err);
  448.         }//--鈥
  449.  
  450.         // Increment the batch counter.
  451.         i++;
  452.  
  453.         // On to the next batch!
  454.         return next();
  455.  
  456.       });//</self-calling function :: process this batch by making either one call or multiple calls to the appropriate iteratee>
  457.  
  458.     });//</deferredForThisBatch.exec()>
  459.  
  460.   },// ~鈭?掳
  461.   function _afterAsyncWhilst(err) {
  462.     if (err) { return done(err); }//-鈥
  463.  
  464.     // console.log('finished `.whilst()` successfully');
  465.     return done();
  466.  
  467.   });//</async.whilst()>
  468.  
  469. };
  470.  
  471.  
  472.  
  473.  
  474. /**
  475.  * ad hoc demonstration...
  476.  */
  477.  
  478. /*```
  479. theOrm = { collections: { user: { attributes: { id: { type: 'string', required: true, unique: true }, age: { type: 'number', required: false }, foo: { type: 'string', required: true }, pets: { collection: 'pet' } }, primaryKey: 'id', hasSchema: false}, pet: { attributes: { id: { type:'number', required: true, unique: true } }, primaryKey: 'id', hasSchema: false } } };
  480. // ^^ except use a real ORM instance
  481. testStream = require('./lib/waterline/methods/stream');
  482. testStream = require('@sailshq/lodash').bind(testStream, { waterline: theOrm, identity: 'user' });
  483. testStream({}, function (record, next){  return next();  }, console.log)
  484. ```*/
  485.  
  486.  
downloadstream.js Source code - Download waterline Source code
Related Source Codes/Software:
notepad-plus-plus - Notepad++ official repository h... 2017-01-10
che - Eclipse Che: Next-generation Eclipse IDE. Open sou... 2017-01-10
Gource - oftware version control visualization ... 2017-01-10
FDFullscreenPopGesture - A UINavigationController's category to enable full... 2017-01-10
node-style-guide - A guide for styling your node.js / JavaScript code... 2017-01-09
Workerman - An asynchronous event driven PHP framework for eas... 2017-01-10
structor - An advanced visual editor for React components ... 2017-01-10
golearn - Machine Learning for Go 2017-01-10
poisontap - Exploits locked/password protected computers over ... 2017-01-10
kcptun - A Simple UDP Tunnel Based On KCP 2017-01-11
discover-flask - Full Stack Web Development with Flask. ... 2017-01-12
spring-mvc-showcase - Demonstrates the features of the Spring MVC web fr... 2017-01-12
tushare - TuShare is a utility for crawling historical data ... 2017-01-12
raml-spec - RAML Specification http://raml.... 2017-01-12
android-stackblur - Android StackBlur is a library that can perform a ... 2017-01-12
sound-redux - A Soundcloud client built with React / Redux ... 2017-01-12
httpstat - curl statistics made simple 2017-01-12
vim - Vim configuration file and plug-ins 2017-01-12
appframework - The definitive HTML5 mobile javascript framework ... 2017-01-12
BaiduExporter - Assistant for Baidu to export download links to ar... 2017-01-11

 Back to top