VanDalkvist
10/5/2015 - 3:13 PM

IndexedDB preparing in Web Worker (with Q promises)

IndexedDB preparing in Web Worker (with Q promises)

"use strict";

// SharedWorkerGlobalScope instance
var sharedSpace = self;

(function (module, Q) {

    if (!!module.DatabaseManager) return;

    var storages = [{name: 'reports'}];

    function DatabaseManager(name) {
        var db = this;

        db.name = name;

        db.storages = storages || [];
    }

    DatabaseManager.prototype.open = _open;
    DatabaseManager.prototype.close = _close;

    module.DatabaseManager = DatabaseManager;

    function _open(options) {
        var db = this;

        options = options || {clear: false};

        var initPromise = options.clear ? _removeDatabase(db.name) : Q.when();

        var dbRequest;

        var deferred = Q.defer();

        return initPromise.then(function () {
            dbRequest = sharedSpace.indexedDB.open(db.name, 1);

            dbRequest.onupgradeneeded = _onUpgradeNeeded;
            dbRequest.onsuccess = _onSuccessfullyOpened;
            dbRequest.onerror = _onError;

            return deferred.promise;
        });

        function _onUpgradeNeeded(event) {
            var openedDB = event.currentTarget.result;

            db.storages.forEach(function _createObjectStore(storage) {
                var objectStoreOptions = {autoIncrement: false};
                openedDB.createObjectStore(storage.name, objectStoreOptions);
            });

            console.log('Worker: Database was successfully upgraded.');
        }

        function _onSuccessfullyOpened(event) {
            var openedDB = dbRequest.result;

            openedDB.onversionchange = _onVersionChange.bind(db);

            db.instance = openedDB;

            console.log('Worker: Database connection was successfully established.');

            deferred.resolve(openedDB);
        }

        function _onError(event) {
            console.log('Worker: Error was occurred during opening db.');

            deferred.reject(event.message);
        }
    }

    function _onVersionChange(event) {
        var db = this;

        console.log('Worker: DB version was changed. Restarting...');
        db.close();
        db.open();
    }

    function _close(options) {
        var db = this;

        console.log('Worker: Stopping database connection...');
        db.instance.onversionchange = null;
        db.instance.close();
        db.instance = null;

        if (options.clear) _removeDatabase(db.name);
    }

    function _removeDatabase(dbName) {
        console.debug("Worker: Removing database...");
        var removeRequest = sharedSpace.indexedDB.deleteDatabase(dbName);
        var deferred = Q.defer();
        removeRequest.onsuccess = function () {
            deferred.resolve();
            console.debug("Worker: Database was deleted successfully.");
        };
        removeRequest.onerror = function () {
            var message = "Worker: Couldn't delete database.";
            deferred.reject(message);
            console.debug(message);
        };
        removeRequest.onblocked = function () {
            var message = "Worker: Couldn't delete database due to the operation being blocked.";
            deferred.reject(message);
            console.debug(message);
        };
        return deferred.promise;
    }

})(sharedSpace.ms, Q);