Fbsqlを使ってみよう

 Tcl言語からMySQLデータベースにアクセスする拡張ライブラリは幾つかあります。 Peter Campbellさんが開発されている Fbsql もそのひとつです。 このリンクから、ソース配布とWin32用バイナリ配布が入手できます。 ここでは、MS-Windows98SEにインストールしたMySQL 3.23.30-gamma に対して Tcl/Tk 8.4a1 で動作が確認できたので、この環境での使い方を報告します。

Windows用バイナリ配布のインストール
 Fbsqlは2001年3月14日公開のバージョン1.04から多国語対応文字コードUTF-8に対応しました。 Windows用のバイナリDLLはUTF対応版と非対応版が配布されていますが、 日本語圏で使うなら迷わずUTF対応版をダウンロードしましょう。 ただし、Fbsqlは、まだTclのスタブ機構に対応していないので、 DLLがビルドされたバージョンと同じでなければ使うことができません。 現在の1.05はUTF非対応版はTcl 8.3で、 UTF対応版はTcl 8.4でビルドされているようなので、 これ以外のバージョンで使いたい場合は次のソース配布からのインストールが必要になります。
 バイナリDLLのインストールはさしたる手順はありません。 インストーラがついていないので、 典型的なやり方に沿って次のような感じで行います。

DOS>mkdir C:\progra~1\tcl\lib\fbsql
DOS>copy fbsql.dll C:\progra~1\tcl\lib\fbsql
DOS>tclsh84
% pkg_mkIndex C:/progra~1/tcl/lib/fbsql
% exit
DOS>

また、ローカルにMySQLをインストールしている場合には、 そのディレクトリのどこかにある「libMySQL.dll」 に環境変数PATHを通しておきます。 そうでなく、Fbsqlを専ら遠隔MySQLサーバへのクライアントとして使う場合、 Fbsqlの配布アーカイブに同梱のlibMySQL.dllをどこかPATHの通った場所にコピーします。

Windowsへのソース配布からのインストール
 FbsqlはバイナリDLLの他にUNIX系各種OS用にソースが配布されていますが、 これをWindows上でコンパイラを使って自分でビルドすることももちろんできます。 ソース配布というか、C言語のソースプログラム1個を、 上のリンクから直接ダウンロードしてくるだけなのですが… ソースプログラム fbsql.c はそのままではUTF非対応なので、 テキストエディタで中をのぞいてみて、

#define UTF_ENCODING 0
という行があるので、
#define UTF_ENCODING 1
に変えてからビルドしましょう。 ビルドするには、 次のようなMakefileを作ってNMAKE.EXEまたはMAKE.EXEにかければOKです。 まずマイクロソフトのVisual C++用のMakefileはこんな感じになります。

MYSQLINC	= C:\mysql\include
MYSQLLIB	= C:\mysql\lib\opt\mysqlclient.lib
TCLROOT	= C:\Program Files\Tcl
CC	= cl
SHLD	= cl /LD
CFLAGS	= -DUSE_TCL_STUBS -I"$(TCLROOT)\include" -I"$(MYSQLINC)"
LIBS	= $(MYSQLLIB) "$(TCLROOT)\lib\tclstub84.lib" "$(TCLROOT)\lib\tkstub84.lib"
.c.obj:
	$(CC) $(CFLAGS) -o $@ -c $*.c
fbsql.dll: fbsql.obj
	$(SHLD) -o $@ fbsql.obj $(LIBS)
# end.

また、Borland C/C++ Compiler (BC++)5.5用のMakefileは下のようになります。 BC++でビルドするには、 Tcl/Tk処理系のDLLから、インポートライブラリを作る必要があります。 この方法については、 このページで紹介されています。

MYSQLINC	= C:\mysql\include
MYSQLLIB	= C:\mysql\lib\opt\mysqlclient.lib
TCLROOT	= C:\Program Files\Tcl
CC	= bcc32
SHLD	= bcc32 -tWD
#CFLAGS	= -D_WIN32 -DUSE_TCL_STUBS -I"$(TCLROOT)\include"
CFLAGS	= -D_WIN32 -I"$(TCLROOT)\include" -I"$(MYSQLINC)"
LIBS	= $(MYSQLLIB) "$(TCLROOT)\lib\tcl84imp.lib" "$(TCLROOT)\lib\tk84imp.lib"
.c.obj:
	$(CC) $(CFLAGS) -e"$@" -c $*.c
fbsql.dll: fbsql.obj
	$(SHLD) -e"$@" fbsql.obj $(LIBS)
# end.

インストール方法はバイナリDLLの場合と同じです。

