Uso de Cursores com o IndexedDB em JavaScript
Os cursores são utilizados para iterar pelos registros armazenados um banco de dados IndexedDB.
Para criar um cursor, utilizamos o método openCursor() do objeto IDBObjectStore. Ele possui a seguinte assinatura:
openCursor();
openCursor(query);
openCursor(query, direction);Parâmetros do Método openCursor:
- query(opcional): Pode ser uma chave específica ou um objeto do tipo- IDBKeyRange, que define um intervalo de chaves. Com este parâmetro, o cursor iterará apenas pelos registros que correspondam ao critério especificado. Caso ele não seja fornecido, o cursor percorrerá todos os registros disponíveis no objeto de armazenamento.
- direction(opcional): Determina a direção de navegação do cursor. Os valores possíveis são:- next: Percorre os registros do início para o fim, em ordem crescente das chaves. Inclui duplicatas. Este é o valor padrão.
- nextunique: Semelhante ao- next, mas ignora registros com chaves duplicadas.
- prev: Percorre os registros do fim para o início, em ordem decrescente das chaves. Inclui duplicatas.
- prevunique: Semelhante ao- prev, mas ignora registros com chaves duplicadas.
 
O método openCursor() retorna um objeto IDBRequest. Quando o cursor é criado com sucesso, o evento success é disparado, e a propriedade result do IDBRequest conterá:
- Um objeto IDBCursorWithValue(se o cursor encontrar registros correspondentes).
- null(se não houver registros correspondentes).
Se ocorrer um erro ao tentar criar o cursor, o evento error será disparado, e a propriedade error do IDBRequest armazenará informações sobre o problema.
Você pode manipular esses eventos por meio das propriedades onsuccess e onerror.
A seguir, temos um exemplo de como criar um cursor para iterar pelos registros de um objeto de armazenamento chamado users:
const request = indexedDB.open("test", 6);
// Configurando o banco de dados
request.onupgradeneeded = (event) => {
  const db = event.target.result;
  if (db.objectStoreNames.contains("users")) {
    db.deleteObjectStore("users");
  }
  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 });
};
// Abrindo um cursor para iterar pelos registros
request.onsuccess = (event) => {
  const db = event.target.result;
  const transaction = db.transaction("users", "readonly");
  const userStore = transaction.objectStore("users");
  const cursorRequest = userStore.openCursor();
  cursorRequest.onsuccess = () => {
    const cursor = cursorRequest.result;
    if (cursor) {
      console.log("Key:", cursor.key, "Value:", cursor.value);
      cursor.continue(); // Avança para o próximo registro
    } else {
      console.log("Fim dos registros.");
    }
  };
  cursorRequest.onerror = () => console.error("Erro ao abrir cursor:", cursorRequest.error);
};Método continue
O método continue() permite que o cursor avance para o próximo registro disponível. Isso dispara novamente o evento onsuccess, possibilitando a navegação contínua por todos os registros do objeto de armazenamento. No exemplo a seguir, todos os registros são armazenados em um array:
const request = indexedDB.open("test", 6);
request.onupgradeneeded = (event) => {
  const db = event.target.result;
  if (db.objectStoreNames.contains("users")) {
    db.deleteObjectStore("users");
  }
  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", "readonly");
  const userStore = transaction.objectStore("users");
  const cursorRequest = userStore.openCursor();
  const users = []; // Array para armazenar os registros
  cursorRequest.onsuccess = () => {
    const cursor = cursorRequest.result;
    if (cursor) {
      users.push(cursor.value); // Armazena o registro no array
      cursor.continue(); // Move para o próximo registro
    } else {
      console.log("Registros lidos:", users);
    }
  };
  cursorRequest.onerror = () => console.error("Erro ao ler registros:", cursorRequest.error);
};Neste exemplo, o array users armazenará todos os registros do objeto de armazenamento users, que serão exibidos no console após a leitura de todos os registros.
Documentação oficial: