idb-wrapper
Advanced tools
Comparing version 1.4.1 to 1.5.0
@@ -5,4 +5,4 @@ { | ||
"main": "idbstore.js", | ||
"version": "1.4.1", | ||
"version": "1.5", | ||
"dependencies": {} | ||
} |
171
idbstore.js
@@ -5,3 +5,3 @@ /*global window:false, self:false, define:false, module:false */ | ||
* @license IDBWrapper - A cross-browser wrapper for IndexedDB | ||
* Copyright (c) 2011 - 2013 Jens Arps | ||
* Copyright (c) 2011 - 2015 Jens Arps | ||
* http://jensarps.de/ | ||
@@ -27,2 +27,3 @@ * | ||
}; | ||
var defaultSuccessHandler = function () {}; | ||
@@ -47,3 +48,3 @@ var defaults = { | ||
* @name IDBStore | ||
* @version 1.4.1 | ||
* @version 1.5 | ||
* | ||
@@ -120,3 +121,3 @@ * @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; | ||
this.idb = env.indexedDB || env.webkitIndexedDB || env.mozIndexedDB || env.shimIndexedDB; | ||
this.keyRange = env.IDBKeyRange || env.webkitIDBKeyRange || env.mozIDBKeyRange; | ||
@@ -155,3 +156,3 @@ | ||
*/ | ||
version: '1.4.1', | ||
version: '1.5', | ||
@@ -195,2 +196,9 @@ /** | ||
/** | ||
* The prefix to prepend to the store name | ||
* | ||
* @type String | ||
*/ | ||
storePrefix: null, | ||
/** | ||
* The key path | ||
@@ -401,6 +409,16 @@ * | ||
* provides that functionality. | ||
* | ||
* @param {Function} [onSuccess] A callback that is called if deletion | ||
* was successful. | ||
* @param {Function} [onError] A callback that is called if deletion | ||
* failed. | ||
*/ | ||
deleteDatabase: function () { | ||
deleteDatabase: function (onSuccess, onError) { | ||
if (this.idb.deleteDatabase) { | ||
this.idb.deleteDatabase(this.dbName); | ||
this.db.close(); | ||
var deleteRequest = this.idb.deleteDatabase(this.dbName); | ||
deleteRequest.onsuccess = onSuccess; | ||
deleteRequest.onerror = onError; | ||
} else { | ||
onError(new Error('Browser does not support IndexedDB deleteDatabase!')); | ||
} | ||
@@ -452,3 +470,3 @@ }, | ||
onError || (onError = defaultErrorHandler); | ||
onSuccess || (onSuccess = noop); | ||
onSuccess || (onSuccess = defaultSuccessHandler); | ||
@@ -495,3 +513,3 @@ var hasSuccess = false, | ||
onError || (onError = defaultErrorHandler); | ||
onSuccess || (onSuccess = noop); | ||
onSuccess || (onSuccess = defaultSuccessHandler); | ||
@@ -530,3 +548,3 @@ var hasSuccess = false, | ||
onError || (onError = defaultErrorHandler); | ||
onSuccess || (onSuccess = noop); | ||
onSuccess || (onSuccess = defaultSuccessHandler); | ||
@@ -567,3 +585,3 @@ var hasSuccess = false, | ||
onError || (onError = defaultErrorHandler); | ||
onSuccess || (onSuccess = noop); | ||
onSuccess || (onSuccess = defaultSuccessHandler); | ||
@@ -645,2 +663,89 @@ if(Object.prototype.toString.call(dataArray) != '[object Array]'){ | ||
/** | ||
* Like putBatch, takes an array of objects and stores them in a single | ||
* transaction, but allows processing of the result values. Returns the | ||
* processed records containing the key for newly created records to the | ||
* onSuccess calllback instead of only returning true or false for success. | ||
* In addition, added the option for the caller to specify a key field that | ||
* should be set to the newly created key. | ||
* | ||
* @param {Array} dataArray An array of objects to store | ||
* @param {Object} [options] An object containing optional options | ||
* @param {String} [options.keyField=this.keyPath] Specifies a field in the record to update | ||
* with the auto-incrementing key. Defaults to the store's keyPath. | ||
* @param {Function} [onSuccess] A callback that is called if all operations | ||
* were successful. | ||
* @param {Function} [onError] A callback that is called if an error | ||
* occurred during one of the operations. | ||
* @returns {IDBTransaction} The transaction used for this operation. | ||
* | ||
*/ | ||
upsertBatch: function (dataArray, options, onSuccess, onError) { | ||
// handle `dataArray, onSuccess, onError` signature | ||
if (typeof options == 'function') { | ||
onSuccess = options; | ||
onError = onSuccess; | ||
options = {}; | ||
} | ||
onError || (onError = defaultErrorHandler); | ||
onSuccess || (onSuccess = defaultSuccessHandler); | ||
options || (options = {}); | ||
if (Object.prototype.toString.call(dataArray) != '[object Array]') { | ||
onError(new Error('dataArray argument must be of type Array.')); | ||
} | ||
var batchTransaction = this.db.transaction([this.storeName], this.consts.READ_WRITE); | ||
batchTransaction.oncomplete = function () { | ||
if (hasSuccess) { | ||
onSuccess(dataArray); | ||
} else { | ||
onError(false); | ||
} | ||
}; | ||
batchTransaction.onabort = onError; | ||
batchTransaction.onerror = onError; | ||
var keyField = options.keyField || this.keyPath; | ||
var count = dataArray.length; | ||
var called = false; | ||
var hasSuccess = false; | ||
var index = 0; // assume success callbacks are executed in order | ||
var onItemSuccess = function (event) { | ||
var record = dataArray[index++]; | ||
record[keyField] = event.target.result; | ||
count--; | ||
if (count === 0 && !called) { | ||
called = true; | ||
hasSuccess = true; | ||
} | ||
}; | ||
dataArray.forEach(function (record) { | ||
var key = record.key; | ||
var onItemError = function (err) { | ||
batchTransaction.abort(); | ||
if (!called) { | ||
called = true; | ||
onError(err); | ||
} | ||
}; | ||
var putRequest; | ||
if (this.keyPath !== null) { // in-line keys | ||
this._addIdPropertyIfNeeded(record); | ||
putRequest = batchTransaction.objectStore(this.storeName).put(record); | ||
} else { // out-of-line keys | ||
putRequest = batchTransaction.objectStore(this.storeName).put(record, key); | ||
} | ||
putRequest.onsuccess = onItemSuccess; | ||
putRequest.onerror = onItemError; | ||
}, this); | ||
return batchTransaction; | ||
}, | ||
/** | ||
* Takes an array of keys and removes matching objects in a single | ||
@@ -723,3 +828,3 @@ * transaction. | ||
onError || (onError = defaultErrorHandler); | ||
onSuccess || (onSuccess = noop); | ||
onSuccess || (onSuccess = defaultSuccessHandler); | ||
arrayType || (arrayType = 'sparse'); | ||
@@ -787,3 +892,3 @@ | ||
onError || (onError = defaultErrorHandler); | ||
onSuccess || (onSuccess = noop); | ||
onSuccess || (onSuccess = defaultSuccessHandler); | ||
var getAllTransaction = this.db.transaction([this.storeName], this.consts.READ_ONLY); | ||
@@ -881,3 +986,3 @@ var store = getAllTransaction.objectStore(this.storeName); | ||
onError || (onError = defaultErrorHandler); | ||
onSuccess || (onSuccess = noop); | ||
onSuccess || (onSuccess = defaultSuccessHandler); | ||
@@ -1028,2 +1133,6 @@ var hasSuccess = false, | ||
* if an error occurred during the operation. | ||
* @param {Number} [options.limit=Infinity] Limit the number of returned | ||
* results to this number | ||
* @param {Number} [options.offset=0] Skip the provided number of results | ||
* in the resultset | ||
* @returns {IDBTransaction} The transaction used for this operation. | ||
@@ -1040,3 +1149,5 @@ */ | ||
onEnd: null, | ||
onError: defaultErrorHandler | ||
onError: defaultErrorHandler, | ||
limit: Infinity, | ||
offset: 0 | ||
}, options || {}); | ||
@@ -1055,2 +1166,3 @@ | ||
} | ||
var recordCount = 0; | ||
@@ -1076,5 +1188,15 @@ cursorTransaction.oncomplete = function () { | ||
if (cursor) { | ||
onItem(cursor.value, cursor, cursorTransaction); | ||
if (options.autoContinue) { | ||
cursor['continue'](); | ||
if (options.offset) { | ||
cursor.advance(options.offset); | ||
options.offset = 0; | ||
} else { | ||
onItem(cursor.value, cursor, cursorTransaction); | ||
recordCount++; | ||
if (options.autoContinue) { | ||
if (recordCount + options.offset < options.limit) { | ||
cursor['continue'](); | ||
} else { | ||
hasSuccess = true; | ||
} | ||
} | ||
} | ||
@@ -1095,3 +1217,3 @@ } else { | ||
* was successful. | ||
* @param {Object} [options] An object defining specific query options | ||
* @param {Object} [options] An object defining specific options | ||
* @param {Object} [options.index=null] An IDBIndex to operate on | ||
@@ -1103,4 +1225,8 @@ * @param {String} [options.order=ASC] The order in which to provide the | ||
* @param {Object} [options.keyRange=null] An IDBKeyRange to use | ||
* @param {Function} [options.onError=throw] A callback to be called if an error | ||
* occurred during the operation. | ||
* @param {Function} [options.onError=throw] A callback to be called | ||
* if an error occurred during the operation. | ||
* @param {Number} [options.limit=Infinity] Limit the number of returned | ||
* results to this number | ||
* @param {Number} [options.offset=0] Skip the provided number of results | ||
* in the resultset | ||
* @returns {IDBTransaction} The transaction used for this operation. | ||
@@ -1111,2 +1237,4 @@ */ | ||
options = options || {}; | ||
options.autoContinue = true; | ||
options.writeAccess = false; | ||
options.onEnd = function () { | ||
@@ -1222,4 +1350,3 @@ onSuccess(result); | ||
var noop = function () { | ||
}; | ||
// TODO: Check Object.create support to get rid of this | ||
var empty = {}; | ||
@@ -1226,0 +1353,0 @@ var mixin = function (target, source) { |
/* | ||
IDBWrapper - A cross-browser wrapper for IndexedDB | ||
Copyright (c) 2011 - 2013 Jens Arps | ||
Copyright (c) 2011 - 2015 Jens Arps | ||
http://jensarps.de/ | ||
@@ -5,0 +5,0 @@ |
{ | ||
"name": "idb-wrapper", | ||
"version": "1.4.1", | ||
"version": "1.5.0", | ||
"description": "A cross-browser wrapper for IndexedDB", | ||
@@ -19,3 +19,5 @@ "keywords": [ | ||
"Max Ogden <max+ogden@maxogden.com> (http://www.maxogden.com)", | ||
"Asa Ayers <asa.ayers@gmail.com>" | ||
"Asa Ayers <asa.ayers@gmail.com>", | ||
"bdPeter (https://github.com/pbenschop)", | ||
"James Kyburz (https://github.com/JamesKyburz)" | ||
], | ||
@@ -22,0 +24,0 @@ "bugs": { |
@@ -1,5 +0,4 @@ | ||
About | ||
===== | ||
IDBWrapper is a cross-browser wrapper for the HTML5 IndexedDB API. While this | ||
[![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) | ||
---- | ||
**IDBWrapper** is a cross-browser wrapper for the HTML5 IndexedDB API. While this | ||
API is the future of offline storage, it is not very intuitive to use. | ||
@@ -10,3 +9,3 @@ IDBWrapper is there to provide easy access to IndexedDB's features. | ||
IDBWrapper works on all browsers supperting the IndexedDB API, which are: | ||
IDBWrapper works on all browsers supporting the IndexedDB API, which are: | ||
@@ -26,2 +25,3 @@ **Desktop** | ||
* IE10 for WP8 | ||
* iOS 8+ | ||
@@ -38,2 +38,4 @@ **Worker** IDBWrapper runs inside of a worker on following browsers: | ||
If using in an older browser supporting WebSql along with [IndexedDBShim](https://github.com/axemclion/IndexedDBShim), IndexedDBShim needs to run first. | ||
##Tutorials | ||
@@ -73,7 +75,7 @@ | ||
IDBWrapper is also available on [cdnjs](http://cdnjs.com/), so you can directly point a script tag there, or require() | ||
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.cloudflare.com/ajax/libs/idbwrapper/1.4.0/idbstore.min.js | ||
//cdnjs.cloudflare.com/ajax/libs/idbwrapper/1.4.1/idbstore.min.js | ||
``` | ||
@@ -149,8 +151,6 @@ | ||
'indexes' contains objects defining indexes (see below for details on indexes). | ||
'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 indexes. See below for further info on indexes. | ||
'indexes' is an array of objects defining indexes (see below for details on indexes). | ||
@@ -274,3 +274,3 @@ 'onError' gets called if an error occurred while trying to open the store. It | ||
This method takes an array of keys and fetches matching objects. | ||
This method takes an array of keys and fetches matching objects. | ||
@@ -284,3 +284,3 @@ `keyArray` must be an array of keys identifying the objects to fetch. | ||
// values 1 and 2, and the call looks like this: | ||
myStore.getBatch([1, 5, 2], onError, function (data) { … }, arrayType); | ||
myStore.getBatch([1, 5, 2], function (data) { … }, onError, arrayType); | ||
@@ -324,3 +324,3 @@ // this is what the `data` array will be like: | ||
``` | ||
``` | ||
@@ -401,3 +401,3 @@ | ||
If you use out-of-line keys, you must also provide a key to put operations: | ||
If you use out-of-line keys, you must also provide a key to put operations: | ||
@@ -510,2 +510,6 @@ | ||
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. | ||
___ | ||
@@ -540,2 +544,6 @@ | ||
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. | ||
___ | ||
@@ -542,0 +550,0 @@ |
describe('IDBWrapper', function(){ | ||
describe('delete databases', function(){ | ||
var store; | ||
before(function(done){ | ||
store = new IDBStore({ | ||
storeName: 'spec-store-simple' | ||
}, done); | ||
}); | ||
it('should delete the newly created database', function(done){ | ||
store.deleteDatabase(function(result){ | ||
expect(result).to.be.ok; | ||
done(); | ||
}, done); | ||
}); | ||
}); | ||
describe('basic CRUD, in-line keys', function(){ | ||
var store; | ||
var store, lastInsertId; | ||
@@ -51,2 +69,3 @@ before(function(done){ | ||
expect(insertId).to.exist; | ||
lastInsertId = insertId; | ||
store.get(insertId, function(result){ | ||
@@ -59,5 +78,16 @@ expect(result.name).to.equal(data.name); | ||
it('should assign an id which is greater than the last assigned', function(done){ | ||
var data = { | ||
name: 'John' | ||
}; | ||
store.put(data, function(insertId){ | ||
expect(insertId).to.exist; | ||
expect(store.idb.cmp(insertId, lastInsertId)).to.equal(1); | ||
done(); | ||
}, done); | ||
}); | ||
it('should get all stored objects', function(done){ | ||
store.getAll(function(data){ | ||
expect(data.length).to.equal(2); | ||
expect(data.length).to.equal(3); | ||
done(); | ||
@@ -216,2 +246,56 @@ }, done); | ||
describe('batch ops - upsertBatch', function () { | ||
var store; | ||
var dataArray = [ | ||
{ | ||
name: 'John' | ||
}, | ||
{ | ||
name: 'Joe' | ||
}, | ||
{ | ||
name: 'James' | ||
} | ||
]; | ||
before(function (done) { | ||
store = new IDBStore({ | ||
storeName: 'spec-store-simple' | ||
}, done); | ||
}); | ||
it('should store multiple objects and add keys to these objects', function (done) { | ||
var options = {keyField: 'foo'}; | ||
store.upsertBatch(dataArray, options, function (data) { | ||
expect(data[0].name).to.equal('John'); | ||
expect(data[1].name).to.equal('Joe'); | ||
expect(data[2].name).to.equal('James'); | ||
expect(data[0].foo).to.exist; | ||
expect(data[1].foo).to.exist; | ||
expect(data[2].foo).to.exist; | ||
done(); | ||
}, done); | ||
}); | ||
it('should default to keyPath when assigning insertId', function (done) { | ||
store.upsertBatch(dataArray, function (data) { | ||
expect(data[0].name).to.equal('John'); | ||
expect(data[1].name).to.equal('Joe'); | ||
expect(data[2].name).to.equal('James'); | ||
expect(data[0].id).to.exist; | ||
expect(data[1].id).to.exist; | ||
expect(data[2].id).to.exist; | ||
done(); | ||
}, done); | ||
}); | ||
after(function (done) { | ||
store.clear(function () { | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('getBatch() dataArray return type', function(){ | ||
@@ -555,3 +639,56 @@ | ||
it('should limit resultset, no index', function(done){ | ||
store.query(function(data){ | ||
expect(data.length).to.equal(2); | ||
done(); | ||
}, { | ||
limit: 2 | ||
}); | ||
}); | ||
it('should limit resultset, using basic index', function(done){ | ||
store.query(function(data){ | ||
expect(data.length).to.equal(2); | ||
expect(data[0].id).to.equal(4); | ||
expect(data[1].id).to.equal(3); | ||
done(); | ||
}, { | ||
limit: 2, | ||
index: 'basic' | ||
}); | ||
}); | ||
it('should start with an offset, using basic index', function(done){ | ||
store.query(function(data){ | ||
expect(data.length).to.equal(4); | ||
expect(data[0].id).to.equal(5); | ||
expect(data[1].id).to.equal(2); | ||
done(); | ||
}, { | ||
offset: 2, | ||
index: 'basic' | ||
}); | ||
}); | ||
it('should start with an offset and limit resultset, using basic index', function(done){ | ||
store.query(function(data){ | ||
expect(data.length).to.equal(2); | ||
expect(data[0].id).to.equal(1); | ||
expect(data[1].id).to.equal(6); | ||
done(); | ||
}, { | ||
offset: 4, | ||
limit: 2, | ||
index: 'basic' | ||
}); | ||
}); | ||
after(function(done){ | ||
@@ -558,0 +695,0 @@ store.clear(function(){ |
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
5501390
4579
579