UNIXへのインストール
 UNIX系各種OSの場合は、ソース配布からのコンパイル・インストールを行う必要があります。

  1. Makefileを編集します。以下は一例です。

    MYSQLLIBDIR = /usr/local/lib/mysql
    MYSQLINCDIR = /usr/local/include/mysql
    PIC = -fPIC
    INCLUDES = -I$(MYSQLINCDIR)
    CFLAGS += -Wall $(PIC) $(INCLUDES)
    LDFLAGS = -lz $(MYSQLLIBDIR)/libmysqlclient.a
    SHLD	= gcc -shared
    all:
    	fbsql.so 
    fbsql.so: fbsql.o
    	$(SHLD) -o $@  $<  $(LDFLAGS)
    

  2. 今度はC言語のソースプログラム fbsql.c をエディタで編集します。 冒頭部分に
    #define UTF_ENCODING 0
    
    という行があるので、
    #define UTF_ENCODING 1
    
    に変えます。
  3. makeコマンドでビルドします。
  4. fbsql.soができたら、/usr/local/libなど、 好きな場所にコピーします。またはTclのパッケージ機構が使えるように pkgIndex.tclを配備するのもよいでしょう。 パッケージ名は「Fbsql」です。

日本語は?
 オープンソースのソフトウェアを使ううえで日本人なら誰でも気になる木になる日本語対応。 Fbsqlは先述の通り、バージョン1.04から Tcl 8.1以降で実装されたUTF-8の自動変換をサポートしています。 ソースコードをのぞいてみるとわかりますが、 プラットフォームの文字コード(WindowsならシフトJIS、UNIXなら環境変数LANGで設定したコード) とMySQLサーバーの文字コードが同じ場合、 全く何も気にしなくても日本語のデータをMySQLデータベースとやりとりできます。 OraTclと同様、Fbsqlも日本語に対応したことで、 活用の幅が一気に広がったといえるでしょう。

最も簡単なサンプル
それでは使ってみましょう。

package require Fbsql

button .cmda -text Connect -command connect_test
button .cmde -text Quit -command exit
pack .cmda .cmde -side left

proc connect_test {} {
    sql connect localhost urano urano398
    sql selectdb "udb"
    set s "SELECT PARTS_CLASS, PARTS_CODE, NAME FROM PARTS
            WHERE NAME LIKE '%FPGA%'"
    set rows [sql query $s]
    set result [join $rows "\n"]
    tk_messageBox -title Result -message $result
    sql disconnect
}

Fbsqlの使い方は大変にシンプルです。
  1. sql connectコマンドでMySQLサーバに接続します。 後ろの3つの引数はそれぞれサーバーホスト名、ユーザー名、パスワードです。
  2. sql selectdbコマンドでアクセスしたいデータベースを指定します。
  3. sql queryコマンドでSQL文を実行します。 戻り値は、全部の行のリストなので、sql query一回で完全な問い合わせ結果が得られることになります。
  4. sql disconnectで接続を終了します。
データベースをselectする、という処理はMySQLに特有に見られるもので、 PHP言語のMySQLインターフェースにもこのような関数があります。 が、他の点は特に違和感なく使えますね。

結果をフェッチループで取得するサンプル
 さて、前の例では問合せ結果がダイレクトにリスト連結されて返ってきたのですが、 そうではなく、問合せ結果を一度に1行ずつ取り出して(「フェッチ」して) 返す処理でやってみます。

package require Fbsql

button .cmda -text Connect -command connect_test
button .cmde -text Quit -command exit
pack .cmda .cmde -side left

proc connect_test {} {
    sql connect localhost urano urano398
    sql selectdb "udb"
    set s "SELECT PARTS_CLASS, PARTS_CODE, NAME FROM PARTS
            WHERE NAME LIKE '%FPGA%'"
    sql startquery $s -array X
    set result {}
    while 1 {
        if {"[sql fetchrow]" == ""} { break }
        lappend result "$X(PARTS_CLASS)-$X(PARTS_CODE) : $X(NAME)"
    }
    sql endquery
    set result [join $result "\n"]
    tk_messageBox -title Result -message $result
    sql disconnect
}

sql queryコマンドの代わりに sql startqueryコマンドを使うと、 問合せ結果を1行ずつ配列要素に格納して返してきます。格納する配列変数名は-array オプションで指定することができ、配列要素名(キー)は列名(大文字)になります。 実際の各行のデータの取得はsql fetchrowコマンドで繰り返し行います。 このコマンドは全部の行を返し終わらないうちは配列変数名を返し、 全部の行を返し終わったら空文字列を返します。 この空文字を検出したら最後にsql endquery コマンドを使い、一連の問合せ処理は終了というわけです。

拡張レビュー分室 top
(first uploaded 2001/03/20 last updated 2004/07/18, MISUMI URANO)