デモ1の画面は以下のような具合だが、
"プログラムからLoad"ボタンで呼び出される処理以下のような感じになっている。
private function programLoad():void{ var count:int = 10; for(var i:int = 0;i < count;i++){ var tmp:Object = new Object(); tmp["col1"] = i; tmp["col2"] = i + "行目"; tmp["col3"] = i % 2 == 0 ? true : false; testdata.addItem(tmp); } }
3カラムの情報を含むtmpオブジェクトを、testdataに10回追加する処理。
testdataというのは、mxmlの定義部分で以下のように定義されているオブジェクトのこと。
<mx:ArrayCollection id="testdata"/>
これが以下のような具合に、データグリッドにバインドされているので、メソッドの処理でtestdataにtmpを追加するたびに、その値がデータグリッドに表示されることになっている。
<mx:DataGrid id="dg" x="10" y="10" dataProvider="{testdata}">
データグリッドのカラムは以下のように定義する。
<mx:columns> <mx:DataGridColumn headerText="カラム 1" dataField="col1"/>
この際指定しているdataField名が、tmpに含まれているオブジェクト名と一致しているので、対応するカラムにデータが入って行くことになっている。
"プログラムからload"がクリックされると以下のような表示になる。
デモ1のデモンストレーションとしては、このデータを"SQLiteにSave"ボタンをクリックして、ローカルのSQLiteに保存し、その後、データグリッドをクリアし、今度は"SQLiteからLoad"ボタンをクリックして、データを復帰させ、ローカルのデータベースとして機能していることを確認する。
データグリッドをクリアする変わりに、アプリケーションを終了させた後、再度アプリケーションを起動して、"SQLiteからLoad"ボタンをクリックしても、データはローカルのデータベースに保存されるので、同じようになる。
SQLiteにデータを保存する処理は以下のようになっている。
private function sqliteSave():void{ var tmpdb:SQLConnection = new SQLConnection(true);※1 var file:File = new File(File.separator + file_name); try{ tmpdb.open(file); tmpdb.begin();※2 var deletedata:SQLStatement = new SQLStatement(); deletedata.sqlConnection = tmpdb; deletedata.text = "delete from TEST_TABLE1";※3 deletedata.execute(); var count:int = testdata.length; for(var i:int = 0;i < count;i++){ var save:SQLStatement = new SQLStatement(); var obj:Object = testdata[i]; save.sqlConnection = tmpdb; save.text = "insert into TEST_TABLE1(col1,col2,col3) values (:data1,:data2,:data3)";※4 save.parameters[":data1"] = obj["col1"]; save.parameters[":data2"] = obj["col2"]; save.parameters[":data3"] = obj["col3"]; save.execute(); } tmpdb.commit();※5 }catch(e:SQLError){ tmpdb.rollback();※6 }finally{ if(tmpdb.connected == true){ tmpdb.close(); } } }
※1のところで、トランザクション処理を設定するために、再度SQLConnectionインスタンスを生成している。
ここでコンストラクタにtrueの引数を渡すことで、エラーイベントをtray-catch-finallyステートメントで拾える形式で発行してくるれようになる。
トランザクション処理として、複数の処理をまとめるので、処理結果を受けるハンドラは、実行単位ではなくて、ブロック単位で定義できる必要がある。
※2でSQLConnectionのbeginメソッドを実行している。
beginメソッドの以下から、※5のcommitメソッド、または、※6のrollbackメソッドまでの間に実行される処理が、トランザクションのグループとされる。
トランザクションとして実行される処理は、
※3のテーブルのデリート
※4のデータのインサート処理
インサートの方法としては、SQLでカラムとパラメータを結びつけた後、パラメータにデータを割り当てている。
トランザクション単位で、処理が問題なく実行されたときは、SQLConnectionのcommitメソッドを実行して、データベースの更新処理を確定し、なんらかのエラーが発生した場合は、rollbackメソッドを実行して、トランザクション単位で処理を無効にする。
SQLiteからデータをロードする処理は以下のようになっている。
まずデータを呼び出す。
private function sqliteLoad():void{ var load:SQLStatement = new SQLStatement(); load.sqlConnection = db; load.text = "select * from TEST_TABLE1"; load.execute(); load.addEventListener(SQLEvent.RESULT,loadHandler,false,0,true);※1 }
SQLの実行が成功すると、※1で定義したリスナーメソッドが、SQLEventを引数として呼ばれる。
private function loadHandler(event:SQLEvent):void{ var stmt:SQLStatement = event.currentTarget as SQLStatement;※1 if(stmt != null){※2 var res:SQLResult = stmt.getResult();※3 testdata = new ArrayCollection(res.data);※4 } }
SQLEventはresultデータにアクセスするメソッドやプロパティを持っていないので、イベントターゲットのSQLStatementインスタンスからresultデータにアクセスする。
AS3では、イベントのターゲットはtargetとcurrentTargetの2種類になっている。
adobeのリファレンスによると、例えばボタンコンポーネントがクリックされて生成されたイベントの場合、targetはコンポーネントのDOMノードの一番末端で、実際にカーソルと接するテキストフィールドで、currentTargetの方は、コンポーネントのDOMの大元のボタンコンポーネント自身になるというような説明があるが、Displayオブジェクトではない場合はどちらも同じ。
asはキャストオペレータで、currentTargetで参照されるObjectをSQLStatementにキャストしています。
※2。AS3.0からランタイムエラーが出るようになっているので、null参照は厳禁なのでnullのチェックをします。
※3。SQLStatementのgetResultメソッドを使ってSQLResultを抽出します。
※4。SQLResultのdataプロパティに、SQLの結果のクエリデータが配列で入っているので、それをArreyCollectionにキャストして、データグリッドにバインドされているtestdataに格納します。
データグリッドの消去は、データグリッドにdataProviderとしてバインドされているtestdata ArrayCollectionのメソッドを使って、以下のように消去します。
private function gridClear():void{ testdata.removeAll(); }
SQLiteのデータベースのクリアは、SQLStatementを実行して、以下のように消去しています。
private function sqliteDelete():void{ var deletedata:SQLStatement = new SQLStatement(); deletedata.sqlConnection = db; deletedata.text = "delete from TEST_TABLE1"; deletedata.execute(); }
« SQLiteを使ったAIRのオフライン運用術 その1 | MAX 2007 | SQLiteを使ったAIRのオフライン運用術 その3 »