連載
» 2008年04月21日 00時00分 公開

SQLiteのDB操作を追加してAIRウィジェットを完成作って学ぶAIRウィジェットの基礎→応用(4)(3/4 ページ)

[福田寅成,クラスメソッド株式会社]

DB(ファイル)の新規作成と接続の確立

 では、実際のDB処理の実装を始めましょう。まずは、DBの作成とDBへの接続の確立です。DBとのやりとりは「接続」を通じて行われますので、この接続確立作業は最初の処理として非常に重要です。MXMLに接続とステートメントを追加しましょう。

 下記2つのタグを追加しましょう。「SQLConnection」クラスが接続、「SQLStatement」クラスがステートメント(SQL文)を担当します。

<mx:Style source="style.css" />
<logic:RSSReaderLogic id="rssReaderLogic" />
<data:SQLConnection id="connection" />
<data:SQLStatement id="statement" />
<mx:Script>

 ロジックの参照、外部との接続情報(サーバとの接続、DBとの接続)はMXML側にタグとして宣言しておくのがいいでしょう。

 次に、ロジッククラスにDBへの接続処理を記述します。記述する場所はMXMLの初期化が終了した際のイベントハンドラである「onCreationCompleteHandler」メソッドに記述します。このメソッドは「Logic」クラスに記述されているもので、このメソッドをRSSReaderのロジッククラスでオーバーライドして実装することにします。

//--------------------------------------
// Initialization
//--------------------------------------

/**
* onCreationCompleteHandler
*/

override protected function onCreationCompleteHandler(
                                             event:FlexEvent):void {
    //DBを開きます。存在しない場合は新規作成されます
    var file:File = File.applicationDirectory
        .resolvePath("rss.db");

    //SQLConnectionを使用して、ローカルDBと接続します
    view.connection = new SQLConnection();

    //イベント登録
    view.connection.addEventListener(SQLEvent.OPEN,
        connectionOpenHandler);
    view.connection.addEventListener(SQLErrorEvent.ERROR,
        connectionErrorHandler);
    //open()によってDBを開きます
    view.connection.open(file);
}

 まず、「File」クラスを利用してDBを開きます。ここでは、ファイル名を「rss.db」としています。このファイルがない場合は自動的に作成されます。「rss.db」ファイルの作られる場所は以下になります。

  • 「bin-debug」フォルダの直下(Flex Builder 3でAIRウィジェットを実行した場合)
  • プログラムフォルダの「RSSReader」フォルダ直下(AIRウィジェットをインストールして実行した場合)

 次に、接続オブジェクトを新規作成します。さらに、接続に対して以下の2つのイベントハンドラを指定します。

  • DB接続オープン成功イベントのイベントハンドラ
  • DB接続オープン失敗イベントのイベントハンドラ

 準備ができたら、接続を開きます(「connection.open(DBファイル名)」)。この段階まで実装すると「イベントハンドラがない」とエラーメッセージが出てると思いますので、2つのイベントハンドラを追加します。以後、DB処理関連のイベントハンドラは「DB Event Handler」区画に記述します。

//--------------------------------------
// DB Event Handler
//--------------------------------------

/**
* DBとの接続に成功
*/

private function connectionOpenHandler(event:SQLEvent):void {
}
/**
* DBとの接続に失敗
*/

private function connectionErrorHandler(event:SQLErrorEvent):void {
    // エラー内容を表示
    Alert.show("データベースエラー:" + event.error.message);
}

 接続成功処理は中身を空にしておきます。接続失敗処理は「Alert」クラスの「show」メソッドでエラーを表示することにします。今回のAIRウィジェットでは接続が失敗になることは基本的にはあり得ません。

図5 rss.dbの確認 図5 rss.dbの確認

 この段階まで実装したら、実行しておきましょう。エラーなく動いたら、rss.dbが作成されていることを確認します。

 「bin-debug」フォルダはRSSReader.mxmlやそれに関連するクラスをビルドしたものが格納されています(「ビルド」は、ここではAIRランタイムで実際に動く状態に変換する作業の意味です)。

 ここに格納されているファイルはAIRウィジェットのインストーラを作る際にインストーラに含まれます。

テーブル新規作成

 ここまででDBは作成されましたが、そのDBにはテーブルがありません。RSS情報を格納するテーブルを作成することにしましょう。

 まずは、下記コードを打ち込んでいきましょう。コードは先ほど作成した「connectionOpenHandler」の直下に記述していきます。

/**
* CREATE処理
*/

private function createTable():void {
    // テーブルを作成します
    view.statement = new SQLStatement();
    view.statement.sqlConnection = view.connection;

    // RSS_INFOテーブルの作成
    view.statement.text =
        "CREATE TABLE IF NOT EXISTS RSS_INFO (" +
        "id INTEGER PRIMARY KEY, " +
        "NAME TEXT, " +
        "URL TEXT" +
    ")";

    // イベント登録
    view.statement.addEventListener(SQLEvent.RESULT,
        statementCreateResultHandler);
    view.statement.addEventListener(SQLErrorEvent.ERROR,
        statementErrorHandler);
    // 実行
    view.statement.execute();
}

  • ステートメントオブジェクトを新規作成
  • SQLステートメントを実行する際に使う接続を指定
  • SQL文を記述。SQLiteでは列(カラム)の型を指定する必要は必ずしもないが、ここでは型を指定して作成している(id列はこの状態でオートインクリメントの状態になる)
