2013-05-15 76 views
0

我正在開發與IndexedDB脫機Web應用程序。所以我想了很多關於版本更改的數據遷移。IndexedDB處理數據遷移onupgradeneeded

例如,我在DB版本3中有3個ObjectStores。現在我注意到,我應該在所有3個ObjectStores中都有一個特定的索引。但是之後不可能將索引添加到現有的ObjectStore中,而不會丟失數據。

在「onupgradeneeded」事件中,處理數據遷移的解決方案是什麼?

+1

你可以在'onupgradeneeded'上做任何你想做的事情。創建/刪除對象存儲,添加/編輯/刪除數據,添加/刪除索引......所有這些都不會丟失數據。所以我不確定你在說什麼。 – dumbmatter

+2

如果將索引添加到現有的ObjectStore,則不會丟失任何數據。存儲在對象庫中的數據將被添加到新索引中。 – dgrogan

+0

Ahhh我忽略了請求對象中有一個事務屬性:D 我試圖在一個對象庫上啓動一個新的事務... Thx爲您的提示!我會看看它。 – Steffen

回答

4

沒有需要殺死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 }); 
} 
0

如上評論指出:

試圖從「onupgradeneeded」發起新的交易將導致該錯誤:

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; 
    }; 
}; 
+0

migraterequest.onsuccess處理程序可以(也可能)在db.deleteObjectStore('myobjects')調用之後被調用,因此您需要採取一些方法使存儲刪除(以及後續的createObjectStore)只發生遷移請求完成後。類似的限制適用於request.onsuccess處理程序代碼(這應該只在migrationrequest.onsuccess後執行,並且後續的delete/create object store命令已完成。 –

0

改變指數應不明確現有的記錄,除非新的索引違反現有記錄數據庫約束。但我確實觀察到Chrome中的對象存儲風扇而不是Firefox。