Flash:Airを使ってローカルのSQLiteデータベース操作をしてみるサンプル
「アプリを開発するにあたって、やはりローカルでデータベースを使う必要が出てくるだろう」という事で、今回はFlashでAIRのデータベースAPIを使って、ローカルにSQLiteのファイルを作成して、「テーブル作成」→「レコード追加」→「レコード取得」を実験してみました。
準備
Flashを開いて、上メニューから「ファイル」「新規作成」を選択します。
AIRの機能を使うので、「AIR FOR Desktop」「AIR FOR Android」「AIR FOR iOS」のいずれかを選択します。
今回は「AIR FOR Android」にしてみました。
タイムラインの最初のフレームを右クリックして、「アクション」を選択します。
表示されたアクションウィンドウに、ActionScript3.0のコードを記述していきます。
ActionScript3.0のコード
リファレンスを見ていたら「暗号化したデータ」を簡単に扱えるという事なので、その様にしてみる事にします。
1)データベースファイル(パス)を指定
2)暗号化キーの作成
3)データベースに接続(ファイル作成)
4)テーブル作成(CREATE TABLE IF NOT EXISTS)
5)レコード追加(INSERT)
6)レコード取得(SELECT)
のテストをしたコードは、次の通りです。
(基本、マニュアルのコピペでやってみました。参照したマニュアル等のURLをたくさんメモ書きしています)
// http://help.adobe.com/ja_JP/as3/dev/WS5b3ccc516d4fbf351e63e3d118666ade46-7d49.html //DBファイルを決定 import flash.filesystem.File; // The database file is in the application storage directory // File.applicationStorageDirectory - インストールされている各 AIR アプリケーションごとに固有の記憶領域ディレクトリ // Windows … C:\Users\[USERNAME]\AppData\Roaming\[AppID(dbtest)]\ var folder: File = File.applicationStorageDirectory; // 「File.applicationStorageDirectory」を基点として、相対パス "DBSample.db" を指定して、新規に File オブジェクトを作成する // Windowsの場合 … C:\Users\[USERNAME]\AppData\Roaming\[AppID(保存していない時はnoName)]\Local Store\DBSample.db var dbFile: File = folder.resolvePath("DBSample.db"); // http://help.adobe.com/ja_JP/as3/dev/WS5b3ccc516d4fbf351e63e3d118666ade46-7d27.html // DB接続 import flash.data.SQLConnection; import flash.events.SQLErrorEvent; import flash.events.SQLEvent; var conn: SQLConnection = new SQLConnection(); conn.addEventListener(SQLEvent.OPEN, openHandler); conn.addEventListener(SQLErrorEvent.ERROR, errorHandler); //暗号化設定 var encryptionKey:ByteArray = new ByteArray(); encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure! // http://help.adobe.com/ja_JP/as3/dev/WS5b3ccc516d4fbf351e63e3d118666ade46-7d39.html // http://help.adobe.com/ja_JP/FlashPlatform/reference/actionscript/3/flash/data/SQLConnection.html#open() import flash.data.SQLMode; // 非同期実行には、DB操作がバックグラウンドで実行されている間もメインのアプリケーションコードの実行が継続される //conn.openAsync(dbFile); //conn.openAsync(dbFile, SQLMode.CREATE, false, 1024, encryptionKey); // 同期実行はDBエンジンに操作を実行するように命令すると、その時点でコードが一時停止して、その間にDBエンジンの処理が行われます。操作が完了すると、コードの次の行から実行が再開されます //conn.open(dbFile); conn.open(dbFile, SQLMode.CREATE, false, 1024, encryptionKey) function openHandler(event: SQLEvent): void { trace("the database was created successfully"); } function errorHandler(event: SQLErrorEvent): void { trace("Error message:", event.error.message); trace("Details:", event.error.details); } //http://help.adobe.com/ja_JP/as3/dev/WS5b3ccc516d4fbf351e63e3d118666ade46-7d2c.html //テーブル作成 import flash.data.SQLStatement; import flash.errors.SQLError; var createStmt: SQLStatement = new SQLStatement(); createStmt.sqlConnection = conn; var sql: String = "CREATE TABLE IF NOT EXISTS egara (" + " egaraId INTEGER PRIMARY KEY AUTOINCREMENT, " + " egaraName TEXT " + ")"; createStmt.text = sql; createStmt.addEventListener(SQLEvent.RESULT, createResult); createStmt.addEventListener(SQLErrorEvent.ERROR, createError); createStmt.execute(); function createResult(event: SQLEvent): void { trace("Table created"); } function createError(event: SQLErrorEvent): void { trace("Error message:", event.error.message); trace("Details:", event.error.details); } //INSERT ステートメントの実行 var insertStmt:SQLStatement = new SQLStatement(); insertStmt.sqlConnection = conn; // define the SQL text sql = "INSERT INTO egara (egaraName) " + "VALUES ('inu')"; insertStmt.text = sql; // register listeners for the result and failure (status) events insertStmt.addEventListener(SQLEvent.RESULT, insertResult); insertStmt.addEventListener(SQLErrorEvent.ERROR, insertError); // execute the statement insertStmt.execute(); function insertResult(event:SQLEvent):void { trace("INSERT statement succeeded"); } function insertError(event:SQLErrorEvent):void { trace("Error message:", event.error.message); trace("Details:", event.error.details); } //http://help.adobe.com/ja_JP/as3/dev/WS5b3ccc516d4fbf351e63e3d118666ade46-7d4c.html //SELECT (データ取得) import flash.data.SQLResult; var selectStmt:SQLStatement = new SQLStatement(); // A SQLConnection named "conn" has been created previously selectStmt.sqlConnection = conn; selectStmt.text = "SELECT * FROM egara"; selectStmt.addEventListener(SQLEvent.RESULT, resultHandler); selectStmt.addEventListener(SQLErrorEvent.ERROR, errorHandler); selectStmt.execute(); function resultHandler(event:SQLEvent):void { // http://help.adobe.com/ja_JP/FlashPlatform/reference/actionscript/3/flash/data/SQLResult.html var result:SQLResult = selectStmt.getResult(); var numResults:int = result.data.length; for (var i:int = 0; i < numResults; i++) { var row:Object = result.data[i]; trace(row); var output:String = "egaraId: " + row.egaraId; output += "; egaraName: " + row.egaraName; trace(output); } }
デバッグで確認
コードを書いたら、上メニューから[デバッグ]→[デバッグ]で、処理を確認します。
「出力」に取得したレコードの中身まで出力されていれば成功です。
ちなみに今回の例では、実行(デバッグ)するたびに「egara」テーブルに「inu」レコードが1件ずつ増えていきます。
マニュアルコピペでDB接続失敗
基本サンプルコードをコピペしただけなので、あんまりエラーは出ないだろうと思っていたのですが、
コピペしたからこそ、エラーで詰まってしまいました。
詰まった場所は、データベースに接続する部分。
conn.open(dbFile, SQLMode.CREATE, false, 1024, encryptionKey)
このコードは正常に動きましたが、サンプルコードでは
conn.open(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey)
となっており、引数がおかしいためコンパイルエラーで止まってしまいました。
…引数の数が違います(「null」がイラナイ)。何か変更があったのでしょうか。
DBファイルの保存パス
コード内にもコメントアウトして記述しましたが、DBファイルの保存されるフォルダを
File.applicationStrageDirectory
としています。
もちろん、OS毎に異なるパスが返ります。
リファレンスマニュアルでは、Windowsの場合として「Documents and Settings」のパスが紹介されています。
「Documents and Settings」ってWindowsXPまででしたっけ?
私の環境がWindows8.1だったので探してみると、
C:\Users\[USERNAME]\AppData\Roaming\[AppID]\DBSample.db
でした。
AppIDはFlashのファイル名? ちなみに、Flashのファイルを保存せずにデバッグすると
C:\Users\[USERNAME]\AppData\Roaming\noName\DBSample.db
ができていました。
