IndexedDB ile çalışma

Bu kılavuz, IndexedDB API. Jake Archibald'ın IndexedDB Promized çok benzer bir işleve sahip olan IndexedDB API'sine çok benzeyen ancak Daha kısa ve öz söz dizimi için await. Bu hem API’yi basitleştirir hem de nasıl koruyoruz?

IndexedDB nedir?

IndexedDB, yalnızca Tarayıcı'daki herhangi bir şey hakkında. Her zamanki aramanızın yanı sıra, Dizine ekleme işlemleri yürütüldüğünde, IndexedDB işlemleri de destekler ve hem büyük miktarda yapılandırılmış verinin depolanmasıdır.

Her IndexedDB veritabanı bir kaynak için benzersizdir (genellikle sitenin alan adı veya alt alan adı) (yani alan adına erişemez veya ulaşılamaz) başka bir kaynak. Veri depolama sınırları büyük olsalar da genellikle büyüktür ancak sınırları farklı tarayıcılar yönetir için farklı işlemler yapmanız gerekir. Daha fazla bilgi için Daha fazla bilgi daha fazla bilgi edinin.

IndexedDB terimleri

Veritabanı
IndexedDB'nin en yüksek düzeyi. Nesne depolarını içerir. Bu da kalıcı olmasını istediğiniz verileri içerir. Aynı e-posta adresini kullanarak birden fazla istediğiniz adı verebilirsiniz.
Nesne deposu
İlişkisel veritabanlarındaki tablolara benzer şekilde, verileri depolamak için ayrı bir paket. Genellikle her tür için bir nesne deposu vardır (JavaScript verileri değil). veri türü) olduğunu unutmayın. Veritabanı tablolarından farklı olarak, JavaScript verileri veri türlerinin tutarlı olması gerekmez. Örneğin, olmak üzere üç kişiyle ilgili bilgileri içeren bir people nesne deposuna sahip. kullanıcıların yaş özellikleri 53, 'twenty-five' ve unknown olabilir.
Dizin
Verileri başka bir nesne deposunda düzenlemek için kullanılan bir tür nesne deposu (veri kaynağı olarak adlandırılır) referans nesne deposu) verilerin ayrı bir özelliğine göre oluşturulur. Dizin kullanılır kullanabilirsiniz. Örneğin projenin zamanlamasıyla ilgili istiyorsanız daha sonra bu kişileri adlarını, yaşlarını veya en sevdiğimiz hayvanı bulmak.
İşlem
Veritabanıyla etkileşim.
İşlem
Bir işlemin veya işlem grubunun etrafında, veritabanının bütünlüğüdür. İşlemdeki işlemlerden biri başarısız olursa bunların hiçbiri uygulanır ve veritabanı işlemden önceki durumuna döner. başladı. IndexedDB'deki tüm okuma veya yazma işlemleri bir işlemin parçası olmalıdır. Bu, çakışma riski olmadan atomik okuma-değiştirme-yazma işlemlerine olanak tanır aynı anda veritabanı üzerinde işlem yapan diğer iş parçacıkları ile yapılır.
İmleç
Veritabanında birden fazla kaydı yineleme mekanizması.

IndexedDB desteği nasıl kontrol edilir?

IndexedDB neredeyse evrensel olarak desteklenmektedir. Bununla birlikte, eski tarayıcılarla çalışıyorsanız, her ihtimale karşı özellik algılama desteğinden yararlanın. En kolay yol window kontrol etmektir nesne:

function indexedDBStuff () {
  // Check for IndexedDB support:
  if (!('indexedDB' in window)) {
    // Can't use IndexedDB
    console.log("This browser doesn't support IndexedDB");
    return;
  } else {
    // Do IndexedDB stuff here:
    // ...
  }
}

// Run IndexedDB code:
indexedDBStuff();

Veritabanı açma

IndexedDB ile istediğiniz ada sahip birden fazla veritabanı oluşturabilirsiniz. Eğer onu açmaya çalıştığınızda veritabanının mevcut olmadığını otomatik olarak oluşturulur. Bir veritabanını açmak için idb kitaplığından openDB() yöntemini kullanın:

