IndexedDB处理升级时需要的数据迁移

IndexedDB handle data migration onupgradeneeded

本文关键字:数据 迁移 处理 IndexedDB      更新时间:2023-09-26

我正在开发一个离线的web应用程序IndexedDB。所以我想了很多关于版本变更情况下数据迁移的问题。

例如,我在DB版本3中有3个objectstore。现在我注意到,我应该在所有3个ObjectStores中有一个特定的索引。但是不可能在不丢失数据的情况下向现有的ObjectStore添加索引。

在"onupgradenneeded"事件中处理数据迁移的解决方案是什么?

不需要终止StoreObject,只需像这样更新它:

request.onupgradeneeded = function(evt) {
        var dataBase = evt.target.result;
        var txn = evt.target.transaction;
        //////////
        var storeCreateIndex = function (objectStore, name, options) {
            if (!objectStore.indexNames.contains(name)) {
                objectStore.createIndex(name, name, options);
            }
        }
        //////////
        var catalogItem, mangaItem, chapterItem, artworkItem;
        if (evt.newVersion != evt.oldVersion) {
            // Get exiting objectStore
            catalogItem = txn.objectStore('CatalogItem');
            mangaItem = txn.objectStore('MangaItem');
            chapterItem = txn.objectStore('ChapterItem');
            artworkItem = txn.objectStore('ArtworkList');
        } else {
            // Fist creation of database objectStore
            catalogItem = dataBase.db.createObjectStore("CatalogItem", { keyPath: "key" });
            mangaItem = dataBase.db.createObjectStore("MangaItem", { keyPath: "key" });
            chapterItem = dataBase.db.createObjectStore("ChapterItem", { keyPath: "key" });
            artworkItem = dataBase.db.createObjectStore("ArtworkList", { keyPath: "key" });
        }
        //////////
        storeCreateIndex(catalogItem, "popularity", { unique: false });
        storeCreateIndex(catalogItem, "author", { unique: false });
        storeCreateIndex(catalogItem, "status", { unique: false });
        storeCreateIndex(catalogItem, "isFavorite", { unique: false });
        storeCreateIndex(chapterItem, "isBookmarked", { unique: false });
        storeCreateIndex(chapterItem, "isDownloaded", { unique: false });
}

如上所述:

尝试从" onupgradenneeded "启动一个新事务将导致错误:

InvalidStateError: DOM IDBDatabase Exception 11

使用请求对象引用的事务。例子:

function opendb(oncomplete){
  var version = 1;
  var migrateobjects = [];
  var request = indexedDB.open('mydb', version);
  request.onupgradeneeded = function(e) {
    db = e.target.result;
    transaction = e.target.transaction;
    if(db.objectStoreNames.contains('myobjects')){ 
      migraterequest = transaction.objectStore('myobjects').openCursor();
      migraterequest.onsuccess = function(e){ 
        var cursor = e.target.result;
        if (cursor){
          migrateobjects.push(cursor.value);
          cursor.continue();
        }
      };
      db.deleteObjectStore('myobjects');
    }
    var store = db.createObjectStore('myobjects', {keyPath: 'id'});
  };
  request.onsuccess = function(e) {
    db = e.target.result;
    transaction = db.transaction('myobjects', 'readwrite')
    store = transaction.objectStore('myobjects');
    for(var i=0; i < migrateobjects.length; ++i)
      store.put(migrateobjects[i]);
    transaction.oncomplete = oncomplete;
  };
};

更改索引不应清除现有记录,除非新索引违反了现有记录的数据库约束。但我确实观察到对象存储在Chrome中消失了,而在Firefox中却没有。