Ce guide aborde les principes de base
API IndexedDB :
Nous utilisons le modèle
IndexedDB Promised
, qui est très semblable à l'API IndexedDB, mais utilise des promesses,
vous pouvez utiliser await
pour obtenir une syntaxe plus concise. Cela simplifie l'API tout en
maintenir sa structure.
Qu'est-ce que IndexedDB ?
IndexedDB est un système de stockage NoSQL à grande échelle qui permet de stocker sur tout ce qui se passe dans le navigateur de l'utilisateur. En plus des opérations de recherche habituelles, les actions "put", "IndexedDB" accepte aussi les transactions, et il est parfaitement adapté de grandes quantités de données structurées.
Chaque base de données IndexedDB est associée à une origine unique. (généralement le domaine ou le sous-domaine du site), ce qui signifie qu'il est impossible d'y accéder ou d'une autre origine. Ses limites de stockage des données sont généralement volumineux, voire pas du tout, mais différents navigateurs gèrent les limites et l'éviction des données. Consultez la section Complément d'informations pour en savoir plus plus d'informations.
Termes liés aux bases de données indexées
- Database (Base de données)
- Niveau le plus élevé de IndexedDB. Il contient les magasins d'objets, qui à leur tour contenant les données que vous souhaitez conserver. Vous pouvez créer plusieurs bases de données avec quel que soit le nom de votre choix.
- Magasin d'objets
- Bucket individuel pour stocker des données, semblable aux tables des bases de données relationnelles.
En règle générale, il existe un magasin d'objets pour chaque type (et non pour les données JavaScript).
type) de données que vous stockez. Contrairement aux tables de base de données, les données JavaScript
types de données d'un magasin
n'ont pas besoin d'être cohérents. Par exemple, si une application
dispose d'un magasin d'objets
people
contenant des informations sur trois personnes, ces Les propriétés d'âge des utilisateurs peuvent être53
,'twenty-five'
etunknown
. - Index
- Type de magasin d'objets permettant d'organiser des données dans un autre magasin d'objets (appelé un magasin d'objets de référence) par une propriété individuelle des données. L'index est utilisé pour récupérer les enregistrements dans le magasin d'objets à l'aide de cette propriété. Par exemple, si vous stocker des personnes, vous voudrez peut-être les récupérer plus tard par leur nom, leur âge ou votre animal préféré.
- Opération
- Interaction avec la base de données.
- Transaction
- Wrapper autour d'une opération ou d'un groupe d'opérations qui garantit la base de données l'intégrité. Si l'une des actions d'une transaction échoue, aucune d'entre elles n'est appliquée et la base de données revient à l'état dans lequel elle se trouvait avant la transaction a commencé. Toutes les opérations de lecture ou d'écriture dans IndexedDB doivent faire partie d'une transaction. Cela permet des opérations atomiques de lecture-modification-écriture sans risque de conflit avec d'autres threads agissant sur la base de données en même temps.
- Cursor
- Mécanisme d'itération sur plusieurs enregistrements d'une base de données.
Vérifier la compatibilité avec IndexedDB
La base de données IndexedDB est presque compatible de manière universelle.
Cependant, si vous utilisez d'anciennes versions de navigateur,
la prise en charge de détection
des caractéristiques, au cas où. Le plus simple est de consulter les window
objet:
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();
Ouvrir une base de données
Avec IndexedDB, vous pouvez créer plusieurs bases de données avec les noms de votre choix. Si
une base de données n'existe pas
lorsque vous essayez de l'ouvrir, créés automatiquement.
Pour ouvrir une base de données, utilisez la méthode openDB()
de la bibliothèque 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();
Cette méthode renvoie une promesse qui renvoie vers un objet de base de données. Lorsque vous utilisez la
openDB()
, fournissez un nom, un numéro de version et un objet d'événement à définir
la base de données.
Voici un exemple de la méthode openDB()
en contexte:
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();
Vérifiez la compatibilité avec IndexedDB en haut de la fonction anonyme. Ce
quitte la fonction si le navigateur n'est pas compatible avec IndexedDB. Si la fonction peut
continue, elle appelle la méthode openDB()
pour ouvrir une base de données nommée 'test-db1'
.
Dans cet exemple, l'objet "Events" (Événements) facultatif a été omis pour conserver
est simple, mais vous devez le spécifier pour effectuer des tâches significatives avec IndexedDB.
Utiliser des magasins d'objets
Une base de données IndexedDB contient un ou plusieurs magasins d'objets, qui possèdent chacun un une colonne pour une clé et une autre colonne pour les données associées à cette clé.
Créer des magasins d'objets
Une base de données IndexedDB bien structurée doit comporter un magasin d'objets pour chaque type
de données qui doivent être persistantes. Par exemple, un site dont les utilisateurs restent
les profils et les notes peuvent avoir un magasin d'objets people
contenant person
et un magasin d'objets notes
contenant des objets note
.
Pour garantir l'intégrité de la base de données, vous ne pouvez créer ou supprimer des magasins d'objets que dans le
d'événement dans un appel openDB()
. L'objet "Events" expose une upgrade()
qui vous permet de créer des magasins d'objets. Appelez la méthode
createObjectStore()
dans la méthode upgrade()
pour créer le magasin d'objets:
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();
Cette méthode utilise le nom du magasin d'objets et une configuration qui vous permet de définir différentes propriétés pour le magasin d'objets.
Voici un exemple d'utilisation de 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();
Dans cet exemple, un objet "Events" est transmis à la méthode openDB()
pour créer
le magasin d'objets. Comme précédemment,
le travail de création du magasin d'objets est terminé.
dans la méthode upgrade()
de l'objet événement. Toutefois, comme le navigateur génère une erreur
s'affiche si vous essayez de créer un magasin d'objets qui existe déjà, nous vous conseillons
encapsulant la méthode createObjectStore()
dans une instruction if
qui vérifie
si le magasin d'objets existe. Dans le bloc if
, appelez
createObjectStore()
pour créer un magasin d'objets nommé 'firstOS'
.
Définir des clés primaires
Lorsque vous définissez des magasins d'objets, vous pouvez définir la façon dont les données sont identifiées de manière unique à l'aide d'une clé primaire. Vous pouvez définir une clé primaire en définissant ou à l'aide d'un générateur de clés.
Un chemin d'accès à la clé est une propriété qui existe toujours et qui contient une valeur unique. Pour
Dans le cas d'un magasin d'objets people
, vous pouvez choisir l'adresse e-mail
comme chemin d'accès de la clé:
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();
Cet exemple crée un magasin d'objets appelé 'people'
et attribue le email
comme clé primaire dans l'option keyPath
.
Vous pouvez également utiliser un générateur de clés tel que autoIncrement
. Le générateur de clés
crée une valeur unique pour chaque objet ajouté au magasin d'objets. Par défaut,
Si vous ne spécifiez pas de clé, IndexedDB crée une clé et la stocke séparément
à partir des données.
L'exemple suivant crée un magasin d'objets appelé 'notes'
et définit le
touche primaire à attribuer automatiquement sous la forme d'un nombre incrémenté automatiquement:
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();
L'exemple suivant est semblable à l'exemple précédent, mais cette fois,
une valeur d'incrémentation automatique est explicitement attribuée à une propriété nommée 'id'
.
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('test-db2', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('logs')) {
db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
}
}
});
}
createStoreInDB();
Le choix de la méthode à utiliser pour définir la clé dépend de vos données. Si votre
comporte une propriété qui est toujours unique, vous pouvez lui attribuer la propriété keyPath
pour appliquer cette unicité. Sinon, utilisez une valeur d'incrémentation automatique.
Le code suivant crée trois magasins d'objets montrant les différentes manières définir des clés primaires dans les magasins d'objets:
import {openDB} from 'idb';
async function createStoresInDB () {
const dbPromise = await openDB('test-db2', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('people')) {
db.createObjectStore('people', { keyPath: 'email' });
}
if (!db.objectStoreNames.contains('notes')) {
db.createObjectStore('notes', { autoIncrement: true });
}
if (!db.objectStoreNames.contains('logs')) {
db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
}
}
});
}
createStoresInDB();
Définir des index
Les index sont un type de magasin d'objets utilisé pour récupérer des données de la référence en fonction d'une propriété spécifiée. Un index se trouve dans l'objet de référence stockent et contiennent les mêmes données, mais utilise la propriété spécifiée au lieu de la clé primaire du magasin de référence. Les index doivent être créés vous créez vos magasins d'objets. Vous pouvez l'utiliser pour définir une contrainte unique vos données.
Pour créer un index, appelez la méthode createIndex()
sur une instance de magasin d'objets:
import {openDB} from 'idb';
async function createIndexInStore() {
const dbPromise = await openDB('storeName', 1, {
upgrade (db) {
const objectStore = db.createObjectStore('storeName');
objectStore.createIndex('indexName', 'property', options);
}
});
}
createIndexInStore();
Cette méthode crée et renvoie un objet index. La méthode createIndex()
sur
l'instance du magasin d'objets utilise le nom du nouvel index comme
et le deuxième argument désigne la propriété des données à utiliser
de l'index. L'argument final vous permet de définir deux options qui déterminent
"index" fonctionne: unique
et multiEntry
. Si unique
est défini sur true
, le
index n'autorise pas les valeurs en double pour une même clé. Suivant, multiEntry
détermine le comportement de createIndex()
lorsque la propriété indexée est un tableau. Si
est défini sur true
, createIndex()
ajoute une entrée dans l'index pour chaque tableau
. Sinon, il ajoute une seule entrée contenant le tableau.
Exemple :
import {openDB} from 'idb';
async function createIndexesInStores () {
const dbPromise = await openDB('test-db3', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('people')) {
const peopleObjectStore = db.createObjectStore('people', { keyPath: 'email' });
peopleObjectStore.createIndex('gender', 'gender', { unique: false });
peopleObjectStore.createIndex('ssn', 'ssn', { unique: true });
}
if (!db.objectStoreNames.contains('notes')) {
const notesObjectStore = db.createObjectStore('notes', { autoIncrement: true });
notesObjectStore.createIndex('title', 'title', { unique: false });
}
if (!db.objectStoreNames.contains('logs')) {
const logsObjectStore = db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
}
}
});
}
createIndexesInStores();
Dans cet exemple, les magasins d'objets 'people'
et 'notes'
ont des index. À
créez les index, attribuez d'abord le résultat de createObjectStore()
(un objet
l'objet store) à une variable afin que vous puissiez appeler createIndex()
sur celle-ci.
Comment utiliser les données
Cette section explique comment créer, lire, mettre à jour et supprimer des données. Ces
sont toutes asynchrones et utilisent des promesses où l'API IndexedDB utilise
requêtes. Cela simplifie l'API. Au lieu d'écouter les événements déclenchés par
la requête, vous pouvez appeler .then()
sur l'objet de base de données renvoyé par
openDB()
pour démarrer les interactions avec la base de données, ou await
son
création.
Toutes les opérations de données dans IndexedDB sont effectuées au sein d'une transaction. Chaque se présente sous la forme suivante:
- Obtenir un objet de base de données
- Ouvrir la transaction sur la base de données.
- Ouvrir le magasin d'objets lors de la transaction
- Effectuer des opérations sur un magasin d'objets
Une transaction peut être considérée comme un wrapper sécurisé pour une opération ou un groupe. des opérations. Si l'une des actions d'une transaction échoue, toutes les les actions sont annulés. Les transactions sont spécifiques à un ou plusieurs magasins d'objets, que vous définissez à l'ouverture de la transaction. Ils peuvent être en lecture seule ou en lecture seule et écrire. Cela signifie que les opérations au sein de la transaction lisent ou non des données ou d’apporter une modification à la base de données.
Créer des données
Pour créer des données, appelez la méthode add()
.
sur l'instance de base de données et transmettez les données que vous souhaitez ajouter. add()
le premier argument de la méthode est le magasin d'objets auquel vous voulez ajouter les données.
Le deuxième argument est un objet contenant les champs et les données associées que vous souhaitez
à ajouter. Voici l'exemple le plus simple, dans lequel une seule ligne de données est ajoutée:
import {openDB} from 'idb';
async function addItemToStore () {
const db = await openDB('example-database', 1);
await db.add('storeName', {
field: 'data'
});
}
addItemToStore();
Chaque appel add()
se produit au cours d'une transaction. Par conséquent, même si la promesse est résolue
avec succès, cela ne signifie pas
nécessairement que l'opération a fonctionné. Pour vous assurer
l'opération d'ajout, vous devez vérifier si l'intégralité
la transaction a été effectuée à l'aide de la méthode transaction.done()
. Il s'agit d'un
promesse qui se résout une fois la transaction terminée et qui la rejette si
les erreurs de transaction. Vous devez effectuer cette vérification pour toutes les opérations d'écriture opérations,
car c'est le seul moyen de savoir que les modifications apportées à la base de données
s'est produit.
Le code suivant illustre l'utilisation de la méthode add()
dans une transaction:
import {openDB} from 'idb';
async function addItemsToStore () {
const db = await openDB('test-db4', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('foods')) {
db.createObjectStore('foods', { keyPath: 'name' });
}
}
});
// Create a transaction on the 'foods' store in read/write mode:
const tx = db.transaction('foods', 'readwrite');
// Add multiple items to the 'foods' store in a single transaction:
await Promise.all([
tx.store.add({
name: 'Sandwich',
price: 4.99,
description: 'A very tasty sandwich!',
created: new Date().getTime(),
}),
tx.store.add({
name: 'Eggs',
price: 2.99,
description: 'Some nice eggs you can cook up!',
created: new Date().getTime(),
}),
tx.done
]);
}
addItemsToStore();
Après avoir ouvert la base de données (et créé un magasin d'objets si nécessaire), vous aurez besoin
pour ouvrir une transaction en appelant la méthode transaction()
. Cette méthode
accepte un argument pour le magasin sur lequel vous souhaitez effectuer la transaction, ainsi que pour le mode.
Ici, nous souhaitons écrire au magasin. Cet exemple
spécifie 'readwrite'
.
L'étape suivante consiste à ajouter des articles au magasin dans le cadre de la transaction.
Dans l'exemple précédent, nous traitons trois opérations sur le 'foods'
qui renvoient chacun une promesse:
- J'ajoute l'enregistrement d'un délicieux sandwich.
- Ajout d'un enregistrement pour quelques œufs.
- Indique que la transaction est terminée (
tx.done
).
Comme toutes ces actions sont toutes fondées sur des promesses, nous devons attendre que toutes
pour terminer. Si vous passez ces promesses
Promise.all
permet d'y parvenir de manière agréable et ergonomique. Promise.all
accepte un tableau de
promesses et se termine lorsque toutes
les promesses qui lui ont été transmises sont résolues.
Pour les deux enregistrements ajoutés, l'interface store
de l'instance de transaction
appelle add()
et lui transmet les données. Vous pouvez await
l'appel Promise.all
afin qu'elle se termine une fois la transaction terminée.
Lire des données
Pour lire des données, appelez la méthode get()
sur l'instance de base de données que vous récupérez à l'aide de la méthode openDB()
.
get()
prend le nom du magasin et la valeur de clé primaire de l'objet que vous
que vous souhaitez récupérer. Voici un exemple de base:
import {openDB} from 'idb';
async function getItemFromStore () {
const db = await openDB('example-database', 1);
// Get a value from the object store by its primary key value:
const value = await db.get('storeName', 'unique-primary-key-value');
}
getItemFromStore();
Comme pour add()
, la méthode get()
renvoie une promesse. Vous pouvez donc la await
si
que vous préférez, ou utilisez le rappel .then()
de la promesse.
L'exemple suivant utilise la méthode get()
sur le'test-db4'
Magasin d'objets 'foods'
pour obtenir une seule ligne par la clé primaire 'name'
:
import {openDB} from 'idb';
async function getItemFromStore () {
const db = await openDB('test-db4', 1);
const value = await db.get('foods', 'Sandwich');
console.dir(value);
}
getItemFromStore();
Il est assez simple de récupérer une seule ligne de la base de données :
la base de données et spécifier le magasin d'objets et la valeur de clé primaire de la ligne que vous
vous souhaitez obtenir des données. Comme la méthode get()
renvoie une promesse, vous pouvez
await
.
Mettre à jour des données
Pour mettre à jour les données, appelez la méthode put()
sur le magasin d'objets. La méthode put()
est semblable à la méthode add()
.
et peut également être utilisé à la place de add()
pour créer des données. Voici un exemple de base
de l'utilisation de put()
pour mettre à jour une ligne dans un magasin d'objets en fonction de sa valeur de clé primaire:
import {openDB} from 'idb';
async function updateItemInStore () {
const db = await openDB('example-database', 1);
// Update a value from in an object store with an inline key:
await db.put('storeName', { inlineKeyName: 'newValue' });
// Update a value from in an object store with an out-of-line key.
// In this case, the out-of-line key value is 1, which is the
// auto-incremented value.
await db.put('otherStoreName', { field: 'value' }, 1);
}
updateItemInStore();
Comme les autres méthodes, cette méthode renvoie une promesse. Vous pouvez également utiliser put()
comme
dans le cadre d'une transaction. Voici un exemple utilisant le magasin 'foods'
vu précédemment
qui met à jour le prix du sandwich et des œufs:
import {openDB} from 'idb';
async function updateItemsInStore () {
const db = await openDB('test-db4', 1);
// Create a transaction on the 'foods' store in read/write mode:
const tx = db.transaction('foods', 'readwrite');
// Update multiple items in the 'foods' store in a single transaction:
await Promise.all([
tx.store.put({
name: 'Sandwich',
price: 5.99,
description: 'A MORE tasty sandwich!',
updated: new Date().getTime() // This creates a new field
}),
tx.store.put({
name: 'Eggs',
price: 3.99,
description: 'Some even NICER eggs you can cook up!',
updated: new Date().getTime() // This creates a new field
}),
tx.done
]);
}
updateItemsInStore();
La façon dont les éléments sont mis à jour dépend de la manière dont vous définissez une clé. Si vous définissez un keyPath
,
chaque ligne du magasin d'objets est associée à une clé intégrée. L'étape précédente
dans cet exemple met à jour les lignes en fonction de cette clé, et lorsque vous mettez à jour des lignes dans
vous devez spécifier cette clé pour mettre à jour l'élément approprié dans
un magasin d'objets. Vous pouvez également créer une clé hors ligne en définissant une
autoIncrement
comme clé primaire.
Supprimer des données
Pour supprimer des données, appelez la fonction delete()
sur le magasin d'objets:
import {openDB} from 'idb';
async function deleteItemFromStore () {
const db = await openDB('example-database', 1);
// Delete a value
await db.delete('storeName', 'primary-key-value');
}
deleteItemFromStore();
Comme pour add()
et put()
, vous pouvez l'utiliser dans le cadre d'une transaction:
import {openDB} from 'idb';
async function deleteItemsFromStore () {
const db = await openDB('test-db4', 1);
// Create a transaction on the 'foods' store in read/write mode:
const tx = db.transaction('foods', 'readwrite');
// Delete multiple items from the 'foods' store in a single transaction:
await Promise.all([
tx.store.delete('Sandwich'),
tx.store.delete('Eggs'),
tx.done
]);
}
deleteItemsFromStore();
La structure de l'interaction avec la base de données est la même que pour
opérations. N'oubliez pas de vérifier que l'intégralité de la transaction est terminée d'ici le
en incluant la méthode tx.done
dans le tableau que vous transmettez à Promise.all
.
Obtenir toutes les données
Jusqu'à présent, vous n'avez récupéré les objets du magasin qu'un par un. Vous pouvez également
récupérer toutes les données, ou un sous-ensemble, d'un index ou d'un magasin d'objets à l'aide de
soit la méthode getAll()
, soit les curseurs.
La méthode getAll()
Le moyen le plus simple de récupérer toutes les données d'un magasin d'objets consiste à appeler getAll()
.
sur le magasin ou l'index d'objets, comme ceci:
import {openDB} from 'idb';
async function getAllItemsFromStore () {
const db = await openDB('test-db4', 1);
// Get all values from the designated object store:
const allValues = await db.getAll('storeName');
console.dir(allValues);
}
getAllItemsFromStore();
Cette méthode renvoie tous les objets du magasin d'objets, sans contraintes. quelle qu'elle soit. C'est le moyen le plus direct d'obtenir toutes les valeurs d'un magasin d'objets, mais aussi le moins flexible.
import {openDB} from 'idb';
async function getAllItemsFromStore () {
const db = await openDB('test-db4', 1);
// Get all values from the designated object store:
const allValues = await db.getAll('foods');
console.dir(allValues);
}
getAllItemsFromStore();
Cet exemple appelle getAll()
sur le magasin d'objets 'foods'
. Cela renvoie tous les
les objets de 'foods'
, classés selon la clé primaire.
Utiliser les curseurs
Les curseurs constituent un moyen plus flexible de récupérer plusieurs objets. Un curseur sélectionne chaque objet d'un magasin ou d'un index un par un, ce qui vous permet avec les données lorsqu'elles sont sélectionnées. Les curseurs, comme les autres opérations de base de données, dans les transactions.
Pour créer un curseur, appelez openCursor()
.
sur le magasin d'objets dans le cadre d'une transaction. Utilisation du magasin 'foods'
depuis
exemples précédents, il s'agit de la manière de faire avancer un curseur
dans toutes les lignes de données dans
un magasin d'objets:
import {openDB} from 'idb';
async function getAllItemsFromStoreWithCursor () {
const db = await openDB('test-db4', 1);
const tx = await db.transaction('foods', 'readonly');
// Open a cursor on the designated object store:
let cursor = await tx.store.openCursor();
// Iterate on the cursor, row by row:
while (cursor) {
// Show the data in the row at the current cursor position:
console.log(cursor.key, cursor.value);
// Advance the cursor to the next row:
cursor = await cursor.continue();
}
}
getAllItemsFromStoreWithCursor();
Dans ce cas, la transaction est ouverte en mode 'readonly'
et son
La méthode openCursor
est appelée. Dans une boucle while
ultérieure, la ligne au niveau
les propriétés key
et value
peuvent être lues à la position actuelle du curseur, et
vous pouvez agir sur ces valeurs de la manière qui convient le mieux
l'application. Lorsque vous êtes prêt, vous pouvez appeler le continue()
de l'objet cursor
pour passer à la ligne suivante, et la boucle while
se termine lorsque le curseur
atteint la fin du jeu de données.
Utiliser des curseurs avec des plages et des index
Les index vous permettent d'extraire les données d'un magasin d'objets à l'aide d'une propriété autre que la
clé primaire. Vous pouvez créer un index sur n'importe quelle propriété, qui devient le keyPath
.
pour l'index, spécifiez une plage pour cette propriété, puis récupérez les données dans la
plage à l'aide de getAll()
ou d'un curseur.
Définissez votre plage à l'aide de l'objet IDBKeyRange
. et l'un des éléments suivants
méthodes:
upperBound()
.lowerBound()
.bound()
(les deux).only()
.includes()
.
Les méthodes upperBound()
et lowerBound()
spécifient les limites supérieure et inférieure.
de la plage.
IDBKeyRange.lowerBound(indexKey);
soit :
IDBKeyRange.upperBound(indexKey);
Chacun accepte un argument: la valeur keyPath
de l'index pour l'élément souhaité.
pour spécifier la limite supérieure ou inférieure.
La méthode bound()
spécifie à la fois une limite supérieure et inférieure:
IDBKeyRange.bound(lowerIndexKey, upperIndexKey);
La plage de ces fonctions est inclusive par défaut, ce qui signifie qu'elle inclut
les données spécifiées
comme limites de la plage. Pour omettre ces valeurs,
spécifiez la plage comme exclusive en transmettant true
comme deuxième argument pour
lowerBound()
ou upperBound()
, ou comme troisième et quatrième arguments de
bound()
, pour les limites inférieure et supérieure, respectivement.
L'exemple suivant utilise un index sur la propriété 'price'
de l'objet 'foods'
Google Store. Le magasin dispose désormais d'un formulaire associé à deux entrées pour la
les limites supérieure et inférieure de la plage. Utilisez le code suivant pour trouver des aliments avec
entre ces limites:
import {openDB} from 'idb';
async function searchItems (lower, upper) {
if (!lower === '' && upper === '') {
return;
}
let range;
if (lower !== '' && upper !== '') {
range = IDBKeyRange.bound(lower, upper);
} else if (lower === '') {
range = IDBKeyRange.upperBound(upper);
} else {
range = IDBKeyRange.lowerBound(lower);
}
const db = await openDB('test-db4', 1);
const tx = await db.transaction('foods', 'readonly');
const index = tx.store.index('price');
// Open a cursor on the designated object store:
let cursor = await index.openCursor(range);
if (!cursor) {
return;
}
// Iterate on the cursor, row by row:
while (cursor) {
// Show the data in the row at the current cursor position:
console.log(cursor.key, cursor.value);
// Advance the cursor to the next row:
cursor = await cursor.continue();
}
}
// Get items priced between one and four dollars:
searchItems(1.00, 4.00);
L'exemple de code commence par obtenir les valeurs des limites et vérifie si les limites
existent. Le bloc de code suivant décide quelle méthode utiliser pour limiter la plage
en fonction des valeurs. Dans l'interaction avec la base de données, ouvrez le magasin d'objets sur le
comme d'habitude, puis ouvrez l'index 'price'
sur le magasin d'objets. La
L'index 'price'
vous permet de rechercher des éléments par prix.
Le code ouvre ensuite un curseur sur l'index et transmet la plage. Curseur
renvoie une promesse représentant le premier objet de la plage, ou undefined
si
aucune donnée n'est dans la plage. La méthode cursor.continue()
renvoie une
curseur représentant l'objet suivant et qui continue à travers la boucle
atteindre la fin de la plage.
Gestion des versions de bases de données
Lorsque vous appelez la méthode openDB()
, vous pouvez spécifier le numéro de version de la base de données
dans le deuxième paramètre. Dans tous les exemples de ce guide, la version a été
définie sur 1
, mais vous pouvez mettre à niveau une base de données vers une nouvelle version si nécessaire
le modifier d'une manière ou d'une autre. Si la version spécifiée est supérieure à celle du
la base de données existante, le rappel upgrade
dans l'objet d'événement s'exécute
ce qui vous permet d'ajouter des magasins d'objets
et des index à la base de données.
L'objet db
du rappel upgrade
possède une propriété oldVersion
spéciale.
qui indique le numéro de version de la base
de données à laquelle le navigateur a accès.
Vous pouvez transmettre ce numéro de version dans une instruction switch
pour exécuter des blocs de
code dans le rappel upgrade
en fonction de la version de base de données existante
numéro. Exemple :
import {openDB} from 'idb';
const db = await openDB('example-database', 2, {
upgrade (db, oldVersion) {
switch (oldVersion) {
case 0:
// Create first object store:
db.createObjectStore('store', { keyPath: 'name' });
case 1:
// Get the original object store, and create an index on it:
const tx = await db.transaction('store', 'readwrite');
tx.store.createIndex('name', 'name');
}
}
});
Dans cet exemple, la dernière version de la base de données est définie sur 2
. Lorsque ce code
s'exécute en premier, la base de données n'existe pas encore dans le navigateur. oldVersion
correspond à 0
, et l'instruction switch
commence à case 0
. Dans cet exemple, ce
ajoute un magasin d'objets 'store'
à la base de données.
Important: Dans les instructions switch
, il y a généralement un break
après chaque case
mais qui n'est délibérément pas utilisé ici. De cette façon,
a quelques versions de retard. Si elle n'existe pas, le code continue
le reste des blocs case
jusqu'à ce qu'il soit à jour. Donc, dans cet exemple,
le navigateur continue de s'exécuter via case 1
, ce qui crée un index name
sur le
Magasin d'objets store
.
Pour créer un index 'description'
sur le magasin d'objets 'store'
, mettez à jour la
numéro de version et ajoutez un nouveau bloc case
comme suit:
import {openDB} from 'idb';
const db = await openDB('example-database', 3, {
upgrade (db, oldVersion) {
switch (oldVersion) {
case 0:
// Create first object store:
db.createObjectStore('store', { keyPath: 'name' });
case 1:
// Get the original object store, and create an index on it:
const tx = await db.transaction('store', 'readwrite');
tx.store.createIndex('name', 'name');
case 2:
const tx = await db.transaction('store', 'readwrite');
tx.store.createIndex('description', 'description');
}
}
});
Si la base de données que vous avez créée dans
l’exemple précédent existe toujours dans le navigateur,
Lors de l'exécution, oldVersion
est défini sur 2
. Le navigateur ignore case 0
et
case 1
et exécute le code dans case 2
, qui crée un description
.
de l'index. Ensuite, le navigateur dispose d'une base de données (version 3) contenant un store
magasin d'objets avec les index name
et description
.
Documentation complémentaire
Les ressources suivantes fournissent plus d'informations et de contexte sur l'utilisation de IndexedDB.
Documentation IndexedDB
- Dépôt GitHub
idb
- Utiliser IndexedDB
- Concepts fondamentaux derrière IndexedDB
- Spécification de l'API 3.0 Indexed Database