Start · Sprachen · JavaScript · Referenz · IDBDatabase.objectStoreNames

IDBDatabase.objectStoreNames

Eigenschaft

Schreibgeschützte <code>DOMStringList</code> mit den Namen aller Object Stores, die in der verbundenen IndexedDB-Datenbank gerade vorhanden sind.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

IDBDatabase.objectStoreNames

Beschreibung

Die schreibgeschützte Eigenschaft objectStoreNames einer IDBDatabase-Instanz liefert eine DOMStringList mit den Namen aller Object Stores der verbundenen Datenbank. Die Namen sind alphabetisch sortiert, genauer nach der Reihenfolge der UTF-16-Codeeinheiten.

Wichtigster Einsatzort ist der upgradeneeded-Handler von indexedDB.open(). Dort prüft man mit db.objectStoreNames.contains(name), ob ein Store schon existiert, bevor man createObjectStore() aufruft. Wird ein bereits vorhandener Name noch einmal angelegt, wirft der Aufruf eine ConstraintError-DOMException. Mit derselben Prüfung lassen sich idempotente Migrationen über mehrere Schema-Versionen schreiben.

Eine DOMStringList ist kein Array. Sie bietet nur length, item(index), contains(string) und den Zugriff per Index. Sie ist aber iterierbar, deshalb funktionieren for...of, der Spread-Operator und Array.from(). Brauchst du Array-Methoden wie map() oder filter(), wandle die Liste vorher um.

Außerhalb einer Versionsänderung bleibt die Liste für die bestehende Verbindung gleich. Object Stores lassen sich nur während einer versionchange-Transaktion anlegen oder löschen.

Rückgabewert

Typ
DOMStringList
Beschreibung
Eine nach Namen sortierte Liste der Object-Store-Namen. Sie bietet length, item() und contains() und ist iterierbar.

Beispiele

Object Store nur bei Bedarf anlegen (upgradeneeded)

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

request.onupgradeneeded = (event) => {
  const db = event.target.result;

  // Nur anlegen, wenn der Store noch fehlt – sonst ConstraintError
  if (!db.objectStoreNames.contains('produkte')) {
    db.createObjectStore('produkte', { keyPath: 'id' });
  }
  if (!db.objectStoreNames.contains('warenkorb')) {
    db.createObjectStore('warenkorb', { autoIncrement: true });
  }
};

request.onsuccess = (event) => {
  const db = event.target.result;
  console.log([...db.objectStoreNames]);
};
["produkte", "warenkorb"]

Alle Stores auflisten (Promise-Wrapper)

const openDB = (name) =>
  new Promise((resolve, reject) => {
    const req = indexedDB.open(name);
    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(req.error);
  });

const listStores = async (dbName) => {
  const db = await openDB(dbName);
  const names = Array.from(db.objectStoreNames);
  console.log(`${db.name} v${db.version}: ${names.length} Stores`);
  for (const name of names) console.log('–', name);
  db.close();
  return names;
};

listStores('shop');
shop v2: 2 Stores – produkte – warenkorb

Veralteten Store bei einer Migration entfernen

const req = indexedDB.open('shop', 3);

req.onupgradeneeded = (event) => {
  const db = event.target.result;

  if (db.objectStoreNames.contains('warenkorb')) {
    db.deleteObjectStore('warenkorb');
  }
  if (!db.objectStoreNames.contains('bestellungen')) {
    const store = db.createObjectStore('bestellungen', { keyPath: 'nr' });
    store.createIndex('datum', 'datum');
  }

  console.log(db.objectStoreNames.length, db.objectStoreNames.item(0));
};
2 bestellungen

Transaktion über alle Stores öffnen

const clearAll = (db) =>
  new Promise((resolve, reject) => {
    // DOMStringList wird von transaction() direkt akzeptiert
    const tx = db.transaction(db.objectStoreNames, 'readwrite');
    for (const name of db.objectStoreNames) {
      tx.objectStore(name).clear();
    }
    tx.oncomplete = () => resolve();
    tx.onerror = () => reject(tx.error);
  });

const req = indexedDB.open('shop');
req.onsuccess = async () => {
  await clearAll(req.result);
  console.log('Alle Stores geleert');
};
Alle Stores geleert

// Wichtig · Fallstricke

  • Kein Array: db.objectStoreNames.includes(), .map() oder .forEach() gibt es nicht. Nutze contains() oder wandle die Liste mit Array.from() bzw. [...liste] um.
  • Leere Liste: Wenn transaction() eine leere Liste bekommt (z. B. bei einer neuen Datenbank ohne Stores), wirft der Aufruf eine InvalidAccessError-DOMException. Prüfe deshalb vorher length > 0.
  • Nur Momentaufnahme pro Verbindung: Wenn ein anderer Tab die Datenbank auf eine neue Version hebt, sieht die bestehende Verbindung die neuen Stores nicht. Schließe sie im versionchange-Event und öffne sie neu.
  • Die Namen sind nach UTF-16-Codeeinheiten sortiert, nicht in der Reihenfolge, in der die Stores angelegt wurden. Großbuchstaben stehen deshalb vor Kleinbuchstaben.
  • Die Eigenschaft wird in allen aktuellen Browsern unterstützt, auch in Web Workern. Im privaten Modus älterer Firefox-Versionen war IndexedDB nicht verfügbar.