Este guia aborda os conceitos básicos da
API IndexedDB.
Estamos usando o projeto
IndexedDB promised (em inglês)
semelhante à API IndexedDB, mas que usa promessas, que
você pode await para uma sintaxe mais concisa. Isso simplifica a API e, ao mesmo tempo,
para manter a estrutura.
O que é IndexedDB?
O IndexedDB é um sistema de armazenamento NoSQL em grande escala que permite o armazenamento de apenas sobre qualquer coisa no navegador do usuário. Além dos métodos usuais de pesquisa, get e put ações, o IndexedDB também oferece suporte a transações e é adequado para armazenar grandes quantidades de dados estruturados.
Cada banco de dados IndexedDB é exclusivo para um objeto origin (normalmente o domínio ou subdomínio do site), o que significa que ele não pode acessar ou ser acessado por qualquer outra origem. Os limites de armazenamento de dados são geralmente grandes, se existirem, mas navegadores diferentes lidam com os limites e remoção de dados de maneiras diferentes. Consulte a seção Leitura adicional para mais informações.
Termos do IndexedDB
- banco de dados
- O nível mais alto do IndexedDB. Ele contém os armazenamentos de objetos, que, por sua vez, contêm os dados que você quer persistir. É possível criar vários bancos de dados com os nomes que você escolher.
- Armazenamento de objetos
- Um bucket individual para armazenar dados, semelhante às tabelas em bancos de dados relacionais.
Normalmente, há um armazenamento de objetos para cada tipo (não dados JavaScript).
tipo) dos dados armazenados. Ao contrário das tabelas de banco de dados, os dados JavaScript
tipos de dados em um repositório não precisam ser consistentes. Por exemplo, se um app
tem um armazenamento de objetos
peoplecontendo informações sobre três pessoas, aquelas as propriedades de idade das pessoas poderiam ser53,'twenty-five'eunknown. - Índice
- Um tipo de armazenamento de objeto para organizar dados em outro armazenamento de objetos (chamado de armazenamento de objetos de referência) por uma propriedade individual dos dados. O índice é usado para recuperar registros no armazenamento de objetos por esta propriedade. Por exemplo, se você estiver armazenar pessoas, convém buscá-las mais tarde por seu nome, idade, ou animal favorito.
- Operação
- Uma interação com o banco de dados.
- Transação
- Um wrapper em torno de uma operação ou grupo de operações que garante que o banco de dados integridade dos dados. Se uma das ações em uma transação falhar, nenhuma delas será é aplicada e o banco de dados retorna ao estado em que estava antes da transação começou. Todas as operações de leitura ou gravação no IndexedDB precisam fazer parte de uma transação. Isso permite operações atômicas de leitura-modificação-gravação sem o risco de conflitos com outras linhas de execução atuando no banco de dados ao mesmo tempo.
- Cursor
- Um mecanismo para iterar vários registros em um banco de dados.
Como verificar o suporte a IndexedDB
O IndexedDB tem suporte universal.
Entretanto, se você estiver trabalhando com navegadores mais antigos, não é má ideia
suporte à detecção de recursos, por precaução. A maneira mais fácil é conferir o window
objeto:
function indexedDBStuff () {
// Check for IndexedDB support:
if (!('indexedDB' in window)) {
// Can't use IndexedDB
console.log("This browser doesn't support IndexedDB");
return;
} else {
// Do IndexedDB stuff here:
// ...
}
}
// Run IndexedDB code:
indexedDBStuff();
Como abrir um banco de dados
Com o IndexedDB, você pode criar vários bancos de dados com qualquer nome que quiser. Se
um banco de dados não existe quando você tenta abri-lo, mas não criadas automaticamente.
Para abrir um banco de dados, use o método openDB() da biblioteca idb:
import {openDB} from 'idb';
async function useDB () {
// Returns a promise, which makes `idb` usable with async-await.
const dbPromise = await openDB('example-database', version, events);
}
useDB();
Esse método retorna uma promessa que é resolvida em um objeto de banco de dados. Ao usar o botão
openDB(), forneça um nome, um número de versão e um objeto de eventos para definir
o banco de dados.
Confira um exemplo do método openDB() no contexto:
import {openDB} from 'idb';
async function useDB () {
// Opens the first version of the 'test-db1' database.
// If the database does not exist, it will be created.
const dbPromise = await openDB('test-db1', 1);
}
useDB();
Coloque a verificação do suporte a IndexedDB na parte superior da função anônima. Isso
sai da função se o navegador não oferece suporte a IndexedDB. Se a função puder
continuar, ele chamará o método openDB() para abrir um banco de dados chamado 'test-db1'.
Neste exemplo, o objeto de eventos opcionais foi deixado de fora para manter as coisas
simples, mas você precisa especificá-lo para fazer qualquer trabalho significativo com IndexedDB.
Como trabalhar com armazenamentos de objetos
Um banco de dados do IndexedDB contém um ou mais armazenamentos de objetos, cada um com uma coluna para uma chave e outra para os dados associados a essa chave.
Criar armazenamentos de objetos
Um banco de dados IndexedDB bem estruturado precisa ter um repositório de objetos para cada tipo
de dados que precisam ser persistidos. Por exemplo, um site que persiste ao usuário
os perfis e as observações podem ter um armazenamento de objetos people contendo person
e um armazenamento de objetos notes que contém objetos note.
Para garantir a integridade do banco de dados, você só pode criar ou remover armazenamentos de objetos no
objeto de eventos em uma chamada openDB(). O objeto de eventos expõe um objeto upgrade()
que permite criar armazenamentos de objetos. Chame o método
createObjectStore()
dentro do método upgrade() para criar o armazenamento de objetos:
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('example-database', 1, {
upgrade (db) {
// Creates an object store:
db.createObjectStore('storeName', options);
}
});
}
createStoreInDB();
Esse método recebe o nome do armazenamento de objetos e uma configuração opcional que permite definir várias propriedades para o armazenamento de objetos.
Confira abaixo um exemplo de como usar createObjectStore():
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('test-db1', 1, {
upgrade (db) {
console.log('Creating a new object store...');
// Checks if the object store exists:
if (!db.objectStoreNames.contains('people')) {
// If the object store does not exist, create it:
db.createObjectStore('people');
}
}
});
}
createStoreInDB();
Neste exemplo, um objeto de eventos é transmitido ao método openDB() para criar
repositório de objetos e, como antes, o trabalho de criação do armazenamento de objetos está concluído
no método upgrade() do objeto de evento. No entanto, como o navegador gera uma
se você tentar criar um armazenamento de objetos que já existe, recomendamos
encapsulando o método createObjectStore() em uma instrução if que verifica
se o armazenamento de objetos existe. No bloco if, chame
createObjectStore() para criar um repositório de objetos chamado 'firstOS'.
Como definir chaves primárias
Ao definir armazenamentos de objetos, é possível definir como os dados são identificados exclusivamente em armazenamento usando uma chave primária. É possível definir uma chave primária definindo uma ou usando um gerador de chaves.
Um caminho de chave é uma propriedade que sempre existe e contém um valor exclusivo. Para
exemplo, no caso de um armazenamento de objetos people, é possível escolher o e-mail
como o caminho da chave:
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('test-db2', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('people')) {
db.createObjectStore('people', { keyPath: 'email' });
}
}
});
}
createStoreInDB();
Este exemplo cria um armazenamento de objetos chamado 'people' e atribui o email
como a chave primária na opção keyPath.
Você também pode usar um gerador de chaves, como autoIncrement. Gerador de chaves
cria um valor exclusivo para cada objeto adicionado ao armazenamento de objetos. Por padrão,
Se você não especificar uma chave, o IndexedDB criará uma chave e a armazenará separadamente.
dos dados.
O exemplo a seguir cria um armazenamento de objetos chamado 'notes' e define o
chave primária seja atribuída automaticamente como um número de incremento automático:
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('test-db2', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('notes')) {
db.createObjectStore('notes', { autoIncrement: true });
}
}
});
}
createStoreInDB();
O exemplo a seguir é semelhante ao anterior, mas, desta vez,
o valor de incremento automático foi atribuído explicitamente a uma propriedade chamada 'id'.