Progressive Web Apps(PWA)コアテクノロジ-Indexed DB
9130 ワード
使用中はhtml、css、jsなどのファイル情報をcacheキャッシュするのが一般的ですが、いくつかの特殊なデータはデータベースのサポートを借りる必要があります.ここではIndexedDBの使用をお勧めします.
IndexedDBは大規模なnoSQLストレージシステムです.これにより、ユーザーのブラウザに任意のコンテンツを格納できます.通常の検索、取得、および保存操作に加えて、IndexedDBはトランザクションをサポートします.
ブラウザがIndexedDBをサポートしているかどうかを確認します
データベースの作成IndexedDBを使用すると、複数のデータベースを作成できますが、原則としてアプリケーションごとに1つのデータベースを作成する必要があります.
name:データベース名、version:バージョン番号、upgradeCallback:コールバックメソッド
IndexedDBのオブジェクトストレージ
主に、データベースがコールバックで返されるインスタンスを作成してcreateObjectStoreメソッドを呼び出すことで、オブジェクトストレージを作成します.プライマリ・キーを定義し、自己増加を設定keyPathを使用してプライマリ・キーを定義し、autoIncrementを使用してプライマリ・キー自己増加を設定します. インデックス作成インデックスを定義し、オブジェクトストレージインスタンスでcreateIndexメソッドを呼び出す:
このメソッドはインデックスオブジェクトを作成して返します.createIndexは、新しいインデックスの名前を最初のパラメータとし、2番目のパラメータはインデックスするデータの属性を指します.最後のパラメータでは、インデックスがどのように動作するかを決定する2つのオプションを定義できます.uniqueとmultiEntryです.uniqueがtrueに設定されている場合、インデックスは単一のキーの重複値を許可しません.インデックス属性が配列である場合、multiEntryはcreateIndexの動作を決定します.trueに設定すると、createIndexは各配列要素のインデックスにエントリを追加します.そうでなければ、配列を含むエントリが追加されます.
注:インデックスは、リファレンス・オブジェクト・ライブラリにデータを書き込むたびに更新されます.インデックスが多いほどIndexedDBのワークロードが大きくなることを意味します.
IndexedDBのオペレーションデータIndexedDBのすべてのデータオペレーションは、1つのトランザクションで実行されます.各操作には、次のような形式があります.
1.データベース・オブジェクトを取得する2.データベース上でトランザクション3を開く.トランザクションでオブジェクトストレージ4を開く.オブジェクトストレージでのアクションの実行
データを書き込むデータを作成するには、オブジェクトストレージでaddメソッドを呼び出し、追加するデータを入力します.Addには、作成時に単一のオブジェクトにプライマリ・キーを定義できるオプションの2番目のパラメータがありますが、createObjectStoreでキー・パスを指定しない場合にのみ使用できます.
someObjectStore.add(data, optionalKey);
データを読み込むデータを読み込むには、オブジェクトストレージのgetメソッドを呼び出します.getメソッドは、ストレージから取得するオブジェクトのプライマリ・キーを使用します.
someObjectStore.get(primaryKey);
データを更新データを更新するには、オブジェクトストレージでputメソッドを呼び出します.putメソッドはaddメソッドとよく似ており、addの代わりにオブジェクトストレージにデータを作成するために使用できます.addのようにputのデータとオプションのプライマリ・キー:
someObjectStore.put(data, optionalKey);
データを削除するには、データを削除し、格納オブジェクトでdeleteメソッドを呼び出します.
someObjectStore.delete(primaryKey);
すべてのデータを取得
また、getAllメソッドを使用するか、カーソルを使用してオブジェクトストレージまたはインデックスからすべてのデータ(またはサブセット)を取得することもできます. getallメソッドを使用して、指定したキーまたはキー範囲に一致するオブジェクトストレージ内のすべてのオブジェクトを返します.
someObjectStore.getAll(optionalConstraint);カーソルを使用する別のデータを取得する方法は、カーソルを使用することです.カーソルは、オブジェクトストレージまたはインデックス内の各オブジェクトを1つずつ選択し、データを選択するときに操作を実行します.
someObjectStore.openCursor(optionalKeyRange, optionalDirection);
このメソッドはpromiseを返し、カーソルオブジェクトでオブジェクトストレージ内の最初のオブジェクトを表し、オブジェクトがない場合はundefinedを返します.オブジェクトストレージの次のオブジェクトに移動するにはcursorを呼び出します.continue.
まず、データベース・オブジェクトを取得し、トランザクションを作成し、オブジェクト・ストレージを開きます.オブジェクトストレージ上でopenCursorメソッドを呼び出し、カーソルオブジェクトを渡す.thenのコールバック関数.今回はコールバック関数を「logItems」と名付けたので、関数内部から呼び出してループすることができます.if(!cursor){return;}もしそうならOpenCursor()が返すpromiseはundefined,またはcursorとして解析される.continue()が返すpromiseはundefinedとして解析される(より多くのオブジェクトがないことを示す).
カーソルオブジェクトには、プロジェクトのプライマリ・キーを表すキー・プロパティが含まれます.また、データを表す値プロパティも含まれます.logItemsが終わるとcursorに戻ります.continue().then(logItems). cursor.continueメソッドは、store内の次のstoreを表すカーソルオブジェクトとして解析されるpromiseを返し、より多くのオブジェクトがない場合はundefinedを返します.この結果は伝えられた.thenのコールバック関数ではlogItemsをこの関数として選択し,関数がループする.したがって、logItemsはオブジェクトが保持されないまで自分を呼び出し続けます.
インデックスによる範囲内のデータの取得
すべてのデータを異なる方法で得ることができますが、特定の属性に基づくデータのサブセットしか必要ありませんか?インデックスを使用できます.インデックスでは、プライマリ・キー以外のプロパティからオブジェクト・ストレージのデータを取得します.任意のプロパティにインデックスを作成し、そのプロパティに範囲を指定し、getallメソッドまたはカーソルを使用して範囲内のデータを取得できます.
IDBKeyRangeオブジェクトを使用して範囲を定義します.このオブジェクトには、upperBound、lowerBound、bound(これは両方を意味する)、onlyの4つの方法があります.upperBoundメソッドとlowerBoundメソッドは、範囲の上限と下限を指定します.
データベース・バージョン番号の使用
ブラウザにデータベースがない場合、oldVersionは0になり、case:0から順に0、1、2を実行し、プライマリ・キーがnameのストレージ・オブジェクトを作成し、そのオブジェクトにpriceのインデックスとdescriptionのインデックスを作成します.
ブラウザにデータベースが存在し、priceというインデックスが作成されている場合、oldVersionが2の場合、0,1はスキップされ、descriptionというインデックスが直接作成されます.
注意:ここのcaseにはbreakはありません.
参照リンク:https://developers.google.com/web/ilt/pwa/working-with-indexeddb#getting_all_the_data
IndexedDBは大規模なnoSQLストレージシステムです.これにより、ユーザーのブラウザに任意のコンテンツを格納できます.通常の検索、取得、および保存操作に加えて、IndexedDBはトランザクションをサポートします.
ブラウザがIndexedDBをサポートしているかどうかを確認します
if (!('indexedDB' in window)) {
console.log('This browser doesn\'t support IndexedDB');
return;
}
データベースの作成IndexedDBを使用すると、複数のデータベースを作成できますが、原則としてアプリケーションごとに1つのデータベースを作成する必要があります.
name:データベース名、version:バージョン番号、upgradeCallback:コールバックメソッド
idb.open(name, version, upgradeCallback)
IndexedDBのオブジェクトストレージ
主に、データベースがコールバックで返されるインスタンスを作成してcreateObjectStoreメソッドを呼び出すことで、オブジェクトストレージを作成します.
if (!('indexedDB' in window)) {
console.log('This browser doesn\'t support IndexedDB');
return;
}
var dbPromise = idb.open('test-db2', 1, function(upgradeDb) {
console.log('making a new object store');
if (!upgradeDb.objectStoreNames.contains('firstOS')) {
upgradeDb.createObjectStore('firstOS');
}
});
var dbPromise = idb.open('test-db3', 1, function(upgradeDb) {
if (!upgradeDb.objectStoreNames.contains('logs')) {
upgradeDb.createObjectStore('logs', {keyPath: 'id', autoIncrement: true});
}
});
objectStore.createIndex('indexName','property',options);
このメソッドはインデックスオブジェクトを作成して返します.createIndexは、新しいインデックスの名前を最初のパラメータとし、2番目のパラメータはインデックスするデータの属性を指します.最後のパラメータでは、インデックスがどのように動作するかを決定する2つのオプションを定義できます.uniqueとmultiEntryです.uniqueがtrueに設定されている場合、インデックスは単一のキーの重複値を許可しません.インデックス属性が配列である場合、multiEntryはcreateIndexの動作を決定します.trueに設定すると、createIndexは各配列要素のインデックスにエントリを追加します.そうでなければ、配列を含むエントリが追加されます.
var dbPromise = idb.open('test-db4', 1, function(upgradeDb) {
if (!upgradeDb.objectStoreNames.contains('people')) {
var peopleOS = upgradeDb.createObjectStore('people', {keyPath: 'email'});
peopleOS.createIndex('gender', 'gender', {unique: false});
peopleOS.createIndex('ssn', 'ssn', {unique: true});
}
});
注:インデックスは、リファレンス・オブジェクト・ライブラリにデータを書き込むたびに更新されます.インデックスが多いほどIndexedDBのワークロードが大きくなることを意味します.
IndexedDBのオペレーションデータIndexedDBのすべてのデータオペレーションは、1つのトランザクションで実行されます.各操作には、次のような形式があります.
1.データベース・オブジェクトを取得する2.データベース上でトランザクション3を開く.トランザクションでオブジェクトストレージ4を開く.オブジェクトストレージでのアクションの実行
データを書き込むデータを作成するには、オブジェクトストレージでaddメソッドを呼び出し、追加するデータを入力します.Addには、作成時に単一のオブジェクトにプライマリ・キーを定義できるオプションの2番目のパラメータがありますが、createObjectStoreでキー・パスを指定しない場合にのみ使用できます.
someObjectStore.add(data, optionalKey);
dbPromise.then(function(db) {
var tx = db.transaction('store', 'readwrite');//
var store = tx.objectStore('store');
var item = {
name: 'sandwich',
price: 4.99,
description: 'A very tasty sandwich',
created: new Date().getTime()
};
store.add(item);
return tx.complete;
}).then(function() {
console.log('added item to the store os!');
});
データを読み込むデータを読み込むには、オブジェクトストレージのgetメソッドを呼び出します.getメソッドは、ストレージから取得するオブジェクトのプライマリ・キーを使用します.
someObjectStore.get(primaryKey);
dbPromise.then(function(db) {
var tx = db.transaction('store', 'readonly');//
var store = tx.objectStore('store');
return store.get('sandwich');// undefined
}).then(function(val) {
console.dir(val);
});
データを更新データを更新するには、オブジェクトストレージでputメソッドを呼び出します.putメソッドはaddメソッドとよく似ており、addの代わりにオブジェクトストレージにデータを作成するために使用できます.addのようにputのデータとオプションのプライマリ・キー:
someObjectStore.put(data, optionalKey);
dbPromise.then(function(db) {
var tx = db.transaction('store', 'readwrite');
var store = tx.objectStore('store');
var item = {
name: 'sandwich',
price: 99.99,
description: 'A very tasty, but quite expensive, sandwich',
created: new Date().getTime()
};
store.put(item);
return tx.complete;
}).then(function() {
console.log('item updated!');
});
データを削除するには、データを削除し、格納オブジェクトでdeleteメソッドを呼び出します.
someObjectStore.delete(primaryKey);
dbPromise.then(function(db) {
var tx = db.transaction('store', 'readwrite');
var store = tx.objectStore('store');
store.delete(key);
return tx.complete;
}).then(function() {
console.log('Item deleted');
});
すべてのデータを取得
また、getAllメソッドを使用するか、カーソルを使用してオブジェクトストレージまたはインデックスからすべてのデータ(またはサブセット)を取得することもできます.
someObjectStore.getAll(optionalConstraint);
dbPromise.then(function(db) {
var tx = db.transaction('store', 'readonly');
var store = tx.objectStore('store');
return store.getAll();
}).then(function(items) {
console.log('Items by name:', items);
});
someObjectStore.openCursor(optionalKeyRange, optionalDirection);
dbPromise.then(function(db) {
var tx = db.transaction('store', 'readonly');
var store = tx.objectStore('store');
return store.openCursor();
}).then(function logItems(cursor) {
if (!cursor) {
return;
}
console.log('Cursored at:', cursor.key);
for (var field in cursor.value) {
console.log(cursor.value[field]);
}
return cursor.continue().then(logItems);
}).then(function() {
console.log('Done cursoring');
});
このメソッドはpromiseを返し、カーソルオブジェクトでオブジェクトストレージ内の最初のオブジェクトを表し、オブジェクトがない場合はundefinedを返します.オブジェクトストレージの次のオブジェクトに移動するにはcursorを呼び出します.continue.
まず、データベース・オブジェクトを取得し、トランザクションを作成し、オブジェクト・ストレージを開きます.オブジェクトストレージ上でopenCursorメソッドを呼び出し、カーソルオブジェクトを渡す.thenのコールバック関数.今回はコールバック関数を「logItems」と名付けたので、関数内部から呼び出してループすることができます.if(!cursor){return;}もしそうならOpenCursor()が返すpromiseはundefined,またはcursorとして解析される.continue()が返すpromiseはundefinedとして解析される(より多くのオブジェクトがないことを示す).
カーソルオブジェクトには、プロジェクトのプライマリ・キーを表すキー・プロパティが含まれます.また、データを表す値プロパティも含まれます.logItemsが終わるとcursorに戻ります.continue().then(logItems). cursor.continueメソッドは、store内の次のstoreを表すカーソルオブジェクトとして解析されるpromiseを返し、より多くのオブジェクトがない場合はundefinedを返します.この結果は伝えられた.thenのコールバック関数ではlogItemsをこの関数として選択し,関数がループする.したがって、logItemsはオブジェクトが保持されないまで自分を呼び出し続けます.
インデックスによる範囲内のデータの取得
すべてのデータを異なる方法で得ることができますが、特定の属性に基づくデータのサブセットしか必要ありませんか?インデックスを使用できます.インデックスでは、プライマリ・キー以外のプロパティからオブジェクト・ストレージのデータを取得します.任意のプロパティにインデックスを作成し、そのプロパティに範囲を指定し、getallメソッドまたはカーソルを使用して範囲内のデータを取得できます.
IDBKeyRangeオブジェクトを使用して範囲を定義します.このオブジェクトには、upperBound、lowerBound、bound(これは両方を意味する)、onlyの4つの方法があります.upperBoundメソッドとlowerBoundメソッドは、範囲の上限と下限を指定します.
IDBKeyRange.lowerBound(indexKey); IDBKeyRange.upperBound(indexKey); IDBKeyRange.bound(lowerIndexKey, upperIndexKey); IDBKeyRange.only(indexKey);
function searchItems(lower, upper) {
if (lower === '' && upper === '') {return;}
var range;
if (lower !== '' && upper !== '') {
range = IDBKeyRange.bound(lower, upper);
} else if (lower === '') {
range = IDBKeyRange.upperBound(upper);
} else {
range = IDBKeyRange.lowerBound(lower);
}
dbPromise.then(function(db) {
var tx = db.transaction(['store'], 'readonly');
var store = tx.objectStore('store');
var index = store.index('price');//
return index.openCursor(range);
}).then(function showRange(cursor) {
if (!cursor) {return;}
console.log('Cursored at:', cursor.key);
for (var field in cursor.value) {
console.log(cursor.value[field]);
}
return cursor.continue().then(showRange);
}).then(function() {
console.log('Done cursoring');
});
}
データベース・バージョン番号の使用
var dbPromise = idb.open('test-db7', 3, function(upgradeDb) {
switch (upgradeDb.oldVersion) {
case 0:
upgradeDb.createObjectStore('store', {keyPath: 'name'});
case 1:
var storeOS = upgradeDb.transaction.objectStore('store');
storeOS.createIndex('price', 'price');
case 2:
var storeOS = upgradeDb.transaction.objectStore('store');
storeOS.createIndex('description', 'description');
}
});
ブラウザにデータベースがない場合、oldVersionは0になり、case:0から順に0、1、2を実行し、プライマリ・キーがnameのストレージ・オブジェクトを作成し、そのオブジェクトにpriceのインデックスとdescriptionのインデックスを作成します.
ブラウザにデータベースが存在し、priceというインデックスが作成されている場合、oldVersionが2の場合、0,1はスキップされ、descriptionというインデックスが直接作成されます.
注意:ここのcaseにはbreakはありません.
参照リンク:https://developers.google.com/web/ilt/pwa/working-with-indexeddb#getting_all_the_data