Permalink
Browse files

rebuilt js

  • Loading branch information...
1 parent c0ef2d1 commit 8fb4c0e76d61a439fc8c62337175fa1c3cd7b05a @davidgtonge committed Sep 22, 2012
Showing with 439 additions and 427 deletions.
  1. +438 −426 lib/backbone-query.js
  2. +1 −1 lib/backbone-query.min.js
View
864 lib/backbone-query.js
@@ -5,455 +5,467 @@ Backbone Query - A lightweight query API for Backbone Collections
May be freely distributed according to MIT license.
*/
-/* UTILS
-*/
-
-var Backbone, detect, filter, getCache, getModels, getSortedModels, getType, iterator, makeObj, pageModels, parseQuery, performQuery, processQuery, reject, sortModels, testModelAttribute, testQueryValue, _,
- __slice = [].slice,
+var __slice = [].slice,
__hasProp = {}.hasOwnProperty,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
-filter = function(array, test) {
- var val, _i, _len, _results;
- _results = [];
- for (_i = 0, _len = array.length; _i < _len; _i++) {
- val = array[_i];
- if (test(val)) {
- _results.push(val);
- }
- }
- return _results;
-};
-
-reject = function(array, test) {
- var val, _i, _len, _results;
- _results = [];
- for (_i = 0, _len = array.length; _i < _len; _i++) {
- val = array[_i];
- if (!test(val)) {
- _results.push(val);
- }
- }
- return _results;
-};
-
-detect = function(array, test) {
- var val, _i, _len;
- for (_i = 0, _len = array.length; _i < _len; _i++) {
- val = array[_i];
- if (test(val)) {
- return true;
- }
- }
- return false;
-};
-
-makeObj = function() {
- var args, current, key, o, val;
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
- o = {};
- current = o;
- while (args.length) {
- key = args.shift();
- val = (args.length === 1 ? args.shift() : {});
- current = current[key] = val;
- }
- return o;
-};
-
-getType = function(item) {
- if (_.isRegExp(item)) {
- return "$regex";
- }
- if (_.isDate(item)) {
- return "$date";
- }
- if (_.isObject(item) && !_.isArray(item)) {
- return "object";
- }
- if (_.isArray(item)) {
- return "array";
- }
- if (_.isString(item)) {
- return "string";
- }
- if (_.isNumber(item)) {
- return "number";
- }
- if (_.isBoolean(item)) {
- return "boolean";
- }
- if (_.isFunction(item)) {
- return "function";
- }
- return false;
-};
-
-/*
-Function to parse raw queries
-@param {mixed} raw query
-@return {array} parsed query
-
-Allows queries of the following forms:
-query
- name: "test"
- id: $gte: 10
-
-query [
- {name:"test"}
- {id:$gte:10}
-]
-*/
+(function(define) {
+ return define('backbone-query', function(require, exports) {
+ var Backbone, detect, filter, getCache, getSortedModels, getType, iterator, makeObj, pageModels, parseQuery, parseSubQuery, performQuery, processQuery, reject, runQuery, sortModels, testModelAttribute, testQueryValue, _;
+ _ = require('underscore');
+ Backbone = require('backbone');
+ /* UTILS
+ */
+ filter = function(array, test) {
+ var val, _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
+ val = array[_i];
+ if (test(val)) {
+ _results.push(val);
+ }
+ }
+ return _results;
+ };
+ reject = function(array, test) {
+ var val, _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
+ val = array[_i];
+ if (!test(val)) {
+ _results.push(val);
+ }
+ }
+ return _results;
+ };
+ detect = function(array, test) {
+ var val, _i, _len;
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
+ val = array[_i];
+ if (test(val)) {
+ return true;
+ }
+ }
+ return false;
+ };
+ makeObj = function() {
+ var args, current, key, o, val;
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
+ o = {};
+ current = o;
+ while (args.length) {
+ key = args.shift();
+ val = (args.length === 1 ? args.shift() : {});
+ current = current[key] = val;
+ }
+ return o;
+ };
+ getType = function(item) {
+ if (_.isRegExp(item)) {
+ return "$regex";
+ }
+ if (_.isDate(item)) {
+ return "$date";
+ }
+ if (_.isObject(item) && !_.isArray(item)) {
+ return "object";
+ }
+ if (_.isArray(item)) {
+ return "array";
+ }
+ if (_.isString(item)) {
+ return "string";
+ }
+ if (_.isNumber(item)) {
+ return "number";
+ }
+ if (_.isBoolean(item)) {
+ return "boolean";
+ }
+ if (_.isFunction(item)) {
+ return "function";
+ }
+ return false;
+ };
+ /*
+ Function to parse raw queries
+ @param {mixed} raw query
+ @return {array} parsed query
+
+ Allows queries of the following forms:
+ query
+ name: "test"
+ id: $gte: 10
+
+ query [
+ {name:"test"}
+ {id:$gte:10}
+ ]
+ */
-parseQuery = function(rawQuery) {
- var key, o, paramType, q, query, queryArray, queryParam, type, val, value, _i, _len, _results;
- if (_.isArray(rawQuery)) {
- queryArray = rawQuery;
- } else {
- queryArray = (function() {
- var _results;
+ parseSubQuery = function(rawQuery) {
+ var key, o, paramType, q, query, queryArray, queryParam, type, val, value, _i, _len, _results;
+ if (_.isArray(rawQuery)) {
+ queryArray = rawQuery;
+ } else {
+ queryArray = (function() {
+ var _results;
+ _results = [];
+ for (key in rawQuery) {
+ if (!__hasProp.call(rawQuery, key)) continue;
+ val = rawQuery[key];
+ _results.push(makeObj(key, val));
+ }
+ return _results;
+ })();
+ }
_results = [];
- for (key in rawQuery) {
- if (!__hasProp.call(rawQuery, key)) continue;
- val = rawQuery[key];
- _results.push(makeObj(key, val));
+ for (_i = 0, _len = queryArray.length; _i < _len; _i++) {
+ query = queryArray[_i];
+ for (key in query) {
+ if (!__hasProp.call(query, key)) continue;
+ queryParam = query[key];
+ o = {
+ key: key
+ };
+ paramType = getType(queryParam);
+ switch (paramType) {
+ case "$regex":
+ case "$date":
+ o.type = paramType;
+ o.value = queryParam;
+ break;
+ case "object":
+ if (key === "$and" || key === "$or" || key === "$nor" || key === "$not") {
+ o.value = parseSubQuery(queryParam);
+ o.type = key;
+ o.key = null;
+ } else {
+ for (type in queryParam) {
+ value = queryParam[type];
+ if (testQueryValue(type, value)) {
+ o.type = type;
+ switch (type) {
+ case "$elemMatch":
+ case "$relationMatch":
+ o.value = parseQuery(value);
+ break;
+ case "$computed":
+ q = makeObj(key, value);
+ o.value = parseSubQuery(q);
+ break;
+ default:
+ o.value = value;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ o.type = "$equal";
+ o.value = queryParam;
+ }
+ if ((o.type === "$equal") && (paramType === "object" || paramType === "array")) {
+ o.type = "$oEqual";
+ }
+ }
+ _results.push(o);
}
return _results;
- })();
- }
- _results = [];
- for (_i = 0, _len = queryArray.length; _i < _len; _i++) {
- query = queryArray[_i];
- for (key in query) {
- if (!__hasProp.call(query, key)) continue;
- queryParam = query[key];
- o = {
- key: key
- };
- paramType = getType(queryParam);
- switch (paramType) {
+ };
+ testQueryValue = function(type, value) {
+ switch (type) {
+ case "$in":
+ case "$nin":
+ case "$all":
+ case "$any":
+ return _(value).isArray();
+ case "$size":
+ return _(value).isNumber();
case "$regex":
- case "$date":
- o.type = paramType;
- o.value = queryParam;
- break;
- case "object":
- if (key === "$and" || key === "$or" || key === "$nor" || key === "$not") {
- o.value = queryParam;
- o.type = key;
- o.key = null;
+ return _(value).isRegExp();
+ case "$like":
+ case "$likeI":
+ return _(value).isString();
+ case "$between":
+ return _(value).isArray() && (value.length === 2);
+ case "$cb":
+ return _(value).isFunction();
+ default:
+ return true;
+ }
+ };
+ testModelAttribute = function(type, value) {
+ switch (type) {
+ case "$like":
+ case "$likeI":
+ case "$regex":
+ return _(value).isString();
+ case "$contains":
+ case "$all":
+ case "$any":
+ case "$elemMatch":
+ return _(value).isArray();
+ case "$size":
+ return _(value).isArray() || _(value).isString();
+ case "$in":
+ case "$nin":
+ return value != null;
+ case "$relationMatch":
+ return (value != null) && value.models;
+ default:
+ return true;
+ }
+ };
+ performQuery = function(type, value, attr, model, key) {
+ switch (type) {
+ case "$equal":
+ if (_(attr).isArray()) {
+ return __indexOf.call(attr, value) >= 0;
} else {
- for (type in queryParam) {
- value = queryParam[type];
- if (testQueryValue(type, value)) {
- o.type = type;
- switch (type) {
- case "$elemMatch":
- case "$relationMatch":
- o.value = parseQuery(value);
- break;
- case "$computed":
- q = makeObj(key, value);
- o.value = parseQuery(q);
- break;
- default:
- o.value = value;
- }
- }
- }
+ return attr === value;
}
break;
+ case "$oEqual":
+ return _(attr).isEqual(value);
+ case "$contains":
+ return __indexOf.call(attr, value) >= 0;
+ case "$ne":
+ return attr !== value;
+ case "$lt":
+ return attr < value;
+ case "$gt":
+ return attr > value;
+ case "$lte":
+ return attr <= value;
+ case "$gte":
+ return attr >= value;
+ case "$between":
+ return (value[0] < attr && attr < value[1]);
+ case "$in":
+ return __indexOf.call(value, attr) >= 0;
+ case "$nin":
+ return __indexOf.call(value, attr) < 0;
+ case "$all":
+ return _(value).all(function(item) {
+ return __indexOf.call(attr, item) >= 0;
+ });
+ case "$any":
+ return _(attr).any(function(item) {
+ return __indexOf.call(value, item) >= 0;
+ });
+ case "$size":
+ return attr.length === value;
+ case "$exists":
+ case "$has":
+ return (attr != null) === value;
+ case "$like":
+ return attr.indexOf(value) !== -1;
+ case "$likeI":
+ return attr.toLowerCase().indexOf(value.toLowerCase()) !== -1;
+ case "$regex":
+ return value.test(attr);
+ case "$cb":
+ return value.call(model, attr);
+ case "$elemMatch":
+ return (runQuery(attr, value, "elemMatch")).length > 0;
+ case "$relationMatch":
+ return (runQuery(attr.models, value, "relationMatch")).length > 0;
+ case "$computed":
+ return iterator([model], value, false, detect, "computed");
+ case "$and":
+ case "$or":
+ case "$nor":
+ case "$not":
+ return (processQuery[type]([model], value)).length === 1;
default:
- o.type = "$equal";
- o.value = queryParam;
- }
- if ((o.type === "$equal") && (paramType === "object" || paramType === "array")) {
- o.type = "$oEqual";
+ return false;
}
- }
- _results.push(o);
- }
- return _results;
-};
-
-testQueryValue = function(type, value) {
- switch (type) {
- case "$in":
- case "$nin":
- case "$all":
- case "$any":
- return _(value).isArray();
- case "$size":
- return _(value).isNumber();
- case "$regex":
- return _(value).isRegExp();
- case "$like":
- case "$likeI":
- return _(value).isString();
- case "$between":
- return _(value).isArray() && (value.length === 2);
- case "$cb":
- return _(value).isFunction();
- default:
- return true;
- }
-};
-
-testModelAttribute = function(type, value) {
- switch (type) {
- case "$like":
- case "$likeI":
- case "$regex":
- return _(value).isString();
- case "$contains":
- case "$all":
- case "$any":
- case "$elemMatch":
- return _(value).isArray();
- case "$size":
- return _(value).isArray() || _(value).isString();
- case "$in":
- case "$nin":
- return value != null;
- case "$relationMatch":
- return (value != null) && value.models;
- default:
- return true;
- }
-};
-
-performQuery = function(type, value, attr, model, key) {
- switch (type) {
- case "$equal":
- if (_(attr).isArray()) {
- return __indexOf.call(attr, value) >= 0;
- } else {
- return attr === value;
+ };
+ iterator = function(models, query, andOr, filterFunction, itemType) {
+ if (itemType == null) {
+ itemType = false;
}
- break;
- case "$oEqual":
- return _(attr).isEqual(value);
- case "$contains":
- return __indexOf.call(attr, value) >= 0;
- case "$ne":
- return attr !== value;
- case "$lt":
- return attr < value;
- case "$gt":
- return attr > value;
- case "$lte":
- return attr <= value;
- case "$gte":
- return attr >= value;
- case "$between":
- return (value[0] < attr && attr < value[1]);
- case "$in":
- return __indexOf.call(value, attr) >= 0;
- case "$nin":
- return __indexOf.call(value, attr) < 0;
- case "$all":
- return _(value).all(function(item) {
- return __indexOf.call(attr, item) >= 0;
- });
- case "$any":
- return _(attr).any(function(item) {
- return __indexOf.call(value, item) >= 0;
+ return filterFunction(models, function(model) {
+ var attr, q, test, _i, _len;
+ for (_i = 0, _len = query.length; _i < _len; _i++) {
+ q = query[_i];
+ attr = (function() {
+ switch (itemType) {
+ case "elemMatch":
+ return model[q.key];
+ case "computed":
+ return model[q.key]();
+ default:
+ return model.get(q.key);
+ }
+ })();
+ test = testModelAttribute(q.type, attr);
+ if (test) {
+ test = performQuery(q.type, q.value, attr, model, q.key);
+ }
+ if (andOr === test) {
+ return andOr;
+ }
+ }
+ return !andOr;
});
- case "$size":
- return attr.length === value;
- case "$exists":
- case "$has":
- return (attr != null) === value;
- case "$like":
- return attr.indexOf(value) !== -1;
- case "$likeI":
- return attr.toLowerCase().indexOf(value.toLowerCase()) !== -1;
- case "$regex":
- return value.test(attr);
- case "$cb":
- return value.call(model, attr);
- case "$elemMatch":
- return iterator(attr, value, false, detect, "elemMatch");
- case "$relationMatch":
- return iterator(attr.models, value, false, detect, "relationMatch");
- case "$computed":
- return iterator([model], value, false, detect, "computed");
- case "$and":
- case "$or":
- case "$nor":
- case "$not":
- return (processQuery[type]([model], value)).length === 1;
- default:
- return false;
- }
-};
-
-iterator = function(models, query, andOr, filterFunction, subQuery) {
- var parsedQuery;
- if (subQuery == null) {
- subQuery = false;
- }
- parsedQuery = subQuery ? query : parseQuery(query);
- return filterFunction(models, function(model) {
- var attr, q, test, _i, _len;
- for (_i = 0, _len = parsedQuery.length; _i < _len; _i++) {
- q = parsedQuery[_i];
- attr = (function() {
- switch (subQuery) {
- case "elemMatch":
- return model[q.key];
- case "computed":
- return model[q.key]();
- default:
- return model.get(q.key);
+ };
+ processQuery = {
+ $and: function(models, query, itemType) {
+ return iterator(models, query, false, filter, itemType);
+ },
+ $or: function(models, query, itemType) {
+ return iterator(models, query, true, filter, itemType);
+ },
+ $nor: function(models, query, itemType) {
+ return iterator(models, query, true, reject, itemType);
+ },
+ $not: function(models, query, itemType) {
+ return iterator(models, query, false, reject, itemType);
+ }
+ };
+ parseQuery = function(query) {
+ var compoundKeys, compoundQuery, key, queryKeys, type, val;
+ queryKeys = _(query).keys();
+ compoundKeys = ["$and", "$not", "$or", "$nor"];
+ compoundQuery = _.intersection(compoundKeys, queryKeys);
+ if (compoundQuery.length === 0) {
+ return [
+ {
+ type: "$and",
+ parsedQuery: parseSubQuery(query)
+ }
+ ];
+ } else {
+ if (compoundQuery.length !== queryKeys.length) {
+ if (__indexOf.call(compoundQuery, "$and") < 0) {
+ query.$and = {};
+ compoundQuery.unshift("$and");
+ }
+ for (key in query) {
+ if (!__hasProp.call(query, key)) continue;
+ val = query[key];
+ if (!(__indexOf.call(compoundKeys, key) < 0)) {
+ continue;
+ }
+ query.$and[key] = val;
+ delete query[key];
+ }
}
- })();
- test = testModelAttribute(q.type, attr);
- if (test) {
- test = performQuery(q.type, q.value, attr, model, q.key);
+ return (function() {
+ var _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = compoundQuery.length; _i < _len; _i++) {
+ type = compoundQuery[_i];
+ _results.push({
+ type: type,
+ parsedQuery: parseSubQuery(query[type])
+ });
+ }
+ return _results;
+ })();
}
- if (andOr === test) {
- return andOr;
+ };
+ runQuery = function(items, query, itemType) {
+ var reduceIterator;
+ if (!itemType) {
+ query = parseQuery(query);
}
- }
- return !andOr;
- });
-};
-
-processQuery = {
- $and: function(models, query) {
- return iterator(models, query, false, filter);
- },
- $or: function(models, query) {
- return iterator(models, query, true, filter);
- },
- $nor: function(models, query) {
- return iterator(models, query, true, reject);
- },
- $not: function(models, query) {
- return iterator(models, query, false, reject);
- }
-};
-
-getCache = function(collection, query, options) {
- var cache, models, queryString, _ref;
- queryString = JSON.stringify(query);
- cache = (_ref = collection._queryCache) != null ? _ref : collection._queryCache = {};
- models = cache[queryString];
- if (!models) {
- models = getSortedModels(collection, query, options);
- cache[queryString] = models;
- }
- return models;
-};
-
-getModels = function(collection, query) {
- var compoundKeys, compoundQuery, key, queryKeys, reduceIterator, val;
- queryKeys = _(query).keys();
- compoundKeys = ["$and", "$not", "$or", "$nor"];
- compoundQuery = _.intersection(compoundKeys, queryKeys);
- if (compoundQuery.length === 0) {
- return processQuery.$and(collection.models, query);
- } else {
- if (compoundQuery.length !== queryKeys.length) {
- if (__indexOf.call(compoundQuery, "$and") < 0) {
- query.$and = {};
- compoundQuery.unshift("$and");
+ reduceIterator = function(memo, queryItem) {
+ return processQuery[queryItem.type](memo, queryItem.parsedQuery, itemType);
+ };
+ return _.reduce(query, reduceIterator, items);
+ };
+ getCache = function(collection, query, options) {
+ var cache, models, queryString, _ref;
+ queryString = JSON.stringify(query);
+ cache = (_ref = collection._queryCache) != null ? _ref : collection._queryCache = {};
+ models = cache[queryString];
+ if (!models) {
+ models = getSortedModels(collection, query, options);
+ cache[queryString] = models;
}
- for (key in query) {
- if (!__hasProp.call(query, key)) continue;
- val = query[key];
- if (!(__indexOf.call(compoundKeys, key) < 0)) {
- continue;
- }
- query.$and[key] = val;
- delete query[key];
+ return models;
+ };
+ getSortedModels = function(collection, query, options) {
+ var models;
+ models = runQuery(collection.models, query);
+ if (options.sortBy) {
+ models = sortModels(models, options);
}
- }
- reduceIterator = function(memo, queryType) {
- return processQuery[queryType](memo, query[queryType]);
+ return models;
};
- return _.reduce(compoundQuery, reduceIterator, collection.models);
- }
-};
-
-getSortedModels = function(collection, query, options) {
- var models;
- models = getModels(collection, query);
- if (options.sortBy) {
- models = sortModels(models, options);
- }
- return models;
-};
-
-sortModels = function(models, options) {
- if (_(options.sortBy).isString()) {
- models = _(models).sortBy(function(model) {
- return model.get(options.sortBy);
+ sortModels = function(models, options) {
+ if (_(options.sortBy).isString()) {
+ models = _(models).sortBy(function(model) {
+ return model.get(options.sortBy);
+ });
+ } else if (_(options.sortBy).isFunction()) {
+ models = _(models).sortBy(options.sortBy);
+ }
+ if (options.order === "desc") {
+ models = models.reverse();
+ }
+ return models;
+ };
+ pageModels = function(models, options) {
+ var end, sliced_models, start, total_pages;
+ if (options.offset) {
+ start = options.offset;
+ } else if (options.page) {
+ start = (options.page - 1) * options.limit;
+ } else {
+ start = 0;
+ }
+ end = start + options.limit;
+ sliced_models = models.slice(start, end);
+ if (options.pager && _.isFunction(options.pager)) {
+ total_pages = Math.ceil(models.length / options.limit);
+ options.pager(total_pages, sliced_models);
+ }
+ return sliced_models;
+ };
+ Backbone.QueryCollection = Backbone.Collection.extend({
+ query: function(query, options) {
+ var models;
+ if (options == null) {
+ options = {};
+ }
+ if (options.cache) {
+ models = getCache(this, query, options);
+ } else {
+ models = getSortedModels(this, query, options);
+ }
+ if (options.limit) {
+ models = pageModels(models, options);
+ }
+ return models;
+ },
+ findOne: function(query) {
+ return this.query(query)[0];
+ },
+ whereBy: function(params, options) {
+ if (options == null) {
+ options = {};
+ }
+ return new this.constructor(this.query(params, options));
+ },
+ resetQueryCache: function() {
+ return this._queryCache = {};
+ }
});
- } else if (_(options.sortBy).isFunction()) {
- models = _(models).sortBy(options.sortBy);
- }
- if (options.order === "desc") {
- models = models.reverse();
- }
- return models;
-};
-
-pageModels = function(models, options) {
- var end, sliced_models, start, total_pages;
- if (options.offset) {
- start = options.offset;
- } else if (options.page) {
- start = (options.page - 1) * options.limit;
+ return exports.QueryCollection = Backbone.QueryCollection;
+ });
+}).call(this, typeof define === 'function' && define.amd ? define : function(id, factory) {
+ if (typeof exports !== 'undefined') {
+ factory((function(id) {
+ return require(id);
+ }), exports);
} else {
- start = 0;
- }
- end = start + options.limit;
- sliced_models = models.slice(start, end);
- if (options.pager && _.isFunction(options.pager)) {
- total_pages = Math.ceil(models.length / options.limit);
- options.pager(total_pages, sliced_models);
- }
- return sliced_models;
-};
-
-if (typeof require !== 'undefined') {
- _ = require('underscore');
- Backbone = require('backbone');
-}
-
-Backbone.QueryCollection = Backbone.Collection.extend({
- query: function(query, options) {
- var models;
- if (options == null) {
- options = {};
- }
- if (options.cache) {
- models = getCache(this, query, options);
- } else {
- models = getSortedModels(this, query, options);
- }
- if (options.limit) {
- models = pageModels(models, options);
- }
- return models;
- },
- findOne: function(query) {
- return this.query(query)[0];
- },
- whereBy: function(params, options) {
- if (options == null) {
- options = {};
- }
- return new this.constructor(this.query(params, options));
- },
- resetQueryCache: function() {
- return this._queryCache = {};
+ factory((function(id) {
+ return this[id === 'underscore' ? '_' : 'Backbone'];
+ }), {});
}
});
-
-if (typeof exports !== "undefined") {
- exports.QueryCollection = Backbone.QueryCollection;
-}
View
2 lib/backbone-query.min.js
@@ -1 +1 @@
-var Backbone,detect,filter,getCache,getModels,getSortedModels,getType,iterator,makeObj,pageModels,parseQuery,performQuery,processQuery,reject,sortModels,testModelAttribute,testQueryValue,_,__slice=[].slice,__hasProp={}.hasOwnProperty,__indexOf=[].indexOf||function(a){for(var b=0,c=this.length;b<c;b++)if(b in this&&this[b]===a)return b;return-1};filter=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)&&f.push(c);return f},reject=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)||f.push(c);return f},detect=function(a,b){var c,d,e;for(d=0,e=a.length;d<e;d++){c=a[d];if(b(c))return!0}return!1},makeObj=function(){var a,b,c,d,e;a=1<=arguments.length?__slice.call(arguments,0):[],d={},b=d;while(a.length)c=a.shift(),e=a.length===1?a.shift():{},b=b[c]=e;return d},getType=function(a){return _.isRegExp(a)?"$regex":_.isDate(a)?"$date":_.isObject(a)&&!_.isArray(a)?"object":_.isArray(a)?"array":_.isString(a)?"string":_.isNumber(a)?"number":_.isBoolean(a)?"boolean":_.isFunction(a)?"function":!1},parseQuery=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;_.isArray(a)?g=a:g=function(){var c;c=[];for(b in a){if(!__hasProp.call(a,b))continue;j=a[b],c.push(makeObj(b,j))}return c}(),n=[];for(l=0,m=g.length;l<m;l++){f=g[l];for(b in f){if(!__hasProp.call(f,b))continue;h=f[b],c={key:b},d=getType(h);switch(d){case"$regex":case"$date":c.type=d,c.value=h;break;case"object":if(b==="$and"||b==="$or"||b==="$nor"||b==="$not")c.value=h,c.type=b,c.key=null;else for(i in h){k=h[i];if(testQueryValue(i,k)){c.type=i;switch(i){case"$elemMatch":case"$relationMatch":c.value=parseQuery(k);break;case"$computed":e=makeObj(b,k),c.value=parseQuery(e);break;default:c.value=k}}}break;default:c.type="$equal",c.value=h}c.type==="$equal"&&(d==="object"||d==="array")&&(c.type="$oEqual")}n.push(c)}return n},testQueryValue=function(a,b){switch(a){case"$in":case"$nin":case"$all":case"$any":return _(b).isArray();case"$size":return _(b).isNumber();case"$regex":return _(b).isRegExp();case"$like":case"$likeI":return _(b).isString();case"$between":return _(b).isArray()&&b.length===2;case"$cb":return _(b).isFunction();default:return!0}},testModelAttribute=function(a,b){switch(a){case"$like":case"$likeI":case"$regex":return _(b).isString();case"$contains":case"$all":case"$any":case"$elemMatch":return _(b).isArray();case"$size":return _(b).isArray()||_(b).isString();case"$in":case"$nin":return b!=null;case"$relationMatch":return b!=null&&b.models;default:return!0}},performQuery=function(a,b,c,d,e){switch(a){case"$equal":return _(c).isArray()?__indexOf.call(c,b)>=0:c===b;case"$oEqual":return _(c).isEqual(b);case"$contains":return __indexOf.call(c,b)>=0;case"$ne":return c!==b;case"$lt":return c<b;case"$gt":return c>b;case"$lte":return c<=b;case"$gte":return c>=b;case"$between":return b[0]<c&&c<b[1];case"$in":return __indexOf.call(b,c)>=0;case"$nin":return __indexOf.call(b,c)<0;case"$all":return _(b).all(function(a){return __indexOf.call(c,a)>=0});case"$any":return _(c).any(function(a){return __indexOf.call(b,a)>=0});case"$size":return c.length===b;case"$exists":case"$has":return c!=null===b;case"$like":return c.indexOf(b)!==-1;case"$likeI":return c.toLowerCase().indexOf(b.toLowerCase())!==-1;case"$regex":return b.test(c);case"$cb":return b.call(d,c);case"$elemMatch":return iterator(c,b,!1,detect,"elemMatch");case"$relationMatch":return iterator(c.models,b,!1,detect,"relationMatch");case"$computed":return iterator([d],b,!1,detect,"computed");case"$and":case"$or":case"$nor":case"$not":return processQuery[a]([d],b).length===1;default:return!1}},iterator=function(a,b,c,d,e){var f;return e==null&&(e=!1),f=e?b:parseQuery(b),d(a,function(a){var b,d,g,h,i;for(h=0,i=f.length;h<i;h++){d=f[h],b=function(){switch(e){case"elemMatch":return a[d.key];case"computed":return a[d.key]();default:return a.get(d.key)}}(),g=testModelAttribute(d.type,b),g&&(g=performQuery(d.type,d.value,b,a,d.key));if(c===g)return c}return!c})},processQuery={$and:function(a,b){return iterator(a,b,!1,filter)},$or:function(a,b){return iterator(a,b,!0,filter)},$nor:function(a,b){return iterator(a,b,!0,reject)},$not:function(a,b){return iterator(a,b,!1,reject)}},getCache=function(a,b,c){var d,e,f,g;return f=JSON.stringify(b),d=(g=a._queryCache)!=null?g:a._queryCache={},e=d[f],e||(e=getSortedModels(a,b,c),d[f]=e),e},getModels=function(a,b){var c,d,e,f,g,h;f=_(b).keys(),c=["$and","$not","$or","$nor"],d=_.intersection(c,f);if(d.length===0)return processQuery.$and(a.models,b);if(d.length!==f.length){__indexOf.call(d,"$and")<0&&(b.$and={},d.unshift("$and"));for(e in b){if(!__hasProp.call(b,e))continue;h=b[e];if(__indexOf.call(c,e)<0)b.$and[e]=h,delete b[e];else continue}}return g=function(a,c){return processQuery[c](a,b[c])},_.reduce(d,g,a.models)},getSortedModels=function(a,b,c){var d;return d=getModels(a,b),c.sortBy&&(d=sortModels(d,c)),d},sortModels=function(a,b){return _(b.sortBy).isString()?a=_(a).sortBy(function(a){return a.get(b.sortBy)}):_(b.sortBy).isFunction()&&(a=_(a).sortBy(b.sortBy)),b.order==="desc"&&(a=a.reverse()),a},pageModels=function(a,b){var c,d,e,f;return b.offset?e=b.offset:b.page?e=(b.page-1)*b.limit:e=0,c=e+b.limit,d=a.slice(e,c),b.pager&&_.isFunction(b.pager)&&(f=Math.ceil(a.length/b.limit),b.pager(f,d)),d},typeof require!="undefined"&&(_=require("underscore"),Backbone=require("backbone")),Backbone.QueryCollection=Backbone.Collection.extend({query:function(a,b){var c;return b==null&&(b={}),b.cache?c=getCache(this,a,b):c=getSortedModels(this,a,b),b.limit&&(c=pageModels(c,b)),c},findOne:function(a){return this.query(a)[0]},whereBy:function(a,b){return b==null&&(b={}),new this.constructor(this.query(a,b))},resetQueryCache:function(){return this._queryCache={}}}),typeof exports!="undefined"&&(exports.QueryCollection=Backbone.QueryCollection)
+var __slice=[].slice,__hasProp={}.hasOwnProperty,__indexOf=[].indexOf||function(a){for(var b=0,c=this.length;b<c;b++)if(b in this&&this[b]===a)return b;return-1};((function(a){return a("backbone-query",function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;return u=a("underscore"),c=a("backbone"),e=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)&&f.push(c);return f},p=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)||f.push(c);return f},d=function(a,b){var c,d,e;for(d=0,e=a.length;d<e;d++){c=a[d];if(b(c))return!0}return!1},j=function(){var a,b,c,d,e;a=1<=arguments.length?__slice.call(arguments,0):[],d={},b=d;while(a.length)c=a.shift(),e=a.length===1?a.shift():{},b=b[c]=e;return d},h=function(a){return u.isRegExp(a)?"$regex":u.isDate(a)?"$date":u.isObject(a)&&!u.isArray(a)?"object":u.isArray(a)?"array":u.isString(a)?"string":u.isNumber(a)?"number":u.isBoolean(a)?"boolean":u.isFunction(a)?"function":!1},m=function(a){var b,c,d,e,f,g,i,k,n,o,p,q,r;u.isArray(a)?g=a:g=function(){var c;c=[];for(b in a){if(!__hasProp.call(a,b))continue;n=a[b],c.push(j(b,n))}return c}(),r=[];for(p=0,q=g.length;p<q;p++){f=g[p];for(b in f){if(!__hasProp.call(f,b))continue;i=f[b],c={key:b},d=h(i);switch(d){case"$regex":case"$date":c.type=d,c.value=i;break;case"object":if(b==="$and"||b==="$or"||b==="$nor"||b==="$not")c.value=m(i),c.type=b,c.key=null;else for(k in i){o=i[k];if(t(k,o)){c.type=k;switch(k){case"$elemMatch":case"$relationMatch":c.value=l(o);break;case"$computed":e=j(b,o),c.value=m(e);break;default:c.value=o}}}break;default:c.type="$equal",c.value=i}c.type==="$equal"&&(d==="object"||d==="array")&&(c.type="$oEqual")}r.push(c)}return r},t=function(a,b){switch(a){case"$in":case"$nin":case"$all":case"$any":return u(b).isArray();case"$size":return u(b).isNumber();case"$regex":return u(b).isRegExp();case"$like":case"$likeI":return u(b).isString();case"$between":return u(b).isArray()&&b.length===2;case"$cb":return u(b).isFunction();default:return!0}},s=function(a,b){switch(a){case"$like":case"$likeI":case"$regex":return u(b).isString();case"$contains":case"$all":case"$any":case"$elemMatch":return u(b).isArray();case"$size":return u(b).isArray()||u(b).isString();case"$in":case"$nin":return b!=null;case"$relationMatch":return b!=null&&b.models;default:return!0}},n=function(a,b,c,e,f){switch(a){case"$equal":return u(c).isArray()?__indexOf.call(c,b)>=0:c===b;case"$oEqual":return u(c).isEqual(b);case"$contains":return __indexOf.call(c,b)>=0;case"$ne":return c!==b;case"$lt":return c<b;case"$gt":return c>b;case"$lte":return c<=b;case"$gte":return c>=b;case"$between":return b[0]<c&&c<b[1];case"$in":return __indexOf.call(b,c)>=0;case"$nin":return __indexOf.call(b,c)<0;case"$all":return u(b).all(function(a){return __indexOf.call(c,a)>=0});case"$any":return u(c).any(function(a){return __indexOf.call(b,a)>=0});case"$size":return c.length===b;case"$exists":case"$has":return c!=null===b;case"$like":return c.indexOf(b)!==-1;case"$likeI":return c.toLowerCase().indexOf(b.toLowerCase())!==-1;case"$regex":return b.test(c);case"$cb":return b.call(e,c);case"$elemMatch":return q(c,b,"elemMatch").length>0;case"$relationMatch":return q(c.models,b,"relationMatch").length>0;case"$computed":return i([e],b,!1,d,"computed");case"$and":case"$or":case"$nor":case"$not":return o[a]([e],b).length===1;default:return!1}},i=function(a,b,c,d,e){return e==null&&(e=!1),d(a,function(a){var d,f,g,h,i;for(h=0,i=b.length;h<i;h++){f=b[h],d=function(){switch(e){case"elemMatch":return a[f.key];case"computed":return a[f.key]();default:return a.get(f.key)}}(),g=s(f.type,d),g&&(g=n(f.type,f.value,d,a,f.key));if(c===g)return c}return!c})},o={$and:function(a,b,c){return i(a,b,!1,e,c)},$or:function(a,b,c){return i(a,b,!0,e,c)},$nor:function(a,b,c){return i(a,b,!0,p,c)},$not:function(a,b,c){return i(a,b,!1,p,c)}},l=function(a){var b,c,d,e,f,g;e=u(a).keys(),b=["$and","$not","$or","$nor"],c=u.intersection(b,e);if(c.length===0)return[{type:"$and",parsedQuery:m(a)}];if(c.length!==e.length){__indexOf.call(c,"$and")<0&&(a.$and={},c.unshift("$and"));for(d in a){if(!__hasProp.call(a,d))continue;g=a[d];if(__indexOf.call(b,d)<0)a.$and[d]=g,delete a[d];else continue}}return function(){var b,d,e;e=[];for(b=0,d=c.length;b<d;b++)f=c[b],e.push({type:f,parsedQuery:m(a[f])});return e}()},q=function(a,b,c){var d;return c||(b=l(b)),d=function(a,b){return o[b.type](a,b.parsedQuery,c)},u.reduce(b,d,a)},f=function(a,b,c){var d,e,f,h;return f=JSON.stringify(b),d=(h=a._queryCache)!=null?h:a._queryCache={},e=d[f],e||(e=g(a,b,c),d[f]=e),e},g=function(a,b,c){var d;return d=q(a.models,b),c.sortBy&&(d=r(d,c)),d},r=function(a,b){return u(b.sortBy).isString()?a=u(a).sortBy(function(a){return a.get(b.sortBy)}):u(b.sortBy).isFunction()&&(a=u(a).sortBy(b.sortBy)),b.order==="desc"&&(a=a.reverse()),a},k=function(a,b){var c,d,e,f;return b.offset?e=b.offset:b.page?e=(b.page-1)*b.limit:e=0,c=e+b.limit,d=a.slice(e,c),b.pager&&u.isFunction(b.pager)&&(f=Math.ceil(a.length/b.limit),b.pager(f,d)),d},c.QueryCollection=c.Collection.extend({query:function(a,b){var c;return b==null&&(b={}),b.cache?c=f(this,a,b):c=g(this,a,b),b.limit&&(c=k(c,b)),c},findOne:function(a){return this.query(a)[0]},whereBy:function(a,b){return b==null&&(b={}),new this.constructor(this.query(a,b))},resetQueryCache:function(){return this._queryCache={}}}),b.QueryCollection=c.QueryCollection})})).call(this,typeof define=="function"&&define.amd?define:function(a,b){typeof exports!="undefined"?b(function(a){return require(a)},exports):b(function(a){return this[a==="underscore"?"_":"Backbone"]},{})})

0 comments on commit 8fb4c0e

Please sign in to comment.