Для получения объектов из хранилища базы данных также можно применять курсоры. В контексте базы данных курсор представляет механизм прохода по различным объектам в хранилище базы данных.
Для создания курсора у объекта IDBObjectStore
используется метод openCursor():
openCursor() openCursor(query) openCursor(query, direction)
В качестве необязательного параметра query
в метод передается ключ или объект IDBKeyRange, который задает диапазон
ключей. В этом случае курсор будет проходить только по объектам с этими ключами. Если данный параметр не указан, то курсор проходит по всем объектам.
Третий параметр - direction
задает направление курсора и может принимать следующие значения:
next: курсор начинает проход по объектам в начале хранилища в порядке возрастания ключей. Курсор возвращает все записи из хранилища, в том числе дубликаты. Это значение по умолчанию
nextunique: курсор начинает проход по объектам в начале хранилища в порядке возрастания ключей. Курсор возвращает все записи из хранилища, кроме дубликатов
prev: курсор начинает проход по объектам в начале хранилища в порядке убывания ключей. Курсор возвращает все записи из хранилища, в том числе дубликаты. Это значение по умолчанию
prevunique: курсор начинает проход по объектам в начале хранилища в порядке убывания ключей. Курсор возвращает все записи из хранилища, кроме дубликатов
Метод openCursor()
возвращает объект IDBRequest. При успешном получении курсора у IDBRequest срабатывает событие
success, а его свойство result
представляет либо значение IDBCursorWithValue
(если курсор нашел объекты в хранилище),
либо null
(если для курсора нет объектов). Если курсор не удалось получить, то генерируется событие error, а свойство error
объекта IDBRequest хранит информацию об ошибке.
Для обработки этих событий можно использовать соответственно свойства onsuccess и
onerror
При успешном открытии курсора и наличии в хранилище объектов для перебора свойство result
объекта IDBRequest хранит значение
IDBCursorWithValue - это и есть непосредственно сам курсор:
const request = indexedDB.open("test", 6); // подключаемся к бд test // при создании или изменении версии базы данных создаем в ней хранилище users request.onupgradeneeded = (event) => { const db = event.target.result; // получаем бд // пересоздаем хранилище users - сначала удаляем, если оно существует db.deleteObjectStore("users"); // ключом является свойство id, и оно автоматически инкрементируется const userStore = db.createObjectStore("users", { keyPath: "id", autoIncrement: true }); userStore.add({name: "Tom", age: 39}); userStore.add({name: "Bob", age: 43}); userStore.add({name: "Sam", age: 28}); }; // при открытии базы данных получаем курсор request.onsuccess = (event) => { const db = event.target.result; // получаем бд const transaction = db.transaction(["users"]); // создаем транзакцию const userStore = transaction.objectStore("users"); // получаем хранилище users const cursorRequest = userStore.openCursor(); // получаем запрос на открытие курсора // получаем курсор cursorRequest.onsuccess = () => { const cursor = cursorRequest.result; // также можно получить через event.target.result console.log(cursor); } cursorRequest.onerror = () => console.log(cursorRequest.error); };
При успешном получении курсора свойство key
объекта IDBCursorWithValue будет содержать ключ первого объекта из хранилища, а свойство value
содержит сам объект:
request.onsuccess = (event) => { const db = event.target.result; // получаем бд const transaction = db.transaction(["users"]); // создаем транзакцию const userStore = transaction.objectStore("users"); // получаем хранилище users const cursorRequest = userStore.openCursor(); // получаем запрос на открытие курсора // получаем курсор cursorRequest.onsuccess = () => { const cursor = cursorRequest.result; // также можно получить через event.target.result const user = cursor.value; // получаем значение, на которое указывает курсор console.log(user.id); // он же cursor.key console.log(user.name); console.log(user.age); } };
Метод continue() заставляет курсор перемещаться к следующей записи (если она есть), что, в свою очередь, приводит к
повторному выполнению обработчика onsuccess
и так далее. Например, получим все объекты из хранилища users:
const request = indexedDB.open("test", 6); // подключаемся к бд test // при создании или изменении версии базы данных создаем в ней хранилище users request.onupgradeneeded = (event) => { const db = event.target.result; // получаем бд // пересоздаем хранилище users - сначала удаляем, если оно существует db.deleteObjectStore("users"); // ключом является свойство id, и оно автоматически инкрементируется const userStore = db.createObjectStore("users", { keyPath: "id", autoIncrement: true }); userStore.add({name: "Tom", age: 39}); userStore.add({name: "Bob", age: 43}); userStore.add({name: "Sam", age: 28}); }; // при открытии базы данных request.onsuccess = (event) => { const db = event.target.result; // получаем бд const transaction = db.transaction(["users"]); // создаем транзакцию const userStore = transaction.objectStore("users"); // получаем хранилище users const cursorRequest = userStore.openCursor(); // получаем запрос на открытие курсора const users = []; // массив, в который считываем данные // получаем курсор cursorRequest.onsuccess = () => { const cursor = cursorRequest.result; // также можно получить через event.target.result if(cursor){ // если еще есть данные для чтения const user = cursor.value; users.push(user); // добавляем полученный объект в массив cursor.continue(); // перемещаем курсор к новой записи } else{ console.log(users); // если записей для чтения больше нет, выводит массив } } cursorRequest.onerror = () => console.log(cursorRequest.error); };
В данном случае, пока для считывания имеются данные, считываем их и добавляем в массив users. Когда все данные будут прочитаны выводим массив на консоль.