import {openDB} from 'idb';

async function useDB () {
  // Returns a promise, which makes `idb` usable with async-await.
  const dbPromise = await openDB('example-database', version, events);
}

useDB();

Bu yöntem, bir veritabanı nesnesine çözümlenen bir taahhüt döndürür. openDB() yöntemini kullanın, ayarlanacak bir ad, sürüm numarası ve etkinlikler nesnesi sağlayın gözden geçireceğiz.

openDB() yönteminin bağlam içindeki bir örneğini aşağıda bulabilirsiniz:

import {openDB} from 'idb';

async function useDB () {
  // Opens the first version of the 'test-db1' database.
  // If the database does not exist, it will be created.
  const dbPromise = await openDB('test-db1', 1);
}

useDB();

IndexedDB desteği kontrolünü anonim işlevin en üstüne yerleştirin. Bu tarayıcı IndexedDB'yi desteklemiyorsa işlevden çıkar. Fonksiyon devam ederse 'test-db1' adlı bir veritabanı açmak için openDB() yöntemini çağırır. Bu örnekte, isteğe bağlı etkinlikler nesnesi, basittir, ancak IndexedDB ile anlamlı bir iş yapmak için bunu belirtmeniz gerekir.

Nesne depolarıyla nasıl çalışılır?

Bir IndexedDB veritabanı, her biri kendi dosyasına sahip bir veya daha fazla nesne deposu içerir. sütunu, o anahtarla ilişkili veriler için de başka bir sütun görürsünüz.

Nesne depoları oluşturma

İyi yapılandırılmış IndexedDB veritabanında her tür için bir nesne deposu olmalıdır. bir sürü veri var. Örneğin, profiller ve notların, person içeren bir people nesne deposu olabilir nesne ve note nesne içeren notes nesne deposu.

Veritabanı bütünlüğünü sağlamak için yalnızca şurada nesne depoları oluşturabilir veya kaldırabilirsiniz: etkinlikler nesnesini ifade eder.openDB() Etkinlik nesnesi bir upgrade() gösteriyor yöntemidir. Şunu çağırın: createObjectStore() yöntemini upgrade() yönteminde kullanarak nesne deposunu oluşturun:

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('example-database', 1, {
    upgrade (db) {
      // Creates an object store:
      db.createObjectStore('storeName', options);
    }
  });
}

createStoreInDB();

Bu yöntem nesne deposunun adını ve isteğe bağlı bir yapılandırmayı alır nesne deposu için çeşitli özellikler tanımlamanıza olanak tanıyan bir nesnedir.

Aşağıda, createObjectStore() özelliğinin nasıl kullanılacağına dair bir örnek verilmiştir:

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db1', 1, {
    upgrade (db) {
      console.log('Creating a new object store...');

      // Checks if the object store exists:
      if (!db.objectStoreNames.contains('people')) {
        // If the object store does not exist, create it:
        db.createObjectStore('people');
      }
    }
  });
}

createStoreInDB();

Bu örnekte, aşağıdakileri oluşturmak için openDB() yöntemine bir etkinlik nesnesi iletilir nesne deposu oluşturma işlemi tamamlandı. Daha önce olduğu gibi, nesne deposu oluşturma işlemi etkinliği nesnesinin upgrade() yönteminde bulunur. Ancak, tarayıcı bir hatasını görürseniz zaten var olan bir nesne deposu oluşturmaya createObjectStore() yöntemini bir if ifadesi içine sarmalama olup olmadığını kontrol edin. if blokun içinde, şunu ara: 'firstOS' adlı bir nesne deposu oluşturmak için createObjectStore().

Birincil anahtarları tanımlama

Nesne depolarını tanımladığınızda, belirli bir projede verilerin nasıl birincil anahtar kullanarak mağazayı kontrol edin. Birincil anahtar, anahtar yolunu izleyerek veya bir anahtar oluşturucu kullanarak.