列名 説明
id INTEGER 連番、プライマリーキー
NAME TEXT RSSの名称、文字列
URL TEXT RSSのURL、文字列
表2 「RSS_INFO」テーブルのテーブル仕様

 SQLでは、「CREATE TABLE IF NOT EXISTS RSS_INFO」というように、RSS_INFOテーブルがない場合にのみ新規作成するように指定しています。この段階まで実装すると「イベントハンドラがない」とエラーメッセージが出ていると思いますので、2つのイベントハンドラを追加します。

/**
* CREATE処理結果
*/

private function statementCreateResultHandler(event:SQLEvent):void {
}

/**
* ステートメントの実行に失敗
*/

private function statementErrorHandler(event:SQLErrorEvent):void {
    // エラー内容を表示
    Alert.show("データベースエラー:" + event.error.message);
}

 前者は「createTable」メソッド直下に、後者は「connectionErrorHandler」メソッド直下に記述します。

 最後に、「createTable」メソッドを「connectionOpenHandler」メソッドから呼ぶように修正します。この段階まで実装したら、実行しておきましょう。

テーブル検索/参照

 それでは、メインのデータ検索/参照処理の実装に入りましょう。実装の前に、先ほど作成したDBのテーブルはデータが空なので、RSS情報を登録したDBに差し替えることにします。ここから「rss.db」ファイルをダウンロードして、「bin-debug」のrss.dbを上書きします。

 コードを打ち込んでいきましょう。コードは先ほど作成した「connectionOpenHandle」メソッドrの直下に記述していきます。

/**
* SELECT処理
*/

private function selectRSSInfo():void {
    view.statement = new SQLStatement();
    view.statement.sqlConnection = view.connection;
    view.statement.text = "SELECT ID, NAME, URL FROM RSS_INFO";

    //イベント登録
    view.statement.addEventListener(SQLEvent.RESULT,
        selectRSSInfoResultHandler);
    view.statement.addEventListener(SQLErrorEvent.ERROR,
        statementErrorHandler);
    //実行
    view.statement.execute();
}

 先ほどの「createTable」メソッドとほとんど同じ処理なので、詳細は省略します。違いはSQLですが、RSS_INFOテーブルからすべてのデータを検索しているだけのシンプルなSQLになっています。検索が成功したときのハンドラである「selectRSSInfoResultHandler」メソッドがありませんので、下記のコードを記述していきます。

/**
* SELECT処理結果
*/

private function selectRSSInfoResultHandler(event:SQLEvent):void {
    var result:SQLResult = view.statement.getResult();

    // ステートメントがデータを返さない場合
    if (result.data == null) {
        return;
    }
    // 取得データを反映
    view.rssInfoList = RSSInfo.populateArray(result.data);
}

 検索結果の取得の流れは以下になります。

  1. 「statement.getResult」メソッドによりSQL実行結果(「SQLResult」オブジェクト)を取得
  2. 「SQLResult」オブジェクトの「data」プロパティに配列形式で検索結果が保存されているので取得する
  3. 「RSSInfo.populateArray」メソッドではオブジェクトの配列形式のものを「RSSInfo」オブジェクトの「ArrayCollection」に変換している。この方がActionScriptでデータを編集するのが楽になる(特に、今回は編集していないが)

 上記をコーディングしても、問題が2点残ります。

  • 問題点【1】viewのrssInfoListがロジッククラスから参照できない
  • 問題点【2】「RSSInfo」オブジェクトに「populateArray」メソッドがない

 まず、問題点【1】に関しては、MXML上でrssInfoListの可視性をprivateからpublicに変更します。問題点【2】に関してはRSSInfo.asをこのRSSInfo.asに差し替えてください。コードの解説に関しては省略します。

 この状態だと検索処理はどこからも呼ばれていません。DBを開いて接続し、テーブルをオープンして、RSS情報を取得するまでをウィジェットの初期化処理とすることにしましょう。そのために、「selectRSSInfo」メソッドを「statementCreateResultHandler」メソッドから呼ぶことにします。

 この段階まで実装したら、実行しておきましょう。いままで3件あったRSSが2件に減っていたら成功です(差し替え用に用意したrss.dbには2件だけデータが入っています)

 最後に、不要になったrssInfoListの初期化処理をMXMLから削除します。rssInfoListは宣言だけのシンプルなものになります。

import mx.collections.ArrayCollection;

[Bindable]
/** RSSのリスト */
public var rssInfoList:ArrayCollection;

[Bindable]
/** FeedItemのリスト */

 ここまでで、前回までのRSSリーダーウィジェットと同様の機能をSQLiteを利用した処理に修正できました。MXMLがすっきりし、ロジッククラスの各区画に処理の種類に応じたメソッドをまとめる形で実装できました。ここでエラーがなくなっていると思うので、ウィジェットを実行してみます。実行してRSSを選択しても、記事一覧には何も出ません。

 最後に次ページでは、前回までの機能になかったRSS新規作成や削除といった新機能の作成について解説します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。