Comparing version 0.2.2 to 0.2.3
@@ -1,1 +0,1 @@ | ||
(function(){"use strict";function normalize(expr){for(var i=0;i<primitives.length;i++)if(primitives[i](expr))return _.isRegExp(expr)?{$regex:expr}:{$eq:expr};if(_.isObject(expr)){var keys=_.keys(expr),notQuery=0===_.intersection(Ops.queryOperators,keys).length;if(notQuery)return{$eq:expr};if(_.contains(keys,"$regex")){var regex=expr.$regex,options=expr.$options||"",modifiers="";_.isString(regex)&&(modifiers+=regex.ignoreCase||options.indexOf("i")>=0?"i":"",modifiers+=regex.multiline||options.indexOf("m")>=0?"m":"",modifiers+=regex.global||options.indexOf("g")>=0?"g":"",regex=new RegExp(regex,modifiers)),expr.$regex=regex,delete expr.$options}}return expr}var previousMingo,_,root=this,Mingo={};null!=root&&(previousMingo=root.Mingo),Mingo.noConflict=function(){return root.Mingo=previousMingo,Mingo};var nodeEnabled="undefined"!=typeof exports&&"undefined"!=typeof module&&"undefined"!=typeof require&&"undefined"!=typeof process;"undefined"!=typeof exports?(exports="undefined"!=typeof module&&module.exports?module.exports=Mingo:Mingo,_=require("underscore")):(root.Mingo=Mingo,_=root._);var primitives=[_.isString,_.isBoolean,_.isNumber,_.isDate,_.isNull,_.isRegExp],settings={key:"_id"};if(Mingo.setup=function(options){_.extend(settings,options||{})},Mingo.Query=function(criteria,projection){return this instanceof Mingo.Query?(this._criteria=criteria,this._projection=projection,this._compiled=[],this._compile(),void 0):new Mingo.Query(criteria,projection)},Mingo.Query.prototype={_compile:function(){if(!_.isEmpty(this._criteria)){if(_.isArray(this._criteria)||_.isFunction(this._criteria)||!_.isObject(this._criteria))throw new Error("Invalid type for criteria");for(var field in this._criteria)if(this._criteria.hasOwnProperty(field)){var expr=this._criteria[field];if(_.contains(Ops.compoundOperators,field)){if(_.contains(["$not"],field))throw Error("Invalid operator");this._processOperator(field,field,expr)}else{expr=normalize(expr);for(var op in expr)expr.hasOwnProperty(op)&&this._processOperator(field,op,expr[op])}}}},_processOperator:function(field,operator,value){var compiledSelector;if(_.contains(Ops.simpleOperators,operator))compiledSelector={test:function(obj){var actualValue=Mingo._resolve(obj,field);return simpleOperators[operator](actualValue,value)}};else{if(!_.contains(Ops.compoundOperators,operator))throw Error("Invalid query operator '"+operator+"' detected");compiledSelector=compoundOperators[operator](field,value)}this._compiled.push(compiledSelector)},test:function(obj){for(var i=0;i<this._compiled.length;i++)if(!this._compiled[i].test(obj))return!1;return!0},find:function(collection,projection){return new Mingo.Cursor(collection,this,projection)},remove:function(collection){for(var arr=[],i=0;i<collection.length;i++)this.test(collection[i])||arr.push(collection[i]);return arr}},nodeEnabled){var Transform=require("stream").Transform,util=require("util");Mingo.Query.prototype.stream=function(options){return new Mingo.Stream(this,options)},Mingo.Stream=function(query,options){return this instanceof Mingo.Stream?(options=options||{},_.extend(options,{objectMode:!0}),Transform.call(this,options),this._query=query,void 0):new Mingo.Stream(query,options)},util.inherits(Mingo.Stream,Transform),Mingo.Stream.prototype._transform=function(chunk,encoding,done){if(_.isObject(chunk)&&this._query.test(chunk))if(_.isEmpty(this._query._projection))this.push(chunk);else{var cursor=new Mingo.Cursor([chunk],this._query);cursor.hasNext()&&this.push(cursor.next())}done()}}Mingo.Cursor=function(collection,query,projection){return this instanceof Mingo.Cursor?(this._query=query,this._collection=collection,this._projection=projection||query._projection,this._operators={},this._result=!1,this._position=0,void 0):new Mingo.Cursor(collection,query,projection)},Mingo.Cursor.prototype={_fetch:function(){var self=this;if(this._result!==!1)return this._result;if(_.isObject(this._projection)&&_.extend(this._operators,{$project:this._projection}),!_.isArray(this._collection))throw Error("Input collection is not of a valid type.");this._result=_.filter(this._collection,this._query.test,this._query);var pipeline=[];if(_.each(["$sort","$skip","$limit","$project"],function(op){_.has(self._operators,op)&&pipeline.push(_.pick(self._operators,op))}),pipeline.length>0){var aggregator=new Mingo.Aggregator(pipeline);this._result=aggregator.run(this._result,this._query)}return this._result},all:function(){return this._fetch()},first:function(){return this.count()>0?this._fetch()[0]:null},last:function(){return this.count()>0?this._fetch()[this.count()-1]:null},count:function(){return this._fetch().length},skip:function(n){return _.extend(this._operators,{$skip:n}),this},limit:function(n){return _.extend(this._operators,{$limit:n}),this},sort:function(modifier){return _.extend(this._operators,{$sort:modifier}),this},next:function(){return this.hasNext()?this._fetch()[this._position++]:null},hasNext:function(){return this.count()>this._position},max:function(expr){return groupOperators.$max(this._fetch(),expr)},min:function(expr){return groupOperators.$min(this._fetch(),expr)},map:function(callback){return _.map(this._fetch(),callback)},forEach:function(callback){_.each(this._fetch(),callback)}},Mingo.Aggregator=function(operators){return this instanceof Mingo.Aggregator?(this._operators=operators,void 0):new Mingo.Aggregator(operators)},Mingo.Aggregator.prototype={run:function(collection,query){if(!_.isEmpty(this._operators))for(var i=0;i<this._operators.length;i++){var operator=this._operators[i];for(var key in operator)operator.hasOwnProperty(key)&&(collection=query?pipelineOperators[key].call(query,collection,operator[key]):pipelineOperators[key](collection,operator[key]))}return collection}},Mingo._get=function(obj,field){return _.result(obj,field)},Mingo._resolve=function(obj,field){if(!field)return void 0;for(var isText,names=field.split("."),value=obj,i=0;i<names.length;i++){if(isText=null===names[i].match(/^\d+$/),isText&&_.isArray(value)){var res=[];_.each(value,function(item){_.isObject(item)&&res.push(Mingo._resolve(item,names[i]))}),value=res}else value=Mingo._get(value,names[i]);if(void 0===value)break}return value},Mingo.compile=function(criteria,projection){return new Mingo.Query(criteria,projection)},Mingo.find=function(collection,criteria,projection){return new Mingo.Query(criteria).find(collection,projection)},Mingo.remove=function(collection,criteria){return new Mingo.Query(criteria).remove(collection)},Mingo.aggregate=function(collection,pipeline){if(!_.isArray(pipeline))throw Error("Aggregation pipeline must be an array");return new Mingo.Aggregator(pipeline).run(collection)},Mingo.CollectionMixin={query:function(criteria,projection){return Mingo.find(this.toJSON(),criteria,projection)},aggregate:function(pipeline){var args=[this.toJSON(),pipeline];return Mingo.aggregate.apply(null,args)}};var pipelineOperators={$group:function(collection,expr){var idKey=expr[settings.key],indexes=[],groups=_.groupBy(collection,function(obj){var key=computeValue(obj,idKey,idKey);return indexes.push(key),key});indexes=_.uniq(indexes),expr=_.omit(expr,settings.key);var result=[];return _.each(indexes,function(index){var obj={};obj[settings.key]=index;for(var key in expr)expr.hasOwnProperty(key)&&(obj[key]=accumulate(groups[index],key,expr[key]));result.push(obj)}),result},$match:function(collection,expr){var query=new Mingo.Query(expr);return query.find(collection).all()},$project:function(collection,expr){if(_.isEmpty(expr))return collection;var projected=[],objKeys=_.keys(expr),removeId=!1;if(_.contains(objKeys,settings.key)){var id=objKeys[settings.key];removeId=0===id||id===!1}for(var i=0;i<collection.length;i++){var obj=collection[i],cloneObj={};_.each(objKeys,function(key){if(!removeId||key!==settings.key){var subExpr=expr[key];if(_.isString(subExpr))cloneObj[key]=computeValue(obj,subExpr,key);else if(1===subExpr||subExpr===!0)cloneObj[key]=_.result(obj,key);else if(_.isObject(subExpr)){var operator=_.keys(subExpr);if(operator=operator.length>1?!1:operator[0],operator!==!1&&_.contains(Ops.projectionOperators,operator)){var temp=projectionOperators[operator](obj,subExpr[operator],key);_.isUndefined(temp)||(cloneObj[key]=temp)}else cloneObj[key]=computeValue(obj,subExpr,key)}}}),removeId||_.has(cloneObj,settings.key)||(cloneObj[settings.key]=obj[settings.key]),projected.push(cloneObj)}return projected},$limit:function(collection,value){return _.first(collection,value)},$skip:function(collection,value){return _.rest(collection,value)},$unwind:function(collection,expr){for(var result=[],field=expr.substr(1),i=0;i<collection.length;i++){var obj=collection[i],value=Mingo._get(obj,field);if(!_.isArray(value))throw new Error("Target field '"+field+"' is not of type Array.");_.each(value,function(item){var tmp=_.clone(obj);tmp[field]=item,result.push(tmp)})}return result},$sort:function(collection,sortKeys){if(!_.isEmpty(sortKeys)&&_.isObject(sortKeys)){var modifiers=_.keys(sortKeys);modifiers.reverse().forEach(function(key){var indexes=[],grouped=_.groupBy(collection,function(obj){var value=Mingo._resolve(obj,key);return indexes.push(value),value});indexes=_.sortBy(_.uniq(indexes),function(item){return item}),-1===sortKeys[key]&&indexes.reverse(),collection=[],_.each(indexes,function(item){Array.prototype.push.apply(collection,grouped[item])})})}return collection}},compoundOperators={$and:function(selector,value){if(!_.isArray(value))throw new Error("Invalid expression for $and criteria");var queries=[];return _.each(value,function(expr){queries.push(new Mingo.Query(expr))}),{test:function(obj){for(var i=0;i<queries.length;i++)if(queries[i].test(obj)===!1)return!1;return!0}}},$or:function(selector,value){if(!_.isArray(value))throw new Error("Invalid expression for $or criteria");var queries=[];return _.each(value,function(expr){queries.push(new Mingo.Query(expr))}),{test:function(obj){for(var i=0;i<queries.length;i++)if(queries[i].test(obj))return!0;return!1}}},$nor:function(selector,value){if(!_.isArray(value))throw new Error("Invalid expression for $nor criteria");var query=this.$or("$or",value);return{test:function(obj){return!query.test(obj)}}},$not:function(selector,value){var criteria={};criteria[selector]=normalize(value);var query=new Mingo.Query(criteria);return{test:function(obj){return!query.test(obj)}}},$where:function(selector,value){return _.isFunction(value)||(value=new Function("return "+value+";")),{test:function(obj){return value.call(obj)===!0}}}},simpleOperators={$eq:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return _.isEqual(val,b)}),void 0!==a},$ne:function(a,b){return!this.$eq(a,b)},$in:function(a,b){return a=_.isArray(a)?a:[a],_.intersection(a,b).length>0},$nin:function(a,b){return _.isUndefined(a)||!this.$in(a,b)},$lt:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return b>val}),void 0!==a},$lte:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return b>=val}),void 0!==a},$gt:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return val>b}),void 0!==a},$gte:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return val>=b}),void 0!==a},$mod:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return _.isNumber(val)&&_.isArray(b)&&2===b.length&&val%b[0]===b[1]}),void 0!==a},$regex:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return _.isString(val)&&_.isRegExp(b)&&!!val.match(b)}),void 0!==a},$exists:function(a,b){return b===!1&&_.isUndefined(a)||b===!0&&!_.isUndefined(a)},$all:function(a,b){var self=this,matched=!1;if(_.isArray(a)&&_.isArray(b))for(var i=0;i<b.length;i++){if(!_.isObject(b[i])||!_.contains(_.keys(b[i]),"$elemMatch"))return _.intersection(b,a).length===b.length;matched=matched||self.$elemMatch(a,b[i].$elemMatch)}return matched},$size:function(a,b){return _.isArray(a)&&_.isNumber(b)&&a.length===b},$elemMatch:function(a,b){if(_.isArray(a)&&!_.isEmpty(a))for(var query=new Mingo.Query(b),i=0;i<a.length;i++)if(query.test(a[i]))return!0;return!1},$type:function(a,b){switch(b){case 1:return _.isNumeric(a)&&-1!==(a+"").indexOf(".");case 2:case 5:return _.isString(a);case 3:return _.isObject(a);case 4:return _.isArray(a);case 8:return _.isBoolean(a);case 9:return _.isDate(a);case 10:return _.isNull(a);case 11:return _.isRegExp(a);case 16:return _.isNumeric(a)&&2147483647>=a&&-1===(a+"").indexOf(".");case 18:return _.isNumeric(a)&&a>2147483647&&0x8000000000000000>=a&&-1===(a+"").indexOf(".");default:return!1}}},projectionOperators={$:function(){throw new Error("$ not implemented")},$elemMatch:function(obj,expr,field){var array=Mingo._resolve(obj,field),query=new Mingo.Query(expr);if(_.isUndefined(array)||!_.isArray(array))return void 0;for(var i=0;i<array.length;i++)if(query.test(array[i]))return array[i];return void 0},$slice:function(obj,expr,field){var array=Mingo._resolve(obj,field);return _.isUndefined(array)?void 0:(_.isArray(expr)||(expr=[expr]),Array.prototype.slice.apply(array,expr))}},groupOperators={$addToSet:function(collection,expr){var result=_.map(collection,function(obj){return computeValue(obj,expr)});return _.uniq(result)},$sum:function(collection,expr){return _.isNumber(expr)?collection.length*expr:_.reduce(collection,function(acc,obj){return acc+computeValue(obj,expr)},0)},$max:function(collection,expr){var obj=_.max(collection,function(obj){return computeValue(obj,expr)});return computeValue(obj,expr)},$min:function(collection,expr){var obj=_.min(collection,function(obj){return computeValue(obj,expr)});return computeValue(obj,expr)},$avg:function(collection,expr){return this.$sum(collection,expr)/collection.length},$push:function(collection,expr){return _.map(collection,function(obj){return computeValue(obj,expr)})},$first:function(collection,expr){return collection.length>0?computeValue(collection[0],expr):void 0},$last:function(collection,expr){return collection.length>0?computeValue(collection[collection.length-1],expr):void 0}},aggregateOperators={$add:function(obj,expr){var args=computeValue(obj,expr);return _.reduce(args,function(memo,num){return memo+num},0)},$subtract:function(obj,expr){var args=computeValue(obj,expr);return args[0]-args[1]},$divide:function(obj,expr){var args=computeValue(obj,expr);return args[0]/args[1]},$multiply:function(obj,expr){var args=computeValue(obj,expr);return _.reduce(args,function(memo,num){return memo*num},1)},$mod:function(obj,expr){var args=computeValue(obj,expr);return args[0]%args[1]},$cmp:function(obj,expr){var args=computeValue(obj,expr);return args[0]>args[1]?1:args[0]<args[1]?-1:0},$concat:function(obj,expr){var args=computeValue(obj,expr);return args.join("")},$strcasecmp:function(obj,expr){var args=computeValue(obj,expr);return args[0]=args[0].toUpperCase(),args[1]=args[1].toUpperCase(),args[0]>args[1]?1:args[0]<args[1]?-1:0},$substr:function(obj,expr){var args=computeValue(obj,expr);return _.isString(args[0])?args[0].substr(args[1],args[2]):void 0},$toLower:function(obj,expr){var value=computeValue(obj,expr);return value.toLowerCase()},$toUpper:function(obj,expr){var value=computeValue(obj,expr);return value.toUpperCase()}},setOperators={$setEquals:function(obj,expr){var args=computeValue(obj,expr);return 0===_.difference(args[0],args[1]).length},$setIntersection:function(obj,expr){var args=computeValue(obj,expr);return _.intersection(args[0],args[1])},$setDifference:function(obj,expr){var args=computeValue(obj,expr);return _.difference(args[0],args[1])},$setUnion:function(obj,expr){var args=computeValue(obj,expr);return _.union(args[0],args[1])},$setIsSubset:function(obj,expr){var args=computeValue(obj,expr);return _.intersection(args[0],args[1]).length===args[0].length},$anyElementTrue:function(obj,expr){for(var args=computeValue(obj,expr),i=0;i<args.length;i++)if(args[i])return!0;return!1},$allElementsTrue:function(obj,expr){for(var args=computeValue(obj,expr),i=0;i<args.length;i++)if(!args[i])return!1;return!0}},conditionalOperators={$cond:function(obj,expr){var ifExpr,thenExpr,elseExpr;if(_.isArray(expr)){if(3!=expr.length)throw Error("Invalid arguments for $cond operator");ifExpr=expr[0],thenExpr=expr[1],elseExpr=expr[2]}else _.isObject(expr)&&(ifExpr=expr["if"],thenExpr=expr.then,elseExpr=expr["else"]);var condition=computeValue(obj,ifExpr);return condition?computeValue(obj,thenExpr):computeValue(obj,elseExpr)},$ifNull:function(obj,expr){if(!_.isArray(expr)||2!=expr.length)throw Error("Invalid arguments for $ifNull operator");var args=computeValue(obj,expr);return null===args[0]||void 0===args[0]?args[1]:args[0]}};_.each(["$eq","$ne","$gt","$gte","$lt","$lte"],function(op){aggregateOperators[op]=function(obj,expr){var args=computeValue(obj,expr);return simpleOperators[op](args[0],args[1])}}),_.extend(aggregateOperators,setOperators,conditionalOperators);var Ops={simpleOperators:_.keys(simpleOperators),compoundOperators:_.keys(compoundOperators),setOperators:_.keys(setOperators),aggregateOperators:_.keys(aggregateOperators),groupOperators:_.keys(groupOperators),pipelineOperators:_.keys(pipelineOperators),projectionOperators:_.keys(projectionOperators)};Ops.queryOperators=_.union(Ops.simpleOperators,Ops.compoundOperators);var accumulate=function(collection,field,expr){if(_.contains(Ops.groupOperators,field))return groupOperators[field](collection,expr);if(_.isObject(expr)){var result={};for(var key in expr)if(expr.hasOwnProperty(key)&&(result[key]=accumulate(collection,key,expr[key]),_.contains(Ops.groupOperators,key))){if(result=result[key],_.keys(expr).length>1)throw new Error("Invalid $group expression '"+JSON.stringify(expr)+"'");break}return result}return void 0},computeValue=function(obj,expr,field){if(_.contains(Ops.aggregateOperators,field))return aggregateOperators[field](obj,expr);if(_.isString(expr)&&expr.length>0&&"$"===expr[0])return Mingo._resolve(obj,expr.slice(1));var result;if(_.isArray(expr)){result=[];for(var i=0;i<expr.length;i++)result.push(computeValue(obj,expr[i],null))}else if(_.isObject(expr)){result={};for(var key in expr)if(expr.hasOwnProperty(key)&&(result[key]=computeValue(obj,expr[key],key),_.contains(Ops.aggregateOperators,key))){if(result=result[key],_.keys(expr).length>1)throw new Error("Invalid aggregation expression '"+JSON.stringify(expr)+"'");break}}else for(var i=0;i<primitives.length;i++)if(primitives[i](expr))return expr;return result}}).call(this); | ||
(function(){"use strict";function normalize(expr){for(var i=0;i<primitives.length;i++)if(primitives[i](expr))return _.isRegExp(expr)?{$regex:expr}:{$eq:expr};if(_.isObject(expr)){var keys=_.keys(expr),notQuery=0===_.intersection(Ops.queryOperators,keys).length;if(notQuery)return{$eq:expr};if(_.contains(keys,"$regex")){var regex=expr.$regex,options=expr.$options||"",modifiers="";_.isString(regex)&&(modifiers+=regex.ignoreCase||options.indexOf("i")>=0?"i":"",modifiers+=regex.multiline||options.indexOf("m")>=0?"m":"",modifiers+=regex.global||options.indexOf("g")>=0?"g":"",regex=new RegExp(regex,modifiers)),expr.$regex=regex,delete expr.$options}}return expr}var previousMingo,_,root=this,Mingo={};null!=root&&(previousMingo=root.Mingo),Mingo.noConflict=function(){return root.Mingo=previousMingo,Mingo};var nodeEnabled="undefined"!=typeof exports&&"undefined"!=typeof module&&"undefined"!=typeof require&&"undefined"!=typeof process;"undefined"!=typeof exports?(exports="undefined"!=typeof module&&module.exports?module.exports=Mingo:Mingo,_=require("underscore")):(root.Mingo=Mingo,_=root._);var primitives=[_.isString,_.isBoolean,_.isNumber,_.isDate,_.isNull,_.isRegExp],settings={key:"_id"};if(Mingo.setup=function(options){_.extend(settings,options||{})},Mingo.Query=function(criteria,projection){return this instanceof Mingo.Query?(this._criteria=criteria,this._projection=projection,this._compiled=[],this._compile(),void 0):new Mingo.Query(criteria,projection)},Mingo.Query.prototype={_compile:function(){if(!_.isEmpty(this._criteria)){if(_.isArray(this._criteria)||_.isFunction(this._criteria)||!_.isObject(this._criteria))throw new Error("Invalid type for criteria");for(var field in this._criteria)if(this._criteria.hasOwnProperty(field)){var expr=this._criteria[field];if(_.contains(Ops.compoundOperators,field)){if(_.contains(["$not"],field))throw new Error("Invalid operator");this._processOperator(field,field,expr)}else{expr=normalize(expr);for(var op in expr)expr.hasOwnProperty(op)&&this._processOperator(field,op,expr[op])}}}},_processOperator:function(field,operator,value){var compiledSelector;if(_.contains(Ops.simpleOperators,operator))compiledSelector={test:function(obj){var actualValue=Mingo._resolve(obj,field);return simpleOperators[operator](actualValue,value)}};else{if(!_.contains(Ops.compoundOperators,operator))throw new Error("Invalid query operator '"+operator+"' detected");compiledSelector=compoundOperators[operator](field,value)}this._compiled.push(compiledSelector)},test:function(obj){for(var i=0;i<this._compiled.length;i++)if(!this._compiled[i].test(obj))return!1;return!0},find:function(collection,projection){return new Mingo.Cursor(collection,this,projection)},remove:function(collection){for(var arr=[],i=0;i<collection.length;i++)this.test(collection[i])||arr.push(collection[i]);return arr}},nodeEnabled){var Transform=require("stream").Transform,util=require("util");Mingo.Query.prototype.stream=function(options){return new Mingo.Stream(this,options)},Mingo.Stream=function(query,options){return this instanceof Mingo.Stream?(options=options||{},_.extend(options,{objectMode:!0}),Transform.call(this,options),this._query=query,void 0):new Mingo.Stream(query,options)},util.inherits(Mingo.Stream,Transform),Mingo.Stream.prototype._transform=function(chunk,encoding,done){if(_.isObject(chunk)&&this._query.test(chunk))if(_.isEmpty(this._query._projection))this.push(chunk);else{var cursor=new Mingo.Cursor([chunk],this._query);cursor.hasNext()&&this.push(cursor.next())}done()}}Mingo.Cursor=function(collection,query,projection){return this instanceof Mingo.Cursor?(this._query=query,this._collection=collection,this._projection=projection||query._projection,this._operators={},this._result=!1,this._position=0,void 0):new Mingo.Cursor(collection,query,projection)},Mingo.Cursor.prototype={_fetch:function(){var self=this;if(this._result!==!1)return this._result;if(_.isObject(this._projection)&&_.extend(this._operators,{$project:this._projection}),!_.isArray(this._collection))throw new Error("Input collection is not of a valid type.");this._result=_.filter(this._collection,this._query.test,this._query);var pipeline=[];if(_.each(["$sort","$skip","$limit","$project"],function(op){_.has(self._operators,op)&&pipeline.push(_.pick(self._operators,op))}),pipeline.length>0){var aggregator=new Mingo.Aggregator(pipeline);this._result=aggregator.run(this._result,this._query)}return this._result},all:function(){return this._fetch()},first:function(){return this.count()>0?this._fetch()[0]:null},last:function(){return this.count()>0?this._fetch()[this.count()-1]:null},count:function(){return this._fetch().length},skip:function(n){return _.extend(this._operators,{$skip:n}),this},limit:function(n){return _.extend(this._operators,{$limit:n}),this},sort:function(modifier){return _.extend(this._operators,{$sort:modifier}),this},next:function(){return this.hasNext()?this._fetch()[this._position++]:null},hasNext:function(){return this.count()>this._position},max:function(expr){return groupOperators.$max(this._fetch(),expr)},min:function(expr){return groupOperators.$min(this._fetch(),expr)},map:function(callback){return _.map(this._fetch(),callback)},forEach:function(callback){_.each(this._fetch(),callback)}},Mingo.Aggregator=function(operators){return this instanceof Mingo.Aggregator?(this._operators=operators,void 0):new Mingo.Aggregator(operators)},Mingo.Aggregator.prototype={run:function(collection,query){if(!_.isEmpty(this._operators))for(var i=0;i<this._operators.length;i++){var operator=this._operators[i];for(var key in operator)operator.hasOwnProperty(key)&&(collection=query?pipelineOperators[key].call(query,collection,operator[key]):pipelineOperators[key](collection,operator[key]))}return collection}},Mingo._get=function(obj,field){return _.result(obj,field)},Mingo._resolve=function(obj,field){if(!field)return void 0;for(var isText,names=field.split("."),value=obj,i=0;i<names.length;i++){if(isText=null===names[i].match(/^\d+$/),isText&&_.isArray(value)){var res=[];_.each(value,function(item){_.isObject(item)&&res.push(Mingo._resolve(item,names[i]))}),value=res}else value=Mingo._get(value,names[i]);if(void 0===value)break}return value},Mingo.compile=function(criteria,projection){return new Mingo.Query(criteria,projection)},Mingo.find=function(collection,criteria,projection){return new Mingo.Query(criteria).find(collection,projection)},Mingo.remove=function(collection,criteria){return new Mingo.Query(criteria).remove(collection)},Mingo.aggregate=function(collection,pipeline){if(!_.isArray(pipeline))throw new Error("Aggregation pipeline must be an array");return new Mingo.Aggregator(pipeline).run(collection)},Mingo.CollectionMixin={query:function(criteria,projection){return Mingo.find(this.toJSON(),criteria,projection)},aggregate:function(pipeline){var args=[this.toJSON(),pipeline];return Mingo.aggregate.apply(null,args)}};var pipelineOperators={$group:function(collection,expr){var idKey=expr[settings.key],indexes=[],groups=_.groupBy(collection,function(obj){var key=computeValue(obj,idKey,idKey);return indexes.push(key),key});indexes=_.uniq(indexes),expr=_.omit(expr,settings.key);var result=[];return _.each(indexes,function(index){var obj={};obj[settings.key]=index;for(var key in expr)expr.hasOwnProperty(key)&&(obj[key]=accumulate(groups[index],key,expr[key]));result.push(obj)}),result},$match:function(collection,expr){var query=new Mingo.Query(expr);return query.find(collection).all()},$project:function(collection,expr){if(_.isEmpty(expr))return collection;var projected=[],objKeys=_.keys(expr);if(_.contains(objKeys,settings.key)){var id=expr[settings.key];(0===id||id===!1)&&(objKeys=_.without(objKeys,settings.key))}else objKeys.push(settings.key);for(var i=0;i<collection.length;i++){var obj=collection[i],cloneObj={};_.each(objKeys,function(key){var newValue,subExpr=expr[key];if(key===settings.key&&_.isEmpty(subExpr))newValue=obj[key];else if(_.isString(subExpr))newValue=computeValue(obj,subExpr,key);else if(1===subExpr||subExpr===!0)newValue=_.result(obj,key);else if(_.isObject(subExpr)){var operator=_.keys(subExpr);if(operator=operator.length>1?!1:operator[0],operator!==!1&&_.contains(Ops.projectionOperators,operator)){var temp=projectionOperators[operator](obj,subExpr[operator],key);_.isUndefined(temp)||(newValue=temp)}else newValue=computeValue(obj,subExpr,key)}void 0!==newValue&&(cloneObj[key]=_.isObject(newValue)?_.clone(newValue):newValue)}),projected.push(cloneObj)}return projected},$limit:function(collection,value){return _.first(collection,value)},$skip:function(collection,value){return _.rest(collection,value)},$unwind:function(collection,expr){for(var result=[],field=expr.substr(1),i=0;i<collection.length;i++){var obj=collection[i],value=Mingo._get(obj,field);if(!_.isArray(value))throw new Error("Target field '"+field+"' is not of type Array.");_.each(value,function(item){var tmp=_.clone(obj);tmp[field]=item,result.push(tmp)})}return result},$sort:function(collection,sortKeys){if(!_.isEmpty(sortKeys)&&_.isObject(sortKeys)){var modifiers=_.keys(sortKeys);modifiers.reverse().forEach(function(key){var indexes=[],grouped=_.groupBy(collection,function(obj){var value=Mingo._resolve(obj,key);return indexes.push(value),value});indexes=_.sortBy(_.uniq(indexes),function(item){return item}),-1===sortKeys[key]&&indexes.reverse(),collection=[],_.each(indexes,function(item){Array.prototype.push.apply(collection,grouped[item])})})}return collection}},compoundOperators={$and:function(selector,value){if(!_.isArray(value))throw new Error("Invalid expression for $and criteria");var queries=[];return _.each(value,function(expr){queries.push(new Mingo.Query(expr))}),{test:function(obj){for(var i=0;i<queries.length;i++)if(queries[i].test(obj)===!1)return!1;return!0}}},$or:function(selector,value){if(!_.isArray(value))throw new Error("Invalid expression for $or criteria");var queries=[];return _.each(value,function(expr){queries.push(new Mingo.Query(expr))}),{test:function(obj){for(var i=0;i<queries.length;i++)if(queries[i].test(obj))return!0;return!1}}},$nor:function(selector,value){if(!_.isArray(value))throw new Error("Invalid expression for $nor criteria");var query=this.$or("$or",value);return{test:function(obj){return!query.test(obj)}}},$not:function(selector,value){var criteria={};criteria[selector]=normalize(value);var query=new Mingo.Query(criteria);return{test:function(obj){return!query.test(obj)}}},$where:function(selector,value){return _.isFunction(value)||(value=new Function("return "+value+";")),{test:function(obj){return value.call(obj)===!0}}}},simpleOperators={$eq:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return _.isEqual(val,b)}),void 0!==a},$ne:function(a,b){return!this.$eq(a,b)},$in:function(a,b){return a=_.isArray(a)?a:[a],_.intersection(a,b).length>0},$nin:function(a,b){return _.isUndefined(a)||!this.$in(a,b)},$lt:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return b>val}),void 0!==a},$lte:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return b>=val}),void 0!==a},$gt:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return val>b}),void 0!==a},$gte:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return val>=b}),void 0!==a},$mod:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return _.isNumber(val)&&_.isArray(b)&&2===b.length&&val%b[0]===b[1]}),void 0!==a},$regex:function(a,b){return a=_.isArray(a)?a:[a],a=_.find(a,function(val){return _.isString(val)&&_.isRegExp(b)&&!!val.match(b)}),void 0!==a},$exists:function(a,b){return b===!1&&_.isUndefined(a)||b===!0&&!_.isUndefined(a)},$all:function(a,b){var self=this,matched=!1;if(_.isArray(a)&&_.isArray(b))for(var i=0;i<b.length;i++){if(!_.isObject(b[i])||!_.contains(_.keys(b[i]),"$elemMatch"))return _.intersection(b,a).length===b.length;matched=matched||self.$elemMatch(a,b[i].$elemMatch)}return matched},$size:function(a,b){return _.isArray(a)&&_.isNumber(b)&&a.length===b},$elemMatch:function(a,b){if(_.isArray(a)&&!_.isEmpty(a))for(var query=new Mingo.Query(b),i=0;i<a.length;i++)if(query.test(a[i]))return!0;return!1},$type:function(a,b){switch(b){case 1:return _.isNumeric(a)&&-1!==(a+"").indexOf(".");case 2:case 5:return _.isString(a);case 3:return _.isObject(a);case 4:return _.isArray(a);case 8:return _.isBoolean(a);case 9:return _.isDate(a);case 10:return _.isNull(a);case 11:return _.isRegExp(a);case 16:return _.isNumeric(a)&&2147483647>=a&&-1===(a+"").indexOf(".");case 18:return _.isNumeric(a)&&a>2147483647&&0x8000000000000000>=a&&-1===(a+"").indexOf(".");default:return!1}}},projectionOperators={$:function(){throw new Error("$ not implemented")},$elemMatch:function(obj,expr,field){var array=Mingo._resolve(obj,field),query=new Mingo.Query(expr);if(_.isUndefined(array)||!_.isArray(array))return void 0;for(var i=0;i<array.length;i++)if(query.test(array[i]))return array[i];return void 0},$slice:function(obj,expr,field){var array=Mingo._resolve(obj,field);return _.isUndefined(array)?void 0:(_.isArray(expr)||(expr=[expr]),Array.prototype.slice.apply(array,expr))}},groupOperators={$addToSet:function(collection,expr){var result=_.map(collection,function(obj){return computeValue(obj,expr)});return _.uniq(result)},$sum:function(collection,expr){return _.isNumber(expr)?collection.length*expr:_.reduce(collection,function(acc,obj){return acc+computeValue(obj,expr)},0)},$max:function(collection,expr){var obj=_.max(collection,function(obj){return computeValue(obj,expr)});return computeValue(obj,expr)},$min:function(collection,expr){var obj=_.min(collection,function(obj){return computeValue(obj,expr)});return computeValue(obj,expr)},$avg:function(collection,expr){return this.$sum(collection,expr)/collection.length},$push:function(collection,expr){return _.map(collection,function(obj){return computeValue(obj,expr)})},$first:function(collection,expr){return collection.length>0?computeValue(collection[0],expr):void 0},$last:function(collection,expr){return collection.length>0?computeValue(collection[collection.length-1],expr):void 0}},aggregateOperators={$add:function(obj,expr){var args=computeValue(obj,expr);return _.reduce(args,function(memo,num){return memo+num},0)},$subtract:function(obj,expr){var args=computeValue(obj,expr);return args[0]-args[1]},$divide:function(obj,expr){var args=computeValue(obj,expr);return args[0]/args[1]},$multiply:function(obj,expr){var args=computeValue(obj,expr);return _.reduce(args,function(memo,num){return memo*num},1)},$mod:function(obj,expr){var args=computeValue(obj,expr);return args[0]%args[1]},$cmp:function(obj,expr){var args=computeValue(obj,expr);return args[0]>args[1]?1:args[0]<args[1]?-1:0},$concat:function(obj,expr){var args=computeValue(obj,expr);return _.contains(args,null)||_.contains(args,void 0)?null:args.join("")},$strcasecmp:function(obj,expr){var args=computeValue(obj,expr);return args[0]=_.isEmpty(args[0])?"":args[0].toUpperCase(),args[1]=_.isEmpty(args[1])?"":args[1].toUpperCase(),args[0]>args[1]?1:args[0]<args[1]?-1:0},$substr:function(obj,expr){var args=computeValue(obj,expr);return _.isString(args[0])?args[1]<0?"":args[2]<0?args[0].substr(args[1]):args[0].substr(args[1],args[2]):""},$toLower:function(obj,expr){var value=computeValue(obj,expr);return _.isEmpty(value)?"":value.toLowerCase()},$toUpper:function(obj,expr){var value=computeValue(obj,expr);return _.isEmpty(value)?"":value.toUpperCase()}},setOperators={$setEquals:function(obj,expr){var args=computeValue(obj,expr);return 0===_.difference(args[0],args[1]).length},$setIntersection:function(obj,expr){var args=computeValue(obj,expr);return _.intersection(args[0],args[1])},$setDifference:function(obj,expr){var args=computeValue(obj,expr);return _.difference(args[0],args[1])},$setUnion:function(obj,expr){var args=computeValue(obj,expr);return _.union(args[0],args[1])},$setIsSubset:function(obj,expr){var args=computeValue(obj,expr);return _.intersection(args[0],args[1]).length===args[0].length},$anyElementTrue:function(obj,expr){for(var args=computeValue(obj,expr),i=0;i<args.length;i++)if(args[i])return!0;return!1},$allElementsTrue:function(obj,expr){for(var args=computeValue(obj,expr),i=0;i<args.length;i++)if(!args[i])return!1;return!0}},conditionalOperators={$cond:function(obj,expr){var ifExpr,thenExpr,elseExpr;if(_.isArray(expr)){if(3!=expr.length)throw new Error("Invalid arguments for $cond operator");ifExpr=expr[0],thenExpr=expr[1],elseExpr=expr[2]}else _.isObject(expr)&&(ifExpr=expr["if"],thenExpr=expr.then,elseExpr=expr["else"]);var condition=computeValue(obj,ifExpr);return condition?computeValue(obj,thenExpr):computeValue(obj,elseExpr)},$ifNull:function(obj,expr){if(!_.isArray(expr)||2!=expr.length)throw new Error("Invalid arguments for $ifNull operator");var args=computeValue(obj,expr);return null===args[0]||void 0===args[0]?args[1]:args[0]}};_.each(["$eq","$ne","$gt","$gte","$lt","$lte"],function(op){aggregateOperators[op]=function(obj,expr){var args=computeValue(obj,expr);return simpleOperators[op](args[0],args[1])}}),_.extend(aggregateOperators,setOperators,conditionalOperators);var Ops={simpleOperators:_.keys(simpleOperators),compoundOperators:_.keys(compoundOperators),setOperators:_.keys(setOperators),aggregateOperators:_.keys(aggregateOperators),groupOperators:_.keys(groupOperators),pipelineOperators:_.keys(pipelineOperators),projectionOperators:_.keys(projectionOperators)};Ops.queryOperators=_.union(Ops.simpleOperators,Ops.compoundOperators);var accumulate=function(collection,field,expr){if(_.contains(Ops.groupOperators,field))return groupOperators[field](collection,expr);if(_.isObject(expr)){var result={};for(var key in expr)if(expr.hasOwnProperty(key)&&(result[key]=accumulate(collection,key,expr[key]),_.contains(Ops.groupOperators,key))){if(result=result[key],_.keys(expr).length>1)throw new Error("Invalid $group expression '"+JSON.stringify(expr)+"'");break}return result}return void 0},computeValue=function(obj,expr,field){if(_.contains(Ops.aggregateOperators,field))return aggregateOperators[field](obj,expr);if(_.isString(expr)&&expr.length>0&&"$"===expr[0])return Mingo._resolve(obj,expr.slice(1));var result;if(_.isArray(expr)){result=[];for(var i=0;i<expr.length;i++)result.push(computeValue(obj,expr[i],null))}else if(_.isObject(expr)){result={};for(var key in expr)if(expr.hasOwnProperty(key)&&(result[key]=computeValue(obj,expr[key],key),_.contains(Ops.aggregateOperators,key))){if(result=result[key],_.keys(expr).length>1)throw new Error("Invalid aggregation expression '"+JSON.stringify(expr)+"'");break}}else for(var i=0;i<primitives.length;i++)if(primitives[i](expr))return expr;return result}}).call(this); |
72
mingo.js
@@ -129,3 +129,3 @@ (function () { | ||
if (_.contains(["$not"], field)) { | ||
throw Error("Invalid operator"); | ||
throw new Error("Invalid operator"); | ||
} | ||
@@ -159,3 +159,3 @@ this._processOperator(field, field, expr); | ||
} else { | ||
throw Error("Invalid query operator '" + operator + "' detected"); | ||
throw new Error("Invalid query operator '" + operator + "' detected"); | ||
} | ||
@@ -285,3 +285,3 @@ this._compiled.push(compiledSelector); | ||
if (!_.isArray(this._collection)) { | ||
throw Error("Input collection is not of a valid type."); | ||
throw new Error("Input collection is not of a valid type."); | ||
} | ||
@@ -551,3 +551,3 @@ | ||
if (!_.isArray(pipeline)) { | ||
throw Error("Aggregation pipeline must be an array") | ||
throw new Error("Aggregation pipeline must be an array") | ||
} | ||
@@ -654,7 +654,11 @@ return (new Mingo.Aggregator(pipeline)).run(collection); | ||
var objKeys = _.keys(expr); | ||
var removeId = false; | ||
if (_.contains(objKeys, settings.key)) { | ||
var id = objKeys[settings.key]; | ||
removeId = (id === 0 || id === false); | ||
var id = expr[settings.key]; | ||
if (id === 0 || id === false) { | ||
objKeys = _.without(objKeys, settings.key); | ||
} | ||
} else { | ||
// if not specified the add the ID field | ||
objKeys.push(settings.key); | ||
} | ||
@@ -668,11 +672,12 @@ | ||
// tiny optimization here to skip over id | ||
if (removeId && key === settings.key) return; | ||
var subExpr = expr[key]; | ||
var newValue; | ||
if (_.isString(subExpr)) { | ||
cloneObj[key] = computeValue(obj, subExpr, key); | ||
// tiny optimization here to skip over id | ||
if (key === settings.key && _.isEmpty(subExpr)) { | ||
newValue = obj[key]; | ||
} else if (_.isString(subExpr)) { | ||
newValue = computeValue(obj, subExpr, key); | ||
} else if (subExpr === 1 || subExpr === true) { | ||
cloneObj[key] = _.result(obj, key); | ||
newValue = _.result(obj, key); | ||
} else if (_.isObject(subExpr)) { | ||
@@ -685,15 +690,15 @@ var operator = _.keys(subExpr); | ||
if (!_.isUndefined(temp)) { | ||
cloneObj[key] = temp; | ||
newValue = temp; | ||
} | ||
} else { | ||
// compute the value for the sub expression for the key | ||
cloneObj[key] = computeValue(obj, subExpr, key); | ||
newValue = computeValue(obj, subExpr, key); | ||
} | ||
} | ||
}); | ||
if (!removeId && !_.has(cloneObj, settings.key)) { | ||
cloneObj[settings.key] = obj[settings.key]; | ||
} | ||
if (newValue !== undefined) { | ||
cloneObj[key] = _.isObject(newValue) ? _.clone(newValue) : newValue; | ||
} | ||
}); | ||
projected.push(cloneObj); | ||
@@ -1400,2 +1405,6 @@ } | ||
var args = computeValue(obj, expr); | ||
// does not allow concatenation with nulls | ||
if (_.contains(args, null) || _.contains(args, undefined)) { | ||
return null; | ||
} | ||
return args.join(""); | ||
@@ -1413,4 +1422,4 @@ }, | ||
var args = computeValue(obj, expr); | ||
args[0] = args[0].toUpperCase(); | ||
args[1] = args[1].toUpperCase(); | ||
args[0] = _.isEmpty(args[0]) ? "" : args[0].toUpperCase(); | ||
args[1] = _.isEmpty(args[1]) ? "" : args[1].toUpperCase(); | ||
if (args[0] > args[1]) { | ||
@@ -1423,3 +1432,4 @@ return 1; | ||
/** | ||
* Takes a string and returns portion of that string. | ||
* Returns a substring of a string, starting at a specified index position and including the specified number of characters. | ||
* The index is zero-based. | ||
* | ||
@@ -1433,5 +1443,11 @@ * @param obj | ||
if (_.isString(args[0])) { | ||
return args[0].substr(args[1], args[2]); | ||
if (args[1] < 0) { | ||
return ""; | ||
} else if (args[2] < 0) { | ||
return args[0].substr(args[1]); | ||
} else { | ||
return args[0].substr(args[1], args[2]); | ||
} | ||
} | ||
return undefined; | ||
return ""; | ||
}, | ||
@@ -1448,3 +1464,3 @@ | ||
var value = computeValue(obj, expr); | ||
return value.toLowerCase(); | ||
return _.isEmpty(value) ? "" : value.toLowerCase(); | ||
}, | ||
@@ -1461,3 +1477,3 @@ | ||
var value = computeValue(obj, expr); | ||
return value.toUpperCase(); | ||
return _.isEmpty(value) ? "" : value.toUpperCase(); | ||
} | ||
@@ -1560,3 +1576,3 @@ }; | ||
if (expr.length != 3) { | ||
throw Error("Invalid arguments for $cond operator"); | ||
throw new Error("Invalid arguments for $cond operator"); | ||
} | ||
@@ -1585,3 +1601,3 @@ ifExpr = expr[0]; | ||
if (!_.isArray(expr) || expr.length != 2) { | ||
throw Error("Invalid arguments for $ifNull operator"); | ||
throw new Error("Invalid arguments for $ifNull operator"); | ||
} | ||
@@ -1588,0 +1604,0 @@ var args = computeValue(obj, expr); |
{ | ||
"name": "mingo", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"description": "JavaScript implementation of MongoDB query language", | ||
@@ -5,0 +5,0 @@ "main": "mingo.js", |
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
72666
1535