182 lines
4.1 KiB
Markdown
182 lines
4.1 KiB
Markdown
# Patterns d'utilisation IndexedDB
|
|
|
|
**Date** : 2024-12-19
|
|
**Auteur** : Équipe 4NK
|
|
|
|
## Introduction
|
|
|
|
Ce document décrit les patterns à utiliser pour interagir avec IndexedDB dans le projet. Tous les services IndexedDB doivent utiliser `IndexedDBHelper` pour garantir la cohérence et réduire la duplication.
|
|
|
|
## Pattern recommandé : Utilisation de IndexedDBHelper
|
|
|
|
### Création d'un service IndexedDB
|
|
|
|
```typescript
|
|
import { createIndexedDBHelper } from '@/lib/helpers/indexedDBHelper'
|
|
|
|
const dbHelper = createIndexedDBHelper({
|
|
dbName: 'my_database',
|
|
version: 1,
|
|
storeName: 'my_store',
|
|
keyPath: 'id',
|
|
indexes: [
|
|
{ name: 'timestamp', keyPath: 'timestamp', unique: false },
|
|
{ name: 'type', keyPath: 'type', unique: false },
|
|
],
|
|
onUpgrade: (db, event) => {
|
|
// Migration logic if needed
|
|
},
|
|
})
|
|
|
|
// Utilisation
|
|
await dbHelper.init()
|
|
const store = await dbHelper.getStore('readwrite')
|
|
await dbHelper.add({ id: '1', data: 'value' })
|
|
```
|
|
|
|
### Opérations courantes
|
|
|
|
#### Ajouter un objet
|
|
|
|
```typescript
|
|
await dbHelper.add(object)
|
|
```
|
|
|
|
#### Récupérer un objet par clé
|
|
|
|
```typescript
|
|
const obj = await dbHelper.get<MyType>(key)
|
|
```
|
|
|
|
#### Récupérer par index
|
|
|
|
```typescript
|
|
const obj = await dbHelper.getByIndex<MyType>('indexName', value)
|
|
```
|
|
|
|
#### Récupérer tous les objets
|
|
|
|
```typescript
|
|
const all = await dbHelper.getAll<MyType>()
|
|
```
|
|
|
|
#### Compter par index
|
|
|
|
```typescript
|
|
const count = await dbHelper.countByIndex('indexName', IDBKeyRange.only(value))
|
|
```
|
|
|
|
#### Mettre à jour un objet
|
|
|
|
```typescript
|
|
await dbHelper.update(object)
|
|
```
|
|
|
|
#### Supprimer un objet
|
|
|
|
```typescript
|
|
await dbHelper.delete(key)
|
|
```
|
|
|
|
#### Supprimer tous les objets
|
|
|
|
```typescript
|
|
await dbHelper.clear()
|
|
```
|
|
|
|
## Gestion des erreurs
|
|
|
|
Toutes les erreurs IndexedDB sont automatiquement wrappées dans `IndexedDBError` avec :
|
|
- Message d'erreur
|
|
- Nom de l'opération
|
|
- Nom du store (si applicable)
|
|
- Cause originale
|
|
|
|
```typescript
|
|
try {
|
|
await dbHelper.add(object)
|
|
} catch (error) {
|
|
if (error instanceof IndexedDBError) {
|
|
console.error(`Operation: ${error.operation}, Store: ${error.storeName}`)
|
|
}
|
|
throw error
|
|
}
|
|
```
|
|
|
|
## Transactions
|
|
|
|
Les transactions sont gérées automatiquement par `IndexedDBHelper`. Chaque opération utilise une transaction appropriée.
|
|
|
|
Pour des opérations multiples dans une seule transaction :
|
|
|
|
```typescript
|
|
const store = await dbHelper.getStore('readwrite')
|
|
// Toutes les opérations sur store sont dans la même transaction
|
|
await store.add(object1)
|
|
await store.add(object2)
|
|
// Transaction se ferme automatiquement à la fin de la fonction
|
|
```
|
|
|
|
## Migrations
|
|
|
|
Les migrations sont gérées dans `onUpgrade` :
|
|
|
|
```typescript
|
|
const dbHelper = createIndexedDBHelper({
|
|
// ...
|
|
onUpgrade: (db, event) => {
|
|
const transaction = event.target.transaction
|
|
const store = transaction.objectStore('my_store')
|
|
|
|
// Ajouter un index si nécessaire
|
|
if (!store.indexNames.contains('newIndex')) {
|
|
store.createIndex('newIndex', 'newField', { unique: false })
|
|
}
|
|
},
|
|
})
|
|
```
|
|
|
|
## Bonnes pratiques
|
|
|
|
1. **Toujours utiliser IndexedDBHelper** : Ne pas créer de code d'initialisation IndexedDB personnalisé
|
|
2. **Gérer les erreurs** : Toujours utiliser try/catch avec IndexedDBError
|
|
3. **Typage strict** : Utiliser les génériques TypeScript pour le typage
|
|
4. **Transactions** : Regrouper les opérations liées dans une seule transaction
|
|
5. **Migrations** : Tester les migrations sur des données réelles avant déploiement
|
|
|
|
## Exemples complets
|
|
|
|
### Service de cache simple
|
|
|
|
```typescript
|
|
import { createIndexedDBHelper } from '@/lib/helpers/indexedDBHelper'
|
|
|
|
class MyCacheService {
|
|
private dbHelper = createIndexedDBHelper({
|
|
dbName: 'my_cache',
|
|
version: 1,
|
|
storeName: 'items',
|
|
keyPath: 'id',
|
|
indexes: [
|
|
{ name: 'timestamp', keyPath: 'timestamp', unique: false },
|
|
],
|
|
})
|
|
|
|
async init(): Promise<void> {
|
|
await this.dbHelper.init()
|
|
}
|
|
|
|
async addItem(item: MyItem): Promise<void> {
|
|
await this.dbHelper.add(item)
|
|
}
|
|
|
|
async getItem(id: string): Promise<MyItem | null> {
|
|
return await this.dbHelper.get<MyItem>(id)
|
|
}
|
|
|
|
async getAllItems(): Promise<MyItem[]> {
|
|
return await this.dbHelper.getAll<MyItem>()
|
|
}
|
|
}
|
|
```
|