Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

lokijs

Package Overview
Dependencies
Maintainers
1
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lokijs - npm Package Compare versions

Comparing version 1.2.3 to 1.2.4

benchmark.html

149

benchmark/benchmark.js

@@ -1,3 +0,3 @@

var loki = require('../src/lokijs.js'),
db = new loki('perftest'),
// var loki = require('../src/lokijs.js'),
var db = new loki('perftest'),
samplecoll = null,

@@ -8,3 +8,3 @@ arraySize = 5000, // how large of a dataset to generate

getIterations = 2000000; // get is crazy fast due to binary search so this needs separate scale
function genRandomVal()

@@ -23,3 +23,3 @@ {

// (customId) which is number from 1- totalIterations
// we will later perform find() queries against customId with and
// we will later perform find() queries against customId with and
// without an index

@@ -29,3 +29,3 @@

db = new loki('perftest');
var start, end, totalTime;

@@ -35,3 +35,3 @@ var totalTimes = [];

samplecoll = db.addCollection('samplecoll');
samplecoll = db.addCollection('samplecoll');
/*

@@ -42,27 +42,28 @@ {

transactional: false,
clone: false
clone: false
}
);
);
*/
for (var idx=0; idx < arraySize; idx++) {
var v1 = genRandomVal();
var v2 = genRandomVal();
start = process.hrtime();
samplecoll.insert({
customId: idx,
val: v1,
val2: v2,
// start = process.hrtime();
start = performance.now();
samplecoll.insert({
customId: idx,
val: v1,
val2: v2,
val3: "more data 1234567890"
});
end = process.hrtime(start);
totalTimes.push(end);
end = performance.now() - start;
totalTimes.push([0, end * 1e6]);
}
for(var idx=0; idx < totalTimes.length; idx++) {
totalMS += totalTimes[idx][0] * 1e3 + totalTimes[idx][1]/1e6;
}
//var totalMS = end[0] * 1e3 + end[1]/1e6;

@@ -82,3 +83,3 @@ totalMS = totalMS.toFixed(2);

var dbTest = new loki('perfInsertWithEval');
var start, end, totalTime;

@@ -88,3 +89,3 @@ var totalTimes = [];

var coll = dbTest.addCollection('samplecoll',
var coll = dbTest.addCollection('samplecoll',
{

@@ -98,21 +99,23 @@ indices: ['customId'],

);
var dv = coll.addDynamicView('test');
dv.applyFind({'customId': {'$lt': arraySize/4 }});
for (var idx=0; idx < arraySize; idx++) {
var v1 = genRandomVal();
var v2 = genRandomVal();
start = process.hrtime();
coll.insert({
customId: idx,
val: v1,
val2: v2,
// start = process.hrtime();
start = performance.now();
coll.insert({
customId: idx,
val: v1,
val2: v2,
val3: "more data 1234567890"
});
end = process.hrtime(start);
totalTimes.push(end);
// end = process.hrtime(start);
end = performance.now() - start;
totalTimes.push([0, end * 1e6]);
}
for(var idx=0; idx < totalTimes.length; idx++) {

@@ -132,16 +135,18 @@ totalMS += totalTimes[idx][0] * 1e3 + totalTimes[idx][1]/1e6;

var totalMS = 0.0;
for (var idx=0; idx < getIterations; idx++) {
var customidx = Math.floor(Math.random() * arraySize) + 1;
start = process.hrtime();
// start = process.hrtime();
start = performance.now();
var results = samplecoll.get(customidx);
end = process.hrtime(start);
totalTimes.push(end);
// end = process.hrtime(start);
end = performance.now() - start;
totalTimes.push([0, end * 1e6]);
}
for(var idx=0; idx < totalTimes.length; idx++) {
totalMS += totalTimes[idx][0] * 1e3 + totalTimes[idx][1]/1e6;
}
totalMS = totalMS.toFixed(2);

@@ -162,16 +167,18 @@ var rate = getIterations * 1000 / totalMS;

}
for (var idx=0; idx < loopIterations; idx++) {
var customidx = Math.floor(Math.random() * arraySize) + 1;
start = process.hrtime();
// start = process.hrtime();
start = performance.now();
var results = samplecoll.find({ 'customId': customidx });
end = process.hrtime(start);
totalTimes.push(end);
// end = process.hrtime(start);
end = performance.now() - start;
totalTimes.push([0, end * 1e6]);
}
for(var idx=0; idx < totalTimes.length; idx++) {
totalMS += totalTimes[idx][0] * 1e3 + totalTimes[idx][1]/1e6;
}
totalMS = totalMS.toFixed(2);

@@ -192,16 +199,18 @@ var rate = loopIterations * 1000 / totalMS;

}
for (var idx=0; idx < loopIterations; idx++) {
var customidx = Math.floor(Math.random() * arraySize) + 1;
start = process.hrtime();
// start = process.hrtime();
start = performance.now();
var results = samplecoll.chain().find({ 'customId': customidx }).data();
end = process.hrtime(start)
totalTimes.push(end);
// end = process.hrtime(start)
end = performance.now() - start;
totalTimes.push([0, end * 1e6]);
}
for(var idx=0; idx < totalTimes.length; idx++) {
totalMS += totalTimes[idx][0] * 1e3 + totalTimes[idx][1]/1e6;
}
totalMS = totalMS.toFixed(2);

@@ -220,3 +229,3 @@ var rate = loopIterations * 1000 / totalMS;

var totalMS2 = 0;
var loopIterations = totalIterations;

@@ -226,22 +235,26 @@ if (typeof(multiplier) != "undefined") {

}
for (var idx=0; idx < loopIterations; idx++) {
var customidx = Math.floor(Math.random() * arraySize) + 1;
start = process.hrtime();
// start = process.hrtime();
start = performance.now();
var dv = samplecoll.addDynamicView("perfview");
dv.applyFind({ 'customId': customidx });
var results = dv.data();
end = process.hrtime(start);
totalTimes.push(end);
// end = process.hrtime(start);
end = performance.now() - start;
totalTimes.push([0, end * 1e6]);
// test speed of repeated query on an already set up dynamicview
start2 = process.hrtime();
// start2 = process.hrtime();
start2 = performance.now();
var results = dv.data();
end2 = process.hrtime(start2);
totalTimes2.push(end2);
// end2 = process.hrtime(start2);
end2 = performance.now() - start2;
totalTimes2.push([0, end2 * 1e6]);
samplecoll.removeDynamicView("perfview");
}
for(var idx=0; idx < totalTimes.length; idx++) {

@@ -251,3 +264,3 @@ totalMS += totalTimes[idx][0] * 1e3 + totalTimes[idx][1]/1e6;

}
totalMS = totalMS.toFixed(2);

@@ -259,3 +272,3 @@ totalMS2 = totalMS2.toFixed(2);

rate2 = rate2.toFixed(2);
console.log("loki dynamic view first find : " + totalMS + "ms (" + rate + " ops/s) " + loopIterations + " iterations");

@@ -262,0 +275,0 @@ console.log("loki dynamic view subsequent finds : " + totalMS2 + "ms (" + rate2 + " ops/s) " + loopIterations + " iterations");

@@ -1,1 +0,2 @@

!function(t,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?module.exports=e():t.loki=e()}(this,function(){return function(){"use strict";function t(t,e,i){return t===e?i?!0:!1:void 0===t?!0:void 0===e?!1:null===t?!0:null===e?!1:e>t}function e(t,e,i){return t===e?i?!0:!1:void 0===t?!1:void 0===e?!0:null===t?!1:null===e?!0:t>e}function i(i,n,s){return i===n?0:s?t(i,n)?1:-1:e(i,n)?1:-1}function n(t,e){var i,n=e||"parse-stringify";return"parse-stringify"===n&&(i=JSON.parse(JSON.stringify(t))),i}function s(){try{return"localStorage"in window&&null!==window.localStorage}catch(t){return!1}}function r(){}function o(t,e){t.apply(null,e)}function a(t,e){this.filename=t||"loki.db",this.collections=[],this.databaseVersion=1.1,this.engineVersion=1.1,this.autosave=!1,this.autosaveInterval=5e3,this.autosaveHandle=null,this.options={},this.persistenceMethod=null,this.persistenceAdapter=null,this.events={init:[],flushChanges:[],close:[],changes:[],warning:[]};var i=function(){return"undefined"==typeof window?"NODEJS":"undefined"!=typeof global&&global.window?"NODEJS":"undefined"!=typeof document?-1===document.URL.indexOf("http://")&&-1===document.URL.indexOf("https://")?"CORDOVA":"BROWSER":"CORDOVA"};this.ENV=e&&e.hasOwnProperty("env")?e.env:i(),"undefined"===this.ENV&&(this.ENV="NODEJS"),"NODEJS"===this.ENV&&(this.fs=require("fs")),"undefined"!=typeof e&&this.configureOptions(e,!0),this.on("init",this.clearChanges)}function l(t,e,i,n){return this.collection=t,this.searchIsChained=!e&&!i,this.filteredrows=[],this.filterInitialized=!1,"undefined"!=typeof e&&null!==e?this.find(e,n):"undefined"!=typeof i&&null!==i?this.where(i):this}function h(t,e,i){this.collection=t,this.name=e,this.persistent=!1,"undefined"!=typeof i&&(this.persistent=i),this.resultset=new l(t),this.resultdata=[],this.resultsdirty=!1,this.cachedresultset=null,this.filterPipeline=[],this.sortFunction=null,this.sortCriteria=null,this.sortDirty=!1,this.events={rebuild:[]}}function c(t,e){function i(t,e,i){u.changes.push({name:t,operation:e,obj:JSON.parse(JSON.stringify(i))})}function n(){u.changes=[]}function s(t){t&&(t.meta||(t.meta={}),t.meta.created=(new Date).getTime(),t.meta.revision=0)}function r(t){t&&(t.meta.updated=(new Date).getTime(),t.meta.revision+=1)}function o(t){i(u.name,"I",t)}function a(t){i(u.name,"U",t)}function l(t){s(t),o(t)}function h(t){r(t),a(t)}function c(){p=u.disableChangesApi?s:l,y=u.disableChangesApi?r:h}this.name=t,this.data=[],this.idIndex=[],this.binaryIndices={},this.objType=t,this.dirty=!0,this.cachedIndex=null,this.cachedBinaryIndex=null,this.cachedData=null;var u=this;e=e||{},this.transactional=e.hasOwnProperty("transactional")?e.transactional:!1,this.cloneObjects=e.hasOwnProperty("clone")?e.clone:!1,this.asyncListeners=e.hasOwnProperty("asyncListeners")?e.asyncListeners:!1,this.disableChangesApi=e.hasOwnProperty("disableChangesApi")?e.disableChangesApi:!0,this.maxId=0,this.DynamicViews=[],this.events={insert:[],update:[],close:[],flushbuffer:[],error:[],"delete":[],warning:[]},this.changes=[],this.ensureId();var d=[];if(e&&e.indices)if("[object Array]"===Object.prototype.toString.call(e.indices))d=e.indices;else{if("string"!=typeof e.indices)throw new TypeError("Indices needs to be a string or an array of strings");d=[e.indices]}for(var f=0;f<d.length;f++)this.ensureIndex(d[f]);this.getChanges=function(){return u.changes},this.flushChanges=n;var p,y;c(),this.setChangesApi=function(t){u.disableChangesApi=!t,c()},this.on("insert",function(t){p(t)}),this.on("update",function(t){y(t)}),this.on("delete",function(t){u.disableChangesApi||i(u.name,"R",t)}),this.on("warning",console.warn),n()}function u(t,e,i){for(var n,s,r=0,o=t.length;o>r;){if(s=(r+o)/2|0,n=i.apply(null,[e,t[s]]),0==n)return{found:!0,index:s};0>n?o=s:r=s+1}return{found:!1,index:o}}function d(t){return function(e,i){return u(e,i,t)}}function f(){}{var p={copyProperties:function(t,e){var i;for(i in t)e[i]=t[i]}},y={$eq:function(t,e){return t===e},$gt:function(t,i){return e(t,i)},$gte:function(t,i){return e(t,i,!0)},$lt:function(e,i){return t(e,i)},$lte:function(e,i){return t(e,i,!0)},$ne:function(t,e){return t!==e},$regex:function(t,e){return e.test(t)},$in:function(t,e){return e.indexOf(t)>-1},$contains:function(t,e){var i=function(){return!0};return Array.isArray(e)||(e=[e]),Array.isArray(t)?i=function(e){return-1!==t.indexOf(e)}:"string"==typeof t?i=function(e){return-1!==t.indexOf(e)}:t&&"object"==typeof t&&(i=function(e){return t.hasOwnProperty(e)}),e.reduce(function(t,e){return t?i(e):t},!0)}};"object"==typeof exports?require("fs"):!1}return r.prototype.events={},r.prototype.asyncListeners=!1,r.prototype.on=function(t,e){var i=this.events[t];return i||(i=this.events[t]=[]),i.push(e),e},r.prototype.emit=function(t){var e=Array.prototype.slice.call(arguments,0),i=this;if(!t||!this.events[t])throw new Error("No event "+t+" defined");e.splice(0,1),this.events[t].forEach(function(t){i.asyncListeners?setTimeout(function(){o(t,e)},1):o(t,e)})},r.prototype.removeListener=function(t,e){if(this.events[t]){var i=this.events[t];i.splice(i.indexOf(e),1)}},a.prototype=new r,a.prototype.configureOptions=function(t,e){this.options={},"undefined"!=typeof t&&(this.options=t),this.persistenceMethod=null,this.options.hasOwnProperty("persistenceMethod")&&(this.persistenceMethod=t.persistenceMethod),this.persistenceAdapter=null,this.options.hasOwnProperty("adapter")&&(this.persistenceMethod="adapter",this.persistenceAdapter=t.adapter),t.hasOwnProperty("autoload")&&"undefined"!=typeof e&&e&&this.loadDatabase(t,t.autoloadCallback),this.options.hasOwnProperty("autosaveInterval")&&(this.autosaveDisable(),this.autosaveInterval=parseInt(this.options.autosaveInterval)),this.options.hasOwnProperty("autosave")&&this.options.autosave&&(this.autosaveDisable(),this.autosave=!0,this.autosaveEnable())},a.prototype.anonym=function(t,e){var i=new c("anonym",e);return i.insert(t),i},a.prototype.addCollection=function(t,e){var i=new c(t,e);return this.collections.push(i),i},a.prototype.loadCollection=function(t){if(!t.name)throw new Error("Collection must be have a name property to be loaded");this.collections.push(t)},a.prototype.getCollection=function(t){var e,i=this.collections.length;for(e=0;i>e;e+=1)if(this.collections[e].name===t)return this.collections[e];return this.emit("warning","collection "+t+" not found"),null},a.prototype.listCollections=function(){for(var t=this.collections.length,e=[];t--;)e.push({name:this.collections[t].name,type:this.collections[t].objType,count:this.collections[t].data.length});return e},a.prototype.removeCollection=function(t){var e,i=this.collections.length;for(e=0;i>e;e+=1)if(this.collections[e].name===t)return void this.collections.splice(e,1)},a.prototype.getName=function(){return this.name},a.prototype.serializeReplacer=function(t,e){switch(t){case"autosaveHandle":return null;default:return e}},a.prototype.serialize=function(){return JSON.stringify(this,this.serializeReplacer)},a.prototype.toJson=a.prototype.serialize,a.prototype.loadJSON=function(t,e){var i,n,s,r,o=JSON.parse(t),a=0,l=o.collections.length,h=!1;for(this.name=o.name,this.databaseVersion=1,o.hasOwnProperty("databaseVersion")&&(this.databaseVersion=o.databaseVersion),this.databaseVersion!==this.engineVersion&&(h=!0),this.collections=[],a;l>a;a+=1){if(i=o.collections[a],n=this.addCollection(i.name),s=i.data.length,r=0,e&&e.hasOwnProperty(i.name)){var c=e[i.name].inflate?e[i.name].inflate:p.copyProperties;for(r;s>r;r++){var u=new e[i.name].proto;c(i.data[r],u),n.data[r]=u}}else for(r;s>r;r++)n.data[r]=i.data[r];if(h&&1.1==this.engineVersion){if(n.transactional=!1,n.cloneObjects=!1,n.asyncListeners=!0,n.disableChangesApi=!0,console.warn("upgrading database, loki id is now called '$loki' instead of 'id'"),n.data.length>0&&!n.data[0].hasOwnProperty("$loki"))for(var d=n.data.length,f=null,y=0;d>y;y++)f=n.data[y],f.$loki=f.id,delete f.id,f.hasOwnProperty.originalId&&(f.id=f.originalId)}else n.transactional=i.transactional,n.asyncListeners=i.asyncListeners,n.disableChangesApi=i.disableChangesApi,n.cloneObjects=i.cloneObjects;if(n.maxId=0===i.data.length?0:i.maxId,n.idIndex=i.idIndex,"undefined"!=typeof i.indices&&(n.idIndex=i.indices.id),"undefined"!=typeof i.binaryIndices&&(n.binaryIndices=i.binaryIndices),n.ensureId(),"undefined"!=typeof i.DynamicViews)for(var y=0;y<i.DynamicViews.length;y++){var v=i.DynamicViews[y],g=n.addDynamicView(v.name,v.persistent);if(g.resultdata=v.resultdata,g.resultsdirty=v.resultsdirty,g.filterPipeline=v.filterPipeline,h&&"undefined"!=typeof v.sortColumn&&null!=v.sortColumn){var w=!1;"undefined"!=typeof v.sortColumnDesc&&(w=v.sortColumnDesc),g.sortCriteria=[v.sortColumn,w]}else g.sortCriteria=v.sortCriteria;g.sortFunction=null,g.sortDirty=v.sortDirty,g.resultset.filteredrows=v.resultset.filteredrows,g.resultset.searchIsChained=v.resultset.searchIsChained,g.resultset.filterInitialized=v.resultset.filterInitialized,g.rematerialize({removeWhereFilters:!0})}}},a.prototype.close=function(t){this.autosave&&(this.autosaveDisable(),this.autosaveDirty()&&this.saveDatabase()),t&&this.on("close",t),this.emit("close")},a.prototype.generateChangesNotification=function(t){function e(t){return t.name}var i=[],n=t||this.collections.map(e);return this.collections.forEach(function(t){-1!==n.indexOf(e(t))&&(i=i.concat(t.getChanges()))}),i},a.prototype.serializeChanges=function(t){return JSON.stringify(this.generateChangesNotification(t))},a.prototype.clearChanges=function(){this.collections.forEach(function(t){t.flushChanges&&t.flushChanges()})},a.prototype.loadDatabase=function(t,e){var i=e||function(t){if(t)throw t},n=this;if(null!=this.persistenceMethod){if("fs"===this.persistenceMethod&&this.fs.readFile(this.filename,{encoding:"utf8"},function(e,s){return e?i(e,null):(n.loadJSON(s,t||{}),void i(null,s))}),"localStorage"===this.persistenceMethod)if(s()){var r=localStorage.getItem(this.filename);n.loadJSON(r,t||{}),i(null,r)}else i(new Error("localStorage is not available"));return void("adapter"===this.persistenceMethod&&(null!==this.persistenceAdapter?this.persistenceAdapter.loadDatabase(this.filename,function(e){"undefined"==typeof e||null===e?(console.warn("lokijs loadDatabase : Database not found"),i("Database not found")):(n.loadJSON(e,t||{}),i(null))}):i(new Error("persistenceAdapter not configured"))))}if("NODEJS"===this.ENV)this.fs.readFile(this.filename,{encoding:"utf8"},function(e,s){return e?i(e,null):(s.length||(s=n.serialize()),n.loadJSON(s,t||{}),void i(null,s))});else if("BROWSER"===this.ENV)if(s()){var r=localStorage.getItem(this.filename);n.loadJSON(r,t||{}),i(null,r)}else i(new Error("localStorage is not available"));else i(new Error("unknown environment"))},a.prototype.saveDatabase=function(t){var e=t||function(t){if(t)throw t},i=this;return this.autosaveClearFlags(),null!=this.persistenceMethod?("fs"===this.persistenceMethod&&i.fs.writeFile(i.filename,i.serialize(),e),"localStorage"===this.persistenceMethod&&(s()?(localStorage.setItem(i.filename,i.serialize()),e(null)):e(new Error("localStorage is not available"))),void("adapter"===this.persistenceMethod&&(null!==this.persistenceAdapter?this.persistenceAdapter.saveDatabase(this.filename,i.serialize(),function(){e(null)}):e(new Error("persistenceAdapter not configured"))))):void("NODEJS"===this.ENV?i.fs.writeFile(i.filename,i.serialize(),e):"BROWSER"===this.ENV||"CORDOVA"===this.ENV?s()?(localStorage.setItem(i.filename,i.serialize()),e(null)):e(new Error("localStorage is not available")):e(new Error("unknown environment")))},a.prototype.save=a.prototype.saveDatabase,a.prototype.autosaveDirty=function(){for(var t=0;t<this.collections.length;t++)if(this.collections[t].dirty)return!0;return!1},a.prototype.autosaveClearFlags=function(){for(var t=0;t<this.collections.length;t++)this.collections[t].dirty=!1},a.prototype.autosaveEnable=function(){this.autosave=!0;var t=5e3,e=this;"undefined"!=typeof this.autosaveInterval&&null!==this.autosaveInterval&&(t=this.autosaveInterval),this.autosaveHandle=setInterval(function(){e.autosaveDirty()&&e.saveDatabase()},t)},a.prototype.autosaveDisable=function(){"undefined"!=typeof this.autosaveHandle&&null!==this.autosaveHandle&&(clearInterval(this.autosaveHandle),this.autosaveHandle=null)},l.prototype.toJSON=function(){var t=this.copy();return t.collection=null,t},l.prototype.limit=function(t){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));var e=this.copy();return e.filteredrows=e.filteredrows.slice(0,t),e},l.prototype.offset=function(t){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));var e=this.copy();return e.filteredrows=e.filteredrows.splice(t,e.filteredrows.length),e},l.prototype.copy=function(){var t=new l(this.collection,null,null);return t.filteredrows=this.filteredrows.slice(),t.filterInitialized=this.filterInitialized,t},l.prototype.branch=l.prototype.copy,l.prototype.sort=function(t){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));var e=function(t,e){return function(i,n){var s=e.collection.data[i],r=e.collection.data[n];return t(s,r)}}(t,this);return this.filteredrows.sort(e),this},l.prototype.simplesort=function(t,e){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data)),"undefined"==typeof e&&(e=!1);var n=function(t,e,n){return function(s,r){var o=n.collection.data[s],a=n.collection.data[r];return i(o[t],a[t],e)}}(t,e,this);return this.filteredrows.sort(n),this},l.prototype.compoundeval=function(t,e,n){var s=t.length;if(0===s)throw new Error("Invalid call to compoundeval, need at least one property");var r=!1,o=t[0];return"string"!=typeof o&&Array.isArray(o)&&(r=o[1],o=o[0]),e[o]===n[o]?1===s?0:this.compoundeval(t.slice(1),e,n,r):i(e[o],n[o],r)},l.prototype.compoundsort=function(t){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));var e=function(t,e){return function(i,n){var s=e.collection.data[i],r=e.collection.data[n];return e.compoundeval(t,s,r)}}(t,this);return this.filteredrows.sort(e),this},l.prototype.calculateRange=function(i,n,s){var r=this.collection.data,o=this.collection.binaryIndices[n].values,a=0,l=o.length-1,h=null,c=0,u=o.length-1;if(0==r.length)return[0,-1];var d=r[o[a]][n],f=r[o[l]][n];switch(i){case"$eq":if(t(s,d)||e(s,f))return[0,-1];break;case"$gt":if(e(s,f,!0))return[0,-1];break;case"$gte":if(e(s,f))return[0,-1];break;case"$lt":if(t(s,d,!0))return[0,-1];break;case"$lte":if(t(s,d))return[0,-1]}for(;l>a;)h=Math.floor((a+l)/2),t(r[o[h]][n],s)?a=h+1:l=h;for(c=a,a=0,l=o.length-1;l>a;)h=Math.floor((a+l)/2),t(s,r[o[h]][n])?l=h:a=h+1;u=l;var p=r[o[c]][n],y=r[o[u]][n];switch(i){case"$eq":return p!==s?[0,-1]:(y!==s&&u--,[c,u]);case"$gt":return t(y,s,!0)?[0,-1]:[u,r.length-1];case"$gte":return t(p,s)?[0,-1]:[c,r.length-1];case"$lt":return 0===c&&t(p,s)?[0,0]:[0,c-1];case"$lte":return y!==s&&u--,0===u&&t(y,s)?[0,0]:[0,u];default:return[0,r.length-1]}},l.prototype.findOr=function(t){var e=0,i=0,n=null,s=[],r=null;if(this.filterInitialized){for(s=[],i=0;i<t.length;i++)for(r=this.branch(),r.find(t[i]),r.data(),n=r.filteredrows,e=0;e<n.length;e++)-1===s.indexOf(n[e])&&s.push(n[e]);this.filteredrows=s}else for(i=0;i<t.length;i++)for(r=this.collection.chain(),r.find(t[i]),r.data(),n=r.filteredrows,e=0;e<n.length;e++)-1===this.filteredrows.indexOf(n[e])&&this.filteredrows.push(n[e]);return this.filterInitialized=!0,this},l.prototype.findAnd=function(t){for(var e=0;e<t.length;e++)this.find(t[e]);return this},l.prototype.find=function(t,e){if(0===this.collection.data.length)return this.searchIsChained?(this.filteredrows=[],this.filterInitialized=!0,this):[];var i,n,s,r,o,a,l,h,c,u=t||"getAll",d={$eq:y.$eq,$gt:y.$gt,$gte:y.$gte,$lt:y.$lt,$lte:y.$lte,$ne:y.$ne,$regex:y.$regex,$in:y.$in,$contains:y.$contains},f=!1,p=[],v=null,g=!0;e=e||!1;for(r in u){g=!1;break}if(g&&(u="getAll"),"getAll"===u)return this.searchIsChained?(this.filteredrows=Object.keys(this.collection.data),this):this.collection.data;var w=!1;for(r in u)if(u.hasOwnProperty(r)){if(i=r,"$and"===r)return this.searchIsChained?(this.findAnd(u[r]),this):this.collection.chain().findAnd(u[r]).data();if("$or"===r)return this.searchIsChained?(this.findOr(u[r]),this):this.collection.chain().findOr(u[r]).data();if(-1!=r.indexOf(".")&&(w=!0),"object"!=typeof u[r])s="$eq",n=u[r];else{if("object"!=typeof u[r])throw"Do not know what you want to do.";for(o in u[r])u[r].hasOwnProperty(o)&&(s=o,n=u[r][o])}break}if("$regex"===s&&(n=RegExp(n)),null===this.collection.data)throw new TypeError;if((!this.searchIsChained||this.searchIsChained&&!this.filterInitialized)&&"$ne"!==s&&"$regex"!==s&&"$contains"!==s&&"$in"!==s&&this.collection.binaryIndices.hasOwnProperty(i)&&(this.collection.ensureIndex(i),f=!0,v=this.collection.binaryIndices[i]),a=d[s],this.searchIsChained){if(this.filterInitialized){if(f)for(l=v,h=this.filteredrows.length;h--;)a(l[this.filteredrows[h]],n)&&p.push(this.filteredrows[h]);else if(l=this.collection.data,h=this.filteredrows.length,w)for(var m,b;h--;)m=l[this.filteredrows[h]],b=i.split("."),b.forEach(function(t){m=m[t]}),a(m,n)&&p.push(this.filteredrows[h]);else for(;h--;)a(l[this.filteredrows[h]][i],n)&&p.push(this.filteredrows[h]);return this.filteredrows=p,this}if(f){l=this.collection.data;for(var I=this.calculateRange(s,i,n,this),O=I[0];O<=I[1];O++)p.push(v.values[O]);this.filteredrows=p}else if(l=this.collection.data,h=l.length,w)for(var m,b;h--;)m=l[h],b=i.split("."),b.forEach(function(t){m=m[t]}),a(m,n)&&p.push(h);else for(;h--;)a(l[h][i],n)&&p.push(h);return this.filteredrows=p,this.filterInitialized=!0,this}if(f){l=this.collection.data,c=l.length;var I=this.calculateRange(s,i,n,this);if(e)return-1!==I[1]?l[v.values[I[0]]]:[];for(h=I[0];h<=I[1];h++)p.push(l[v.values[h]]);this.filteredrows=p}else{if(l=this.collection.data,h=l.length,e){for(;h--;)if(a(l[h][i],n))return l[h];return[]}if(w)for(var m,b;h--;)m=l[h],b=i.split("."),b.forEach(function(t){m=m[t]}),a(m,n)&&p.push(l[h]);else for(;h--;)a(l[h][i],n)&&p.push(l[h])}return p},l.prototype.where=function(t){var e,i=[];if("function"!=typeof t)throw"Argument is not a stored view or a function";e=t;try{if(this.searchIsChained){if(this.filterInitialized){for(var n=this.filteredrows.length;n--;)e(this.collection.data[this.filteredrows[n]])===!0&&i.push(this.filteredrows[n]);return this.filteredrows=i,this}for(var n=this.collection.data.length;n--;)e(this.collection.data[n])===!0&&i.push(n);return this.filteredrows=i,this.filterInitialized=!0,this}for(var n=this.collection.data.length;n--;)e(this.collection.data[n])===!0&&i.push(this.collection.data[n]);return i}catch(s){throw s}},l.prototype.data=function(){var t=[];if(this.searchIsChained&&!this.filterInitialized){if(0===this.filteredrows.length)return this.collection.data;this.filterInitialized=!0}var e,i=this.collection.data,n=this.filteredrows,s=this.filteredrows.length;for(e=0;s>e;e++)t.push(i[n[e]]);return t},l.prototype.update=function(t){if("function"!=typeof t)throw"Argument is not a function";this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));for(var e=this.filteredrows.length,i=this.collection.data,n=0;e>n;n++)t(i[this.filteredrows[n]]),this.collection.update(i[this.filteredrows[n]]);return this},l.prototype.remove=function(){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));for(var t=this.filteredrows.length,e=0;t>e;e++)this.collection.remove(this.filteredrows[e]);return this.filteredrows=[],this},l.prototype.mapReduce=function(t,e){try{return e(this.data().map(t))}catch(i){throw i}},h.prototype=new r,h.prototype.rematerialize=function(t){var e,i,n;if(t=t||{},this.resultdata=[],this.resultsdirty=!0,this.resultset=new l(this.collection),(this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0),t.hasOwnProperty("removeWhereFilters"))for(e=this.filterPipeline.length,i=e;i--;)"where"===this.filterPipeline[i].type&&(i!==this.filterPipeline.length-1&&(this.filterPipeline[i]=this.filterPipeline[this.filterPipeline.length-1]),this.filterPipeline.length--);var s=this.filterPipeline;for(this.filterPipeline=[],e=s.length,n=0;e>n;n++)this.applyFind(s[n].val);return this.data(),this.emit("rebuild",this),this},h.prototype.branchResultset=function(){return this.resultset.copy()},h.prototype.toJSON=function(){var t=new h(this.collection,this.name,this.persistent);return t.resultset=this.resultset,t.resultdata=[],t.resultsdirty=!0,t.filterPipeline=this.filterPipeline,t.sortFunction=this.sortFunction,t.sortCriteria=this.sortCriteria,t.sortDirty=this.sortDirty,t.collection=null,t},h.prototype.applySort=function(t){return this.sortFunction=t,this.sortCriteria=null,this.resultset.sort(t),this.sortDirty=!1,this},h.prototype.applySimpleSort=function(t,e){return"undefined"==typeof e&&(e=!1),this.sortCriteria=[[t,e]],this.sortFunction=null,this.resultset.simplesort(t,e),this.sortDirty=!1,this},h.prototype.applySortCriteria=function(t){return this.sortCriterial=t,this.sortFunction=null,this.resultset.compoundsort(t),this.sortDirty=!1,this},h.prototype.startTransaction=function(){return this.cachedresultset=this.resultset.copy(),this},h.prototype.commit=function(){return this.cachedresultset=null,this},h.prototype.rollback=function(){return this.resultset=this.cachedresultset,this.persistent&&(this.resultdata=this.resultset.data(),this.emit("rebuild",this)),this},h.prototype.applyFind=function(t){return this.filterPipeline.push({type:"find",val:t}),this.resultset.find(t),(this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0),this.persistent&&(this.resultsdirty=!0),this},h.prototype.applyWhere=function(t){return this.filterPipeline.push({type:"where",val:t}),this.resultset.where(t),(this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0),this.persistent&&(this.resultsdirty=!0),this},h.prototype.data=function(){return this.sortDirty&&(this.sortFunction&&this.resultset.sort(this.sortFunction),this.sortCriteria&&this.resultset.compoundsort(this.sortCriteria),this.sortDirty=!1,this.persistent&&(this.resultsdirty=!0)),this.persistent?(this.resultsdirty&&(this.resultdata=this.resultset.data(),this.resultsdirty=!1,this.emit("rebuild",this)),this.resultdata):(this.resultset.filterInitialized||this.emit("rebuild",this),this.resultset.data())},h.prototype.evaluateDocument=function(t){var e=this.resultset.filteredrows,i=e.indexOf(t),n=e.length,s=new l(this.collection);s.filteredrows=[t],s.filterInitialized=!0;for(var r=0;r<this.filterPipeline.length;r++)switch(this.filterPipeline[r].type){case"find":s.find(this.filterPipeline[r].val);break;case"where":s.where(this.filterPipeline[r].val)}var o=0===s.filteredrows.length?-1:0;return-1!=i||-1!=o?-1===i&&-1!==o?(e.push(t),this.persistent&&this.resultdata.push(this.collection.data[t]),void((this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0))):-1!==i&&-1===o?void(n-1>i?(e[i]=e[n-1],e.length=n-1,this.persistent&&(this.resultdata[i]=this.resultdata[n-1],this.resultdata.length=n-1)):(e.length=n-1,this.persistent&&(this.resultdata.length=n-1))):-1!==i&&-1!==o?(this.persistent&&(this.resultdata[i]=this.collection.data[t]),void((this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0))):void 0:void 0},h.prototype.removeDocument=function(t){var e,i=this.resultset.filteredrows,n=i.indexOf(t),s=i.length;for(-1!==n&&(s-1>n?(i[n]=i[s-1],i.length=s-1,this.persistent&&(this.resultdata[n]=this.resultdata[s-1],this.resultdata.length=s-1)):(i.length=s-1,this.persistent&&(this.resultdata.length=s-1))),s=i.length,e=0;s>e;e++)i[e]>t&&i[e]--},h.prototype.mapReduce=function(t,e){try{return e(this.data().map(t))}catch(i){throw i}},c.prototype=new r,c.prototype.ensureIndex=function(i,n){if("undefined"==typeof n&&(n=!1),null===i||void 0===i)throw"Attempting to set index without an associated property";if(!this.binaryIndices.hasOwnProperty(i)||n||this.binaryIndices[i].dirty){this.binaryIndices[i]={name:i,dirty:!0,values:[]};var s,r=this.data.length,o=0;for(s=this.binaryIndices[i],o;r>o;o+=1)s.values.push(o);var a=function(i,n){return function(s,r){var o=n.data[s],a=n.data[r];return o[i]===a[i]?0:e(o[i],a[i])?1:t(o[i],a[i])?-1:void 0}}(i,this);s.values.sort(a),s.dirty=!1,this.dirty=!0}},c.prototype.ensureAllIndexes=function(t){for(var e=Object.keys(this.binaryIndices),i=e.length;i--;)this.ensureIndex(e[i],t)},c.prototype.flagBinaryIndexesDirty=function(){for(var t=Object.keys(this.binaryIndices),e=t.length;e--;)this.binaryIndices[t[e]].dirty=!0},c.prototype.ensureId=function(){var t=this.data.length,e=0;for(this.idIndex=[],e;t>e;e+=1)this.idIndex.push(this.data[e].$loki)},c.prototype.ensureIdAsync=function(t){this.async(function(){this.ensureId()},t)},c.prototype.addDynamicView=function(t,e){var i=new h(this,t,e);return this.DynamicViews.push(i),i},c.prototype.removeDynamicView=function(t){for(var e=0;e<this.DynamicViews.length;e++)this.DynamicViews[e].name===t&&this.DynamicViews.splice(e,1)},c.prototype.getDynamicView=function(t){for(var e=0;e<this.DynamicViews.length;e++)if(this.DynamicViews[e].name===t)return this.DynamicViews[e];return null},c.prototype.findAndUpdate=function(t,e){var i,n=this.where(t),s=0;try{for(s;s<n.length;s++)i=e(n[s]),this.update(i)}catch(r){this.rollback(),console.error(r.message)}},c.prototype.insert=function(t){if(!t){var e=new Error("Object cannot be null");throw this.emit("error",e),e}var i,n=this,s=Array.isArray(t)?t:[t];return s.forEach(function(t){if("object"!=typeof t)throw new TypeError("Document needs to be an object");i=n.clone?JSON.parse(JSON.stringify(t)):t,"undefined"==typeof i.meta&&(i.meta={revision:0,created:0}),n.add(i),n.emit("insert",i)}),i},c.prototype.clear=function(){this.data=[],this.idIndex=[],this.binaryIndices={},this.cachedIndex=null,this.cachedData=null,this.maxId=0,this.DynamicViews=[],this.dirty=!0},c.prototype.update=function(t){if(Object.keys(this.binaryIndices).length>0&&this.flagBinaryIndexesDirty(),Array.isArray(t)){var e=0,i=t.length;for(e;i>e;e+=1)this.update(t[e])}else{if(!t.hasOwnProperty("$loki"))throw"Trying to update unsynced document. Please save the document first by using insert() or addMany()";try{this.startTransaction();var n,s,r=this.get(t.$loki,!0);if(!r)throw new Error("Trying to update a document not in collection.");n=r[0],s=r[1],this.data[s]=t;for(var o=0;o<this.DynamicViews.length;o++)this.DynamicViews[o].evaluateDocument(s);this.idIndex[s]=n.$loki,this.commit(),this.dirty=!0,this.emit("update",t)}catch(a){throw this.rollback(),console.error(a.message),this.emit("error",a),a}}},c.prototype.add=function(t){var e,i=this.DynamicViews.length;if("object"!=typeof t)throw"Object being added needs to be an object";if(Object.keys(this.binaryIndices).length>0&&this.flagBinaryIndexesDirty(),"undefined"!=typeof t.$loki)throw"Document is already in collection, please use update()";try{this.startTransaction(),this.maxId++;var e;for(isNaN(this.maxId)&&(this.maxId=this.data[this.data.length-1].$loki+1),t.$loki=this.maxId,t.meta.version=0,this.data.push(t),e=0;i>e;e++)this.DynamicViews[e].evaluateDocument(this.data.length-1);return this.idIndex.push(t.$loki),this.commit(),this.dirty=!0,t}catch(n){this.rollback(),console.error(n.message)}},c.prototype.removeWhere=function(t){var e;e="function"==typeof t?this.data.filter(t):new l(this,t);for(var i=e.length;i--;)this.remove(e[i])},c.prototype.removeDataOnly=function(){this.removeWhere(function(){return!0})},c.prototype.remove=function(t){if("number"==typeof t&&(t=this.get(t)),"object"!=typeof t)throw new Error("Parameter is not an object");if(Array.isArray(t)){var e=0,i=t.length;for(e;i>e;e+=1)this.remove(t[e])}else{if(!t.hasOwnProperty("$loki"))throw new Error("Object is not a document stored in the collection");Object.keys(this.binaryIndices).length>0&&this.flagBinaryIndexesDirty();try{this.startTransaction();for(var n=this.get(t.$loki,!0),s=n[1],r=0;r<this.DynamicViews.length;r++)this.DynamicViews[r].removeDocument(s);this.data.splice(s,1),this.idIndex.splice(s,1),this.commit(),this.dirty=!0,this.emit("delete")}catch(o){this.rollback(),console.error(o.message),this.emit("error",o)}}},c.prototype.get=function(t,e){var i=e||!1,n=this.idIndex,s=n.length-1,r=0,o=Math.floor(r+(s-r)/2);if(t="number"==typeof t?t:parseInt(t,10),isNaN(t))throw"Passed id is not an integer";for(;n[r]<n[s];)o=Math.floor((r+s)/2),n[o]<t?r=o+1:s=o;return s===r&&n[r]===t?i?[this.data[r],r]:this.data[r]:null},c.prototype.findOne=function(t){var e=new l(this,t,null,!0);return Array.isArray(e)&&0===e.length?null:e},c.prototype.chain=function(){return new l(this,null,null)},c.prototype.find=function(t){return"undefined"==typeof t&&(t="getAll"),new l(this,t,null)},c.prototype.findOneUnindexed=function(t,e){for(var i,n=this.data.length;n--;)if(this.data[n][t]===e)return i=this.data[n];return null},c.prototype.startTransaction=function(){if(this.transactional){this.cachedData=n(this.data,"parse-stringify"),this.cachedIndex=this.idIndex,this.cachedBinaryIndex=this.binaryIndices;for(var t=0;t<this.DynamicViews.length;t++)this.DynamicViews[t].startTransaction()}},c.prototype.commit=function(){if(this.transactional){this.cachedData=null,this.cachedIndex=null,this.cachedBinaryIndices=null;for(var t=0;t<this.DynamicViews.length;t++)this.DynamicViews[t].commit()}},c.prototype.rollback=function(){if(this.transactional){null!==this.cachedData&&null!==this.cachedIndex&&(this.data=this.cachedData,this.idIndex=this.cachedIndex,this.binaryIndices=this.cachedBinaryIndex);for(var t=0;t<this.DynamicViews.length;t++)this.DynamicViews[t].rollback()}},c.prototype.async=function(t,e){setTimeout(function(){if("function"!=typeof t)throw"Argument passed for async execution is not a function";t(),e()},0)},c.prototype.where=function(t){return new l(this,null,t)},c.prototype.mapReduce=function(t,e){try{return e(this.data.map(t))}catch(i){throw i}},c.prototype.no_op=function(){},f.prototype={keys:[],values:[],sort:function(t,e){return e>t?-1:t>e?1:0},setSort:function(t){this.bs=d(t)},bs:function(){return d(this.sort)},set:function(t,e){var i=this.bs(this.keys,t);i.found?this.values[i.index]=e:(this.keys.splice(i.index,0,t),this.values.splice(i.index,0,e))},get:function(t){return this.values[u(this.keys,t,this.sort).index]}},a.Collection=c,a.KeyValueStore=f,a}()});
!function(t,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?module.exports=e():t.loki=e()}(this,function(){return function(){"use strict";function t(t,e,i){return t===e?i?!0:!1:void 0===t?!0:void 0===e?!1:null===t?!0:null===e?!1:e>t}function e(t,e,i){return t===e?i?!0:!1:void 0===t?!1:void 0===e?!0:null===t?!1:null===e?!0:t>e}function i(i,n,r){return i===n?0:r?t(i,n)?1:-1:e(i,n)?1:-1}function n(t){return Array.isArray(t)?function(e){return-1!==t.indexOf(e)}:"string"==typeof t?function(e){return-1!==t.indexOf(e)}:t&&"object"==typeof t?function(e){return t.hasOwnProperty(e)}:void 0}function r(t,e){var i,n=e||"parse-stringify";return"parse-stringify"===n&&(i=JSON.parse(JSON.stringify(t))),i}function s(){try{return"localStorage"in window&&null!==window.localStorage}catch(t){return!1}}function o(){}function a(t,e){this.filename=t||"loki.db",this.collections=[],this.databaseVersion=1.1,this.engineVersion=1.1,this.autosave=!1,this.autosaveInterval=5e3,this.autosaveHandle=null,this.options={},this.persistenceMethod=null,this.persistenceAdapter=null,this.events={init:[],flushChanges:[],close:[],changes:[],warning:[]};var i=function(){return"undefined"==typeof window?"NODEJS":"undefined"!=typeof global&&global.window?"NODEJS":"undefined"!=typeof document?-1===document.URL.indexOf("http://")&&-1===document.URL.indexOf("https://")?"CORDOVA":"BROWSER":"CORDOVA"};this.ENV=e&&e.hasOwnProperty("env")?e.env:i(),"undefined"===this.ENV&&(this.ENV="NODEJS"),this.configureOptions(e,!0),this.on("init",this.clearChanges)}function h(){this.fs=require("fs")}function l(){}function c(t,e,i,n){return this.collection=t,this.searchIsChained=!e&&!i,this.filteredrows=[],this.filterInitialized=!1,"undefined"!=typeof e&&null!==e?this.find(e,n):"undefined"!=typeof i&&null!==i?this.where(i):this}function u(t,e,i){this.collection=t,this.name=e,this.persistent=!1,"undefined"!=typeof i&&(this.persistent=i),this.resultset=new c(t),this.resultdata=[],this.resultsdirty=!1,this.cachedresultset=null,this.filterPipeline=[],this.sortFunction=null,this.sortCriteria=null,this.sortDirty=!1,this.events={rebuild:[]}}function f(t,e){function i(t,e,i){u.changes.push({name:t,operation:e,obj:JSON.parse(JSON.stringify(i))})}function n(){u.changes=[]}function r(t){t&&(t.meta||(t.meta={}),t.meta.created=(new Date).getTime(),t.meta.revision=0)}function s(t){t&&(t.meta.updated=(new Date).getTime(),t.meta.revision+=1)}function o(t){i(u.name,"I",t)}function a(t){i(u.name,"U",t)}function h(t){r(t),o(t)}function l(t){s(t),a(t)}function c(){p=u.disableChangesApi?r:h,y=u.disableChangesApi?s:l}this.name=t,this.data=[],this.idIndex=[],this.binaryIndices={},this.constraints={unique:{},exact:{}},this.objType=t,this.dirty=!0,this.cachedIndex=null,this.cachedBinaryIndex=null,this.cachedData=null;var u=this;e=e||{},e.hasOwnProperty("unique")&&e.unique.forEach(function(t){u.constraints.unique[t]={}}),e.hasOwnProperty("exact")&&e.exact.forEach(function(t){u.constraints.exact[t]={}}),this.transactional=e.hasOwnProperty("transactional")?e.transactional:!1,this.cloneObjects=e.hasOwnProperty("clone")?e.clone:!1,this.asyncListeners=e.hasOwnProperty("asyncListeners")?e.asyncListeners:!1,this.disableChangesApi=e.hasOwnProperty("disableChangesApi")?e.disableChangesApi:!0,this.maxId=0,this.DynamicViews=[],this.events={insert:[],update:[],"pre-insert":[],"pre-update":[],close:[],flushbuffer:[],error:[],"delete":[],warning:[]},this.changes=[],this.ensureId();var f=[];if(e&&e.indices)if("[object Array]"===Object.prototype.toString.call(e.indices))f=e.indices;else{if("string"!=typeof e.indices)throw new TypeError("Indices needs to be a string or an array of strings");f=[e.indices]}for(var d=0;d<f.length;d++)this.ensureIndex(f[d]);this.getChanges=function(){return u.changes},this.flushChanges=n;var p,y;c(),this.setChangesApi=function(t){u.disableChangesApi=!t,c()},this.on("insert",function(t){p(t)}),this.on("update",function(t){y(t)}),this.on("delete",function(t){u.disableChangesApi||i(u.name,"R",t)}),this.on("warning",console.warn),n()}function d(t){return-1!==t.indexOf(".")}function p(t){return parseFloat(t,10)}function y(t,e){return t+e}function v(t,e){return t-e}function w(t){return t.reduce(y,0)/t.length}function g(t){var e=w(t),i=t.map(function(t){var i=t-e,n=i*i;return n}),n=w(i),r=Math.sqrt(n);return r}function m(t,e,i){if(i===!1)return t[e];for(var n=e.split("."),r=t;n.length>0;)r=r[n.shift()];return r}function b(t,e,i){for(var n,r,s=0,o=t.length;o>s;){if(r=(s+o)/2|0,n=i.apply(null,[e,t[r]]),0===n)return{found:!0,index:r};0>n?o=r:s=r+1}return{found:!1,index:o}}function I(t){return function(e,i){return b(e,i,t)}}function D(){}var x={copyProperties:function(t,e){var i;for(i in t)e[i]=t[i]}},O={$eq:function(t,e){return t===e},$gt:function(t,i){return e(t,i)},$gte:function(t,i){return e(t,i,!0)},$lt:function(e,i){return t(e,i)},$lte:function(e,i){return t(e,i,!0)},$ne:function(t,e){return t!==e},$regex:function(t,e){return e.test(t)},$in:function(t,e){return e.indexOf(t)>-1},$containsAny:function(t,e){var i;return Array.isArray(e)||(e=[e]),i=n(t,e)||function(){return!1},e.reduce(function(t,e){return t?t:i(e)},!1)},$contains:function(t,e){var i;return Array.isArray(e)||(e=[e]),i=n(t,e)||function(){return!0},e.reduce(function(t,e){return t?i(e):t},!0)}},C={$eq:O.$eq,$gt:O.$gt,$gte:O.$gte,$lt:O.$lt,$lte:O.$lte,$ne:O.$ne,$regex:O.$regex,$in:O.$in,$contains:O.$contains,$containsAny:O.$containsAny};return o.prototype.events={},o.prototype.asyncListeners=!1,o.prototype.on=function(t,e){var i=this.events[t];return i||(i=this.events[t]=[]),i.push(e),e},o.prototype.emit=function(t,e){var i=this;if(!t||!this.events[t])throw new Error("No event "+t+" defined");this.events[t].forEach(function(t){i.asyncListeners?setTimeout(function(){t(e)},1):t(e)})},o.prototype.removeListener=function(t,e){if(this.events[t]){var i=this.events[t];i.splice(i.indexOf(e),1)}},a.prototype=new o,a.prototype.configureOptions=function(t,e){var i={NODEJS:"fs",BROWSER:"localStorage",CORDOVA:"localStorage"},n={fs:h,localStorage:l};if(this.options={},this.persistenceMethod=null,this.persistenceAdapter=null,"undefined"!=typeof t){if(this.options=t,this.options.hasOwnProperty("persistenceMethod")&&"function"==typeof n[t.persistenceMethod]&&(this.persistenceMethod=t.persistenceMethod,this.persistenceAdapter=new n[t.persistenceMethod]),this.options.hasOwnProperty("adapter")&&(this.persistenceMethod="adapter",this.persistenceAdapter=t.adapter),t.hasOwnProperty("autoload")&&"undefined"!=typeof e&&e){var r=this;setTimeout(function(){r.loadDatabase(t,t.autoloadCallback)},1)}this.options.hasOwnProperty("autosaveInterval")&&(this.autosaveDisable(),this.autosaveInterval=parseInt(this.options.autosaveInterval,10)),this.options.hasOwnProperty("autosave")&&this.options.autosave&&(this.autosaveDisable(),this.autosave=!0,this.autosaveEnable())}null===this.persistenceAdapter&&(this.persistenceMethod=i[this.ENV],this.persistenceMethod&&(this.persistenceAdapter=new n[this.persistenceMethod]))},a.prototype.anonym=function(t,e){var i=new f("anonym",e);return i.insert(t),i},a.prototype.addCollection=function(t,e){var i=new f(t,e);return this.collections.push(i),i},a.prototype.loadCollection=function(t){if(!t.name)throw new Error("Collection must be have a name property to be loaded");this.collections.push(t)},a.prototype.getCollection=function(t){var e,i=this.collections.length;for(e=0;i>e;e+=1)if(this.collections[e].name===t)return this.collections[e];return this.emit("warning","collection "+t+" not found"),null},a.prototype.listCollections=function(){for(var t=this.collections.length,e=[];t--;)e.push({name:this.collections[t].name,type:this.collections[t].objType,count:this.collections[t].data.length});return e},a.prototype.removeCollection=function(t){var e,i=this.collections.length;for(e=0;i>e;e+=1)if(this.collections[e].name===t)return void this.collections.splice(e,1)},a.prototype.getName=function(){return this.name},a.prototype.serializeReplacer=function(t,e){switch(t){case"autosaveHandle":return null;case"persistenceAdapter":return null;default:return e}},a.prototype.serialize=function(){return JSON.stringify(this,this.serializeReplacer)},a.prototype.toJson=a.prototype.serialize,a.prototype.loadJSON=function(t,e){var i,n,r,s,o=JSON.parse(t),a=0,h=o.collections.length;for(this.name=o.name,this.databaseVersion=1,o.hasOwnProperty("databaseVersion")&&(this.databaseVersion=o.databaseVersion),this.collections=[],a;h>a;a+=1){if(i=o.collections[a],n=this.addCollection(i.name),r=i.data.length,s=0,e&&e.hasOwnProperty(i.name)){var l=e[i.name].inflate?e[i.name].inflate:x.copyProperties;for(s;r>s;s++){var c=new e[i.name].proto;l(i.data[s],c),n.data[s]=c}}else for(s;r>s;s++)n.data[s]=i.data[s];if(n.transactional=i.transactional,n.asyncListeners=i.asyncListeners,n.disableChangesApi=i.disableChangesApi,n.cloneObjects=i.cloneObjects,n.maxId=0===i.data.length?0:i.maxId,n.idIndex=i.idIndex,"undefined"!=typeof i.indices&&(n.idIndex=i.indices.id),"undefined"!=typeof i.binaryIndices&&(n.binaryIndices=i.binaryIndices),n.ensureId(),"undefined"!=typeof i.DynamicViews)for(var u=0;u<i.DynamicViews.length;u++){var f=i.DynamicViews[u],d=n.addDynamicView(f.name,f.persistent);d.resultdata=f.resultdata,d.resultsdirty=f.resultsdirty,d.filterPipeline=f.filterPipeline,d.sortCriteria=f.sortCriteria,d.sortFunction=null,d.sortDirty=f.sortDirty,d.resultset.filteredrows=f.resultset.filteredrows,d.resultset.searchIsChained=f.resultset.searchIsChained,d.resultset.filterInitialized=f.resultset.filterInitialized,d.rematerialize({removeWhereFilters:!0})}}},a.prototype.close=function(t){this.autosave&&(this.autosaveDisable(),this.autosaveDirty()&&this.saveDatabase()),t&&this.on("close",t),this.emit("close")},a.prototype.generateChangesNotification=function(t){function e(t){return t.name}var i=[],n=t||this.collections.map(e);return this.collections.forEach(function(t){-1!==n.indexOf(e(t))&&(i=i.concat(t.getChanges()))}),i},a.prototype.serializeChanges=function(t){return JSON.stringify(this.generateChangesNotification(t))},a.prototype.clearChanges=function(){this.collections.forEach(function(t){t.flushChanges&&t.flushChanges()})},h.prototype.loadDatabase=function(t,e){this.fs.readFile(t,{encoding:"utf8"},function(t,i){e(t?new Error(t):i)})},h.prototype.saveDatabase=function(t,e,i){this.fs.writeFile(t,e,i)},l.prototype.loadDatabase=function(t,e){e(s()?localStorage.getItem(t):new Error("localStorage is not available"))},l.prototype.saveDatabase=function(t,e,i){s()?(localStorage.setItem(t,e),i(null)):i(new Error("localStorage is not available"))},a.prototype.loadDatabase=function(t,e){var i=e||function(t){if(t)throw t},n=this;null!==this.persistenceAdapter?this.persistenceAdapter.loadDatabase(this.filename,function(e){"string"==typeof e?(n.loadJSON(e,t||{}),i(null)):(console.warn("lokijs loadDatabase : Database not found"),i("object"==typeof e?e:"Database not found"))}):i(new Error("persistenceAdapter not configured"))},a.prototype.saveDatabase=function(t){var e=t||function(t){if(t)throw t},i=this;null!==this.persistenceAdapter?this.persistenceAdapter.saveDatabase(this.filename,i.serialize(),function(){i.autosaveClearFlags(),e(null)}):e(new Error("persistenceAdapter not configured"))},a.prototype.save=a.prototype.saveDatabase,a.prototype.autosaveDirty=function(){for(var t=0;t<this.collections.length;t++)if(this.collections[t].dirty)return!0;return!1},a.prototype.autosaveClearFlags=function(){for(var t=0;t<this.collections.length;t++)this.collections[t].dirty=!1},a.prototype.autosaveEnable=function(){this.autosave=!0;var t=5e3,e=this;"undefined"!=typeof this.autosaveInterval&&null!==this.autosaveInterval&&(t=this.autosaveInterval),this.autosaveHandle=setInterval(function(){e.autosaveDirty()&&e.saveDatabase()},t)},a.prototype.autosaveDisable=function(){"undefined"!=typeof this.autosaveHandle&&null!==this.autosaveHandle&&(clearInterval(this.autosaveHandle),this.autosaveHandle=null)},c.prototype.toJSON=function(){var t=this.copy();return t.collection=null,t},c.prototype.limit=function(t){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));var e=this.copy();return e.filteredrows=e.filteredrows.slice(0,t),e},c.prototype.offset=function(t){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));var e=this.copy();return e.filteredrows=e.filteredrows.splice(t,e.filteredrows.length),e},c.prototype.copy=function(){var t=new c(this.collection,null,null);return t.filteredrows=this.filteredrows.slice(),t.filterInitialized=this.filterInitialized,t},c.prototype.branch=c.prototype.copy,c.prototype.sort=function(t){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));var e=function(t,e){return function(i,n){var r=e.collection.data[i],s=e.collection.data[n];return t(r,s)}}(t,this);return this.filteredrows.sort(e),this},c.prototype.simplesort=function(t,e){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data)),"undefined"==typeof e&&(e=!1);var n=function(t,e,n){return function(r,s){var o=n.collection.data[r],a=n.collection.data[s];return i(o[t],a[t],e)}}(t,e,this);return this.filteredrows.sort(n),this},c.prototype.compoundeval=function(t,e,n){var r=t.length;if(0===r)throw new Error("Invalid call to compoundeval, need at least one property");var s=!1,o=t[0];return"string"!=typeof o&&Array.isArray(o)&&(s=o[1],o=o[0]),e[o]===n[o]?1===r?0:this.compoundeval(t.slice(1),e,n,s):i(e[o],n[o],s)},c.prototype.compoundsort=function(t){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));var e=function(t,e){return function(i,n){var r=e.collection.data[i],s=e.collection.data[n];return e.compoundeval(t,r,s)}}(t,this);return this.filteredrows.sort(e),this},c.prototype.calculateRange=function(i,n,r){var s=this.collection.data,o=this.collection.binaryIndices[n].values,a=0,h=o.length-1,l=null,c=0,u=o.length-1;if(0===s.length)return[0,-1];var f=s[o[a]][n],d=s[o[h]][n];switch(i){case"$eq":if(t(r,f)||e(r,d))return[0,-1];break;case"$gt":if(e(r,d,!0))return[0,-1];break;case"$gte":if(e(r,d))return[0,-1];break;case"$lt":if(t(r,f,!0))return[0,-1];break;case"$lte":if(t(r,f))return[0,-1]}for(;h>a;)l=Math.floor((a+h)/2),t(s[o[l]][n],r)?a=l+1:h=l;for(c=a,a=0,h=o.length-1;h>a;)l=Math.floor((a+h)/2),t(r,s[o[l]][n])?h=l:a=l+1;u=h;var p=s[o[c]][n],y=s[o[u]][n];switch(i){case"$eq":return p!==r?[0,-1]:(y!==r&&u--,[c,u]);case"$gt":return t(y,r,!0)?[0,-1]:[u,s.length-1];case"$gte":return t(p,r)?[0,-1]:[c,s.length-1];case"$lt":return 0===c&&t(p,r)?[0,0]:[0,c-1];case"$lte":return y!==r&&u--,0===u&&t(y,r)?[0,0]:[0,u];default:return[0,s.length-1]}},c.prototype.findOr=function(t){var e=0,i=0,n=null,r=[],s=null;if(this.filterInitialized){for(r=[],i=0;i<t.length;i++)for(s=this.branch(),s.find(t[i]),s.data(),n=s.filteredrows,e=0;e<n.length;e++)-1===r.indexOf(n[e])&&r.push(n[e]);this.filteredrows=r}else for(i=0;i<t.length;i++)for(s=this.collection.chain(),s.find(t[i]),s.data(),n=s.filteredrows,e=0;e<n.length;e++)-1===this.filteredrows.indexOf(n[e])&&this.filteredrows.push(n[e]);return this.filterInitialized=!0,this},c.prototype.findAnd=function(t){for(var e=0;e<t.length;e++)this.find(t[e]);return this},c.prototype.dotSubScan=function(t,e,i,n){var r,s,o,a=null,h=e.split(".");for(r=0;r<h.length;r++)if(o=h[r],a){for(s=0;s<a.length;s++)if(i(a[s][o],n))return!0}else t=t[o],Array.isArray(t)&&(a=t);return i(t,n)},c.prototype.find=function(t,e){if(0===this.collection.data.length)return this.searchIsChained?(this.filteredrows=[],this.filterInitialized=!0,this):[];var i,n,r,s,o,a,h,l,c=t||"getAll",u=!1,f=[],d=null,p=!0;e=e||!1;for(s in c){p=!1;break}if(p&&(c="getAll"),"getAll"===c)return this.searchIsChained?(this.filteredrows=Object.keys(this.collection.data),this):this.collection.data;var y=!1;for(s in c)if(c.hasOwnProperty(s)){if(i=s,"$and"===s)return this.searchIsChained?(this.findAnd(c[s]),e&&this.filteredrows.length>1&&(this.filteredrows=this.filteredrows.slice(0,1)),this):(f=this.collection.chain().findAnd(c[s]).data(),e?0===f.length?[]:f[0]:f);if("$or"===s)return this.searchIsChained?(this.findOr(c[s]),e&&this.filteredrows.length>1&&(this.filteredrows=this.filteredrows.slice(0,1)),this):(f=this.collection.chain().findOr(c[s]).data(),e?0===f.length?[]:f[0]:f);if(-1!=s.indexOf(".")&&(y=!0),"object"!=typeof c[s])r="$eq",n=c[s];else{if("object"!=typeof c[s])throw"Do not know what you want to do.";for(o in c[s])c[s].hasOwnProperty(o)&&(r=o,n=c[s][o])}break}if("$regex"===r&&(n=new RegExp(n)),null===this.collection.data)throw new TypeError;if((!this.searchIsChained||this.searchIsChained&&!this.filterInitialized)&&"$ne"!==r&&"$regex"!==r&&"$contains"!==r&&"$containsAny"!==r&&"$in"!==r&&this.collection.binaryIndices.hasOwnProperty(i)&&(this.collection.ensureIndex(i),u=!0,d=this.collection.binaryIndices[i]),a=C[r],this.searchIsChained){if(this.filterInitialized){if(u)for(h=d,l=this.filteredrows.length;l--;)a(h[this.filteredrows[l]],n)&&f.push(this.filteredrows[l]);else if(h=this.collection.data,l=this.filteredrows.length,y)for(;l--;)this.dotSubScan(h[this.filteredrows[l]],i,a,n)&&f.push(this.filteredrows[l]);else for(;l--;)a(h[this.filteredrows[l]][i],n)&&f.push(this.filteredrows[l]);return this.filteredrows=f,this}if(u){h=this.collection.data;for(var v=this.calculateRange(r,i,n,this),w=v[0];w<=v[1];w++)f.push(d.values[w]);this.filteredrows=f}else if(h=this.collection.data,l=h.length,y)for(;l--;)this.dotSubScan(h[l],i,a,n)&&f.push(l);else for(;l--;)a(h[l][i],n)&&f.push(l);return this.filteredrows=f,this.filterInitialized=!0,this}if(u){h=this.collection.data;var v=this.calculateRange(r,i,n,this);if(e)return-1!==v[1]?h[d.values[v[0]]]:[];for(l=v[0];l<=v[1];l++)f.push(h[d.values[l]]);this.filteredrows=f}else{if(h=this.collection.data,l=h.length,e){for(;l--;)if(a(h[l][i],n))return h[l];return[]}if(y)for(;l--;)this.dotSubScan(h[l],i,a,n)&&f.push(h[l]);else for(;l--;)a(h[l][i],n)&&f.push(h[l])}return f},c.prototype.where=function(t){var e,i=[];if("function"!=typeof t)throw"Argument is not a stored view or a function";e=t;try{if(this.searchIsChained){if(this.filterInitialized){for(var n=this.filteredrows.length;n--;)e(this.collection.data[this.filteredrows[n]])===!0&&i.push(this.filteredrows[n]);return this.filteredrows=i,this}for(var n=this.collection.data.length;n--;)e(this.collection.data[n])===!0&&i.push(n);return this.filteredrows=i,this.filterInitialized=!0,this}for(var n=this.collection.data.length;n--;)e(this.collection.data[n])===!0&&i.push(this.collection.data[n]);return i}catch(r){throw r}},c.prototype.data=function(){var t=[];if(this.searchIsChained&&!this.filterInitialized){if(0===this.filteredrows.length)return this.collection.data;this.filterInitialized=!0}var e,i=this.collection.data,n=this.filteredrows,r=this.filteredrows.length;for(e=0;r>e;e++)t.push(i[n[e]]);return t},c.prototype.update=function(t){if("function"!=typeof t)throw"Argument is not a function";this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));for(var e=this.filteredrows.length,i=this.collection.data,n=0;e>n;n++)t(i[this.filteredrows[n]]),this.collection.update(i[this.filteredrows[n]]);return this},c.prototype.remove=function(){this.searchIsChained&&!this.filterInitialized&&0===this.filteredrows.length&&(this.filteredrows=Object.keys(this.collection.data));for(var t=this.filteredrows.length,e=0;t>e;e++)this.collection.remove(this.filteredrows[e]);return this.filteredrows=[],this},c.prototype.mapReduce=function(t,e){try{return e(this.data().map(t))}catch(i){throw i}},c.prototype.eqJoin=function(t,e,i,n){var r,s,o,a=[],h=[],l=[],u="function"==typeof e,d="function"==typeof i,p={};if(a=this.data(),r=a.length,t instanceof c)h=t.data();else{if(!Array.isArray(t))throw new TypeError("joinData needs to be an array or result set");h=t}s=h.length;for(var y=0;s>y;y++)o=d?i(h[y]):h[y][i],p[o]=h[y];n||(n=function(t,e){return{left:t,right:e}});for(var y=0;r>y;y++)o=u?e(a[y]):a[y][e],l.push(n(a[y],p[o]||{}));return this.collection=new f("joinData"),this.collection.insert(l),this.filteredrows=[],this.filterInitialized=!1,this},c.prototype.map=function(t){var e=this.data().map(t);return this.collection=new f("mappedData"),this.collection.insert(e),this.filteredrows=[],this.filterInitialized=!1,this},u.prototype=new o,u.prototype.rematerialize=function(t){var e,i,n;if(t=t||{},this.resultdata=[],this.resultsdirty=!0,this.resultset=new c(this.collection),(this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0),t.hasOwnProperty("removeWhereFilters"))for(e=this.filterPipeline.length,i=e;i--;)"where"===this.filterPipeline[i].type&&(i!==this.filterPipeline.length-1&&(this.filterPipeline[i]=this.filterPipeline[this.filterPipeline.length-1]),this.filterPipeline.length--);var r=this.filterPipeline;for(this.filterPipeline=[],e=r.length,n=0;e>n;n++)this.applyFind(r[n].val);return this.data(),this.emit("rebuild",this),this},u.prototype.branchResultset=function(){return this.resultset.copy()},u.prototype.toJSON=function(){var t=new u(this.collection,this.name,this.persistent);return t.resultset=this.resultset,t.resultdata=[],t.resultsdirty=!0,t.filterPipeline=this.filterPipeline,t.sortFunction=this.sortFunction,t.sortCriteria=this.sortCriteria,t.sortDirty=this.sortDirty,t.collection=null,t},u.prototype.applySort=function(t){return this.sortFunction=t,this.sortCriteria=null,this.queueSortPhase(),this},u.prototype.applySimpleSort=function(t,e){return"undefined"==typeof e&&(e=!1),this.sortCriteria=[[t,e]],this.sortFunction=null,this.queueSortPhase(),this},u.prototype.applySortCriteria=function(t){return this.sortCriterial=t,this.sortFunction=null,this.queueSortPhase(),this},u.prototype.startTransaction=function(){return this.cachedresultset=this.resultset.copy(),this},u.prototype.commit=function(){return this.cachedresultset=null,this},u.prototype.rollback=function(){return this.resultset=this.cachedresultset,this.persistent&&(this.resultdata=this.resultset.data(),this.emit("rebuild",this)),this},u.prototype.applyFind=function(t){return this.filterPipeline.push({type:"find",val:t}),this.resultset.find(t),(this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0,this.queueSortPhase()),this.persistent&&(this.resultsdirty=!0,this.queueSortPhase()),this},u.prototype.applyWhere=function(t){return this.filterPipeline.push({type:"where",val:t}),this.resultset.where(t),(this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0,this.queueSortPhase()),this.persistent&&(this.resultsdirty=!0,this.queueSortPhase()),this},u.prototype.data=function(){return(this.sortDirty||this.resultsdirty||!this.resultset.filterInitialized)&&this.performSortPhase(),this.persistent?this.resultdata:this.resultset.data()},u.prototype.queueSortPhase=function(){var t=this;this.sortDirty||(this.sortDirty=!0,setTimeout(function(){t.performSortPhase()},1))},u.prototype.performSortPhase=function(){if(this.sortDirty||this.resultsdirty||!this.resultset.filterInitialized){if(this.sortFunction&&this.resultset.sort(this.sortFunction),this.sortCriteria&&this.resultset.compoundsort(this.sortCriteria),!this.persistent)return void(this.sortDirty=!1);this.resultdata=this.resultset.data(),this.resultsdirty=!1,this.sortDirty=!1,this.emit("rebuild",this)}},u.prototype.evaluateDocument=function(t){var e=this.resultset.filteredrows,i=e.indexOf(t),n=e.length,r=new c(this.collection);r.filteredrows=[t],r.filterInitialized=!0;for(var s=0;s<this.filterPipeline.length;s++)switch(this.filterPipeline[s].type){case"find":r.find(this.filterPipeline[s].val);break;case"where":r.where(this.filterPipeline[s].val)}var o=0===r.filteredrows.length?-1:0;return-1!=i||-1!=o?-1===i&&-1!==o?(e.push(t),this.persistent&&this.resultdata.push(this.collection.data[t]),void((this.sortFunction||this.sortCriteria)&&this.queueSortPhase())):-1!==i&&-1===o?(n-1>i?(e[i]=e[n-1],e.length=n-1,this.persistent&&(this.resultdata[i]=this.resultdata[n-1],this.resultdata.length=n-1)):(e.length=n-1,this.persistent&&(this.resultdata.length=n-1)),void((this.sortFunction||this.sortCriteria)&&this.queueSortPhase())):-1!==i&&-1!==o?(this.persistent&&(this.resultdata[i]=this.collection.data[t]),void((this.sortFunction||this.sortCriteria)&&(this.sortDirty=!0))):void 0:void 0},u.prototype.removeDocument=function(t){var e,i=this.resultset.filteredrows,n=i.indexOf(t),r=i.length;for(-1!==n&&(r-1>n?(i[n]=i[r-1],i.length=r-1,this.persistent&&(this.resultdata[n]=this.resultdata[r-1],this.resultdata.length=r-1)):(i.length=r-1,this.persistent&&(this.resultdata.length=r-1)),(this.sortFunction||this.sortCriteria)&&this.queueSortPhase()),r=i.length,e=0;r>e;e++)i[e]>t&&i[e]--},u.prototype.mapReduce=function(t,e){try{return e(this.data().map(t))}catch(i){throw i}},f.prototype=new o,f.prototype.ensureIndex=function(i,n){if("undefined"==typeof n&&(n=!1),null===i||void 0===i)throw"Attempting to set index without an associated property";if(!this.binaryIndices.hasOwnProperty(i)||n||this.binaryIndices[i].dirty){this.binaryIndices[i]={name:i,dirty:!0,values:[]};var r,s=this.data.length,o=0;for(r=this.binaryIndices[i],o;s>o;o+=1)r.values.push(o);var a=function(i,n){return function(r,s){var o=n.data[r],a=n.data[s];return o[i]===a[i]?0:e(o[i],a[i])?1:t(o[i],a[i])?-1:void 0}}(i,this);r.values.sort(a),r.dirty=!1,this.dirty=!0}},f.prototype.ensureAllIndexes=function(t){for(var e=Object.keys(this.binaryIndices),i=e.length;i--;)this.ensureIndex(e[i],t)},f.prototype.flagBinaryIndexesDirty=function(){for(var t=Object.keys(this.binaryIndices),e=t.length;e--;)this.binaryIndices[t[e]].dirty=!0},f.prototype.ensureId=function(){var t=this.data.length,e=0;for(this.idIndex=[],e;t>e;e+=1)this.idIndex.push(this.data[e].$loki)},f.prototype.ensureIdAsync=function(t){this.async(function(){this.ensureId()},t)},f.prototype.addDynamicView=function(t,e){var i=new u(this,t,e);return this.DynamicViews.push(i),i},f.prototype.removeDynamicView=function(t){for(var e=0;e<this.DynamicViews.length;e++)this.DynamicViews[e].name===t&&this.DynamicViews.splice(e,1)},f.prototype.getDynamicView=function(t){for(var e=0;e<this.DynamicViews.length;e++)if(this.DynamicViews[e].name===t)return this.DynamicViews[e];return null},f.prototype.findAndUpdate=function(t,e){var i,n=this.where(t),r=0;try{for(r;r<n.length;r++)i=e(n[r]),this.update(i)}catch(s){this.rollback(),console.error(s.message)}},f.prototype.insert=function(t){if(!t){var e=new Error("Object cannot be null");throw this.emit("error",e),e}var i,n=this,r=Array.isArray(t)?t:[t];return r.forEach(function(t){if("object"!=typeof t)throw new TypeError("Document needs to be an object");return i=n.clone?JSON.parse(JSON.stringify(t)):t,"undefined"==typeof i.meta&&(i.meta={revision:0,created:0}),n.emit("pre-insert",i),n.add(i)?void n.emit("insert",i):void 0}),i},f.prototype.clear=function(){this.data=[],this.idIndex=[],this.binaryIndices={},this.cachedIndex=null,this.cachedData=null,this.maxId=0,this.DynamicViews=[],this.dirty=!0},f.prototype.update=function(t){if(Object.keys(this.binaryIndices).length>0&&this.flagBinaryIndexesDirty(),Array.isArray(t)){var e=0,i=t.length;for(e;i>e;e+=1)this.update(t[e])}else{if(!t.hasOwnProperty("$loki"))throw"Trying to update unsynced document. Please save the document first by using insert() or addMany()";try{this.startTransaction();var n,r,s=this.get(t.$loki,!0);if(!s)throw new Error("Trying to update a document not in collection.");this.emit("pre-update",t),n=s[0],r=s[1],this.data[r]=t;for(var o=0;o<this.DynamicViews.length;o++)this.DynamicViews[o].evaluateDocument(r);this.idIndex[r]=n.$loki,this.commit(),this.dirty=!0,this.emit("update",t)}catch(a){throw this.rollback(),console.error(a.message),this.emit("error",a),a}}},f.prototype.add=function(t){var e,i=this.DynamicViews.length;if("object"!=typeof t)throw"Object being added needs to be an object";if(Object.keys(this.binaryIndices).length>0&&this.flagBinaryIndexesDirty(),"undefined"!=typeof t.$loki)throw"Document is already in collection, please use update()";try{this.startTransaction(),this.maxId++;var e;isNaN(this.maxId)&&(this.maxId=this.data[this.data.length-1].$loki+1),t.$loki=this.maxId,t.meta.version=0,this.data.push(t);var n=this;for(Object.keys(n.constraints.unique).forEach(function(e){if(t.hasOwnProperty(e)){if(n.constraints.unique[e][t[e]])throw n.emit("error","Duplicate key for key "+e+" (value "+t[e]+" + already in collection)"),n.data.pop(),new Error("Duplicate key for property "+e);n.constraints.unique[e][t[e]]=t}}),e=0;i>e;e++)this.DynamicViews[e].evaluateDocument(this.data.length-1);return this.idIndex.push(t.$loki),this.commit(),this.dirty=!0,t}catch(r){this.rollback(),console.error(r.message)}},f.prototype.removeWhere=function(t){var e;e="function"==typeof t?this.data.filter(t):new c(this,t);for(var i=e.length;i--;)this.remove(e[i])},f.prototype.removeDataOnly=function(){this.removeWhere(function(){return!0})},f.prototype.remove=function(t){if("number"==typeof t&&(t=this.get(t)),"object"!=typeof t)throw new Error("Parameter is not an object");if(Array.isArray(t)){var e=0,i=t.length;for(e;i>e;e+=1)this.remove(t[e])}else{if(!t.hasOwnProperty("$loki"))throw new Error("Object is not a document stored in the collection");Object.keys(this.binaryIndices).length>0&&this.flagBinaryIndexesDirty();try{this.startTransaction();var n=this.get(t.$loki,!0),r=n[1],s=this;Object.keys(this.constraints.unique).forEach(function(e){s.constraints.unique[e][t[e]]=null,delete s.constraints.unique[e][t[e]]});for(var o=0;o<this.DynamicViews.length;o++)this.DynamicViews[o].removeDocument(r);this.data.splice(r,1),this.idIndex.splice(r,1),this.commit(),this.dirty=!0,this.emit("delete")}catch(a){this.rollback(),console.error(a.message),this.emit("error",a)}}},f.prototype.get=function(t,e){var i=e||!1,n=this.idIndex,r=n.length-1,s=0,o=Math.floor(s+(r-s)/2);if(t="number"==typeof t?t:parseInt(t,10),isNaN(t))throw"Passed id is not an integer";for(;n[s]<n[r];)o=Math.floor((s+r)/2),n[o]<t?s=o+1:r=o;return r===s&&n[s]===t?i?[this.data[s],s]:this.data[s]:null},f.prototype.by=function(t,e){var i;return e?this.constraints.unique[t]&&this.constraints.unique[t][e]?this.constraints.unique[t][e]:void 0:(i=this,function(e){return i.by(t,e)})},f.prototype.findOne=function(t){var e=new c(this,t,null,!0);return Array.isArray(e)&&0===e.length?null:e},f.prototype.chain=function(){return new c(this,null,null)},f.prototype.find=function(t){return"undefined"==typeof t&&(t="getAll"),new c(this,t,null)},f.prototype.findOneUnindexed=function(t,e){for(var i,n=this.data.length;n--;)if(this.data[n][t]===e)return i=this.data[n];return null},f.prototype.startTransaction=function(){if(this.transactional){this.cachedData=r(this.data,"parse-stringify"),this.cachedIndex=this.idIndex,this.cachedBinaryIndex=this.binaryIndices;for(var t=0;t<this.DynamicViews.length;t++)this.DynamicViews[t].startTransaction()}},f.prototype.commit=function(){if(this.transactional){this.cachedData=null,this.cachedIndex=null,this.cachedBinaryIndices=null;for(var t=0;t<this.DynamicViews.length;t++)this.DynamicViews[t].commit()}},f.prototype.rollback=function(){if(this.transactional){null!==this.cachedData&&null!==this.cachedIndex&&(this.data=this.cachedData,this.idIndex=this.cachedIndex,this.binaryIndices=this.cachedBinaryIndex);for(var t=0;t<this.DynamicViews.length;t++)this.DynamicViews[t].rollback()}},f.prototype.async=function(t,e){setTimeout(function(){if("function"!=typeof t)throw"Argument passed for async execution is not a function";t(),e()},0)},f.prototype.where=function(t){return new c(this,null,t)},f.prototype.mapReduce=function(t,e){try{return e(this.data.map(t))}catch(i){throw i}},f.prototype.eqJoin=function(t,e,i,n){return new c(this).eqJoin(t,e,i,n)},f.prototype.no_op=function(){},f.prototype.extract=function(t){var e=0,i=this.data.length,n=d(t),r=[];
for(e;i>e;e+=1)r.push(m(this.data[e],t,n));return r},f.prototype.max=function(t){return Math.max.apply(null,this.extract(t))},f.prototype.min=function(t){return Math.min.apply(null,this.extract(t))},f.prototype.maxRecord=function(t){var e=0,i=this.data.length,n=d(t),r={index:0,value:void 0},s=void 0;for(e;i>e;e+=1)void 0!==s?s<m(this.data[e],t,n)&&(s=m(this.data[e],t,n),r.index=this.data[e].$loki):(s=m(this.data[e],t,n),r.index=this.data[e].$loki);return r.value=s,r},f.prototype.minRecord=function(t){var e=0,i=this.data.length,n=d(t),r={index:0,value:void 0},s=void 0;for(e;i>e;e+=1)void 0!==s?s>m(this.data[e],t,n)&&(s=m(this.data[e],t,n),r.index=this.data[e].$loki):(s=m(this.data[e],t,n),r.index=this.data[e].$loki);return r.value=s,r},f.prototype.extractNumerical=function(t){return this.extract(t).map(p).filter(Number).filter(function(t){return!isNaN(t)})},f.prototype.avg=function(t){return w(this.extractNumerical(t))},f.prototype.stdDev=function(t){return g(this.extractNumerical(t))},f.prototype.mode=function(t){var e={},i=this.extract(t);i.forEach(function(t){e[t]?e[t]+=1:e[t]=1});var n,r,s=void 0;for(n in e)s?s<e[n]&&(r=n):(r=n,s=e[n]);return r},f.prototype.median=function(t){var e=this.extractNumerical(t);e.sort(v);var i=Math.floor(e.length/2);return e.length%2?e[i]:(e[i-1]+e[i])/2},D.prototype={keys:[],values:[],sort:function(t,e){return e>t?-1:t>e?1:0},setSort:function(t){this.bs=new I(t)},bs:function(){return new I(this.sort)},set:function(t,e){var i=this.bs(this.keys,t);i.found?this.values[i.index]=e:(this.keys.splice(i.index,0,t),this.values.splice(i.index,0,e))},get:function(t){return this.values[b(this.keys,t,this.sort).index]}},a.Collection=f,a.KeyValueStore=D,a}()});
{
"name": "lokijs",
"version": "1.2.3",
"version": "1.2.4",
"description": "Fast document oriented javascript in-memory database",

@@ -24,3 +24,3 @@ "homepage": "http://lokijs.org",

"scripts": {
"test": "make test && istanbul cover tests/"
"test": "karma start karma.conf.js --single-run"
},

@@ -43,3 +43,8 @@ "author": "Joe Minichino <joe.minichino@gmail.com>",

"istanbul": "^0.3.2",
"karma": "^0.12.31",
"karma-cli": "0.0.4",
"karma-jasmine": "^0.3.5",
"karma-phantomjs-launcher": "^0.1.4",
"mocha": "^2.0.1",
"phantomjs": "^1.9.16",
"should": "^4.3.0",

@@ -46,0 +51,0 @@ "uglify-js": "^2.4.15"

# LokiJS
[![Join the chat at https://gitter.im/techfort/LokiJS](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/techfort/LokiJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![alt CI-badge](https://travis-ci.org/techfort/LokiJS.svg?branch=master)
[![npm version](https://badge.fury.io/js/lokijs.svg)](http://badge.fury.io/js/lokijs)
[![alt packagequality](http://npm.packagequality.com/shield/lokijs.svg)](http://packagequality.com/#?package=lokijs)

@@ -19,11 +22,11 @@ ## Overview

example usage [here](https://github.com/techfort/LokiJS/wiki)
## Demo
## Current state
The following demos are available:
- [Sandbox / Playground] (https://rawgit.com/techfort/LokiJS/master/examples/sandbox/LokiSandbox.htm)
- a node-webkit small demo in the folder demos/desktop_app. You can launch it by running `/path/to/nw demos/desktop_app/'
LokiJS is at version 1.2 [Schnee]. While the roadmap is exciting, LokiJS is at the moment stable.
As LokiJS is written in Javascript it can be run on any environment supporting javascript such as browsers, node.js/node-webkit, hybrid mobile apps (such as phonegap/cordova), or the jvm through engines such as rhino.
## Wiki
Example usage can be found on the [wiki](https://github.com/techfort/LokiJS/wiki)
Made by [@techfort](http://twitter.com/tech_fort), with the precious help of Dave Easterday. [Leave a tip](https://gratipay.com/techfort/) or give us a star if you find LokiJS useful!
### Main Features

@@ -37,2 +40,9 @@

## Current state
LokiJS is at version 1.2 [Schnee]. While the roadmap is exciting, LokiJS is at the moment stable.
As LokiJS is written in Javascript it can be run on any environment supporting javascript such as browsers, node.js/node-webkit, and hybrid mobile apps (such as phonegap/cordova).
Made by [@techfort](http://twitter.com/tech_fort), with the precious help of Dave Easterday. [Leave a tip](https://gratipay.com/techfort/) or give us a star if you find LokiJS useful!
## Installation

@@ -46,5 +56,3 @@

## Demo
There's a node-webkit small demo in the folder demos/desktop_app. You can launch it by running `/path/to/nw demos/desktop_app/'

@@ -51,0 +59,0 @@ ## Roadmap

@@ -1,46 +0,56 @@

var loki = require('../src/lokijs.js'),
db = new loki(),
gordian = require('gordian'),
suite = new gordian('testEvents'),
options = {
asyncListeners: false,
disableChangesApi: false
},
users = db.addCollection('users', options),
test = db.addCollection('test', options),
test2 = db.addCollection('test2', options);
// var loki = require('../src/lokijs.js'),
describe('changesApi', function () {
it('does what it says on the tin', function () {
var db = new loki(),
// gordian = require('gordian'),
// suite = new gordian('testEvents'),
options = {
asyncListeners: false,
disableChangesApi: false
},
users = db.addCollection('users', options),
test = db.addCollection('test', options),
test2 = db.addCollection('test2', options);
var u = users.insert({
name: 'joe'
});
u.name = 'jack';
users.update(u);
test.insert({
name: 'test'
});
test2.insert({
name: 'test2'
});
var u = users.insert({
name: 'joe'
});
u.name = 'jack';
users.update(u);
test.insert({
name: 'test'
});
test2.insert({
name: 'test2'
});
var userChanges = db.generateChangesNotification(['users']);
suite.assertEqual('Single collection changes', 2, userChanges.length);
suite.assertEqual('Check serialized changes', db.serializeChanges(['users']), JSON.stringify(userChanges));
var someChanges = db.generateChangesNotification(['users', 'test2']);
suite.assertEqual('Changes number for selected collections', 3, someChanges.length);
var allChanges = db.generateChangesNotification();
suite.assertEqual('Changes number for all collections', 4, allChanges.length);
users.setChangesApi(false);
suite.assertEqual('Changes Api disabled', true, users.disableChangesApi);
u.name = 'john';
users.update(u);
var newChanges = db.generateChangesNotification(['users']);
suite.assertEqual('Change should not register after Api disabled', 2, newChanges.length);
db.clearChanges();
suite.assertEqual('clearChanges should wipe changes', 0, users.getChanges().length);
var userChanges = db.generateChangesNotification(['users']);
u.name = 'jim';
users.update(u);
users.flushChanges();
suite.assertEqual('Collection level changes flush', 0, users.getChanges().length);
expect(userChanges.length).toEqual(2);
expect(db.serializeChanges(['users'])).toEqual(JSON.stringify(userChanges));
suite.report();
var someChanges = db.generateChangesNotification(['users', 'test2']);
expect(someChanges.length).toEqual(3);
var allChanges = db.generateChangesNotification();
expect(allChanges.length).toEqual(4);
users.setChangesApi(false);
expect(users.disableChangesApi).toEqual(true);
u.name = 'john';
users.update(u);
var newChanges = db.generateChangesNotification(['users']);
expect(newChanges.length).toEqual(2);
db.clearChanges();
expect(users.getChanges().length).toEqual(0);
u.name = 'jim';
users.update(u);
users.flushChanges();
expect(users.getChanges().length).toEqual(0);
});
});

@@ -1,37 +0,36 @@

var loki = require('../src/lokijs.js'),
db = new loki('test', {
persistenceMethod: null
}),
gordian = require('gordian'),
suite = new gordian('testEvents'),
users = db.addCollection('users', {
asyncListeners: false
});
// var loki = require('../src/lokijs.js'),
describe('eventEmitter', function () {
var db;
users.insert({
name: 'joe'
});
beforeEach(function () {
db = new loki('test', {
persistenceMethod: null
}),
users = db.addCollection('users', {
asyncListeners: false
});
function testAsync() {
suite.assertEqual('DB events async', db.asyncListeners, false);
}
users.insert({
name: 'joe'
});
});
function testEmit() {
var index = db.on('test', function test(obj) {
suite.assertEqual('Argument passed to event', 42, obj);
it('async', function testAsync() {
expect(db.asyncListeners).toBe(false);
});
db.emit('test', 42);
db.removeListener('test', index);
it('emit', function () {
var index = db.on('test', function test(obj) {
expect(obj).toEqual(42);
});
suite.assertEqual('Event has no listeners attached', db.events['test'].length, 0);
db.emit('test', 42);
db.removeListener('test', index);
suite.assertThrows('No event testEvent', function testEvent() {
db.emit('testEvent');
}, Error);
}
expect(db.events['test'].length).toEqual(0);
testAsync();
testEmit();
suite.report();
expect(function testEvent() {
db.emit('testEvent');
}).toThrow(new Error('No event testEvent defined'));
});
});

@@ -1,9 +0,10 @@

require('./test');
require('./testTyped');
require('./eventEmitter');
require('./changesApi');
require('./testCollection');
require('./nodePersistence');
require('./testRemove');
require('./testCryptedFileAdapter');
require('./testStats');
// require('./test');
//require('./testTyped');
// require('./eventEmitter');
// require('./changesApi');
// require('./testCollection');
// require('./nodePersistence');
// require('./testRemove');
// require('./testCryptedFileAdapter');
// require('./testStats');
// require('./joins');

@@ -1,40 +0,40 @@

var loki = require('../src/lokijs.js'),
db = new loki('./loki.json'),
gordian = require('gordian'),
suite = new gordian('nodePersistence'),
users = db.addCollection('users');
// var loki = require('../src/lokijs.js'),
// db = new loki('./loki.json'),
// gordian = require('gordian'),
// suite = new gordian('nodePersistence'),
// users = db.addCollection('users');
users.insert([{
name: 'joe'
}, {
name: 'jack'
}]);
// users.insert([{
// name: 'joe'
// }, {
// name: 'jack'
// }]);
db.saveDatabase( function reload(){
// db.saveDatabase( function reload(){
var reloaded = new loki('./loki.json');
reloaded.loadDatabase({}, function () {
var users2 = reloaded.getCollection('users');
suite.assertEqual('There are 2 objects in the reloaded db', 2, users2.data.length);
require('fs').unlink('./loki.json');
});
});
// var reloaded = new loki('./loki.json');
// reloaded.loadDatabase({}, function () {
// var users2 = reloaded.getCollection('users');
// suite.assertEqual('There are 2 objects in the reloaded db', 2, users2.data.length);
// require('fs').unlink('./loki.json');
// });
// });
// test autoload callback fires even when database does not exist
function testAutoLoad() {
var cbSuccess = false;
// // test autoload callback fires even when database does not exist
// function testAutoLoad() {
// var cbSuccess = false;
var tdb = new loki('nonexistent.db',
{
autoload: true,
autoloadCallback : function() { cbSuccess = true; }
});
// var tdb = new loki('nonexistent.db',
// {
// autoload: true,
// autoloadCallback : function() { cbSuccess = true; }
// });
setTimeout(function() {
suite.assertEqual('autoload callback was called', cbSuccess, true);
suite.report();
}, 500);
}
// setTimeout(function() {
// suite.assertEqual('autoload callback was called', cbSuccess, true);
// suite.report();
// }, 500);
// }
// due to async nature of top inline test, give it some time to complete
setTimeout(testAutoLoad, 500);
// // due to async nature of top inline test, give it some time to complete
// setTimeout(testAutoLoad, 500);
// to be run in node
var gordian = require('gordian'),
suite = new gordian('LokiTests'),
loki = require('../src/lokijs.js'),
db,
users;
// var gordian = require('gordian'),
// suite = new gordian('LokiTests'),
// loki = require('../src/lokijs.js'),
describe('loki', function () {
var db,
users,
jonas;
function docCompare(a, b) {
if (a.$loki < b.$loki) return -1;
if (a.$loki > b.$loki) return 1;
function docCompare(a, b) {
if (a.$loki < b.$loki) return -1;
if (a.$loki > b.$loki) return 1;
return 0;
}
return 0;
}
db = new loki('test.json');
users = db.addCollection('user');
var jonas = null;
beforeEach(function () {
db = new loki('test.json');
users = db.addCollection('user');
function populateTestData() {
users.insert({
name: 'dave',
age: 25,
lang: 'English'
});
users.insert({
name: 'dave',
age: 25,
lang: 'English'
});
users.insert({
name: 'joe',
age: 39,
lang: 'Italian'
});
users.insert({
name: 'joe',
age: 39,
lang: 'Italian'
});
jonas = users.insert({
name: 'jonas',
age: 30,
lang: 'Swedish'
});
})
jonas = users.insert({
name: 'jonas',
age: 30,
lang: 'Swedish'
});
}
describe('core methods', function () {
it('works', function () {
// findOne()
var j = users.findOne({
'name': 'jonas'
});
suite.assertStrictEqual("findOne", j.name, 'jonas');
function testCoreMethods() {
// findOne()
var j = users.findOne({
'name': 'jonas'
});
suite.assertStrictEqual("findOne", j.name, 'jonas');
// find()
var result = users.find({
'age': {
'$gt': 29
}
});
suite.assertStrictEqual("find", result.length, 2);
// find()
var result = users.find({
'age': {
'$gt': 29
}
});
suite.assertStrictEqual("find", result.length, 2);
// $regex test
suite.assertStrictEqual('$regex', users.find({
"name": {
'$regex': /o/
}
}).length, 2);
// $regex test
suite.assertStrictEqual('$regex', users.find({
"name": {
'$regex': /o/
}
}).length, 2);
// insert() : try inserting existing document (should fail), try adding doc with legacy id column
var collectionLength = users.data.length;
var objDave = users.findOne({
'name': 'dave'
});
var wasAdded = true;
try {
users.insert(objDave);
} catch (err) {
wasAdded = false;
}
suite.assertStrictEqual('insert existing document caught', wasAdded, false);
// insert() : try inserting existing document (should fail), try adding doc with legacy id column
var collectionLength = users.data.length;
var objDave = users.findOne({
'name': 'dave'
});
var wasAdded = true;
try {
users.insert(objDave);
} catch (err) {
wasAdded = false;
}
suite.assertStrictEqual('insert existing document caught', wasAdded, false);
// our collections are not strongly typed so lets invent some object that has its 'own' id column
var legacyObject = {
id: 999,
first: 'aaa',
last: 'bbb',
city: 'pasadena',
state: 'ca'
}
// our collections are not strongly typed so lets invent some object that has its 'own' id column
var legacyObject = {
id: 999,
first: 'aaa',
last: 'bbb',
city: 'pasadena',
state: 'ca'
}
wasAdded = true;
wasAdded = true;
try {
users.insert(legacyObject);
} catch (err) {
wasAdded = false;
}
try {
users.insert(legacyObject);
} catch (err) {
wasAdded = false;
}
suite.assertStrictEqual('insert legacy document allowed', wasAdded, true);
suite.assertStrictEqual('insert legacy document allowed', wasAdded, true);
// remove object so later queries access valid properties on all objects
if (wasAdded) {
users.remove(legacyObject); // the object itself should have been modified
}
// remove object so later queries access valid properties on all objects
if (wasAdded) {
users.remove(legacyObject); // the object itself should have been modified
}
// update()
legacyObject = {
id: 998,
first: 'aaa',
last: 'bbb',
city: 'pasadena',
state: 'ca'
}
var wasUpdated = true;
// update()
legacyObject = {
id: 998,
first: 'aaa',
last: 'bbb',
city: 'pasadena',
state: 'ca'
}
var wasUpdated = true;
try {
users.update(legacyObject);
} catch (err) {
wasUpdated = false;
}
suite.assertStrictEqual('updating object not in collection should fail', wasUpdated, false);
try {
users.update(legacyObject);
} catch (err) {
wasUpdated = false;
}
suite.assertStrictEqual('updating object not in collection should fail', wasUpdated, false);
// remove() - add some bogus object to remove
var userCount1 = users.data.length;
// remove() - add some bogus object to remove
var userCount1 = users.data.length;
testObject = {
first: 'aaa',
last: 'bbb',
city: 'pasadena',
state: 'ca'
}
testObject = {
first: 'aaa',
last: 'bbb',
city: 'pasadena',
state: 'ca'
}
users.insert(testObject);
users.insert(testObject);
suite.assertStrictEqual('delete test : insert obj to delete', userCount1 + 1, users.data.length);
users.remove(testObject);
suite.assertStrictEqual('delete test : delete', userCount1, users.data.length);
})
});
suite.assertStrictEqual('delete test : insert obj to delete', userCount1 + 1, users.data.length);
users.remove(testObject);
suite.assertStrictEqual('delete test : delete', userCount1, users.data.length);
}
describe('calculateRange', function () {
it('works', function () {
var eic = db.addCollection("eic");
eic.ensureIndex("testid");
function testCalculateRange() {
var eic = db.addCollection("eic");
eic.ensureIndex("testid");
eic.insert({
'testid': 1,
'testString': 'hhh',
'testFloat': 5.2
}); //0
eic.insert({
'testid': 1,
'testString': 'aaa',
'testFloat': 6.2
}); //1
eic.insert({
'testid': 5,
'testString': 'zzz',
'testFloat': 7.2
}); //2
eic.insert({
'testid': 6,
'testString': 'ggg',
'testFloat': 1.2
}); //3
eic.insert({
'testid': 9,
'testString': 'www',
'testFloat': 8.2
}); //4
eic.insert({
'testid': 11,
'testString': 'yyy',
'testFloat': 4.2
}); //5
eic.insert({
'testid': 22,
'testString': 'yyz',
'testFloat': 9.2
}); //6
eic.insert({
'testid': 23,
'testString': 'm',
'testFloat': 2.2
}); //7
eic.insert({
'testid': 1,
'testString': 'hhh',
'testFloat': 5.2
}); //0
eic.insert({
'testid': 1,
'testString': 'aaa',
'testFloat': 6.2
}); //1
eic.insert({
'testid': 5,
'testString': 'zzz',
'testFloat': 7.2
}); //2
eic.insert({
'testid': 6,
'testString': 'ggg',
'testFloat': 1.2
}); //3
eic.insert({
'testid': 9,
'testString': 'www',
'testFloat': 8.2
}); //4
eic.insert({
'testid': 11,
'testString': 'yyy',
'testFloat': 4.2
}); //5
eic.insert({
'testid': 22,
'testString': 'yyz',
'testFloat': 9.2
}); //6
eic.insert({
'testid': 23,
'testString': 'm',
'testFloat': 2.2
}); //7
var rset = eic.chain();
rset.find({
'testid': 1
}); // force index to be built
var rset = eic.chain();
rset.find({
'testid': 1
}); // force index to be built
// ranges are order of sequence in index not data array positions
// ranges are order of sequence in index not data array positions
var range = rset.calculateRange('$eq', 'testid', 22);
suite.assertEqual('calculateRange $eq', range, [6, 6]);
var range = rset.calculateRange('$eq', 'testid', 22);
suite.assertEqual('calculateRange $eq', range, [6, 6]);
range = rset.calculateRange('$eq', 'testid', 1);
suite.assertEqual('calculateRange $eq multiple', range, [0, 1]);
range = rset.calculateRange('$eq', 'testid', 1);
suite.assertEqual('calculateRange $eq multiple', range, [0, 1]);
range = rset.calculateRange('$eq', 'testid', 7);
suite.assertEqual('calculateRange $eq not found', range, [0, -1]);
range = rset.calculateRange('$eq', 'testid', 7);
suite.assertEqual('calculateRange $eq not found', range, [0, -1]);
range = rset.calculateRange('$gte', 'testid', 23);
suite.assertEqual('calculateRange $gte', range, [7, 7]);
range = rset.calculateRange('$gte', 'testid', 23);
suite.assertEqual('calculateRange $gte', range, [7, 7]);
// reference this new record for future evaluations
eic.insert({
'testid': 23,
'testString': 'bbb',
'testFloat': 1.9
});
// reference this new record for future evaluations
eic.insert({
'testid': 23,
'testString': 'bbb',
'testFloat': 1.9
});
range = rset.calculateRange('$gte', 'testid', 23);
suite.assertEqual('calculateRange $gte', range, [7, 8]);
range = rset.calculateRange('$gte', 'testid', 23);
suite.assertEqual('calculateRange $gte', range, [7, 8]);
range = rset.calculateRange('$gte', 'testid', 24);
suite.assertEqual('calculateRange $gte out of range', range, [0, -1]);
range = rset.calculateRange('$gte', 'testid', 24);
suite.assertEqual('calculateRange $gte out of range', range, [0, -1]);
range = rset.calculateRange('$lte', 'testid', 5);
suite.assertEqual('calculateRange $lte', range, [0, 2]);
range = rset.calculateRange('$lte', 'testid', 5);
suite.assertEqual('calculateRange $lte', range, [0, 2]);
range = rset.calculateRange('$lte', 'testid', 1);
suite.assertEqual('calculateRange $lte', range, [0, 1]);
range = rset.calculateRange('$lte', 'testid', 1);
suite.assertEqual('calculateRange $lte', range, [0, 1]);
range = rset.calculateRange('$lte', 'testid', -1);
suite.assertEqual('calculateRange $lte out of range', range, [0, -1]);
range = rset.calculateRange('$lte', 'testid', -1);
suite.assertEqual('calculateRange $lte out of range', range, [0, -1]);
// add another index on string property
eic.ensureIndex('testString');
rset.find({
'testString': 'asdf'
}); // force index to be built
// add another index on string property
eic.ensureIndex('testString');
rset.find({
'testString': 'asdf'
}); // force index to be built
range = rset.calculateRange('$lte', 'testString', 'ggg');
suite.assertEqual('calculateRange $lte string', range, [0, 2]); // includes record added in middle
range = rset.calculateRange('$lte', 'testString', 'ggg');
suite.assertEqual('calculateRange $lte string', range, [0, 2]); // includes record added in middle
range = rset.calculateRange('$gte', 'testString', 'm');
suite.assertEqual('calculateRange $gte string', range, [4, 8]); // offset by 1 because of record in middle
range = rset.calculateRange('$gte', 'testString', 'm');
suite.assertEqual('calculateRange $gte string', range, [4, 8]); // offset by 1 because of record in middle
// add some float range evaluations
eic.ensureIndex('testFloat');
rset.find({
'testFloat': '1.1'
}); // force index to be built
// add some float range evaluations
eic.ensureIndex('testFloat');
rset.find({
'testFloat': '1.1'
}); // force index to be built
range = rset.calculateRange('$lte', 'testFloat', 1.2);
suite.assertEqual('calculateRange $lte float', range, [0, 0]);
range = rset.calculateRange('$lte', 'testFloat', 1.2);
suite.assertEqual('calculateRange $lte float', range, [0, 0]);
range = rset.calculateRange('$eq', 'testFloat', 1.111);
suite.assertEqual('calculateRange $eq not found', range, [0, -1]);
range = rset.calculateRange('$eq', 'testFloat', 1.111);
suite.assertEqual('calculateRange $eq not found', range, [0, -1]);
range = rset.calculateRange('$eq', 'testFloat', 8.2);
suite.assertEqual('calculateRange $eq found', range, [7, 7]); // 8th pos
range = rset.calculateRange('$eq', 'testFloat', 8.2);
suite.assertEqual('calculateRange $eq found', range, [7, 7]); // 8th pos
range = rset.calculateRange('$gte', 'testFloat', 1.0);
suite.assertEqual('calculateRange $gt all', range, [0, 8]); // 8th pos
})
});
range = rset.calculateRange('$gte', 'testFloat', 1.0);
suite.assertEqual('calculateRange $gt all', range, [0, 8]); // 8th pos
}
describe('indexLifecycle', function () {
it('works', function () {
var ilc = db.addCollection('ilc');
function testIndexLifecycle() {
var ilc = db.addCollection('ilc');
var hasIdx = ilc.binaryIndices.hasOwnProperty('testid');
suite.assertEqual('index lifecycle before', hasIdx, false);
var hasIdx = ilc.binaryIndices.hasOwnProperty('testid');
suite.assertEqual('index lifecycle before', hasIdx, false);
ilc.ensureIndex('testid');
hasIdx = ilc.binaryIndices.hasOwnProperty('testid');
suite.assertEqual('index lifecycle created', hasIdx, true);
suite.assertEqual('index lifecycle created', ilc.binaryIndices.testid.dirty, false);
suite.assertEqual('index lifecycle created', ilc.binaryIndices.testid.values, []);
ilc.ensureIndex('testid');
hasIdx = ilc.binaryIndices.hasOwnProperty('testid');
suite.assertEqual('index lifecycle created', hasIdx, true);
suite.assertEqual('index lifecycle created', ilc.binaryIndices.testid.dirty, false);
suite.assertEqual('index lifecycle created', ilc.binaryIndices.testid.values, []);
ilc.insert({
'testid': 5
});
suite.assertEqual('index lifecycle dirty', ilc.binaryIndices.testid.dirty, true);
ilc.insert({
'testid': 8
});
suite.assertEqual('index lifecycle still lazy', ilc.binaryIndices.testid.values, []);
suite.assertEqual('index lifecycle still dirty', ilc.binaryIndices.testid.dirty, true);
ilc.insert({
'testid': 5
});
suite.assertEqual('index lifecycle dirty', ilc.binaryIndices.testid.dirty, true);
ilc.insert({
'testid': 8
});
suite.assertEqual('index lifecycle still lazy', ilc.binaryIndices.testid.values, []);
suite.assertEqual('index lifecycle still dirty', ilc.binaryIndices.testid.dirty, true);
ilc.find({
'testid': 8
}); // should force index build
suite.assertEqual('index lifecycle built', ilc.binaryIndices.testid.dirty, false);
suite.assertEqual('index lifecycle still lazy', ilc.binaryIndices.testid.values.length, 2);
})
})
ilc.find({
'testid': 8
}); // should force index build
suite.assertEqual('index lifecycle built', ilc.binaryIndices.testid.dirty, false);
suite.assertEqual('index lifecycle still lazy', ilc.binaryIndices.testid.values.length, 2);
}
describe('indexes', function () {
it('works', function () {
var itc = db.addCollection('test', {
indices: ['testid']
});
function testIndexes() {
var itc = db.addCollection('test', {
indices: ['testid']
});
itc.insert({
'testid': 1
});
itc.insert({
'testid': 2
});
itc.insert({
'testid': 5
});
itc.insert({
'testid': 5
});
itc.insert({
'testid': 9
});
itc.insert({
'testid': 11
});
itc.insert({
'testid': 22
});
itc.insert({
'testid': 22
});
itc.insert({
'testid': 1
});
itc.insert({
'testid': 2
});
itc.insert({
'testid': 5
});
itc.insert({
'testid': 5
});
itc.insert({
'testid': 9
});
itc.insert({
'testid': 11
});
itc.insert({
'testid': 22
});
itc.insert({
'testid': 22
});
// lte
var results = itc.find({
'testid': {
'$lte': 1
}
});
suite.assertStrictEqual('find using index $lte', results.length, 1);
// lte
var results = itc.find({
'testid': {
'$lte': 1
}
});
suite.assertStrictEqual('find using index $lte', results.length, 1);
results = itc.find({
'testid': {
'$lte': 22
}
});
suite.assertStrictEqual('find using index $lte', results.length, 8);
results = itc.find({
'testid': {
'$lte': 22
}
});
suite.assertStrictEqual('find using index $lte', results.length, 8);
// lt
results = itc.find({
'testid': {
'$lt': 1
}
});
suite.assertStrictEqual('find using index $lt', results.length, 0);
// lt
results = itc.find({
'testid': {
'$lt': 1
}
});
suite.assertStrictEqual('find using index $lt', results.length, 0);
results = itc.find({
'testid': {
'$lt': 22
}
});
suite.assertStrictEqual('find using index $lt', results.length, 6);
results = itc.find({
'testid': {
'$lt': 22
}
});
suite.assertStrictEqual('find using index $lt', results.length, 6);
// eq
results = itc.find({
'testid': {
'$eq': 22
}
});
suite.assertStrictEqual('find using index $eq', results.length, 2);
// eq
results = itc.find({
'testid': {
'$eq': 22
}
});
suite.assertStrictEqual('find using index $eq', results.length, 2);
// gt
results = itc.find({
'testid': {
'$gt': 22
}
});
suite.assertStrictEqual('find using index $eq', results.length, 0);
// gt
results = itc.find({
'testid': {
'$gt': 22
}
});
suite.assertStrictEqual('find using index $eq', results.length, 0);
results = itc.find({
'testid': {
'$gt': 5
}
});
suite.assertStrictEqual('find using index $eq', results.length, 4);
results = itc.find({
'testid': {
'$gt': 5
}
});
suite.assertStrictEqual('find using index $eq', results.length, 4);
// gte
results = itc.find({
'testid': {
'$gte': 5
}
});
suite.assertStrictEqual('find using index $gte', results.length, 6);
// gte
results = itc.find({
'testid': {
'$gte': 5
}
});
suite.assertStrictEqual('find using index $gte', results.length, 6);
results = itc.find({
'testid': {
'$gte': 10
}
});
suite.assertStrictEqual('find using index $gte', results.length, 3);
})
})
results = itc.find({
'testid': {
'$gte': 10
}
});
suite.assertStrictEqual('find using index $gte', results.length, 3);
}
describe('resultSet', function () {
it('works', function () {
// Resultset find
suite.assertStrictEqual('Resultset (chained) find', users.chain().find({
'age': {
'$gte': 30
}
}).where(function (obj) {
return obj.lang === 'Swedish';
}).data().length, 1);
function testResultset() {
// Resultset find
suite.assertStrictEqual('Resultset (chained) find', users.chain().find({
'age': {
'$gte': 30
}
}).where(function (obj) {
return obj.lang === 'Swedish';
}).data().length, 1);
// Resultset offset
suite.assertStrictEqual('Resultset (chained) offset', users.chain().offset(1).data().length, users.data.length - 1);
// Resultset offset
suite.assertStrictEqual('Resultset (chained) offset', users.chain().offset(1).data().length, users.data.length - 1);
// Resultset limit
suite.assertStrictEqual('Resultset (chained) limit', users.chain().limit(2).data().length, 2);
})
})
// Resultset limit
suite.assertStrictEqual('Resultset (chained) limit', users.chain().limit(2).data().length, 2);
describe('andOrOps', function () {
it('works', function () {
var eic = db.addCollection("eic");
}
eic.insert({
'testid': 1,
'testString': 'hhh',
'testFloat': 5.2
}); //0
eic.insert({
'testid': 1,
'testString': 'bbb',
'testFloat': 6.2
}); //1
eic.insert({
'testid': 5,
'testString': 'zzz',
'testFloat': 7.2
}); //2
eic.insert({
'testid': 6,
'testString': 'ggg',
'testFloat': 1.2
}); //3
eic.insert({
'testid': 9,
'testString': 'www',
'testFloat': 8.2
}); //4
eic.insert({
'testid': 11,
'testString': 'yyy',
'testFloat': 4.2
}); //5
eic.insert({
'testid': 22,
'testString': 'bbb',
'testFloat': 9.2
}); //6
eic.insert({
'testid': 23,
'testString': 'm',
'testFloat': 2.2
}); //7
function testAndOrOps() {
var eic = db.addCollection("eic");
// coll.find $and
suite.assertStrictEqual('$and op test1', eic.find({
'$and': [{
'testid': 1
}, {
'testString': 'bbb'
}]
}).length, 1);
eic.insert({
'testid': 1,
'testString': 'hhh',
'testFloat': 5.2
}); //0
eic.insert({
'testid': 1,
'testString': 'bbb',
'testFloat': 6.2
}); //1
eic.insert({
'testid': 5,
'testString': 'zzz',
'testFloat': 7.2
}); //2
eic.insert({
'testid': 6,
'testString': 'ggg',
'testFloat': 1.2
}); //3
eic.insert({
'testid': 9,
'testString': 'www',
'testFloat': 8.2
}); //4
eic.insert({
'testid': 11,
'testString': 'yyy',
'testFloat': 4.2
}); //5
eic.insert({
'testid': 22,
'testString': 'bbb',
'testFloat': 9.2
}); //6
eic.insert({
'testid': 23,
'testString': 'm',
'testFloat': 2.2
}); //7
// resultset.find $and
suite.assertStrictEqual('$and op test2', eic.chain().find({
'$and': [{
'testid': 1
}, {
'testString': 'bbb'
}]
}).data().length, 1);
// coll.find $and
suite.assertStrictEqual('$and op test1', eic.find({
'$and': [
{'testid': 1},
{'testString': 'bbb'}
]
}).length, 1);
// resultset.find explicit operators
suite.assertStrictEqual('$and op test3', eic.chain().find({
'$and': [{
'testid': {
'$eq': 1
}
}, {
'testFloat': {
'$gt': 6.0
}
}]
}).data().length, 1);
// resultset.find $and
suite.assertStrictEqual('$and op test2', eic.chain().find({
'$and': [
{'testid': 1},
{'testString': 'bbb'}
]
}).data().length, 1);
// coll.find $or
suite.assertStrictEqual('$or op test1', eic.find({
'$or': [{
'testid': 1
}, {
'testString': 'bbb'
}]
}).length, 3);
// resultset.find explicit operators
suite.assertStrictEqual('$and op test3', eic.chain().find({
'$and': [
{'testid': {'$eq': 1}},
{'testFloat': {'$gt': 6.0}}
]
}).data().length, 1);
// resultset.find $or
suite.assertStrictEqual('$or op test2', eic.chain().find({
'$or': [{
'testid': 1
}, {
'testString': 'bbb'
}]
}).data().length, 3);
// coll.find $or
suite.assertStrictEqual('$or op test1', eic.find({
'$or': [
{'testid': 1},
{'testString': 'bbb'}
]
}).length, 3);
// resultset.find explicit operators
suite.assertStrictEqual('$or op test3', eic.chain().find({
'$or': [{
'testid': 1
}, {
'testFloat': {
'$gt': 7.0
}
}]
}).data().length, 5);
// resultset.find $or
suite.assertStrictEqual('$or op test2', eic.chain().find({
'$or': [
{'testid': 1},
{'testString': 'bbb'}
]
}).data().length, 3);
// add index and repeat final test
eic.ensureIndex("testid");
// resultset.find explicit operators
suite.assertStrictEqual('$or op test3', eic.chain().find({
'$or': [
{'testid': 1},
{'testFloat': {'$gt': 7.0}}
]
}).data().length, 5);
suite.assertStrictEqual('$and op test4', eic.chain().find({
'$and': [{
'testid': {
'$eq': 1
}
}, {
'testFloat': {
'$gt': 6.0
}
}]
}).data().length, 1);
// add index and repeat final test
eic.ensureIndex("testid");
suite.assertStrictEqual('$or op test4', eic.chain().find({
'$or': [{
'testid': 1
}, {
'testFloat': {
'$gt': 7.0
}
}]
}).data().length, 5);
suite.assertStrictEqual('$and op test4', eic.chain().find({
'$and': [
{'testid': {'$eq': 1}},
{'testFloat': {'$gt': 6.0}}
]
}).data().length, 1);
db.removeCollection("eic");
})
})
suite.assertStrictEqual('$or op test4', eic.chain().find({
'$or': [
{'testid': 1},
{'testFloat': {'$gt': 7.0}}
]
}).data().length, 5);
describe('findOne', function () {
it('works', function () {
var eic = db.addCollection("eic");
db.removeCollection("eic");
}
eic.insert({
'testid': 1,
'testString': 'hhh',
'testFloat': 5.2
}); //0
eic.insert({
'testid': 1,
'testString': 'bbb',
'testFloat': 6.2
}); //1
eic.insert({
'testid': 5,
'testString': 'zzz',
'testFloat': 7.2
}); //2
function testFindOne() {
var eic = db.addCollection("eic");
// coll.findOne return type
suite.assertStrictEqual('findOne return type', typeof eic.findOne({
'testid': 1
}), 'object');
eic.insert({
'testid': 1,
'testString': 'hhh',
'testFloat': 5.2
}); //0
eic.insert({
'testid': 1,
'testString': 'bbb',
'testFloat': 6.2
}); //1
eic.insert({
'testid': 5,
'testString': 'zzz',
'testFloat': 7.2
}); //2
// coll.findOne return match
suite.assertStrictEqual('findOne return match', eic.findOne({
'testid': 5
}).testFloat, 7.2);
// coll.findOne return type
suite.assertStrictEqual('findOne return type', typeof eic.findOne({'testid': 1}), 'object');
// findOne with $and op
suite.assertStrictEqual('findOne with $and op', eic.findOne({
'$and': [{
'testid': 1
}, {
'testString': 'bbb'
}]
}).testFloat, 6.2);
// coll.findOne return match
suite.assertStrictEqual('findOne return match', eic.findOne({'testid': 5}).testFloat, 7.2);
// findOne with $and op
suite.assertStrictEqual('findOne with $or op', eic.findOne({
'$or': [{
'testid': 2
}, {
'testString': 'zzz'
}]
}).testFloat, 7.2);
// findOne with $and op
suite.assertStrictEqual('findOne with $and op', eic.findOne({
'$and': [
{'testid': 1},
{'testString': 'bbb'}
]
}).testFloat, 6.2);
db.removeCollection("eic");
})
})
// findOne with $and op
suite.assertStrictEqual('findOne with $or op', eic.findOne({
'$or': [
{'testid': 2},
{'testString': 'zzz'}
]
}).testFloat, 7.2);
/* Dynamic View Tests */
describe('stepEvaluateDocument', function () {
it('works', function () {
var view = users.addDynamicView('test');
var query = {
'age': {
'$gt': 24
}
};
db.removeCollection("eic");
}
view.applyFind(query);
/* Dynamic View Tests */
function stepEvaluateDocument() {
var view = users.addDynamicView('test');
var query = {
'age': {
'$gt': 24
}
};
// churn evaluateDocuments() to make sure it works right
jonas.age = 23;
users.update(jonas);
view.applyFind(query);
suite.assertStrictEqual("evalDoc1", view.data().length, users.data.length - 1);
jonas.age = 30;
users.update(jonas);
suite.assertStrictEqual("evalDoc2", view.data().length, users.data.length);
jonas.age = 23;
users.update(jonas);
suite.assertStrictEqual("evalDoc3", view.data().length, users.data.length - 1);
jonas.age = 30;
users.update(jonas);
suite.assertStrictEqual("evalDoc4", view.data().length, users.data.length);
// churn evaluateDocuments() to make sure it works right
jonas.age = 23;
users.update(jonas);
// assert set equality of docArrays irrelevant of sort/sequence
var result1 = users.find(query).sort(docCompare);
var result2 = view.data().sort(docCompare);
result1.forEach(function (obj) {
delete obj.meta
});
result2.forEach(function (obj) {
delete obj.meta
});
suite.assertStrictEqual("evalDoc1", view.data().length, users.data.length - 1);
jonas.age = 30;
users.update(jonas);
suite.assertStrictEqual("evalDoc2", view.data().length, users.data.length);
jonas.age = 23;
users.update(jonas);
suite.assertStrictEqual("evalDoc3", view.data().length, users.data.length - 1);
jonas.age = 30;
users.update(jonas);
suite.assertStrictEqual("evalDoc4", view.data().length, users.data.length);
suite.assertEqual('Result data Equality', result1, result2);
// assert set equality of docArrays irrelevant of sort/sequence
var result1 = users.find(query).sort(docCompare);
var result2 = view.data().sort(docCompare);
result1.forEach(function (obj) {
delete obj.meta
});
result2.forEach(function (obj) {
delete obj.meta
});
suite.assertNotStrictEqual('Strict Equality', users.find(query), view.data());
suite.assertEqual('View data equality', view.resultset, view.resultset.copy());
suite.assertNotStrictEqual('View data copy strict equality', view.resultset, view.resultset.copy());
suite.assertEqual('Result data Equality', result1, result2);
return view;
})
})
suite.assertNotStrictEqual('Strict Equality', users.find(query), view.data());
suite.assertEqual('View data equality', view.resultset, view.resultset.copy());
suite.assertNotStrictEqual('View data copy strict equality', view.resultset, view.resultset.copy());
describe('stepDynamicViewPersistence', function () {
it('works', function stepDynamicViewPersistence() {
var query = {
'age': {
'$gt': 24
}
};
return view;
}
// set up a persistent dynamic view with sort
var pview = users.addDynamicView('test2', true);
pview.applyFind(query);
pview.applySimpleSort("age");
// make sure view persistence works as expected
function stepDynamicViewPersistence() {
var query = {
'age': {
'$gt': 24
}
};
// the dynamic view depends on an internal resultset
// the persistent dynamic view also depends on an internal resultdata data array
// filteredrows should be applied immediately to resultset will be lazily built into resultdata later when data() is called
suite.assertStrictEqual("dynamic view initialization 1", pview.resultset.filteredrows.length, 3);
suite.assertStrictEqual("dynamic view initialization 2", pview.resultdata.length, 0);
// set up a persistent dynamic view with sort
var pview = users.addDynamicView('test2', true);
pview.applyFind(query);
pview.applySimpleSort("age");
// compare how many documents are in results before adding new ones
var pviewResultsetLenBefore = pview.resultset.filteredrows.length;
// the dynamic view depends on an internal resultset
// the persistent dynamic view also depends on an internal resultdata data array
// filteredrows should be applied immediately to resultset will be lazily built into resultdata later when data() is called
suite.assertStrictEqual("dynamic view initialization 1", pview.resultset.filteredrows.length, 3);
suite.assertStrictEqual("dynamic view initialization 2", pview.resultdata.length, 0);
users.insert({
name: 'abc',
age: 21,
lang: 'English'
});
// compare how many documents are in results before adding new ones
var pviewResultsetLenBefore = pview.resultset.filteredrows.length;
users.insert({
name: 'def',
age: 25,
lang: 'English'
});
users.insert({
name: 'abc',
age: 21,
lang: 'English'
});
// now see how many are in resultset (without rebuilding persistent view)
var pviewResultsetLenAfter = pview.resultset.filteredrows.length;
users.insert({
name: 'def',
age: 25,
lang: 'English'
});
// only one document should have been added to resultset (1 was filtered out)
suite.assertStrictEqual("dv resultset is 'set' valid", pviewResultsetLenBefore + 1, pviewResultsetLenAfter);
// now see how many are in resultset (without rebuilding persistent view)
var pviewResultsetLenAfter = pview.resultset.filteredrows.length;
// Test sorting and lazy build of resultdata
// only one document should have been added to resultset (1 was filtered out)
suite.assertStrictEqual("dv resultset is 'set' valid", pviewResultsetLenBefore + 1, pviewResultsetLenAfter);
// retain copy of internal resultset's filteredrows before lazy sort
var frcopy = pview.resultset.filteredrows.slice();
pview.data();
// now make a copy of internal result's filteredrows after lazy sort
var frcopy2 = pview.resultset.filteredrows.slice();
// Test sorting and lazy build of resultdata
// verify filteredrows logically matches resultdata (irrelevant of sort)
for (var idxFR = 0; idxFR < frcopy2.length; idxFR++) {
suite.assertEqual("dynamic view resultset/resultdata consistency", pview.resultdata[idxFR], pview.collection.data[frcopy2[idxFR]]);
}
// now verify they are not exactly equal (verify sort moved stuff)
suite.assertNotEqual('dynamic view sort', frcopy, frcopy2);
})
})
// retain copy of internal resultset's filteredrows before lazy sort
var frcopy = pview.resultset.filteredrows.slice();
pview.data();
// now make a copy of internal result's filteredrows after lazy sort
var frcopy2 = pview.resultset.filteredrows.slice();
describe('stepDynamicViewPersistence', function () {
it('works', function duplicateItemFoundOnIndex() {
var test = db.addCollection('nodupes', ['index']);
// verify filteredrows logically matches resultdata (irrelevant of sort)
for (var idxFR = 0; idxFR < frcopy2.length; idxFR++) {
suite.assertEqual("dynamic view resultset/resultdata consistency", pview.resultdata[idxFR], pview.collection.data[frcopy2[idxFR]]);
}
// now verify they are not exactly equal (verify sort moved stuff)
suite.assertNotEqual('dynamic view sort', frcopy, frcopy2);
}
var item = test.insert({
index: 'key',
a: 1
});
function testDynamicView() {
var view = stepEvaluateDocument();
stepDynamicViewPersistence();
}
var results = test.find({
index: 'key'
});
suite.assertStrictEqual('one result exists', results.length, 1);
suite.assertStrictEqual('the correct result is returned', results[0].a, 1);
function duplicateItemFoundOnIndex() {
var test = db.addCollection('nodupes', ['index']);
item.a = 2;
test.update(item);
var item = test.insert({
index: 'key',
a: 1
});
results = test.find({
index: 'key'
});
suite.assertStrictEqual('one result exists', results.length, 1);
suite.assertStrictEqual('the correct result is returned', results[0].a, 2);
})
})
var results = test.find({
index: 'key'
});
suite.assertStrictEqual('one result exists', results.length, 1);
suite.assertStrictEqual('the correct result is returned', results[0].a, 1);
describe('stepDynamicViewPersistence', function () {
it('works', function testEmptyTableWithIndex() {
var itc = db.addCollection('test', ['testindex']);
item.a = 2;
test.update(item);
var resultsNoIndex = itc.find({
'testid': 2
});
suite.assertStrictEqual('no results found', resultsNoIndex.length, 0);
results = test.find({
index: 'key'
});
suite.assertStrictEqual('one result exists', results.length, 1);
suite.assertStrictEqual('the correct result is returned', results[0].a, 2);
}
var resultsWithIndex = itc.find({
'testindex': 4
});
suite.assertStrictEqual('no results found', resultsWithIndex.length, 0);
})
})
function testEmptyTableWithIndex() {
var itc = db.addCollection('test', ['testindex']);
describe('stepDynamicViewPersistence', function () {
it('works', function testAnonym() {
var coll = db.anonym([{
name: 'joe'
}, {
name: 'jack'
}], ['name']);
suite.assertEqual('Anonym collection', coll.data.length, 2);
suite.assertEqual('Collection not found', db.getCollection('anonym'), null);
coll.name = 'anonym';
db.loadCollection(coll);
suite.assertEqual('Anonym collection loaded', !!db.getCollection('anonym'), true);
coll.clear();
suite.assertEqual('No data after coll.clear()', 0, coll.data.length);
})
})
var resultsNoIndex = itc.find({
'testid': 2
});
suite.assertStrictEqual('no results found', resultsNoIndex.length, 0);
describe('stepDynamicViewPersistence', function () {
it('works', function testCollections() {
var db = new loki('testCollections');
db.name = 'testCollections';
suite.assertEqual('DB name', db.getName(), 'testCollections');
var t = db.addCollection('test1', {
transactional: true
});
db.addCollection('test2');
suite.assertThrows('Throw error on wrong remove', function () {
t.remove('foo');
}, Error);
suite.assertThrows('Throw error on non-synced doc', function () {
t.remove({
name: 'joe'
});
}, Error);
suite.assertEqual('List collections', db.listCollections().length, 2);
t.clear();
var users = [{
name: 'joe'
}, {
name: 'dave'
}];
t.insert(users);
var resultsWithIndex = itc.find({
'testindex': 4
});
suite.assertStrictEqual('no results found', resultsWithIndex.length, 0);
}
suite.assertEqual('2 docs after array insert', 2, t.data.length);
t.remove(users);
suite.assertEqual('0 docs after array remove', 0, t.data.length);
function testAnonym() {
var coll = db.anonym([{
name: 'joe'
}, {
name: 'jack'
}], ['name']);
suite.assertEqual('Anonym collection', coll.data.length, 2);
suite.assertEqual('Collection not found', db.getCollection('anonym'), null);
coll.name = 'anonym';
db.loadCollection(coll);
suite.assertEqual('Anonym collection loaded', !!db.getCollection('anonym'), true);
coll.clear();
suite.assertEqual('No data after coll.clear()', 0, coll.data.length);
}
function TestError() {}
TestError.prototype = new Error;
db.autosaveEnable();
db.on('close', function () {
throw new TestError;
});
suite.assertThrows('Throw error on purpose on close', function () {
db.close(function () {
return;
});
}, TestError);
})
})
function testCollections() {
var db = new loki('testCollections');
db.name = 'testCollections';
suite.assertEqual('DB name', db.getName(), 'testCollections');
var t = db.addCollection('test1', {
transactional: true
});
db.addCollection('test2');
suite.assertThrows('Throw error on wrong remove', function () {
t.remove('foo');
}, Error);
suite.assertThrows('Throw error on non-synced doc', function () {
t.remove({
name: 'joe'
});
}, Error);
suite.assertEqual('List collections', db.listCollections().length, 2);
t.clear();
var users = [{
name: 'joe'
}, {
name: 'dave'
}];
t.insert(users);
suite.assertEqual('2 docs after array insert', 2, t.data.length);
t.remove(users);
suite.assertEqual('0 docs after array remove', 0, t.data.length);
function TestError() {}
TestError.prototype = new Error;
db.autosaveEnable();
db.on('close', function () {
throw new TestError;
});
suite.assertThrows('Throw error on purpose on close', function () {
db.close(function () {
return;
});
}, TestError);
}
/* Main Test */
populateTestData();
testCoreMethods();
testAndOrOps();
testFindOne();
testCalculateRange();
testIndexes();
testIndexLifecycle();
testResultset();
testDynamicView();
duplicateItemFoundOnIndex();
testEmptyTableWithIndex();
testAnonym();
testCollections();
suite.report();
})
/* Main Test */
// populateTestData();
// testCoreMethods();
// testAndOrOps();
// testFindOne();
// testCalculateRange();
// testIndexes();
// testIndexLifecycle();
// testResultset();
// testDynamicView();
// duplicateItemFoundOnIndex();
// testEmptyTableWithIndex();
// testAnonym();
// testCollections();
// suite.report();

@@ -1,20 +0,19 @@

var Loki = require('../src/lokijs.js'),
gordian = require('gordian'),
suite = new gordian('testCollection');
describe('collection', function () {
it('works', function () {
function SubclassedCollection() {
loki.Collection.apply(this, Array.prototype.slice.call(arguments));
}
SubclassedCollection.prototype = new loki.Collection;
SubclassedCollection.prototype.extendedMethod = function () {
return this.name.toUpperCase();
}
var coll = new SubclassedCollection('users', {});
function SubclassedCollection() {
Loki.Collection.apply(this, Array.prototype.slice.call(arguments));
}
SubclassedCollection.prototype = new Loki.Collection;
SubclassedCollection.prototype.extendedMethod = function () {
return this.name.toUpperCase();
}
var coll = new SubclassedCollection('users', {});
suite.assertEqual('Exposed Collection is not null', true, coll != null);
suite.assertEqual('Exposed Collection methods work normally', 'users'.toUpperCase(), coll.extendedMethod());
coll.insert({
name: 'joe'
expect(coll != null).toBe(true);
expect('users'.toUpperCase()).toEqual(coll.extendedMethod());
coll.insert({
name: 'joe'
});
expect(coll.data.length).toEqual(1);
});
});
suite.assertEqual('Exposed Collection operations work normally', coll.data.length, 1);
suite.report();
var fs = require("fs");
var isError = require('util').isError;
// var fs = require("fs");
// var isError = require('util').isError;
// these 2 function test the interworking between Lokijs and the adapter
function saveTest(){
users.insert([{
name: 'joe'
}, {
name: 'jack'
}]);
db.saveDatabase(reloadTest);
}
// // these 2 function test the interworking between Lokijs and the adapter
// function saveTest(){
// users.insert([{
// name: 'joe'
// }, {
// name: 'jack'
// }]);
// db.saveDatabase(reloadTest);
// }
function reloadTest(){
var reloaded = new loki('./loki.json.crypted',{ adapter: cryptedFileAdapter });
reloaded.loadDatabase({}, function () {
var users2 = reloaded.getCollection('users');
suite.assertEqual('There are 2 objects in the reloaded and decrypted db', 2, users2.data.length);
errorHandlingTest();
});
}
// function reloadTest(){
// var reloaded = new loki('./loki.json.crypted',{ adapter: cryptedFileAdapter });
// reloaded.loadDatabase({}, function () {
// var users2 = reloaded.getCollection('users');
// suite.assertEqual('There are 2 objects in the reloaded and decrypted db', 2, users2.data.length);
// errorHandlingTest();
// });
// }
function errorHandlingTest(){
var reloaded = new loki('./nonExistingDatabase',{ adapter: cryptedFileAdapter });
reloaded.loadDatabase({}, function (r){
suite.assertStrictEqual('Missing database caught by loadDatabase and passed via Lokijs', (r !== undefined) , true);
noSecretOnSaveTest();
});
}
// function errorHandlingTest(){
// var reloaded = new loki('./nonExistingDatabase',{ adapter: cryptedFileAdapter });
// reloaded.loadDatabase({}, function (r){
// suite.assertStrictEqual('Missing database caught by loadDatabase and passed via Lokijs', (r !== undefined) , true);
// noSecretOnSaveTest();
// });
// }
// now on to testing error handling in the adapter itself
// // now on to testing error handling in the adapter itself
function noSecretOnSaveTest(){
// function noSecretOnSaveTest(){
cryptedFileAdapter.setSecret(undefined);
cryptedFileAdapter.saveDatabase('./testfile.json',"{}",
function(r){
suite.assertStrictEqual('Missing secret caught on saveDatabase', isError(r), true);
noSecretOnLoadTest();
});
}
// cryptedFileAdapter.setSecret(undefined);
function noSecretOnLoadTest(){
cryptedFileAdapter.loadDatabase('./loki.json.crypted',
function(r){
suite.assertStrictEqual('Missing secret caught by loadDatabase', isError(r), true);
missingDbTest();
});
}
// cryptedFileAdapter.saveDatabase('./testfile.json',"{}",
// function(r){
// suite.assertStrictEqual('Missing secret caught on saveDatabase', isError(r), true);
// noSecretOnLoadTest();
// });
// }
function missingDbTest(){
cryptedFileAdapter.setSecret('mySecret');
cryptedFileAdapter.loadDatabase("./nonExistingDatabase",
function(r){
suite.assertStrictEqual('Missing database caught by loadDatabase', isError(r), true);
noJsonTest();
});
}
// function noSecretOnLoadTest(){
// cryptedFileAdapter.loadDatabase('./loki.json.crypted',
// function(r){
// suite.assertStrictEqual('Missing secret caught by loadDatabase', isError(r), true);
// missingDbTest();
// });
// }
function noJsonTest(){
fs.writeFileSync("./nonJsonTestFile.txt","this is not json",'utf8');
cryptedFileAdapter.loadDatabase("./nonJsonTestFile.txt",
function(r){
fs.unlink("./nonJsonTestFile.txt");
suite.assertStrictEqual('No Json content caught by loadDatabase', isError(r), true);
wrongJsonTest();
});
}
// function missingDbTest(){
// cryptedFileAdapter.setSecret('mySecret');
function wrongJsonTest(){
fs.writeFileSync("./wrongJsonTestFile.txt",'{"name":"value"}','utf8');
cryptedFileAdapter.loadDatabase("./wrongJsonTestFile.txt",
function(r){
fs.unlink("./wrongJsonTestFile.txt");
suite.assertStrictEqual('Wrong Json content caught by loadDatabase', isError(r), true);
endOfTest();
});
}
// cryptedFileAdapter.loadDatabase("./nonExistingDatabase",
// function(r){
// suite.assertStrictEqual('Missing database caught by loadDatabase', isError(r), true);
// noJsonTest();
// });
// }
function endOfTest(){
suite.report();
fs.unlink('./loki.json.crypted');
}
// function noJsonTest(){
// fs.writeFileSync("./nonJsonTestFile.txt","this is not json",'utf8');
// cryptedFileAdapter.loadDatabase("./nonJsonTestFile.txt",
// function(r){
// fs.unlink("./nonJsonTestFile.txt");
// suite.assertStrictEqual('No Json content caught by loadDatabase', isError(r), true);
// wrongJsonTest();
// });
// }
var cryptedFileAdapter = require('../src/lokiCryptedFileAdapter');
// function wrongJsonTest(){
// fs.writeFileSync("./wrongJsonTestFile.txt",'{"name":"value"}','utf8');
// cryptedFileAdapter.loadDatabase("./wrongJsonTestFile.txt",
// function(r){
// fs.unlink("./wrongJsonTestFile.txt");
// suite.assertStrictEqual('Wrong Json content caught by loadDatabase', isError(r), true);
// endOfTest();
// });
// }
cryptedFileAdapter.setSecret('mySecret');
var loki = require('../src/lokijs.js'),
db = new loki('./loki.json.crypted',{ adapter: cryptedFileAdapter }),
gordian = require('gordian'),
suite = new gordian('testCryptedFileAdapter'),
users = db.addCollection('users');
// function endOfTest(){
// suite.report();
// fs.unlink('./loki.json.crypted');
// }
saveTest();
// var cryptedFileAdapter = require('../src/lokiCryptedFileAdapter');
// cryptedFileAdapter.setSecret('mySecret');
// var loki = require('../src/lokijs.js'),
// db = new loki('./loki.json.crypted',{ adapter: cryptedFileAdapter }),
// gordian = require('gordian'),
// suite = new gordian('testCryptedFileAdapter'),
// users = db.addCollection('users');
// saveTest();

@@ -110,1 +107,4 @@

@@ -1,21 +0,23 @@

var loki = require('../src/lokijs.js'),
gordian = require('gordian'),
suite = new gordian('testKv'),
store = new loki.KeyValueStore();
// var loki = require('../src/lokijs.js'),
// gordian = require('gordian'),
// suite = new gordian('testKv'),
// store = new loki.KeyValueStore();
var key = {
name: 'joe'
},
value = {
position: 'developer'
};
describe('kv', function () {
it('works', function () {
var store = new loki.KeyValueStore();
var key = {
name: 'joe'
},
value = {
position: 'developer'
};
store.set('foo', 'bar');
store.set('bar', 'baz');
store.set('baz', 'quux');
store.set(key, value);
//store.set(key, value);
console.log(store.keys, store.values)
suite.assertEqual('Finding key and value', 'bar', store.get('foo'));
suite.assertEqual('Finding key by object', value, store.get(key));
suite.report();
store.set('foo', 'bar');
store.set('bar', 'baz');
store.set('baz', 'quux');
store.set(key, value);
expect('bar').toEqual(store.get('foo'));
expect(value).toEqual(store.get(key));
});
});

@@ -1,52 +0,58 @@

var loki = require('../src/lokijs.js'),
db = new loki(),
gordian = require('gordian'),
suite = new gordian('testEvents'),
users = db.addCollection('users');
// var loki = require('../src/lokijs.js'),
// db = new loki(),
// gordian = require('gordian'),
// suite = new gordian('testEvents'),
// users = db.addCollection('users');
users.insert({
name: 'joe',
age: 39
});
users.insert({
name: 'jack',
age: 20
});
users.insert({
name: 'jim',
age: 40
});
users.insert({
name: 'dave',
age: 33
});
users.insert({
name: 'jim',
age: 29
});
users.insert({
name: 'dave',
age: 21
});
describe('remove', function () {
it('removes', function () {
var db = new loki();
var users = db.addCollection('users');
var dv = users.addDynamicView('testview');
dv.applyWhere(function (obj) {
return obj.name.length > 3;
});
users.insert({
name: 'joe',
age: 39
});
users.insert({
name: 'jack',
age: 20
});
users.insert({
name: 'jim',
age: 40
});
users.insert({
name: 'dave',
age: 33
});
users.insert({
name: 'jim',
age: 29
});
users.insert({
name: 'dave',
age: 21
});
users.removeWhere(function (obj) {
return obj.age > 35;
var dv = users.addDynamicView('testview');
dv.applyWhere(function (obj) {
return obj.name.length > 3;
});
users.removeWhere(function (obj) {
return obj.age > 35;
});
expect(users.data.length).toEqual(4);
users.removeWhere({
'age': {
$gt: 25
}
});
expect(users.data.length).toEqual(2);
users.remove(6);
expect(users.data.length).toEqual(1);
users.removeDataOnly();
expect(users.data.length).toEqual(0);
expect(!!users.getDynamicView('testview')).toEqual(true);
});
});
suite.assertEqual('Users length after removeWhere()', users.data.length, 4);
users.removeWhere({
'age': {
$gt: 25
}
});
suite.assertEqual('Users length after removeWhere()', users.data.length, 2);
users.remove(6);
suite.assertEqual('Users length after remove(int)', users.data.length, 1);
users.removeDataOnly();
suite.assertEqual('No users left after removeDataOnly()', users.data.length, 0);
suite.assertEqual('DynamicView still in existence after removing data', !!users.getDynamicView('testview'), true);
suite.report();

@@ -1,66 +0,96 @@

var loki = require('../src/lokijs.js'),
db = new loki(),
gordian = require('gordian'),
suite = new gordian('testEvents'),
users = db.addCollection('users');
// var loki = require('../src/lokijs.js'),
// db = new loki(),
// gordian = require('gordian'),
// suite = new gordian('testEvents'),
// users = db.addCollection('users');
users.insert({
name: 'joe',
age: 35,
relatives: {
firstgrade: 15
}
describe('stats', function () {
var db = new loki();
var users = db.addCollection('users');
users.insert({
name: 'joe',
age: 35,
relatives: {
firstgrade: 15
}
});
users.insert({
name: 'jack',
age: 20,
relatives: {
firstgrade: 20
}
});
users.insert({
name: 'jim',
age: 40,
relatives: {
firstgrade: 32
}
});
users.insert({
name: 'dave',
age: 15,
relatives: {
firstgrade: 20
}
});
users.insert({
name: 'jim',
age: 28,
relatives: {
firstgrade: 15
}
});
users.insert({
name: 'dave',
age: 12,
relatives: {
firstgrade: 12
}
});
it('max should be 32', function () {
expect(users.max('relatives.firstgrade')).toEqual(32);
});
it('max record should be 3, 32', function () {
suite.assertEqual('Max record: ', {
index: 3,
value: 32
}, users.maxRecord('relatives.firstgrade'));
});
it('min should be 12', function () {
expect(users.min('age')).toEqual(12);
});
it('min record to be 6, 12', function () {
expect(users.minRecord('age')).toEqual({
index: 6,
value: 12
});
});
it('average to be 19', function () {
expect(users.avg('relatives.firstgrade')).toEqual(19);
});
it('median to be 17.5', function () {
expect(users.median('relatives.firstgrade')).toEqual(17.5);
});
it('ages should be [35, 20, 40, 15, 28, 12]', function () {
expect(users.extract('age')).toEqual([35, 20, 40, 15, 28, 12]);
});
it('Standard deviation on firstgrade relatives should be 6.48...', function () {
expect(users.stdDev('relatives.firstgrade')).toEqual(6.48074069840786);
});
it('stdDev should be 10.23...', function () {
expect(users.stdDev('age')).toEqual(10.23067283548187);
});
});
users.insert({
name: 'jack',
age: 20,
relatives: {
firstgrade: 20
}
});
users.insert({
name: 'jim',
age: 40,
relatives: {
firstgrade: 32
}
});
users.insert({
name: 'dave',
age: 15,
relatives: {
firstgrade: 20
}
});
users.insert({
name: 'jim',
age: 28,
relatives: {
firstgrade: 15
}
});
users.insert({
name: 'dave',
age: 12,
relatives: {
firstgrade: 12
}
});
suite.assertEqual('Simple max: ', 32, users.max('relatives.firstgrade'));
suite.assertEqual('Max record: ', {
index: 3,
value: 32
}, users.maxRecord('relatives.firstgrade'));
suite.assertEqual('Simple min: ', 12, users.min('age'));
suite.assertEqual('Min record: ', {
index: 6,
value: 12
}, users.minRecord('age'));
suite.assertEqual('Average: ', 19, users.avg('relatives.firstgrade'));
suite.assertEqual('Mode: ', 20, users.mode('relatives.firstgrade'));
suite.assertEqual('Median: ', 17.5, users.median('relatives.firstgrade'));
suite.assertEqual('Extract ages: ', [35, 20, 40, 15, 28, 12], users.extract('age'));
suite.assertEqual('Standard deviation on firstgrade relatives: ', 6.48074069840786, users.stdDev('relatives.firstgrade'));
suite.assertEqual('Standard deviation on ages: ', 10.23067283548187, users.stdDev('age'));
suite.report();

@@ -1,72 +0,77 @@

var loki = require('../src/lokijs.js'),
db,
users,
gordian = require('gordian'),
suite = new gordian('testTyped');
// var loki = require('../src/lokijs.js'),
// db,
// users,
// gordian = require('gordian'),
// suite = new gordian('testTyped');
db = new loki('test.json');
describe('typed', function () {
it('works', function () {
var db = new loki('test.json');
var users;
function User(n) {
this.name = n || '';
this.log = function () {
console.log('Name: ' + this.name);
};
}
function User(n) {
this.name = n || '';
this.log = function () {
console.log('Name: ' + this.name);
};
}
var json = {
"filename": "test.json",
"collections": [{
"name": "users",
"data": [{
"name": "joe",
"objType": "users",
"meta": {
"version": 0,
"created": 1415467401386,
"revision": 0
var json = {
"filename": "test.json",
"collections": [{
"name": "users",
"data": [{
"name": "joe",
"objType": "users",
"meta": {
"version": 0,
"created": 1415467401386,
"revision": 0
},
"$loki": 1
}, {
"name": "jack",
"objType": "users",
"meta": {
"version": 0,
"created": 1415467401388,
"revision": 0
},
"$loki": 2
}],
"idIndex": [1, 2],
"binaryIndices": {},
"objType": "users",
"transactional": false,
"cachedIndex": null,
"cachedBinaryIndex": null,
"cachedData": null,
"maxId": 2,
"DynamicViews": [],
"events": {
"insert": [null],
"update": [null],
"close": [],
"flushbuffer": [],
"error": [],
"delete": []
}
}],
"events": {
"close": []
},
"$loki": 1
}, {
"name": "jack",
"objType": "users",
"meta": {
"version": 0,
"created": 1415467401388,
"revision": 0
},
"$loki": 2
}],
"idIndex": [1, 2],
"binaryIndices": {},
"objType": "users",
"transactional": false,
"cachedIndex": null,
"cachedBinaryIndex": null,
"cachedData": null,
"maxId": 2,
"DynamicViews": [],
"events": {
"insert": [null],
"update": [null],
"close": [],
"flushbuffer": [],
"error": [],
"delete": []
}
}],
"events": {
"close": []
},
"ENV": "NODEJS",
"fs": {}
};
"ENV": "NODEJS",
"fs": {}
};
db.loadJSON(JSON.stringify(json), {
users: {
proto: User
}
db.loadJSON(JSON.stringify(json), {
users: {
proto: User
}
});
users = db.getCollection('users');
//suite.assertEqual('Inflated object prototype', users.get(1) instanceof User, true);
expect(users.get(1) instanceof User).toBe(true);
});
});
users = db.getCollection('users');
suite.assertEqual('Inflated object prototype', users.get(1) instanceof User, true);
suite.report();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc