Создать индекс на уже существующем объекте Store - PullRequest
0 голосов
/ 05 мая 2018

В качестве примера при базовой настройке создается один индекс.

db.onupgradeneeded = function(event) {
   var db = event.target.result;
   var store = db.createObjectStore('name', { keyPath: 'id' });
   store.createIndex('by name', 'name', { unique: false });
};

Вопрос : Можно ли создать / добавить больше индексов к тому же objectStore на future versionupdate?

Так как, если я попытаюсь:

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

1 Ответ

0 голосов
/ 06 мая 2018

Да, это возможно. Сначала это может быть немного запутанным. Вы хотите получить существующее хранилище объектов с помощью неявной транзакции, созданной для вас в 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(...). Это совсем не одно и то же. Одна ссылается на существующую транзакцию, а другая создает новую.

Наконец, и, кроме того, мое личное правило, а не формальное требование кодирования, вы никогда не должны использовать db.transaction() изнутри onupgradeneeded. При обновлении придерживайтесь изменения схемы и выполняйте все изменения данных вне ее.

...