HTML 5. Работа с Web SQL базой данных

http://openbit.co.uk/?p=135
  • Перевод
В HTML 5 есть много новых возможностей, которые позволяют web разработчикам создавать более мощные и насыщенные приложения. К этим возможностям относятся и новые способы хранения данных на клиенте, такие как web storage(поддерживается в IE8) и web SQL database.

При этом если web storage ориентирован на хранение пар ключ-значение, то в случае с web SQL database у нас есть полноценный sqlite(во всех текущих реализациях применяется именно этот движок баз данных, что является проблемой при стандартизации).

Далее я расскажу, как работать с web SQL database. При этом примеры естественно будут на JavaScript. Кроме того, стоит отметить, что с поддержкой браузерами всего этого хозяйства дела обстоят, не очень хорошо, но всё постепенно меняется к лучшему и, скажем, в Opera 10.50 поддержка будет, а браузерах на движке WebKit она уже есть. Более подробно про то, какой браузер, что поддерживает можно узнать, пройдя по ссылке.

Соединение с базой данных.


Подсоединиться к базе данных очень просто:

db = openDatabase("ToDo", "0.1", "A list of to do items.", 200000);

Данный код создаёт объект, представляющий БД, а если базы данных с таким именем не существует, то создаётся и она. При этом в аргументах указывается имя базы данных, версия, отображаемое имя и приблизительный размер. Кроме того важно отметить, что приблизительный размер не является ограничением. Реальный размер базы данных может изменяться.

Успешность подключения к БД можно оценить, проверив объект db на null:

if(!db){alert("Failed to connect to database.");}

Всегда предпринимайте данную проверку, даже если соединение с БД для данного пользователя уже производилось в прошлом, и было успешно. Могут измениться настройки безопасности, закончиться дисковое пространство (скажем, если пользователь использует смартфон) или фаза луны окажется неподходящей.

Выполнение запросов.


Для выполнения запросов к БД предварительно надо создать транзакцию, вызвав функцию database.transaction(). У неё один аргумент, а именно другая JavaScript функция, принимающая объект транзакции и предпринимающая запросы к базе данных.

Собственно сам SQL запрос можно выполнить, вызвав функцию executeSql объекта транзакции. Она принимает 4 аргумента:
  • строка SQL запроса
  • массив параметров запроса (параметры подставляются на место вопросительных знаков в SQL запросе)
  • функция, вызываемая при успешном выполнении запроса
  • функция, вызываемая в случае возникновения ошибки выполнения запроса
Пример работы функции executeSql ниже:

db.transaction(function(tx) {
tx.executeSql("SELECT COUNT(*) FROM ToDo", [], function(result){}, function(tx, error){});
});

Давайте теперь изменим код так, чтобы при невозможности выборки из таблицы «ToDo»(которой пока не существует), данная таблица создавалась.

db.transaction(function(tx) {
tx.executeSql("SELECT COUNT(*) FROM ToDo", [], function (result) { alert('dsfsdf') }, function (tx, error) {
tx.executeSql("CREATE TABLE ToDo (id REAL UNIQUE, label TEXT, timestamp REAL)", [], null, null);
})});

Вставка данных.


Давайте вставим новую строку в таблицу «ToDo». Для знакомых с синтаксисом SQL пример, приведённый ниже, покажется очень знакомым:

db.transaction(function(tx) {
tx.executeSql("INSERT INTO ToDo (label, timestamp) values(?, ?)", ["Купить iPad или HP Slate", new Date().getTime()], null, null);
});

Первый знак вопроса в SQL запросе заменяется на «Купить iPad или HP Slate», а второй на метку времени. В итоге выполнен будет примерно такой запрос:
INSERT INTO ToDo (label, timestamp) values ("Купить iPad или HP Slate", 1265925077487)

Работа с результатами запросов.


Результат выполнения запроса на выборку данных содержит набор строк, а каждая строка содержит значения столбцов таблицы для данной строки.

Вы можете получить доступ к какой-либо строке результата вызвав функцию result.rows.item(i), где i – индекс строки. Далее, для получения требуемого значения, нужно обратиться к конкретному столбцу по имени – result.rows.item(i)[ «label»].

Следующий пример выводит результат запроса к базе данных на страницу:

db.transaction(function(tx) {
tx.executeSql("SELECT * FROM ToDo", [], function(tx, result) {
for(var i = 0; i < result.rows.length; i++) {
document.write('<b>' + result.rows.item(i)['label'] + '</b><br />');
}}, null)});

Заключение.


Использование web SQL database предоставляет мощные возможности, но не стоит увлекаться. Если задачу можно решить с помощью web storage, лучше использовать его.

