MindでMySQL(Linux)にクエリーする（1-API準備編）

# はじめに

だいぶ前2017年ごろMindユーザーの@MindZanmaiさんのご質問に回答して、MindでLinux上のMySQLにクエリーする方法を詳しくコメントに解説しておりまして、最近SQLServerへのクエリ記事を書かれている@mylifewithviolinさんのおすすめもあって記事にまとめておくことにしました。内容は少し古いですが、MindのDB接続関連の情報は少ないので参考になれば幸いです。

# Mindから「外の」APIを呼び出す

まず最初に、Mindから「外の」APIを呼び出すお話しから。
そのような機構が一つ前のMind Ver7から入っています。
たとえばWindows版Mindには file/fwinAPI.src に次のような単語定義があります。
```mind
Ｗｉｎｄｏｗｓディレクトリは　処理単語　.Y
　（［文字列実体情報］　→　ディレクトリ名）
　　　　　　　　クライアント実体は　文字列実体情報
        実績長さは　　　　　変数
　　　　パスバッファで　省略時の文字列実体に積み換え　クライアント実体に　入れ
    クライアント実体を　クリアし
    クライアント実体を　文字列実体を参照し　アドレスを得て、
    　クライアント実体の　追加余裕をつみ、
    　　"kernel32"と　"GetWindowsDirectoryA"で
    　　　ＡＰＩ呼出し２　実績長さに　入れ
```

上記で使っている「ＡＰＩ呼出し２」というのがその一つです。kernel32 というDLLの中にある GetWindowsDirectoryA() という関数というかAPIを呼び出しています。ということで、Mindには「このような機構がある」‥というだけでなく、Windows版においては実際にわずかですが使っています。

Windows版だけでなくLinux版でも同様の機構が入っています。Linux環境ではかなり以前に、言語工学さんが販売されていたシソーラス辞書APIというものを検索エンジンMindSearchから使ったことがあります。実はそのときに書いた共有ライブラリ呼出しのソースがMindのLinux版のAPI呼び出し機構で使われています。Mind 8をリリースしたときも、この辞書APIを呼び出すことで動作確認をしました。

# DLL（ダイナミックリンクライブラリ）について

「DLL」はWindowsの世界で使われている呼称ですが、Linuxでは「共有ライブラリ」という呼び方が多いようです。概念的には同じようなものです。どちらもユーザプログラムから静的に、あるいは動的にリンクし、DLL内にある関数を呼び出すことができます。

## DLL（Linuxは共有ライブラリCL）の動的リンクについて

Mind以外の言語では静的にリンクする方法で使われることが多いと思いますが、Mindでは静的リンクはカーネルのC記述レベルで修正とmakeする話になり大袈裟になってしまうので、動的リンクで使うことになります。

動的リンクとは、ユーザプログラムが起動してからプログラムの指示でDLLをメモリ上にロードし、その中に含まれる関数(API)を呼び出す方法です。このあたりすの仕組みは基本的にWindows/Linuxで同じです。

# MySQLの共有ライブラリ

MySQLの共有ライブラリのうち、クライアントプログラム向けのインターフェースとしての共有ライブラリは libmysqlclient.so であることが分かります（さらに末尾に数字が付くことも）。

次に注意するのが、64bit版と32bit版の違いです。今では多くの場合、MySQLの64bit版がインストールされると思いますが、Mindからは64bit向けDLLは呼べないなめ、32bit向けのDLLが必要になります。

まず、64bit, 32bit を問わず、そもそも libmysqlclient.so (あるいは libmysqlclient.so* ) がマシン内に存在するか確認を願います。
ありがちな場所としては、/usr/lib, /usr/lib64/, /usr/local/lib, /usr/local/lib64 あたりかと思います。/usr 直下で find . -name 'libmysqlclient*' などとすれば見つかると思います。

見つかったとして、その場所が lib/ 内ならOK、そうでなくてたとえば lib64/ 以下にしか無いようだと、前記したように別途、32bit版の共有ライブラリをインストールする必要があるかと思います。

# MySQLの共有ライブラリを動的ロードする

MySQLとの接続という前に、Mindのプログラムから、MySQLの共有ライブラリを動的ロードする必要があります。そのための単語が以下の２つです。

