HTML 5のIndexedDB使用の詳細


firefox 4の正式版が発売されるにつれて、IndexedDBは正式に私たちの視線に入った.IndexedDBはHTML 5-WebStorageの重要な一環であり、軽量レベルのNOSQLデータベースである.それに比べて、WebDataBase規格は長い間更新されておらず、IndexedDBに取って代わられる意味が大きい.
 
Section 1:開始、データベース参照
w 3 cはIndexedDBに多くのインタフェースを定義しており、DatabaseオブジェクトはIDBdataBaseとして定義されている.IDBDataBaseを得るには工場法,すなわちIDBfactoryから取得する.ブラウザオブジェクトでIDBfactoryが実装されているのはindexedDBというインスタンスだけです.
IDBfactoryとIDBDataBaseインタフェースの定義を見てみましょう
interface IDBFactory {
    IDBRequest open (in DOMString name);
    IDBRequest deleteDatabase (in DOMString name);
};

interface IDBDatabase : EventTarget {
    readonly attribute DOMString     name;
    readonly attribute DOMString     version;
    readonly attribute DOMStringList objectStoreNames;
    IDBObjectStore          createObjectStore (in DOMString name, in optional Object optionalParameters) raises (IDBDatabaseException);
    IDBRequest              deleteObjectStore (in DOMString name) raises (IDBDatabaseException);
    IDBVersionChangeRequest setVersion ([TreatNullAs=EmptyString] in DOMString version);
    IDBTransaction          transaction (in any storeNames, in optional unsigned short mode) raises (IDBDatabaseException);
    void                    close ();
             attribute Function      onabort;
             attribute Function      onerror;
             attribute Function      onversionchange;
};

interface IDBRequest : EventTarget {
    readonly attribute any            result get raises (IDBDatabaseException);
    readonly attribute unsigned short errorCode get raises (IDBDatabaseException);
    readonly attribute Object         source;
    readonly attribute IDBTransaction transaction;
    const unsigned short LOADING = 1;
    const unsigned short DONE = 2;
    readonly attribute unsigned short readyState;
             attribute Function       onsuccess;
             attribute Function       onerror;
};

 
重要:IndexedDBでは、ほとんどの操作がcommand->request->resultの方式を採用しています.たとえば、レコードをクエリーし、requestを返し、requestのresultでクエリー結果を取得します.たとえば、データベースを開き、requestを返し、requestのresultで返されたデータベース参照を取得します.
 
IDBfactoryのメソッドボディ定義から、IDBRequestオブジェクトが返されていることがわかります.このIDBRequestは先ほどお話ししたrequestです.
 
次に、IDBdataBaseを得るための一般的な方法を示す.
 
if (!window.indexedDB) {
	window.indexedDB = window.mozIndexedDB || window.webkitIndexedDB;
}

var request = indexedDB.open("MyTestDatabase");

request.onsuccess = function(e) {
	// Obtain IDBDatabase 
	// VERSION_CHANGE transaction callback
	var db = request.result;
}

 
Firefox 4でIndexedDBを使用する場合の注意点:
1.indexedDBこの例はindexedDBではなく、mozIndexedDBと呼ばれています
2.indexedDBはiframeまたはframeタグでは使用できません
3.Firefox 4ではdeleteDatabaseメソッドは実装されていません(新しいバージョンで改善される可能性があります)
4.indexedDB.Openは単純にデータベースを開くのではなく、データベースを開く上でversionを起動しました.Changeイベントメソッドコールバック.このコールバックメソッドでは、version_用のトランザクションが自動的に開始されます.change.IDBdatabaseオブジェクトは、このトランザクションで取得する必要があります.
 
 
Section 2:object storeの初期化
indexedDB標準では、初期化時にテーブルを作成することを推奨します.後でブラウザを開くたびにcheckバージョン番号だけが必要です.2回目の作成は必要ありません.テーブルはindexedDBでobject storeと呼ばれています.
次にobject storeインタフェースの定義を示します.
interface IDBObjectStore {
    readonly attribute DOMString      name;
    readonly attribute DOMString      keyPath;
    readonly attribute DOMStringList  indexNames;
    readonly attribute IDBTransaction transaction;
    IDBRequest put (in any value, in optional any key) raises (IDBDatabaseException, DOMException);
    IDBRequest add (in any value, in optional any key) raises (IDBDatabaseException, DOMException);
    IDBRequest delete (in any key) raises (IDBDatabaseException);
    IDBRequest get (in any key) raises (IDBDatabaseException);
    IDBRequest clear () raises (IDBDatabaseException);
    IDBRequest openCursor (in optional any range, in optional unsigned short direction) raises (IDBDatabaseException);
    IDBIndex   createIndex (in DOMString name, in DOMString keyPath, in optional Object optionalParameters) raises (IDBDatabaseException);
    IDBIndex   index (in DOMString name) raises (IDBDatabaseException);
    void       deleteIndex (in DOMString indexName) raises (IDBDatabaseException);
};
 
 
IDBdatabaseにはcreateObjectStoreメソッドがあります.ただしIDBdatabaseを取得した後は直接Exceptionを呼び出します.なぜならcreateObjectStoreはversion_changeのtransaction callbackで呼び出されます.
 
