LinuxからRubyでInformixに接続

Rubyでinformixに接続してみようと思う。
rbenvの仮想環境を使う予定だったが、
gem install ruby-informixを実行すると、
informixc.oにコンパイルできないというErrorがでて、
ruby-informixがインストールできない為に諦めた。

System環境のRubyとruby-gemを使うことにする。

## 環境

- Client
    - CentOS7 (Linux)
    - ja_JP.UTF-8 (日本語UTF-8)
    - Informix CSDK Installed
- Server
    - HP-UX
    - ja_JP.932 (Shift-JIS)


## 手順
Informix CSDKをインストールします。
手順は僕の[Informix Client SDKをInstall for Linux](http://qiita.com/arachan@github/items/933a1acc17821eb3cd81)を参照。

### Rubyをインストール

```bash:CentOS/RedHat
$ sudo yum install ruby ruby-devel

```

```bash:ubuntu/debian
$ sudo apt-get install ruby ruby-dev

```

### Ruby-informixをインストール
いきなりruby-informixをインストールしてみる

```bash:ruby-informix
$ gem install ruby-informix
Fetching: ruby-informix-0.8.0.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing ruby-informix:
        ERROR: Failed to build gem native extension.

    /usr/bin/ruby extconf.rb
Set the Informix environment variables before installing this library
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib64
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/usr/bin/ruby


Gem files will remain installed in /home/vagrant/.gem/ruby/gems/ruby-informix-0.
8.0 for inspection.
Results logged to /home/vagrant/.gem/ruby/gems/ruby-informix-0.8.0/ext/gem_make.
out
```

#### INFORMIXDIR環境変数をセット

長いエラーメッセージですが、
**Set the Informix environment variables before installing this library**
に注目。
Informix環境変数をセットしてと書いてあるので、
INFORMIXDIRだけSetしてみましょう。


```bash:INFOMIXDIR
export INFORMIXDIR=/opt/IBM/informix
```

もう一度実行してみましょう。

```bash:install_ruby-informix
$ gem install ruby-informix
Building native extensions.  This could take a while...
Successfully installed ruby-informix-0.8.0
Parsing documentation for ruby-informix-0.8.0
unable to convert "\xD0" from ASCII-8BIT to UTF-8 for lib/informixc.so, skipping

Installing ri documentation for ruby-informix-0.8.0
1 gem installed
```

成功です。

## RubyでInformixに接続してみる

まずはRubyのソースファイルを作ります。

```bash:informixに接続するSource作成
$ vi ifxruby.rb
```

```rb:ifxruby.rb
require 'informix'

db=Informix.connect('dbname@servername',user='username',password='password')

cursor=db.cursor("select * from 売上d where 売上伝票no=997176")
cursor.open.each{ |row|
        puts row[24]
}.close

```

これを実行してみると

```bash:execute_ifxruby.rb
$ ruby ifxruby.rb
/usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require': libifsql.so: cannot open shared object file: No such file or directory - /home/vagrant/.gem/ruby/gems/ruby-informix-0.8.0/lib/informixc.so (LoadError)
        from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
...(略)...
```

### LD_LIBRARY_PATH環境変数を設定

盛大にエラーが出ました。
**require libifsql.so:cannot open shared object file**
に注目しましょう。

まずは、libifsql.soが何処にあるか検索してみます。

```bash:libifsql.so
$ locate libifsql.so
/opt/IBM/informix/lib/esql/libifsql.so
```

上記の場所にあるようです。
この場所にPATHを通せばいいのでしょうね。
そこで、LD_LIBRARY_PATHに下記の場所を追加します。


```bash:LD_LIBRARY_PATH
$ export LD_LIBRARY_PATH=/opt/IBM/informix/lib/esql

```


```bash:execute_ifxruby.rb
$ ruby ifxruby.rb
/usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require':
libifasf.so: cannot open shared object file: No such file or directory - /home/vagrant/.gem/ruby/gems/ruby-informix-0.8.0/lib/informixc.so (LoadError)

```

**require libifasf.so:cannot open shared object file**
に注目しましょう。
libifasf.soの場所を探します。

```bash:
$ locate libifasf.so
/opt/IBM/informix/lib/libifasf.so

```

上記の場所をLD_LIBRARY_PATHに追加します。

```bash:LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/opt/IBM/informix/lib/:$LD_LIBRARY_PATH

```

### sqlhostsファイルの作成

```bash:sqlhosts
$ ruby ifxruby.rb
/home/vagrant/.gem/ruby/gems/ruby-informix-0.8.0/lib/informix.rb:101:in `initialize':
Sqlhosts file not found or cannot be opened. (Informix::DatabaseError)
```

sqlhostsファイルが開かないと言っています。
これは /opt/IBM/informix/etc/sqlhosts の事です。
sqlhostsを作ります。

```bash:sqlhosts.stdを元にsqlhostsを作成
$ sudo cp /opt/IBM/informix/etc/sqlhosts.std /opt/IBM/informix/etc/sqlhosts
```

```bash:
$ sudo vi /opt/IBM/informix/etc/sqlhosts
...(略)....
# <dbservername> <nettype> <hostname> <servicename> <options>
servername onsoctcp        192.168.0.1      1526
#保存する

```

### INFORMIXSERVER環境変数

```bash:
$ ruby ifxruby.rb
/home/vagrant/.gem/ruby/gems/ruby-informix-0.8.0/lib/informix.rb:101:in `initialize':
Environment variable INFORMIXSERVER must be set. (Informix::DatabaseError)
```

**Environment variable INFORMIXSERVER must be set.**
INFORMIXSERVER環境変数をセットすべきと書いてあります。
セットします。

```bash:INFORMIXSERVER環境変数
$ export INFORMIXSERVER=servername

```

### DB_LOCALE環境変数をセット

```bash:DB_LOCALEをセットせよ
$ ruby ifxruby.rb
/home/vagrant/.gem/ruby/gems/ruby-informix-0.8.0/lib/informix.rb:101:in `initialize':
Database locale information mismatch.(Informix::DatabaseError)
```

Database locale information mismatchと言われてしまっています。
DB_Locale環境変数で正しいDatabase localeをセットします。



```bash:
export DB_LOCALE=ja_JP.932
```

### CLIENT_LOCALE環境変数をセット

```bash:
$ ruby ifxruby.rb
/home/vagrant/.gem/ruby/gems/ruby-informix-0.8.0/lib/informix.rb:101:in `initialize':
SQL ERROR: SQLCODE -23104 (sorry, no GET DIAGNOSTICS information available) (Informix::OperationalError)
```

**SQLCODE -23104**　に注目
[IBM Informix Messages and Corrections](http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.em.doc/errors.html)を見てみます。

> -23104 必要なコードセット変換オブジェクトファイルをオープン中にエラーが発生しました。
>
> 指定された2つのコードセットに対するコード変換(定義)ファイルが存在しません。環境変数 DB_LOCALE、またはCLIENT_LOCALEがエラー場内の発生となる間違った値に設定された可能性があります。ファイルが無かったり、ファイル内の情報が文字化けしてた入りすることも考えられます。環境変数 CLIENT_LOCALE、またはDB_LOCALEの値を確認して下さい。 ....


CLIENT_LOCALEはセットしていません。
CLIENT_LOCALE環境変数をセットしてみます。

```bash:CLIENT_LOCALEをセット
export CLIENT_LOCALE=ja_JP.utf8
```

今度こそ。

```bash:売上dの中の商品名
$ ruby ifxruby.rb
電気ローソク灯　１本立　茶　小

```

成功です！

## まとめ

```bash:ruby環境準備(CentOS/RedHat)
$ sudo yum install ruby ruby-devel
```

```bash:ruby環境準備(Ubuntu/Debian)
$ sudo apt-get install ruby ruby-dev

```

```bash:INFORMIXDIR
$ export INFORMIXDIR=/opt/IBM/informix
```

```bash:ruby-informix
$ gem install ruby-informix
Building native extensions.  This could take a while...
Successfully installed ruby-informix-0.8.0
Parsing documentation for ruby-informix-0.8.0
unable to convert "\xD0" from ASCII-8BIT to UTF-8 for lib/informixc.so, skipping

Installing ri documentation for ruby-informix-0.8.0
1 gem installed
```

```bash:EMVIRONMENT_VALUE
$ export LD_LIBRARY_PATH=/opt/IBM/informix/lib/:/opt/IBM/informix/lib/esql
$ export DB_LOCALE=ja_JP.932
$ export CLIENT_LOCALE=ja_JP.utf8
$ export INFORMIXSERVER=servername

```

```bash:sqlhosts作成
$ sudo cp /opt/IBM/informix/etc/sqlhost.std /opt/IBM/informix/etc/sqlhost
$ vi /opt/IBM/informix/etc/sqlhost
....(略)...
# <dbservername> <nettype> <hostname> <servicename> <options>
servername onsoctcp        192.168.0.1      1526
#保存する
```

```bash:ifxruby.rbを作成
$ vi ifxruby.rb
```

```rb:ifxruby.rb
require 'informix'

db=Informix.connect('dbname@servername',user='username',password='password')

cursor=db.cursor("select * from 売上d where 売上伝票no=1")
cursor.open.each{ |row|
        puts row[24]
}.close
```

```bash:run_ifxruby.rb
$ ruby ifxruby.rb
電気ローソク灯　１本立　茶　小

```

## 参考文献

[ruby-informix - ruby-gem](https://rubygems.org/gems/ruby-informix/versions/0.8.0)
[ruby-informix - github](https://github.com/santana/ruby-informix)
[IBM Informix Messages and Corrections](http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.em.doc/errors.html)