(function(global) { var FILE_SYSTEM_NAME = require('../constants.js').FILE_SYSTEM_NAME; var FILE_STORE_NAME = require('../constants.js').FILE_STORE_NAME; var IDB_RW = require('../constants.js').IDB_RW; var IDB_RO = require('../constants.js').IDB_RO; var Errors = require('../errors.js'); var indexedDB = global.indexedDB || global.mozIndexedDB || global.webkitIndexedDB || global.msIndexedDB; function IndexedDBContext(db, mode) { var transaction = db.transaction(FILE_STORE_NAME, mode); this.objectStore = transaction.objectStore(FILE_STORE_NAME); } IndexedDBContext.prototype.clear = function(callback) { try { var request = this.objectStore.clear(); request.onsuccess = function(event) { callback(); }; request.onerror = function(error) { callback(error); }; } catch(e) { callback(e); } }; IndexedDBContext.prototype.get = function(key, callback) { try { var request = this.objectStore.get(key); request.onsuccess = function onsuccess(event) { var result = event.target.result; callback(null, result); }; request.onerror = function onerror(error) { callback(error); }; } catch(e) { callback(e); } }; IndexedDBContext.prototype.put = function(key, value, callback) { try { var request = this.objectStore.put(value, key); request.onsuccess = function onsuccess(event) { var result = event.target.result; callback(null, result); }; request.onerror = function onerror(error) { callback(error); }; } catch(e) { callback(e); } }; IndexedDBContext.prototype.delete = function(key, callback) { try { var request = this.objectStore.delete(key); request.onsuccess = function onsuccess(event) { var result = event.target.result; callback(null, result); }; request.onerror = function(error) { callback(error); }; } catch(e) { callback(e); } }; function IndexedDB(name) { this.name = name || FILE_SYSTEM_NAME; this.db = null; } IndexedDB.isSupported = function() { return !!indexedDB; }; IndexedDB.prototype.open = function(callback) { var that = this; // Bail if we already have a db open if( that.db ) { callback(null, false); return; } // Keep track of whether we're accessing this db for the first time // and therefore needs to get formatted. var firstAccess = false; // NOTE: we're not using versioned databases. var openRequest = indexedDB.open(that.name); // If the db doesn't exist, we'll create it openRequest.onupgradeneeded = function onupgradeneeded(event) { var db = event.target.result; if(db.objectStoreNames.contains(FILE_STORE_NAME)) { db.deleteObjectStore(FILE_STORE_NAME); } db.createObjectStore(FILE_STORE_NAME); firstAccess = true; }; openRequest.onsuccess = function onsuccess(event) { that.db = event.target.result; callback(null, firstAccess); }; openRequest.onerror = function onerror(error) { callback(new Errors.EINVAL('IndexedDB cannot be accessed. If private browsing is enabled, disable it.')); }; }; IndexedDB.prototype.getReadOnlyContext = function() { // Due to timing issues in Chrome with readwrite vs. readonly indexeddb transactions // always use readwrite so we can make sure pending commits finish before callbacks. // See https://github.com/js-platform/filer/issues/128 return new IndexedDBContext(this.db, IDB_RW); }; IndexedDB.prototype.getReadWriteContext = function() { return new IndexedDBContext(this.db, IDB_RW); }; module.exports = IndexedDB; }(this));