LinuxからInformixにODBCで繋ぐ

前回、informixのDatabaseを見に行く為の[Informix Client SDKをインストール](http://qiita.com/arachan@github/items/933a1acc17821eb3cd81)しました。
ODBCもPerlもPHPもRubyもInformix Client SDKのライブラリーを見に行いきます。
入れていない方はインストールしておいて下さい。
Informix CDSKは /opt/IBM/informix にインストールされているものとします。

今回はODBCでInformixサーバーのデータを見に行くように設定していく。
isqlで接続してデータの内容を表示できるところまで説明します。

## 環境
- Client
    - Ubuntu 15.04 (Debian系)
    - 文字コード: ja_JP.UTF-8
    - Informix CSDK 4.10 Installed(インストール済み)
- Server
    - HP-UX
    - 文字コード： ja_JP.932 (SJIS)
    - Table名 半角カタカタも使う日本語
    - Column名 半角カタカナも使う日本語
    - 文字列の空白にはスペースが埋められている
    - Informix v11.50
    - IPAddress 192.168.0.1

## 概要

設定項目は4つです。

- odbcinst.ini
- odbc.ini
- sqlhosts
- 環境変数

### odbcinst.ini
主にドライバーを指定している。

### sqlhosts
主にinformix Database Serverの場所を指定してる。
他にも接続時のプロトコルやoption等の設定で必要になる。

### odbc.ini
odbcini.iniのドライバーの設定とsqlhostのサーバーの場所を合わせて、
DSN名として登録している。
isqlはこのDSN名を使って接続する。

### 概要図

図解するの下図のようになる。

![informix2odbc.png](https://qiita-image-store.s3.amazonaws.com/0/24550/8e4c5552-557a-8f98-a7c6-65d6c2286c63.png)

### 環境変数
informixに接続する場合、幾つかの環境変数を設定する必要がある。
今回必要な環境変数は下記の通り

- INFORMIXDIR
    - Informix Client SDKが入っているフォルダ
    - /opt/IBM/informix
- INFORMIXSQLHOSTS
    - sqlhostsの場所
    - /opt/IBM/etc/sqlhosts

Linuxの場合はbashである場合が殆どなので、
.bashrcに環境変数を書き込むことになる。

## 手順


### unixODBCをインストール

```bash:Install_UnixODBC
$ sudo apt-get install unixodbc libodbc1 odbcinst1debian2

```

### 設定ファイル

informixのCSDKがインストールされたフォルダにサンプルファイルがあるので眺めてみる。

```bash:SampleConfigrationFiles
$ cd /opt/IBM/informix/etc
$ ls
odbc.ini odbcinst.ini sqlhost.std
....(省略)...

```

ODBCで接続するためにはこの3つのファイルの設定といくつかの環境設定が必要になる。

#### odbcinst.ini
ドライバーの場所やodbc.iniに必要な設定が掛かれている。

今回は/opt/IBM/informixにCSDKがインストールされているので、
DriverとSetupの部分は下記のように書き換える。
Driver=/opt/IBM/informix/lib/cli/iclit09b.so
Setup=/opt/IBM/informix/lib/cli/iclit09b.so

テンプレートとして自分のドキュメントフォルダに保存しておきましょう。

```bash:odbcinst.tpl
$ cp /opt/IBM/informix/etc/odbcinst.ini /home/yusuke/Documents/odbcinst.tpl
$ vi /home/yusuke/Documents/odbcinst.tpl
;---------------------------------
;IBM INFORMIX ODBC Sample File
;
;File:        odbcinst.ini
;--------------------------------
[ODBC Drivers]
IBM INFORMIX ODBC DRIVER=Installed
[IBM INFORMIX ODBC DRIVER] #ドライバー名
Driver=/opt/IBM/informix/lib/cli/iclit09b.so # ドライバーライブラリーの場所
Setup=/opt/IBM/informix/lib/cli/iclit09b.so # ドライバーのセットアップライブラリーの場所
APILevel=1
ConnectFunctions=YYY
DriverODBCVer=03.51 # ODBC Driverのバージョン
FileUsage=0
SQLLevel=1
smProcessPerConnect=Y

```

#### odbc.ini
データベースの場所やodbcinst.iniで設定した情報をもとに、
DSN名を設定する。

自分の環境に合わせて下記のように書き換えてテンプレートにしておく。
自分のドキュメントフォルダに移動しておきましょう。

以下のようにodbc.iniを書き換え

```bash:odbc.tpl
$ vi /opt/IBM/informix/etc/odbc.ini
[MyDB]
Driver=/opt/IBM/informix/lib/cli/iclis09b.so
Description=IBM INFORMIX ODBC DRIVER
Database=mydb
LogonID=admin
pwd=admin
Servername=serverhost
CLIENT_LOCALE=ja_JP.utf8 #Linux側のロケール
DB_LOCALE=ja_JP.932 #Database側のロケール
TRANSLATIONDLL=/opt/IBM/informix/lib/esql/igo4a304.so
```

書き換えたら以下のようにDocuments(ドキュメント)にコピーしておきましょう。

```bash:Documentsにコピー
$ cp /opt/IBM/informix/etc/odbc.ini /home/yusuke/Documents/odbc.tpl
```

odbc.iniで設定しているServernameはsqlhostsで指定する。
sqlhosts.stdをコピーして書き換えることにする。

```bash:sqlhosts.stdをコピー
$ cp /opt/IBM/informix/etc/sqlhosts.std /opt/IBM/informix/etc/sqlhosts

```

#### sqlhosts

以下のように書き換えて保存します。
Windowsで接続に成功しているODBCの設定と同じようにしております。

```bash:sqlhostsを以下のように書き換えて保存
$ sudo vi /opt/IBM/informix/etc/sqlhosts
# The format for the five fields of connectivity information for a database server
# is one line in the UNIX sqlhosts file. as follows:
# <日本語訳> データーベースサーバーの5つの接続情報のフォーマットは1行のUNIXのsqlhostファイルです。　
# 次のように書きます。
# <dbservername><nettype><hostname><servicename><options>
...(省略)....
#コメントアウトする
# demo_no   onipcshm on_hostname on_servername
serverhost onsoctcp 192.168.0.1 1526
```
書き込んだら保存して終了しましょう。

### ODBC ManagerにDriverを登録

odbcinstとodbcのtemplateを自分のDocumentsフォルダーの中に作成しました。
自分のフォルダーに移動して下記のようにドライバーの設定をインストールします。

```bash:odbcinst
$ cd /home/yusuke/Documents
$ sudo odbcinst -i -d -f odbcinst.tpl

```

-i インストール
-d ドライバー
-f テンプレートファイルから


### DSN名を登録

```bash:odbc
$ cd /home/yusuke/Documents
$ sudo odbcinst -i -s -l -f odbc.tpl
```

-i インストール
-s DSN名
-l システム
-f Templateファイルから

とりあえず、isql実行してみます。

```bash:isql実行

$ isql -v MyDB
[01000][unixODBC][Driver Manager]Can't open lib '/opt/IBM/informix/lib/cli/iclis09b.so' : file not found
[ISQL]ERROR: Could not SQLConnect
```

うーん、
あるのにおかしいですね。

```bash:iclis09b.soがあるか確認

$ ls /opt/IBM/informix/lib/cli/iclis09b.so
/opt/IBM/informix/lib/cli/iclis09b.so

```

別のライブラリーを読んでいないのでしょうか？

```bash:lddで調査

$ ldd /opt/IBM/informix/lib/cli/iclis09b.so
	linux-vdso.so.1 (0x00007ffe799f9000)
	libifgls.so => not found
	libifglx.so => not found
```

- libifgls.so => not found
- libifglx.so => not found

この2つが読み込めていないのは、非常に怪しい。

```bash:ライブラリを探す
locate libifgls.so libifglx.so
/opt/IBM/informix/lib/esql/libifgls.so
/opt/IBM/informix/lib/esql/libifglx.so

```

うーん、存在しますね。
Shared Libraryを読み込むようにします。

```bash:SharedLibraryとして読みこむようにする
$ cd /etc/ld.so.conf.d
$ ls /etc/ld.so.conf.d
libc.conf  x86_64-linux-gnu.conf
$ sudo vi /etc/ld.so.conf.d/informix.conf
/opt/IBM/informix
/opt/IBM/informix/lib
/opt/IBM/informix/lib/esql
$ ls
libc.conf  x86_64-linux-gnu.conf informix.conf
$ sudo ldconfig -v | grep libifgls.so
[sudo] password for yusuke:
/sbin/ldconfig.real: パス `/lib/x86_64-linux-gnu' が二回以上与えられました
/sbin/ldconfig.real: パス `/usr/lib/x86_64-linux-gnu' が二回以上与えられました
	libifgls.so -> libifgls.so
/sbin/ldconfig.real: /lib/x86_64-linux-gnu/ld-2.19.so is the dynamic linker, ignoring

```

今度はError内容が変わった。

```bash:UnspecifiedSystemError
$ isql MyDB -v
[S1000][unixODBC][Informix][Informix ODBC Driver]Unspecified System Error =  -11041.

```
Unspecified System Error =  -11041で検索をかけると、
[-11041 trying to connect with PDO_INFORMIX php driver](http://www-01.ibm.com/support/docview.wss?uid=swg21454845)
環境変数を追加せよと書いてある。

### 環境変数追加

しょうがないので、
環境変数を追加する。
最小構成で追加するために少しづつ追加して試してみる。

```bash:環境変数INFORMIXSQLHOSTSを追加
$ cd ~
$ vi ~/.bashrc
...(省略)...
INFORMIXSQLHOSTS=/opt/IBM/informix/etc/sqlhosts
export INFOMRIXSQLHOSTS
$ source ~/.bashrc

# エラー内容変わらず
$ isql -v MyDB
[S1000][unixODBC][Informix][Informix ODBC Driver]Unspecified System Error =  -11041.
```

下記のフォーラムを見る限り、ODBCINIという環境設定は必要なようだ。
例え、odbcinstでDSN名を設定していたとしても。
[[unixODBC-support] unixODBC and Informix](http://mailman.unixodbc.org/pipermail/unixodbc-support/2008-July/001786.html)

```bash:環境変数ODBCINIを追加
# ODBCINIの環境変数を追加してみる
$ vi ~/.bashrc
...(省略)...
INFORMIXSQLHOSTS=/opt/IBM/informix/sqlhosts
export INFOMRIXSQLHOSTS
ODBCINI=/etc/odbc.ini
export ODBCINI
# 保存

# 読み込み
$ source ~/.bashrc
# 接続テスト
$ isql -v MyDB
[S1000][unixODBC][Informix][Informix ODBC Driver][Informix]Unspecified System Error =  -23101.
```

エラー内容が変わった。
エラー内容をまともに取るとLocaleがおかしいとなるけど、
localeはodbc.iniで指定している。
INFORMIXDIRという環境変数も必要かな…。

```bash:環境変数INFORMIXDIRを追加
# INFORMIXDIRという環境変数を追加してみる。
$ vi ~/.bashrc
INFORMIXDIR=/opt/IBM/informix
export INFORMIXDIR
INFORMIXSQLHOSTS=/opt/IBM/informix/sqlhosts
export INFOMRIXSQLHOSTS
ODBCINI=/etc/odbc.ini
export ODBCINI
# 保存

# 読み込み
$ source ~/.bashrc
```


今度こそ繋がるはずです。
接続してみましょう。

```bash:isqlで接続成功!
# こんどこそ接続
$ isql -v MyDB
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

```

接続成功しましたね。
helpコマンドを入力すると大量のテーブルを表示してくれます。

### 参考サイト
[Use Informix ODBC Driver with an ODBC Driver Manager](https://www.ibm.com/developerworks/data/library/techarticle/dm-1108odbcdrivermanager/)

[Getting the ODBC driver from the Informix Client access or SDK working with unixODBC - unixODBC](http://www.unixodbc.org/doc/informix.html)

[IBM RedBook Informix](http://www.redbooks.ibm.com/redbooks/SG247884/wwhelp/wwhimpl/js/html/wwhelp.htm?href=08-06.htm)

[sqlhostsの内容](http://www-01.ibm.com/support/knowledgecenter/SSGU8G_11.50.0/com.ibm.admin.doc/ids_admin_0158.htm?cp=SSGU8G_11.50.0%2F4-4-5)

[[unixODBC-support] unixODBC and Informix](http://mailman.unixodbc.org/pipermail/unixodbc-support/2008-July/001786.html)

[Infomirxエラーコード](http://publibfp.dhe.ibm.com/epubs/pdf/b8886920.pdf)