ODBC API を C++ から直接コールして使うプログラムがやっとまともに動くようになった。 そこでリファクタリングしたりして、 共通処理をまとめようとクラス化していくうちに、 MFC に CODBC クラスというのがあったと思い出した。 車輪の再発明をするのは本意ではない。 しかし MFC を使うのも癪だ。 ODBC 用のクラスなんて MFC に統合しないで単独で提供しろよな、とか思った。
それ以前に ODBC API の使い方は、 リファレンスマニュアルを読むのをサボって、 サンプルプログラムや何やから適当に切り張りして作っている。 あまりいいことではない。 そこで最新のマニュアルを読もうと Microsoft の Developer's サイトをあさってみた。 しかしどうしたことか ODBC API のマニュアルが見つからない。 データベース関連は ADO のマニュアルしかない。 もしかして、 ODBC ってそのうちサポートされなくなるのか?
いろいろ検索してみると、 ODBC API マニュアルは MDAC SDK に含まれている様子。 そこで MDAC SDK をダウンロードする。 中を確認すると確かに ODBC API のマニュアルがあった。
早速、 作成したプログラムで使用した API をマニュアルで確認してみると、 いきなり deprecated になっている。 月初めに書いたプログラムは次のように書くのが新しい。
#include <sql.h> #include <sqlext.h> ... // SQLHANDLE 変数を用意して初期化する SQLHANDLE henv; SQLHANDLE hdbc; SQLHANDLE hstmt; SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc); SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt); // データベースに接続 RETCODE rc; rc = SQLConnect (hdbc, "DS", SQL_NTS, "USER", SQL_NTS, "PASS", SQL_NTS); // プリペアステートメント rc = QSLPrepare (hstmt, "insert into table values (?, ?)", SQL_NTS); long id; const int LEN = 32; char name[LEN+1]; // 変数をバインドする SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &id, 0, NULL); SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, LEN, 0, name, 0, NULL); for (int i = 100; i < 200; i ++) { id = i; sprintf (name, "user%d", i); // SQL を実行する rc = SQLExecute (hstmt); } // 接続を切断し、ハンドルを開放する SQLFreeHandle (SQL_HANDLE_STMT, hstmt); SQLDisconnect (hdbc); SQLFreeHandle (SQL_HANDLE_DBC, hdbc); SQLFreeHandle (SQL_HANDLE_ENV, henv);
月曜日にも書いたように、 ODBC API をラップする C++ クラスを作るのは車輪の再発明になって躊躇される。 加えてせっかくダウンロードした MDAC SDK には ADO の SDK もはいっているので、 どうせクラスを作るなら ADO コンポーネントを C++ から利用してやろうと思った。 それも g++ で。
そこで Windows の COM を C++ から利用する方法、
つまり COM クライアントを作成する方法を検索してみた。
すると VC++ には #import
という、
タイプライブラリを読み込んで C++ のクラス定義や外部変数宣言へ変換する拡張機能があるようだ。
だから #import <msado15.dll>
とすると、
ADO の C++ ヘッダをインクルードしたようになり、
ADO クラスを使えるようになるわけだ。
まったく Microsoft って、
ライブラリのバージョン管理をしたくないのではないか。
昔から共有ライブラリのバージョン違いには悩まされてきたけれど、
何も言語仕様まで拡張することはないだろうに。
MDAC SDK をあさっていたら、
ADO の C++ ヘッダが含まれていた。
これがあれば #import
を使わなくても ADO を利用できる。
しかしヘッダがたくさんありすぎてどれをインクルードすればいいのかよくわからん。
とりあえずめぼしいヘッダをインクルードしてみると山のようにエラーが起こる。 ヘッダの中をのぞいてみると、 条件コンパイル文が幾重にも折り重なっている。 少しやる気をなくす。
気をとりなおして、
プリプロセッサに通したりしながら追跡していくと、
ADOConnection;
というクラス名だけ単独に記述されている行を発見。
ほかにもクラスの数だけぽんと記述されている。
この文はいったい何がしたいのか。
C++ 的には意味のない文のはずなのでコメントアウトする。
不可解なり。
何とかコネクションを張るところまでは動くようになった。
昨日の続き。
張ったコネクションを使って SQL を実行させようとしたところ、
実行時エラーになってしまう。
ヘッダを grep してエラーコードを検索してみると、
OLE_E_NOTRUNNING
というマクロが定義されている様子。
ということは OLE の初期化に失敗しているということか。
しかし、データベースへの接続はうまく行っているように見える。
というか正常終了している。
ふとしたことでちょと切れる。 メールで友人に愚痴をこぼす。
いやなことのあった次の日は一日中寝ているに限る。
昨日と同じ。寝て暮し。