JavaScript. Подробное руководство, 6-е издание
Шрифт:
Прикладной интерфейс веб-хранилища, определяемый спецификацией «Web Storage» и описанный в разделе 20.1, можно расценивать как простейшую разновидность базы данных, хранящую пары ключ/значение. Но помимо него имеются еще два прикладных интерфейса доступа к клиентским базам данных, которые являются «настоящими» базами данных. Один из них известен как «Web SQL Database» - простая реляционная база данных, поддерживающая простейшие SQL-запросы. Этот прикладной интерфейс реализован в броузерах Chrome, Safari и Opera. Он не реализован в Firefox и IE и, скорее всего, никогда не будет реализован в них. Работа над официальной спецификацией этого прикладного интерфейса была остановлена, и поддержка полноценной базы данных SQL, вероятно, никогда не приобретет статус официального стандарта или неофициальной, но широко поддерживаемой особенности веб-платформы.
В настоящее время все усилия по стандартизации сконцентрированы на другом прикладном интерфейсе к базам данных, известном как IndexedDB. Пока слишком рано описывать детали этого прикладного интерфейса (его описание отсутствует в четвертой части книги), но Firefox 4 и Chrome 11
IndexedDB - это объектная, а не реляционная база данных, и она намного проще, чем базы данных, поддерживающие язык запросов SQL. Однако она гораздо мощнее, эффективнее и надежнее, чем веб-хранилище пар ключ/значение, доступное посредством прикладного интерфейса Web Storage. Как и в случае прикладных интерфейсов к веб-хранилищам и файловой системе, доступность базы данных IndexedDB определяется происхождением создавшего ее документа: две веб-страницы с общим происхождением могут обращаться к данным друг друга, но вебстраницы с разным происхождением - нет.
Для каждого происхождения может быть создано произвольное число баз данных IndexedDB. Каждая база данных имеет имя, которое должно быть уникальным для данного происхождения. С точки зрения прикладного интерфейса IndexedDB база данных является простой коллекцией именованных хранилищ объектов. Как следует из этого названия, хранилище объектов хранит объекты (или любые другие значения, которые можно копировать, - смотрите врезку «Структурированные копии» выше). Каждый объект должен иметь ключ, под которым он сохраняется и извлекается из хранилища. Ключи должны быть уникальными - два объекта в одном хранилище не могут иметь одинаковые ключи, - и они должны иметь естественный порядок следования, чтобы их можно было сортировать. Примерами допустимых ключей являются строки, числа и объекты
Помимо возможности извлекать объекты из хранилища по значению первичного ключа существует также возможность выполнить поиск по значениям других свойств объекта. Чтобы обеспечить эту возможность, в хранилище объектов можно определить любое количество индексов. (Способность индексировать объекты подчеркивается самим названием «IndexedDB».) Каждый индекс определяет вторичный ключ хранимых объектов. Эти индексы в целом могут быть неуникальными, и одному и тому же ключу может соответствовать множество объектов. Поэтому в операциях обращения к хранилищу объектов с использованием индекса обычно используется курсор, определяющий прикладной интерфейс для извлечения объектов из потока результатов по одному. Курсоры могут также использоваться для обращения к хранилищу объектов с использованием диапазона ключей (или индексов), и прикладной интерфейс IndexedDB включает объект, используемый для описания диапазонов (с верхней и/или с нижней границей, включающих или не включающих границы) ключей.
IndexedDB гарантирует атомарность операций: операции чтения и записи в базу данных объединяются в транзакции, благодаря чему либо они все будут успешно выполнены, либо ни одна из них не будет выполнена, и база данных никогда не останется в неопределенном, частично измененном состоянии. Транзакции в IndexedDB реализованы намного проще, чем во многих других прикладных интерфейсах к базам данных, и мы еще вернемся к ним ниже.
Концепция прикладного интерфейса IndexedDB чрезвычайно проста. Чтобы прочитать или изменить данные, сначала необходимо открыть требуемую базу данных (указав ее имя). Затем создать объект транзакции и с помощью этого объекта отыскать требуемое хранилище объектов в базе данных, также по имени. Наконец, отыскать объект вызовом метода
Однако эта концептуальная простота осложняется тем фактом, что прикладной интерфейс должен быть асинхронным, чтобы веб-приложения могли пользоваться им, не блокируя основной поток выполнения броузера, управляющий пользовательским интерфейсом. (Спецификация IndexedDB определяет синхронную версию прикладного интерфейса для использования в фоновых потоках выполнения, но на момент написания этих строк ни один броузер еще не реализовал эту версию, поэтому она не рассматривается здесь.) Создание транзакции, а также поиск хранилища объектов и индексов являются простыми синхронными операциями. Но открытие базы данных, обновление хранилища объектов с помощью метода
Одно из удобств этого асинхронного прикладного интерфейса заключается в простоте управления транзакциями. При типичном использовании прикладного интерфейса IndexedDB сначала открывается база данных. Это асинхронная операция, поэтому по ее выполнении вызывается обработчик
Наконец, существует один особый вид транзакций, обеспечивающий возможность работы очень важной части прикладного интерфейса IndexedDB. Создать новую базу данных с использованием интерфейса IndexedDB API очень просто: достаточно выбрать имя и запросить открытие этой базы данных. Но новая база данных создается абсолютно пустой, и она совершенно бесполезна, пока в нее не будет добавлено одно или более хранилищ объектов (и, возможно, нескольких индексов). Создавать хранилища объектов и индексы можно только внутри обработчика события
Теперь, получив представление о прикладном интерфейсе IndexedDB, вы сможете самостоятельно разобраться в примере 22.15. Этот пример использует IndexedDB для создания базы данных, отображающей почтовые индексы США в названия городов, и выполнения запросов к ней. Он демонстрирует многие, хотя и не все, основные особенности IndexedDB. На момент написания этих строк пример действовал в Firefox 4 и Chrome 11, но из-за того, что спецификация все еще продолжала меняться и реализации находились на предварительной стадии разработки, велика вероятность, что он не будет работать именно так, как описывается здесь, когда вы будете читать эти строки. Однако общая структура примера должна сохранить свою полезность для вас. Пример 22.15 получился достаточно длинным, но в нем имеется большое количество комментариев, которые облегчат его изучение.
Пример 22.15. База данных IndexedDB с почтовыми индексами США