Вы можете найти дополнительную информацию по данной теме в соответствующем разделе сайта консорциуме w3c.
Также для web SQL database уже начали разрабатывать ORM библиотеки. Пример такой библиотеки тут.
Метки:
Поделиться публикацией
Комментарии 39
  • –11
    Не тестировали на скорость работы идентичных вариаций в случае выполнения на клиенте хтмл 5 и стандартным php скриптом?
    • +6
      Причем тут пхп? Или предлагаете сравнить sqlite на сервере с sqlite на клиенте?

      База на клиенте не заменит базу на сервере, у нее задачи другие. Например, позволить веб приложению функционировать в режиме оффлайн, или выступить в качестве кеша — хотя тут уже storage уместнее.

      Хотя возможны и другие варианты, например, роль основной базы в приложении Opera Unite…
      • +6
        точно, ступилс, что-то совершенно не о том подумал :)
    • –2
      Лично я в этом не вижу смысла. HTML все больше уходит от языка разметки, которым задумывался первоначально.
      • +6
        Ну вы же понимаете, что sqlite на клиенте — это никоим образом не HTML :)
        HTML был и остается тем же что и всегда — декларативным языком разметки. Просто для разработки красивых и динамичных веб приложений не хватает очень многого и со стороны HTML, и JS, и транспортных возможностей, и…
        Вот как-то так и получилось, что собрали всё это светлое будущее в одну кучу. И назвали HTML5
        • +3
          HTML тут по сути нипричем, это для толстых клиентов сделано, и я лично, разрабатывая в свое время очень большой проект, был бы доволен такой возможности как клиентские дб
          • +1
            Все разъяснившим что к чему, спасибо. Въехал.
            • +1
              Javascript (nodejs+v8) уходит на сервера, а ORM приходит к клиенту. Как тяжело ломать стереотипы.
            • 0
              Подскажите, кто из браузеров это поддерживает?
              • +1
                WebKit(Chrome, Safari включая iPhone) и Opera c версии 10.50
                • 0
                  А что там с ФФ?
                  • +1
                    В Firefox поддержка работы с произвольными SQLite базами давно уже есть.
                    https://addons.mozilla.org/en-US/firefox/addon/5817
                    • 0
                      Если не ошибаюсь, это имеено инструмент для работы, но не интерфейс.
                      В FF 3.6 реализовано DOM Storage — https://developer.mozilla.org/en/DOM/Storage
                  • 0
                    У Chrome трудности с поддержкой.
                • 0
                  Это же офигенная вещь выходит. Дополнительное хранилище на стороне клиента лишним не будет, давно лелеял свою параноидальную идею об использовании ассиметричного шифрования для аутентификации пользователя на Веб-проектах.
                  • 0
                    чем для этого куки не угодили?
                    • 0
                      А в том-то и соль, что использовать это шифрование каждый раз — слишком ресурсоемко и ненужно. Его планирую использовать иногда, в остальных случая использовать как раз временные cookie. Имелось ввиду что не ключ в них передавать, конечно же.
                      • 0
                        Не понял, что именно предполагается хранить в безе клиента?
                  • 0
                    а если я кэш постоянно очищаю? что тогда?
                    • +1
                      А думаете эта БД будет стираться при очистке кеша?
                      Если будет — чтож, придется перелогиниваться вручную =)

                      Все же отошли мы от темы топика, нот гуд.
                      • +1
                        Вообще хорошая вещь. Тоже выберу, как только HTML5 заработает на полную.
                        • +1
                          HTML5 достигнет статуса W3C recommendation в 2022 или позже, поэтому начинайте внедрение сейчас =)
                          • НЛО прилетело и опубликовало эту надпись здесь
                            • 0
                              а вот web sql не то что бы нас покинул, но вроде как засобирался.
                    • +1
                      Неплохая выйдет связь со сторонними приложениями на компе клиента, через БД.
                      • НЛО прилетело и опубликовало эту надпись здесь
                        • +1
                          работы уже ведутся, посмотрите проект ActiveJS — activejs.org/
                          • НЛО прилетело и опубликовало эту надпись здесь
                        • 0
                          Подмена знаков вопроса нативно — зачем? База локальная, что ломать тут?
                          • 0
                            Это в первую очередь механизм для переиспользования запросов (для ускорения их отработки при нескольких последовательных вызовах), во вторую — для передачи сложным структур данных (array/blob/clob, хотя не в курсе: есть ли такое в sqlite), а уж потом для верификации типов и противодействия sql-injection.
                            • 0
                              Видимо, чтобы не было подобного:

                              (обычный текст введен пользователем) — I'm looking at cruiser «Aurora»! That's great!

                              Какие кавычки в запросе не поставите — без экранирования не обойтись
                            • 0
                              Если интересно: БД на стороне клиента возможна также через использование Google gears (http://gears.google.com/)
                              • 0
                                Ура, новое не паханное поле для специалистов из области клиентской оптимизации.
                                • 0
                                  А как делать синхронные запросы, а то эта асинхронность башню рвет.
                                  openDatabaseSync() почему-то не работает.
                                  • 0
                                    Это не реализовано.
                                    • 0
                                      До сих пор? :)))
                                      • 0
                                        Пробовал — не работает в Хроме.
                                        • 0
                                          работает и еще как и в хроме и в андроиде
                                  • 0
                                    в статье кое-что упущено, при использовании метода openDatabase работает асинхронная версия API и сигнатура метода db.transaction включает в себя ещё два обработчика
                                    transaction(transaction, errorCallback, successCallback);

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.