CでプログラミングしたAPI

mSQLの一部として、mSQL APIライブラリであるlibmsql.aが提供されます。APIを使用すると、Cプログラムでデータベース・エンジンを利用できます。APIの機能は、プログラムにmsql.hヘッダー・ファイルを指定して、mSQLライブラリにリンクを設定することでアクセスします。(Cコンパイラへの引き数として、-lmsqlを使用します) 特別に指定しない限り、ライブラリは/usr/local/Minerva/libに、ヘッダー・ファイルは/usr/local/Minerva/includeにインストールされます。

mSQLエンジンと同様に、APIではMINERVA_DEBUG環境変数を使うことができます。現在のところAPIでは、query、api、mallocの3つのデバッグ・モジュールを利用できます。"query"を設定すると、APIはサーバーにクエリーを送信する時に、その内容を表示します。"api"を設定すると、通信状況などの内部情報が表示されます。"malloc"を設定すると、APIライブラリによるメモリーの使用状況が表示されます。メモリーを割り当てたブロックの位置とサイズの情報、free()に渡すアドレスなどが表示されます。これらのモジュールは、MINERVA_DEBUG環境変数を設定すれば使うことができます。環境変数に指定する場合は、各デバッグ・モジュールの名前をコロンで区切って、次のように指定してください。
	setenv MINERVA_DEBUG api:query

msqlConnect()

int msqlConnect(char * host)
msqlConnect()は、mSQLエンジンとの通信を設定します。mSQLサーバーが稼働しているホストの名前か、あるいはそのIPアドレスだけが、引き数として指定することができます。ホストの引き数としてNULLを指定した場合、Unixドメイン・ソケット/dev/msqldを使って、ローカル・ホストで稼働しているサーバーに接続されます。エラーが発生すると-1が値として戻され、外部変数msqlErrMsgに適切なテキスト・メッセージが入れられます。この変数は、"msql.h"に定義します。

サーバーに接続すると、整数の識別子が、呼び出しを実行した機能に戻されます。mSQL APIの呼び出しを行うその他の機能のために、この値がハンドルとして使用されます。つまり、この戻された値は、接続の際にソケットを識別するためのデータ(ソケット記述子)なのです。msqlConnect()を複数回呼び出して、戻された値を別々の変数に割り当てておけば、複数のデータベース・サーバーに同時に接続することが可能になります。

mSQLの以前のバージョンでは、MSQL_HOST環境変数を使用して、hostパラメータがNULLであった場合でも、ターゲット・マシーンを指定することができました。しかし、現在では指定することができません。


msqlSelectDB()

int msqlSelectDB(sock,dbName)

	int	sock;

	char	*dbName;
クエリーをサブミットするには、データベースを選択する必要があります。msqlSelectDB()には、アクセスするデータベースを指定します。msqlSelectDB()には、msqlConnect()が戻したソケット記述子と、アクセスするデータベースの名前を指定します。リターン値-1が戻された場合、エラーが発生したことを表しており、そのエラーを説明するテキスト・メッセージがmsqlErrMsgに入れられます。msqlSelectDB()は、プログラムの実行中に何度でも呼び出すことができます。呼び出すたびに、サーバーは将来のアクセスのために、指定したデータベースを使用します。msqlSelectDB()を何度も呼び出せば、プログラムの実行中に複数のデータベースを処理することができます。


msqlQuery()

int msqlQuery(sock, query)

	int	sock;

	char	*query;
エンジンにクエリーを送信する場合、ソケット記述子で識別した通信接続が使用されます。またクエリーは、プレーン・テキストとして、msqlQuery()によって送信されます。通常、戻された値が-1であった場合、これはエラーが発生したことを表しています。msqlErrMsgに、エラーを表すメッセージが入れられます。SELECTステートメントのように、クエリーがエンジンからデータを抽出してくる場合、そのデータはAPIの中に一時的に保存され、アプリケーションがこのデータを読み込みにくるのを待つことになります。msqlStoreResult()を使用してデータを処理する前に、アプリケーションが別のクエリーをサブミットしてしまった場合、一時的に保存してあるデータは、新しいクエリーで抽出したデータによって上書きされてしまいます。


msqlStoreResult()

m_result *msqlStoreResult()
SELECTのクエリーで抽出したデータは、他のクエリーをサブミットしたり、内部のAPIバッファから削除したりする前に、保存しておかなければなりません。データは、msqlStoreResult()機能によって保存します。この機能は、呼び出しを実行したルーチンに対して、処理結果ハンドルを戻します。処理結果ハンドルは、m_result構造へのポインタであり、データへのアクセスを確保した時点で、他のAPIルーチンに渡されます。処理結果ハンドルを割り当てると、他のクエリーもサブミットできるようになります。1つのプログラムによって、同時に複数の処理結果ハンドルをアクティブにすることが可能です。


msqlFreeResult()

void msqlFreeResult(result)

	m_result		*result;
処理結果ハンドルで識別しているデータが、プログラムにとって不要になった場合、msqlFreeResult()を使用してそのデータを削除しなければなりません。削除するデータを識別するために、msqlStoreResult()が戻した処理結果ハンドルを、msqlFreeResult()に指定してください。


msqlFetchRow()

m_row msqlFetchRow(result)

	m_result		*result;
SELECTで抽出したデータベースの各行は、msqlFetchRow()機能によってアクセスします。データがm_row変数に入れられて戻されますが、この変数には行の各フィールドへの文字ポインタが入れられます。たとえば、抽出した各行からSELECTステートメントが3つのフィールドを選択した場合、この3つのフィールドの値に対して、変数エレメント[0]、[1]、[2]が割り当てられます。この変数エレメントを、msqlFetchRow()に指定して、各行をアクセスしてください。データの終わりに達した場合、NULL値が戻されます。詳細については、この節の最後の例を参照してください。


