- Notifications
You must be signed in to change notification settings - Fork 5
Description
Db2 on cloud(先前叫dashDB), 注册需要credit card
Db2 warehouse, 可以免费注册, 以此为例, 它提供了各种编程语言的API, NODE的还是那个叫ibm_db的
提供了JDBC URL, 但是密码使用的placeholder. 需要点左边的credentials, 创建一个credential 然后从json格式的一个文件中找到密码部分.
可以用DBVisualizer连上去, 并可以建表和建SEQ.
Sybase Power Designer可以建Physical Data Model (PDM) 然后生成对应的SQL
Db2 warehouse提供的UI只能建表, 找不到建sequence的地方.
node-ibm_db
node-ibm_db是ibm db2的node版驱动. 安装npm install ibm_db --save,
安装过程要下载好几十M的clidriver安装包, 并且因为墙的原因可能会经常安装失败(下载的压缩包格式损坏)
官方的安装文档提供了不用重复下载clidriver的办法, 如果你之前有在其它项目已经用npm安装过ibm_db , 执行如下命令可以秒安装:
export IBM_DB_HOME=/Users/cyper/xxxx/ibm_db/installer/clidriver npm install [email protected] --save也可以使用yarn安装: yarn add ibm_db
20170929: 今天在新项目安装ibm_db报错:
gyp: Call to 'node -e "require('nan')"' returned exit status 0 while in binding.gyp. while trying to load binding.gyp gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1 gyp ERR! stack at ChildProcess.onCpExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:305:16) gyp ERR! stack at emitTwo (events.js:106:13) gyp ERR! node-gyp -v v3.4.0 换成yarn的时候有如下提示
Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command. gyp ERR! build error gyp ERR! stack Error: `make` failed with exit code: 69 gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:276:23) gyp ERR! stack at emitTwo (events.js:106:13) gyp ERR! stack at ChildProcess.emit (events.js:191:7) gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:219:12) NM的, 原来macOS自动更新了我的Xcode至9.0, 我得打开xcode同意一下新的条款. WTF
connection pool
从官方docs中找到了一些关于pool的文档, https://github.com/ibmdb/node-ibm_db#PoolAPIs
文档上关于init方法, 有如下示例代码
varret=pool.init(5,connStr);if(ret!=true){console.log(ret);returnfalse;}pool.open(connStr,function(err,db){ ...一开始没怎么看明白, 比如init方法为什么没有callback, 要是出错了怎么知道(ret != true呗), 那出错的具体原因在哪? debug了一下源代码, :
原来init是一个阻塞方法, 内部会循环调用Database.openSync(...)初始化连接, 并将connection放在一个内部数组里.
init方法的返回值(示例中的ret)要么为true(表示pool初始化成功), 要么是一个Error Object. (出错的堆栈信息全在里面)
最后要注意的是连接bluemix上的db2, 需要在connectionString最后拼上Security=SSL
据此我设计了自己的db2 pool工具类 db2.js, 如下
varformat=require('string-format');varibm_db=require('ibm_db');varpool=newibm_db.Pool;varcn=null;module.exports.initPool=initPool;module.exports.ping=ping;module.exports.open=open;module.exports.close=close;module.exports.closePool=closePool;functioninitPool(db2_config,cb){cn=format('DATABASE={db};HOSTNAME={host};PORT={port};PROTOCOL=TCPIP;UID={user};PWD={pass};Security=SSL',db2_config);// set to true then db2 driver will print debug logs.ibm_db.debug(!!db2_config.debug);pool.setMaxPoolSize(db2_config.maxPoolSize||10);console.log('initializing pool, please wait ...');varresult=pool.init(db2_config.poolSize||1,cn);if(result!=true){returncb&&cb(result);}else{console.log('pool initialized('+db2_config.poolSize+')');cb&&cb(null);}}functionping(){console.log('ping db2 server.');open(function(err,conn){if(err)returnconsole.log(err);varrows=conn.querySync('select 1 from sysibm.sysdummy1');console.log(rows);close(conn);});}functionopen(cb){pool.open(cn,function(err,conn){if(err){returncb(err);}console.log('get one connection');cb(null,conn);});}functionclose(rs,stmt,conn,cb){// overload close, now we can use close(conn) | close(conn, cb) | close(rs, stmt, conn) | close(rs, stmt, conn, cb)if(arguments.length>2){rs&&rs.closeSync();stmt&&stmt.closeSync();}else{conn=rs;cb=stmt;}conn&&conn.close(function(){console.log('connection released to pool.');cb&&cb();});}functionclosePool(cb){pool.close(function(){console.log('all connections in the pool are closed');cb&&cb();});}我在./bin/www初始化日志组件log4js就立即初始化db2 pool, 这样如果有任何出错的日志, 会记录到日志文件, 并且如果db2 pool 初始化失败, 则直接退出app. 如果process.exit(1) 打印出来的NPM ERR吓着你, 可以用process.exit(0) 😄
// init db2 connection pooldb2.initPool(db2_config,function(err){if(err){console.error(err);log4js.shutdown();process.exit(1);}else{db2.ping();}});// express启动失败时的处理case'EADDRINUSE': logger.error(bind+' is already in use');db2.closePool(function(){log4js.shutdown();});process.exit(1);启动时的日志如下.
[2017-09-19 14:57:55.227 INFO] env= development [2017-09-19 14:57:55.230 INFO] node-ibm_db logs disabled. [2017-09-19 14:57:58.876 INFO] pool initialized [2017-09-19 14:57:58.877 INFO] ping db2 server. [2017-09-19 14:57:58.877 INFO] get one connection [2017-09-19 14:57:59.503 INFO] [{'1': 1 } ] [2017-09-19 14:57:59.505 INFO] connection released to pool. [2017-09-19 14:57:59.509 INFO] Listening on port 3000