michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: this.EXPORTED_SYMBOLS = ["AlarmDB"]; michael@0: michael@0: /* static functions */ michael@0: const DEBUG = false; michael@0: michael@0: function debug(aStr) { michael@0: if (DEBUG) michael@0: dump("AlarmDB: " + aStr + "\n"); michael@0: } michael@0: michael@0: const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; michael@0: michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/IndexedDBHelper.jsm"); michael@0: michael@0: const ALARMDB_NAME = "alarms"; michael@0: const ALARMDB_VERSION = 1; michael@0: const ALARMSTORE_NAME = "alarms"; michael@0: michael@0: this.AlarmDB = function AlarmDB() { michael@0: debug("AlarmDB()"); michael@0: } michael@0: michael@0: AlarmDB.prototype = { michael@0: __proto__: IndexedDBHelper.prototype, michael@0: michael@0: init: function init() { michael@0: debug("init()"); michael@0: michael@0: this.initDBHelper(ALARMDB_NAME, ALARMDB_VERSION, [ALARMSTORE_NAME]); michael@0: }, michael@0: michael@0: upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) { michael@0: debug("upgradeSchema()"); michael@0: michael@0: let objectStore = aDb.createObjectStore(ALARMSTORE_NAME, { keyPath: "id", autoIncrement: true }); michael@0: michael@0: objectStore.createIndex("date", "date", { unique: false }); michael@0: objectStore.createIndex("ignoreTimezone", "ignoreTimezone", { unique: false }); michael@0: objectStore.createIndex("timezoneOffset", "timezoneOffset", { unique: false }); michael@0: objectStore.createIndex("data", "data", { unique: false }); michael@0: objectStore.createIndex("pageURL", "pageURL", { unique: false }); michael@0: objectStore.createIndex("manifestURL", "manifestURL", { unique: false }); michael@0: michael@0: debug("Created object stores and indexes"); michael@0: }, michael@0: michael@0: /** michael@0: * @param aAlarm michael@0: * The record to be added. michael@0: * @param aSuccessCb michael@0: * Callback function to invoke with result ID. michael@0: * @param aErrorCb [optional] michael@0: * Callback function to invoke when there was an error. michael@0: */ michael@0: add: function add(aAlarm, aSuccessCb, aErrorCb) { michael@0: debug("add()"); michael@0: michael@0: this.newTxn( michael@0: "readwrite", michael@0: ALARMSTORE_NAME, michael@0: function txnCb(aTxn, aStore) { michael@0: debug("Going to add " + JSON.stringify(aAlarm)); michael@0: aStore.put(aAlarm).onsuccess = function setTxnResult(aEvent) { michael@0: aTxn.result = aEvent.target.result; michael@0: debug("Request successful. New record ID: " + aTxn.result); michael@0: }; michael@0: }, michael@0: aSuccessCb, michael@0: aErrorCb michael@0: ); michael@0: }, michael@0: michael@0: /** michael@0: * @param aId michael@0: * The ID of record to be removed. michael@0: * @param aManifestURL michael@0: * The manifest URL of the app that alarm belongs to. michael@0: * If null, directly remove the ID record; otherwise, michael@0: * need to check if the alarm belongs to this app. michael@0: * @param aSuccessCb michael@0: * Callback function to invoke with result. michael@0: * @param aErrorCb [optional] michael@0: * Callback function to invoke when there was an error. michael@0: */ michael@0: remove: function remove(aId, aManifestURL, aSuccessCb, aErrorCb) { michael@0: debug("remove()"); michael@0: michael@0: this.newTxn( michael@0: "readwrite", michael@0: ALARMSTORE_NAME, michael@0: function txnCb(aTxn, aStore) { michael@0: debug("Going to remove " + aId); michael@0: michael@0: // Look up the existing record and compare the manifestURL michael@0: // to see if the alarm to be removed belongs to this app. michael@0: aStore.get(aId).onsuccess = function doRemove(aEvent) { michael@0: let alarm = aEvent.target.result; michael@0: michael@0: if (!alarm) { michael@0: debug("Alarm doesn't exist. No need to remove it."); michael@0: return; michael@0: } michael@0: michael@0: if (aManifestURL && aManifestURL != alarm.manifestURL) { michael@0: debug("Cannot remove the alarm added by other apps."); michael@0: return; michael@0: } michael@0: michael@0: aStore.delete(aId); michael@0: }; michael@0: }, michael@0: aSuccessCb, michael@0: aErrorCb michael@0: ); michael@0: }, michael@0: michael@0: /** michael@0: * @param aManifestURL michael@0: * The manifest URL of the app that alarms belong to. michael@0: * If null, directly return all alarms; otherwise, michael@0: * only return the alarms that belong to this app. michael@0: * @param aSuccessCb michael@0: * Callback function to invoke with result array. michael@0: * @param aErrorCb [optional] michael@0: * Callback function to invoke when there was an error. michael@0: */ michael@0: getAll: function getAll(aManifestURL, aSuccessCb, aErrorCb) { michael@0: debug("getAll()"); michael@0: michael@0: this.newTxn( michael@0: "readonly", michael@0: ALARMSTORE_NAME, michael@0: function txnCb(aTxn, aStore) { michael@0: if (!aTxn.result) { michael@0: aTxn.result = []; michael@0: } michael@0: michael@0: let index = aStore.index("manifestURL"); michael@0: index.mozGetAll(aManifestURL).onsuccess = function setTxnResult(aEvent) { michael@0: aTxn.result = aEvent.target.result; michael@0: debug("Request successful. Record count: " + aTxn.result.length); michael@0: }; michael@0: }, michael@0: aSuccessCb, michael@0: aErrorCb michael@0: ); michael@0: } michael@0: };