LinuxからPerlでInformixに接続

>welcome to this crazy time このふざけた時代へようこそ。
君はTOUGH BOY(タフ ボーイ),TOUGH BOY,TOUGH BOY。[^1]

Crazy DB,InformixにPerlで接続してみたいと思います。
Tough Boyな皆様なら、きっとできる。

## 環境

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

## 手順
Perl入学式というのがあるようで勉強になります。
そこにPerlの仮想環境をインストールする方法が書かれています。
plenvをオシャレに設定します。
とにかく長い文章を読むのが嫌いな方は、いきなり まとめ を読んでその通りにやってみて下さい。
躓いたときに、躓いた箇所の手順を見て修正してみるというやり方でも構いません。

### plenvをインストール
予めPerlのBuildに必要なものを入れます。
ざくっとdevelopをgroupインストールすると入ります。

```bash:buildに必要なものをインストール
$ sudo yum groupinstall development

```

```bash:ubuntu/debianの場合
$ sudo apt-get install build-essentials

```

buildに必要なものを入れたので、
plenvを導入していきます。
下記のスクリプトを実行してしまうのが一番お手軽です。

```bash:plenvの導入
$ curl -L http://is.gd/plenvsetup | bash

```

インストール成功と。
plenvでどんなバージョンがインストールできるか見てみましょう。

```bash:plenv実行
$ plenv install list
...(省略)...
5.23.6
```

最新版の5.23.6をインストールします。

```bash:install
$ plenv install 5.23.6
```

インストールできているか確認します。

```bash:インストールされているか確認
$ plenv versions
* system
5.23.6

```

今回は、perlというフォルダを作って、
その中だけPerl 5.23.6 になるようにします。

```bash:perlというフォルダを作る
$ mkdir perl
$ cd perl
```

perlフォルダの中に入ったら、
5.23.6に切り替えます。

```bash:5.23.6に切替
$ plenv local 5.23.6
$ plenv version
5.23.6
$ perl -v

his is perl 5, version 23, subversion 6 (v5.23.6) built for x86_64-linux
with 1 registered patch, see perl -V for more detail)
...(略)...
```

```bash:cpanmをインストール
$ plenv install-cpanm

```

以上でPerlの設定は終了です。
次は、DBD::InformixをCPANでインストールです。
設定項目が多いですよ～。

### DBD::Informixのインストール

DBDはDBIを拡張したモジュールですので、
予めDBIを入れておきます。
さらに、DBD::InformixのBuild時のTestにTest::Podというモジュールが必要です。
予めインストールしておきます。

```bash:DBIとTestPodのインストール
$ cpanm Test::Pod
$ cpanm DBI

```

Perlに関してはマニュアルらしいマニュアルありません。
Informix CSDKが必要なことぐらいです。
ぶっつけ本番でインストールしてみましょう。

```bash:DBD-Informixをインストール
$ cpanm DBD::Informix
...(省略)...
-> N/A
-> FAIL Configure failed for DBD-Informix-2015.1101. See /home/vagrant/.cpanm/wo
rk/1452012501.9051/build.log for details.
```