Anahtar yolu, her zaman var olan ve benzersiz bir değer içeren bir özelliktir. Örneğin, Örneğin, people nesne deposu söz konusu olduğunda, adresini anahtar yolu olarak ayarlayın:

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        db.createObjectStore('people', { keyPath: 'email' });
      }
    }
  });
}

createStoreInDB();

Bu örnek, 'people' adında bir nesne deposu oluşturur ve email özelliğini keyPath seçeneğinde birincil anahtar olarak ayarlayın.

autoIncrement gibi bir anahtar oluşturma aracı da kullanabilirsiniz. Anahtar oluşturma aracı nesne deposuna eklenen her nesne için benzersiz bir değer oluşturur. Varsayılan olarak bir anahtar belirtmezseniz IndexedDB bir anahtar oluşturur ve bunu ayrı olarak depolar bu verilerden ayırt edebilmelisiniz.

Aşağıdaki örnek, 'notes' adında bir nesne deposu oluşturur ve birincil anahtar otomatik artan sayı şeklinde otomatik olarak atanacaktır:

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('notes')) {
        db.createObjectStore('notes', { autoIncrement: true });
      }
    }
  });
}

createStoreInDB();

Aşağıdaki örnek bir önceki örneğe benziyor, ancak bu kez otomatik artan değer açıkça 'id' adlı bir özelliğe atandı.

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('logs')) {
        db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createStoreInDB();

Anahtarı tanımlamak için kullanılacak yöntemi seçmek, verilerinize bağlıdır. Eğer verilerinin her zaman benzersiz bir özelliği olduğundan, bunu keyPath uygulayacaksınız. Aksi takdirde otomatik artan bir değer kullanın.

Aşağıdaki kod, farklı veri işleme yöntemlerinin çeşitli yollarını gösteren nesne depolarında birincil anahtarları tanımlama:

import {openDB} from 'idb';

async function createStoresInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        db.createObjectStore('people', { keyPath: 'email' });
      }

      if (!db.objectStoreNames.contains('notes')) {
        db.createObjectStore('notes', { autoIncrement: true });
      }

      if (!db.objectStoreNames.contains('logs')) {
        db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createStoresInDB();

Dizinleri tanımlama

Dizinler, referanstan veri almak için kullanılan bir nesne deposu türüdür. nesne deposunu tanımlamaya çalışın. Bir dizin, referans nesnenin içinde bulunur depoladığını ve aynı verileri içerdiğini ancak belirtilen özelliği anahtar yolunu izleyerek kaynak kodunu kullanın. Dizinler şu durumlarda oluşturulmalıdır: nesne depolarınızı oluşturursunuz ve bu, nesneyle ilgili benzersiz bir kısıtlama tanımlamak için verileriniz.

Dizin oluşturmak için createIndex() öğesini çağırın yöntemini kullanabilirsiniz:

import {openDB} from 'idb';

async function createIndexInStore() {
  const dbPromise = await openDB('storeName', 1, {
    upgrade (db) {
      const objectStore = db.createObjectStore('storeName');

      objectStore.createIndex('indexName', 'property', options);
    }
  });
}

createIndexInStore();

Bu yöntem bir dizin nesnesi oluşturur ve döndürür. Şu sayfadaki createIndex() yöntemi: nesne deposunun örneği ilk olarak yeni dizinin adını alır bağımsız değişkeni, ikinci bağımsız değişken ise her bir bağımsız değişkende dizin. Son bağımsız değişken, her bir değişken için en iyi performansı nasıl şu dizin çalışır: unique ve multiEntry. unique, true değerine ayarlanırsa dizini tek bir anahtar için yinelenen değerlere izin vermez. Sonraki, multiEntry dizine eklenen mülk bir dizi olduğunda createIndex() öğesinin nasıl davranacağını belirler. Eğer true olarak ayarlanırsa createIndex() her dizi için dizine bir giriş ekler öğesine dokunun. Aksi takdirde, diziyi içeren tek bir giriş ekler.

Aşağıda bununla ilgili bir örnek verilmiştir:

import {openDB} from 'idb';

async function createIndexesInStores () {
  const dbPromise = await openDB('test-db3', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        const peopleObjectStore = db.createObjectStore('people', { keyPath: 'email' });

        peopleObjectStore.createIndex('gender', 'gender', { unique: false });
        peopleObjectStore.createIndex('ssn', 'ssn', { unique: true });
      }

      if (!db.objectStoreNames.contains('notes')) {
        const notesObjectStore = db.createObjectStore('notes', { autoIncrement: true });

        notesObjectStore.createIndex('title', 'title', { unique: false });
      }

      if (!db.objectStoreNames.contains('logs')) {
        const logsObjectStore = db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createIndexesInStores();

Bu örnekte, 'people' ve 'notes' nesne depoları dizinlere sahip. Alıcı: dizinleri oluşturun, önce createObjectStore() işlevinin sonucunu atayın (bir nesne Store nesnesi) bir değişkene ekleyebilirsiniz. Böylece, söz konusu değişken üzerinde createIndex() çağırabilirsiniz.

Verilerle çalışma

Bu bölümde verilerin nasıl oluşturulacağı, okunacağı, güncelleneceği ve silineceği açıklanmaktadır. Bu tüm işlemler eşzamansız olup IndexedDB API'nin kullandığı kabul edersiniz. Bu, API'yi basitleştirir. tarafından tetiklenen etkinlikleri dinlemek yerine, istekte bulunulduğunda, API'den döndürülen veritabanı nesnesinde .then() Veritabanıyla etkileşimleri başlatmak için openDB() yöntemini veya await çok önemli.

IndexedDB'deki tüm veri işlemleri bir işlem içinde gerçekleştirilir. Her biri işlemi aşağıdaki biçimdedir:

  1. Veritabanı nesnesini alın.
  2. Veritabanındaki işlemi açın.
  3. İşlemde nesne deposunu açın.
  4. Nesne deposunda işlem gerçekleştirin.

İşlem, bir işlem veya grubun güvenli bir sarmalayıcı olarak düşünülebilir. anlamına gelir. Bir işlemdeki işlemlerden biri başarısız olursa işlemleri geri alınır. İşlemler bir veya daha fazla nesne mağazasına özgüdür. (işlemi açtığınızda tanımlamanız gerekir.) Salt okunur veya okunabilir olabilirler yazmamız gerekecek. Bu, işlem içindeki işlemlerin veya veritabanında değişiklik yapabilirsiniz.

Veri oluşturma

Veri oluşturmak için add() numaralı telefonu arayın yöntemini çağırın ve eklemek istediğiniz verileri iletin. add() yönteminin ilk bağımsız değişkeni, verileri eklemek istediğiniz nesne deposudur. ikinci bağımsız değişken, istediğiniz alanları ve ilişkili verileri içeren bir nesnedir dokunun. Tek bir veri satırının eklendiği en basit örneği burada bulabilirsiniz:

import {openDB} from 'idb';

async function addItemToStore () {
  const db = await openDB('example-database', 1);

  await db.add('storeName', {
    field: 'data'
  });
}

addItemToStore();

Taahhüt gerçekleşse bile her add() araması işlem kapsamında gerçekleşir. işlemenin başarılı olduğu anlamına gelmez. Emin olmak için ekleme işlemi gerçekleştirildikten sonra, bu işlemin tamamının işlem, transaction.done() yöntemi kullanılarak tamamlandı. Bu, işlem tamamlandığında sonuçlandırılacağına dair taahhütte bulunur ve işlem hataları. Bu kontrolü tüm "yazma" işlemleri için gerçekleştirmeniz gerekir işlemleri, çünkü veritabanında yapılan değişikliklerin gerçekten yaşanmıştır.

Aşağıdaki kod, add() yönteminin bir işlem içinde kullanımını gösterir:

import {openDB} from 'idb';

async function addItemsToStore () {
  const db = await openDB('test-db4', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('foods')) {
        db.createObjectStore('foods', { keyPath: 'name' });
      }
    }
  });
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Add multiple items to the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.add({
      name: 'Sandwich',
      price: 4.99,
      description: 'A very tasty sandwich!',
      created: new Date().getTime(),
    }),
    tx.store.add({
      name: 'Eggs',
      price: 2.99,
      description: 'Some nice eggs you can cook up!',
      created: new Date().getTime(),
    }),
    tx.done
  ]);
}

