// 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: false, // 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"}); } } }, Capable: function() { return typeof indexedDB != "undefined"; }, // Turn on/off debug logging. ToggleDebug: function() { this.debug = !this.debug; }, // 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); } } }; });