Jeremy Wall (zaphar) dcd08a2dd1 Add a Tagging module.
* It uses an indexedb datastore.
* Fix the api of the indexeddb wrapper now that I have some real world usage
  examples.
* Implemented API Calls:
   * UpdateTags
   * GetTags
* Exposed but unimplemented API Calls:
   * GetVersesForTag
   * Sync
* Add a tooltip that shows the tags for a reference to the reference link.
2013-04-19 20:13:05 -05:00

155 lines
7.0 KiB
JavaScript

// js/db implements a basic wrapper for IndexedDB databases.
// See http://www.w3.org/TR/IndexedDB/ for more details about the
// IDB* interfaces referenced below.
define(
'db', function() {
return {
version: 1,
dbName: "dynamic_bible_db",
stores: ['tags'],
debug: true,
// Internal method not for external use.
handleError: function(e) {
this.debug && console.log("Error: ", e);
},
// Internal method not for external use.
handleUpdate: function(e) {
var db = e.target.result;
e.target.transaction.onerror = this.handleError;
this.debug && console.log("Updating database", this.dbName);
for (i in this.stores) {
if (!db.objectStoreNames.contains(this.stores[i])) {
this.debug && console.log("Creating objectStore", this.stores[i]);
db.createObjectStore(this.stores[i], {keyPath: "key"});
}
}
},
// Turn on debug logging.
SetDebug: function() {
this.debug = self;
},
// Session does operations on an open database.
// ops is expected to be a function taking an IDBDatabase object
// as a parameter.
Session: function(ops) {
var self = this;
self.debug && console.log('Opening session for ', this.dbName, this.version);
var req = indexedDB.open(this.dbName, this.version);
// HandleUpgrades
req.onupgradeneeded = function(e) {
self.handleUpdate(e);
};
req.onsuccess = function(e) {
ops(e.target.result);
};
},
// Transaction does operations on an open transaction scoped to
// the list of stores.
// ops is expected to be a function taking an IDBTransation object
// as a parameter.
// type is an optional transaction type. values should be one of the
// following: readonly or readwrite
Transaction: function(stores, ops, type) {
var self = this;
var transType = type || "readonly";
self.debug && console.log(
"running", transType, "transaction on stores",
stores);
self.Session(
function(db) {
// Figure this api out.
var trans = db.transaction(stores, transType);
ops(trans);
});
},
// Get a key from the the object store.
// callbacks is a dict with two fields.
// callbacks.success is expected to be a function taking an
// IDBRequest object as a parameter.
// callbacks.error is optional and expected to be a function
// taking an IDBRequest object as a parameter.
// trans is optional and is expected to be a a function taking
// an IDBTransaction object. If none is provided
// one will be started for you.
Get: function(storeName, key, callbacks, trans) {
var self = this;
var op = function(trans) {
var store = trans.objectStore(storeName);
var req = store.get(key);
req.onsuccess = callbacks.success;
req.onerror = callbacks.error || self.handleError;
};
if (trans) {
ops(trans);
} else {
self.Transaction([storeName], op);
}
},
// Store or update a key with data in an object store.
// callbacks is a dict with up to two fields.
// success is expected to be a function taking an IDBRequest
// object as a parameter.
// error is also optional and expected to be a function taking an
// IDBRequest object as a parameter.
// The trans argument is optional and is expected to be a a
// function taking an IDBTransaction object. If none is provided
// one will be started for you.
Update: function(storeName, key, data, callbacks, trans) {
var self = this;
var op = function(trans) {
var store = trans.objectStore(storeName);
var req = store.put(
{"key": key, "data": data, ts: new Date().getTime()});
req.onsuccess = callbacks.success;
req.onerror = callbacks.error || self.handleError;
};
if (trans) {
op(trans);
} else {
self.Transaction(
[storeName], op, "readwrite");
}
},
// Delete a key from an object store.
// callbacks is a dict with up to two fields.
// callbacks.success is expected to be a function taking an
// IDBRequest object as a parameter.
// callbacks.error is optional and expected to be a function
// taking an IDBRequest object as a parameter.
Delete: function(storeName, key, callbacks) {
var self = this;
self.Transaction(
[storeName], function(trans) {
var store = trans.objectStore(storeName);
var req = store.delete(key);
req.onsuccess = callbacks.success;
req.onerror = callbacks.error || self.handleError;
}, "readwrite");
},
// Query a range of values from an object store.
// range is expected to be an IDBKeyRange.
// callbacks is a dict with up to two fields.
// callbacks.success is expected to be a function taking an
// IDBRequest object as a parameter.
// callbacks.error is optional and expected to be a function
// taking an IDBRequest object as a parameter.
// The trans argument is optional and is expected to be a a
// function taking an IDBTransaction object. If none is provided
// one will be started for you.
Query: function(storeName, range, callbacks, trans) {
var self = this;
var op = function(trans) {
var store = trans.objectStore(storeName);
var req = store.openCursor(range);
req.onsuccess = callbacks.success;
req.onerror = callbacks.error || self.handleError;
};
if (trans) {
op(trans);
} else {
self.Transaction([storeName], op);
}
}
};
});