IndexedDB — NoSQL в вебе

IndexedDB представляет собой хранилище больших объемов структурированных данных на клиенте. Это хранилище объектов или, если хотите, объектная СУБД для веб. По сути, это те же таблицы, типы данных, транзакции, курсоры, но вместо языка запросов здесь применяются методы доступа. Разницу подходов хорошо иллюстрирует пример с сайта одного из разработчиков IndexedDB, Mozilla. org:

WebSQL:

Var kids = [

{ name: "Anna" },

{ name: "Betty" },

];

Var db = window. spenDatabase(”CandyDB”, ”1”,

"My candy store database”,

1024);

Db. transaction(function(tx) {

For (var index = 0; index < kids. length; index++) { var kid = kids[index];

Tx. executeSql(”INSERT INTO kids (name) VALUES (:name);”, [kid], function(tx, results) { document. get ElementById("display”).textContent =

"Saved record for ” + kid. name +

” with id ” + results. insertId;

});

}

}):

IndexedDB:

Var kids = [

{ name: ”Anna” },

{ name: ”Betty” },

{ name: ”Christine” }

];

Var request = window.1ndexedDB. open(”CandyDB”,

”My candy store database”); request. onsuccess = function(event) { var objectStore = event. result. objectStore(”kids”); for (var index = 0; index < kids. length; index++) { var kid = kids[index];

ObjectStore. add(kid).onsuccess = function(event) { document. getElementById(”display”).textContent =

”Saved record for ” + kid. name + ” with id ” + event. result;

};

}

}:

Для «шапочного» знакомства этого достаточно, но я советую пойти дальше и познакомиться с работой IndexedDB несколько более детально. Сейчас мы этим и займемся, причем на практике.

Начнем с создания объекта IndexedDB:

Var idb = window. tndexedDB || window. webkittndexedDB || window. moztndexedDB || window. msIndexedDB:

Увы, vendor prefix тут пока обязателен. Теперь необходимо создать объект типа IDBRequest, предоставляющий асинхронный доступ к объектам базы данных:

Var request = window. tndexedDB. open("MyDb");

После этого особо деликатные браузеры (например, Mozilla Firefox) попросят разрешения разместить на вашем компьютере локальное хранилище (рис. 74). После этого будет предоставлен доступ к локальной базе данных MyDb. Если такой еще нет, она будет создана. При использовании браузера Google Chrome мы можем видеть ее посредством Developer Tools Resourses IndexedDB (рис. 75).

Рис. 74. У нас вежливо спрашивают разрешения хранить данные

Теперь можно привязать к созданному объекту функции обратного вызова:

Var dbVersion; var db;

Request. onsuccess = function (e) { db=e. target. result; if (db. version===»){

DbVersion = db. setVersion(‘ 1. 0′);

}

Else{

DbVersion = db. version; alert(db. version);

}

};};

Тут мы работаем с понятием версии базы. Она, версия, в данном случае очень важна, так как добавлять и изменять объекты в хранилище мы можем только со сменой версии (если подумать, преимущества такого подхода очевидны).

Доступ к данным в IndexedDB осуществляется через механизм транзакций. Всего их предусмотрено три вида:

- READ_ONLY — блокирующая транзакция с доступом только на чтение;

- READ_WRITE — блокирующая транзакция для изменения данных, осуществляется при завершении всех конкурирующих транзакций над выбранным объектом;

- VERSION_CHANGE — транзакция, как следует из названия, изменяющая версию хранилища, осуществляется при завершении всех конкурирующих транзакций над выбранным объектом. Именно в этой транзакции можно создавать, удалять или изменять объекты данных.

Для создания объектов нам нужен последний тип, поэтому начнем:

Function create(){

SetVersion = db. setVersion(dbVersion+0.1); setVersion. onsuccess=function (e) { var dbt=e. target. transaction. db;

Var store = dbt. createObjectStore("users", "id", true );

};

Тут мы создали объект users, определили ему индекс id, по которому к нему будем обращаться. Последний параметр — это не что иное, как аналог автоинкремента. Все. Объект, аналогом которому в реляционной СУБД была бы таблица, создан.

Что делаем дальше? Логично сохранить с помощью этого объекта какие-нибудь данные. Для этого сначала нужно создать транзакцию:

Var writeTransaction = db. transaction( [ "users" ],

IDBT ransation. READ_WRITE

);

Мы создаем транзакцию типа READ_WRITE, указывая ресурс для блокирования — ранее созданный объект users. Теперь открываем хранилище:

Var store = writeTransaction. objectStore("users");

И записываем туда данные:

Var request = store. add({

"name":  "vasya",

"password": "12345"

});

Request. onerror = function (e) { writeT ransaction. abort():

};

Теперь чтение. Для этой операции мы создадим транзакцию на чтение и откроем курсор:

Var readTransaction = db. t ransaction(

[ "users" ],

IDBT ransation. READ_ONLY

);

Var store = readTransaction. objectStore("users");

Var readCursor = store. openCursor();

Теперь свяжем курсор с функций обратного вызова:

ReadCursor. onsuccess = function (e) { if (e. result) {

Console. log(e. result. value. name); Mkwst@google. com } else {

конец списка пользователей readT ransaction. abort():

}

}:

Вот так все, почти просто.

Разумеется, я тут порассказал самые основы работы с IndexedDB. Если вы посмотрите на спецификации этого веб-хранилища, можно найти немало интересного, но… но, к сожалению, реализация всех его заявленных возможностей в браузерах пока оставляет желать лучшего. Настолько, что я не могу гарантировать корректной работы приведенного здесь кода — все еще очень «сыро». Остается надеяться, что это положение будет в ближайшее время исправлено, — технология хранения данных выглядит очень многообещающе, особенно в свети современных NoSQL-тенденций.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *