Загрузка файла JSON в IndexedDB

Сценарий с демонстрацией заполнения базы IDB из файла и доступа к содержимому.

База IndexedDB состоит из списка ключей-значений. Итак, идентификаторы, связанные с объектами, которые образуют полезное содержание: данные или сценарии...

На самом деле ключи могут быть частью содержащихся объектов, так бывает в нашем примере, когда ты хранишь объекты JavaScript, которые могут исходить из JSON-файлов, экспортированных из другой базы данных. Также можно хранить сценарии.

Пример файла данных:

{ "fruits": [
  {
	"name": "orange",	
	"color":"orange",
	"origin":"Asia",
	"content":"200"
  },
  {
	"name": "apple",  
	"color":"red, green, yellow",
	"origin":"Asia",
	"content":"1000"
  },
  {
	"name":"strawberry",   
	"color": "red",
	"origin": "France",
	"content":"50"
  },
  {
	"name":"blueberry",
	"color":"purple",
	"origin":"America",
	"content":"300"
  }
 ]
}

1) Загрузить файл JSON

async function loadJSON(fname) {
  var response = await fetch(fname)
  var str = await response.text()
  var data = JSON.parse(str)
  var idb = await importIDB("fruits", "fstore", data["fruits"])
  await displayIDB(idb, "fstore", "storage")
}

Файл JSON загружается в виде текста и преобразуется в объект с помощью JSON.parse ().

Функция объявляется асинхронной, чтобы можно было использовать await и, следовательно, ждать завершения загрузки, чтобы связать ее с отображением содержимого.

2) Перенести его содержимое в базу

function importIDB(dname, sname, arr) {
  return new Promise(function(resolve) {
    var r = window.indexedDB.open(dname)
    r.onupgradeneeded = function() {
      var idb = r.result
      var store = idb.createObjectStore(sname, {keyPath: "name"})
    }
    r.onsuccess = function() {
      var idb = r.result
        let tactn = idb.transaction(sname, "readwrite")
    	  var store = tactn.objectStore(sname)
        for(var obj of arr) {
          store.put(obj)
        }
        resolve(idb)
    }
    r.onerror = function (e) {
     alert("Enable to access IndexedDB, " + e.target.errorCode)
    }    
  })
}

Параметр importIDB содержит имя базы данных, имя таблицы (хранилища) и таблицу со списком объектов, которые будут помещены в таблицу.

База открыта открытым методом indexedDB. Таблица создается с использованием метода createObjectStore в функции, связанной с событием onupgradened.

Параметр keyPath: «name» используется для задания в качестве ключа поиска свойства «name», которое является частью каждого объекта, хранящегося в базе данных. Это равно столбцу первичного ключа в SQL.

При успешном создании базы запускается событие success и выполняется содержимое связанной функции. Затем открывается транзакция для доступа к таблице и хранения записей.

3) Показать содержимое базы

Следующая функция имеет только демонстрационную цель, чтобы убедиться, что заливка выполнена правильно. В приложении предполагается, что база содержит тысячи записей, поэтому ее содержимое не отображается в блоке.

Однако полезно посмотреть, как можно использовать курсор для просмотра содержимого базы, хочешь ли ты выполнить там поиск и, возможно, использовать запросы типа GraphQL.

function displayIDB(idb, sname, id) {
  let storage = document.getElementById(id)
  let tactn = idb.transaction(sname, "readonly")
  let osc = tactn.objectStore(sname).openCursor()
  osc.onsuccess = function(e) {
    let cursor = e.target.result
    if (cursor) {
      storage.innerHTML += "Name " + cursor.value["name"] + " : " + cursor.value["origin"] + " " + cursor.value["color"] + "<br>"
      cursor.continue()
    }
  } 
  tactn.oncomplete = function() {
    idb.close();
  }
}

Необходимо открыть транзакцию для доступа к таблице записей, а особенность indexedDB - использовать «курсор» для разбора содержимого.
Когда операция завершена, запускается событие oncelete complete и закрывается база (это вариант).

4) Доступ к записи

async function getIDB(dname, sname, key) {
  return new Promise(function(resolve) {
    var r = indexedDB.open(dname)
      r.onsuccess = function(e) {
        var idb = r.result
        let tactn = idb.transaction(sname, "readonly")
        let store = tactn.objectStore(sname)
        let data = store.get(key)
        data.onsuccess = function() {
          resolve(data.result)
        }
        tactn.oncomplete = function() {
          idb.close()
        }
     }
  })
}

База снова открывается, поскольку она была закрыта в предыдущей функции. Выполняется новая транзакция, и метод store.get () позволяет найти запись, ключ к которой дается.

Эта функция возвращает обещанное, чтобы можно было убедиться, что содержимое доступно перед просмотром. Это зависит от функции, включенной при нажатии кнопки, которая является следующей функцией в нашем демо:

async function search() {
  var key = document.getElementById("searchval").value
  var infos = await getIDB("fruits", "fstore", key)
  document.getElementById("storage").innerHTML = JSON.stringify(infos, null, ' ')
}

Альтернативой является использование обратного вызова .

Полный код доступен в архиве для скачивания.

Чтобы запустить демонстрацию, загрузите demoIDB.html в Firefox или другой браузер, который принимает загрузку файлов с локальной страницы .

Читайте также: