Gerenciando Objetos de Armazenamento com o IndexedDB em JavaScript
Introdução
O IndexedDB utiliza a interface IDBDatabase para estabelecer conexões, gerenciar armazenamentos (object stores) e executar consultas a dados. A interface IDBDatabase disponibiliza propriedades úteis para acessar informações do banco de dados:
name: retorna o nome do banco de dados conectado.version: retorna o número da versão do banco de dados. Ao criar um banco de dados, esse valor é inicialmente uma string vazia. A versão serve para controlar alterações na estrutura do banco.objectStoreNames: retorna uma lista dos nomes dos armazenamentos existentes no banco conectado, representada por um objeto do tipoDOMStringList.
A seguir, um exemplo de como obter essas informações:
const request = indexedDB.open("test"); // Conectando ao banco de dados "test"
// Evento acionado ao abrir o banco com sucesso
request.onsuccess = (event) => {
const database = event.target.result; // Acessa a conexão com o banco
console.log(database.name); // Nome do banco de dados: "test"
console.log(database.version); // Versão do banco de dados
console.log(database.objectStoreNames); // Lista de armazenamentos no banco
};Além de suas propriedades, a interface IDBDatabase oferece métodos importantes para o gerenciamento do banco de dados:
close(): encerra a conexão com o banco de dados.createObjectStore(): cria um armazenamento.deleteObjectStore(): remove um armazenamento.transaction(): retorna um objeto de transação (IDBTransaction), usado para acessar armazenamentos e realizar operações em dados.
É importante ressaltar que a criação de armazenamentos só é permitida durante a criação inicial do banco de dados ou quando sua versão é alterada. Da mesma forma, a exclusão de armazenamentos só pode ser realizada durante uma mudança de versão.
Criando Armazenamentos de Objetos
O método createObjectStore() é usado para criar armazenamentos:
createObjectStore(name);
createObjectStore(name, options);O primeiro argumento é o nome do armazenamento. Opcionalmente, um objeto de configuração pode ser passado como segundo argumento. Este objeto aceita as seguintes propriedades:
keyPath: define o nome do atributo que será usado como chave para cada objeto.autoIncrement: se definido comotrue, valores para as chaves serão gerados automaticamente. O valor padrão éfalse, o que significa que os valores das chaves devem ser fornecidos explicitamente.
A maneira como as chaves são gerenciadas depende da combinação de keyPath e autoIncrement. A tabela abaixo explica as possibilidades:
| keyPath | autoIncrement | Descrição |
|---|---|---|
| Não especificado | false | O armazenamento aceita valores de qualquer tipo, incluindo tipos primitivos (números e strings). No entanto, a chave precisa ser fornecida explicitamente ao adicionar objetos. |
| Especificado | false | O armazenamento aceita apenas objetos (não primitivos). Esses objetos precisam conter uma propriedade cujo nome corresponda ao valor de keyPath. |
| Não especificado | true | O armazenamento aceita valores de qualquer tipo. As chaves são geradas automaticamente, mas podem ser fornecidas manualmente, se necessário. |
| Especificado | true | O armazenamento aceita apenas objetos. As chaves correspondem à propriedade especificada em keyPath. Se a propriedade não existir no objeto, uma chave será gerada automaticamente e adicionada ao objeto. |
A seguir, criamos um armazenamento chamado "users" na base de dados test, configurado para usar uma chave chamada "id", gerando automaticamente os valores:
Neste exemplo, a chave para cada objeto será a propriedade "id", gerada automaticamente. O método db.createObjectStore() retorna um objeto do tipo IDBObjectStore, que representa o armazenamento criado.
É importante destacar que se o número da versão do banco for incrementado ao abrir a conexão, os armazenamentos existentes são preservados. Tentativas de recriar um armazenamento já existente resultarão em erro.
Excluindo Armazenamentos
Para excluir um armazenamento, utiliza-se o método deleteObjectStore() e informa-se o nome do armazenamento a ser removido. Essa operação só é permitida durante uma alteração de versão do banco.
No exemplo a seguir, o armazenamento "users" é removido e recriado com novas configurações:
const request = indexedDB.open("test", 3); // Conecta ao banco de dados "test" na versão 3
request.onupgradeneeded = (event) => {
const db = event.target.result; // Obtém o banco de dados
// Remove o armazenamento "users"
db.deleteObjectStore("users");
// Cria novamente o armazenamento "users"
db.createObjectStore("users", { keyPath: "id", autoIncrement: true });
console.log(db.objectStoreNames); // Lista de armazenamentos no banco
};Nesse caso, o armazenamento antigo é excluído antes de ser recriado com novos parâmetros. Essa abordagem é útil para redefinir as configurações de um armazenamento já existente.
Documentação oficial: