Errors with IndexedDB versions and Dexie.js
Asked Answered
S

1

7

I´m starting with IndexedDB and to not reinvent the wheel I´m using Dexie.js https://github.com/dfahlander/Dexie.js

I created the database, I added data and now I´m creating a generic function that get a CSV and populate the database in anothers tables.

So, more or less my code is

// Creation and populate database and first table
var db = new Dexie("database");
db.version(1).stores({table1: '++id, name'});

db.table1.add({name: 'hello'});

Until here all is OK

Now, in success of ajax request

db.close();
db.version(2).stores({table2: '++id, name'});
db.open();

db.table2.add({name: 'hello'});

First time this code run everything is OK, but next time I get this error

VersionError The operation failed because the stored database is a 
higher version than the version requested.

If I delete database and run code again only first time works OK.

Any idea? I don´t like too much IndexedDB version way, it´s looks frustrating and I don't get lot of help in the Net Thanks.

Edit: I discover the ¿problem/bug/procedure?. If I don´t add nothing before any version modification I haven't this issue, but does somebody know if is this the normal procedure?

So.. if this is the procedure I can't add any table dinamycally with a generic method. First all declarations and then add values. Any possibility to add a table after add values?

Edit again... I just realized that I could create another database. I'll post results. But any information about this issue is welcome :)

Edit again... I created dinamycally another database and everybody is happy!!

Sueannsuede answered 17/8, 2016 at 15:31 Comment(0)
K
7

That is because the second time the code runs, your database is on version 2, but your main code still tries to open it at version 1.

If not knowing the current version installed, try opening dexie in dynamic mode. This is done by not specifying any version:

var db = new Dexie('database');
db.open().then(function (db) {
    console.log("Database is at version: " + db.verno);
    db.tables.forEach(function (table) {
        console.log("Found a table with name: " + table.name);
    }); 
});

And to dynamically add a new table:

function addTable (tableName, tableSchema) {
    var currentVersion = db.verno;
    db.close();
    var newSchema = {};
    newSchema[tableName] = tableSchema;

    // Now use statically opening to add table:
    var upgraderDB = new Dexie('database');
    upgraderDB.version(currentVersion + 1).stores(newSchema);
    return upgraderDB.open().then(function() {
        upgraderDB.close();
        return db.open(); // Open the dynamic Dexie again.
    });
}

The latter function returns a promise to wait until it's done before using the new table.

If your app resides in several browsers, the other windows will get their db connection closed as well so they can never trust the db instance to be open at any time. You might want to listen for db.on('versionchange') (https://github.com/dfahlander/Dexie.js/wiki/Dexie.on.versionchange) to override the default behavior for that:

db.on("versionchange", function() {
    db.close(); // Allow other page to upgrade schema.
    db.open() // Reopen the db again.
        .then(()=> {
           // New table can be accessed from now on.
        }).catch(err => {
           // Failed to open. Log or show!
        });
    return false; // Tell Dexie's default implementation not to run.
};
Kerek answered 18/8, 2016 at 10:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.