Dexie.js Autoincrement Primary Key - does it ever reset? How to reset it?

南楼画角 提交于 2019-12-11 10:07:04

问题


In Dexie.js you can create a store with an auto-incrementing key

    let db = new Dexie("nav_api");
    db.version(1).stores({
        jobs: '++id, json'
    });

So to test, I created 14 objects in the db via db.jobs.put({json: '[]'}), and all their keys came out as expected, started at 1 up to 14. Then deleted some of the later ones, db.jobs.where('id').above(6).delete(), and added another one to the db, and its index was 15.

Is there any way to reset the index to 0? I was using it for ordering, and I'm not sure what happens when the value gets incredibly large -- does it eventually wrap back around to 0?

On the other hand, it's also probably not something I need to worry about. Depending on how high the '++id' field can be, and I'm assuming it will be in the billions, it would be many many years (many lifetimes) before it was ever something to worry about. So maybe I should just ignore it.

[edit] I tried clearing the table, db.jobs.clear() and then putting a new row in the table, but again it used the next index after. I can't find a way to fully delete a table, however I can fully delete an entire database but I don't really want to do that.


回答1:


The IndexedDB spec has more info.

You probably won't hit the upper limit:

The current number is always a positive integer less than or equal to 253 (9007199254740992) + 1.

And there is no way to reset it, other than deleting the object store and recreating it:

The current number for a key generator never decreases, other than as a result of database operations being reverted. Deleting a record from an object store never affects the object store’s key generator. Even clearing all records from an object store, for example using the clear() method, does not affect the current number of the object store’s key generator.




回答2:


The accepted answer solves the question just partially and doesn't provides an actual solution to the problem in form of code. In my oppinion it isn't a good idea to count up the auto-incremented integers without need. For sure one would need huge sets of data, but high numbers could be irritating to users, especially if they ask themself where the previous id's are.

I mostly copied over this script from the Dexie-Developer dfahlander and altered it to achieve what was asked for. Beware that cloning a database forth and back could take a long time to run, depending on the size of your database. The bulkAdd isn't wrapped in a transaction, so on errors the script could break. That said I've to warn you to make a backup before you execute this function.

function refreshIndices(database){

  const databases = [database, database+'_temp'];
  // Loop 2 times - move database forth and back
  (function next(cnt, max){
    if(cnt++ >= max){ doSomething(); return;}
    // ! turns 1 into 0 and vice-versa / + turns boolean into integer
    var sdb = new Dexie(databases[cnt-1]),
        ddb = new Dexie(databases[+!(cnt-1)]);

    sdb.open().then(()=>{
        // Clone scheme
        const schema = sdb.tables.reduce((result,table)=>{
          result[table.name] = (
            [table.schema.primKey]
            .concat(table.schema.indexes)
            .map(indexSpec => indexSpec.src)
            ).toString();
          return result;
        }, {});
        ddb.version(sdb.verno).stores(schema);

        // Clone Data and delete source-database
        return sdb.tables.reduce(
          (result, table) => result
            .then(() => table.toArray())
            .then(rows => ddb.table(table.name).bulkAdd(rows) ),
          Promise.resolve()     
        ).then((x)=>{ sdb.delete(); ddb.close(); next(cnt,max); })
    })
  })(0, databases.length);
}

This function must be called with the database name as string, which you want to clone. (i.e. refreshIndices('dbname')) The database must exist. The function iterates 2 times. On first run, the source database gets cloned into a temporary database and then the source database gets deleted. When done the function runs again and clones the temporary database into the source database and then deletes the temporary database. No overhead will be left.

For debugging purposes I would alter

.then(rows => ddb.table(table.name).bulkAdd(rows) )

to

.then((rows) => { 
    console.log("Cloning "+table.name);
    ddb.table(table.name).bulkAdd(rows)
}) )

This function should work out of the Box with Dexie.js. Database creation can also be followed via Developer Tools (Chrome) => Application => IndexedDB => __dbnames => Refresh.



来源:https://stackoverflow.com/questions/49190878/dexie-js-autoincrement-primary-key-does-it-ever-reset-how-to-reset-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!