Nodejs db2 RPG Talking at Last3
Nodejs db2 RPG Talking at Last3
Biggest benefit: One language for both client (browser) and server (IBM i).
BIG TIME SAVER!!
License
The exports syntax declares the functions to make available, like export on
an RPG sub procedure.
ibmi.js
1. function current_user(){
2. return rtvjoba('USER');
3. }
4.
5. exports.current_user = current_user;
http://stackoverflow.com/questions/16521471/relation-between-commonjs-amd-and-requirejs - Answers
noobs continued...
1. function my_callback(data) {
2. console.log('data: ' + data);
3. }
4.
5. function hi(callback) {
6. callback('get it?');
7. }
8.
9. hi(my_callback);
1. function hi(callback) {
2. callback('get it?');
3. }
4.
5. hi(function(data) {
6. console.log('data: ' + data);
7. });
Toolkit for i
● Descr: API set for interfacing with XMLSERVICE.
● Docs: http://bit.ly/nodejs_toolkitfori
● IFS Location:
/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/itoolkit
Do yourself a favor and DON'T use CALL QP2TERM, use SSH client instead.
$ export PATH=/QOpenSys/QIBM/ProdData/Node/bin:$PATH
$ export LIBPATH=/QOpenSys/QIBM/ProdData/Node/bin:$LIBPATH
Now you can invoke node binary from anywhere in the IFS.
$ node -v
v0.10.29
Put the above exports into node_env.sh and then easily invoke it (note the
period!)
$ . node_env.sh
<myscript>
DB2
<pgm>...</pgm>
Node.js, Ruby, PGM
PHP, Java, etc. <cmd>...</cmd>
SRVPGM
<sh>...</sh> PASE
DB2 connection <sql>...</sql> System API
</myscript> User Space
WRKACTJOB
REST
GET/POST
XML
itoolkit.js in action
1. var xt = require("/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/itoolkit");
2. var conn = new xt.iConn("*LOCAL");
3. conn.add(xt.iCmd('RTVJOBA USER(?)'));
4. conn.run(function(str) {
5. console.log(str);
6. });
1. <?xml version='1.0'?>
2. <myscript>
3. <cmd exec='rexx' error='fast'>
4. <success>+++ success RTVJOBA USER(?)</success>
Output --->
5. <row>
6. <data desc='USER'>QUSER</data>
7. </row>
8. </cmd>
9. </myscript>
node REPL
Type node at the command line to start a REPL session. Copy/paste code for
quick testing! REPL = Read Eval Print Loop
1. conn.run(function(str) {
2. result = xt.xmlToJson(str);
3. console.log(result[0].data[0].value);
4. });
Before After
1. <?xml version='1.0'?> 1. [{ "type":"cmd",
2. <myscript> 2. "success":true,
3. <cmd exec='rexx' error='fast'> 3. "cmd":"RTVJOBA USER(?)",
4. <success>+++ success 4. "data":[{
5. RTVJOBA USER(?)</success> 5. "name":"USER",
6. <row> 6. "value":"QUSER"
7. <data desc='USER'>QUSER</data> 7. }]
8. </row> 8. }]
9. </cmd>
10. </myscript>
debugging
Additional output:
1. ============
2. INPUT XML
3. ============
4. <?xml version='1.0'?>
5. <myscript>
6. <cmd exec='rexx' error='fast'>RTVJOBA USER(?)</cmd>
7. </myscript>
Still can't determine why it's not working? It's open source! Look at the code. . .
/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/itoolkit.js
Call a *PGM
1. var xt = require('/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/itoolkit');
2. var conn = new xt.iConn("*LOCAL");
3.
4. var pgm = new xt.iPgm("PGM1", {"lib":"MYLIB"});
5. pgm.addParam("","1A");
6. pgm.addParam("0", "7p4");
7.
8. conn.add(pgm.toXML());
9.
10. conn.run(function (rsp) {
11. var results = xt.xmlToJson(rsp);
12. results.forEach(function(result, index){
13. result.data.forEach(function(data, index2){
14. console.log("type:" + data.type + " value:" + data.value);
15. });
16. });
17. });
Encapsulation
Encapsulate RPG for easy invocation
rpg.js
1. var xt = require('/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/itoolkit');
2. var conn = new xt.iConn("*LOCAL");
3.
4. function pgm1(char1, dec1){
5. var results;
6. var pgm = new xt.iPgm("PGM1", {"lib":"MYLIB"});
7. pgm.addParam("","1A");
8. pgm.addParam("0", "7p4");
9. conn.add(pgm.toXML());
10. conn.run(function (rsp) {
11. results = xt.xmlToJson(rsp);
12. });
13. return {char1: results[0].data[0].value,
14. dec1: results[0].data[1].value};
15. }
16. exports.pgm1 = pgm1;
1. var xt = require('/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/itoolkit');
2. var option = {
3. host : '192.168.0.10',
4. port : 8000,
5. path : '/cgi-bin/xmlcgi.pgm'
6. };
7. var conn2 = new xt.iConn('*LOCAL', 'USR1', 'bleh!', option);
Example
1. var db = require('/QOpenSys/QIBM/ProdData/Node/os400/db2i/lib/db2');
2. db.init();
3. db.conn("*LOCAL");
4. db.exec("SELECT LSTNAM,CITY FROM QIWS.QCUSTCDT", function(result_set) {
5. console.log(result_set);
6. });
7. db.close();
Results
1. [ { LSTNAM: 'Henning ', CITY: 'Dallas' },
2. { LSTNAM: 'Jones ', CITY: 'Clay ' },
3. { LSTNAM: 'Vine ', CITY: 'Broton' },
4. { LSTNAM: 'Johnson ', CITY: 'Helen ' },
5. { LSTNAM: 'Tyron ', CITY: 'Hector' },
6. { LSTNAM: 'Stevens ', CITY: 'Denver' }
7. . . .
8. ]
DB2 Connection
1. try{
2. db.init(function(){
3. db.serverMode(true);
4. });
5. db.conn('*LOCAL', function(){
6. db.autoCommit(true);
7. });
8. db.close();
9. } catch(e) {
10. console.log(e);
11. }
Metadata
1. db.exec('SELECT * FROM MYLIB.MYTABLE', function(result) {
2. var fieldNum = db.numFields();
3. console.log('Name | Length | Type | Precise | Scale | Null');
4. for(var i = 0; i < fieldNum; i++)
5. console.log('%s | %d | %d | %d | %d | %d',
6. db.fieldName(i), db.fieldWidth(i), db.fieldType(i),
7. db.fieldPrecise(i),db.fieldScale(i), db.fieldNullable(i));
8. });
Result processing
1. db.exec('SELECT * FROM MYLIB.MYTABLE', function(result) {
2. for(var x = 0; x < result.length; x++){
3. console.log(result[x].COLNAME);
4. }
5. });
Aaron Bartell
[email protected] - @aaronbartell