はい、Build失敗 (T-T
See /home/vagrant/.cpanm/work/1452012501.9051/build.log for details.って書いてあるので、
このlogを眺めてみましょう。

#### INFORMIXDIRをセット

```bash:build.log
$ less /home/vagrant/.cpanm/work/1452012501.9051/build.log
...(省略)...
*** You didn't read the README file!
$INFORMIXDIR is not set
```

「README読んでねえだろ。
$INFORMIXDIRがセットされていない。」って、
cpanでインストールする時代なんでREADMEなんてWebで晒して貰わなきゃ分からんよ。

あえてREADMEなんて読みません。
僕はTOUGH BOYなんでね。

全ての地雷を踏んで安全な道を作り出してやる。

とにかく$INFORMIXDIRという環境変数をセットします。

```bash:INFORMIXDIR環境変数を設定
$ export INFORMIXDIR=/opt/IBM/informix
```

INFORMIXDIR環境変数をセットしたのでもう一度実行してみます。

```bash:もう一度インストール
$ cpanm DBD::Informix
...(省略)...
-> FAIL Configure failed for DBD-Informix-2015.1101. See /home/vagrant/.cpanm/wo
rk/1452558143.7153/build.log for details.
(END)

```

エラーです。
また、buildログを見てみましょう。

#### PATHにINFORMIXDIR/binを追加

```bash:PATHにINFORMIXDIR/binをセットして
$ less /home/vagrant/.cpanm/work/1452558143.7153/build.log for details.
...(省略)...
*** You didn't read the README file!
$INFORMIXDIR/bin is not in $PATH

```

INFORMIXDIR/binをPATHに入れて欲しいようだ。

```bash:INFORMIXDIR/binを追加
$ export PATH=$INFORMIXDIR/bin:$PATH

```

もう一度チャレンジ。

```bash:cpanm実行
$ cpanm DBD::Informix
...(省略)...
-> N/A
-> FAIL Configure failed for DBD-Informix-2015.1101. See /home/vagrant/.cpanm/work/1452558877.7339/build.log for details.
```

またダメですね。
build.logを見てみましょう。

#### INFORMIXSERVERをセット

```bash:INFORMIXSERVER環境変数をセットすべき
$ less  /home/vagrant/.cpanm/work/1452558877.7339/build.log for details.
...(略)...
*** Environment variable $INFORMIXSERVER is not set and should be!
...
```
うーん、INFORMIXSERVERをセットしろと。

```bash:INFORMIXSERVERをセット
$ export INFORMIXSERVER=servername

```

もう一度実行

```bash:cpanm実行
$ cpanm DBD::Informix cpanm
--> Working on DBD::Informix
Fetching http://www.cpan.org/authors/id/J/JO/JOHNL/DBD-Informix-2015.1101.tar.gz
 ... OK
Configuring DBD-Informix-2015.1101 ... N/A
! Configure failed for DBD-Informix-2015.1101. See /home/vagrant/.cpanm/work/1452559996.7608/build.log for details.

```

build.logを見てみます。

#### LD_LIBRARY_PATHを追加する

```bash:libifsql.soが読めない
$ less /home/vagrant/.cpanm/work/1452559996.7608/build.log
./esqltest: error while loading shared libraries: libifsql.so: cannot open share
d object file: No such file or directory

If the esqltest program did not produce any output:
    This suggests that there is a problem with the ESQL/C runtime
    environment, or with the database permissions (in which case, you
    should have seen diagnostics from the esqltest program itself).
    Consider whether the shared library path environment variable (eg
    LD_LIBRARY_PATH or SHLIB_PATH) is set correctly.

```

ざっくり言うと、libifsql.soが読めないからLD_LIBRARY_PATHをセットしろと。
libifsql.soの場所をlocateで検索します。

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

/opt/IBM/informix/lib/esql
にあるようです。
それをLD_LIBRARY_PATHに指定します。

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

```

もう一度。

```bash:
$ cpanm DBD::Informix
--> Working on DBD::Informix
Fetching http://www.cpan.org/authors/id/J/JO/JOHNL/DBD-Informix-2015.1101.tar.gz
 ... OK
Configuring DBD-Informix-2015.1101 ... N/A
! Configure failed for DBD-Informix-2015.1101. See /home/vagrant/.cpanm/work/1452562266.8182/build.log for details.

```

まだ、Buildできませんね。
build.logを読んでみましょう。

```bash:libifasf.soがない
$ less /home/vagrant/.cpanm/work/1452562266.8182/build.log
...(略)...
./esqltest: error while loading shared libraries: libifasf.so: cannot open share
d object file: No such file or directory
...
```

libifasf.soというライブラリが読めて無いようです。
何処にあるのでしょうか？
探してみましょう。

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

LD_LIBRARY_PATHには /opt/IBM/informix/lib も追加する必要があるようです。
下記のようにして追加します。

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

```

もう一度やってみます。

```
[vagrant@localhost perl]$ cpanm DBD::Informix cpanm/work/145
--> Working on DBD::Informix
Fetching http://www.cpan.org/authors/id/J/JO/JOHNL/DBD-Informix-2015.1101.tar.gz
 ... OK
Configuring DBD-Informix-2015.1101 ... N/A
! Configure failed for DBD-Informix-2015.1101. See /home/vagrant/.cpanm/work/1452562640.8324/build.log for details.

```

懲りずにbuild.logを見てみます。

#### INFORMIXSQLHOSTSを追加

```bash:sqlhostsを指定せよ
$ less /home/vagrant/.cpanm/work/1452562640.8324/build.log
...(略)...
SQL: -25553: Sqlhosts file not found or cannot be opened.

SQL: -25553: Sqlhosts file not found or cannot be opened.

ESQLTEST Program Running:
@(#)$Id: esqltest.ec,v 2015.1 2014/07/28 07:16:36 jleffler Exp $
        $INFORMIXDIR is set to '/opt/IBM/informix'.
        $INFORMIXSERVER is set to 'servername'.
        $DBI_DBNAME unset - defaulting to 'stores'.
        $DBD_INFORMIX_DATABASE unset - defaulting to 'stores'.
        $DBD_INFORMIX_DATABASE2 unset - defaulting to 'stores'.
        $DBD_INFORMIX_USERNAME is unset.
        $DBD_INFORMIX_USERNAME2 is unset.
        $DBD_INFORMIX_PASSWORD is unset.
        $DBD_INFORMIX_PASSWORD2 is unset.
Testing connection to stores
        1: CONNECT TO 'stores' - no user info
Testing concurrent connection to stores
        1: CONNECT TO 'stores' - no user info
...(略)...
```

SQL:-25553:Sqlhosts file not found or cannto be opened.
sqlhostsファイルが見つからないか開かないと言っています。
Informixでは　/opt/IBM/informix/etc/sqlhost　に、
sqlhostsを書き込んで、
$INFORMIXSQLHOSTSという環境変数を設定します。

```bash:sqlhostsの内容を書き込む
$ sudo cp /opt/IBM/informix/etc/sqlhosts.std /opt/IBM/informix/etc/sqlhosts
$ sudo vi /opt/IBM/informix/etc/sqlhosts
# <dbservername> <nettype> <hostname> <servicename> <options>
servername  onsoctcp 192.168.0.1 1526
#保存
```

```bash:INFORMIXSQLHOSTS環境変数を指定
$ export INFORMIXSQLHOSTS=/opt/IBM/informix/etc/sqlhosts

```

#### 各種DBIの環境変数を設定

更に、下記の環境変数もセットしておきます。
ESQLTEST Programの時に使っているようですので。

- DBI_DBNAME
- DBD_INFORMIX_DATABASE
- DBD_INFORMIX_USERNAME
- DBD_INFORMIX_PASSWORD

```bash:その他の環境変数を全てセット
$ export DBI_DBNAME=mydb
$ export DBD_INFORMIX_DATABASE=mydb
$ export DBD_INFORMIX_USERNAME=user
$ export DBD_INFORMIX_PASSWORD=passowrd

```

もう一度。

```bash:もう一度
$ cpanm DBD::Informix
Configuring DBD-Informix-2015.1101 ... N/A
! Configure failed for DBD-Informix-2015.1101. See /home/vagrant/.cpanm/work/1452578586.11759/build.log for details.
```

build.logを読みます。

#### DB_LOCALEを追加

```bash:データベースのLocaleが違う
$ less /home/vagrant/.cpanm/work/1452578586.11759/build.log
...(省略)...
SQL: -23197: Database locale information mismatch.

```

Databaseのlocaleが違うみたいだ。
informixではlocaleも環境変数で指定する。 (根拠は?)

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

```

もう一度やってみる

```bash:もう一度
$ cpanm DBD::Informix
--> Working on DBD::Informix
Fetching http://www.cpan.org/authors/id/J/JO/JOHNL/DBD-Informix-2015.1101.tar.gz
 ... OK
Configuring DBD-Informix-2015.1101 ... N/A
! Configure failed for DBD-Informix-2015.1101. See /home/vagrant/.cpanm/work/1452580037.12117/build.log for details.
```

build.logを読みます。

#### CLIENT_LOCALEを追加

```bash:client_localeを設定せよ
less /home/vagrant/.cpanm/work/1452580037.12117/build.log
...(略)...
-23104 Error opening required code-set conversion object file.
```

このエラーが出た場合は、client_localeを環境変数で設定します。
[Error opening required code-set conversion object file](https://groups.google.com/forum/#!msg/node-ibm_db/322tEhEc96E/wKumi983CQAJ)

```bash:client_locale設定
export CLIENT_LOCALE=ja_JP.utf8
```

また、Buildしてみましょう。

```bash:
$ cpanm DBD::Informix
Building and testing DBD-Informix-2015.1101 ... FAIL
! Installing DBD::Informix failed. See /home/vagrant/.cpanm/work/1452580376.12221/build.log for details. Retry with --force to force install it.
```

もうそろそろbuildに成功してもいい頃なんですが・・・。

#### cpanm DBD::Informix --force

```bash:
$ less /home/vagrant/.cpanm/work/1452580376.12221/build.log
Test Summary Report
-------------------
t/t46chpblk.t     (Wstat: 65280 Tests: 3 Failed: 1)
  Failed test:  3
  Non-zero exit status: 255
  Parse errors: Bad plan.  You planned 22 tests but ran 3.
Files=59, Tests=839, 22 wallclock secs ( 0.50 usr  0.07 sys +  4.64 cusr  1.16 c
sys =  6.37 CPU)
Result: FAIL
Failed 1/59 test programs. 1/839 subtests failed.
make: *** [test_dynamic] Error 255
-> FAIL Installing DBD::Informix failed. See /home/vagrant/.cpanm/work/145258037
6.12221/build.log for details. Retry with --force to force install it.
```

何やら1つテストに失敗しているようです。
DatabaseがANSIでない為にTestがPassしないようです。
Table名が日本語名、そして何故かShiftJIS使っているDBなんで無理もありません。

> ルーク、フォースを使え [^2]

ん! 何か聞こえた？
Forceを使って無理やりインストールするか。


```bash:forceを使ってみた
[vagrant@localhost perl]$ cpanm DBD::Informix --force
--> Working on DBD::Informix
Fetching http://www.cpan.org/authors/id/J/JO/JOHNL/DBD-Informix-2015.1101.tar.gz
 ... OK
Configuring DBD-Informix-2015.1101 ... OK
Building and testing DBD-Informix-2015.1101 ... FAIL
! Testing DBD-Informix-2015.1101 failed but installing it anyway.
Successfully installed DBD-Informix-2015.1101
1 distribution installed

```

やっとインストール成功です。

### Perlで接続

```perl:informixに接続
$ vi ifxcnnt.pl
#! /usr/bin/env perl

use DBI qw(:sql_types);
use DBD::Informix qw (:ix_types);
use strict;
use warnings;
use Data::Dumper;

my $dbh=DBI->connect("DBI:Informix:mydb","user","password");

my $stmt="SELECT * FROM 商品m WHERE 商品cd=1";
my $sth=$dbh->prepare($stmt);
$sth->execute();
my @results=$sth->fetchall_arrayref([4]); #4行目の商品名を取得
print Dumper @results;


$dbh->disconnect();
```

実行してみます。

```bash:perlで接続
$ perl ifxcnnt.pl
$VAR1 = [
          [
            '僕の商品
                                              '
          ]
        ];

```

商品名も出力されました。
一応は成功です。

## まとめ

ざっと以下のようにコマンドを打っていけばインストールできる。

```bash:perl準備
$ sudo yum groupinstall development
$ curl -L http://is.gd/plenvsetup | bash
$ mkdir ~/perl
$ cd perl
$ plenv install 5.23.6
$ plenv local 5.23.6
$ plenv version
5.23.6
$ plenv install-cpamn
$ cpanm Test::Pod
$ cpanm DBI
```

```bash:informixで必要な環境変数をセット
export INFORMIXDIR=/opt/IBM/informix
export PATH=INFORMIXDIR/bin:$PATH
export INFORMIXSERVER=servername
export LD_LIBRARY_PATH=/opt/IBM/informix/lib/esql:/opt/IBM/informix/lib/
```

```bash:DBIで必要な環境変数をセット
export DBI_DBNAME=mydb
export DBD_INFORMIX_DATABASE=mydb
export DBD_INFORMIX_USERNAME=user
export DBD_INFORMIX_PASSWORD=passowrd
```

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

```bash:cpanm
cpanm DBD::Informix --force
```

## 参考文献
[Perlの環境構築 - Perl入学式](https://github.com/perl-entrance-org/workshop-2014-01/blob/master/build_perl.md)
[DBD::Informix - CPAN](http://search.cpan.org/~johnl/DBD-Informix/Informix.pm)
[DBD::Informix - README](http://cpansearch.perl.org/src/JOHNL/DBD-Informix-2015.1101/README)

[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)


[Shared libraries - IBM Redbook](https://www.ibm.com/docs/ja/informix-servers/14.10?topic=unix-linking-shared-informix-general-libraries-esqlc-module)
Informix CSDKのShared LibraryはLinux(Bash)の場合だと、
LD_LIBRARY_PATHという環境変数で指定することが明記されている。

Informixでは多くの環境変数をセットする必要があります。
下記はここで設定した環境変数を公式Helpで検索した結果です。

- [INFORMIXSERVER環境変数](https://www.ibm.com/docs/ja/informix-servers/14.10?topic=products-informixserver-environment-variable)
- [INFORMIXDIR環境変数](https://www.ibm.com/docs/ja/informix-servers/14.10?topic=products-informixdir-environment-variable)
- [INFORMIXSQLHOSTS環境変数](https://www.ibm.com/docs/ja/informix-servers/14.10?topic=products-informixsqlhosts-environment-variable)
- [CLIENT_LOCALE環境変数](http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.glsug.doc/ids_gug_065.htm?lang=ja)
- [DB_LOCALE環境変数](http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.glsug.doc/ids_gug_068.htm?lang=ja)

[^1]: 北斗の拳2のオープニング TOUGH BOY
[^2]: Star Wars Episode 4 デススター攻撃時、ルークに聞こえたオビワンの声