MySQL Java JavaScript PHP Python HTML-CSS C-sharp

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ă.

← Lecția anterioară Lecția următoare →