Question

I'm experimenting with Linq2IndexedDB (v. 1.0.21) via unit tests (via Mocha), but I can't even make a simple insert work. What happens (when running under Google Chrome) is an internal exception is thrown on line 1535 of Linq2IndexedDB.js:

Uncaught TypeError: Cannot read property 'version' of undefined

My unit test code looks as follows; there's basically one test, "it can add objects":

"use strict";

define(["db", "linq2indexeddb", "chai", "underscore", "stacktrace"], function (db, linq2indexeddb, chai, _,
    printStacktrace) {
    var should = chai.should();

    describe("db", function () {
        var _db;

        function fail(done, reason, err) {
            if (typeof reason === "string") {
                reason = new Error(reason);
            }
            if (!reason) {
                console.log(typeof done, typeof reason);
                reason = new Error("There's been an error, but no reason was supplied!");
                var st = printStacktrace({e: reason});
                console.log(st);
            }
            if (typeof done !== "function") {
                throw new Error("Was not supplied a function for 'done'!");
            }
            done(reason);
        }

        // Bind done as the first argument to the fail function
        function bindFail(done, reason) {
            if (typeof done !== "function") {
                throw new Error("done must be a function");
            }
            return _.partial(fail, done, reason);
        }

        beforeEach(function (done) {
            _db = linq2indexeddb("test", null, true);
            _db.deleteDatabase()
            .done(function () {
                _db.initialize()
                .done(done)
                .fail(bindFail(done, "Initializing database failed"));
            })
            .fail(bindFail(done, "Deleting database failed"));
        });

        it("can add objects", function (done) {
            console.log("Starting test");
            var refObj = {"key": "value"};
            _db.linq.from("store").insert(refObj, "Key")
            .done(function () {
                console.log("Added object successfully");
                done();
            })
            .fail(bindFail(done, "Inserting object failed"));
        });
    });
});

Am I doing something wrong here, or is there a bug in Linq2IndexedDB (or both)?

I've put up a corresponding test project on Github, complete with a Karma configuration, so you can run the included tests easily. The Karma configuration assumes you have Chrome installed.

Was it helpful?

Solution

I found a couple of issues:

  1. I got the Linq2IndexedDB worker location wrong, it should be: '/base/lib/Linq2IndexedDB.js'
  2. Inserting with the object with an out-of-line key doesn't work.

I eventually got insertion working on IE 10 and Chrome, although I'm still struggling with PhantomJS. To get it working under Chrome, I had to specify my schema explicitly, I suspect this is due to a bug in Linq2IndexedDB. My working solution is as follows:

Test:

"use strict";

define(["db", "linq2indexeddb", "chai", "underscore", "stacktrace"], function (db, linq2indexeddb, chai, _,
    printStacktrace) {
    var should = chai.should();

    describe("db", function () {
        var _db;

        function fail(done, reason, err) {
            console.log("err:", err);
            if (typeof reason === "string") {
                reason = new Error(reason);
            }
            if (!reason) {
                console.log(typeof done, typeof reason);
                reason = new Error("There's been an error, but no reason was supplied!");
                var st = printStacktrace({e: reason});
                console.log(st);
            }
            if (typeof done !== "function") {
                throw new Error("Was not supplied a function for 'done'!");
            }
            done(reason);
        }

        // Bind done as the first argument to the fail function
        function bindFail(done, reason) {
            if (typeof done !== "function") {
                throw new Error("done must be a function");
            }
            return _.partial(fail, done, reason);
        }

        beforeEach(function (done) {
            // Linq2IndexedDB's web worker needs this URL
            linq2indexeddb.prototype.utilities.linq2indexedDBWorkerFileLocation = '/base/lib/Linq2IndexedDB.js'

            _db = new db.Database("test");

            console.log("Deleting database");
            _db.deleteDatabase()
            .done(function () {
                console.log("Initializing database");
                _db.initialize()
                .done(done)
                .fail(bindFail(done, "Initializing database failed"));
            })
            .fail(bindFail(done, "Deleting database failed"));
        });

        it("can add objects", function (done) {
            console.log("Starting test");
            var refObj = {"key": "value"};
            _db.insert(refObj)
            .done(function () {
                done();
            })
            .fail(bindFail(done, "Database insertion failed"));
        });
    });
});

Implementation:

define("db", ["linq2indexeddb"], function (linq2indexeddb) {
    function getDatabaseConfiguration() {
        var dbConfig = {
            version: 1
        };
        // NOTE: definition is an array of schemas, keyed by version;
        // this allows linq2indexedDb to do auto-schema-migrations, based upon the current dbConfig.version
        dbConfig.definition = [{
            version: 1,
            objectStores: [
            { name: "store", objectStoreOptions: { keyPath: 'key' } },
            ],
            defaultData: []
        },
        ];

        return dbConfig;
    }

    var module = {
        Database: function (name) {
            var self = this;

            self._db = linq2indexeddb(name, getDatabaseConfiguration());

            self.deleteDatabase = function () {
                return self._db.deleteDatabase();
            };

            self.initialize = function () {
                return self._db.initialize();
            };

            self.insert = function (data) {
                return self._db.linq.from("store").insert(data);
            };
        }
    };
    return module;
});

EDIT: The reason it wasn't working under PhantomJS was that I'd enabled debug logging in Linq2IndexedDB, for some reason this would seemingly clog up Karma's pipes at some point. After turning off debug logging, all configurations work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top