次に、object storeを作成する一般的なコードを示します.
var db = null;
var customerData = [
		{ssn: "444-44-4444", name: "Bill", age: 25, email: "[email protected]", nickName: ["1", "2", "3"]},
		{ssn: "555-55-5555", name: "Donna", age: 34, email: "[email protected]"},
		{ssn: "666-66-6666", name: "Jack", age: 14, email: "[email protected]"}
	];
request.onsuccess = function(e) {
	// Obtain IDBDatabase 
	// VERSION_CHANGE transaction callback
	db = request.result;
	
	if (db.version != "1.0") {
		var requestVersion = db.setVersion("1.0");
		requestVersion.onerror = function(event) {
			alert(event);
		}
		requestVersion.onsuccess = function(event) {
			createObjectStore(db);
		}
	}
	
	db.close();
};

function createObjectStore(db) {

	if (db.objectStoreNames.contains('customers')) {
		db.deleteObjectStore("customers")
	}
	// Create Object Store
	// This method was not called from a VERSION_CHANGE transaction callback.
	var objectStore = db.createObjectStore("customers", {
		// primary key
		keyPath: "ssn",
		// auto increment
		autoIncrement: false
	});
	
	objectStore.createIndex("name", "name", { unique: false });
	
	objectStore.createIndex("email", "email", { unique: true });
	
	// Add initial data
	for (var index = 0; index < customerData.length; index++) {
		objectStore.add(customerData[index]);
	}
}

上記のコードはcustomersという名前で、PrimaryKeyはssnであり、自己増加シーケンスを持たないobject store(テーブル)を作成します.このobject storeのために2つのインデックス(nameとemail)を作成した.ここでemailは一意のキーです.customersの初期データが作成されました.初期データに多層構造がネストされていることがわかります.
 
Section 3:トランザクションとカーソル
上記IDBdatabaseインタフェースの定義により、IDBdatabaseからtransactionを取得できます.indexedDBでは、トランザクションが自動的にコミットまたはロールバックされます.手動commitやrollbackは必要ありません.
事務は三つに分かれている
IDBTransaction.READ_ONLY読み取り専用
IDBTransaction.READ_WRITE読み書き可能
IDBTransaction.VERSION_CHANGEバージョンアップグレード
私たちが一番使っているのは前の2種類です.トランザクション・レベルを設定しない場合、デフォルトはREAD_です.ONLY.
 
カーソルはobject storeを巡回する唯一の方法です.firefox 4にはgetallがありますが、近い将来、この方法は取り締まると信じています.
 
カーソルを開くときに設定しない場合、デフォルトではIDBCursorが使用されます.NEXT
 
次に、トランザクション・オブジェクトを取得するための一般的な方法を示します.
//   IDBDatabase  IDBTransaction
var transaction = db.transaction(["customers"]);

//   IDBTransaction  IDBObjectStore
var objectStore = transaction.objectStore("customers");

//     ,  customers     
objectStore.openCursor().onsuccess = function(event) {
			
	var cursor = event.target.result;
			
	if (cursor) {
		var key = cursor.key;
		var rowData = cursor.value;
		alert(rowData.name);
		cursor.continue();
	}
}

上のコードではカーソルが使用されていますが、cursorが呼び出されていることに注意してください.continueの後、cursorはonsuccessハンドルのメソッドを再呼び出します.したがって,以上のコードのonsuccessは実際に3回呼び出された.OpenCursorの使い方については、次のセクションで説明します.
 
Section 4:インデックスクエリ
section 3のobjectStore.OpenCursorはkeyPathに基づいてクエリーします.インデックスで検索するにはobjectStoreを使用します.index(インデックス名).OpenCursorクエリー
 
1)OpenCursorの最初のパラメータはクエリー条件であり、IDBKeyRangeオブジェクトを入力する必要があります.
IDBKeyRangeの作成方法は4種類あり,いずれもIDBKeyRangeを呼び出した静的メソッドである.それぞれ4つの異なるタイプの条件を表しています.
//           Bill   
IDBKeyRange.only("Bill");

//            Bill,     Bill   
IDBKeyRange.lowerBound("Bill", true);

//            Bill,    Bill   
IDBKeyRange.upperBound("Bill", false);

//           Bill Jack  ,    Bill,    Jack   
IDBKeyRange.bound("Bill", "Jack", false, true);

2)OpenCursorの2番目のパラメータはカーソル方向である.4種類あります
IDBCursor.NEXTシーケンスループ
IDBCursor.NEXT_NO_DUPLICATEシーケンスサイクルが重複しない
IDBCursor.PREV逆順サイクル
IDBCursor.PREV_NO_DUPLICATE逆順サイクルが繰り返されない
 
例:
var boundKeyRange = IDBKeyRange.upperBound("Jack", false);
objectStore.index("name").openCursor(boundKeyRange, IDBCursor.PREV_NO_DUPLICATE).onsuccess = function(event) {
		var cursor = event.target.result;
		
		if (!cursor) {
			return;
		}
		
		var rowData = cursor.value;
		
		alert(rowData.name);
		cursor.continue();
	};

 
完全なインスタンスは添付ファイルを参照してください.indexedDBは、パブリッシュ環境(webコンテナ)で実行する必要があります.