Для получения объектов из хранилища базы данных также можно применять курсоры. В контексте базы данных курсор представляет механизм прохода по различным объектам в хранилище базы данных.
Для создания курсора у объекта 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. Когда все данные будут прочитаны выводим массив на консоль.