```mind
モジュールをロードとは　（モジュール名　→　モジュールハンドル(0はエラー)）
モジュールを解放とは　（モジュールハンドル　→　・）
```

上記で言う「モジュール名」とはDLL名(Windows)または共有ライブラリ名(Linux)のことです。
ロードした共有ライブラリは最後に解放してあげる必要があり、それが「モジュールを解放」です。

Mindのプログラムとしては以下のようになると思います。

```mind
モジュールハンドルは　変数。

MySQLの共有ライブラリをロードとは　（・　→　真偽）
     "/usr/～～/～.so"で　モジュールをロードし　モジュールハンドルに　入れ
     モジュールハンドルが　ゼロ以外を　返すこと。

MySQLの共有ライブラリを破棄とは　（・　→　・）
     モジュールハンドルが　ゼロ以外
          ならば　モジュールハンドルで　モジュールを解放し
               モジュールハンドルを　クリアする　　※←二度呼ばれることに備え

          つぎに。

メインとは
　　　　「共有ライブラリをロードする」
　　　　MySQLの共有ライブラリをロードし　偽？
　　　　　　　　ならば　（何かエラー処理し）　　※重大エラーでもいい
　　　　　　　　　　　　終り
　　　　　　　　つぎに

　　　　「ロード成功」を　一行表示し

　　　　「共有ライブラリを破棄する」を　一行表示し
　　　　MySQLの共有ライブラリを破棄する。
```

上のプログラムでは、冒頭で「モジュールハンドル」という大域変数を定義していますが、共有ライブラリに対して何かする場合にはかならずこのハンドルが必要になるため大域変数に入れておきます。

# 関数アドレスの取得

次に関数アドレスの取得です。
共有ライブラリ内の関数をMindの中に素で書くわけにはいきません。関数のアドレスを知り、そのアドレスをもって間接的にCallする形になります。関数のアドレスを知るために以下の処理単語があります。

```mind
モジュールの関数アドレスを得るとは　（モジュールハンドル、関数名　→　関数アドレス）
　　　　※　エラーリターンが有る　※
```

上記を使い、MySQL共有ライブラリの関数群のアドレスを取得するには以下のような感じになります。

```mind
mysql_connectアドレスは　変数。
mysql_closeアドレスは  　変数。
※mysql_・・・アドレスは 　変数。
※mysql_・・・アドレスは 　変数。

mysql関数アドレス群を取得とは　（・　→　・）
　　（エラーリターンがあるので「エラー？」で調べよ）
　　　　モジュールハンドルと　"mysql_connect"で　モジュールの関数アドレスを得て
　　　　mysql_connectアドレスに　入れ
　　　　エラー？
　　　　　　　　ならば　終り
　　　　　　　　つぎに
　　　　モジュールハンドルと　"mysql_close"で　モジュールの関数アドレスを得て
　　　　mysql_closeアドレスに　入れ
　　　　エラー？
　　　　　　　　ならば　終り
　　　　　　　　つぎに
※　　（当初は上だけで良いです。本格的に実験するには他の関数群も取得してください）
※　　　　モジュールハンドルと　"・・・"で　モジュールの関数アドレスを得て
※　　　　～略～
※　　　　モジュールハンドルと　"・・・"で　モジュールの関数アドレスを得て
※　　　　～略～
※　　　　モジュールハンドルと　"・・・"で　モジュールの関数アドレスを得て
※　　　　～略～
　　　　。

メインとは
　　　　「共有ライブラリをロードする」
　　　　MySQLの共有ライブラリをロードし　偽？
　　　　　　　　ならば　（何かエラー処理し）　　※重大エラーでもいい
　　　　　　　　　　　　終り
　　　　　　　　つぎに
　　　　「ロード成功」を　一行表示し

　　　　「関数アドレス群を取得」を　一行表示し
　　　　mysql関数アドレス群を取得し
　　　　「取得成功」を　一行表示し

　　　　「共有ライブラリを破棄する」を　一行表示し
　　　　MySQLの共有ライブラリを破棄する。
```

# おわりに

今回はここまでです。次回はMySQLへの接続処理について記述します。