Search code examples
javascriptgoogle-chrome-extensionindexeddbdexie

Dumping indexedDB data


Working on a Chrome Extension, which needs to integrate with IndexedDB. Trying to figure out how to use Dexie.JS. Found a bunch of samples. Those don't look too complicated. There is one specific example particularly interesting for exploring IndexedDB with Dexie at https://github.com/dfahlander/Dexie.js/blob/master/samples/open-existing-db/dump-databases.html

However, when I run the one above - the "dump utility," it does not see IndexedDB databases, telling me: There are databases at the current origin.

From the developer tools Application tab, under Storage, I see my IndexedDB database.

Is this some sort of a permissions issue? Can any indexedDB database be accessed by any tab/user?

What should I be looking at?

Thank you


Solution

  • In chrome/opera, there is a non-standard API webkitGetDatabaseNames() that Dexie.js uses to retrieve the list of database names on current origin. For other browsers, Dexie emulates this API by keeping an up-to-date database of database-names for each origin, so:

    For chromium browsers, Dexie.getDatabaseNames() will list all databases at current origin, but for non-chromium browsers, only databases created with Dexie will be shown.

    If you need to dump the contents of each database, have a look at this issue, that basically gives:

    interface TableDump {
        table: string
        rows: any[]
    }
    
    function export(db: Dexie): TableDump[] {
        return db.transaction('r', db.tables, ()=>{
            return Promise.all(
                db.tables.map(table => table.toArray()
                    .then(rows => ({table: table.name, rows: rows})));
        });
    }
    
    function import(data: TableDump[], db: Dexie) {
        return db.transaction('rw', db.tables, () => {
            return Promise.all(data.map (t =>
                db.table(t.table).clear()
                  .then(()=>db.table(t.table).bulkAdd(t.rows)));
        });
    }
    

    Combine the functions with JSON.stringify() and JSON.parse() to fully serialize the data.

    const db = new Dexie('mydb');
    db.version(1).stores({friends: '++id,name,age'});
    
    (async ()=>{
        // Export
        const allData = await export (db);
        const serialized = JSON.stringify(allData);
    
        // Import
        const jsonToImport = '[{"table": "friends", "rows": [{id:1,name:"foo",age:33}]}]';
        const dataToImport = JSON.parse(jsonToImport);
        await import(dataToImport, db);
    })();