lokijs
Version:
Fast document oriented javascript in-memory database
2 lines • 105 kB
JavaScript
(function(root,factory){if(typeof define==="function"&&define.amd){define([],factory)}else if(typeof exports==="object"){module.exports=factory()}else{root.loki=factory()}})(this,function(){return function(){"use strict";var hasOwnProperty=Object.prototype.hasOwnProperty;function deepFreeze(obj){var prop,i;if(Array.isArray(obj)){for(i=0;i<obj.length;i++){deepFreeze(obj[i])}freeze(obj)}else if(obj!==null&&typeof obj==="object"){for(prop in obj){if(obj.hasOwnProperty(prop)){deepFreeze(obj[prop])}}freeze(obj)}}function freeze(obj){if(!Object.isFrozen(obj)){Object.freeze(obj)}}function unFreeze(obj){if(!Object.isFrozen(obj)){return obj}return clone(obj,"shallow")}var Utils={copyProperties:function(src,dest){var prop;for(prop in src){dest[prop]=src[prop]}},resolveTransformObject:function(subObj,params,depth){var prop,pname;if(typeof depth!=="number"){depth=0}if(++depth>=10)return subObj;for(prop in subObj){if(typeof subObj[prop]==="string"&&subObj[prop].indexOf("[%lktxp]")===0){pname=subObj[prop].substring(8);if(params.hasOwnProperty(pname)){subObj[prop]=params[pname]}}else if(typeof subObj[prop]==="object"){subObj[prop]=Utils.resolveTransformObject(subObj[prop],params,depth)}}return subObj},resolveTransformParams:function(transform,params){var idx,clonedStep,resolvedTransform=[];if(typeof params==="undefined")return transform;for(idx=0;idx<transform.length;idx++){clonedStep=clone(transform[idx],"shallow-recurse-objects");resolvedTransform.push(Utils.resolveTransformObject(clonedStep,params))}return resolvedTransform},getIn:function(object,path,usingDotNotation){if(object==null){return undefined}if(!usingDotNotation){return object[path]}if(typeof path==="string"){path=path.split(".")}if(!Array.isArray(path)){throw new Error("path must be a string or array. Found "+typeof path)}var index=0,length=path.length;while(object!=null&&index<length){object=object[path[index++]]}return index&&index==length?object:undefined}};var Comparators={aeq:aeqHelper,lt:ltHelper,gt:gtHelper};function aeqHelper(prop1,prop2){var cv1,cv2,t1,t2;if(prop1===prop2)return true;if(!prop1||!prop2||prop1===true||prop2===true||prop1!==prop1||prop2!==prop2){switch(prop1){case undefined:t1=1;break;case null:t1=1;break;case false:t1=3;break;case true:t1=4;break;case"":t1=5;break;default:t1=prop1===prop1?9:0;break}switch(prop2){case undefined:t2=1;break;case null:t2=1;break;case false:t2=3;break;case true:t2=4;break;case"":t2=5;break;default:t2=prop2===prop2?9:0;break}if(t1!==9||t2!==9){return t1===t2}}cv1=Number(prop1);cv2=Number(prop2);if(cv1===cv1||cv2===cv2){return cv1===cv2}cv1=prop1.toString();cv2=prop2.toString();return cv1==cv2}function ltHelper(prop1,prop2,equal){var cv1,cv2,t1,t2;if(!prop1||!prop2||prop1===true||prop2===true||prop1!==prop1||prop2!==prop2){switch(prop1){case undefined:t1=1;break;case null:t1=1;break;case false:t1=3;break;case true:t1=4;break;case"":t1=5;break;default:t1=prop1===prop1?9:0;break}switch(prop2){case undefined:t2=1;break;case null:t2=1;break;case false:t2=3;break;case true:t2=4;break;case"":t2=5;break;default:t2=prop2===prop2?9:0;break}if(t1!==9||t2!==9){return t1===t2?equal:t1<t2}}cv1=Number(prop1);cv2=Number(prop2);if(cv1===cv1&&cv2===cv2){if(cv1<cv2)return true;if(cv1>cv2)return false;return equal}if(cv1===cv1&&cv2!==cv2){return true}if(cv2===cv2&&cv1!==cv1){return false}if(prop1<prop2)return true;if(prop1>prop2)return false;if(prop1==prop2)return equal;cv1=prop1.toString();cv2=prop2.toString();if(cv1<cv2){return true}if(cv1==cv2){return equal}return false}function gtHelper(prop1,prop2,equal){var cv1,cv2,t1,t2;if(!prop1||!prop2||prop1===true||prop2===true||prop1!==prop1||prop2!==prop2){switch(prop1){case undefined:t1=1;break;case null:t1=1;break;case false:t1=3;break;case true:t1=4;break;case"":t1=5;break;default:t1=prop1===prop1?9:0;break}switch(prop2){case undefined:t2=1;break;case null:t2=1;break;case false:t2=3;break;case true:t2=4;break;case"":t2=5;break;default:t2=prop2===prop2?9:0;break}if(t1!==9||t2!==9){return t1===t2?equal:t1>t2}}cv1=Number(prop1);cv2=Number(prop2);if(cv1===cv1&&cv2===cv2){if(cv1>cv2)return true;if(cv1<cv2)return false;return equal}if(cv1===cv1&&cv2!==cv2){return false}if(cv2===cv2&&cv1!==cv1){return true}if(prop1>prop2)return true;if(prop1<prop2)return false;if(prop1==prop2)return equal;cv1=prop1.toString();cv2=prop2.toString();if(cv1>cv2){return true}if(cv1==cv2){return equal}return false}function sortHelper(prop1,prop2,desc){if(Comparators.aeq(prop1,prop2))return 0;if(Comparators.lt(prop1,prop2,false)){return desc?1:-1}if(Comparators.gt(prop1,prop2,false)){return desc?-1:1}return 0}function compoundeval(properties,obj1,obj2){var res=0;var prop,field,val1,val2,arr,path;for(var i=0,len=properties.length;i<len;i++){prop=properties[i];field=prop[0];if(~field.indexOf(".")){arr=field.split(".");val1=Utils.getIn(obj1,arr,true);val2=Utils.getIn(obj2,arr,true)}else{val1=obj1[field];val2=obj2[field]}res=sortHelper(val1,val2,prop[1]);if(res!==0){return res}}return 0}function dotSubScan(root,paths,fun,value,extra,poffset){var pathOffset=poffset||0;var path=paths[pathOffset];var valueFound=false;var element;if(typeof root==="object"&&path in root){element=root[path]}if(pathOffset+1>=paths.length){valueFound=fun(element,value,extra)}else if(Array.isArray(element)){for(var index=0,len=element.length;index<len;index+=1){valueFound=dotSubScan(element[index],paths,fun,value,extra,pathOffset+1);if(valueFound===true){break}}}else{valueFound=dotSubScan(element,paths,fun,value,extra,pathOffset+1)}return valueFound}function containsCheckFn(a){if(typeof a==="string"||Array.isArray(a)){return function(b){return a.indexOf(b)!==-1}}else if(typeof a==="object"&&a!==null){return function(b){return hasOwnProperty.call(a,b)}}return null}function doQueryOp(val,op,record){for(var p in op){if(hasOwnProperty.call(op,p)){return LokiOps[p](val,op[p],record)}}return false}var LokiOps={$eq:function(a,b){return a===b},$aeq:function(a,b){return a==b},$ne:function(a,b){if(b!==b){return a===a}return a!==b},$dteq:function(a,b){return Comparators.aeq(a,b)},$gt:function(a,b){return Comparators.gt(a,b,false)},$gte:function(a,b){return Comparators.gt(a,b,true)},$lt:function(a,b){return Comparators.lt(a,b,false)},$lte:function(a,b){return Comparators.lt(a,b,true)},$jgt:function(a,b){return a>b},$jgte:function(a,b){return a>=b},$jlt:function(a,b){return a<b},$jlte:function(a,b){return a<=b},$between:function(a,vals){if(a===undefined||a===null)return false;return Comparators.gt(a,vals[0],true)&&Comparators.lt(a,vals[1],true)},$jbetween:function(a,vals){if(a===undefined||a===null)return false;return a>=vals[0]&&a<=vals[1]},$in:function(a,b){return b.indexOf(a)!==-1},$inSet:function(a,b){return b.has(a)},$nin:function(a,b){return b.indexOf(a)===-1},$keyin:function(a,b){return a in b},$nkeyin:function(a,b){return!(a in b)},$definedin:function(a,b){return b[a]!==undefined},$undefinedin:function(a,b){return b[a]===undefined},$regex:function(a,b){return b.test(a)},$containsString:function(a,b){return typeof a==="string"&&a.indexOf(b)!==-1},$containsNone:function(a,b){return!LokiOps.$containsAny(a,b)},$containsAny:function(a,b){var checkFn=containsCheckFn(a);if(checkFn!==null){return Array.isArray(b)?b.some(checkFn):checkFn(b)}return false},$contains:function(a,b){var checkFn=containsCheckFn(a);if(checkFn!==null){return Array.isArray(b)?b.every(checkFn):checkFn(b)}return false},$elemMatch:function(a,b){if(Array.isArray(a)){return a.some(function(item){return Object.keys(b).every(function(property){var filter=b[property];if(!(typeof filter==="object"&&filter)){filter={$eq:filter}}if(property.indexOf(".")!==-1){return dotSubScan(item,property.split("."),doQueryOp,b[property],item)}return doQueryOp(item[property],filter,item)})})}return false},$type:function(a,b,record){var type=typeof a;if(type==="object"){if(Array.isArray(a)){type="array"}else if(a instanceof Date){type="date"}}return typeof b!=="object"?type===b:doQueryOp(type,b,record)},$finite:function(a,b){return b===isFinite(a)},$size:function(a,b,record){if(Array.isArray(a)){return typeof b!=="object"?a.length===b:doQueryOp(a.length,b,record)}return false},$len:function(a,b,record){if(typeof a==="string"){return typeof b!=="object"?a.length===b:doQueryOp(a.length,b,record)}return false},$where:function(a,b){return b(a)===true},$not:function(a,b,record){return!doQueryOp(a,b,record)},$and:function(a,b,record){for(var idx=0,len=b.length;idx<len;idx+=1){if(!doQueryOp(a,b[idx],record)){return false}}return true},$or:function(a,b,record){for(var idx=0,len=b.length;idx<len;idx+=1){if(doQueryOp(a,b[idx],record)){return true}}return false},$exists:function(a,b){if(b){return a!==undefined}else{return a===undefined}}};var valueLevelOps=["$eq","$aeq","$ne","$dteq","$gt","$gte","$lt","$lte","$jgt","$jgte","$jlt","$jlte","$type"];valueLevelOps.forEach(function(op){var fun=LokiOps[op];LokiOps["$"+op]=function(a,spec,record){if(typeof spec==="string"){return fun(a,record[spec])}else if(typeof spec==="function"){return fun(a,spec(record))}else{throw new Error("Invalid argument to $$ matcher")}}});var indexedOps={$eq:LokiOps.$eq,$aeq:true,$dteq:true,$gt:true,$gte:true,$lt:true,$lte:true,$in:true,$between:true};function clone(data,method){if(data===null||data===undefined){return null}var cloneMethod=method||"parse-stringify",cloned;switch(cloneMethod){case"parse-stringify":cloned=JSON.parse(JSON.stringify(data));break;case"jquery-extend-deep":cloned=jQuery.extend(true,{},data);break;case"shallow":cloned=Object.create(data.constructor.prototype);Object.keys(data).map(function(i){cloned[i]=data[i]});break;case"shallow-assign":cloned=Object.create(data.constructor.prototype);Object.assign(cloned,data);break;case"shallow-recurse-objects":cloned=clone(data,"shallow");var keys=Object.keys(data);keys.forEach(function(key){if(typeof data[key]==="object"&&data[key].constructor.name==="Object"){cloned[key]=clone(data[key],"shallow-recurse-objects")}else if(Array.isArray(data[key])){cloned[key]=cloneObjectArray(data[key],"shallow-recurse-objects")}});break;default:break}return cloned}function cloneObjectArray(objarray,method){if(method=="parse-stringify"){return clone(objarray,method)}var result=[];for(var i=0,len=objarray.length;i<len;i++){result[i]=clone(objarray[i],method)}return result}function localStorageAvailable(){try{return window&&window.localStorage!==undefined&&window.localStorage!==null}catch(e){return false}}function LokiEventEmitter(){}LokiEventEmitter.prototype.events={};LokiEventEmitter.prototype.asyncListeners=false;LokiEventEmitter.prototype.on=function(eventName,listener){var event;var self=this;if(Array.isArray(eventName)){eventName.forEach(function(currentEventName){self.on(currentEventName,listener)});return listener}event=this.events[eventName];if(!event){event=this.events[eventName]=[]}event.push(listener);return listener};LokiEventEmitter.prototype.emit=function(eventName){var self=this;var selfArgs;if(eventName&&this.events[eventName]){if(this.events[eventName].length){selfArgs=Array.prototype.slice.call(arguments,1);this.events[eventName].forEach(function(listener){if(self.asyncListeners){setTimeout(function(){listener.apply(self,selfArgs)},1)}else{listener.apply(self,selfArgs)}})}}else{throw new Error("No event "+eventName+" defined")}};LokiEventEmitter.prototype.addListener=LokiEventEmitter.prototype.on;LokiEventEmitter.prototype.removeListener=function(eventName,listener){var self=this;if(Array.isArray(eventName)){eventName.forEach(function(currentEventName){self.removeListener(currentEventName,listener)});return}if(this.events[eventName]){var listeners=this.events[eventName];listeners.splice(listeners.indexOf(listener),1)}};function Loki(filename,options){this.filename=filename||"loki.db";this.collections=[];this.databaseVersion=1.5;this.engineVersion=1.5;this.autosave=false;this.autosaveInterval=5e3;this.autosaveHandle=null;this.throttledSaves=true;this.options={};this.persistenceMethod=null;this.persistenceAdapter=null;this.throttledSavePending=false;this.throttledCallbacks=[];this.verbose=options&&options.hasOwnProperty("verbose")?options.verbose:false;this.events={init:[],loaded:[],flushChanges:[],close:[],changes:[],warning:[]};var getENV=function(){if(typeof global!=="undefined"&&(global.android||global.NSObject)){return"NATIVESCRIPT"}if(typeof window==="undefined"){return"NODEJS"}if(typeof global!=="undefined"&&global.window&&typeof process!=="undefined"){return"NODEJS"}if(typeof document!=="undefined"){if(document.URL.indexOf("http://")===-1&&document.URL.indexOf("https://")===-1){return"CORDOVA"}return"BROWSER"}return"CORDOVA"};if(options&&options.hasOwnProperty("env")){this.ENV=options.env}else{this.ENV=getENV()}if(this.ENV==="undefined"){this.ENV="NODEJS"}this.configureOptions(options,true);this.on("init",this.clearChanges)}Loki.prototype=new LokiEventEmitter;Loki.prototype.constructor=Loki;Loki.prototype.getIndexedAdapter=function(){var adapter;if(typeof require==="function"){adapter=require("./loki-indexed-adapter.js")}return adapter};Loki.prototype.configureOptions=function(options,initialConfig){var defaultPersistence={NODEJS:"fs",BROWSER:"localStorage",CORDOVA:"localStorage",MEMORY:"memory"},persistenceMethods={fs:LokiFsAdapter,localStorage:LokiLocalStorageAdapter,memory:LokiMemoryAdapter};this.options={};this.persistenceMethod=null;this.persistenceAdapter=null;if(typeof options!=="undefined"){this.options=options;if(this.options.hasOwnProperty("persistenceMethod")){if(typeof persistenceMethods[options.persistenceMethod]=="function"){this.persistenceMethod=options.persistenceMethod;this.persistenceAdapter=new persistenceMethods[options.persistenceMethod]}}if(this.options.hasOwnProperty("adapter")){this.persistenceMethod="adapter";this.persistenceAdapter=options.adapter;this.options.adapter=null;this.isIncremental=this.persistenceAdapter.mode==="incremental"}if(options.autoload&&initialConfig){var self=this;setTimeout(function(){self.loadDatabase(options,options.autoloadCallback)},1)}if(this.options.hasOwnProperty("autosaveInterval")){this.autosaveDisable();this.autosaveInterval=parseInt(this.options.autosaveInterval,10)}if(this.options.hasOwnProperty("autosave")&&this.options.autosave){this.autosaveDisable();this.autosave=true;if(this.options.hasOwnProperty("autosaveCallback")){this.autosaveEnable(options,options.autosaveCallback)}else{this.autosaveEnable()}}if(this.options.hasOwnProperty("throttledSaves")){this.throttledSaves=this.options.throttledSaves}}if(!this.options.hasOwnProperty("serializationMethod")){this.options.serializationMethod="normal"}if(!this.options.hasOwnProperty("destructureDelimiter")){this.options.destructureDelimiter="$<\n"}if(this.persistenceAdapter===null){this.persistenceMethod=defaultPersistence[this.ENV];if(this.persistenceMethod){this.persistenceAdapter=new persistenceMethods[this.persistenceMethod]}}};Loki.prototype.copy=function(options){var databaseCopy=new Loki(this.filename,{env:"NA"});var clen,idx;options=options||{};databaseCopy.loadJSONObject(this,{retainDirtyFlags:true});if(options.hasOwnProperty("removeNonSerializable")&&options.removeNonSerializable===true){databaseCopy.autosaveHandle=null;databaseCopy.persistenceAdapter=null;clen=databaseCopy.collections.length;for(idx=0;idx<clen;idx++){databaseCopy.collections[idx].constraints=null;databaseCopy.collections[idx].ttl=null}}return databaseCopy};Loki.prototype.addCollection=function(name,options){var i,len=this.collections.length;if(options&&options.disableMeta===true){if(options.disableChangesApi===false){throw new Error("disableMeta option cannot be passed as true when disableChangesApi is passed as false")}if(options.disableDeltaChangesApi===false){throw new Error("disableMeta option cannot be passed as true when disableDeltaChangesApi is passed as false")}if(typeof options.ttl==="number"&&options.ttl>0){throw new Error("disableMeta option cannot be passed as true when ttl is enabled")}}for(i=0;i<len;i+=1){if(this.collections[i].name===name){return this.collections[i]}}var collection=new Collection(name,options);collection.isIncremental=this.isIncremental;this.collections.push(collection);if(this.verbose)collection.lokiConsoleWrapper=console;return collection};Loki.prototype.loadCollection=function(collection){if(!collection.name){throw new Error("Collection must have a name property to be loaded")}this.collections.push(collection)};Loki.prototype.getCollection=function(collectionName){var i,len=this.collections.length;for(i=0;i<len;i+=1){if(this.collections[i].name===collectionName){return this.collections[i]}}this.emit("warning","collection "+collectionName+" not found");return null};Loki.prototype.renameCollection=function(oldName,newName){var c=this.getCollection(oldName);if(c){c.name=newName}return c};Loki.prototype.listCollections=function(){var i=this.collections.length,colls=[];while(i--){colls.push({name:this.collections[i].name,type:this.collections[i].objType,count:this.collections[i].data.length})}return colls};Loki.prototype.removeCollection=function(collectionName){var i,len=this.collections.length;for(i=0;i<len;i+=1){if(this.collections[i].name===collectionName){var tmpcol=new Collection(collectionName,{});var curcol=this.collections[i];for(var prop in curcol){if(curcol.hasOwnProperty(prop)&&tmpcol.hasOwnProperty(prop)){curcol[prop]=tmpcol[prop]}}this.collections.splice(i,1);return}}};Loki.prototype.getName=function(){return this.name};Loki.prototype.serializeReplacer=function(key,value){switch(key){case"autosaveHandle":case"persistenceAdapter":case"constraints":case"ttl":return null;case"throttledSavePending":case"throttledCallbacks":return undefined;case"lokiConsoleWrapper":return null;default:return value}};Loki.prototype.serialize=function(options){options=options||{};if(!options.hasOwnProperty("serializationMethod")){options.serializationMethod=this.options.serializationMethod}switch(options.serializationMethod){case"normal":return JSON.stringify(this,this.serializeReplacer);case"pretty":return JSON.stringify(this,this.serializeReplacer,2);case"destructured":return this.serializeDestructured();default:return JSON.stringify(this,this.serializeReplacer)}};Loki.prototype.toJson=Loki.prototype.serialize;Loki.prototype.serializeDestructured=function(options){var idx,sidx,result,resultlen;var reconstruct=[];var dbcopy;options=options||{};if(!options.hasOwnProperty("partitioned")){options.partitioned=false}if(!options.hasOwnProperty("delimited")){options.delimited=true}if(!options.hasOwnProperty("delimiter")){options.delimiter=this.options.destructureDelimiter}if(options.partitioned===true&&options.hasOwnProperty("partition")&&options.partition>=0){return this.serializeCollection({delimited:options.delimited,delimiter:options.delimiter,collectionIndex:options.partition})}dbcopy=new Loki(this.filename);dbcopy.loadJSONObject(this);for(idx=0;idx<dbcopy.collections.length;idx++){dbcopy.collections[idx].data=[]}if(options.partitioned===true&&options.partition===-1){return dbcopy.serialize({serializationMethod:"normal"})}reconstruct.push(dbcopy.serialize({serializationMethod:"normal"}));dbcopy=null;for(idx=0;idx<this.collections.length;idx++){result=this.serializeCollection({delimited:options.delimited,delimiter:options.delimiter,collectionIndex:idx});if(options.partitioned===false&&options.delimited===false){if(!Array.isArray(result)){throw new Error("a nondelimited, non partitioned collection serialization did not return an expected array")}resultlen=result.length;for(sidx=0;sidx<resultlen;sidx++){reconstruct.push(result[sidx]);result[sidx]=null}reconstruct.push("")}else{reconstruct.push(result)}}if(options.partitioned){if(options.delimited){return reconstruct}else{return reconstruct}}else{if(options.delimited){reconstruct.push("");return reconstruct.join(options.delimiter)}else{reconstruct.push("");return reconstruct}}reconstruct.push("");return reconstruct.join(delim)};Loki.prototype.serializeCollection=function(options){var doccount,docidx,resultlines=[];options=options||{};if(!options.hasOwnProperty("delimited")){options.delimited=true}if(!options.hasOwnProperty("collectionIndex")){throw new Error("serializeCollection called without 'collectionIndex' option")}doccount=this.collections[options.collectionIndex].data.length;resultlines=[];for(docidx=0;docidx<doccount;docidx++){resultlines.push(JSON.stringify(this.collections[options.collectionIndex].data[docidx]))}if(options.delimited){resultlines.push("");return resultlines.join(options.delimiter)}else{return resultlines}};Loki.prototype.deserializeDestructured=function(destructuredSource,options){var workarray=[];var len,cdb;var idx,collIndex=0,collCount,lineIndex=1,done=false;var currLine,currObject;options=options||{};if(!options.hasOwnProperty("partitioned")){options.partitioned=false}if(!options.hasOwnProperty("delimited")){options.delimited=true}if(!options.hasOwnProperty("delimiter")){options.delimiter=this.options.destructureDelimiter}if(options.partitioned){if(options.hasOwnProperty("partition")){if(options.partition===-1){cdb=JSON.parse(destructuredSource[0]);return cdb}return this.deserializeCollection(destructuredSource[options.partition+1],options)}cdb=JSON.parse(destructuredSource[0]);collCount=cdb.collections.length;for(collIndex=0;collIndex<collCount;collIndex++){cdb.collections[collIndex].data=this.deserializeCollection(destructuredSource[collIndex+1],options)}return cdb}if(options.delimited){workarray=destructuredSource.split(options.delimiter);destructuredSource=null;len=workarray.length;if(len===0){return null}}else{workarray=destructuredSource}cdb=JSON.parse(workarray[0]);collCount=cdb.collections.length;workarray[0]=null;while(!done){currLine=workarray[lineIndex];if(workarray[lineIndex]===""){if(++collIndex>collCount){done=true}}else{currObject=JSON.parse(workarray[lineIndex]);cdb.collections[collIndex].data.push(currObject)}workarray[lineIndex++]=null}return cdb};Loki.prototype.deserializeCollection=function(destructuredSource,options){var workarray=[];var idx,len;options=options||{};if(!options.hasOwnProperty("partitioned")){options.partitioned=false}if(!options.hasOwnProperty("delimited")){options.delimited=true}if(!options.hasOwnProperty("delimiter")){options.delimiter=this.options.destructureDelimiter}if(options.delimited){workarray=destructuredSource.split(options.delimiter);workarray.pop()}else{workarray=destructuredSource}len=workarray.length;for(idx=0;idx<len;idx++){workarray[idx]=JSON.parse(workarray[idx])}return workarray};Loki.prototype.loadJSON=function(serializedDb,options){var dbObject;if(serializedDb.length===0){dbObject={}}else{switch(this.options.serializationMethod){case"normal":case"pretty":dbObject=JSON.parse(serializedDb);break;case"destructured":dbObject=this.deserializeDestructured(serializedDb);break;default:dbObject=JSON.parse(serializedDb);break}}this.loadJSONObject(dbObject,options)};Loki.prototype.loadJSONObject=function(dbObject,options){var i=0,len=dbObject.collections?dbObject.collections.length:0,coll,copyColl,clen,j,loader,collObj;this.name=dbObject.name;if(dbObject.hasOwnProperty("throttledSaves")&&options&&!options.hasOwnProperty("throttledSaves")){this.throttledSaves=dbObject.throttledSaves}this.collections=[];function makeLoader(coll){var collOptions=options[coll.name];var inflater;if(collOptions.proto){inflater=collOptions.inflate||Utils.copyProperties;return function(data){var collObj=new collOptions.proto;inflater(data,collObj);return collObj}}return collOptions.inflate}for(i;i<len;i+=1){coll=dbObject.collections[i];copyColl=this.addCollection(coll.name,{disableChangesApi:coll.disableChangesApi,disableDeltaChangesApi:coll.disableDeltaChangesApi,disableMeta:coll.disableMeta,disableFreeze:coll.hasOwnProperty("disableFreeze")?coll.disableFreeze:true});copyColl.adaptiveBinaryIndices=coll.hasOwnProperty("adaptiveBinaryIndices")?coll.adaptiveBinaryIndices===true:false;copyColl.transactional=coll.transactional;copyColl.asyncListeners=coll.asyncListeners;copyColl.cloneObjects=coll.cloneObjects;copyColl.cloneMethod=coll.cloneMethod||"parse-stringify";copyColl.autoupdate=coll.autoupdate;copyColl.changes=coll.changes;copyColl.dirtyIds=coll.dirtyIds||[];if(options&&options.retainDirtyFlags===true){copyColl.dirty=coll.dirty}else{copyColl.dirty=false}clen=coll.data.length;j=0;if(options&&options.hasOwnProperty(coll.name)){loader=makeLoader(coll);for(j;j<clen;j++){collObj=loader(coll.data[j]);copyColl.data[j]=collObj;copyColl.addAutoUpdateObserver(collObj);if(!copyColl.disableFreeze){deepFreeze(copyColl.data[j])}}}else{for(j;j<clen;j++){copyColl.data[j]=coll.data[j];copyColl.addAutoUpdateObserver(copyColl.data[j]);if(!copyColl.disableFreeze){deepFreeze(copyColl.data[j])}}}copyColl.maxId=typeof coll.maxId==="undefined"?0:coll.maxId;if(typeof coll.binaryIndices!=="undefined"){copyColl.binaryIndices=coll.binaryIndices}if(typeof coll.transforms!=="undefined"){copyColl.transforms=coll.transforms}copyColl.uniqueNames=[];if(coll.hasOwnProperty("uniqueNames")){copyColl.uniqueNames=coll.uniqueNames}if(typeof coll.DynamicViews==="undefined")continue;for(var idx=0;idx<coll.DynamicViews.length;idx++){var colldv=coll.DynamicViews[idx];var dv=copyColl.addDynamicView(colldv.name,colldv.options);dv.resultdata=colldv.resultdata;dv.resultsdirty=colldv.resultsdirty;dv.filterPipeline=colldv.filterPipeline;dv.sortCriteriaSimple=colldv.sortCriteriaSimple;dv.sortCriteria=colldv.sortCriteria;dv.sortFunction=null;dv.sortDirty=colldv.sortDirty;if(!copyColl.disableFreeze){deepFreeze(dv.filterPipeline);if(dv.sortCriteriaSimple){deepFreeze(dv.sortCriteriaSimple)}else if(dv.sortCriteria){deepFreeze(dv.sortCriteria)}}dv.resultset.filteredrows=colldv.resultset.filteredrows;dv.resultset.filterInitialized=colldv.resultset.filterInitialized;dv.rematerialize({removeWhereFilters:true})}if(dbObject.databaseVersion<1.5){copyColl.ensureAllIndexes(true);copyColl.dirty=true}}};Loki.prototype.close=function(callback){if(this.autosave){this.autosaveDisable();if(this.autosaveDirty()){this.saveDatabase(callback);callback=undefined}}if(callback){this.on("close",callback)}this.emit("close")};Loki.prototype.generateChangesNotification=function(arrayOfCollectionNames){function getCollName(coll){return coll.name}var changes=[],selectedCollections=arrayOfCollectionNames||this.collections.map(getCollName);this.collections.forEach(function(coll){if(selectedCollections.indexOf(getCollName(coll))!==-1){changes=changes.concat(coll.getChanges())}});return changes};Loki.prototype.serializeChanges=function(collectionNamesArray){return JSON.stringify(this.generateChangesNotification(collectionNamesArray))};Loki.prototype.clearChanges=function(){this.collections.forEach(function(coll){if(coll.flushChanges){coll.flushChanges()}})};function LokiMemoryAdapter(options){this.hashStore={};this.options=options||{};if(!this.options.hasOwnProperty("asyncResponses")){this.options.asyncResponses=false}if(!this.options.hasOwnProperty("asyncTimeout")){this.options.asyncTimeout=50}}LokiMemoryAdapter.prototype.loadDatabase=function(dbname,callback){var self=this;if(this.options.asyncResponses){setTimeout(function(){if(self.hashStore.hasOwnProperty(dbname)){callback(self.hashStore[dbname].value)}else{callback(null)}},this.options.asyncTimeout)}else{if(this.hashStore.hasOwnProperty(dbname)){callback(this.hashStore[dbname].value)}else{callback(null)}}};LokiMemoryAdapter.prototype.saveDatabase=function(dbname,dbstring,callback){var self=this;var saveCount;if(this.options.asyncResponses){setTimeout(function(){saveCount=self.hashStore.hasOwnProperty(dbname)?self.hashStore[dbname].savecount:0;self.hashStore[dbname]={savecount:saveCount+1,lastsave:new Date,value:dbstring};callback()},this.options.asyncTimeout)}else{saveCount=this.hashStore.hasOwnProperty(dbname)?this.hashStore[dbname].savecount:0;this.hashStore[dbname]={savecount:saveCount+1,lastsave:new Date,value:dbstring};callback()}};LokiMemoryAdapter.prototype.deleteDatabase=function(dbname,callback){if(this.hashStore.hasOwnProperty(dbname)){delete this.hashStore[dbname]}if(typeof callback==="function"){callback()}};function LokiPartitioningAdapter(adapter,options){this.mode="reference";this.adapter=null;this.options=options||{};this.dbref=null;this.dbname="";this.pageIterator={};if(adapter){if(adapter.mode==="reference"){throw new Error("LokiPartitioningAdapter cannot be instantiated with a reference mode adapter")}else{this.adapter=adapter}}else{throw new Error("LokiPartitioningAdapter requires a (non-reference mode) adapter on construction")}if(!this.options.hasOwnProperty("paging")){this.options.paging=false}if(!this.options.hasOwnProperty("pageSize")){this.options.pageSize=25*1024*1024}if(!this.options.hasOwnProperty("delimiter")){this.options.delimiter="$<\n"}}LokiPartitioningAdapter.prototype.loadDatabase=function(dbname,callback){var self=this;this.dbname=dbname;this.dbref=new Loki(dbname);this.adapter.loadDatabase(dbname,function(result){if(!result){callback(result);return}if(typeof result!=="string"){callback(new Error("LokiPartitioningAdapter received an unexpected response from inner adapter loadDatabase()"))}var db=JSON.parse(result);self.dbref.loadJSONObject(db);db=null;var clen=self.dbref.collections.length;if(self.dbref.collections.length===0){callback(self.dbref);return}self.pageIterator={collection:0,pageIndex:0};self.loadNextPartition(0,function(){callback(self.dbref)})})};LokiPartitioningAdapter.prototype.loadNextPartition=function(partition,callback){var keyname=this.dbname+"."+partition;var self=this;if(this.options.paging===true){this.pageIterator.pageIndex=0;this.loadNextPage(callback);return}this.adapter.loadDatabase(keyname,function(result){var data=self.dbref.deserializeCollection(result,{delimited:true,collectionIndex:partition});self.dbref.collections[partition].data=data;if(++partition<self.dbref.collections.length){self.loadNextPartition(partition,callback)}else{callback()}})};LokiPartitioningAdapter.prototype.loadNextPage=function(callback){var keyname=this.dbname+"."+this.pageIterator.collection+"."+this.pageIterator.pageIndex;var self=this;this.adapter.loadDatabase(keyname,function(result){var data=result.split(self.options.delimiter);result="";var dlen=data.length;var idx;var isLastPage=data[dlen-1]==="";if(isLastPage){data.pop();dlen=data.length;if(data[dlen-1]===""&&dlen===1){data.pop();dlen=data.length}}for(idx=0;idx<dlen;idx++){self.dbref.collections[self.pageIterator.collection].data.push(JSON.parse(data[idx]));data[idx]=null}data=[];if(isLastPage){if(++self.pageIterator.collection<self.dbref.collections.length){self.loadNextPartition(self.pageIterator.collection,callback)}else{callback()}}else{self.pageIterator.pageIndex++;self.loadNextPage(callback)}})};LokiPartitioningAdapter.prototype.exportDatabase=function(dbname,dbref,callback){var self=this;var idx,clen=dbref.collections.length;this.dbref=dbref;this.dbname=dbname;this.dirtyPartitions=[-1];for(idx=0;idx<clen;idx++){if(dbref.collections[idx].dirty){this.dirtyPartitions.push(idx)}}this.saveNextPartition(function(err){callback(err)})};LokiPartitioningAdapter.prototype.saveNextPartition=function(callback){var self=this;var partition=this.dirtyPartitions.shift();var keyname=this.dbname+(partition===-1?"":"."+partition);if(this.options.paging&&partition!==-1){this.pageIterator={collection:partition,docIndex:0,pageIndex:0};this.saveNextPage(function(err){if(self.dirtyPartitions.length===0){callback(err)}else{self.saveNextPartition(callback)}});return}var result=this.dbref.serializeDestructured({partitioned:true,delimited:true,partition:partition});this.adapter.saveDatabase(keyname,result,function(err){if(err){callback(err);return}if(self.dirtyPartitions.length===0){callback(null)}else{self.saveNextPartition(callback)}})};LokiPartitioningAdapter.prototype.saveNextPage=function(callback){var self=this;var coll=this.dbref.collections[this.pageIterator.collection];var keyname=this.dbname+"."+this.pageIterator.collection+"."+this.pageIterator.pageIndex
;var pageLen=0,cdlen=coll.data.length,delimlen=this.options.delimiter.length;var serializedObject="",pageBuilder="";var doneWithPartition=false,doneWithPage=false;var pageSaveCallback=function(err){pageBuilder="";if(err){callback(err)}if(doneWithPartition){callback(null)}else{self.pageIterator.pageIndex++;self.saveNextPage(callback)}};if(coll.data.length===0){doneWithPartition=true}while(true){if(!doneWithPartition){serializedObject=JSON.stringify(coll.data[this.pageIterator.docIndex]);pageBuilder+=serializedObject;pageLen+=serializedObject.length;if(++this.pageIterator.docIndex>=cdlen)doneWithPartition=true}if(pageLen>=this.options.pageSize)doneWithPage=true;if(!doneWithPage||doneWithPartition){pageBuilder+=this.options.delimiter;pageLen+=delimlen}if(doneWithPartition||doneWithPage){this.adapter.saveDatabase(keyname,pageBuilder,pageSaveCallback);return}}};function LokiFsAdapter(){try{this.fs=require("fs")}catch(e){this.fs=null}}LokiFsAdapter.prototype.loadDatabase=function loadDatabase(dbname,callback){var self=this;this.fs.stat(dbname,function(err,stats){if(!err&&stats.isFile()){self.fs.readFile(dbname,{encoding:"utf8"},function readFileCallback(err,data){if(err){callback(new Error(err))}else{callback(data)}})}else{callback(null)}})};LokiFsAdapter.prototype.saveDatabase=function saveDatabase(dbname,dbstring,callback){var self=this;var tmpdbname=dbname+"~";this.fs.writeFile(tmpdbname,dbstring,function writeFileCallback(err){if(err){callback(new Error(err))}else{self.fs.rename(tmpdbname,dbname,callback)}})};LokiFsAdapter.prototype.deleteDatabase=function deleteDatabase(dbname,callback){this.fs.unlink(dbname,function deleteDatabaseCallback(err){if(err){callback(new Error(err))}else{callback()}})};function LokiLocalStorageAdapter(){}LokiLocalStorageAdapter.prototype.loadDatabase=function loadDatabase(dbname,callback){if(localStorageAvailable()){callback(localStorage.getItem(dbname))}else{callback(new Error("localStorage is not available"))}};LokiLocalStorageAdapter.prototype.saveDatabase=function saveDatabase(dbname,dbstring,callback){if(localStorageAvailable()){localStorage.setItem(dbname,dbstring);callback(null)}else{callback(new Error("localStorage is not available"))}};LokiLocalStorageAdapter.prototype.deleteDatabase=function deleteDatabase(dbname,callback){if(localStorageAvailable()){localStorage.removeItem(dbname);callback(null)}else{callback(new Error("localStorage is not available"))}};Loki.prototype.throttledSaveDrain=function(callback,options){var self=this;var now=(new Date).getTime();if(!this.throttledSaves){callback(true)}options=options||{};if(!options.hasOwnProperty("recursiveWait")){options.recursiveWait=true}if(!options.hasOwnProperty("recursiveWaitLimit")){options.recursiveWaitLimit=false}if(!options.hasOwnProperty("recursiveWaitLimitDuration")){options.recursiveWaitLimitDuration=2e3}if(!options.hasOwnProperty("started")){options.started=(new Date).getTime()}if(this.throttledSaves&&this.throttledSavePending){if(options.recursiveWait){this.throttledCallbacks.push(function(){if(self.throttledSavePending){if(options.recursiveWaitLimit&&now-options.started>options.recursiveWaitLimitDuration){callback(false);return}self.throttledSaveDrain(callback,options);return}else{callback(true);return}})}else{this.throttledCallbacks.push(callback);return}}else{callback(true)}};Loki.prototype.loadDatabaseInternal=function(options,callback){var cFun=callback||function(err,data){if(err){throw err}},self=this;if(this.persistenceAdapter!==null){this.persistenceAdapter.loadDatabase(this.filename,function loadDatabaseCallback(dbString){if(typeof dbString==="string"){var parseSuccess=false;try{self.loadJSON(dbString,options||{});parseSuccess=true}catch(err){cFun(err)}if(parseSuccess){cFun(null);self.emit("loaded","database "+self.filename+" loaded")}}else{if(!dbString){cFun(null);self.emit("loaded","empty database "+self.filename+" loaded");return}if(dbString instanceof Error){cFun(dbString);return}if(typeof dbString==="object"){self.loadJSONObject(dbString,options||{});cFun(null);self.emit("loaded","database "+self.filename+" loaded");return}cFun("unexpected adapter response : "+dbString)}})}else{cFun(new Error("persistenceAdapter not configured"))}};Loki.prototype.loadDatabase=function(options,callback){var self=this;if(!this.throttledSaves){this.loadDatabaseInternal(options,callback);return}this.throttledSaveDrain(function(success){if(success){self.throttledSavePending=true;self.loadDatabaseInternal(options,function(err){if(self.throttledCallbacks.length===0){self.throttledSavePending=false}else{self.saveDatabase()}if(typeof callback==="function"){callback(err)}});return}else{if(typeof callback==="function"){callback(new Error("Unable to pause save throttling long enough to read database"))}}},options)};Loki.prototype.saveDatabaseInternal=function(callback){var cFun=callback||function(err){if(err){throw err}return};var self=this;if(!this.persistenceAdapter){cFun(new Error("persistenceAdapter not configured"));return}if(this.persistenceAdapter.mode==="incremental"){var cachedDirty;this.ignoreAutosave=true;this.persistenceAdapter.saveDatabase(this.filename,function getLokiCopy(){self.ignoreAutosave=false;if(cachedDirty){cFun(new Error("adapter error - getLokiCopy called more than once"));return}var lokiCopy=self.copy({removeNonSerializable:true});cachedDirty=self.collections.map(function(collection){return[collection.dirty,collection.dirtyIds]});self.collections.forEach(function(col){col.dirty=false;col.dirtyIds=[]});return lokiCopy},function exportDatabaseCallback(err){self.ignoreAutosave=false;if(err&&cachedDirty){self.collections.forEach(function(col,i){var cached=cachedDirty[i];col.dirty=col.dirty||cached[0];col.dirtyIds=col.dirtyIds.concat(cached[1])})}cFun(err)})}else if(this.persistenceAdapter.mode==="reference"&&typeof this.persistenceAdapter.exportDatabase==="function"){this.persistenceAdapter.exportDatabase(this.filename,this.copy({removeNonSerializable:true}),function exportDatabaseCallback(err){self.autosaveClearFlags();cFun(err)})}else{this.autosaveClearFlags();this.persistenceAdapter.saveDatabase(this.filename,this.serialize(),function saveDatabasecallback(err){cFun(err)})}};Loki.prototype.saveDatabase=function(callback){if(!this.throttledSaves){this.saveDatabaseInternal(callback);return}if(this.throttledSavePending){this.throttledCallbacks.push(callback);return}var localCallbacks=this.throttledCallbacks;this.throttledCallbacks=[];localCallbacks.unshift(callback);this.throttledSavePending=true;var self=this;this.saveDatabaseInternal(function(err){self.throttledSavePending=false;localCallbacks.forEach(function(pcb){if(typeof pcb==="function"){setTimeout(function(){pcb(err)},1)}});if(self.throttledCallbacks.length>0){self.saveDatabase()}})};Loki.prototype.save=Loki.prototype.saveDatabase;Loki.prototype.deleteDatabase=function(options,callback){var cFun=callback||function(err,data){if(err){throw err}};if(typeof options==="function"&&!callback){cFun=options}if(this.persistenceAdapter!==null){this.persistenceAdapter.deleteDatabase(this.filename,function deleteDatabaseCallback(err){cFun(err)})}else{cFun(new Error("persistenceAdapter not configured"))}};Loki.prototype.autosaveDirty=function(){for(var idx=0;idx<this.collections.length;idx++){if(this.collections[idx].dirty){return true}}return false};Loki.prototype.autosaveClearFlags=function(){for(var idx=0;idx<this.collections.length;idx++){this.collections[idx].dirty=false}};Loki.prototype.autosaveEnable=function(options,callback){this.autosave=true;var delay=5e3,self=this;if(typeof this.autosaveInterval!=="undefined"&&this.autosaveInterval!==null){delay=this.autosaveInterval}this.autosaveHandle=setInterval(function autosaveHandleInterval(){if(self.autosaveDirty()&&!self.ignoreAutosave){self.saveDatabase(callback)}},delay)};Loki.prototype.autosaveDisable=function(){if(typeof this.autosaveHandle!=="undefined"&&this.autosaveHandle!==null){clearInterval(this.autosaveHandle);this.autosaveHandle=null}};function Resultset(collection,options){options=options||{};this.collection=collection;this.filteredrows=[];this.filterInitialized=false;return this}Resultset.prototype.reset=function(){if(this.filteredrows.length>0){this.filteredrows=[]}this.filterInitialized=false;return this};Resultset.prototype.toJSON=function(){var copy=this.copy();copy.collection=null;return copy};Resultset.prototype.limit=function(qty){if(!this.filterInitialized&&this.filteredrows.length===0){this.filteredrows=this.collection.prepareFullDocIndex()}var rscopy=new Resultset(this.collection);rscopy.filteredrows=this.filteredrows.slice(0,qty);rscopy.filterInitialized=true;return rscopy};Resultset.prototype.offset=function(pos){if(!this.filterInitialized&&this.filteredrows.length===0){this.filteredrows=this.collection.prepareFullDocIndex()}var rscopy=new Resultset(this.collection);rscopy.filteredrows=this.filteredrows.slice(pos);rscopy.filterInitialized=true;return rscopy};Resultset.prototype.copy=function(){var result=new Resultset(this.collection);if(this.filteredrows.length>0){result.filteredrows=this.filteredrows.slice()}result.filterInitialized=this.filterInitialized;return result};Resultset.prototype.branch=Resultset.prototype.copy;Resultset.prototype.transform=function(transform,parameters){var idx,step,rs=this;if(typeof transform==="string"){if(this.collection.transforms.hasOwnProperty(transform)){transform=this.collection.transforms[transform]}}if(typeof transform!=="object"||!Array.isArray(transform)){throw new Error("Invalid transform")}if(typeof parameters!=="undefined"){transform=Utils.resolveTransformParams(transform,parameters)}for(idx=0;idx<transform.length;idx++){step=transform[idx];switch(step.type){case"find":rs.find(step.value);break;case"where":rs.where(step.value);break;case"simplesort":rs.simplesort(step.property,step.desc||step.options);break;case"compoundsort":rs.compoundsort(step.value);break;case"sort":rs.sort(step.value);break;case"limit":rs=rs.limit(step.value);break;case"offset":rs=rs.offset(step.value);break;case"map":rs=rs.map(step.value,step.dataOptions);break;case"eqJoin":rs=rs.eqJoin(step.joinData,step.leftJoinKey,step.rightJoinKey,step.mapFun,step.dataOptions);break;case"mapReduce":rs=rs.mapReduce(step.mapFunction,step.reduceFunction);break;case"update":rs.update(step.value);break;case"remove":rs.remove();break;default:break}}return rs};Resultset.prototype.sort=function(comparefun){if(!this.filterInitialized&&this.filteredrows.length===0){this.filteredrows=this.collection.prepareFullDocIndex()}var wrappedComparer=function(userComparer,data){return function(a,b){return userComparer(data[a],data[b])}}(comparefun,this.collection.data);this.filteredrows.sort(wrappedComparer);return this};Resultset.prototype.simplesort=function(propname,options){var eff,targetEff=10,dc=this.collection.data.length,frl=this.filteredrows.length,hasBinaryIndex=this.collection.binaryIndices.hasOwnProperty(propname);if(typeof options==="undefined"||options===false){options={desc:false}}if(options===true){options={desc:true}}if(frl===0){if(this.filterInitialized){return this}if(this.collection.binaryIndices.hasOwnProperty(propname)){this.collection.ensureIndex(propname);this.filteredrows=this.collection.binaryIndices[propname].values.slice(0);if(options.desc){this.filteredrows.reverse()}return this}else{this.filteredrows=this.collection.prepareFullDocIndex()}}else{if(!options.disableIndexIntersect&&hasBinaryIndex){eff=dc/frl;if(options.useJavascriptSorting){targetEff=6}if(eff<=targetEff||options.forceIndexIntersect){var idx,fr=this.filteredrows;var io={};for(idx=0;idx<frl;idx++){io[fr[idx]]=true}var pv=this.collection.binaryIndices[propname].values;this.filteredrows=pv.filter(function(n){return io[n]});if(options.desc){this.filteredrows.reverse()}return this}}}if(options.useJavascriptSorting){return this.sort(function(obj1,obj2){if(obj1[propname]===obj2[propname])return 0;if(obj1[propname]>obj2[propname])return 1;if(obj1[propname]<obj2[propname])return-1})}var wrappedComparer=function(prop,desc,data){var val1,val2,arr;return function(a,b){if(~prop.indexOf(".")){arr=prop.split(".");val1=Utils.getIn(data[a],arr,true);val2=Utils.getIn(data[b],arr,true)}else{val1=data[a][prop];val2=data[b][prop]}return sortHelper(val1,val2,desc)}}(propname,options.desc,this.collection.data);this.filteredrows.sort(wrappedComparer);return this};Resultset.prototype.compoundsort=function(properties){if(properties.length===0){throw new Error("Invalid call to compoundsort, need at least one property")}var prop;if(properties.length===1){prop=properties[0];if(Array.isArray(prop)){return this.simplesort(prop[0],prop[1])}return this.simplesort(prop,false)}for(var i=0,len=properties.length;i<len;i+=1){prop=properties[i];if(!Array.isArray(prop)){properties[i]=[prop,false]}}if(!this.filterInitialized&&this.filteredrows.length===0){this.filteredrows=this.collection.prepareFullDocIndex()}var wrappedComparer=function(props,data){return function(a,b){return compoundeval(props,data[a],data[b])}}(properties,this.collection.data);this.filteredrows.sort(wrappedComparer);return this};Resultset.prototype.findOr=function(expressionArray){var fr=null,fri=0,frlen=0,docset=[],idxset=[],idx=0,origCount=this.count();for(var ei=0,elen=expressionArray.length;ei<elen;ei++){fr=this.branch().find(expressionArray[ei]).filteredrows;frlen=fr.length;for(fri=0;fri<frlen;fri++){idx=fr[fri];if(idxset[idx]===undefined){idxset[idx]=true;docset.push(idx)}}}this.filteredrows=docset;this.filterInitialized=true;return this};Resultset.prototype.$or=Resultset.prototype.findOr;function precompileQuery(operator,value){if(operator==="$regex"){if(Array.isArray(value)){value=new RegExp(value[0],value[1])}else if(!(value instanceof RegExp)){value=new RegExp(value)}}else if(typeof value==="object"){for(var key in value){if(key==="$regex"||typeof value[key]==="object"){value[key]=precompileQuery(key,value[key])}}}return value}Resultset.prototype.findAnd=function(expressionArray){for(var i=0,len=expressionArray.length;i<len;i++){if(this.count()===0){return this}this.find(expressionArray[i])}return this};Resultset.prototype.$and=Resultset.prototype.findAnd;Resultset.prototype.find=function(query,firstOnly){if(this.collection.data.length===0){this.filteredrows=[];this.filterInitialized=true;return this}var queryObject=query||"getAll",p,property,queryObjectOp,obj,operator,value,key,searchByIndex=false,result=[],filters=[],index=null;firstOnly=firstOnly||false;if(typeof queryObject==="object"){for(p in queryObject){obj={};obj[p]=queryObject[p];filters.push(obj);if(hasOwnProperty.call(queryObject,p)){property=p;queryObjectOp=queryObject[p]}}if(filters.length>1){return this.find({$and:filters},firstOnly)}}if(!property||queryObject==="getAll"){if(firstOnly){if(this.filterInitialized){this.filteredrows=this.filteredrows.slice(0,1)}else{this.filteredrows=this.collection.data.length>0?[0]:[];this.filterInitialized=true}}return this}if(property==="$and"||property==="$or"){this[property](queryObjectOp);if(firstOnly&&this.filteredrows.length>1){this.filteredrows=this.filteredrows.slice(0,1)}return this}if(queryObjectOp===null||(typeof queryObjectOp!=="object"||queryObjectOp instanceof Date)){operator="$eq";value=queryObjectOp}else if(typeof queryObjectOp==="object"){for(key in queryObjectOp){if(hasOwnProperty.call(queryObjectOp,key)){operator=key;value=queryObjectOp[key];break}}}else{throw new Error("Do not know what you want to do.")}if(operator==="$regex"||typeof value==="object"){value=precompileQuery(operator,value)}var usingDotNotation=property.indexOf(".")!==-1;var doIndexCheck=!this.filterInitialized;if(doIndexCheck&&this.collection.binaryIndices[property]&&indexedOps[operator]){if(this.collection.adaptiveBinaryIndices!==true){this.collection.ensureIndex(property)}searchByIndex=true;index=this.collection.binaryIndices[property]}if(!searchByIndex&&operator==="$in"&&Array.isArray(value)&&typeof Set!=="undefined"){value=new Set(value);operator="$inSet"}var fun=LokiOps[operator];var t=this.collection.data;var i=0,len=0;var filter,rowIdx=0,record;if(this.filterInitialized){filter=this.filteredrows;len=filter.length;if(usingDotNotation){property=property.split(".");for(i=0;i<len;i++){rowIdx=filter[i];record=t[rowIdx];if(dotSubScan(record,property,fun,value,record)){result.push(rowIdx);if(firstOnly){this.filteredrows=result;return this}}}}else{for(i=0;i<len;i++){rowIdx=filter[i];record=t[rowIdx];if(fun(record[property],value,record)){result.push(rowIdx);if(firstOnly){this.filteredrows=result;return this}}}}}else{if(!searchByIndex){len=t.length;if(usingDotNotation){property=property.split(".");for(i=0;i<len;i++){record=t[i];if(dotSubScan(record,property,fun,value,record)){result.push(i);if(firstOnly){this.filteredrows=result;this.filterInitialized=true;return this}}}}else{for(i=0;i<len;i++){record=t[i];if(fun(record[property],value,record)){result.push(i);if(firstOnly){this.filteredrows=result;this.filterInitialized=true;return this}}}}}else{var segm=this.collection.calculateRange(operator,property,value);if(operator!=="$in"){for(i=segm[0];i<=segm[1];i++){if(indexedOps[operator]!==true){if(indexedOps[operator](Utils.getIn(t[index.values[i]],property,usingDotNotation),value)){result.push(index.values[i]);if(firstOnly){this.filteredrows=result;this.filterInitialized=true;return this}}}else{result.push(index.values[i]);if(firstOnly){this.filteredrows=result;this.filterInitialized=true;return this}}}}else{for(i=0,len=segm.length;i<len;i++){result.push(index.values[segm[i]]);if(firstOnly){this.filteredrows=result;this.filterInitialized=true;return this}}}}}this.filteredrows=result;this.filterInitialized=true;return this};Resultset.prototype.where=function(fun){var viewFunction,result=[];if("function"===typeof fun){viewFunction=fun}else{throw new TypeError("Argument is not a stored view or a function")}try{if(this.filterInitialized){var j=this.filteredrows.length;while(j--){if(viewFunction(this.collection.data[this.filteredrows[j]])===true){result.push(this.