在现有的 objectStore 上创建索引
Create index on already existing objectStore
作为基本设置的示例,创建了一个索引。
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.createObjectStore('name', { keyPath: 'id' });
store.createIndex('by name', 'name', { unique: false });
};
问题:
是否可以在 future
versionupdate
上对相同的 objectStore
添加更多索引 create/append?
因为如果我尝试:
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.createObjectStore('name', { keyPath: 'id' });
store.createIndex('by newName', 'newName', { unique: false });
};
它抛出 current objectStore does already exist
的错误。如果我尝试使用事务创建商店引用:
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.transaction('name', 'readwrite').objectStore('name');
store.createIndex('by newName', 'newName', { unique: false });
};
它抛出 version change transaction is currently running
是的,这是可能的。一开始可能有点混乱。您希望通过在 onupgradeneeded 中为您创建的隐式事务来获取现有的对象存储。这是一个 versionchange 类型的事务,它基本上类似于 readwrite 事务,但特定于 onupgradeneeded 处理函数。
像这样:
var request = indexedDB.open(name, oldVersionPlusOne);
request.onupgradeneeded = myOnUpgradeNeeded;
function myOnUpgradeNeeded(event) {
// Get a reference to the request related to this event
// @type IDBOpenRequest (a specialized type of IDBRequest)
var request = event.target;
// Get a reference to the IDBDatabase object for this request
// @type IDBDatabase
var db = request.result;
// Get a reference to the implicit transaction for this request
// @type IDBTransaction
var txn = request.transaction;
// Now, get a reference to the existing object store
// @type IDBObjectStore
var store = txn.objectStore('myStore');
// Now, optionally inspect index names, or create a new index
console.log('existing index names in store', store.indexNames);
// Add a new index to the existing object store
store.createIndex(...);
}
您还需要注意增加版本以保证调用 onupgradeneeded 处理程序函数,并表示您的架构(基本上是表和索引的集合以及事物的属性)已在新版本。
您还需要重写该函数,以便您仅根据版本创建或进行更改。您可以使用 event.oldVersion
或 db.objectStoreNames.contains
.
来帮助解决这个问题
像这样:
function myOnUpgradeNeeded(event) {
var is_new_db = isNaN(event.oldVersion) || event.oldVersion === 0;
if(is_new_db) {
var db = event.target.result;
var store = db.createObjectStore(...);
store.createIndex('my-initial-index');
// Now that you decided you want a second index, you also need
// to do this for brand new databases
store.createIndex('my-second-new-index');
}
// But if the database already exists, we are not creating things,
// instead we are modifying the existing things to get into the
// new state of things we want
var is_old_db_not_yet_current_version = !isNaN(event.oldVersion) && event.oldVersion < 2;
if(is_old_db_not_yet_current_version) {
var txn = event.target.transaction;
var store = txn.objectStore('store');
store.createIndex('my-second-new-index');
}
}
请注意我使用 event.target.transaction
而不是 db.transaction(...)
。这些根本不是一回事。一个引用现有交易,一个创建新交易。
最后,此外,我的个人规则而不是正式的编码要求,您永远不应该在 onupgradeneeded 中使用 db.transaction()
。在进行升级时坚持修改架构,并在架构之外进行所有数据更改。
作为基本设置的示例,创建了一个索引。
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.createObjectStore('name', { keyPath: 'id' });
store.createIndex('by name', 'name', { unique: false });
};
问题:
是否可以在 future
versionupdate
上对相同的 objectStore
添加更多索引 create/append?
因为如果我尝试:
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.createObjectStore('name', { keyPath: 'id' });
store.createIndex('by newName', 'newName', { unique: false });
};
它抛出 current objectStore does already exist
的错误。如果我尝试使用事务创建商店引用:
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.transaction('name', 'readwrite').objectStore('name');
store.createIndex('by newName', 'newName', { unique: false });
};
它抛出 version change transaction is currently running
是的,这是可能的。一开始可能有点混乱。您希望通过在 onupgradeneeded 中为您创建的隐式事务来获取现有的对象存储。这是一个 versionchange 类型的事务,它基本上类似于 readwrite 事务,但特定于 onupgradeneeded 处理函数。
像这样:
var request = indexedDB.open(name, oldVersionPlusOne);
request.onupgradeneeded = myOnUpgradeNeeded;
function myOnUpgradeNeeded(event) {
// Get a reference to the request related to this event
// @type IDBOpenRequest (a specialized type of IDBRequest)
var request = event.target;
// Get a reference to the IDBDatabase object for this request
// @type IDBDatabase
var db = request.result;
// Get a reference to the implicit transaction for this request
// @type IDBTransaction
var txn = request.transaction;
// Now, get a reference to the existing object store
// @type IDBObjectStore
var store = txn.objectStore('myStore');
// Now, optionally inspect index names, or create a new index
console.log('existing index names in store', store.indexNames);
// Add a new index to the existing object store
store.createIndex(...);
}
您还需要注意增加版本以保证调用 onupgradeneeded 处理程序函数,并表示您的架构(基本上是表和索引的集合以及事物的属性)已在新版本。
您还需要重写该函数,以便您仅根据版本创建或进行更改。您可以使用 event.oldVersion
或 db.objectStoreNames.contains
.
像这样:
function myOnUpgradeNeeded(event) {
var is_new_db = isNaN(event.oldVersion) || event.oldVersion === 0;
if(is_new_db) {
var db = event.target.result;
var store = db.createObjectStore(...);
store.createIndex('my-initial-index');
// Now that you decided you want a second index, you also need
// to do this for brand new databases
store.createIndex('my-second-new-index');
}
// But if the database already exists, we are not creating things,
// instead we are modifying the existing things to get into the
// new state of things we want
var is_old_db_not_yet_current_version = !isNaN(event.oldVersion) && event.oldVersion < 2;
if(is_old_db_not_yet_current_version) {
var txn = event.target.transaction;
var store = txn.objectStore('store');
store.createIndex('my-second-new-index');
}
}
请注意我使用 event.target.transaction
而不是 db.transaction(...)
。这些根本不是一回事。一个引用现有交易,一个创建新交易。
最后,此外,我的个人规则而不是正式的编码要求,您永远不应该在 onupgradeneeded 中使用 db.transaction()
。在进行升级时坚持修改架构,并在架构之外进行所有数据更改。