Cursori
Pentru a obține obiecte din depozitul bazei de date se pot utiliza și cursorii. În contextul unei baze de date, un cursor reprezintă un mecanism pentru a parcurge diferite obiecte din depozitul bazei de date.
Pentru a crea un cursor la obiectul IDBObjectStore se folosește metoda openCursor():
openCursor()
openCursor(query)
openCursor(query, direction)
Ca parametru opțional, query în metodă se transmite cheia sau obiectul IDBKeyRange, care definește un interval de chei. În acest caz, cursorul va trece doar prin obiectele cu aceste chei. Dacă acest parametru nu este specificat, cursorul trece prin toate obiectele.
Al treilea parametru, direction, definește direcția cursorului și poate avea următoarele valori:
- next: cursorul începe parcurgerea obiectelor de la începutul depozitului în ordinea crescătoare a cheilor. Cursorul returnează toate înregistrările din depozit, inclusiv duplicatele. Aceasta este valoarea implicită
- nextunique: cursorul începe parcurgerea obiectelor de la începutul depozitului în ordinea crescătoare a cheilor. Cursorul returnează toate înregistrările din depozit, excluzând duplicatele
- prev: cursorul începe parcurgerea obiectelor de la începutul depozitului în ordinea descrescătoare a cheilor. Cursorul returnează toate înregistrările din depozit, inclusiv duplicatele
- prevunique: cursorul începe parcurgerea obiectelor de la începutul depozitului în ordinea descrescătoare a cheilor. Cursorul returnează toate înregistrările din depozit, excluzând duplicatele
Metoda openCursor() returnează un obiect IDBRequest. La obținerea cu succes a cursorului, la IDBRequest se declanșează evenimentul success, iar proprietatea sa result reprezintă fie valoarea IDBCursorWithValue (dacă cursorul a găsit obiecte în depozit), fie null (dacă nu există obiecte pentru cursor). Dacă cursorul nu poate fi obținut, se generează evenimentul error, iar proprietatea error a obiectului IDBRequest conține informații despre eroare. Pentru a gestiona aceste evenimente, se pot utiliza, respectiv, proprietățile onsuccess și onerror.
La deschiderea cu succes a cursorului și prezența obiectelor în depozit pentru iterare, proprietatea result a obiectului IDBRequest stochează valoarea IDBCursorWithValue - acesta este chiar cursorul:
const request = indexedDB.open("test", 6); // Conectăm la baza de date "test"
// La crearea sau modificarea versiunii bazei de date, creăm depozitul "users"
request.onupgradeneeded = (event) => {
const db = event.target.result; // Obținem baza de date
// Recreăm depozitul "users" - îl ștergem mai întâi dacă există
db.deleteObjectStore("users");
// Cheia este proprietatea "id", și este autoincrementată
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});
};
// La deschiderea bazei de date, obținem un cursor
request.onsuccess = (event) => {
const db = event.target.result; // Obținem baza de date
const transaction = db.transaction(["users"]); // Creăm o tranzacție
const userStore = transaction.objectStore("users"); // Obținem depozitul "users"
const cursorRequest = userStore.openCursor(); // Obținem o solicitare pentru deschiderea unui cursor
// Obținem cursorul
cursorRequest.onsuccess = () => {
const cursor = cursorRequest.result; // Poate fi obținut și prin event.target.result
console.log(cursor);
}
cursorRequest.onerror = () => console.log(cursorRequest.error);
};
La obținerea cu succes a cursorului, proprietatea key a obiectului IDBCursorWithValue va conține cheia primului obiect din depozit, iar proprietatea value va conține obiectul însuși.
request.onsuccess = (event) => {
const db = event.target.result; // Obținem baza de date
const transaction = db.transaction(["users"]); // Creăm o tranzacție
const userStore = transaction.objectStore("users"); // Obținem depozitul "users"
const cursorRequest = userStore.openCursor(); // Obținem o solicitare pentru deschiderea unui cursor
// Obținem cursorul
cursorRequest.onsuccess = () => {
const cursor = cursorRequest.result; // De asemenea, poate fi obținut prin event.target.result
const user = cursor.value; // Obținem valoarea la care indică cursorul
console.log(user.id); // Acesta este și cursor.key
console.log(user.name);
console.log(user.age);
}
};
Metoda continue() determină cursorul să se deplaseze la următoarea înregistrare (dacă există), ceea ce duce la reexecutarea handlerului onsuccess și așa mai departe. De exemplu, pentru a obține toate obiectele din depozitul users:
const request = indexedDB.open("test", 6); // Ne conectăm la baza de date "test"
// La crearea sau modificarea versiunii bazei de date, creăm depozitul "users"
request.onupgradeneeded = (event) => {
const db = event.target.result; // Obținem baza de date
// Recreăm depozitul "users" - îl ștergem mai întâi dacă există
db.deleteObjectStore("users");
// Cheia este proprietatea "id", și este autoincrementată
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});
};
// La deschiderea bazei de date
request.onsuccess = (event) => {
const db = event.target.result; // Obținem baza de date
const transaction = db.transaction(["users"]); // Creăm o tranzacție
const userStore = transaction.objectStore("users"); // Obținem depozitul "users"
const cursorRequest = userStore.openCursor(); // Obținem o solicitare pentru deschiderea unui cursor
const users = []; // Array în care citim datele
// Obținem cursorul
cursorRequest.onsuccess = () => {
const cursor = cursorRequest.result; // De asemenea, poate fi obținut prin event.target.result
if(cursor){ // Dacă mai sunt date de citit
const user = cursor.value;
users.push(user); // Adăugăm obiectul obținut în array
cursor.continue(); // Mutăm cursorul la următoarea înregistrare
}
else{
console.log(users); // Dacă nu mai sunt înregistrări de citit, afișăm array-ul
}
}
cursorRequest.onerror = () => console.log(cursorRequest.error);
};
În acest caz, cât timp există date de citit, le citim și le adăugăm în array-ul users. Când toate datele au fost citite, afișăm array-ul pe consolă.