addItemsToStore();

Veritabanını açtıktan (ve gerekirse nesne deposu oluşturduktan) sonra transaction() yöntemini çağırarak bir işlemi açın. Bu yöntem işlem yapmak istediğiniz mağaza ve mod için bir bağımsız değişken alır. Bu örnekte, mağazayla iletişime geçmek istediğimiz için bu örnekteki 'readwrite' belirtir.

Bir sonraki adım, işlemin bir parçası olarak ürünleri mağazaya eklemeye başlamaktır. Yukarıdaki örnekte, 'foods' üzerindeki üç işlemi ele alıyoruz. bir vaat döndüren mağaza sayısını artırır:

  1. Lezzetli bir sandviç için bir rekor ekleniyor.
  2. Birkaç yumurtanın kaydı ekleniyor.
  3. İşlemin tamamlandığını belirten bir işaret (tx.done).

Tüm bu eylemler vaatlere dayalı olduğundan tüm işlemlerin tamamlanmasını beklememiz gerekir. Bu vaatleri yerine getirecek Promise.all bunun güzel ve ergonomik bir yoludur. Promise.all, taahhüt edilen tüm vaatler yerine getirildiğinde taahhüt eder ve bitirir.

Eklenen iki kayıt için işlem örneğinin store arayüzü add() işlevini çağırır ve verileri bu cihaza iletir. Promise.all araması için await işlemi gerçekleştirebilirsiniz işlem tamamlandığında da tamamlanır.

Verileri okuma

Verileri okumak için get() numaralı telefonu arayın yöntemini openDB() yöntemini kullanarak aldığınız veritabanı örneğinde tutar. get(), mağazanın adını ve depoladığınız nesnenin birincil anahtar değerini alır belirir. Aşağıda temel bir örnek verilmiştir:

import {openDB} from 'idb';

async function getItemFromStore () {
  const db = await openDB('example-database', 1);

  // Get a value from the object store by its primary key value:
  const value = await db.get('storeName', 'unique-primary-key-value');
}

getItemFromStore();

add() yönteminde olduğu gibi get() yöntemi de bir vaat döndürür. Böylece şu durumda await işlemini yapabilirsiniz: ya da taahhütteki .then() geri arama özelliğini kullanın.

Aşağıdaki örnekte 'test-db4' veritabanında get() yöntemi kullanılmaktadır 'foods' nesne deposunu kullanarak 'name' birincil anahtarıyla tek bir satır alın:

import {openDB} from 'idb';

async function getItemFromStore () {
  const db = await openDB('test-db4', 1);
  const value = await db.get('foods', 'Sandwich');

  console.dir(value);
}

getItemFromStore();

Veritabanından tek bir satır almak oldukça kolaydır: açık ve nesne deposunu ve birincil anahtar değerini belirterek almak istediğiniz e-postadır. get() yöntemi bir söz döndürdüğü için await.

Verileri güncelle

Verileri güncellemek için put() numaralı telefonu arayın yöntemini kullanabilirsiniz. put() yöntemi, add() yöntemine benzer ve veri oluşturmak için add() yerine kullanılabilir. Elektronik tablo kullanarak yapılmış put() kullanarak nesne deposundaki bir satırı birincil anahtar değerine göre güncelleyebilirsiniz:

import {openDB} from 'idb';

async function updateItemInStore () {
  const db = await openDB('example-database', 1);

  // Update a value from in an object store with an inline key:
  await db.put('storeName', { inlineKeyName: 'newValue' });

  // Update a value from in an object store with an out-of-line key.
  // In this case, the out-of-line key value is 1, which is the
  // auto-incremented value.
  await db.put('otherStoreName', { field: 'value' }, 1);
}

updateItemInStore();

Diğer yöntemler gibi bu yöntem de umut veriyor. Ayrıca put() adresini şu şekilde de kullanabilirsiniz: olduğunu unutmayın. Aşağıda, daha önceki 'foods' mağazasının kullanıldığı bir örnek verilmiştir: sandviç ve yumurtanın fiyatını güncelleyen bir metin yazın:

import {openDB} from 'idb';

async function updateItemsInStore () {
  const db = await openDB('test-db4', 1);
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Update multiple items in the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.put({
      name: 'Sandwich',
      price: 5.99,
      description: 'A MORE tasty sandwich!',
      updated: new Date().getTime() // This creates a new field
    }),
    tx.store.put({
      name: 'Eggs',
      price: 3.99,
      description: 'Some even NICER eggs you can cook up!',
      updated: new Date().getTime() // This creates a new field
    }),
    tx.done
  ]);
}

updateItemsInStore();

Öğelerin güncellenme şekli, anahtarı nasıl ayarladığınıza bağlıdır. Bir keyPath ayarlarsanız nesne deposundaki her satır bir satır içi anahtarla ilişkilendirilir. Önceki örnek, satırları bu anahtara göre günceller ve bu anahtardaki satırları güncellediğinizde uygun öğeyi güncellemek için bu anahtarı belirtmeniz kullanabilirsiniz. İsterseniz bir satır dışı anahtar autoIncrement birincil anahtar olacak.

Verileri sil

Verileri silmek için delete() numaralı telefonu arayın yöntemini kullanabilirsiniz:

import {openDB} from 'idb';

async function deleteItemFromStore () {
  const db = await openDB('example-database', 1);

  // Delete a value 
  await db.delete('storeName', 'primary-key-value');
}

deleteItemFromStore();

add() ve put() gibi, bunu bir işlemin parçası olarak kullanabilirsiniz:

import {openDB} from 'idb';

async function deleteItemsFromStore () {
  const db = await openDB('test-db4', 1);
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Delete multiple items from the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.delete('Sandwich'),
    tx.store.delete('Eggs'),
    tx.done
  ]);
}

deleteItemsFromStore();

Veritabanı etkileşiminin yapısı, diğer anlamına gelir. Tüm işlemin Google Ads tarafından Promise.all öğesine ilettiğiniz dizideki tx.done yöntemi dahil.

Tüm verileri alma

Şu ana kadar mağazadan her defasında yalnızca bir nesne aldınız. Ayrıca transkriptinizi bir nesne deposundan veya dizinden tüm verileri veya bir alt kümeyi almak için getAll() yöntemini veya imleçleri kullanabilirsiniz.

getAll() yöntemi

Bir nesne deposunun tüm verilerini almanın en basit yolu getAll() çağrısı yapmaktır veya dizinde şunun gibi:

import {openDB} from 'idb';

async function getAllItemsFromStore () {
  const db = await openDB('test-db4', 1);

  // Get all values from the designated object store:
  const allValues = await db.getAll('storeName');

  console.dir(allValues);
}

getAllItemsFromStore();

Bu yöntem, herhangi bir kısıtlama olmadan nesne deposundaki tüm nesneleri döndürür her şey. Bu, bir nesne deposundan tüm değerleri almanın en doğrudan yoludur. aynı zamanda en az esnek olanıdır.

import {openDB} from 'idb';

async function getAllItemsFromStore () {
  const db = await openDB('test-db4', 1);

  // Get all values from the designated object store:
  const allValues = await db.getAll('foods');

  console.dir(allValues);
}

getAllItemsFromStore();

Bu örnek, 'foods' nesne deposunda getAll() öğesini çağırır. Bu, şunları döndürür: birincil anahtara göre sıralanmış 'foods' öğeleri.

İmleçler nasıl kullanılır?

İmleçler, birden çok nesneyi almak için daha esnek bir yöntemdir. İmleç seçilir nesne deposundaki her bir nesneyi tek tek dizine ekleyerek istediğiniz işlemi yapabilirsiniz. verileri de içerecek şekilde hazırlar. İmleçler, diğer veritabanı işlemlerinde olduğu gibi işlemler üzerinde çalışır.

İmleç oluşturmak için openCursor() numaralı telefonu arayın değişiklik yapmayın. Şuradaki 'foods' mağazası kullanılıyor: Örneğin, imleç Google Cloud'daki tüm veri satırlarında bir nesne deposudur:

