我正在使用IndexedDB开发离线Web应用程序。因此,在版本更改的情况下,我想了很多关于数据迁移的内容。
例如,我在数据库版本3中有3个ObjectStore。现在我注意到,我应该在所有3个ObjectStore上都有一个特定的索引。但是之后不可能将索引添加到现有的ObjectStore,而不会丢失数据。
在“onupgradeneeded”-event中处理数据迁移的解决方案是什么?
答案 0 :(得分:5)
无需杀死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 });
}
答案 1 :(得分:0)
如上述评论中所述:
尝试从“onupgradeneeded”启动新事务将导致错误:
InvalidStateError:DOM IDBDatabase异常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;
};
};
答案 2 :(得分:0)
除非新索引违反现有记录的数据库约束,否则更改索引不应清除现有记录。但我确实观察到对象存储在Chrome中被吹走了,但在Firefox中没有。