Курсоры

Последнее обновление: 11.11.2023

Для получения объектов из хранилища базы данных также можно применять курсоры. В контексте базы данных курсор представляет механизм прохода по различным объектам в хранилище базы данных.

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

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850