Last active
December 25, 2015 03:39
-
-
Save odoe/6911676 to your computer and use it in GitHub Desktop.
IndexedDBStore and PouchDBStorefor holding ArcGIS Features.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*global define */ | |
/*jshint browser:true, laxcomma:true, newcap:false*/ | |
/** Heavily influenced by https://github.com/pjekel/indexedDB **/ | |
define([ | |
'dojo/Deferred', | |
'dojo/_base/declare', | |
'dojo/_base/array', | |
'dojo/store/util/QueryResults', | |
'dojo/store/util/SimpleQueryEngine' | |
], function (Deferred, declare, array, QueryResults, SimpleQueryEngine) { | |
'use strict'; | |
/** Remove null/undefined values from an array. */ | |
function cleanArgs(args) { | |
return array.filter(args, function(arg) { | |
return !!arg; | |
}); | |
} | |
/** Return transaction mode based on method. */ | |
function transactionType(method) { | |
if ('add,put,delete'.indexOf(method) > -1) { | |
return 'readwrite'; | |
} else { | |
return 'readonly'; | |
} | |
} | |
/** Convert arguments to array. */ | |
function toArray(args) { | |
return Array.prototype.slice.call(args, 1); | |
} | |
return declare(null, { | |
database: null, | |
name: null, | |
idbSupported: false, | |
keyPath: 'id', | |
indexes: null, | |
queryEngine: SimpleQueryEngine, | |
_db: null, | |
/** | |
* @example | |
* var indexedDBStore = new IndexedDBStore('csd', 'test', { | |
* version: 3, | |
* keyPath: 'attributes.AIN', | |
* indexes: ['attributes.AIN'], | |
* indexnames: ['ain'], | |
* indexOptions: { unique: true } | |
* }); | |
* | |
* @constructor | |
* @param {string} database - database name. | |
* @param {string} name - objectstore name. | |
* @param {object} options - IndexedDB parameters. | |
*/ | |
constructor: function (database, name, options) { | |
this.options = this.options || {}; | |
this.database = database; | |
this.name = name; | |
this._init(); | |
}, | |
// public methods | |
/** | |
* @example | |
* indexedDBStore.add(feature).then(function(result) { | |
* logger.debug('added my feature to indexedDB', result); | |
* }); | |
* | |
* @param {object} object- Item to add to database. | |
* @param {object} options - key or id to use in add function. | |
*/ | |
add: function (object, options) { | |
var key = options ? options.key || options.id : null; | |
return this._exec('add', object, key); | |
}, | |
/** | |
* @example: | |
* indexedDBStore.get('3142007045').then(function(result) { | |
* logger.debug('did i find it in indexedDB', result); | |
* }); | |
* | |
* @param {object} options - key or id to use in add function. | |
*/ | |
get: function (key) { | |
return this._exec('get', key); | |
}, | |
/** | |
* @example: | |
* indexedDBStore.query(function(o) { | |
* return o.attributes.TRA === '7080'; | |
* }).then(function(results) { | |
* logger.debug('indexeddb query results: ', results); | |
* }); | |
* | |
* @param {Function} qry - Query function to filter results. | |
* @param {object} options - options for query. | |
*/ | |
query: function (qry, options) { | |
var deferred = new Deferred() | |
, self = this | |
, results = [] | |
, trans = this._db.transaction([this.name], 'readonly') | |
, store = trans.objectStore(this.name) | |
, cursor = store.openCursor(); | |
cursor.onsuccess = function (e) { | |
var res = e.target.result; | |
if (res) { | |
results.push(res.value); | |
res.continue(); | |
} | |
}; | |
cursor.onerror = function (e) { | |
deferred.reject(e); | |
}; | |
trans.oncomplete = function () { | |
deferred.resolve(self.queryEngine(qry, options)(results)); | |
}; | |
return QueryResults(deferred.promise); | |
}, | |
// private methods | |
// based on https://github.com/pjekel/indexedDB/blob/master/store/Store.js | |
_exec: function(method) { | |
var deferred = new Deferred() | |
, transMode = transactionType(method); | |
try { | |
var trans = this._db.transaction([this.name], transMode) | |
, store = trans.objectStore(this.name) | |
, _method = store[method] | |
, args = toArray(arguments) | |
, request = _method.apply(store, cleanArgs(args)); | |
request.onsuccess = function() { | |
deferred.resolve(this.result); | |
}; | |
request.onerror = function() { | |
deferred.reject(this.error); | |
}; | |
} catch(err) { | |
console.warn('transaction error:', err); | |
deferred.reject(err); | |
} | |
return deferred.promise; | |
}, | |
_init: function () { | |
var indexedDB = window.indexedDB || window.webkitIndexedDB || | |
window.mozIndexedDB; | |
this.idbSupported = !!indexedDB; | |
if (this.idbSupported) { | |
alert('IndexedDB Supported'); | |
if (this.database && this.name) { | |
// testing | |
//indexedDB.deleteDatabase(this.database); | |
var openRequest = indexedDB.open(this.database, this.version || 1) | |
, self = this; | |
openRequest.onupgradeneeded = function () { | |
var db = this.result | |
, store | |
, trans; | |
// testing | |
if (db.objectStoreNames.contains(self.name)) { | |
//db.deleteObjectStore(this.name); | |
} | |
if (!db.objectStoreNames.contains(self.name)) { | |
store = db.createObjectStore(self.name, { keyPath: self.keyPath }); | |
store.createIndex(self.indexnames.toString(), self.indexes, | |
self.indexOptions || {}); | |
} | |
trans = db.transaction(self.name); | |
if (!store) { | |
store = trans.objectStore(self.name); | |
} | |
self.indexes = store.indexNames; | |
self.keyPath = store.keyPath; | |
}; | |
openRequest.onsuccess = function () { | |
self._db = this.result; | |
}; | |
openRequest.onerror = function () { | |
console.warn(this.error); | |
}; | |
} else { | |
throw new Error('IndexedDBStore#constructor() requires database and store name parameters'); | |
} | |
} else { | |
// TODO - gracefully fall back to local storage | |
//throw new Error('IndexedDBStore#constructor() IndexedDB is not supported on your browser'); | |
alert('IndexedDB not supported'); | |
} | |
} | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*global define, alert */ | |
/*jshint browser:true, laxcomma:true, newcap:false*/ | |
define([ | |
'dojo/Deferred', | |
'dojo/_base/declare', | |
'dojo/_base/array', | |
'dojo/store/util/QueryResults' | |
], function ( | |
Deferred, | |
declare, arrayUtil, | |
QueryResults | |
) { | |
'use strict'; | |
return declare(null, { | |
database: null, | |
name: null, | |
_db: null, | |
/** | |
* @example | |
* var pouchDBStore = new PouchStore('dbname', 'test', { | |
* version: 3, | |
* keyPath: 'attributes.AIN', | |
* indexes: ['attributes.AIN'], | |
* indexnames: ['ain'], | |
* indexOptions: { unique: true } | |
* }); | |
* | |
* @constructor | |
* @param {string} database - database name. | |
* @param {string} name - objectstore name. | |
* @param {object} options - IndexedDB parameters. | |
*/ | |
constructor: function (database, name, options) { | |
this.options = options || {}; | |
this.database = database; | |
this.name = name; | |
this._init(); | |
}, | |
// public methods | |
/** | |
* @example | |
* pouchStore.add(feature).then(function(result) { | |
* logger.debug('added my feature to indexedDB', result); | |
* }); | |
* | |
* @param {object} object- Item to add to database. | |
*/ | |
add: function (object) { | |
var deferred = new Deferred(); | |
this._db.put({ | |
_id: new Date().toISOString(), | |
item: object | |
}, function (err, result) { | |
if (!err) { | |
//console.log('successfully add', result); | |
alert('Item saved locally'); | |
deferred.resolve(result); | |
} else { | |
//console.warn('error adding', err); | |
alert('Error saving item locally: ' + err.message); | |
deferred.reject(err); | |
} | |
}); | |
return deferred.promise; | |
}, | |
getAll: function () { | |
var deferred = new Deferred(); | |
this._db.allDocs({ include_docs: true }, function (err, response) { | |
if (!err) { | |
//console.warn('PouchStore#getAll - response: ', response); | |
alert('local data retrieved', response); | |
deferred.resolve(response.rows); | |
} else { | |
//console.warn('PouchStore#getAll - error: ', err); | |
alert('Error retrieving local data: ' + err.message); | |
deferred.reject(err); | |
} | |
}); | |
return QueryResults(deferred.promise); | |
}, | |
_init: function () { | |
this._db = new window.PouchDB(this.database); | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello Rene,
Can you provide a client application or sample code to use IndexedDBStore?
Regards,
Waseem