import {openDB} from 'idb';

async function getAllItemsFromStoreWithCursor () {
  const db = await openDB('test-db4', 1);
  const tx = await db.transaction('foods', 'readonly');

  // Open a cursor on the designated object store:
  let cursor = await tx.store.openCursor();

  // Iterate on the cursor, row by row:
  while (cursor) {
    // Show the data in the row at the current cursor position:
    console.log(cursor.key, cursor.value);

    // Advance the cursor to the next row:
    cursor = await cursor.continue();
  }
}

getAllItemsFromStoreWithCursor();

Bu durumda işlem 'readonly' modunda açılır ve openCursor yöntemi çağrılır. Sonraki bir while döngüsünde, imlecin geçerli konumunda key ve value özellikleri okunabilir ve Bu değerler üzerinde, işletmeniz açısından en anlamlı olan şekilde uygulamasını indirin. Hazır olduğunuzda cursor nesnesinin continue() öğesini çağırabilirsiniz. yöntemini kullanabilirsiniz ve imleç açıldığında while döngüsü sona erer veri kümesinin sonuna ulaştığından emin olun.

Aralık ve dizinlerle imleç kullanma

Dizinler, bir nesne deposundaki verileri birincil anahtardır. Herhangi bir mülkte bir dizin oluşturabilirsiniz. Bu dizin, keyPath olur için, bu mülkte bir aralık belirtin ve verileri aralığı, getAll() veya imleç kullanarak görebilirsiniz.

IDBKeyRange nesnesini kullanarak aralığınızı tanımlayın. ve aşağıdakilerden herhangi biri yöntemleri:

upperBound() ve lowerBound() yöntemleri üst ve alt sınırları belirtir değer aralığı.

IDBKeyRange.lowerBound(indexKey);

veya:

IDBKeyRange.upperBound(indexKey);

Her biri bir bağımsız değişken alır: istediğiniz öğe için dizinin keyPath değeri üst veya alt sınır olarak belirleyin.

bound() yöntemi hem üst hem de alt sınır belirtir:

IDBKeyRange.bound(lowerIndexKey, upperIndexKey);

Bu işlevlerin aralığı varsayılan olarak kapsayıcıdır, yani aralığın sınırları olarak belirtilen verilerdir. Bu değerleri hariç tutmak için true değerini, lowerBound() veya upperBound() ya da üçüncü ve dördüncü bağımsız değişkenler olarak Sırasıyla alt ve üst sınırlar için bound().

Sonraki örnek, 'foods' nesnesindeki 'price' özelliğinde yer alan bir dizin kullanır mağaza. Mağazada artık iki girişin yer aldığı bir form da bulunuyor: üst ve alt sınırlarını içerir. Şu yemeği içeren yiyecekleri bulmak için aşağıdaki kodu kullanın: fiyatlar arasında geçiş yapmanız gerekir:

import {openDB} from 'idb';

async function searchItems (lower, upper) {
  if (!lower === '' && upper === '') {
    return;
  }

  let range;

  if (lower !== '' && upper !== '') {
    range = IDBKeyRange.bound(lower, upper);
  } else if (lower === '') {
    range = IDBKeyRange.upperBound(upper);
  } else {
    range = IDBKeyRange.lowerBound(lower);
  }

  const db = await openDB('test-db4', 1);
  const tx = await db.transaction('foods', 'readonly');
  const index = tx.store.index('price');

  // Open a cursor on the designated object store:
  let cursor = await index.openCursor(range);

  if (!cursor) {
    return;
  }

  // Iterate on the cursor, row by row:
  while (cursor) {
    // Show the data in the row at the current cursor position:
    console.log(cursor.key, cursor.value);

    // Advance the cursor to the next row:
    cursor = await cursor.continue();
  }
}

// Get items priced between one and four dollars:
searchItems(1.00, 4.00);

