Comparing version 0.6.4 to 0.6.5
@@ -7,4 +7,2 @@ 'use strict'; | ||
var _PIPELINE_PROCESSORS; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
@@ -15,8 +13,4 @@ | ||
}); | ||
exports.Cursor = exports.PIPELINE_PROCESSORS = exports.PIPELINE_TYPE = undefined; | ||
exports.Cursor = exports.PIPELINE_PROCESSORS = undefined; | ||
var _bind2 = require('fast.js/function/bind'); | ||
var _bind3 = _interopRequireDefault(_bind2); | ||
var _forEach = require('fast.js/forEach'); | ||
@@ -26,10 +20,2 @@ | ||
var _filter2 = require('fast.js/array/filter'); | ||
var _filter3 = _interopRequireDefault(_filter2); | ||
var _reduce2 = require('fast.js/array/reduce'); | ||
var _reduce3 = _interopRequireDefault(_reduce2); | ||
var _assign2 = require('fast.js/object/assign'); | ||
@@ -47,6 +33,2 @@ | ||
var _checkTypes = require('check-types'); | ||
var _checkTypes2 = _interopRequireDefault(_checkTypes); | ||
var _AsyncEventEmitter2 = require('./AsyncEventEmitter'); | ||
@@ -60,4 +42,2 @@ | ||
var _Document = require('./Document'); | ||
var _DocumentRetriver = require('./DocumentRetriver'); | ||
@@ -91,146 +71,26 @@ | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
// UUID counter for all cursors | ||
var _currentCursorId = 0; | ||
// Maker used for stopping pipeline processing | ||
var PIPLEINE_STOP_MARKER = {}; | ||
// Pipeline processors map | ||
var PIPELINE_PROCESSORS = exports.PIPELINE_PROCESSORS = _extends({}, require('./cursor-processors/filter'), require('./cursor-processors/sortFunc'), require('./cursor-processors/map'), require('./cursor-processors/aggregate'), require('./cursor-processors/reduce'), require('./cursor-processors/join'), require('./cursor-processors/joinEach'), require('./cursor-processors/joinAll'), require('./cursor-processors/joinObj'), require('./cursor-processors/ifNotEmpty')); | ||
// Pipeline processors definition | ||
var PIPELINE_TYPE = exports.PIPELINE_TYPE = { | ||
Filter: 'Filter', | ||
Sort: 'Sort', | ||
Map: 'Map', | ||
Aggregate: 'Aggregate', | ||
Reduce: 'Reduce', | ||
Join: 'Join', | ||
JoinEach: 'JoinEach', | ||
JoinAll: 'JoinAll', | ||
JoinObj: 'JoinObj', | ||
IfNotEmpty: 'IfNotEmpty' | ||
}; | ||
// Create basic cursor with pipeline methods | ||
var PIPELINE_PROCESSORS = exports.PIPELINE_PROCESSORS = (_PIPELINE_PROCESSORS = {}, _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.Filter, function (docs, pipeObj) { | ||
return (0, _filter3.default)(docs, pipeObj.value); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.Sort, function (docs, pipeObj) { | ||
return docs.sort(pipeObj.value); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.Map, function (docs, pipeObj) { | ||
return (0, _map3.default)(docs, pipeObj.value); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.Aggregate, function (docs, pipeObj) { | ||
return pipeObj.value(docs); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.Reduce, function (docs, pipeObj) { | ||
return (0, _reduce3.default)(docs, pipeObj.value, pipeObj.args[0]); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.Join, function (docs, pipeObj, cursor) { | ||
if (_checkTypes2.default.object(pipeObj.value)) { | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinObj](docs, pipeObj, cursor); | ||
} else if (_checkTypes2.default.array(docs)) { | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinEach](docs, pipeObj, cursor); | ||
} else { | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinAll](docs, pipeObj, cursor); | ||
} | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.JoinEach, function (docs, pipeObj, cursor) { | ||
docs = _checkTypes2.default.array(docs) ? docs : [docs]; | ||
var docsLength = docs.length; | ||
return Promise.all((0, _map3.default)(docs, function (x, i) { | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinAll](x, pipeObj, cursor, i, docsLength); | ||
})); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.JoinAll, function (docs, pipeObj, cursor) { | ||
var i = arguments.length <= 3 || arguments[3] === undefined ? 0 : arguments[3]; | ||
var len = arguments.length <= 4 || arguments[4] === undefined ? 1 : arguments[4]; | ||
var BasicCursor = function (_AsyncEventEmitter) { | ||
_inherits(BasicCursor, _AsyncEventEmitter); | ||
var updatedFn = cursor._propagateUpdate ? (0, _bind3.default)(cursor._propagateUpdate, cursor) : function () {}; | ||
function BasicCursor() { | ||
_classCallCheck(this, BasicCursor); | ||
var res = pipeObj.value(docs, updatedFn, i, len); | ||
res = _checkTypes2.default.array(res) ? res : [res]; | ||
res = (0, _map3.default)(res, function (val) { | ||
var cursorPromise = undefined; | ||
if (val instanceof Cursor) { | ||
cursorPromise = val.exec(); | ||
} else if (_checkTypes2.default.object(val) && val.cursor && val.then) { | ||
cursorPromise = val; | ||
} | ||
if (cursorPromise) { | ||
cursor._trackChildCursorPromise(cursorPromise); | ||
} | ||
return cursorPromise || val; | ||
}); | ||
return _possibleConstructorReturn(this, Object.getPrototypeOf(BasicCursor).apply(this, arguments)); | ||
} | ||
return Promise.all(res).then(function () { | ||
return docs; | ||
}); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.JoinObj, function (docs, pipeObj, cursor) { | ||
var joinObj = pipeObj.value; | ||
var options = pipeObj.args[0] || {}; | ||
var isObj = !_checkTypes2.default.array(docs); | ||
docs = !isObj ? docs : [docs]; | ||
return BasicCursor; | ||
}(_AsyncEventEmitter3.default); | ||
var joinerFn = function joinerFn(dcs) { | ||
return (0, _map3.default)((0, _keys3.default)(joinObj), function (k) { | ||
var joinKey = k.split('.')[0]; | ||
var model = joinObj[k]; | ||
var lookupFn = (0, _DocumentMatcher.makeLookupFunction)(k); | ||
var childToRootMap = {}; | ||
var docsById = {}; | ||
var allIds = []; | ||
(0, _forEach2.default)(PIPELINE_PROCESSORS, function (v, procName) { | ||
BasicCursor.prototype[procName] = v.method; | ||
}); | ||
(0, _forEach2.default)(dcs, function (d) { | ||
docsById[d._id] = { d: d, isArray: false }; | ||
var val = lookupFn(d); | ||
var singleJoin = !val[0] || !val[0].arrayIndices; | ||
var joinIds = (0, _filter3.default)((0, _reduce3.default)((0, _map3.default)(val, function (x) { | ||
return x.value; | ||
}), function (a, b) { | ||
if (_checkTypes2.default.array(b)) { | ||
singleJoin = false; | ||
return [].concat(_toConsumableArray(a), _toConsumableArray(b)); | ||
} else { | ||
return [].concat(_toConsumableArray(a), [b]); | ||
} | ||
}, []), function (x) { | ||
return (0, _Document.selectorIsId)(x); | ||
}); | ||
allIds = allIds.concat(joinIds); | ||
docsById[d._id].isArray = !singleJoin; | ||
d[joinKey] = singleJoin ? null : []; | ||
(0, _forEach2.default)(joinIds, function (joinId) { | ||
var localIdsMap = childToRootMap[joinId] || []; | ||
localIdsMap.push(d._id); | ||
childToRootMap[joinId] = localIdsMap; | ||
}); | ||
}); | ||
var execFnName = options.observe ? 'observe' : 'then'; | ||
return model.find({ _id: { $in: allIds } })[execFnName](function (res) { | ||
(0, _forEach2.default)(res, function (objToJoin) { | ||
var docIdsForJoin = childToRootMap[objToJoin._id]; | ||
(0, _forEach2.default)(docIdsForJoin, function (docId) { | ||
var doc = docsById[docId]; | ||
if (doc) { | ||
if (doc.isArray) { | ||
doc.d[joinKey].push(objToJoin); | ||
} else { | ||
doc.d[joinKey] = objToJoin; | ||
} | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
}; | ||
var newPipeObj = _extends({}, pipeObj, { value: joinerFn }); | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinAll](docs, newPipeObj, cursor).then(function (res) { | ||
return isObj ? res[0] : res; | ||
}); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.IfNotEmpty, function (docs) { | ||
var isEmptyRes = !_checkTypes2.default.assigned(docs) || _checkTypes2.default.array(docs) && _checkTypes2.default.emptyArray(docs) || _checkTypes2.default.object(docs) && _checkTypes2.default.emptyObject(docs); | ||
return isEmptyRes ? PIPLEINE_STOP_MARKER : docs; | ||
}), _PIPELINE_PROCESSORS); | ||
/** | ||
@@ -243,4 +103,4 @@ * Class for storing information about query | ||
var Cursor = function (_AsyncEventEmitter) { | ||
_inherits(Cursor, _AsyncEventEmitter); | ||
var Cursor = function (_BasicCursor) { | ||
_inherits(Cursor, _BasicCursor); | ||
@@ -253,14 +113,14 @@ function Cursor(db) { | ||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Cursor).call(this)); | ||
var _this2 = _possibleConstructorReturn(this, Object.getPrototypeOf(Cursor).call(this)); | ||
_this.db = db; | ||
_this.options = options; | ||
_this._id = _currentCursorId++; | ||
_this._query = query; | ||
_this._pipeline = []; | ||
_this._latestResult = null; | ||
_this._childrenCursors = {}; | ||
_this._parentCursors = {}; | ||
_this._ensureMatcherSorter(); | ||
return _this; | ||
_this2.db = db; | ||
_this2.options = options; | ||
_this2._id = _currentCursorId++; | ||
_this2._query = query; | ||
_this2._pipeline = []; | ||
_this2._latestResult = null; | ||
_this2._childrenCursors = {}; | ||
_this2._parentCursors = {}; | ||
_this2._ensureMatcherSorter(); | ||
return _this2; | ||
} | ||
@@ -311,91 +171,9 @@ | ||
}, { | ||
key: 'sortFunc', | ||
value: function sortFunc(sortFn) { | ||
(0, _invariant2.default)(typeof sortFn === 'function', 'sortFunc(...): argument must be a function'); | ||
this._addPipeline(PIPELINE_TYPE.Sort, sortFn); | ||
return this; | ||
} | ||
}, { | ||
key: 'filter', | ||
value: function filter(filterFn) { | ||
(0, _invariant2.default)(typeof filterFn === 'function', 'filter(...): argument must be a function'); | ||
this._addPipeline(PIPELINE_TYPE.Filter, filterFn); | ||
return this; | ||
} | ||
}, { | ||
key: 'map', | ||
value: function map(mapperFn) { | ||
(0, _invariant2.default)(typeof mapperFn === 'function', 'map(...): mapper must be a function'); | ||
this._addPipeline(PIPELINE_TYPE.Map, mapperFn); | ||
return this; | ||
} | ||
}, { | ||
key: 'reduce', | ||
value: function reduce(reduceFn, initial) { | ||
(0, _invariant2.default)(typeof reduceFn === 'function', 'reduce(...): reducer argument must be a function'); | ||
this._addPipeline(PIPELINE_TYPE.Reduce, reduceFn, initial); | ||
return this; | ||
} | ||
}, { | ||
key: 'aggregate', | ||
value: function aggregate(aggrFn) { | ||
(0, _invariant2.default)(typeof aggrFn === 'function', 'aggregate(...): aggregator must be a function'); | ||
this._addPipeline(PIPELINE_TYPE.Aggregate, aggrFn); | ||
return this; | ||
} | ||
}, { | ||
key: 'join', | ||
value: function join(joinFn) { | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
(0, _invariant2.default)(typeof joinFn === 'function' || _checkTypes2.default.object(joinFn), 'join(...): argument must be a function'); | ||
this._addPipeline(PIPELINE_TYPE.Join, joinFn, options); | ||
return this; | ||
} | ||
}, { | ||
key: 'joinEach', | ||
value: function joinEach(joinFn) { | ||
(0, _invariant2.default)(typeof joinFn === 'function', 'joinEach(...): argument must be a function'); | ||
this._addPipeline(PIPELINE_TYPE.JoinEach, joinFn); | ||
return this; | ||
} | ||
}, { | ||
key: 'joinAll', | ||
value: function joinAll(joinFn) { | ||
(0, _invariant2.default)(typeof joinFn === 'function', 'joinAll(...): argument must be a function'); | ||
this._addPipeline(PIPELINE_TYPE.JoinAll, joinFn); | ||
return this; | ||
} | ||
}, { | ||
key: 'joinObj', | ||
value: function joinObj(obj) { | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
(0, _invariant2.default)(_checkTypes2.default.object(obj), 'joinObj(...): argument must be an object'); | ||
this._addPipeline(PIPELINE_TYPE.JoinObj, obj, options); | ||
return this; | ||
} | ||
}, { | ||
key: 'ifNotEmpty', | ||
value: function ifNotEmpty() { | ||
this._addPipeline(PIPELINE_TYPE.IfNotEmpty); | ||
return this; | ||
} | ||
}, { | ||
key: 'exec', | ||
value: function exec() { | ||
var _this2 = this; | ||
var _this3 = this; | ||
this.emit('beforeExecute'); | ||
return this._createCursorPromise(this._doExecute().then(function (result) { | ||
_this2._latestResult = result; | ||
_this3._latestResult = result; | ||
return result; | ||
@@ -412,3 +190,3 @@ })); | ||
value: function _addPipeline(type, val) { | ||
(0, _invariant2.default)(type && PIPELINE_TYPE[type], 'Unknown pipeline processor type %s', type); | ||
(0, _invariant2.default)(type && PIPELINE_PROCESSORS[type], 'Unknown pipeline processor type %s', type); | ||
@@ -429,3 +207,3 @@ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
value: function _processPipeline(docs) { | ||
var _this3 = this; | ||
var _this4 = this; | ||
@@ -438,7 +216,7 @@ var i = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; | ||
} else { | ||
return Promise.resolve(PIPELINE_PROCESSORS[pipeObj.type](docs, pipeObj, this)).then(function (result) { | ||
if (result === PIPLEINE_STOP_MARKER) { | ||
return Promise.resolve(PIPELINE_PROCESSORS[pipeObj.type].process(docs, pipeObj, this)).then(function (result) { | ||
if (result === '___[STOP]___') { | ||
return result; | ||
} else { | ||
return _this3._processPipeline(result, i + 1); | ||
return _this4._processPipeline(result, i + 1); | ||
} | ||
@@ -451,10 +229,10 @@ }); | ||
value: function _doExecute() { | ||
var _this4 = this; | ||
var _this5 = this; | ||
return this._matchObjects().then(function (docs) { | ||
var clonned = undefined; | ||
if (_this4.options.noClone) { | ||
if (_this5.options.noClone) { | ||
clonned = docs; | ||
} else { | ||
if (!_this4._projector) { | ||
if (!_this5._projector) { | ||
clonned = (0, _map3.default)(docs, function (doc) { | ||
@@ -464,6 +242,6 @@ return _EJSON2.default.clone(doc); | ||
} else { | ||
clonned = _this4._projector.project(docs); | ||
clonned = _this5._projector.project(docs); | ||
} | ||
} | ||
return _this4._processPipeline(clonned); | ||
return _this5._processPipeline(clonned); | ||
}); | ||
@@ -474,14 +252,14 @@ } | ||
value: function _matchObjects() { | ||
var _this5 = this; | ||
var _this6 = this; | ||
return new _DocumentRetriver2.default(this.db).retriveForQeury(this._query).then(function (docs) { | ||
var results = []; | ||
var withFastLimit = _this5._limit && !_this5._skip && !_this5._sorter; | ||
var withFastLimit = _this6._limit && !_this6._skip && !_this6._sorter; | ||
(0, _forEach2.default)(docs, function (d) { | ||
var match = _this5._matcher.documentMatches(d); | ||
var match = _this6._matcher.documentMatches(d); | ||
if (match.result) { | ||
results.push(d); | ||
} | ||
if (withFastLimit && results.length === _this5._limit) { | ||
if (withFastLimit && results.length === _this6._limit) { | ||
return false; | ||
@@ -495,9 +273,9 @@ } | ||
if (_this5._sorter) { | ||
var comparator = _this5._sorter.getComparator(); | ||
if (_this6._sorter) { | ||
var comparator = _this6._sorter.getComparator(); | ||
results.sort(comparator); | ||
} | ||
var skip = _this5._skip || 0; | ||
var limit = _this5._limit || results.length; | ||
var skip = _this6._skip || 0; | ||
var limit = _this6._limit || results.length; | ||
return results.slice(skip, limit + skip); | ||
@@ -519,3 +297,3 @@ }); | ||
value: function _trackChildCursorPromise(childCursorPromise) { | ||
var _this6 = this; | ||
var _this7 = this; | ||
@@ -527,4 +305,4 @@ var childCursor = childCursorPromise.cursor; | ||
this.once('beforeExecute', function () { | ||
delete _this6._childrenCursors[childCursor._id]; | ||
delete childCursor._parentCursors[_this6._id]; | ||
delete _this7._childrenCursors[childCursor._id]; | ||
delete childCursor._parentCursors[_this7._id]; | ||
if ((0, _keys3.default)(childCursor._parentCursors).length === 0) { | ||
@@ -538,3 +316,3 @@ childCursor.emit('beforeExecute'); | ||
value: function _createCursorPromise(promise) { | ||
var _this7 = this; | ||
var _this8 = this; | ||
@@ -546,3 +324,3 @@ var mixin = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
then: function then(successFn, failFn) { | ||
return _this7._createCursorPromise(promise.then(successFn, failFn), mixin); | ||
return _this8._createCursorPromise(promise.then(successFn, failFn), mixin); | ||
} | ||
@@ -554,5 +332,5 @@ }, mixin); | ||
return Cursor; | ||
}(_AsyncEventEmitter3.default); | ||
}(BasicCursor); | ||
exports.Cursor = Cursor; | ||
exports.default = Cursor; |
@@ -10,3 +10,3 @@ 'use strict'; | ||
}); | ||
exports.DocumentModifier = undefined; | ||
exports.findModTarget = exports.DocumentModifier = undefined; | ||
@@ -227,3 +227,3 @@ var _checkTypes = require('check-types'); | ||
// the path. | ||
var findModTarget = function findModTarget(doc, keyparts, options) { | ||
var findModTarget = exports.findModTarget = function findModTarget(doc, keyparts, options) { | ||
options = options || {}; | ||
@@ -230,0 +230,0 @@ var usedArrayIndex = false; |
@@ -1,14 +0,9 @@ | ||
import _bind from 'fast.js/function/bind'; | ||
import _each from 'fast.js/forEach'; | ||
import _filter from 'fast.js/array/filter'; | ||
import _reduce from 'fast.js/array/reduce'; | ||
import _assign from 'fast.js/object/assign'; | ||
import _keys from 'fast.js/object/keys'; | ||
import _map from 'fast.js/map'; | ||
import _check from 'check-types'; | ||
import AsyncEventEmitter from './AsyncEventEmitter'; | ||
import invariant from 'invariant'; | ||
import { selectorIsId } from './Document'; | ||
import DocumentRetriver from './DocumentRetriver'; | ||
import DocumentMatcher, { makeLookupFunction } from './DocumentMatcher'; | ||
import DocumentMatcher from './DocumentMatcher'; | ||
import DocumentSorter from './DocumentSorter'; | ||
@@ -22,146 +17,23 @@ import DocumentProjector from './DocumentProjector'; | ||
// Maker used for stopping pipeline processing | ||
const PIPLEINE_STOP_MARKER = {}; | ||
// Pipeline processors definition | ||
export const PIPELINE_TYPE = { | ||
Filter: 'Filter', | ||
Sort: 'Sort', | ||
Map: 'Map', | ||
Aggregate: 'Aggregate', | ||
Reduce: 'Reduce', | ||
Join: 'Join', | ||
JoinEach: 'JoinEach', | ||
JoinAll: 'JoinAll', | ||
JoinObj: 'JoinObj', | ||
IfNotEmpty: 'IfNotEmpty', | ||
// Pipeline processors map | ||
export const PIPELINE_PROCESSORS = { | ||
...require('./cursor-processors/filter'), | ||
...require('./cursor-processors/sortFunc'), | ||
...require('./cursor-processors/map'), | ||
...require('./cursor-processors/aggregate'), | ||
...require('./cursor-processors/reduce'), | ||
...require('./cursor-processors/join'), | ||
...require('./cursor-processors/joinEach'), | ||
...require('./cursor-processors/joinAll'), | ||
...require('./cursor-processors/joinObj'), | ||
...require('./cursor-processors/ifNotEmpty'), | ||
}; | ||
export const PIPELINE_PROCESSORS = { | ||
[PIPELINE_TYPE.Filter]: (docs, pipeObj) => { | ||
return _filter(docs, pipeObj.value); | ||
}, | ||
[PIPELINE_TYPE.Sort]: (docs, pipeObj) => { | ||
return docs.sort(pipeObj.value); | ||
}, | ||
[PIPELINE_TYPE.Map]: (docs, pipeObj) => { | ||
return _map(docs, pipeObj.value); | ||
}, | ||
[PIPELINE_TYPE.Aggregate]: (docs, pipeObj) => { | ||
return pipeObj.value(docs); | ||
}, | ||
[PIPELINE_TYPE.Reduce]: (docs, pipeObj) => { | ||
return _reduce(docs, pipeObj.value, pipeObj.args[0]); | ||
}, | ||
[PIPELINE_TYPE.Join]: (docs, pipeObj, cursor) => { | ||
if (_check.object(pipeObj.value)) { | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinObj](docs, pipeObj, cursor); | ||
} else if (_check.array(docs)) { | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinEach](docs, pipeObj, cursor); | ||
} else { | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinAll](docs, pipeObj, cursor); | ||
} | ||
}, | ||
[PIPELINE_TYPE.JoinEach]: (docs, pipeObj, cursor) => { | ||
docs = _check.array(docs) ? docs : [docs]; | ||
const docsLength = docs.length; | ||
return Promise.all(_map(docs, (x, i) => | ||
PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinAll](x, pipeObj, cursor, | ||
i, docsLength) | ||
)); | ||
}, | ||
[PIPELINE_TYPE.JoinAll]: (docs, pipeObj, cursor, i = 0, len = 1) => { | ||
const updatedFn = (cursor._propagateUpdate) | ||
? _bind(cursor._propagateUpdate, cursor) | ||
: function() {}; | ||
// Create basic cursor with pipeline methods | ||
class BasicCursor extends AsyncEventEmitter {} | ||
_each(PIPELINE_PROCESSORS, (v, procName) => { | ||
BasicCursor.prototype[procName] = v.method; | ||
}); | ||
let res = pipeObj.value(docs, updatedFn, i, len); | ||
res = _check.array(res) ? res : [res]; | ||
res =_map(res, val => { | ||
let cursorPromise; | ||
if (val instanceof Cursor) { | ||
cursorPromise = val.exec(); | ||
} else if (_check.object(val) && val.cursor && val.then) { | ||
cursorPromise = val; | ||
} | ||
if (cursorPromise) { | ||
cursor._trackChildCursorPromise(cursorPromise); | ||
} | ||
return cursorPromise || val; | ||
}); | ||
return Promise.all(res).then(() => docs); | ||
}, | ||
[PIPELINE_TYPE.JoinObj]: (docs, pipeObj, cursor) => { | ||
const joinObj = pipeObj.value; | ||
const options = pipeObj.args[0] || {}; | ||
const isObj = !_check.array(docs); | ||
docs = !isObj ? docs : [docs]; | ||
const joinerFn = (dcs) => _map(_keys(joinObj), k => { | ||
const joinKey = k.split('.')[0]; | ||
const model = joinObj[k]; | ||
const lookupFn = makeLookupFunction(k); | ||
const childToRootMap = {}; | ||
const docsById = {}; | ||
let allIds = []; | ||
_each(dcs, (d) => { | ||
docsById[d._id] = { d, isArray: false }; | ||
const val = lookupFn(d); | ||
let singleJoin = !val[0] || !val[0].arrayIndices; | ||
const joinIds = _filter(_reduce(_map(val, x => x.value), (a, b) => { | ||
if (_check.array(b)) { | ||
singleJoin = false; | ||
return [...a, ...b]; | ||
} else { | ||
return [...a, b]; | ||
} | ||
}, []), x => selectorIsId(x)); | ||
allIds = allIds.concat(joinIds); | ||
docsById[d._id].isArray = !singleJoin; | ||
d[joinKey] = singleJoin ? null : []; | ||
_each(joinIds, joinId => { | ||
const localIdsMap = childToRootMap[joinId] || []; | ||
localIdsMap.push(d._id); | ||
childToRootMap[joinId] = localIdsMap; | ||
}); | ||
}); | ||
const execFnName = options.observe ? 'observe' : 'then'; | ||
return model.find({_id: {$in: allIds}})[execFnName](res => { | ||
_each(res, objToJoin => { | ||
const docIdsForJoin = childToRootMap[objToJoin._id]; | ||
_each(docIdsForJoin, docId => { | ||
const doc = docsById[docId]; | ||
if (doc) { | ||
if (doc.isArray) { | ||
doc.d[joinKey].push(objToJoin); | ||
} else { | ||
doc.d[joinKey] = objToJoin; | ||
} | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
const newPipeObj = { ...pipeObj, value: joinerFn }; | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinAll](docs, newPipeObj, cursor) | ||
.then(res => isObj ? res[0] : res); | ||
}, | ||
[PIPELINE_TYPE.IfNotEmpty]: (docs) => { | ||
const isEmptyRes = ( | ||
!_check.assigned(docs) || | ||
(_check.array(docs) && _check.emptyArray(docs)) || | ||
(_check.object(docs) && _check.emptyObject(docs)) | ||
); | ||
return isEmptyRes ? PIPLEINE_STOP_MARKER : docs; | ||
}, | ||
}; | ||
/** | ||
@@ -173,3 +45,3 @@ * Class for storing information about query | ||
*/ | ||
export class Cursor extends AsyncEventEmitter { | ||
export class Cursor extends BasicCursor { | ||
constructor(db, query = {}, options = {}) { | ||
@@ -234,97 +106,2 @@ super(); | ||
sortFunc(sortFn) { | ||
invariant( | ||
typeof sortFn === 'function', | ||
'sortFunc(...): argument must be a function' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.Sort, sortFn); | ||
return this; | ||
} | ||
filter(filterFn) { | ||
invariant( | ||
typeof filterFn === 'function', | ||
'filter(...): argument must be a function' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.Filter, filterFn); | ||
return this; | ||
} | ||
map(mapperFn) { | ||
invariant( | ||
typeof mapperFn === 'function', | ||
'map(...): mapper must be a function' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.Map, mapperFn); | ||
return this; | ||
} | ||
reduce(reduceFn, initial) { | ||
invariant( | ||
typeof reduceFn === 'function', | ||
'reduce(...): reducer argument must be a function' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.Reduce, reduceFn, initial); | ||
return this; | ||
} | ||
aggregate(aggrFn) { | ||
invariant( | ||
typeof aggrFn === 'function', | ||
'aggregate(...): aggregator must be a function' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.Aggregate, aggrFn); | ||
return this; | ||
} | ||
join(joinFn, options = {}) { | ||
invariant( | ||
typeof joinFn === 'function' || _check.object(joinFn), | ||
'join(...): argument must be a function' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.Join, joinFn, options); | ||
return this; | ||
} | ||
joinEach(joinFn) { | ||
invariant( | ||
typeof joinFn === 'function', | ||
'joinEach(...): argument must be a function' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.JoinEach, joinFn); | ||
return this; | ||
} | ||
joinAll(joinFn) { | ||
invariant( | ||
typeof joinFn === 'function', | ||
'joinAll(...): argument must be a function' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.JoinAll, joinFn); | ||
return this; | ||
} | ||
joinObj(obj, options = {}) { | ||
invariant( | ||
_check.object(obj), | ||
'joinObj(...): argument must be an object' | ||
); | ||
this._addPipeline(PIPELINE_TYPE.JoinObj, obj, options); | ||
return this; | ||
} | ||
ifNotEmpty() { | ||
this._addPipeline(PIPELINE_TYPE.IfNotEmpty); | ||
return this; | ||
} | ||
exec() { | ||
@@ -346,3 +123,3 @@ this.emit('beforeExecute'); | ||
invariant( | ||
type && PIPELINE_TYPE[type], | ||
type && PIPELINE_PROCESSORS[type], | ||
'Unknown pipeline processor type %s', | ||
@@ -366,5 +143,7 @@ type | ||
return Promise.resolve( | ||
PIPELINE_PROCESSORS[pipeObj.type](docs, pipeObj, this) | ||
PIPELINE_PROCESSORS[pipeObj.type].process( | ||
docs, pipeObj, this | ||
) | ||
).then((result) => { | ||
if (result === PIPLEINE_STOP_MARKER) { | ||
if (result === '___[STOP]___') { | ||
return result; | ||
@@ -371,0 +150,0 @@ } else { |
@@ -175,3 +175,3 @@ import _check from 'check-types'; | ||
// the path. | ||
var findModTarget = function(doc, keyparts, options) { | ||
export const findModTarget = function(doc, keyparts, options) { | ||
options = options || {}; | ||
@@ -178,0 +178,0 @@ var usedArrayIndex = false; |
{ | ||
"name": "marsdb", | ||
"version": "0.6.4", | ||
"version": "0.6.5", | ||
"author": { | ||
@@ -5,0 +5,0 @@ "name": "Artem Artemev", |
@@ -459,4 +459,4 @@ import Collection from '../../lib/Collection'; | ||
res[5].j.should.have.length(2); | ||
res[5].j[0]._id.should.be.equal('5'); | ||
res[5].j[1]._id.should.be.equal('7'); | ||
res[5].j[0]._id.should.be.equal('7'); | ||
res[5].j[1]._id.should.be.equal('5'); | ||
expect(res[6].j).to.be.an('array'); | ||
@@ -478,10 +478,10 @@ }); | ||
sinon.spy(db, 'find'); | ||
return db.find().sort(['_id']).joinObj({'j._id': db}).then(res => { | ||
return db.find().sort(['_id']).joinObj({'j._id': {model: db, joinPath: 'j.$'}}).then(res => { | ||
db.find.should.be.calledTwice; | ||
expect(res[0].j).to.be.null; | ||
expect(res[1].j).to.be.null; | ||
expect(res[2].j).to.be.null; | ||
expect(res[3].j).to.be.null; | ||
expect(res[4].j).to.be.null; | ||
expect(res[5].j).to.be.null; | ||
expect(res[0].j).to.be.equal('2'); | ||
expect(res[1].j).to.be.equal('3'); | ||
expect(res[2].j).to.be.equal('4'); | ||
expect(res[3].j).to.be.equal('5'); | ||
expect(res[4].j).to.be.equal('6'); | ||
expect(res[5].j).to.be.deep.equal(['7', '5']); | ||
res[6].j.should.have.length(2); | ||
@@ -488,0 +488,0 @@ res[6].j[0]._id.should.be.equal('1'); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1012570
103
23327