Node.js + node-ibm_db で Db2 に接続してSELECT文を実行する


Node.jsでDb2にアクセスしてみました。
Db2導入済みのLinux環境に、Node.js/node-ibm_db をインストールするところからメモを残します。

## Node.jsからDb2にアクセスするための前提
* Db2サーババージョンがV10.5.0.4以上であること
* クライアントバージョンは制限なし

## 環境
| 項目 | バージョン |
|:------|:------|
| Linux  | CentOS Linux 7 (Core)  |
| npm  | 6.14.4  |
| ibm_db  | 2.6.4  |
| Db2  | 11.5.0  |

## Node.js のセットアップ

### 1. Node.js インストール・イメージのダウンロード
Windowsにいったんダウンロードして、LinuxへWinSCPで転送。
https://nodejs.org/en/download/

### 2. ファイル展開
(権限の都合上、rootユーザで実行)
どのディレクトリに展開するかは環境ごとのルールに従うと良さそうですが
個人で使える環境なので、適当なところに展開。

```
cd /opt
tar xvzf /tmp/node-v12.16.2-linux-x64.tar.gz
```

### 3. シンボリックリンク作成
(権限の都合上、rootユーザで実行)

```
ln -s node-v12.16.2-linux-x64 node
```

### 4. パス設定
node、npm等のコマンドにパスを通すため、以下3つの環境変数をexportしておく。
都度やるのも面倒なので Node.jsアプリを動かすユーザの.bashrc に記述。

```

export NODE_HOME=/opt/node
export NODE_PATH=$NODE_HOME/lib/node_modules
export PATH=$NODE_HOME/bin:$PATH
```

### 5. 初期化
node-ibm_db をインストールする前に、カレントディレクトリにpackage.jsonを作成。
対話式コマンドで色々聞かれますが、他の方々のQiita等見ていると全部EnterでもOKらしいので、ここは素直に全Enter。

```
npm init
```


## node-ibm_db ドライバーのインストール
インストール済みのドライバーを使わせたい場合にはIBM_DB_HOME環境変数でドライバーインストールパスを設定しておくと、CLIドライバのダウンロードは回避されてローカルのドライバが使われるようです。
IBM_DB_HOME環境変数を設定せず npm install コマンドを実行すると、最新バージョンのドライバが都度ダウンロードされます。

```
npm install ibm_db
```

標準出力：

```

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (build)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /database/config/db2inst1/node_modules/ibm_db/build/package.json:

{
  "name": "build",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)
[db2inst1@7471dc6b3181 build]$
[db2inst1@7471dc6b3181 build]$
[db2inst1@7471dc6b3181 build]$ npm install ibm_db
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142

> ibm_db@2.6.4 install /database/config/db2inst1/node_modules/ibm_db/build/node_modules/ibm_db
> node installer/driverInstall.js

platform =  linux , arch =  x64 , node.js version =  v12.16.2
make version = GNU Make 3.82
Downloading DB2 ODBC CLI Driver from https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/linuxx64_odbc_cli.tar.gz...

42.67% | 9011200 bytes downloaded out of 21119049 bytes.
100.00% | 21119049 bytes downloaded out of 21119049 bytes.

****************************************
You are downloading a package which includes the Node.js module for IBM DB2/Informix.  The module is licensed under the Apache License 2.0. The package also includes IBM ODBC and CLI Driver from IBM, which is automatically downloaded as the node module is installed on your system/device. The license agreement to the IBM ODBC and CLI Driver is available in undefined   Check for additional dependencies, which may come with their own license agreement(s). Your use of the components of the package and dependencies constitutes your acceptance of their respective license agreements. If you do not accept the terms of any license agreement(s), then delete the relevant component(s) from your device.
****************************************

Downloading and extraction of DB2 ODBC CLI Driver completed successfully ...

make: Entering directory `/database/config/db2inst1/node_modules/ibm_db/build/node_modules/ibm_db/build'
  CXX(target) Release/obj.target/odbc_bindings/src/odbc.o
  CXX(target) Release/obj.target/odbc_bindings/src/odbc_connection.o
  CXX(target) Release/obj.target/odbc_bindings/src/odbc_statement.o
  CXX(target) Release/obj.target/odbc_bindings/src/odbc_result.o
  SOLINK_MODULE(target) Release/obj.target/odbc_bindings.node
  COPY Release/odbc_bindings.node
make: Leaving directory `/database/config/db2inst1/node_modules/ibm_db/build/node_modules/ibm_db/build'

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN build@1.0.0 No description
npm WARN build@1.0.0 No repository field.

+ ibm_db@2.6.4
added 102 packages from 96 contributors and audited 184 packages in 73.863s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities

```

WARNING(WARN) が2つ出るのは、導入失敗というわけではなくて
npm init時にDescriptionなどちゃんと入力すれば出なくなります。(今回は全項目で空Enter)
次はこれを試してみたいなと思います---> [Qiita「面倒なので`npm init`を実行しない」](https://qiita.com/sugoroku_y/items/8c1bda7916fd8b377036)


(備忘録：IBM_DB_HOME環境変数を設定した状態では、このようなメッセージが出力される)

```
Downloading of clidriver skipped - build is in progress...
```


## コード

Db2データベースに接続して、SELECTを行うプログラム。

接続情報(DBサーバホスト名、ポート番号、DB名、ユーザ名、パスワード)は
変更に対応しやすいよう外出しにします。
(※本来パスワードを平文ファイルに記述するべきではありませんがお試しということで。)


```javascript:settings.js
exports.host = 'localhost';
exports.port = 50000;
exports.dbname = 'TESTDB';
exports.username = 'db2inst1';
exports.password = 'xxxxxxxx';
```


```javascript:test1.js
var ibm_db = require( 'ibm_db' );
var settings = require( './settings' );

var db_con_str =
"DRIVER={DB2}"
  + ";DATABASE=" + settings.dbname
  + ";HOSTNAME=" + settings.host
  + ";PORT=" + settings.port
  + ";PROTOCOL=TCPIP"
  + ";UID=" + settings.username
  + ";PWD=" + settings.password
;

var sql_str = "select C1, C2 from T3";

ibm_db.open( db_con_str, function( err, conn ){
  if( err ) return console.log( err );

  conn.query( sql_str, function( err, data ){
    if( err ) console.log( err );

    console.log( data );

    conn.close( function(){
      console.log( 'done' );
    });
  });
});
```

## 実行結果
SELECTできました。

```
$ node test1.js
[
  { C1: 1, C2: 'a       ' },
  { C1: 2, C2: 'b       ' },
  { C1: 10001, C2: 'A10001  ' }
]
done
$
```