Örnek kod, ilk olarak sınırlara ilişkin değerleri alır ve sınırların bulunur. Bir sonraki kod bloğu, aralığı sınırlandırmak için hangi yöntemin kullanılacağını belirler değerler temel alınarak oluşturulur. Veritabanı etkileşiminde, işlemi normal şekilde yapın ve ardından nesne deposunda 'price' dizinini açın. İlgili içeriği oluşturmak için kullanılan 'price' dizininde ürünleri fiyata göre arayabilirsiniz.

Daha sonra kod, dizinde bir imleç açar ve aralığın içine geçer. İmleç aralıktaki ilk nesneyi temsil eden bir vaat veya aralıktaki ilk nesneyi temsil eden bir söz döndürürse undefined aralığında veri yok. cursor.continue() yöntemi, gösteren imleçtir ve siz bu işlemi gerçekleştirene kadar döngüde devam eder. aralığın sonuna ulaşırız.

Veritabanı sürümü oluşturma

openDB() yöntemini çağırırken veritabanı sürüm numarasını belirtebilirsiniz değerini girin. Bu kılavuzdaki tüm örneklerde, sürüm 1 olarak ayarlandı. Ancak isterseniz veritabanı yeni bir sürüme yükseltilebilir. bir şekilde değiştiremiyorsunuz. Belirtilen sürüm, varsa, etkinlik nesnesindeki upgrade geri çağırması yürütülür, Böylece veritabanına yeni nesne depoları ve dizinler ekleyebilirsiniz.

upgrade geri çağırmasındaki db nesnesinin özel bir oldVersion özelliği var. Bu, tarayıcının erişebildiği veritabanının sürüm numarasını gösterir. Şu sürüm numarasını bir switch deyimine ileterek şu blokları yürütebilirsiniz: Mevcut veritabanı sürümüne göre upgrade geri çağırması içindeki kod sayı. Aşağıda bununla ilgili bir örnek verilmiştir:

import {openDB} from 'idb';

const db = await openDB('example-database', 2, {
  upgrade (db, oldVersion) {
    switch (oldVersion) {
      case 0:
        // Create first object store:
        db.createObjectStore('store', { keyPath: 'name' });

      case 1:
        // Get the original object store, and create an index on it:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('name', 'name');
    }
  }
});

Bu örnekte, veritabanının en yeni sürümü 2 olarak ayarlanmaktadır. Bu kod ilk çalıştırıldığında, veritabanı henüz tarayıcıda mevcut değildir. Bu nedenle oldVersion 0 ve switch ifadesi case 0 tarihinde başlıyor. Örnekte bu, veritabanına bir 'store' nesne deposu ekler.

Önemli nokta: switch ifadelerinde genellikle her case sonrasında bir break bulunur ancak bu burada kasıtlı olarak kullanılmıyor. Bu şekilde, veritabanı birkaç sürüm gerideyse veya yoksa kod yoksa tamamlanana kadar case blok boyunca uygulayın. Örnekte, tarayıcı case 1 boyunca yürütmeye devam ederekname store nesne deposu.

'store' nesne deposunda bir 'description' dizini oluşturmak için şunu güncelleyin: sürüm numarası ve aşağıdaki gibi yeni bir case bloğu ekleyin:

import {openDB} from 'idb';

const db = await openDB('example-database', 3, {
  upgrade (db, oldVersion) {
    switch (oldVersion) {
      case 0:
        // Create first object store:
        db.createObjectStore('store', { keyPath: 'name' });

      case 1:
        // Get the original object store, and create an index on it:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('name', 'name');

      case 2:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('description', 'description');
    }
  }
});

Önceki örnekte oluşturduğunuz veritabanı tarayıcıda hâlâ mevcutsa Bu yürütüldüğünde oldVersion, 2 olur. Tarayıcı case 0 parametresini atlar ve case 1 ve case 2 içinde kodu yürüterek description oluşturur dizin. Bundan sonra, tarayıcının sürüm 3'te store içeren bir veritabanı olur nesne deposu olarak name ve description dizinlerini oluşturun.

Daha fazla bilgi

Aşağıdaki kaynaklar, IndexedDB kullanımı için daha fazla bilgi ve bağlam sağlamaktadır.

IndexedDB Belgeleri

Veri depolama sınırları