Start · Sprachen · JavaScript · Referenz · IDBCursor.source

IDBCursor.source

Eigenschaft

Schreibgeschützte Eigenschaft, die den <code>IDBObjectStore</code> oder <code>IDBIndex</code> liefert, über den der Cursor iteriert.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

IDBCursor.source

Beschreibung

Die Eigenschaft source eines IDBCursor (bzw. IDBCursorWithValue) verweist auf das Objekt, auf dem der Cursor geöffnet wurde. Wurde er mit IDBObjectStore.openCursor() oder openKeyCursor() erzeugt, ist das ein IDBObjectStore. Wurde er mit IDBIndex.openCursor() oder openKeyCursor() erzeugt, ist es ein IDBIndex.

Nützlich ist das vor allem in allgemein gehaltenen Hilfsfunktionen, die einen Cursor als Argument bekommen und nicht wissen, woher er stammt. Über cursor.source kommt man an den Namen des Stores oder Index, am Index an keyPath oder über source.objectStore an den zugehörigen Object Store.

Die Eigenschaft ist nur lesbar und bleibt für den Cursor immer gleich. Sie gibt nie null zurück, solange der Cursor existiert. Auf den zurückgegebenen Store oder Index kann man aber nur zugreifen, solange die zugehörige Transaktion aktiv ist.

Rückgabewert

Typ
IDBObjectStore | IDBIndex
Beschreibung
Der Object Store oder Index, auf dem der Cursor geöffnet wurde.

Beispiele

Quelle eines Store-Cursors ausgeben

const request = indexedDB.open('shop', 1);

request.onupgradeneeded = () => {
  const db = request.result;
  const store = db.createObjectStore('produkte', { keyPath: 'id' });
  store.createIndex('nachPreis', 'preis');
  store.add({ id: 1, name: 'Tasse', preis: 8 });
  store.add({ id: 2, name: 'Teller', preis: 12 });
};

request.onsuccess = () => {
  const db = request.result;
  const tx = db.transaction('produkte', 'readonly');
  const store = tx.objectStore('produkte');

  store.openCursor().onsuccess = (event) => {
    const cursor = event.target.result;
    if (!cursor) return;
    console.log(cursor.source instanceof IDBObjectStore, cursor.source.name);
    cursor.continue();
  };
};
true "produkte" true "produkte"

Allgemeine Hilfsfunktion: Store oder Index erkennen

// Gibt für jeden Cursor aus, woher er stammt
const beschreibeQuelle = (cursor) => {
  const { source } = cursor;
  if (source instanceof IDBIndex) {
    return `Index "${source.name}" auf Store "${source.objectStore.name}" (keyPath: ${source.keyPath})`;
  }
  return `Object Store "${source.name}"`;
};

const request = indexedDB.open('shop', 1);
request.onsuccess = () => {
  const db = request.result;
  const tx = db.transaction('produkte');
  const index = tx.objectStore('produkte').index('nachPreis');

  index.openCursor().onsuccess = (event) => {
    const cursor = event.target.result;
    if (cursor) {
      console.log(beschreibeQuelle(cursor), cursor.value.name);
      cursor.continue();
    }
  };
};
Index "nachPreis" auf Store "produkte" (keyPath: preis) Tasse Index "nachPreis" auf Store "produkte" (keyPath: preis) Teller

Über einen Index-Cursor Datensätze löschen

// Löscht alle Produkte unter 10 € über den Preis-Index
const loescheGuenstige = (db) => new Promise((resolve, reject) => {
  const tx = db.transaction('produkte', 'readwrite');
  const range = IDBKeyRange.upperBound(10, true);

  tx.objectStore('produkte').index('nachPreis').openCursor(range).onsuccess = (event) => {
    const cursor = event.target.result;
    if (!cursor) return;
    // cursor.primaryKey passt zum Store, der hinter source.objectStore steht
    console.log('Lösche', cursor.primaryKey, 'aus', cursor.source.objectStore.name);
    cursor.delete();
    cursor.continue();
  };

  tx.oncomplete = () => resolve();
  tx.onerror = () => reject(tx.error);
});
Lösche 1 aus produkte

// Wichtig · Fallstricke

  • Schreibgeschützt: Wenn man cursor.source etwas zuweist, wird das ignoriert (im Strict Mode gibt es einen TypeError). Um eine andere Quelle zu nutzen, muss man einen neuen Cursor öffnen.
  • Transaktion muss aktiv sein: Hebt man source auf und ruft es später auf, etwa nach einem await oder in einem setTimeout, gibt es einen TransactionInactiveError, denn IndexedDB-Transaktionen werden automatisch abgeschlossen.
  • Typ prüfen: Store und Index bieten unterschiedliche Eigenschaften (objectStore, unique und multiEntry gibt es nur am Index). Deshalb vorher mit instanceof IDBIndex unterscheiden.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt, auch in Web Workern. In Node.js gibt es IndexedDB nicht von Haus aus, dafür braucht man z. B. fake-indexeddb.