msqlDataSeek()

void msqlDataSeek(result, pos)

	m_result 		*result;

	in		pos;
m_result構造には、クライアント側の「カーソル」が含まれます。このカーソルは、データの次行の位置を示します。データ・カーソルの位置を変更するには、msqlDataSeek()を使用してください。0を指定してこの機能を呼びだした後に、msqlFetchRowを呼びだすと、サーバーが戻したデータの第1行が抽出されます。位置情報の値としては、0(第1行)からテーブルの行数までを指定できます。テーブルの終わりを越えて、データの検索が行われた場合、msqlFetchRow()の呼び出しに対してNULL値が戻されます。


msqlNumRows()

int msqlNumRows(result)

	m_result		*result;
msqlStoreResult()が戻した処理結果ハンドルを指定して、msqlNumRows()を呼び出せば、クエリーで抽出した行の数をチェックできます。クエリーで抽出したデータの数は、整数の値として戻されます。SELECTを使用したクエリーで、条件を満たすデータが無かった場合、msqlNumRows()は値として0を戻します。(注意: mSQLの以前のバージョンでは、データが無かった場合、処理結果ハンドルとしてNULL値が戻されていました。しかし現在では、0行という意味を分かりやすくするためにも、0を値とするように改良されています。)


msqlFetchField()

m_field *msqlFetchField(result)

	m_result		*result;
実際のデータ行とともに、サーバーは選択したデータ・フィールドに関する情報も戻します。msqlFetchField()機能によって、プログラムを呼び出すと、この情報を表示することができます。msqlFetchRow()と同様に、この機能は1度に1エレメントの情報を戻し、情報が無くなるとNULL値を戻します。データはm_field構造で戻されますが、それには次のような情報が含まれています。
typedef struct {

	char	*name,		/* name of field */

		*table;		/* name of table */

	int	type,		/* data type of field */

		length,		/* length in bytes of field */

		flags;		/* attribute flags */

} m_field;
タイプ・フィールドに指定できる値は、INT_TYPE、CHAR_TYPE、REAL_TYPEとしてmsql.hに定義します。各属性フラッグは、次のマクロを使用してアクセスできます。
IS_PRI_KEY(flags)			/* Field is the primary key */

IS_NOT_NULL(flags)			/* Field may not contain a NULL value */




msqlFieldSeek()

void msqlFieldSeek(result, pos)

	m_result		*result;

	int		pos;
処理結果として得られる構造には、フィールド・データの「カーソル」が含まれます。msqlFieldSeek()機能を使用すれば、この位置を移動させることができます。詳細については、msqlDataSeek()機能の解説を参照してください。


msqlNumFields()

int msqlNumFields(result)

	m_result		*result;
処理結果ハンドルを指定して、msqlNumFields()を呼び出すと、クエリーが戻したフィールドの数をチェックできます。msqlNumFields()が戻す値は、msqlFetchRow()で抽出したデータ・ベクトルのエレメント数を示します。その他の配列の場合と同様に、データ・ベクトルの終わりを越えてエレメントをアクセスすると、セグメント・エラーが発生することがあります。したがって、抽出したフィールドの数は、あらかじめチェックしておくと良いでしょう。


msqlListDBs()

m_result *msqlListDBs(sock)

	int		sock;;
msqlListDBs()機能を使用すると、mSQLエンジンで利用できるデータベースのリストを作成できます。呼び出しを実行したプログラムには、処理結果ハンドルが戻されます。このハンドルを使用すると、実際のデータベース名をアクセスすることができます。処理結果ハンドルを指定して、msqlFetchRow()を呼び出すと、それぞれの名前をチェックすることが可能です。1回の呼び出しで戻されるm_rowデータ構造には、1つのフィールドが含まれています。このフィールドの値が、利用できるデータベースの名前です。処理結果ハンドルを戻す他の機能と同様に、処理結果ハンドルで識別するデータが不要になった場合、msqlFreeResult()によってそれを削除しなければなりません。


msqlListTables()

m_result *msqlListTables(sock)

	int	sock;;
msqlInitDB()によってデータベースを選択してある場合、msqlListTables()を使用すれば、データベースに定義したテーブルのリストを作成できます。msqlListDBs()と同様に、呼び出しを実行したプログラムには処理結果ハンドルが戻されます。テーブルの名前はデータ行に入れられますが、行のエレメント[0]は現在のデータベースの1番目のテーブルの名前となります。処理結果ハンドルが必要でなくなった場合、msqlFreeResult()を使用して削除しなければなりません。


msqlListFields()

m_result *msqlListFields(sock,tableName);

	int	sock;

	char	*tableName
msqlListFields()を使用すると、特定のテーブルのフィールド情報を表示できます。msqlSelectDB()による選択と同様に、現在のデータベースにあるテーブルの名前を指定して、この機能を呼び出してください。呼び出しを実行したプログラムには、処理結果ハンドルが戻されます。msqlListDBs()またはmsqlListTables()とは異なり、このフィールド情報はデータ行ではなく、フィールド構造に入れられます。この情報をアクセスするには、msqlFetchField()を使用してください。処理ハンドルが必要でなくなった場合、msqlFreeResult()を使用して削除しなければなりません。


msqlClose()

int msqlClose(sock)

	int	sock;
msqlClose()を使用すると、mSQLエンジンへの接続を解除できます。この機能を伸び出す時には、以前接続を設定した時にmsqlConnect()が戻したソケット記述子を指定しなければなりません。