Changeset: fb74bbd8e41b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fb74bbd8e41b
Modified Files:
        clients/nodejs/Tests/nodetest.js
        clients/nodejs/monetdb/mapiclient.js
        clients/nodejs/monetdb/package.json
Branch: Oct2014
Log Message:

Node.JS connector: prepared statement support and exports cleanup


diffs (236 lines):

diff --git a/clients/nodejs/Tests/nodetest.js b/clients/nodejs/Tests/nodetest.js
--- a/clients/nodejs/Tests/nodetest.js
+++ b/clients/nodejs/Tests/nodetest.js
@@ -21,7 +21,7 @@ monetdb.connect({dbname:dbname, user:'no
 });
 
 /* now actually connect */
-var conn = monetdb.connect({dbname:dbname, port:dbport}, function(resp) {
+var conn = monetdb.connect({dbname:dbname, port:dbport, debug: false}, 
function(resp) {
        assert.equal(true,resp.success);
 });
 
@@ -66,7 +66,6 @@ var longstr = rep('ABCDEFGHIJKLMNOP',100
 conn.query("SELECT '"+longstr+"'", function(res) {
        assert.equal(true, res.success);
        assert.equal(longstr,res.data[0][0]);
-
 });
 
 /* failing query */
@@ -75,4 +74,11 @@ conn.query('MEHR BIER', function(res) {
        assert(res.message.trim().length > 0);
 });
 
-conn.close();
\ No newline at end of file
+/* prepared statement */
+conn.prepare('PREPARE select id from tables where name=? and type=? and 
readonly=?', function(resp) {
+       assert.equal(true, resp.success);
+       resp.exec('connections', 0, false, function(resp2) {
+               assert(resp2.rows > 0);
+               conn.close();
+       });
+});
diff --git a/clients/nodejs/monetdb/mapiclient.js 
b/clients/nodejs/monetdb/mapiclient.js
--- a/clients/nodejs/monetdb/mapiclient.js
+++ b/clients/nodejs/monetdb/mapiclient.js
@@ -1,6 +1,7 @@
 var net    = require('net');
 var crypto = require('crypto');
 
+/* constructor for connection object */
 function MonetDBConnection(options, conncallback) {
        this.state = 'new';
        this.options = options; 
@@ -17,7 +18,7 @@ function MonetDBConnection(options, conn
                thizz.state = 'connected';
        });
        this.socket.on('data', function(data) {
-               thizz.handleInput(data);
+               handle_input.call(thizz, data);
        });
        this.socket.on('end', function() {
                thizz.state = 'disconnected';
@@ -50,15 +51,63 @@ MonetDBConnection.prototype.query = func
        this.queryqueue.push({'message' : message , 'callback' : callback})
 }
 
+MonetDBConnection.prototype.prepare = function(query, callback) {
+       if (query.toUpperCase().trim().substring(0,7) != 'PREPARE')
+               query = 'PREPARE ' + query;
+       var thizz = this;
+       thizz.query(query, function(resp) {
+               if (resp.success) {
+                       var execfun = function() {
+                               /* last parameter is the callback on result */
+                               var ecallback = arguments[arguments.length-1];
+                               /* first n-1 parameters are the values to bind 
*/
+                               var bindparams = 
Array.prototype.slice.call(arguments, 0, arguments.length-1);
+                               var quoted = bindparams.map(function(param) {
+                                       var type = typeof param;
+                                       switch(type) {
+                                               case 'boolean':
+                                               case 'number':
+                                                       return ''+param;
+                                                       break
+                                               default:
+                                               /* escape single quotes except 
if they are already escaped */
+                                                       return "'" + 
param.replace(/([^\\])'/g,"$1\\'") + "'";
+                                                       break
+                                       }
+                               }).join(', ');
 
-MonetDBConnection.prototype.handleMessage = function(message) {
+                               var execquery = 'EXEC ' + resp.queryid + '(' + 
quoted + ')';
+                               thizz.query(execquery, ecallback);
+                       }
+                       callback({'success' : true, 'message' : 'ok', 'prepare' 
:  resp, 'exec' : execfun});
+               }
+               else {
+                       callback(resp);
+               }
+       });
+}
+
+MonetDBConnection.prototype.disconnect = 
+MonetDBConnection.prototype.close = function() {
+       var thizz = this;
+       /* kills the connection after the query has been processed (will also 
wait for all others) */
+       this.request('SELECT 42', function(x) {
+               thizz.socket.destroy();
+       });
+}
+
+exports.connect = exports.open = function() {
+  return new MonetDBConnection(__get_connect_args(arguments[0]), arguments[1]);
+}
+
+function handle_message(message) {
        if (this.options.debug)
                console.log('RX ['+this.state+']: '+message);
 
        /* prompt, good */
        if (message == '') {
                this.state = 'ready';
-               this.nextOp();
+               next_op.call(this);
                return;
        }
 
@@ -83,7 +132,7 @@ MonetDBConnection.prototype.handleMessag
                var pwhash = __sha512(__sha512(this.options.password) + salt)
                var response = 'LIT:' + this.options.user + ':{SHA512}' + 
pwhash + ':' +
                        this.options.language + ':' + this.options.dbname + ':';
-               this.sendMessage(response);
+               send_message.call(this, response);
                return;
        }
 
@@ -106,20 +155,20 @@ MonetDBConnection.prototype.handleMessag
                this.read_callback(response);
                this.read_callback = undefined;
        }
-       this.nextOp();  
+       next_op.call(this);
 }
 
 
-MonetDBConnection.prototype.nextOp = function() {
+function next_op() {
        if (this.queryqueue.length < 1) {
                return;
        }
        var op = this.queryqueue.shift();
-       this.sendMessage(op.message);
+       send_message.call(this, op.message);
        this.read_callback = op.callback;
 }      
 
-MonetDBConnection.prototype.handleInput = function(data) {
+function handle_input(data) {
        /* we need to read a header obviously */
        if (this.read_leftover == 0) {
                var hdr = data.readUInt16LE(0);
@@ -142,7 +191,7 @@ MonetDBConnection.prototype.handleInput 
 
        /* pass on reassembled messages */
        if (this.read_leftover == 0 && this.read_final) {
-               this.handleMessage(this.read_str);
+               handle_message.call(this, this.read_str);
                this.read_str = '';
        }
 
@@ -150,12 +199,12 @@ MonetDBConnection.prototype.handleInput 
        if (data.length > read_cnt) {
                var leftover = new Buffer(data.length - read_cnt);
                data.copy(leftover, 0, read_cnt, data.length);
-               this.handleInput(leftover);
+               handle_input.call(this, leftover);
        }
 
 };
 
-MonetDBConnection.prototype.sendMessage = function(message) {
+function send_message(message) {
        if (this.options.debug) 
                console.log('TX: '+message);
 
@@ -274,8 +323,8 @@ function _parseresponse(msg) {
        var resp = {};
        var tpe = lines[0].charAt(1);
 
-       /* table result, we only like Q_TABLE for now */
-       if (tpe == 1) { 
+       /* table result, we only like Q_TABLE and Q_PREPARE for now */
+       if (tpe == 1 || tpe == 5) { 
                var hdrf = lines[0].split(" ");
 
                resp.type='table';
@@ -304,17 +353,6 @@ function _parseresponse(msg) {
        return resp;
 }
 
-MonetDBConnection.prototype.close = function() {
-       var thizz = this;
-       /* kills the connection after the query has been processed (will also 
wait for all others) */
-       this.request('SELECT 42', function(x) {
-               thizz.socket.destroy();
-       });
-}
-
-exports.connect = exports.open = function() {
-  return new MonetDBConnection(getConnectArgs(arguments[0]), arguments[1]);
-}
 
 function __check_arg(options, argname, type, dflt) {
        var argval = options[argname];
@@ -343,14 +381,15 @@ function __check_arg(options, argname, t
        }
 }
 
-function getConnectArgs(options) {
+function __get_connect_args(options) {
        __check_arg(options, 'dbname'  , 'string' , 'demo');
        __check_arg(options, 'user'    , 'string' , 'monetdb');
        __check_arg(options, 'password', 'string' , 'monetdb');
        __check_arg(options, 'host'    , 'string' , 'localhost');
-       __check_arg(options, 'port'    , 'number'    , 50000);
+       __check_arg(options, 'port'    , 'number' , 50000);
        __check_arg(options, 'language', 'string' , 'sql');
        __check_arg(options, 'debug'   , 'boolean', false);
   return options;
 }
 
+
diff --git a/clients/nodejs/monetdb/package.json 
b/clients/nodejs/monetdb/package.json
--- a/clients/nodejs/monetdb/package.json
+++ b/clients/nodejs/monetdb/package.json
@@ -1,6 +1,6 @@
 {
   "name": "monetdb",
-  "version": "0.0.5",
+  "version": "0.0.6",
   "description": "Connect MonetDB and node.js",
   "main": "mapiclient.js",
   "author": "Hannes Mühleisen <[email protected]>",
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to