idb-wrapper
Advanced tools
Comparing version 1.5.0 to 1.6.0
@@ -5,4 +5,4 @@ { | ||
"main": "idbstore.js", | ||
"version": "1.5", | ||
"version": "1.6.0", | ||
"dependencies": {} | ||
} |
@@ -5,2 +5,3 @@ /*global window:false, self:false, define:false, module:false */ | ||
* @license IDBWrapper - A cross-browser wrapper for IndexedDB | ||
* Version 1.6.0 | ||
* Copyright (c) 2011 - 2015 Jens Arps | ||
@@ -47,3 +48,3 @@ * http://jensarps.de/ | ||
* @name IDBStore | ||
* @version 1.5 | ||
* @version 1.6.0 | ||
* | ||
@@ -120,9 +121,5 @@ * @param {Object} [kwArgs] An options object used to configure the store and | ||
var env = typeof window == 'object' ? window : self; | ||
this.idb = env.indexedDB || env.webkitIndexedDB || env.mozIndexedDB || env.shimIndexedDB; | ||
this.idb = env.shimIndexedDB || env.indexedDB || env.webkitIndexedDB || env.mozIndexedDB; | ||
this.keyRange = env.IDBKeyRange || env.webkitIDBKeyRange || env.mozIDBKeyRange; | ||
this.features = { | ||
hasAutoIncrement: !env.mozIndexedDB | ||
}; | ||
this.consts = { | ||
@@ -155,3 +152,3 @@ 'READ_ONLY': 'readonly', | ||
*/ | ||
version: '1.5', | ||
version: '1.6.0', | ||
@@ -223,11 +220,2 @@ /** | ||
/** | ||
* A hashmap of features of the used IDB implementation | ||
* | ||
* @type Object | ||
* @proprty {Boolean} autoIncrement If the implementation supports | ||
* native auto increment | ||
*/ | ||
features: null, | ||
/** | ||
* The callback to be called when the store is ready to be used | ||
@@ -584,2 +572,4 @@ * | ||
onError(new Error('dataArray argument must be of type Array.')); | ||
} else if (dataArray.length === 0) { | ||
return onSuccess(true); | ||
} | ||
@@ -825,4 +815,6 @@ var batchTransaction = this.db.transaction([this.storeName] , this.consts.READ_WRITE); | ||
if(Object.prototype.toString.call(keyArray) != '[object Array]'){ | ||
if (Object.prototype.toString.call(keyArray) != '[object Array]'){ | ||
onError(new Error('keyArray argument must be of type Array.')); | ||
} else if (keyArray.length === 0) { | ||
return onSuccess([]); | ||
} | ||
@@ -1010,3 +1002,3 @@ var batchTransaction = this.db.transaction([this.storeName] , this.consts.READ_ONLY); | ||
_addIdPropertyIfNeeded: function (dataObj) { | ||
if (!this.features.hasAutoIncrement && typeof dataObj[this.keyPath] == 'undefined') { | ||
if (typeof dataObj[this.keyPath] == 'undefined') { | ||
dataObj[this.keyPath] = this._insertIdCount++ + Date.now(); | ||
@@ -1335,4 +1327,2 @@ } | ||
/** helpers **/ | ||
// TODO: Check Object.create support to get rid of this | ||
var empty = {}; | ||
@@ -1339,0 +1329,0 @@ var mixin = function (target, source) { |
/* | ||
IDBWrapper - A cross-browser wrapper for IndexedDB | ||
Version 1.6.0 | ||
Copyright (c) 2011 - 2015 Jens Arps | ||
@@ -8,21 +9,23 @@ http://jensarps.de/ | ||
*/ | ||
(function(h,j,i){"function"===typeof define?define(j):"undefined"!==typeof module&&module.exports?module.exports=j():i[h]=j()})("IDBStore",function(){var h=function(b){throw b;},j={storeName:"Store",storePrefix:"IDBWrapper-",dbVersion:1,keyPath:"id",autoIncrement:!0,onStoreReady:function(){},onError:h,indexes:[]},i=function(b,c){"undefined"==typeof c&&"function"==typeof b&&(c=b);"[object Object]"!=Object.prototype.toString.call(b)&&(b={});for(var a in j)this[a]="undefined"!=typeof b[a]?b[a]:j[a]; | ||
this.dbName=this.storePrefix+this.storeName;this.dbVersion=parseInt(this.dbVersion,10)||1;c&&(this.onStoreReady=c);a="object"==typeof window?window:self;this.idb=a.indexedDB||a.webkitIndexedDB||a.mozIndexedDB;this.keyRange=a.IDBKeyRange||a.webkitIDBKeyRange||a.mozIDBKeyRange;this.features={hasAutoIncrement:!a.mozIndexedDB};this.consts={READ_ONLY:"readonly",READ_WRITE:"readwrite",VERSION_CHANGE:"versionchange",NEXT:"next",NEXT_NO_DUPLICATE:"nextunique",PREV:"prev",PREV_NO_DUPLICATE:"prevunique"};this.openDB()}; | ||
i.prototype={constructor:i,version:"1.4.1",db:null,dbName:null,dbVersion:null,store:null,storeName:null,keyPath:null,autoIncrement:null,indexes:null,features:null,onStoreReady:null,onError:null,_insertIdCount:0,openDB:function(){var b=this.idb.open(this.dbName,this.dbVersion),c=!1;b.onerror=function(a){var b=!1;"error"in a.target?b="VersionError"==a.target.error.name:"errorCode"in a.target&&(b=12==a.target.errorCode);if(b)this.onError(Error("The version number provided is lower than the existing one.")); | ||
else this.onError(a)}.bind(this);b.onsuccess=function(a){if(!c)if(this.db)this.onStoreReady();else if(this.db=a.target.result,"string"==typeof this.db.version)this.onError(Error("The IndexedDB implementation in this browser is outdated. Please upgrade your browser."));else if(this.db.objectStoreNames.contains(this.storeName)){this.store=this.db.transaction([this.storeName],this.consts.READ_ONLY).objectStore(this.storeName);var b=Array.prototype.slice.call(this.getIndexList());this.indexes.forEach(function(a){var e= | ||
a.name;e?(this.normalizeIndexData(a),this.hasIndex(e)?(this.indexComplies(this.store.index(e),a)||(c=!0,this.onError(Error('Cannot modify index "'+e+'" for current version. Please bump version number to '+(this.dbVersion+1)+"."))),b.splice(b.indexOf(e),1)):(c=!0,this.onError(Error('Cannot create new index "'+e+'" for current version. Please bump version number to '+(this.dbVersion+1)+".")))):(c=!0,this.onError(Error("Cannot create index: No index name given.")))},this);b.length&&(c=!0,this.onError(Error('Cannot delete index(es) "'+ | ||
b.toString()+'" for current version. Please bump version number to '+(this.dbVersion+1)+".")));c||this.onStoreReady()}else this.onError(Error("Something is wrong with the IndexedDB implementation in this browser. Please upgrade your browser."))}.bind(this);b.onupgradeneeded=function(a){this.db=a.target.result;if(this.db.objectStoreNames.contains(this.storeName))this.store=a.target.transaction.objectStore(this.storeName);else{a={autoIncrement:this.autoIncrement};if(null!==this.keyPath)a.keyPath=this.keyPath; | ||
this.store=this.db.createObjectStore(this.storeName,a)}var b=Array.prototype.slice.call(this.getIndexList());this.indexes.forEach(function(a){var e=a.name;e||(c=!0,this.onError(Error("Cannot create index: No index name given.")));this.normalizeIndexData(a);this.hasIndex(e)?(this.indexComplies(this.store.index(e),a)||(this.store.deleteIndex(e),this.store.createIndex(e,a.keyPath,{unique:a.unique,multiEntry:a.multiEntry})),b.splice(b.indexOf(e),1)):this.store.createIndex(e,a.keyPath,{unique:a.unique, | ||
multiEntry:a.multiEntry})},this);b.length&&b.forEach(function(a){this.store.deleteIndex(a)},this)}.bind(this)},deleteDatabase:function(){this.idb.deleteDatabase&&this.idb.deleteDatabase(this.dbName)},put:function(b,c,a,d){null!==this.keyPath&&(d=a,a=c,c=b);d||(d=h);a||(a=k);var f=!1,e=null,g=this.db.transaction([this.storeName],this.consts.READ_WRITE);g.oncomplete=function(){(f?a:d)(e)};g.onabort=d;g.onerror=d;null!==this.keyPath?(this._addIdPropertyIfNeeded(c),b=g.objectStore(this.storeName).put(c)): | ||
b=g.objectStore(this.storeName).put(c,b);b.onsuccess=function(a){f=!0;e=a.target.result};b.onerror=d;return g},get:function(b,c,a){a||(a=h);c||(c=k);var d=!1,f=null,e=this.db.transaction([this.storeName],this.consts.READ_ONLY);e.oncomplete=function(){(d?c:a)(f)};e.onabort=a;e.onerror=a;b=e.objectStore(this.storeName).get(b);b.onsuccess=function(a){d=!0;f=a.target.result};b.onerror=a;return e},remove:function(b,c,a){a||(a=h);c||(c=k);var d=!1,f=null,e=this.db.transaction([this.storeName],this.consts.READ_WRITE); | ||
e.oncomplete=function(){(d?c:a)(f)};e.onabort=a;e.onerror=a;b=e.objectStore(this.storeName)["delete"](b);b.onsuccess=function(a){d=!0;f=a.target.result};b.onerror=a;return e},batch:function(b,c,a){a||(a=h);c||(c=k);"[object Array]"!=Object.prototype.toString.call(b)&&a(Error("dataArray argument must be of type Array."));var d=this.db.transaction([this.storeName],this.consts.READ_WRITE);d.oncomplete=function(){(g?c:a)(g)};d.onabort=a;d.onerror=a;var f=b.length,e=!1,g=!1,l=function(){f--;0===f&&!e&& | ||
(g=e=!0)};b.forEach(function(b){var c=b.type,f=b.key,g=b.value,b=function(b){d.abort();e||(e=!0,a(b,c,f))};if("remove"==c)g=d.objectStore(this.storeName)["delete"](f),g.onsuccess=l,g.onerror=b;else if("put"==c)null!==this.keyPath?(this._addIdPropertyIfNeeded(g),g=d.objectStore(this.storeName).put(g)):g=d.objectStore(this.storeName).put(g,f),g.onsuccess=l,g.onerror=b},this);return d},putBatch:function(b,c,a){return this.batch(b.map(function(a){return{type:"put",value:a}}),c,a)},removeBatch:function(b, | ||
c,a){return this.batch(b.map(function(a){return{type:"remove",key:a}}),c,a)},getBatch:function(b,c,a,d){a||(a=h);c||(c=k);d||(d="sparse");"[object Array]"!=Object.prototype.toString.call(b)&&a(Error("keyArray argument must be of type Array."));var f=this.db.transaction([this.storeName],this.consts.READ_ONLY);f.oncomplete=function(){(l?c:a)(i)};f.onabort=a;f.onerror=a;var e=[],g=b.length,l=!1,i=null,j=function(a){a.target.result||"dense"==d?e.push(a.target.result):"sparse"==d&&e.length++;g--;0===g&& | ||
(l=!0,i=e)};b.forEach(function(b){b=f.objectStore(this.storeName).get(b);b.onsuccess=j;b.onerror=function(b){i=b;a(b);f.abort()}},this);return f},getAll:function(b,c){c||(c=h);b||(b=k);var a=this.db.transaction([this.storeName],this.consts.READ_ONLY),d=a.objectStore(this.storeName);d.getAll?this._getAllNative(a,d,b,c):this._getAllCursor(a,d,b,c);return a},_getAllNative:function(b,c,a,d){var f=!1,e=null;b.oncomplete=function(){(f?a:d)(e)};b.onabort=d;b.onerror=d;b=c.getAll();b.onsuccess=function(a){f= | ||
!0;e=a.target.result};b.onerror=d},_getAllCursor:function(b,c,a,d){var f=[],e=!1,g=null;b.oncomplete=function(){(e?a:d)(g)};b.onabort=d;b.onerror=d;b=c.openCursor();b.onsuccess=function(a){(a=a.target.result)?(f.push(a.value),a["continue"]()):(e=!0,g=f)};b.onError=d},clear:function(b,c){c||(c=h);b||(b=k);var a=!1,d=null,f=this.db.transaction([this.storeName],this.consts.READ_WRITE);f.oncomplete=function(){(a?b:c)(d)};f.onabort=c;f.onerror=c;var e=f.objectStore(this.storeName).clear();e.onsuccess= | ||
function(b){a=!0;d=b.target.result};e.onerror=c;return f},_addIdPropertyIfNeeded:function(b){!this.features.hasAutoIncrement&&"undefined"==typeof b[this.keyPath]&&(b[this.keyPath]=this._insertIdCount++ +Date.now())},getIndexList:function(){return this.store.indexNames},hasIndex:function(b){return this.store.indexNames.contains(b)},normalizeIndexData:function(b){b.keyPath=b.keyPath||b.name;b.unique=!!b.unique;b.multiEntry=!!b.multiEntry},indexComplies:function(b,c){return["keyPath","unique","multiEntry"].every(function(a){if("multiEntry"== | ||
a&&void 0===b[a]&&!1===c[a])return!0;if("keyPath"==a&&"[object Array]"==Object.prototype.toString.call(c[a])){var a=c.keyPath,d=b.keyPath;if("string"==typeof d)return a.toString()==d;if(!("function"==typeof d.contains||"function"==typeof d.indexOf)||d.length!==a.length)return!1;for(var f=0,e=a.length;f<e;f++)if(!(d.contains&&d.contains(a[f])||d.indexOf(-1!==a[f])))return!1;return!0}return c[a]==b[a]})},iterate:function(b,c){var c=m({index:null,order:"ASC",autoContinue:!0,filterDuplicates:!1,keyRange:null, | ||
writeAccess:!1,onEnd:null,onError:h},c||{}),a="desc"==c.order.toLowerCase()?"PREV":"NEXT";c.filterDuplicates&&(a+="_NO_DUPLICATE");var d=!1,f=this.db.transaction([this.storeName],this.consts[c.writeAccess?"READ_WRITE":"READ_ONLY"]),e=f.objectStore(this.storeName);c.index&&(e=e.index(c.index));f.oncomplete=function(){if(d)if(c.onEnd)c.onEnd();else b(null);else c.onError(null)};f.onabort=c.onError;f.onerror=c.onError;a=e.openCursor(c.keyRange,this.consts[a]);a.onerror=c.onError;a.onsuccess=function(a){if(a= | ||
a.target.result){if(b(a.value,a,f),c.autoContinue)a["continue"]()}else d=!0};return f},query:function(b,c){var a=[],c=c||{};c.onEnd=function(){b(a)};return this.iterate(function(b){a.push(b)},c)},count:function(b,c){var c=m({index:null,keyRange:null},c||{}),a=c.onError||h,d=!1,f=null,e=this.db.transaction([this.storeName],this.consts.READ_ONLY);e.oncomplete=function(){(d?b:a)(f)};e.onabort=a;e.onerror=a;var g=e.objectStore(this.storeName);c.index&&(g=g.index(c.index));g=g.count(c.keyRange);g.onsuccess= | ||
function(a){d=!0;f=a.target.result};g.onError=a;return e},makeKeyRange:function(b){var c="undefined"!=typeof b.lower,a="undefined"!=typeof b.upper,d="undefined"!=typeof b.only;switch(!0){case d:b=this.keyRange.only(b.only);break;case c&&a:b=this.keyRange.bound(b.lower,b.upper,b.excludeLower,b.excludeUpper);break;case c:b=this.keyRange.lowerBound(b.lower,b.excludeLower);break;case a:b=this.keyRange.upperBound(b.upper,b.excludeUpper);break;default:throw Error('Cannot create KeyRange. Provide one or both of "lower" or "upper" value, or an "only" value.'); | ||
}return b}};var k=function(){},n={},m=function(b,c){var a,d;for(a in c)d=c[a],d!==n[a]&&d!==b[a]&&(b[a]=d);return b};i.version=i.prototype.version;return i},this); | ||
(function(h,i,l){"function"===typeof define?define(i):"undefined"!==typeof module&&module.exports?module.exports=i():l[h]=i()})("IDBStore",function(){var h=function(a){throw a;},i=function(){},l={storeName:"Store",storePrefix:"IDBWrapper-",dbVersion:1,keyPath:"id",autoIncrement:!0,onStoreReady:function(){},onError:h,indexes:[]},j=function(a,c){"undefined"==typeof c&&"function"==typeof a&&(c=a);"[object Object]"!=Object.prototype.toString.call(a)&&(a={});for(var b in l)this[b]="undefined"!=typeof a[b]? | ||
a[b]:l[b];this.dbName=this.storePrefix+this.storeName;this.dbVersion=parseInt(this.dbVersion,10)||1;c&&(this.onStoreReady=c);b="object"==typeof window?window:self;this.idb=b.shimIndexedDB||b.indexedDB||b.webkitIndexedDB||b.mozIndexedDB;this.keyRange=b.IDBKeyRange||b.webkitIDBKeyRange||b.mozIDBKeyRange;this.consts={READ_ONLY:"readonly",READ_WRITE:"readwrite",VERSION_CHANGE:"versionchange",NEXT:"next",NEXT_NO_DUPLICATE:"nextunique",PREV:"prev",PREV_NO_DUPLICATE:"prevunique"};this.openDB()};j.prototype= | ||
{constructor:j,version:"1.6.0",db:null,dbName:null,dbVersion:null,store:null,storeName:null,storePrefix:null,keyPath:null,autoIncrement:null,indexes:null,onStoreReady:null,onError:null,_insertIdCount:0,openDB:function(){var a=this.idb.open(this.dbName,this.dbVersion),c=!1;a.onerror=function(b){var a=!1;"error"in b.target?a="VersionError"==b.target.error.name:"errorCode"in b.target&&(a=12==b.target.errorCode);if(a)this.onError(Error("The version number provided is lower than the existing one."));else this.onError(b)}.bind(this); | ||
a.onsuccess=function(a){if(!c)if(this.db)this.onStoreReady();else if(this.db=a.target.result,"string"==typeof this.db.version)this.onError(Error("The IndexedDB implementation in this browser is outdated. Please upgrade your browser."));else if(this.db.objectStoreNames.contains(this.storeName)){this.store=this.db.transaction([this.storeName],this.consts.READ_ONLY).objectStore(this.storeName);var d=Array.prototype.slice.call(this.getIndexList());this.indexes.forEach(function(a){var b=a.name;b?(this.normalizeIndexData(a), | ||
this.hasIndex(b)?(this.indexComplies(this.store.index(b),a)||(c=!0,this.onError(Error('Cannot modify index "'+b+'" for current version. Please bump version number to '+(this.dbVersion+1)+"."))),d.splice(d.indexOf(b),1)):(c=!0,this.onError(Error('Cannot create new index "'+b+'" for current version. Please bump version number to '+(this.dbVersion+1)+".")))):(c=!0,this.onError(Error("Cannot create index: No index name given.")))},this);d.length&&(c=!0,this.onError(Error('Cannot delete index(es) "'+d.toString()+ | ||
'" for current version. Please bump version number to '+(this.dbVersion+1)+".")));c||this.onStoreReady()}else this.onError(Error("Something is wrong with the IndexedDB implementation in this browser. Please upgrade your browser."))}.bind(this);a.onupgradeneeded=function(a){this.db=a.target.result;if(this.db.objectStoreNames.contains(this.storeName))this.store=a.target.transaction.objectStore(this.storeName);else{a={autoIncrement:this.autoIncrement};if(null!==this.keyPath)a.keyPath=this.keyPath;this.store= | ||
this.db.createObjectStore(this.storeName,a)}var d=Array.prototype.slice.call(this.getIndexList());this.indexes.forEach(function(a){var b=a.name;b||(c=!0,this.onError(Error("Cannot create index: No index name given.")));this.normalizeIndexData(a);this.hasIndex(b)?(this.indexComplies(this.store.index(b),a)||(this.store.deleteIndex(b),this.store.createIndex(b,a.keyPath,{unique:a.unique,multiEntry:a.multiEntry})),d.splice(d.indexOf(b),1)):this.store.createIndex(b,a.keyPath,{unique:a.unique,multiEntry:a.multiEntry})}, | ||
this);d.length&&d.forEach(function(a){this.store.deleteIndex(a)},this)}.bind(this)},deleteDatabase:function(a,c){if(this.idb.deleteDatabase){this.db.close();var b=this.idb.deleteDatabase(this.dbName);b.onsuccess=a;b.onerror=c}else c(Error("Browser does not support IndexedDB deleteDatabase!"))},put:function(a,c,b,d){null!==this.keyPath&&(d=b,b=c,c=a);d||(d=h);b||(b=i);var e=!1,f=null,g=this.db.transaction([this.storeName],this.consts.READ_WRITE);g.oncomplete=function(){(e?b:d)(f)};g.onabort=d;g.onerror= | ||
d;null!==this.keyPath?(this._addIdPropertyIfNeeded(c),a=g.objectStore(this.storeName).put(c)):a=g.objectStore(this.storeName).put(c,a);a.onsuccess=function(a){e=!0;f=a.target.result};a.onerror=d;return g},get:function(a,c,b){b||(b=h);c||(c=i);var d=!1,e=null,f=this.db.transaction([this.storeName],this.consts.READ_ONLY);f.oncomplete=function(){(d?c:b)(e)};f.onabort=b;f.onerror=b;a=f.objectStore(this.storeName).get(a);a.onsuccess=function(a){d=!0;e=a.target.result};a.onerror=b;return f},remove:function(a, | ||
c,b){b||(b=h);c||(c=i);var d=!1,e=null,f=this.db.transaction([this.storeName],this.consts.READ_WRITE);f.oncomplete=function(){(d?c:b)(e)};f.onabort=b;f.onerror=b;a=f.objectStore(this.storeName)["delete"](a);a.onsuccess=function(a){d=!0;e=a.target.result};a.onerror=b;return f},batch:function(a,c,b){b||(b=h);c||(c=i);if("[object Array]"!=Object.prototype.toString.call(a))b(Error("dataArray argument must be of type Array."));else if(0===a.length)return c(!0);var d=this.db.transaction([this.storeName], | ||
this.consts.READ_WRITE);d.oncomplete=function(){(g?c:b)(g)};d.onabort=b;d.onerror=b;var e=a.length,f=!1,g=!1,k=function(){e--;0===e&&!f&&(g=f=!0)};a.forEach(function(a){var c=a.type,e=a.key,g=a.value,a=function(a){d.abort();f||(f=!0,b(a,c,e))};if("remove"==c)g=d.objectStore(this.storeName)["delete"](e),g.onsuccess=k,g.onerror=a;else if("put"==c)null!==this.keyPath?(this._addIdPropertyIfNeeded(g),g=d.objectStore(this.storeName).put(g)):g=d.objectStore(this.storeName).put(g,e),g.onsuccess=k,g.onerror= | ||
a},this);return d},putBatch:function(a,c,b){return this.batch(a.map(function(a){return{type:"put",value:a}}),c,b)},upsertBatch:function(a,c,b,d){"function"==typeof c&&(d=b=c,c={});d||(d=h);b||(b=i);c||(c={});"[object Array]"!=Object.prototype.toString.call(a)&&d(Error("dataArray argument must be of type Array."));var e=this.db.transaction([this.storeName],this.consts.READ_WRITE);e.oncomplete=function(){m?b(a):d(!1)};e.onabort=d;e.onerror=d;var f=c.keyField||this.keyPath,g=a.length,k=!1,m=!1,j=0,o= | ||
function(b){a[j++][f]=b.target.result;g--;0===g&&!k&&(m=k=!0)};a.forEach(function(a){var b=a.key;null!==this.keyPath?(this._addIdPropertyIfNeeded(a),a=e.objectStore(this.storeName).put(a)):a=e.objectStore(this.storeName).put(a,b);a.onsuccess=o;a.onerror=function(a){e.abort();k||(k=!0,d(a))}},this);return e},removeBatch:function(a,c,b){return this.batch(a.map(function(a){return{type:"remove",key:a}}),c,b)},getBatch:function(a,c,b,d){b||(b=h);c||(c=i);d||(d="sparse");if("[object Array]"!=Object.prototype.toString.call(a))b(Error("keyArray argument must be of type Array.")); | ||
else if(0===a.length)return c([]);var e=this.db.transaction([this.storeName],this.consts.READ_ONLY);e.oncomplete=function(){(k?c:b)(j)};e.onabort=b;e.onerror=b;var f=[],g=a.length,k=!1,j=null,l=function(a){a.target.result||"dense"==d?f.push(a.target.result):"sparse"==d&&f.length++;g--;0===g&&(k=!0,j=f)};a.forEach(function(a){a=e.objectStore(this.storeName).get(a);a.onsuccess=l;a.onerror=function(a){j=a;b(a);e.abort()}},this);return e},getAll:function(a,c){c||(c=h);a||(a=i);var b=this.db.transaction([this.storeName], | ||
this.consts.READ_ONLY),d=b.objectStore(this.storeName);d.getAll?this._getAllNative(b,d,a,c):this._getAllCursor(b,d,a,c);return b},_getAllNative:function(a,c,b,d){var e=!1,f=null;a.oncomplete=function(){(e?b:d)(f)};a.onabort=d;a.onerror=d;a=c.getAll();a.onsuccess=function(a){e=!0;f=a.target.result};a.onerror=d},_getAllCursor:function(a,c,b,d){var e=[],f=!1,g=null;a.oncomplete=function(){(f?b:d)(g)};a.onabort=d;a.onerror=d;a=c.openCursor();a.onsuccess=function(a){(a=a.target.result)?(e.push(a.value), | ||
a["continue"]()):(f=!0,g=e)};a.onError=d},clear:function(a,c){c||(c=h);a||(a=i);var b=!1,d=null,e=this.db.transaction([this.storeName],this.consts.READ_WRITE);e.oncomplete=function(){(b?a:c)(d)};e.onabort=c;e.onerror=c;var f=e.objectStore(this.storeName).clear();f.onsuccess=function(a){b=!0;d=a.target.result};f.onerror=c;return e},_addIdPropertyIfNeeded:function(a){"undefined"==typeof a[this.keyPath]&&(a[this.keyPath]=this._insertIdCount++ +Date.now())},getIndexList:function(){return this.store.indexNames}, | ||
hasIndex:function(a){return this.store.indexNames.contains(a)},normalizeIndexData:function(a){a.keyPath=a.keyPath||a.name;a.unique=!!a.unique;a.multiEntry=!!a.multiEntry},indexComplies:function(a,c){return["keyPath","unique","multiEntry"].every(function(b){if("multiEntry"==b&&void 0===a[b]&&!1===c[b])return!0;if("keyPath"==b&&"[object Array]"==Object.prototype.toString.call(c[b])){var b=c.keyPath,d=a.keyPath;if("string"==typeof d)return b.toString()==d;if(!("function"==typeof d.contains||"function"== | ||
typeof d.indexOf)||d.length!==b.length)return!1;for(var e=0,f=b.length;e<f;e++)if(!(d.contains&&d.contains(b[e])||d.indexOf(-1!==b[e])))return!1;return!0}return c[b]==a[b]})},iterate:function(a,c){var c=n({index:null,order:"ASC",autoContinue:!0,filterDuplicates:!1,keyRange:null,writeAccess:!1,onEnd:null,onError:h,limit:Infinity,offset:0},c||{}),b="desc"==c.order.toLowerCase()?"PREV":"NEXT";c.filterDuplicates&&(b+="_NO_DUPLICATE");var d=!1,e=this.db.transaction([this.storeName],this.consts[c.writeAccess? | ||
"READ_WRITE":"READ_ONLY"]),f=e.objectStore(this.storeName);c.index&&(f=f.index(c.index));var g=0;e.oncomplete=function(){if(d)if(c.onEnd)c.onEnd();else a(null);else c.onError(null)};e.onabort=c.onError;e.onerror=c.onError;b=f.openCursor(c.keyRange,this.consts[b]);b.onerror=c.onError;b.onsuccess=function(b){if(b=b.target.result)if(c.offset)b.advance(c.offset),c.offset=0;else{if(a(b.value,b,e),g++,c.autoContinue)if(g+c.offset<c.limit)b["continue"]();else d=!0}else d=!0};return e},query:function(a,c){var b= | ||
[],c=c||{};c.autoContinue=!0;c.writeAccess=!1;c.onEnd=function(){a(b)};return this.iterate(function(a){b.push(a)},c)},count:function(a,c){var c=n({index:null,keyRange:null},c||{}),b=c.onError||h,d=!1,e=null,f=this.db.transaction([this.storeName],this.consts.READ_ONLY);f.oncomplete=function(){(d?a:b)(e)};f.onabort=b;f.onerror=b;var g=f.objectStore(this.storeName);c.index&&(g=g.index(c.index));g=g.count(c.keyRange);g.onsuccess=function(a){d=!0;e=a.target.result};g.onError=b;return f},makeKeyRange:function(a){var c= | ||
"undefined"!=typeof a.lower,b="undefined"!=typeof a.upper,d="undefined"!=typeof a.only;switch(!0){case d:a=this.keyRange.only(a.only);break;case c&&b:a=this.keyRange.bound(a.lower,a.upper,a.excludeLower,a.excludeUpper);break;case c:a=this.keyRange.lowerBound(a.lower,a.excludeLower);break;case b:a=this.keyRange.upperBound(a.upper,a.excludeUpper);break;default:throw Error('Cannot create KeyRange. Provide one or both of "lower" or "upper" value, or an "only" value.');}return a}};var p={},n=function(a, | ||
c){var b,d;for(b in c)d=c[b],d!==p[b]&&d!==a[b]&&(a[b]=d);return a};j.version=j.prototype.version;return j},this); |
{ | ||
"name": "idb-wrapper", | ||
"version": "1.5.0", | ||
"version": "1.6.0", | ||
"description": "A cross-browser wrapper for IndexedDB", | ||
@@ -15,9 +15,3 @@ "keywords": [ | ||
"contributors": [ | ||
"Josh Matthews <josh@joshmatthews.net> (http://www.joshmatthews.net/blog/)", | ||
"Raynos <raynos2@gmail.com> (http://raynos.org)", | ||
"Chad Engler <chad@pantherdev.com> (http://chad.pantherdev.com)", | ||
"Max Ogden <max+ogden@maxogden.com> (http://www.maxogden.com)", | ||
"Asa Ayers <asa.ayers@gmail.com>", | ||
"bdPeter (https://github.com/pbenschop)", | ||
"James Kyburz (https://github.com/JamesKyburz)" | ||
"Github Contributors (https://github.com/jensarps/IDBWrapper/graphs/contributors)" | ||
], | ||
@@ -30,4 +24,4 @@ "bugs": { | ||
"devDependencies": { | ||
"mocha": "~1.13.0", | ||
"chai": "~1.8.1" | ||
"mocha": "~2.3.3", | ||
"chai": "~3.3.0" | ||
}, | ||
@@ -34,0 +28,0 @@ "licenses": [ |
536
README.md
@@ -17,2 +17,3 @@ [![NPM version](https://badge.fury.io/js/idb-wrapper.svg)](http://badge.fury.io/js/idb-wrapper) [![Dependency Status](https://gemnasium.com/jensarps/IDBWrapper.png)](https://gemnasium.com/jensarps/IDBWrapper) | ||
* IE 10+ | ||
* Safari 8+ | ||
@@ -29,12 +30,16 @@ **Mobile** | ||
* Chrome | ||
* Chrome for Android | ||
* Firefox | ||
* Opera | ||
* Opera for Android | ||
* IE10 | ||
* IE10 for WP8 | ||
* Chrome (also on Android) | ||
* Firefox (also on Android) | ||
* Opera (also on Android) | ||
* IE10+ (also on WP8+) | ||
If using in an older browser supporting WebSql along with [IndexedDBShim](https://github.com/axemclion/IndexedDBShim), IndexedDBShim needs to run first. | ||
Note on limited/buggy IndexedDB support: | ||
* IE has limited support, which can be fixed by including [idb-iegap](https://github.com/dfahlander/idb-iegap) | ||
* Safari has buggy support, which can be fixed by using the above mentioned shim | ||
#Using IDBWrapper | ||
##Tutorials | ||
@@ -50,4 +55,3 @@ | ||
Examples | ||
======== | ||
##Examples | ||
@@ -58,26 +62,28 @@ There are some examples to run right in your browser over here: http://jensarps.github.com/IDBWrapper/example/ | ||
API Reference | ||
============= | ||
##Wiki | ||
For usage instructions, details about mothods for reading and writing | ||
data, setting up indexes and runnoing queries, please refer to the | ||
[Wiki](https://github.com/jensarps/IDBWrapper/wiki). | ||
##API Reference | ||
There's an API reference over here: http://jensarps.github.com/IDBWrapper/jsdoc/IDBStore.html | ||
You can create a local version of the reference using a terminal. Go into the | ||
IDBWrapper directory and run the following command: | ||
#Obtaining IDBWrapper | ||
```bash | ||
$ make doc | ||
``` | ||
##git | ||
Obtaining IDBWrapper | ||
==================== | ||
You can git clone the repository, or download a zip file here: https://github.com/jensarps/IDBWrapper/tags | ||
IDBWrapper is also available on [cdnjs](http://cdnjs.com/), so you can directly point a script tag there, or require() | ||
it from there. cdnjs supports http, https and spdy, so you can just leave the protocol off. The URL is: | ||
##cdnjs | ||
``` | ||
//cdnjs.cloudflare.com/ajax/libs/idbwrapper/1.4.1/idbstore.min.js | ||
``` | ||
IDBWrapper is also available on [cdnjs](http://cdnjs.com/). You can directly | ||
point a script tag there, or require() it from there. cdnjs supports http, | ||
https and spdy, so you can just leave the protocol off. The URLs for the | ||
different versions of IDBWrapper can be found here: | ||
[https://cdnjs.com/libraries/idbwrapper](https://cdnjs.com/libraries/idbwrapper) | ||
##Package Managers | ||
If you use NPM as your package manager, you can get it from there, too, by | ||
@@ -102,482 +108,4 @@ running: | ||
#License | ||
Usage | ||
===== | ||
Including the idbstore.js file will add an IDBStore constructor to the global scope. | ||
Alternatively, you can use an AMD loader such as RequireJS, or a CommonJS loader | ||
to load the module, and you will receive the constructor in your load callback | ||
(the constructor will then, of course, have whatever name you call it). | ||
You can then create an IDB store: | ||
```javascript | ||
var myStore = new IDBStore(); | ||
``` | ||
You may pass two parameters to the constructor: the first is an object with optional parameters, | ||
the second is a function reference to a function that is called when the store is ready to use. | ||
The options object may contain the following properties (default values are shown -- all | ||
properties are optional): | ||
```javascript | ||
{ | ||
storeName: 'Store', | ||
storePrefix: 'IDBWrapper-', | ||
dbVersion: 1, | ||
keyPath: 'id', | ||
autoIncrement: true, | ||
indexes: [], | ||
onStoreReady: function(){}, | ||
onError: function(error){ throw error; } | ||
} | ||
``` | ||
'storeName' is the name of the store: for different stores, use different names. | ||
'storePrefix' is an additional prefix; the created database will finally have | ||
the name "storePrefix+storeName". You can safely ignore this property, but if | ||
you want to have full control over the IDB name, you can pass your own prefix. | ||
'dbVersion' is the version number of your store. You'll only have to provide | ||
this if you change the structure of the store at a later time. | ||
'keyPath' is the name of the property to be used as key index. If `autoIncrement` is set to true, | ||
the database will automatically add a unique key to the keyPath index when storing objects missing | ||
that property. If you want to use out-of-line keys, you must set this property to `null` (see below for details on out-of-line keys). | ||
'autoIncrement' is a boolean and toggles, well, auto-increment on or off. You | ||
can leave it to true, even if you do provide your own ids. | ||
'indexes' is an array of objects defining indexes (see below for details on indexes). | ||
'onError' gets called if an error occurred while trying to open the store. It | ||
receives the error instance as only argument. | ||
As an alternative to passing a ready handler as second argument, you can also | ||
pass it in the 'onStoreReady' property. If a callback is provided both as second | ||
parameter and inside of the options object, the function passed as second | ||
parameter will be used. | ||
### Out-of-line Keys | ||
IDBWrapper supports working with out-of-line keys. This is a feature of IndexedDB, and it means that an object's identifier is not kept on the object itself. Usually, you'll want to go with the default way, using in-line keys. If you, however, want to use out-of-line keys, note that the `put()` and `batch()` methods behave differently, and that the `autoIncrement` property has no effect – you MUST take care of the ids yourself! | ||
Methods | ||
======= | ||
Here's an overview of available methods in IDBStore: | ||
Data Manipulation | ||
----------------- | ||
Use the following methods to read and write data (all methods in this section return the `IDBTransaction` they open): | ||
___ | ||
1) The put method. | ||
```javascript | ||
put(/*Object*/ dataObj, /*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
`dataObj` is the Object to store. `onSuccess` will be called when the insertion/update was successful, | ||
and it will receive the keyPath value (the id, so to say) of the inserted object as first and only | ||
argument. `onError` will be called if the insertion/update failed and it will receive the error event | ||
object as first and only argument. If the store already contains an object with the given keyPath id, | ||
it will be overwritten by `dataObj`. | ||
**Out-of-line Keys** | ||
If you use out-of-line keys in your store, you must provide a key as first argument to the put method: | ||
```javascript | ||
put(/*Anything*/ key, /*Object*/ dataObj, /*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
The `onSuccess` and `onError` arguments remain optional. | ||
___ | ||
2) The get method. | ||
```javascript | ||
get(/*keyPath value*/ key, /*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
`key` is the keyPath property value (the id) of the object to retrieve. `onSuccess` will be called if | ||
the get operation was successful, and it will receive the stored object as first and only argument. If | ||
no object was found with the given keyPath value, this argument will be null. `onError` will be called | ||
if the get operation failed and it will receive the error event object as first and only argument. | ||
___ | ||
3) The getAll method. | ||
```javascript | ||
getAll: function(/*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
`onSuccess` will be called if the getAll operation was successful, and it will receive an Array of | ||
all objects currently stored in the store as first and only argument. `onError` will be called if | ||
the getAll operation failed and it will receive the error event object as first and only argument. | ||
___ | ||
4) The remove method. | ||
```javascript | ||
remove: function(/*keyPath value*/ key, /*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
`key` is the keyPath property value (the id) of the object to remove. `onSuccess` will be called if | ||
the remove operation was successful, and it _should_ receive `false` as first and only argument if the | ||
object to remove was not found, and `true` if it was found and removed. | ||
NOTE: FF 8 will pass the key to the onSuccess handler, no matter if there is an corresponding object | ||
or not. Chrome 15 will pass `null` if removal was successful, and call the error handler if the object | ||
wasn't found. Chrome 17 will behave as described above. | ||
`onError` will be called if the remove operation failed and it will receive the error event object as first | ||
and only argument. | ||
___ | ||
5) The clear method. | ||
```javascript | ||
clear: function(/*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
`onSuccess` will be called if the clear operation was successful. `onError` will be called if the clear | ||
operation failed and it will receive the error event object as first and only argument. | ||
##Batch Operations | ||
IDBWrapper allows to run a single method when dealing with multiple objects. All methods in this section return the `IDBTransaction` they open. | ||
1) The getBatch method. | ||
```javascript | ||
getBatch: function (/*Array*/keyArray, /*Function?*/onSuccess, /*Function?*/onError, /*String?*/arrayType) | ||
``` | ||
This method takes an array of keys and fetches matching objects. | ||
`keyArray` must be an array of keys identifying the objects to fetch. | ||
`arrayType` defines the type of array to pass to the success handler. May be one of 'sparse', 'dense' or 'skip'. Defaults to 'sparse'. This parameter specifies how to handle the situation if a get operation did not throw an error, but there was no matching object in the database. In most cases, 'sparse' provides the most desired behavior. See the examples for details: | ||
```javascript | ||
// given that there are two objects in the database with the keypath | ||
// values 1 and 2, and the call looks like this: | ||
myStore.getBatch([1, 5, 2], function (data) { … }, onError, arrayType); | ||
// this is what the `data` array will be like: | ||
// arrayType == 'sparse': | ||
// data is a sparse array containing two entries and having a length of 3: | ||
[Object, 2: Object] | ||
0: Object | ||
2: Object | ||
length: 3 | ||
__proto__: Array[0] | ||
// calling forEach on data will result in the callback being called two | ||
// times, with the index parameter matching the index of the key in the | ||
// keyArray. | ||
// arrayType == 'dense': | ||
// data is a dense array containing three entries and having a length of 3, | ||
// where data[1] is of type undefined: | ||
[Object, undefined, Object] | ||
0: Object | ||
1: undefined | ||
2: Object | ||
length: 3 | ||
__proto__: Array[0] | ||
// calling forEach on data will result in the callback being called three | ||
// times, with the index parameter matching the index of the key in the | ||
// keyArray, but the second call will have undefined as first argument. | ||
// arrayType == 'skip': | ||
// data is a dense array containing two entries and having a length of 2: | ||
[Object, Object] | ||
0: Object | ||
1: Object | ||
length: 2 | ||
__proto__: Array[0] | ||
// calling forEach on data will result in the callback being called two | ||
// times, with the index parameter not matching the index of the key in the | ||
// keyArray. | ||
``` | ||
___ | ||
2) The putBatch method. | ||
```javascript | ||
putBatch: function (/*Array*/dataArray, /*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
`putBatch` takes an array of objects and stores them in a single transaction. | ||
**Out-of-line Keys** | ||
The `putBatch` method does not support out-of-line keys. If you need to store multiple out-of-line objects, use the `batch` method. | ||
___ | ||
3) The removeBatch method. | ||
```javascript | ||
removeBatch: function (/*Array*/keyArray, /*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
`removeBatch` takes an array of keys and removes matching objects in a single transaction. | ||
--- | ||
4) The batch method. | ||
```javascript | ||
batch: function (/*Array*/operations, /*Function?*/onSuccess, /*Function?*/onError) | ||
``` | ||
This method allows you to combine put and remove actions in a single call. `batch` expects an array of operations that you want to apply in a single | ||
IndexedDB transaction. `operations` is an Array of objects, each containing two | ||
properties, defining the type of operation. There are two operations | ||
supported, put and remove. A put entry looks like this: | ||
```javascript | ||
{ type: "put", value: dataObj } // dataObj being the object to store | ||
``` | ||
A remove entry looks like this; | ||
```javascript | ||
{ type: "remove", key: someKey } // someKey being the keyPath value of the item to remove | ||
``` | ||
You can mix both types in the `operations` Array: | ||
```javascript | ||
batch([ | ||
{ type: "put", value: dataObj }, | ||
{ type: "remove", key: someKey } | ||
], onSuccess, onError) | ||
``` | ||
`onSuccess` will be called if all operations were successful and will receive no | ||
arguments. `onError` will be called if an error happens for one of the | ||
operations and will receive three arguments: the Error instance, the type of | ||
operation that caused the error and either the key or the value property | ||
(depending on the type). | ||
If an error occurs, no changes will be made to the store, even if some | ||
of the given operations would have succeeded. | ||
**Out-of-line Keys** | ||
If you use out-of-line keys, you must also provide a key to put operations: | ||
```javascript | ||
{ type: "put", value: dataObj, key: 12345 } // also add a `key` property containing the object's identifier | ||
``` | ||
Index Operations | ||
---------------- | ||
To create indexes, you need to pass the index information to the IDBStore() | ||
constructor, for example: | ||
```javascript | ||
{ | ||
storeName: 'customers', | ||
dbVersion: 1, | ||
keyPath: 'customerid', | ||
autoIncrement: true, | ||
onStoreReady: function(){}, | ||
indexes: [ | ||
{ name: 'lastname', keyPath: 'lastname', unique: false, multiEntry: false } | ||
] | ||
} | ||
``` | ||
An entry in the index Array is an object containing the following properties: | ||
The `name` property is the identifier of the index. If you want to work with the created index later, this name is used to identify the index. This is the only property that is mandatory. | ||
The `keyPath` property is the name of the property in your stored data that you want to index. If you omit that, IDBWrapper will assume that it is the same as the provided name, and will use this instead. | ||
The `unique` property tells the store whether the indexed property in your data is unique. If you set this to true, it will add a uniqueness constraint to the store which will make it throw if you try to store data that violates that constraint. If you omit that, IDBWrapper will set this to false. | ||
The `multiEntry` property is kinda weird. You can read up on it here: http://www.w3.org/TR/IndexedDB/#dfn-multientry. However, you can live perfectly fine with setting this to false (or just omitting it, this is set to false by default). | ||
If you want to add an index to an existing store, you need to increase the | ||
version number of your store, as adding an index changes the structure of | ||
the database. | ||
To modify an index, modify the object in the indexes Array in the constructor. | ||
Again, you need to increase the version of your store. | ||
In addition, there are still some convenience methods available: | ||
___ | ||
1) The hasIndex method. | ||
```javascript | ||
hasIndex: function(/*String*/ indexName) | ||
``` | ||
Return true if an index with the given name exists in the store, false if not. | ||
___ | ||
2) The getIndexList method. | ||
```javascript | ||
getIndexList: function() | ||
``` | ||
Returns a `DOMStringList` with all existing indices. | ||
Running Queries | ||
--------------- | ||
To run queries, IDBWrapper provides a `query()` and an `iterate()` method. To create keyRanges, there is the `makeKeyRange()` method. In addition to these, IDBWrapper comes with a `count()` method. The `query`, `iterate` and `count` methods return the `IDBTransaction` they open. | ||
___ | ||
1) The iterate method. | ||
```javascript | ||
iterate: function(/*Function*/ onItem, /*Object*/ iterateOptions) | ||
``` | ||
The `onItem` callback will be called once for every match. It will receive three arguments: the object that matched the query, a reference to the current cursor object (IDBWrapper uses IndexedDB's Cursor internally to iterate), and a reference to the current ongoing transaction. | ||
There's one special situation: if you didn't pass an onEnd handler in the options objects (see below), the onItem handler will be called one extra time when the transaction is over. In this case, it will receive null as only argument. So, to check when the iteration is over and you won't get any more data objects, you can either pass an onEnd handler, or check for null in the onItem handler. | ||
The `iterateOptions` object can contain one or more of the following properties: | ||
The `index` property contains the name of the index to operate on. If you omit this, IDBWrapper will use the store's keyPath as index. | ||
In the `keyRange` property you can pass a keyRange. | ||
The `order` property can be set to 'ASC' or 'DESC', and determines the ordering direction of results. If you omit this, IDBWrapper will use 'ASC'. | ||
The `autoContinue` property defaults to true. If you set this to false, IDBWrapper will not automatically advance the cursor to next result, but instead pause after it obtained a result. To move the cursor to the next result, you need to call the cursor object's `continue()` method (you get the cursor object as second argument to the `onItem` callback). | ||
The `filterDuplicates` property is an interesting one: If you set this to true (it defaults to false), and have several objects that have the same value in their key, the store will only fetch the first of those. It is not about objects being the same, it's about their key being the same. For example, in the customers database are a couple of guys having 'Smith' as last name. Setting filterDuplicates to true in the above example will make `iterate()` call the onItem callback only for the first of those. | ||
The `writeAccess` property defaults to false. If you need write access to the store during the iteration, you need to set this to true. | ||
In the `onEnd` property you can pass a callback that gets called after the iteration is over and the transaction is closed. It does not receive any arguments. | ||
In the `onError` property you can pass a custom error handler. In case of an error, it will be called and receives the Error object as only argument. | ||
The `limit` property defaults to `Infinity` and is used to limit the resultset to the provided number. | ||
The `offset` property defaults to `0` and is used to skip the provided number of results in the resultset. | ||
___ | ||
2) The query method. | ||
```javascript | ||
query: function(/*Function*/ onSuccess, /*Object*/ queryOptions) | ||
``` | ||
The query() method is just like the iterate() method, except that it will call | ||
the onSuccess callback with an array of the matched objects instead of calling | ||
a callback for each item. | ||
The `onSuccess` callback will be called if the operation was successful, and it | ||
will receive an array objects as only argument. | ||
The `queryOptions` object can contain one or more of the following properties: | ||
The `index` property contains the name of the index to operate on. If you omit this, IDBWrapper will use the store's keyPath as index. | ||
In the `keyRange` property you can pass a keyRange. | ||
The `order` property can be set to 'ASC' or 'DESC', and determines the ordering direction of results. If you omit this, IDBWrapper will use 'ASC'. | ||
The `filterDuplicates` property is an interesting one: If you set this to true (it defaults to false), and have several objects that have the same value in their key, the store will only fetch the first of those. It is not about objects being the same, it's about their key being the same. For example, in the customers database are a couple of guys having 'Smith' as last name. Setting filterDuplicates to true in the above example will make `iterate()` call the onItem callback only for the first of those. | ||
In the `onError` property you can pass a custom error handler. In case of an error, it will be called and receives the Error object as only argument. | ||
The `limit` property defaults to `Infinity` and is used to limit the resultset to the provided number. | ||
The `offset` property defaults to `0` and is used to skip the provided number of results in the resultset. | ||
___ | ||
3) The makeKeyRange method. | ||
```javascript | ||
makeKeyRange: function(/*Object*/ keyRangeOptions) | ||
``` | ||
Returns an IDBKeyRange. | ||
The `keyRangeOptions` object must have one or more of the following properties: | ||
`lower`: The lower bound of the range | ||
`excludeLower`: Boolean, whether to exclude the lower bound itself. Default: false | ||
`upper`: The upper bound of the range | ||
`excludeUpper`: Boolean, whether to exclude the upper bound itself. Default: false | ||
`only`: If you want a key range around only one value, pass just this property. | ||
___ | ||
4) The count method. | ||
```javascript | ||
count: function(/*Function*/ onSuccess, /*Object*/ countOptions) | ||
``` | ||
The onSuccess receives the result of the count as only argument. | ||
The `countOptions` object may have one or more of the following properties: | ||
index: The name of an index to operate on. | ||
keyRange: A keyRange to use | ||
[MIT style (X11)](https://github.com/jensarps/IDBWrapper/blob/master/LICENSE) |
@@ -215,2 +215,10 @@ describe('IDBWrapper', function(){ | ||
it('should short circuit putBatch when an empty array of items are passed and should call success', function(done) { | ||
store.putBatch([], function(){ | ||
done(); | ||
}, function(error){ | ||
done(new Error('Error event encountered when an empty data array is passed to putBatch.', error)); | ||
}); | ||
}); | ||
it('should fetch multiple objects', function(done){ | ||
@@ -225,2 +233,11 @@ store.getBatch([1,2,3], function(data){ | ||
it('should short circuit getBatch when an empty array of keys is passed with calling success with an empty array of results', function(done) { | ||
store.getBatch([], function(data){ | ||
expect(data).to.deep.equal([]); | ||
done(); | ||
}, function(error){ | ||
done(new Error('Error event encountered when an empty key array is passed to getBatch. The error message is null and not useful.', error)); | ||
}); | ||
}); | ||
it('should delete multiple objects', function(done){ | ||
@@ -237,3 +254,11 @@ store.removeBatch([1,2], function(result){ | ||
it('should short circuit removeBatch when an empty array of items is passed and should call success', function(done) { | ||
store.removeBatch([], function(){ | ||
done(); | ||
}, function(error){ | ||
done(new Error('Error event encountered when an empty data array is passed to removeBatch.', error)); | ||
}); | ||
}); | ||
after(function(done){ | ||
@@ -391,10 +416,19 @@ store.clear(function(){ | ||
before(function(done){ | ||
var indexes = [ | ||
{ name: 'basic', keyPath: 'name', unique: false, multiEntry: false }, | ||
{ name: 'deep', keyPath: 'address.email', unique: false, multiEntry: false }, | ||
{ name: 'date', keyPath: 'joined', unique: false, multiEntry: false } | ||
]; | ||
if (!excludeIE) { | ||
indexes.push.apply(indexes, [ | ||
{ name: 'compound', keyPath: ['name', 'age'], unique: false, multiEntry: false }, | ||
{ name: 'multi', keyPath: 'pets', unique: false, multiEntry: true } | ||
]); | ||
} | ||
store = new IDBStore({ | ||
storeName: 'spec-store-indexes', | ||
indexes: [ | ||
{ name: 'basic', keyPath: 'name', unique: false, multiEntry: false }, | ||
{ name: 'deep', keyPath: 'address.email', unique: false, multiEntry: false }, | ||
{ name: 'date', keyPath: 'joined', unique: false, multiEntry: false }, | ||
{ name: 'compound', keyPath: ['name', 'age'], unique: false, multiEntry: false } | ||
] | ||
indexes: indexes | ||
}, done); | ||
@@ -406,3 +440,3 @@ }); | ||
expect(indexList).to.respondTo('contains'); | ||
expect(indexList.length).to.equal(4); | ||
expect(indexList.length).to.equal(excludeIE ? 3 : 5); | ||
}); | ||
@@ -420,3 +454,4 @@ | ||
city: 'New Boston' | ||
} | ||
}, | ||
pets: ['cat', 'dog'] | ||
}; | ||
@@ -442,10 +477,19 @@ store.put(data, function(insertId){ | ||
before(function(done){ | ||
var indexes = [ | ||
{ name: 'basic', keyPath: 'name', unique: false, multiEntry: false }, | ||
{ name: 'deep', keyPath: 'address.email', unique: false, multiEntry: false }, | ||
{ name: 'date', keyPath: 'joined', unique: false, multiEntry: false } | ||
]; | ||
if (!excludeIE) { | ||
indexes.push.apply(indexes, [ | ||
{ name: 'compound', keyPath: ['name', 'age'], unique: false, multiEntry: false }, | ||
{ name: 'multi', keyPath: 'pets', unique: false, multiEntry: true } | ||
]); | ||
} | ||
store = new IDBStore({ | ||
storeName: 'spec-store-indexes', | ||
indexes: [ | ||
{ name: 'basic', keyPath: 'name', unique: false, multiEntry: false }, | ||
{ name: 'deep', keyPath: 'address.email', unique: false, multiEntry: false }, | ||
{ name: 'date', keyPath: 'joined', unique: false, multiEntry: false }, | ||
{ name: 'compound', keyPath: ['name', 'age'], unique: false, multiEntry: false } | ||
] | ||
indexes: indexes | ||
}, function(){ | ||
@@ -463,3 +507,4 @@ | ||
city: 'New Boston' | ||
} | ||
}, | ||
pets: ['cat', 'dog'] | ||
}, | ||
@@ -475,3 +520,4 @@ { | ||
city: 'New Boston' | ||
} | ||
}, | ||
pets: ['dog'] | ||
}, | ||
@@ -487,3 +533,4 @@ { | ||
city: 'New York' | ||
} | ||
}, | ||
pets: ['dog', 'mouse', 'parrot'] | ||
}, | ||
@@ -499,3 +546,4 @@ { | ||
city: 'New York' | ||
} | ||
}, | ||
pets: ['cat', 'parrot'] | ||
}, | ||
@@ -511,3 +559,5 @@ { | ||
city: 'New Boston' | ||
} | ||
}, | ||
pets: [] | ||
}, | ||
@@ -523,3 +573,4 @@ { | ||
city: 'New Boston' | ||
} | ||
}, | ||
pets: ['dog', 'parrot'] | ||
} | ||
@@ -635,5 +686,9 @@ ]; | ||
it('should fetch objects using compound index (KeyRange.only)', function(done){ | ||
it('should fetch objects using compound index (KeyRange.only)', function (done) { | ||
store.query(function(data){ | ||
if (excludeIE) { | ||
return done(new Error('Test skipped.')); | ||
} | ||
store.query(function (data) { | ||
expect(data.length).to.equal(1); | ||
@@ -650,2 +705,20 @@ done(); | ||
it('should fetch objects using multiEntry index (KeyRange.only)', function (done) { | ||
if (excludeIE) { | ||
return done(new Error('Test skipped.')); | ||
} | ||
store.query(function (data) { | ||
expect(data.length).to.equal(4); | ||
done(); | ||
}, { | ||
index: 'multi', | ||
keyRange: store.makeKeyRange({ | ||
only: 'dog' | ||
}) | ||
}); | ||
}); | ||
it('should limit resultset, no index', function(done){ | ||
@@ -652,0 +725,0 @@ |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
0
4636
202637
30
107