diff --git a/CUBRID version supported.txt b/CUBRID version supported.txt
new file mode 100644
index 0000000..cd2f0a9
--- /dev/null
+++ b/CUBRID version supported.txt
@@ -0,0 +1 @@
+>=8.4.1.2030
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..9e9eef3
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,50 @@
+Copyright (c) 2008-2012, Search Solution Corporation.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions
+ and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of the Search Solution Corporation nor the names of its contributors may be used to endorse
+ or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Project notes
+==================================================================================================================================
+Part of this software uses code from the node-mysql project:
+https://github.com/felixge/node-mysql
+See below the license of the node-mysql project.
+
+
+Additional licenses
+==================================================================================================================================
+Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
diff --git a/Readme.md b/Readme.md
new file mode 100644
index 0000000..e86e8b6
--- /dev/null
+++ b/Readme.md
@@ -0,0 +1,82 @@
+node-cubrid
+June-August, 2012
+http://www.cubrid.org
+
+
+Introduction
+=======================================================================================================
+The CUBRID node.js driver is an open-source project with the goal of implementing a 100% native node.js driver for the CUBRID database engine (www.cubrid.org).
+
+The driver is currently under development and this (August 2012) is the first release (Milestone 1) of the driver code, which features:
+- 2.000+ LOC
+- Connect/Close, Query, Execute, Fetch, Close request etc. completed
+- 15+ functional test cases
+- 15+ unit tests
+- E2E demos
+
+These are the main project deliverables we target for the project:
+- The driver source code
+- Test cases
+- Code documentation
+- Demos & Tutorials
+- npm package; registered on http://search.npmjs.org/
+
+
+Installation
+=======================================================================================================
+
+This first release does not feature yet an npm installer – it will be available in the upcoming beta release.
+Therefore, if you want to use it now, please download the driver code on your machine.
+
+
+Usage
+=======================================================================================================
+This first release contains many test cases and demos which will show you how to use the driver.
+These examples are located in the following (sub)folders:
+ \demo
+ \src\test
+
+
+TODOs
+=======================================================================================================
+In the next code release (Technology preview - September 2012), we are targeting:
+- Transactions support
+- Additional data types support
+- Schema support
+- Documentation release
+- More functionality & more testing
+- Additional demos and E2E scenarios
+- Code improvements, optimizations and refactoring
+
+
+Author and Contributors
+=======================================================================================================
+The main authors of this driver are the members of the CUBRID API team - http://www.cubrid.org/wiki_apis.
+
+We welcome any contributors and we hope you will enjoy coding with CUBRID! J
+
+
+Special thanks
+=======================================================================================================
+We would like to thanks to the following people & projects for inspiration,
+code we have reused and for doing such a great job for the open-source community!
+- https://github.com/caolan/async
+- https://github.com/felixge/node-mysql
+- https://github.com/jeromeetienne/microcache.js
+
+
+TODO
+=======================================================================================================
+This release is just the first milestone for this project.
+We intend to release soon a beta version, followed by a stable release, with demos and tutorials.
+Here are the scheduled releases:
+- Milestone 1. Basic driver interfaces: connect, queries support
+- Milestone 2. Technology preview release: ~80% functionality ready
+- Milestone 3. Beta release
+- Milestone 4. Stable release
+- Milestone 5. Tutorials & Installer/Package completed; web awareness achieved.
+
+...Stay tuned! :)
+
+
+
diff --git a/demo/DemoServer.js b/demo/DemoServer.js
new file mode 100644
index 0000000..d33243e
--- /dev/null
+++ b/demo/DemoServer.js
@@ -0,0 +1,74 @@
+var http = require('http'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ client = require('../index.js').createDefaultCUBRIDDemodbConnection();
+
+//Note: Open http://localhost:8080 to test it
+
+function resultToHtmlTable(result) {
+ var ret = '';
+
+ ret += '
Table `code` content
';
+ ret += ' ';
+
+ var arr = Result2Array.GetResultsArray(result);
+ for (var i = 0; i < arr.length; i++) {
+ ret += ' ';
+ for (var j = 0; j < arr[i].length; j++) {
+ ret += ' ';
+ ret += ' ' + arr[i][j];
+ ret += ' | ';
+ }
+ ret += '
';
+ }
+ ret += '
';
+
+ return ret;
+}
+
+http.createServer(function (request, response) {
+ if (request.url == '/') {
+ client.connect(function (err) {
+ if (err) {
+ response.end(err.message);
+ } else {
+ client.query('select * from code', function (err, result, queryHandle) {
+ if (err) {
+ response.end(err.message);
+ } else {
+ var output = '';
+ output += '';
+ output += ' ';
+ output += ' CUBRID Node.js Driver test';
+ output += ' ';
+ output += ' ';
+ output += ' ';
+ output += resultToHtmlTable(result);
+ output += ' ';
+ output += '';
+ client.closeRequest(queryHandle, function (err) {
+ if (err) {
+ response.end(err.message);
+ } else {
+ client.close(function (err) {
+ if (err) {
+ response.end(err.message);
+ }
+ });
+ response.writeHead(200, {'Content-Type' : 'text/html'});
+ response.end(output);
+ }
+ })
+ }
+ })
+ }
+ })
+ } else {
+ response.writeHead(404, {'Content-Type' : 'text/plain'});
+ response.end('Error: Unexpected request!');
+ }
+}).listen(8080, 'localhost');
+
diff --git a/demo/E2E_01.js b/demo/E2E_01.js
new file mode 100644
index 0000000..6a9448f
--- /dev/null
+++ b/demo/E2E_01.js
@@ -0,0 +1,66 @@
+var client = require('../index.js').createDefaultCUBRIDDemodbConnection(),
+ Result2Array = require('../src/resultset/Result2Array');
+
+var sql = 'select * from game';
+
+client.connect(function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Connected successfully to ' + client.brokerServer + ':' + client.connectionBrokerPort + '.');
+ client.getEngineVersion(function (err, result) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('CUBRID Engine version is: ' + result);
+ console.log('Querying: [' + sql + ']');
+ client.query(sql, function (err, queryResults, queryHandle) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Query results - Rows count: ' + Result2Array.GetResultsCount(queryResults));
+ console.log('Query results - Column names: ' + Result2Array.GetResultsColumnNamesArray(queryResults));
+ console.log('Query results - Column data types: ' + Result2Array.GetResultsColumnsTypeArray(queryResults));
+ console.log('Query results - Data [displaying only the first 10 rows]:');
+ var arr = Result2Array.GetResultsArray(queryResults);
+ for (var j = 0; j < 10; j++) {
+ console.log(arr[j].toString());
+ }
+ console.log('Fetching more results:');
+ client.fetch(queryHandle, function (err, result) {
+ if (err) {
+ throw err.message;
+ } else {
+ if (result) {
+ console.log('Fetch results - Data [displaying only the first 10 rows]:');
+ var arr = Result2Array.GetResultsArray(result);
+ for (var k = 0; k < 10; k++) {
+ console.log(arr[k].toString());
+ }
+ } else {
+ console.log('There is no more data to fetch.');
+ }
+ client.closeRequest(queryHandle, function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Query closed.');
+ client.close(function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Connection closed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/demo/E2E_02.js b/demo/E2E_02.js
new file mode 100644
index 0000000..e46d633
--- /dev/null
+++ b/demo/E2E_02.js
@@ -0,0 +1,59 @@
+var client = require('../index.js').createDefaultCUBRIDDemodbConnection(),
+ Result2Array = require('../src/resultset/Result2Array');
+
+var sqlsSetup = ['drop table if exists node_test',
+ 'create table node_test(id int)',
+ 'insert into node_test values(1), (22)'];
+var sqlQuery = 'select * from node_test';
+var sqlsCleanup = 'drop table node_test';
+
+client.connect(function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Connected to ' + client.brokerServer + ':' + client.connectionBrokerPort + '.');
+ console.log('Creating test data...');
+ client.batchExecuteNoQuery(sqlsSetup, function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Querying: [' + sqlQuery + ']');
+ client.query(sqlQuery, function (err, queryResults, queryHandle) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Query results - Rows count: ' + Result2Array.GetResultsCount(queryResults));
+ console.log('Query results - Column names: ' + Result2Array.GetResultsColumnNamesArray(queryResults));
+ console.log('Query results - Column data types: ' + Result2Array.GetResultsColumnsTypeArray(queryResults));
+ console.log('Query results:');
+ var arr = Result2Array.GetResultsArray(queryResults);
+ for (var j = 0; j < arr.length; j++) {
+ console.log(arr[j].toString());
+ }
+ client.closeRequest(queryHandle, function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ client.batchExecuteNoQuery(sqlsCleanup, function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Cleanup done.');
+ client.close(function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ console.log('Connection closed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+});
+
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..a1e3aeb
--- /dev/null
+++ b/index.js
@@ -0,0 +1,24 @@
+var CUBRIDConnection = require('./src/CUBRIDConnection');
+
+/**
+ * Creates a new CUBRID connection
+ * @param brokerServer
+ * @param brokerPort
+ * @param user
+ * @param password
+ * @param database
+ * @return {*}
+ */
+exports.createCUBRIDConnection = function(brokerServer, brokerPort, user, password, database) {
+ return new CUBRIDConnection(brokerServer, brokerPort, user, password, database);
+};
+
+/**
+ * Creates a new CUBRID connection to the demodb database, with the default parameters
+ * @return {*}
+ */
+exports.createDefaultCUBRIDDemodbConnection = function() {
+ //return new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+ return this.createCUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+};
+
diff --git a/installer/CUBRID.ico b/installer/CUBRID.ico
new file mode 100644
index 0000000..e585a78
Binary files /dev/null and b/installer/CUBRID.ico differ
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..55eb500
--- /dev/null
+++ b/package.json
@@ -0,0 +1,48 @@
+{
+ "author" : "CUBRID (http://www.cubrid.org/)",
+
+ "contributors" : [
+ {
+ "name" : "",
+ "url" : ""
+ }
+ ],
+
+ "name" : "node-cubrid",
+
+ "description" : "This is a native Node.js driver for CUBRID (www.cubrid.org). \
+ It is developed entirely in JavaScript, so it doesn't require platform compilation, and it is MIT licensed.",
+
+ "version" : "0.1",
+
+ "repository" : {
+ "type" : "git",
+ "url" : "git://github.com/cubrid/node-cubrid.git"
+ },
+
+ "licenses" : [
+ {
+ "type" : "MIT",
+ "url" : "http://github.com/cubrid/node-cubrid/raw/master/LICENSE"
+ }
+ ],
+
+ "keywords" : [
+ "native",
+ "CUBRID",
+ "module"
+ ],
+
+ "engines" : {
+ "node" : "*"
+ },
+
+ "dependencies" : {
+ },
+
+ "devDependencies" : {
+ },
+
+ "optionalDependencies" : {
+ }
+}
diff --git a/src/CUBRIDConnection.js b/src/CUBRIDConnection.js
new file mode 100644
index 0000000..79e66d3
--- /dev/null
+++ b/src/CUBRIDConnection.js
@@ -0,0 +1,537 @@
+var Net = require('net'),
+ EventEmitter = require('events').EventEmitter,
+ DATA_TYPES = require('./constants/DataTypes'),
+ PacketReader = require('./packets/PacketReader'),
+ PacketWriter = require('./packets/PacketWriter'),
+ ActionQueue = require('./utils/ActionQueue'),
+ Helpers = require('../src/utils/Helpers'),
+ Cache = require('../src/utils/Cache'),
+ ClientInfoExchangePacket = require('./packets/ClientInfoExchangePacket'),
+ OpenDatabasePacket = require('./packets/OpenDatabasePacket'),
+ GetEngineVersionPacket = require('./packets/GetEngineVersionPacket'),
+ ExecuteQueryPacket = require('./packets/ExecuteQueryPacket'),
+ CloseQueryPacket = require('./packets/CloseQueryPacket'),
+ BatchExecuteNoQueryPacket = require('./packets/BatchExecuteNoQueryPacket'),
+ CloseDatabasePacket = require('./packets/CloseDatabasePacket'),
+ FetchPacket = require('./packets/FetchPacket');
+
+module.exports = CUBRIDConnection;
+
+//TODO Add Utils.inherit for EventEmitter
+
+function CUBRIDConnection(brokerServer, brokerPort, user, password, database, cacheTimeout) {
+ // Using EventEmitter.call on an object will do the setup of instance methods / properties
+ // (not inherited) of an EventEmitter.
+ // It is similar in purpose to super(...) in Java or base(...) in C#, but it is not implicit in Javascript.
+ // Because of this, we must manually call it ourselves:
+ //EventEmitter.call(this);
+
+ this.queryCache = null;
+ if (typeof cacheTimeout !== 'undefined' && cacheTimeout > 0) {
+ this.queryCache = new Cache();
+ }
+
+ this.brokerServer = brokerServer || 'localhost';
+ this.initialBrokerPort = brokerPort || 33000;
+ this.connectionBrokerPort = 0;
+ this.user = user || 'public';
+ this.password = password || '';
+ this.database = database || 'demodb';
+ this.socket = new Net.Socket();
+ this.CASInfo = [0, 0xFF, 0xFF, 0xFF];
+ this.connectionOpened = false;
+ this.autoCommitMode = 0;
+ this.sessionId = 0;
+ this.queriesHandleList = new Array();
+}
+
+CUBRIDConnection.prototype._doGetBrokerPort = function (self, callback) {
+ self.socket = Net.createConnection(self.initialBrokerPort, self.brokerServer);
+ self.socket.setNoDelay(true);
+
+ self.socket.on('error', function (err) {
+ this.connectionOpened = false;
+ delete this.queriesHandleList;
+ //throw err;
+ callback.call(err);
+ });
+ self.socket.once('data', function (data) {
+ var packetReader = new PacketReader();
+ packetReader.write(data);
+ clientInfoExchangePacket.parse(packetReader);
+ var newPort = clientInfoExchangePacket.newConnectionPort;
+ self.connectionBrokerPort = newPort;
+ self.socket.end();
+ if (callback && typeof(callback) === 'function') {
+ if (newPort > 0) {
+ callback.call(null);
+ } else {
+ var err = new Error('Error receiving a new connection port!');
+ callback.call(err);
+ }
+ }
+ });
+
+ var packetWriter = new PacketWriter();
+ var clientInfoExchangePacket = new ClientInfoExchangePacket();
+ clientInfoExchangePacket.write(packetWriter);
+ self.socket.write(packetWriter._buffer);
+};
+
+CUBRIDConnection.prototype._doDatabaseLogin = function (self, callback) {
+ var err = null;
+ var responseData = new Buffer(0);
+ var expectedResponseLength = -1;
+
+ self.socket = Net.createConnection(self.connectionBrokerPort, self.brokerServer);
+ self.socket.setNoDelay(true);
+ self.socket.on('error', function (err) {
+ this.connectionOpened = false;
+ delete this.queriesHandleList;
+ callback.call(self, err);
+ });
+
+ self.socket.on('data', function (data) {
+ responseData = Helpers.combineData(responseData, data);
+
+ if (expectedResponseLength === -1 && responseData.length >= DATA_TYPES.DATA_LENGTH_SIZEOF) {
+ expectedResponseLength = Helpers.getExpectedResponseLength(responseData);
+ }
+ if (responseData.length === expectedResponseLength) {
+// self.socket.listeners('data').splice(0).forEach(function (listener) {
+// self.socket.removeListener('data', listener);
+// });
+ self.socket.removeAllListeners('data');
+ var packetReader = new PacketReader();
+ packetReader.write(responseData);
+ openDatabasePacket.parse(packetReader);
+ self.CASInfo = openDatabasePacket.casInfo;
+ var errorCode = openDatabasePacket.errorCode;
+ var errorMsg = openDatabasePacket.errorMsg;
+ if (errorCode !== 0) {
+ err = new Error(errorCode + ':' + errorMsg);
+ } else {
+ self.sessionId = openDatabasePacket.sessionId;
+ self.autoCommitMode = (self.CASInfo[3] & 0x01) ? true : false;
+ }
+ if (callback && typeof(callback) === 'function') {
+ callback.call(self, err);
+ }
+ }
+ });
+
+ var packetWriter = new PacketWriter();
+ var openDatabasePacket = new OpenDatabasePacket(
+ {
+ database : self.database,
+ user : self.user,
+ password : self.password,
+ casInfo : self.CASInfo
+ }
+ );
+ openDatabasePacket.write(packetWriter);
+ self.socket.write(packetWriter._buffer);
+};
+
+CUBRIDConnection.prototype.connect = function (callback) {
+ var self = this;
+
+ ActionQueue.enqueue(
+ [
+ function (cb) {
+ self._doGetBrokerPort(self, cb);
+ },
+ function (cb) {
+ self._doDatabaseLogin(self, cb);
+ }
+ ],
+ function (err) {
+ if (callback && typeof(callback) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ if (typeof err === undefined || err === null) {
+ self.connectionOpened = true;
+ }
+ callback.call(self, err);
+ }
+ }
+ );
+};
+
+CUBRIDConnection.prototype.getEngineVersion = function (callback) {
+ var err = null;
+ var engineVersion = '';
+ var self = this;
+ var responseData = new Buffer(0);
+ var expectedResponseLength = -1;
+
+ ActionQueue.enqueue(
+ [
+ function (cb) {
+ if (self.connectionOpened === false) {
+ self.connect(cb);
+ }
+ else {
+ cb();
+ }
+ },
+ function (cb) {
+ self.socket.on('data', function (data) {
+ responseData = Helpers.combineData(responseData, data);
+
+ if (expectedResponseLength === -1 && responseData.length >= DATA_TYPES.DATA_LENGTH_SIZEOF) {
+ expectedResponseLength = Helpers.getExpectedResponseLength(responseData);
+ }
+ if (responseData.length === expectedResponseLength) {
+// self.socket.listeners('data').splice(0).forEach(function (listener) {
+// self.socket.removeListener('data', listener);
+// });
+ self.socket.removeAllListeners('data');
+ var packetReader = new PacketReader();
+ packetReader.write(data);
+ getEngineVersionPacket.parse(packetReader);
+ var errorCode = getEngineVersionPacket.errorCode;
+ var errorMsg = getEngineVersionPacket.errorMsg;
+ if (errorCode !== 0) {
+ err = new Error(errorCode + ':' + errorMsg);
+ } else {
+ engineVersion = getEngineVersionPacket.engineVersion;
+ }
+ if (cb && typeof(cb) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ cb.call(self, err, engineVersion);
+ }
+ }
+ });
+
+ var packetWriter = new PacketWriter();
+ var getEngineVersionPacket = new GetEngineVersionPacket({casInfo : self.CASInfo});
+ getEngineVersionPacket.write(packetWriter);
+ self.socket.write(packetWriter._buffer);
+ }
+ ],
+ function (err, engineVersion) {
+ if (callback && typeof(callback) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ callback.call(self, err, engineVersion);
+ }
+ }
+ );
+};
+
+CUBRIDConnection.prototype.batchExecuteNoQuery = function (sqls, callback) {
+ var sqlsArr;
+
+ if (Array.isArray(sqls)) {
+ if (sqls.length == 0) {
+ callback.call(this, null);
+ return;
+ }
+ sqlsArr = sqls;
+ } else {
+ sqlsArr = new Array(sqls);
+ }
+
+ var err = null;
+ var self = this;
+ var responseData = new Buffer(0);
+ var expectedResponseLength = -1;
+
+ ActionQueue.enqueue(
+ [
+ function (cb) {
+ if (self.connectionOpened === false) {
+ self.connect(cb);
+ }
+ else {
+ cb();
+ }
+ },
+ function (cb) {
+ self.socket.on('data', function (data) {
+ responseData = Helpers.combineData(responseData, data);
+
+ if (expectedResponseLength === -1 && responseData.length >= DATA_TYPES.DATA_LENGTH_SIZEOF) {
+ expectedResponseLength = Helpers.getExpectedResponseLength(responseData);
+ }
+ if (responseData.length === expectedResponseLength) {
+// self.socket.listeners('data').splice(0).forEach(function (listener) {
+// self.socket.removeListener('data', listener);
+// });
+ self.socket.removeAllListeners('data');
+ var packetReader = new PacketReader();
+ packetReader.write(data);
+ batchExecuteNoQueryPacket.parse(packetReader);
+ var errorCode = batchExecuteNoQueryPacket.errorCode;
+ var errorMsg = batchExecuteNoQueryPacket.errorMsg;
+ if (errorCode !== 0) {
+ err = new Error(errorCode + ':' + errorMsg);
+ }
+ if (cb && typeof(cb) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ cb.call(self, err);
+ }
+ }
+ });
+
+ var packetWriter = new PacketWriter();
+ var batchExecuteNoQueryPacket = new BatchExecuteNoQueryPacket(
+ {
+ SQLs : sqlsArr,
+ casInfo : self.CASInfo,
+ autoCommitMode : self.autoCommitMode
+ }
+ );
+ batchExecuteNoQueryPacket.write(packetWriter);
+ self.socket.write(packetWriter._buffer);
+ }
+ ],
+ function (err) {
+ if (callback && typeof(callback) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ callback.call(self, err);
+ }
+ }
+ );
+};
+
+CUBRIDConnection.prototype.query = function (sql, callback) {
+ var err = null;
+ var self = this;
+ var responseData = new Buffer(0);
+ var expectedResponseLength = -1;
+
+ ActionQueue.enqueue(
+ [
+ function (cb) {
+ if (self.connectionOpened === false) {
+ self.connect(cb);
+ } else {
+ cb();
+ }
+ },
+ function (cb) {
+ if (self.queryCache != null) {
+ if (self.queryCache.contains(sql)) {
+ callback(err, self.queryCache.get(sql), null); //null: to prevent fetch (cache is intended for small data)
+ return;
+ }
+ }
+
+ self.socket.on('data', function (data) {
+ responseData = Helpers.combineData(responseData, data);
+
+ if (expectedResponseLength === -1 && responseData.length >= DATA_TYPES.DATA_LENGTH_SIZEOF) {
+ expectedResponseLength = Helpers.getExpectedResponseLength(responseData);
+ }
+ if (responseData.length === expectedResponseLength) {
+// self.socket.listeners('data').splice(0).forEach(function (listener) {
+// self.socket.removeListener('data', listener);
+// });
+ self.socket.removeAllListeners('data');
+ var packetReader = new PacketReader();
+ packetReader.write(responseData);
+ var result = executeQueryPacket.parse(packetReader);
+ var errorCode = executeQueryPacket.errorCode;
+ var errorMsg = executeQueryPacket.errorMsg;
+ if (errorCode !== 0) {
+ err = new Error(errorCode + ':' + errorMsg);
+ } else {
+ self.queriesHandleList.push(executeQueryPacket);
+ }
+ if (cb && typeof(cb) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ } else {
+ if (self.queryCache !== null) {
+ self.queryCache.getSet(sql, result);
+ }
+ }
+ cb.call(self, err, result, executeQueryPacket.handle);
+ }
+ }
+ });
+
+ var packetWriter = new PacketWriter();
+ var executeQueryPacket = new ExecuteQueryPacket(
+ {
+ sql : sql,
+ casInfo : self.CASInfo,
+ autoCommitMode : self.autoCommitMode
+ }
+ );
+ executeQueryPacket.write(packetWriter);
+ self.socket.write(packetWriter._buffer);
+ }
+ ],
+ function (err, result, handle) {
+ if (callback && typeof(callback) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ callback.call(self, err, result, handle);
+ }
+ }
+ );
+};
+
+CUBRIDConnection.prototype.fetch = function (queryHandle, callback) {
+ var err = null;
+ var self = this;
+ var responseData = new Buffer(0);
+ var expectedResponseLength = -1;
+
+ self.socket.on('data', function (data) {
+ responseData = Helpers.combineData(responseData, data);
+
+ if (expectedResponseLength === -1 && responseData.length >= DATA_TYPES.DATA_LENGTH_SIZEOF) {
+ expectedResponseLength = Helpers.getExpectedResponseLength(responseData);
+ }
+ if (responseData.length === expectedResponseLength) {
+ self.socket.removeAllListeners('data');
+ var packetReader = new PacketReader();
+ packetReader.write(responseData);
+ var result = fetchPacket.parse(packetReader, self.queriesHandleList[i]);
+ var errorCode = fetchPacket.errorCode;
+ var errorMsg = fetchPacket.errorMsg;
+ if (errorCode !== 0) {
+ err = new Error(errorCode + ':' + errorMsg);
+ }
+ if (callback && typeof(callback) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ callback.call(self, err, result);
+ }
+ }
+ });
+
+ var foundQueryHandle = false;
+ for (var i = 0; i < this.queriesHandleList.length; i++) {
+ if (this.queriesHandleList[i].handle === queryHandle) {
+ foundQueryHandle = true;
+ break;
+ }
+ }
+ if (!foundQueryHandle) {
+ err = new Error('No active query with this handle!');
+ self.socket.removeAllListeners('data');
+ callback.call(self, err, null);
+ } else {
+ if (this.queriesHandleList[i].currentTupleCount === this.queriesHandleList[i].totalTupleCount) {
+ self.socket.removeAllListeners('data');
+ callback.call(self, err, null);
+ } else {
+ var packetWriter = new PacketWriter();
+ var fetchPacket = new FetchPacket({casInfo : self.CASInfo});
+ fetchPacket.write(packetWriter, this.queriesHandleList[i]); //TODO Verify this
+ self.socket.write(packetWriter._buffer);
+ }
+ }
+};
+
+CUBRIDConnection.prototype.closeRequest = function (requestHandle, callback) {
+ var err = null;
+ var self = this;
+ var responseData = new Buffer(0);
+ var expectedResponseLength = -1;
+
+ self.socket.on('data', function (data) {
+ responseData = Helpers.combineData(responseData, data);
+
+ if (expectedResponseLength === -1 && responseData.length >= DATA_TYPES.DATA_LENGTH_SIZEOF) {
+ expectedResponseLength = Helpers.getExpectedResponseLength(responseData);
+ }
+ if (responseData.length === expectedResponseLength) {
+// self.socket.listeners('data').splice(0).forEach(function (listener) {
+// self.socket.removeListener('data', listener);
+// });
+ self.socket.removeAllListeners('data');
+ var packetReader = new PacketReader();
+ packetReader.write(data);
+ closeQueryPacket.parse(packetReader);
+ var errorCode = closeQueryPacket.errorCode;
+ var errorMsg = closeQueryPacket.errorMsg;
+ if (errorCode !== 0) {
+ err = new Error(errorCode + ':' + errorMsg);
+ }
+ if (callback && typeof(callback) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ callback.call(self, err);
+ }
+ }
+ });
+
+ var packetWriter = new PacketWriter();
+ var closeQueryPacket = new CloseQueryPacket(
+ {
+ casInfo : self.CASInfo,
+ reqHandle : requestHandle
+ }
+ );
+ for (var i = 0; i < this.queriesHandleList.length; i++) {
+ if (this.queriesHandleList[i].handle === requestHandle) {
+ this.queriesHandleList.splice(i, 1);
+ }
+ }
+ closeQueryPacket.write(packetWriter);
+ self.socket.write(packetWriter._buffer);
+};
+
+CUBRIDConnection.prototype.close = function (callback) {
+ var err = null;
+ var self = this;
+ var responseData = new Buffer(0);
+ var expectedResponseLength = -1;
+
+ self.socket.on('data', function (data) {
+ responseData = Helpers.combineData(responseData, data);
+
+ if (expectedResponseLength === -1 && responseData.length >= DATA_TYPES.DATA_LENGTH_SIZEOF) {
+ expectedResponseLength = Helpers.getExpectedResponseLength(responseData);
+ }
+ if (responseData.length === expectedResponseLength) {
+// self.socket.listeners('data').splice(0).forEach(function (listener) {
+// self.socket.removeListener('data', listener);
+// });
+ self.socket.removeAllListeners('data');
+ var packetReader = new PacketReader();
+ packetReader.write(data);
+ closeDatabasePacket.parse(packetReader);
+ // Close socket connection
+ self.socket.destroy();
+ var errorCode = closeDatabasePacket.errorCode;
+ var errorMsg = closeDatabasePacket.errorMsg;
+ if (errorCode !== 0) {
+ err = new Error(errorCode + ':' + errorMsg);
+ }
+
+ if (callback && typeof(callback) === 'function') {
+ if (typeof err != undefined && err != null) {
+ //self.emit('error', err);
+ }
+ callback.call(self, err);
+ }
+ }
+ });
+
+ var packetWriter = new PacketWriter();
+ var closeDatabasePacket = new CloseDatabasePacket({casInfo : self.CASInfo});
+ closeDatabasePacket.write(packetWriter);
+ self.socket.write(packetWriter._buffer);
+};
+
+
+
+
diff --git a/src/Config.js b/src/Config.js
new file mode 100644
index 0000000..894f7e8
--- /dev/null
+++ b/src/Config.js
@@ -0,0 +1,11 @@
+/**
+ * Debug enabled in application?
+ * @type {Boolean}
+ * @private
+ */
+var _DEBUG_ENABLED = true;
+//var _DEBUG_ENABLED = false;
+
+exports.DEBUG_ENABLED = _DEBUG_ENABLED;
+
+
diff --git a/src/constants/CASConstants.js b/src/constants/CASConstants.js
new file mode 100644
index 0000000..ca853c0
--- /dev/null
+++ b/src/constants/CASConstants.js
@@ -0,0 +1,330 @@
+/**
+ * Define CUBRID Function codes constants
+ */
+exports.CASFunctionCode = {
+ CAS_FC_END_TRAN : 1,
+ CAS_FC_PREPARE : 2,
+ CAS_FC_EXECUTE : 3,
+ CAS_FC_GET_DB_PARAMETER : 4,
+ CAS_FC_SET_DB_PARAMETER : 5,
+ CAS_FC_CLOSE_REQ_HANDLE : 6,
+ CAS_FC_CURSOR : 7,
+ CAS_FC_FETCH : 8,
+ CAS_FC_SCHEMA_INFO : 9,
+ CAS_FC_OID_GET : 10,
+ CAS_FC_OID_PUT : 11,
+ CAS_FC_DEPRECATED1 : 12,
+ CAS_FC_DEPRECATED2 : 13,
+ CAS_FC_DEPRECATED3 : 14,
+ CAS_FC_GET_DB_VERSION : 15,
+ CAS_FC_GET_CLASS_NUM_OBJS : 16,
+ CAS_FC_OID_CMD : 17,
+ CAS_FC_COLLECTION : 18,
+ CAS_FC_NEXT_RESULT : 19,
+ CAS_FC_EXECUTE_BATCH : 20,
+ CAS_FC_EXECUTE_ARRAY : 21,
+ CAS_FC_CURSOR_UPDATE : 22,
+ CAS_FC_GET_ATTR_TYPE_STR : 23,
+ CAS_FC_GET_QUERY_INFO : 24,
+ CAS_FC_DEPRECATED4 : 25,
+ CAS_FC_SAVEPOINT : 26,
+ CAS_FC_PARAMETER_INFO : 27,
+ CAS_FC_XA_PREPARE : 28,
+ CAS_FC_XA_RECOVER : 29,
+ CAS_FC_XA_END_TRAN : 30,
+ CAS_FC_CON_CLOSE : 31,
+ CAS_FC_CHECK_CAS : 32,
+ CAS_FC_MAKE_OUT_RS : 33,
+ CAS_FC_GET_GENERATED_KEYS : 34,
+ CAS_FC_LOB_NEW : 35,
+ CAS_FC_LOB_WRITE : 36,
+ CAS_FC_LOB_READ : 37,
+ CAS_FC_END_SESSION : 38,
+ CAS_FC_GET_ROW_COUNT : 39,
+ CAS_FC_GET_LAST_INSERT_ID : 40,
+ CAS_FC_PREPARE_AND_EXECUTE : 41
+};
+
+/**
+ * Define CUBRID Statement types constants
+ */
+exports.CUBRIDStatementType = {
+ CUBRID_STMT_ALTER_CLASS : 0,
+ CUBRID_STMT_ALTER_SERIAL : 1,
+ CUBRID_STMT_COMMIT_WORK : 2,
+ CUBRID_STMT_REGISTER_DATABASE : 3,
+ CUBRID_STMT_CREATE_CLASS : 4,
+ CUBRID_STMT_CREATE_INDEX : 5,
+ CUBRID_STMT_CREATE_TRIGGER : 6,
+ CUBRID_STMT_CREATE_SERIAL : 7,
+ CUBRID_STMT_DROP_DATABASE : 8,
+ CUBRID_STMT_DROP_CLASS : 9,
+ CUBRID_STMT_DROP_INDEX : 10,
+ CUBRID_STMT_DROP_LABEL : 11,
+ CUBRID_STMT_DROP_TRIGGER : 12,
+ CUBRID_STMT_DROP_SERIAL : 13,
+ CUBRID_STMT_EVALUATE : 14,
+ CUBRID_STMT_RENAME_CLASS : 15,
+ CUBRID_STMT_ROLLBACK_WORK : 16,
+ CUBRID_STMT_GRANT : 17,
+ CUBRID_STMT_REVOKE : 18,
+ CUBRID_STMT_STATISTICS : 19,
+ CUBRID_STMT_INSERT : 20,
+ CUBRID_STMT_SELECT : 21,
+ CUBRID_STMT_UPDATE : 22,
+ CUBRID_STMT_DELETE : 23,
+ CUBRID_STMT_CALL : 24,
+ CUBRID_STMT_GET_ISO_LVL : 25,
+ CUBRID_STMT_GET_TIMEOUT : 26,
+ CUBRID_STMT_GET_OPT_LVL : 27,
+ CUBRID_STMT_SET_OPT_LVL : 28,
+ CUBRID_STMT_SCOPE : 29,
+ CUBRID_STMT_GET_TRIGGER : 30,
+ CUBRID_STMT_SET_TRIGGER : 31,
+ CUBRID_STMT_SAVEPOINT : 32,
+ CUBRID_STMT_PREPARE : 33,
+ CUBRID_STMT_ATTACH : 34,
+ CUBRID_STMT_USE : 35,
+ CUBRID_STMT_REMOVE_TRIGGER : 36,
+ CUBRID_STMT_RENAME_TRIGGER : 37,
+ CUBRID_STMT_ON_LDB : 38,
+ CUBRID_STMT_GET_LDB : 39,
+ CUBRID_STMT_SET_LDB : 40,
+ CUBRID_STMT_GET_STATS : 41,
+ CUBRID_STMT_CREATE_USER : 42,
+ CUBRID_STMT_DROP_USER : 43,
+ CUBRID_STMT_ALTER_USER : 44,
+ CUBRID_STMT_CALL_SP : 0x7e,
+ CUBRID_STMT_UNKNOWN : 0x7f
+};
+
+/**
+ * Define CUBRID Isolation levels constants
+ */
+exports.CUBRIDIsolationLevel = {
+ TRAN_UNKNOWN_ISOLATION : 0x00,
+ TRAN_COMMIT_CLASS_UNCOMMIT_INSTANCE : 0x01,
+ TRAN_COMMIT_CLASS_COMMIT_INSTANCE : 0x02,
+ TRAN_REP_CLASS_UNCOMMIT_INSTANCE : 0x03,
+ TRAN_REP_CLASS_COMMIT_INSTANCE : 0x04,
+ TRAN_REP_CLASS_REP_INSTANCE : 0x05,
+ TRAN_SERIALIZABLE : 0x06,
+ TRAN_DEFAULT_ISOLATION : 0x01
+};
+
+/**
+ * Define CUBRID Data types constants
+ */
+exports.CUBRIDDataType = {
+ CCI_U_TYPE_UNKNOWN : 0,
+ CCI_U_TYPE_NULL : 0,
+ CCI_U_TYPE_CHAR : 1,
+ CCI_U_TYPE_STRING : 2,
+ CCI_U_TYPE_NCHAR : 3,
+ CCI_U_TYPE_VARNCHAR : 4,
+ CCI_U_TYPE_BIT : 5,
+ CCI_U_TYPE_VARBIT : 6,
+ CCI_U_TYPE_NUMERIC : 7,
+ CCI_U_TYPE_INT : 8,
+ CCI_U_TYPE_SHORT : 9,
+ CCI_U_TYPE_MONETARY : 10,
+ CCI_U_TYPE_FLOAT : 11,
+ CCI_U_TYPE_DOUBLE : 12,
+ CCI_U_TYPE_DATE : 13,
+ CCI_U_TYPE_TIME : 14,
+ CCI_U_TYPE_TIMESTAMP : 15,
+ CCI_U_TYPE_SET : 16,
+ CCI_U_TYPE_MULTISET : 17,
+ CCI_U_TYPE_SEQUENCE : 18,
+ CCI_U_TYPE_OBJECT : 19,
+ CCI_U_TYPE_RESULTSET : 20,
+ CCI_U_TYPE_BIGINT : 21,
+ CCI_U_TYPE_DATETIME : 22,
+ CCI_U_TYPE_BLOB : 23,
+ CCI_U_TYPE_CLOB : 24
+};
+
+exports.getCUBRIDDataType = function (type) {
+ switch (type) {
+ case this.CUBRIDDataType.CCI_U_TYPE_CHAR:
+ return 'Char';
+ case this.CUBRIDDataType.CCI_U_TYPE_NCHAR:
+ return 'NChar';
+ case this.CUBRIDDataType.CCI_U_TYPE_STRING:
+ return 'String';
+ case this.CUBRIDDataType.CCI_U_TYPE_VARNCHAR:
+ return 'VarNchar';
+ case this.CUBRIDDataType.CCI_U_TYPE_SHORT:
+ return 'Short';
+ case this.CUBRIDDataType.CCI_U_TYPE_INT:
+ return 'Int';
+ case this.CUBRIDDataType.CCI_U_TYPE_BIGINT:
+ return 'Bigint';
+ case this.CUBRIDDataType.CCI_U_TYPE_FLOAT:
+ return 'Float';
+ case this.CUBRIDDataType.CCI_U_TYPE_DOUBLE:
+ return 'Double';
+ case this.CUBRIDDataType.CCI_U_TYPE_MONETARY:
+ return 'Monetary';
+ case this.CUBRIDDataType.CCI_U_TYPE_NUMERIC:
+ return 'Numeric';
+ case this.CUBRIDDataType.CCI_U_TYPE_DATE:
+ return 'Date';
+ case this.CUBRIDDataType.CCI_U_TYPE_TIME:
+ return 'Time';
+ case this.CUBRIDDataType.CCI_U_TYPE_DATETIME:
+ return 'DateTime';
+ case this.CUBRIDDataType.CCI_U_TYPE_TIMESTAMP:
+ return 'Timestamp';
+ case this.CUBRIDDataType.CCI_U_TYPE_OBJECT:
+ return 'Object';
+ case this.CUBRIDDataType.CCI_U_TYPE_BIT:
+ return 'Bit';
+ case this.CUBRIDDataType.CCI_U_TYPE_VARBIT:
+ return 'Varbit';
+ case this.CUBRIDDataType.CCI_U_TYPE_SET:
+ return 'Set';
+ case this.CUBRIDDataType.CCI_U_TYPE_MULTISET:
+ return 'Multiset';
+ case this.CUBRIDDataType.CCI_U_TYPE_SEQUENCE:
+ return 'Sequence';
+ case this.CUBRIDDataType.CCI_U_TYPE_BLOB:
+ return 'Blob';
+ case this.CUBRIDDataType.CCI_U_TYPE_CLOB:
+ return 'Clob';
+ case this.CUBRIDDataType.CCI_U_TYPE_RESULTSET:
+ return 'Resultset';
+ default:
+ return 'UNKNOWN';
+ }
+};
+
+/**
+ * Define CUBRID Schema type constants
+ */
+exports.CUBRIDSchemaType = {
+ CCI_SCH_CLASS : 1,
+ CCI_SCH_VCLASS : 2,
+ CCI_SCH_QUERY_SPEC : 3,
+ CCI_SCH_ATTRIBUTE : 4,
+ CCI_SCH_CLASS_ATTRIBUTE : 5,
+ CCI_SCH_METHOD : 6,
+ CCI_SCH_CLASS_METHOD : 7,
+ CCI_SCH_METHOD_FILE : 8,
+ CCI_SCH_SUPERCLASS : 9,
+ CCI_SCH_SUBCLASS : 10,
+ CCI_SCH_CONSTRAIT : 11,
+ CCI_SCH_TRIGGER : 12,
+ CCI_SCH_CLASS_PRIVILEGE : 13,
+ CCI_SCH_ATTR_PRIVILEGE : 14,
+ CCI_SCH_DIRECT_SUPER_CLASS : 15,
+ CCI_SCH_PRIMARY_KEY : 16,
+ CCI_SCH_IMPORTED_KEYS : 17,
+ CCI_SCH_EXPORTED_KEYS : 18,
+ CCI_SCH_CROSS_REFERENCE : 19
+};
+
+/**
+ * Define CUBRID Prepare statement constants
+ */
+exports.CCIPrepareOption = {
+ CCI_PREPARE_NORMAL : 0x00,
+ CCI_PREPARE_INCLUDE_OID : 0x01,
+ CCI_PREPARE_UPDATABLE : 0x02,
+ CCI_PREPARE_QUERY_INFO : 0x04,
+ CCI_PREPARE_HOLDABLE : 0x08,
+ CCI_PREPARE_CALL : 0x40
+};
+
+/**
+ * Define CUBRID OID commands constants
+ */
+exports.OidCommand = {
+ DROP_BY_OID : 1,
+ IS_INSTANCE : 2,
+ GET_READ_LOCK_BY_OID : 3,
+ GET_WRITE_LOCK_BY_OID : 4,
+ GET_CLASS_NAME_BY_OID : 5
+};
+
+/**
+ * Define CUBRID Transaction type constants
+ */
+exports.CCITransactionType = {
+ CCI_TRAN_COMMIT : 1,
+ CCI_TRAN_ROLLBACK : 2
+};
+
+/**
+ * Define CUBRID Database parameters constants
+ */
+exports.CCIDbParam = {
+ CCI_PARAM_ISOLATION_LEVEL : 1,
+ CCI_PARAM_LOCK_TIMEOUT : 2,
+ CCI_PARAM_MAX_STRING_LENGTH : 3,
+ CCI_PARAM_AUTO_COMMIT : 4
+};
+
+/**
+ * Define CUBRID Collection-related commands constants
+ */
+exports.CUBRIDCollectionCommand = {
+ GET_COLLECTION_VALUE : 1,
+ GET_SIZE_OF_COLLECTION : 2,
+ DROP_ELEMENT_IN_SET : 3,
+ ADD_ELEMENT_TO_SET : 4,
+ DROP_ELEMENT_IN_SEQUENCE : 5,
+ INSERT_ELEMENT_INTO_SEQUENCE : 6,
+ PUT_ELEMENT_ON_SEQUENCE : 7
+};
+
+/**
+ * Define CUBRID Connection status constants
+ */
+exports.ConnectionStatus = {
+ CON_STATUS_OUT_TRAN : 0,
+ CON_STATUS_IN_TRAN : 1,
+ CON_STATUS_CLOSE : 2,
+ CON_STATUS_CLOSE_AND_CONNECT : 3
+};
+
+/**
+ * Define CUBRID Cursor position constants
+ */
+exports.CCICursorPosition = {
+ CCI_CURSOR_FIRST : 0,
+ CCI_CURSOR_CURRENT : 1,
+ CCI_CURSOR_LAST : 2
+};
+
+/**
+ * Define CUBRID Statement execution type constants
+ */
+exports.StmtType = {
+ NORMAL : 0,
+ GET_BY_OID : 1,
+ GET_SCHEMA_INFO : 2,
+ GET_AUTOINCREMENT_KEYS : 3
+};
+
+/**
+ * Define CUBRID Query execution constants
+ */
+exports.QueryExecutionMode = {
+ SYNC_EXEC : 0,
+ ASYNC_EXEC : 1
+};
+
+/**
+ * Define CUBRID Statement execution constants
+ */
+exports.CCIExecutionOption = {
+ CCI_EXEC_NORMAL : 0x00,
+ CCI_EXEC_ASYNC : 0x01,
+ CCI_EXEC_QUERY_ALL : 0x02,
+ CCI_EXEC_QUERY_INFO : 0x04,
+ CCI_EXEC_ONLY_QUERY_PLAN : 0x08,
+ CCI_EXEC_THREAD : 0x10,
+ CCI_EXEC_HOLDABLE : 0x20
+};
+
diff --git a/src/constants/DataTypes.js b/src/constants/DataTypes.js
new file mode 100644
index 0000000..d59d69c
--- /dev/null
+++ b/src/constants/DataTypes.js
@@ -0,0 +1,25 @@
+/**
+ * Define standard CUBRID data types size (in bytes)
+ */
+
+exports.UNSPECIFIED_SIZEOF = 0;
+exports.BYTE_SIZEOF = 1;
+exports.BOOL_SIZEOF = 1;
+exports.INT_SIZEOF = 4;
+exports.LONG_SIZEOF = 8;
+exports.OBJECT_SIZEOF = 8;
+exports.RESULTSET_SIZEOF = 4;
+exports.SHORT_SIZEOF = 2;
+exports.FLOAT_SIZEOF = 4;
+exports.DOUBLE_SIZEOF = 8;
+exports.DATE_SIZEOF = 14;
+exports.TIME_SIZEOF = 14;
+exports.DATETIME_SIZEOF = 14;
+exports.TIMESTAMP_SIZEOF = 14;
+exports.OID_SIZEOF = 8;
+
+exports.DATA_LENGTH_SIZEOF = 4;
+exports.CAS_INFO_SIZE = 4;
+
+
+
diff --git a/src/constants/DriverVersion.js b/src/constants/DriverVersion.js
new file mode 100644
index 0000000..24571f6
--- /dev/null
+++ b/src/constants/DriverVersion.js
@@ -0,0 +1,16 @@
+/**
+ * Define the supported protocol version
+ * The protocol version is validated by the CUBRID broker,
+ * to assess the compatibility level with the CUBRID engine.
+ */
+var CAS_PROTO_INDICATOR = 0x40;
+var CAS_PROTOCOL_VERSION = 0x01;
+
+exports.CAS_VER = CAS_PROTO_INDICATOR | CAS_PROTOCOL_VERSION;
+
+/**
+ * Current driver version
+ * @type {String}
+ */
+exports.DRIVER_VER = '0.1';
+
diff --git a/src/constants/ErrorMessages.js b/src/constants/ErrorMessages.js
new file mode 100644
index 0000000..3daf94e
--- /dev/null
+++ b/src/constants/ErrorMessages.js
@@ -0,0 +1,35 @@
+/**
+ * Define CUBRID error messages
+ */
+exports.CASErrorMsgId = [
+ ['CAS_ER_DBMS' , -1000],
+ ['CAS_ER_INTERNAL' , -1001],
+ ['CAS_ER_NO_MORE_MEMORY' , -1002],
+ ['CAS_ER_COMMUNICATION' , -1003],
+ ['CAS_ER_ARGS' , -1004],
+ ['CAS_ER_TRAN_TYPE' , -1005],
+ ['CAS_ER_SRV_HANDLE' , -1006],
+ ['CAS_ER_NUM_BIND' , -1007],
+ ['CAS_ER_UNKNOWN_U_TYPE' , -1008],
+ ['CAS_ER_DB_VALUE' , -1009],
+ ['CAS_ER_TYPE_CONVERSION' , -1010],
+ ['CAS_ER_PARAM_NAME' , -1011],
+ ['CAS_ER_NO_MORE_DATA' , -1012],
+ ['CAS_ER_OBJECT' , -1013],
+ ['CAS_ER_OPEN_FILE' , -1014],
+ ['CAS_ER_SCHEMA_TYPE' , -1015],
+ ['CAS_ER_VERSION' , -1016],
+ ['CAS_ER_FREE_SERVER' , -1017],
+ ['CAS_ER_NOT_AUTHORIZED_CLIENT' , -1018],
+ ['CAS_ER_QUERY_CANCEL' , -1019],
+ ['CAS_ER_NOT_COLLECTION' , -1020],
+ ['CAS_ER_COLLECTION_DOMAIN' , -1021],
+ ['CAS_ER_NO_MORE_RESULT_SET' , -1022],
+ ['CAS_ER_INVALID_CALL_STMT' , -1023],
+ ['CAS_ER_STMT_POOLING' , -1024],
+ ['CAS_ER_DBSERVER_DISCONNECTED' , -1025],
+ ['CAS_ER_MAX_PREPARED_STMT_COUNT_EXCEEDED' , -1026],
+ ['CAS_ER_HOLDABLE_NOT_ALLOWED' , -1027],
+ ['CAS_ER_NOT_IMPLEMENTED' , -1100],
+ ['CAS_ER_IS' , -1200]
+];
diff --git a/src/packets/BatchExecuteNoQueryPacket.js b/src/packets/BatchExecuteNoQueryPacket.js
new file mode 100644
index 0000000..9c42dad
--- /dev/null
+++ b/src/packets/BatchExecuteNoQueryPacket.js
@@ -0,0 +1,61 @@
+var DATA_TYPES = require('../constants/DataTypes'),
+ ErrorMessages = require('../constants/ErrorMessages'),
+ CAS = require('../constants/CASConstants');
+
+module.exports = BatchExecuteNoQueryPacket;
+
+function BatchExecuteNoQueryPacket(options) {
+ options = options || {};
+
+ this.SQLs = options.SQLs;
+ this.casInfo = options.casInfo;
+ this.autoCommit = options.autoCommitMode;
+
+ this.responseCode = 0;
+ this.errorCode = 0;
+ this.errorMsg = '';
+}
+
+BatchExecuteNoQueryPacket.prototype.write = function (writer) {
+ var statementsLength = 0;
+ for (var i = 0; i < this.SQLs.length; i++) {
+ statementsLength += DATA_TYPES.INT_SIZEOF;
+ statementsLength += (this.SQLs[i].length + 1);
+ }
+ var bufferLength = DATA_TYPES.DATA_LENGTH_SIZEOF + DATA_TYPES.CAS_INFO_SIZE +
+ DATA_TYPES.BYTE_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.BYTE_SIZEOF + statementsLength;
+
+ writer._writeInt(bufferLength - DATA_TYPES.DATA_LENGTH_SIZEOF - DATA_TYPES.CAS_INFO_SIZE);
+ writer._writeBytes(4, this.casInfo);
+ writer._writeByte(CAS.CASFunctionCode.CAS_FC_EXECUTE_BATCH);
+ writer._writeInt(DATA_TYPES.BYTE_SIZEOF);
+ writer._writeByte(this.autoCommit ? 1 : 0); //Autocommit
+ for (var j = 0; j < this.SQLs.length; j++) {
+ writer._writeNullTerminatedString(this.SQLs[j]);
+ }
+
+ return writer;
+};
+
+BatchExecuteNoQueryPacket.prototype.parse = function (parser) {
+ var reponseLength = parser._parseInt();
+ this.casInfo = parser._parseBuffer(4);
+
+ var responseBuffer = parser._parseBuffer(reponseLength);
+ this.responseCode = parser._parseInt();
+ if (this.responseCode < 0) {
+ this.errorCode = parser._parseInt();
+ this.errorMsg = parser._parseNullTerminatedString(responseBuffer.length - 2 * DATA_TYPES.INT_SIZEOF);
+ if (this.errorMsg.length == 0) {
+ for (var iter = 0; iter < ErrorMessages.CASErrorMsgId.length; iter++) {
+ if (this.errorCode == ErrorMessages.CASErrorMsgId[iter][1]) {
+ this.errorMsg = ErrorMessages.CASErrorMsgId[iter][0];
+ break;
+ }
+ }
+ }
+ }
+
+ return this;
+};
+
diff --git a/src/packets/ClientInfoExchangePacket.js b/src/packets/ClientInfoExchangePacket.js
new file mode 100644
index 0000000..f008145
--- /dev/null
+++ b/src/packets/ClientInfoExchangePacket.js
@@ -0,0 +1,37 @@
+var DRIVER_VERSION = require('../constants/DriverVersion');
+
+module.exports = ClientInfoExchangePacket;
+
+/**
+ * Constructor
+ * @constructor
+ */
+function ClientInfoExchangePacket() {
+ this.newConnectionPort = 0;
+}
+
+/**
+ * Write data
+ * @param writer
+ */
+ClientInfoExchangePacket.prototype.write = function (writer) {
+ writer._writeFixedLengthString('CUBRK', 0, 5);
+ writer._writeByte(3); // 3 = JDBC client type
+ writer._writeByte(DRIVER_VERSION.CAS_VER);
+ writer._writeByte(0);
+ writer._writeByte(0);
+ writer._writeByte(0);
+
+ return writer;
+};
+
+/**
+ * Read data
+ * @param parser
+ */
+ClientInfoExchangePacket.prototype.parse = function (parser) {
+ this.newConnectionPort = parser._parseInt();
+
+ return this;
+};
+
diff --git a/src/packets/CloseDatabasePacket.js b/src/packets/CloseDatabasePacket.js
new file mode 100644
index 0000000..484e71f
--- /dev/null
+++ b/src/packets/CloseDatabasePacket.js
@@ -0,0 +1,62 @@
+var DATA_TYPES = require('../constants/DataTypes'),
+ ErrorMessages = require('../constants/ErrorMessages'),
+ CAS = require('../constants/CASConstants');
+
+module.exports = CloseDatabasePacket;
+
+/**
+ * Constructor
+ * @param options
+ * @constructor
+ */
+function CloseDatabasePacket(options) {
+ options = options || {};
+
+ this.casInfo = options.casInfo;
+
+ this.responseCode = 0;
+ this.errorCode = 0;
+ this.errorMsg = '';
+}
+
+/**
+ * Write data
+ * @param writer
+ */
+CloseDatabasePacket.prototype.write = function (writer) {
+ var bufferLength = DATA_TYPES.DATA_LENGTH_SIZEOF + DATA_TYPES.CAS_INFO_SIZE +
+ DATA_TYPES.BYTE_SIZEOF;
+
+ writer._writeInt(bufferLength - DATA_TYPES.DATA_LENGTH_SIZEOF - DATA_TYPES.CAS_INFO_SIZE);
+ writer._writeBytes(4, this.casInfo);
+ writer._writeByte(CAS.CASFunctionCode.CAS_FC_CON_CLOSE);
+
+ return writer;
+};
+
+/**
+ * Read data
+ * @param parser
+ */
+CloseDatabasePacket.prototype.parse = function (parser) {
+ var reponseLength = parser._parseInt();
+ this.casInfo = parser._parseBytes(4);
+
+ var responseBuffer = parser._parseBuffer(reponseLength);
+ this.responseCode = parser._parseInt();
+ if (this.responseCode < 0) {
+ this.errorCode = parser._parseInt();
+ this.errorMsg = parser._parseNullTerminatedString(responseBuffer.length - 2 * DATA_TYPES.INT_SIZEOF);
+ if (this.errorMsg.length == 0) {
+ for (var iter = 0; iter < ErrorMessages.CASErrorMsgId.length; iter++) {
+ if (this.errorCode == ErrorMessages.CASErrorMsgId[iter][1]) {
+ this.errorMsg = ErrorMessages.CASErrorMsgId[iter][0];
+ break;
+ }
+ }
+ }
+ }
+
+ return this;
+};
+
diff --git a/src/packets/CloseQueryPacket.js b/src/packets/CloseQueryPacket.js
new file mode 100644
index 0000000..ef32997
--- /dev/null
+++ b/src/packets/CloseQueryPacket.js
@@ -0,0 +1,68 @@
+var DATA_TYPES = require('../constants/DataTypes'),
+ ErrorMessages = require('../constants/ErrorMessages'),
+ CAS = require('../constants/CASConstants');
+
+module.exports = CloseQueryPacket;
+
+/**
+ * Constructor
+ * @param options
+ * @constructor
+ */
+function CloseQueryPacket(options) {
+ options = options || {};
+
+ this.casInfo = options.casInfo;
+ this.reqHandle = options.reqHandle;
+
+ this.responseCode = 0;
+ this.errorCode = 0;
+ this.errorMsg = '';
+}
+
+/**
+ * Write data
+ * @param writer
+ */
+CloseQueryPacket.prototype.write = function (writer) {
+ var bufferLength = DATA_TYPES.DATA_LENGTH_SIZEOF + DATA_TYPES.CAS_INFO_SIZE +
+ DATA_TYPES.BYTE_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF +
+ DATA_TYPES.INT_SIZEOF + DATA_TYPES.BYTE_SIZEOF;
+
+ writer._writeInt(bufferLength - DATA_TYPES.DATA_LENGTH_SIZEOF - DATA_TYPES.CAS_INFO_SIZE);
+ writer._writeBytes(4, this.casInfo);
+ writer._writeByte(CAS.CASFunctionCode.CAS_FC_CLOSE_REQ_HANDLE);
+ writer._writeInt(DATA_TYPES.INT_SIZEOF);
+ writer._writeInt(this.reqHandle);
+ writer._writeInt(1); //TODO Document this value
+ writer._writeByte(0); //autocommit mode
+
+ return writer;
+};
+
+/**
+ * Read data
+ * @param parser
+ */
+CloseQueryPacket.prototype.parse = function (parser) {
+ var reponseLength = parser._parseInt();
+ this.casInfo = parser._parseBytes(4);
+
+ var responseBuffer = parser._parseBuffer(reponseLength);
+ this.responseCode = parser._parseInt();
+ if (this.responseCode < 0) {
+ this.errorCode = parser._parseInt();
+ this.errorMsg = parser._parseNullTerminatedString(responseBuffer.length - 2 * DATA_TYPES.INT_SIZEOF);
+ if (this.errorMsg.length == 0) {
+ for (var iter = 0; iter < ErrorMessages.CASErrorMsgId.length; iter++) {
+ if (this.errorCode == ErrorMessages.CASErrorMsgId[iter][1]) {
+ this.errorMsg = ErrorMessages.CASErrorMsgId[iter][0];
+ break;
+ }
+ }
+ }
+ }
+
+ return this;
+};
+
diff --git a/src/packets/ExecuteQueryPacket.js b/src/packets/ExecuteQueryPacket.js
new file mode 100644
index 0000000..2950153
--- /dev/null
+++ b/src/packets/ExecuteQueryPacket.js
@@ -0,0 +1,271 @@
+var DATA_TYPES = require('../constants/DataTypes'),
+ CAS = require('../constants/CASConstants'),
+ ErrorMessages = require('../constants/ErrorMessages'),
+ ColumnMetaData = require('../resultset/ColumnMetaData'),
+ ResultInfo = require('../resultset/ResultInfo');
+
+module.exports = ExecuteQueryPacket;
+
+/**
+ * Constructor
+ * @param options
+ * @constructor
+ */
+function ExecuteQueryPacket(options) {
+ options = options || {};
+
+ this.casInfo = options.casInfo;
+ this.sql = options.sql;
+ this.autoCommit = options.autoCommitMode;
+ this.resultset = '';
+ this.resultCacheLifetime = 0;
+ this.statementType = null;
+ this.bindCount = 0;
+ this.isUpdatable = false;
+ this.totalTupleCount = 0;
+ this.cache_reusable = 0;
+ this.resultCount = 0;
+ this.resultInfos = null;
+ this.columnCount = 0;
+ this.infoArray = new ColumnMetaData();
+ this.resultInfos = new ResultInfo();
+ this.handle = 0;
+ this.currentTupleCount = 0;
+ this.tupleCount = 0;
+ this.errorCode = 0;
+ this.errorMsg = '';
+}
+
+/**
+ * Write data
+ * @param writer
+ */
+ExecuteQueryPacket.prototype.write = function (writer) {
+ var bufferLength = DATA_TYPES.DATA_LENGTH_SIZEOF + DATA_TYPES.CAS_INFO_SIZE +
+ DATA_TYPES.BYTE_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF +
+ this.sql.length + 1 + DATA_TYPES.INT_SIZEOF + DATA_TYPES.BYTE_SIZEOF +
+ DATA_TYPES.INT_SIZEOF + DATA_TYPES.BYTE_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.BYTE_SIZEOF +
+ DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF +
+ DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF +
+ DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF;
+
+ //Prepare info
+ writer._writeInt(bufferLength - DATA_TYPES.DATA_LENGTH_SIZEOF - DATA_TYPES.CAS_INFO_SIZE);
+ writer._writeBytes(4, this.casInfo);
+ writer._writeByte(CAS.CASFunctionCode.CAS_FC_PREPARE_AND_EXECUTE);
+ writer._writeInt(DATA_TYPES.INT_SIZEOF);
+ writer._writeInt(3);// number of CAS args
+ writer._writeNullTerminatedString(this.sql);//sql string
+ writer._writeInt(DATA_TYPES.BYTE_SIZEOF);
+ writer._writeByte(CAS.CCIPrepareOption.CCI_PREPARE_NORMAL); //prepare flag
+ writer._writeInt(DATA_TYPES.BYTE_SIZEOF);
+ writer._writeByte(this.autoCommit ? 1 : 0); //autocommit mode
+
+ //Execute info
+ writer._writeInt(DATA_TYPES.BYTE_SIZEOF);
+ writer._writeByte(CAS.CCIExecutionOption.CCI_EXEC_QUERY_ALL); //execute flag
+ writer._writeInt(DATA_TYPES.INT_SIZEOF);
+ writer._writeInt(0); //max col size;
+ writer._writeInt(DATA_TYPES.INT_SIZEOF);
+ writer._writeInt(0); //max row size;
+ writer._writeInt(0);//NULL
+ writer._writeInt(2 * DATA_TYPES.INT_SIZEOF); // write cache time
+ writer._writeInt(0); //seconds
+ writer._writeInt(0); //useconds
+ writer._writeInt(DATA_TYPES.INT_SIZEOF);
+ writer._writeInt(0);//query timeout
+
+ return writer;
+};
+
+/**
+ * Read data
+ * @param parser
+ */
+ExecuteQueryPacket.prototype.parse = function (parser) {
+ var reponseLength = parser._parseInt();
+ this.casInfo = parser._parseInt();
+
+ //var responseBuffer = parser.parseBuffer(reponseLength);
+ this.handle = parser._parseInt();
+ if (this.handle < 0) {
+ this.errorCode = parser._parseInt();
+ this.errorMsg = parser._parseNullTerminatedString(reponseLength - 2 * DATA_TYPES.INT_SIZEOF);
+ if (this.errorMsg.length == 0) {
+ for (var iter = 0; iter < ErrorMessages.CASErrorMsgId.length; iter++) {
+ if (this.errorCode == ErrorMessages.CASErrorMsgId[iter][1]) {
+ this.errorMsg = ErrorMessages.CASErrorMsgId[iter][0];
+ break;
+ }
+ }
+ }
+ return -1; //TODO Document this
+ } else {
+ this.resultCacheLifetime = parser._parseInt();
+ this.statementType = parser._parseByte();
+ this.bindCount = parser._parseInt();
+ this.isUpdatable = (parser._parseByte() === 0);
+ this.columnCount = parser._parseInt();
+ this.infoArray = new Array();
+ for (i = 0; i < this.columnCount; i++) {
+ var info = new ColumnMetaData();
+ info.ColumnType = parser._parseByte();
+ info.scale = parser._parseShort();
+ info.precision = parser._parseInt();
+ var len = parser._parseInt();
+ info.Name = parser._parseNullTerminatedString(len);
+ if (true) { //TODO Refactor condition
+ len = parser._parseInt();
+ info.RealName = parser._parseNullTerminatedString(len);
+ len = parser._parseInt();
+ info.TableName = parser._parseNullTerminatedString(len);
+ info.IsNullable = (parser._parseByte() === 1);
+ len = parser._parseInt();
+ info.DafaultValue = parser._parseNullTerminatedString(len);
+ info.IsAutoIncrement = (parser._parseByte() === 1);
+ info.IsUniqueKey = (parser._parseByte() === 1);
+ info.IsPrimaryKey = (parser._parseByte() === 1);
+ info.IsReverseIndex = (parser._parseByte() === 1);
+ info.IsReverseUnique = (parser._parseByte() === 1);
+ info.IsForeignKey = (parser._parseByte() === 1);
+ info.IsShared = (parser._parseByte() === 1);
+ }
+ this.infoArray[i] = info;
+ }
+
+ this.totalTupleCount = parser._parseInt();
+ this.cache_reusable = parser._parseByte();
+ this.resultCount = parser._parseInt();
+ //read resultinfo
+ for (i = 0; i < this.resultCount; i++) {
+ var resultInfo = new ResultInfo();
+ resultInfo.StmtType = parser._parseByte();
+ resultInfo.ResultCount = parser._parseInt();
+ resultInfo.Oid = parser._parseBytes(8);
+ resultInfo.CacheTimeSec = parser._parseInt();
+ resultInfo.CacheTimeUsec = parser._parseInt();
+ this.resultInfos[i] = resultInfo;
+ }
+ }
+
+ if (this.statementType === CAS.CUBRIDStatementType.CUBRID_STMT_SELECT) {
+ var fetchCode = parser._parseInt();
+ this.tupleCount = parser._parseInt();
+ var columnNames = new Array(this.columnCount);
+ var columnDataTypes = new Array(this.columnCount);
+ var columnValues = new Array(this.tupleCount);
+ for (var i = 0; i < this.columnCount; i++) {
+ columnNames[i] = this.infoArray[i].Name;
+ columnDataTypes[i] = CAS.getCUBRIDDataType(this.infoArray[i].ColumnType);
+ }
+
+ columnValues = this._getData(parser, this.tupleCount);
+
+ return JSON.stringify({
+ ColumnNames : columnNames,
+ ColumnDataTypes : columnDataTypes,
+ RowsCount : this.totalTupleCount,
+ ColumnValues : columnValues
+ });
+ }
+
+ return parser;
+};
+
+ExecuteQueryPacket.prototype._getData = function (parser, tupleCount) {
+ var columnValues = new Array(tupleCount);
+ for (var i = 0; i < tupleCount; i++) {
+ columnValues[i] = new Array(this.columnCount);
+ var index = parser._parseInt();
+ var Oid = parser._parseBytes(8);
+ for (var j = 0; j < this.columnCount; j++) {
+ var size = parser._parseInt();
+ var val;
+ if (size <= 0) {
+ val = null;
+ } else {
+ var type = CAS.CUBRIDDataType.CCI_U_TYPE_NULL;
+
+ if (this.statementType === CAS.CUBRIDStatementType.CUBRID_STMT_CALL ||
+ this.statementType === CAS.CUBRIDStatementType.CUBRID_STMT_EVALUATE ||
+ this.statementType === CAS.CUBRIDStatementType.CUBRID_STMT_CALL_SP ||
+ this.infoArray[j].ColumnType === CAS.CUBRIDDataType.CCI_U_TYPE_NULL) {
+ type = parser._parseByte();
+ size--;
+ } else {
+ type = this.infoArray[j].ColumnType;
+ }
+
+ val = this._readValue(j, type, size, parser);
+ columnValues[i][j] = val;
+ }
+ }
+ }
+ this.currentTupleCount += tupleCount;
+ return columnValues;
+};
+
+ExecuteQueryPacket.prototype._readValue = function (index, type, size, parser) {
+ switch (type) {
+ case CAS.CUBRIDDataType.CCI_U_TYPE_CHAR:
+ case CAS.CUBRIDDataType.CCI_U_TYPE_NCHAR:
+ case CAS.CUBRIDDataType.CCI_U_TYPE_STRING:
+ case CAS.CUBRIDDataType.CCI_U_TYPE_VARNCHAR:
+ return parser._parseNullTerminatedString(size);
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_SHORT:
+ return parser._parseShort();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_INT:
+ return parser._parseInt();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_BIGINT:
+ return parser._parseLong();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_FLOAT:
+ return parser._parseFloat();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_DOUBLE:
+ case CAS.CUBRIDDataType.CCI_U_TYPE_MONETARY:
+ return parser._parseDouble();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_NUMERIC:
+ return parser._parseNumeric(size);
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_DATE:
+ return parser._parseDate();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_TIME:
+ return parser._parseTime();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_DATETIME:
+ return parser._parseDateTime();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_TIMESTAMP:
+ return parser._parseTimeStamp();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_OBJECT:
+ return parser._parseObject();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_BIT:
+ case CAS.CUBRIDDataType.CCI_U_TYPE_VARBIT:
+ return parser._parseBytes(size)[0]; //TODO: Refactor this
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_SET:
+ case CAS.CUBRIDDataType.CCI_U_TYPE_MULTISET:
+ case CAS.CUBRIDDataType.CCI_U_TYPE_SEQUENCE:
+ return parser._parseSequence();
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_BLOB:
+ return parser._parseBlob(size);
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_CLOB:
+ return parser._parseClob(size);
+
+ case CAS.CUBRIDDataType.CCI_U_TYPE_RESULTSET:
+ return parser._parseResultSet();
+
+ default:
+ return new Error('Invalid data type');
+ }
+};
diff --git a/src/packets/FetchPacket.js b/src/packets/FetchPacket.js
new file mode 100644
index 0000000..c910fcf
--- /dev/null
+++ b/src/packets/FetchPacket.js
@@ -0,0 +1,76 @@
+var DATA_TYPES = require('../constants/DataTypes'),
+ ErrorMessages = require('../constants/ErrorMessages'),
+ CAS = require('../constants/CASConstants');
+
+module.exports = FetchPacket;
+
+/**
+ * Constructor
+ * @param options
+ * @constructor
+ */
+function FetchPacket(options) {
+ this.casInfo = options.casInfo;
+
+ this.responseCode = 0;
+ this.errorCode = 0;
+ this.errorMsg = '';
+}
+
+/**
+ * Write data
+ * @param writer
+ */
+FetchPacket.prototype.write = function (writer, queryHandle) {
+ var bufferLength = DATA_TYPES.DATA_LENGTH_SIZEOF + DATA_TYPES.CAS_INFO_SIZE +
+ DATA_TYPES.BYTE_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF +
+ DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF +
+ DATA_TYPES.INT_SIZEOF + DATA_TYPES.BYTE_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.INT_SIZEOF;
+
+ writer._writeInt(bufferLength - DATA_TYPES.DATA_LENGTH_SIZEOF - DATA_TYPES.CAS_INFO_SIZE);
+ writer._writeBytes(4, this.casInfo);
+
+ writer._writeByte(CAS.CASFunctionCode.CAS_FC_FETCH);
+ writer._writeInt(4); //int sizeof
+ writer._writeInt(queryHandle.handle); //serverHandler
+ writer._writeInt(4); //int sizeof
+ writer._writeInt(queryHandle.currentTupleCount + 1); //Start position (= current cursor position + 1)
+ writer._writeInt(4); //int sizeof
+ writer._writeInt(100); //Fetch size; 0 = default; recommended = 100
+ writer._writeInt(1); //byte sizeof
+ writer._writeByte(0); //Is case sensitive
+ writer._writeInt(4); //int sizeof
+ writer._writeInt(0); //Is the ResultSet index...?
+
+ return writer;
+};
+
+/**
+ * Read data
+ * @param parser
+ * @param queryHandle
+ */
+FetchPacket.prototype.parse = function (parser, queryHandle) {
+ var responseLength = parser._parseInt();
+ this.casInfo = parser._parseBuffer(4);
+
+ this.responseCode = parser._parseInt();
+ if (this.responseCode !== 0) {
+ this.errorCode = parser._parseInt();
+ this.errorMsg = parser._parseNullTerminatedString(responseLength - 2 * DATA_TYPES.INT_SIZEOF);
+ if (this.errorMsg.length == 0) {
+ for (var iter = 0; iter < ErrorMessages.CASErrorMsgId.length; iter++) {
+ if (this.errorCode == ErrorMessages.CASErrorMsgId[iter][1]) {
+ this.errorMsg = ErrorMessages.CASErrorMsgId[iter][0];
+ break;
+ }
+ }
+ }
+ }
+ else {
+ this.tupleCount = parser._parseInt();
+ return JSON.stringify({ColumnValues : queryHandle._getData(parser, this.tupleCount)});
+ }
+};
+
+
diff --git a/src/packets/GetEngineVersionPacket.js b/src/packets/GetEngineVersionPacket.js
new file mode 100644
index 0000000..6f29948
--- /dev/null
+++ b/src/packets/GetEngineVersionPacket.js
@@ -0,0 +1,67 @@
+var DATA_TYPES = require('../constants/DataTypes'),
+ ErrorMessages = require('../constants/ErrorMessages'),
+ CAS = require('../constants/CASConstants');
+
+module.exports = GetEngineVersionPacket;
+
+/**
+ * Constructor
+ * @param options
+ * @constructor
+ */
+function GetEngineVersionPacket(options) {
+ options = options || {};
+
+ this.casInfo = options.casInfo;
+
+ this.engineVersion = '';
+
+ this.responseCode = 0;
+ this.errorCode = 0;
+ this.errorMsg = '';
+}
+
+/**
+ * Write data
+ * @param writer
+ */
+GetEngineVersionPacket.prototype.write = function (writer) {
+ var bufferLength = DATA_TYPES.DATA_LENGTH_SIZEOF + DATA_TYPES.CAS_INFO_SIZE +
+ DATA_TYPES.BYTE_SIZEOF + DATA_TYPES.INT_SIZEOF + DATA_TYPES.BYTE_SIZEOF;
+
+ writer._writeInt(bufferLength - DATA_TYPES.DATA_LENGTH_SIZEOF - DATA_TYPES.CAS_INFO_SIZE);
+ writer._writeBytes(4, this.casInfo);
+ writer._writeByte(CAS.CASFunctionCode.CAS_FC_GET_DB_VERSION);
+ writer._writeInt(DATA_TYPES.BYTE_SIZEOF);
+ writer._writeByte(1);
+
+ return writer;
+};
+
+/**
+ * Read data
+ * @param parser
+ */
+GetEngineVersionPacket.prototype.parse = function (parser) {
+ var reponseLength = parser._parseInt();
+ this.casInfo = parser._parseBuffer(4);
+ this.responseCode = parser._parseInt();
+ if (this.responseCode < 0) {
+ this.errorCode = parser._parseInt();
+ this.errorMsg = parser._parseNullTerminatedString(reponseLength - 2 * DATA_TYPES.INT_SIZEOF);
+ if (this.errorMsg.length == 0) {
+ for (var iter = 0; iter < ErrorMessages.CASErrorMsgId.length; iter++) {
+ if (this.errorCode == ErrorMessages.CASErrorMsgId[iter][1]) {
+ this.errorMsg = ErrorMessages.CASErrorMsgId[iter][0];
+ break;
+ }
+ }
+ }
+ } else {
+ this.engineVersion = parser._parseNullTerminatedString(reponseLength - DATA_TYPES.INT_SIZEOF);
+ }
+
+ return this;
+};
+
+
diff --git a/src/packets/OpenDatabasePacket.js b/src/packets/OpenDatabasePacket.js
new file mode 100644
index 0000000..f9722a9
--- /dev/null
+++ b/src/packets/OpenDatabasePacket.js
@@ -0,0 +1,69 @@
+var DATA_TYPES = require('../constants/DataTypes'),
+ ErrorMessages = require('../constants/ErrorMessages'),
+ CAS = require('../constants/CASConstants');
+
+module.exports = OpenDatabasePacket;
+
+/**
+ * Constructor
+ * @param options
+ * @constructor
+ */
+function OpenDatabasePacket(options) {
+ options = options || {};
+
+ this.database = options.database;
+ this.user = options.user;
+ this.password = options.password;
+
+ this.casInfo = options.casInfo;
+
+ this.responseCode = 0;
+ this.errorCode = 0;
+ this.errorMsg = '';
+}
+
+/**
+ * Write data
+ * @param writer
+ */
+OpenDatabasePacket.prototype.write = function (writer) {
+ writer._writeFixedLengthString(this.database, 0, 32);
+ writer._writeFixedLengthString(this.user, 0, 32);
+ writer._writeFixedLengthString(this.password, 0, 32);
+ writer._writeFiller(512, 0);
+ writer._writeFiller(20, 0);
+
+ return writer;
+};
+
+/**
+ * Read data
+ * @param parser
+ */
+OpenDatabasePacket.prototype.parse = function (parser) {
+ var reponseLength = parser._parseInt();
+ this.casInfo = parser._parseBytes(4);
+
+ this.responseCode = parser._parseInt();
+ if (this.responseCode < 0) {
+ this.errorCode = parser._parseInt();
+ this.errorMsg = parser._parseNullTerminatedString(reponseLength - DATA_TYPES.INT_SIZEOF * 2);
+ if (this.errorMsg.length == 0) {
+ for (var iter = 0; iter < ErrorMessages.CASErrorMsgId.length; iter++) {
+ if (this.errorCode == ErrorMessages.CASErrorMsgId[iter][1]) {
+ this.errorMsg = ErrorMessages.CASErrorMsgId[iter][0];
+ break;
+ }
+ }
+ }
+ } else {
+ //this.processId = this.responseCode;
+ this.brokerInfo = parser._parseBytes(8);
+ this.sessionId = parser._parseInt();
+ }
+
+ return this;
+};
+
+
diff --git a/src/packets/PacketReader.js b/src/packets/PacketReader.js
new file mode 100644
index 0000000..abb4e61
--- /dev/null
+++ b/src/packets/PacketReader.js
@@ -0,0 +1,348 @@
+var DATA_TYPES = require('./../constants/DataTypes'),
+ CAS = require('../constants/CASConstants');
+
+module.exports = PacketReader;
+
+/**
+ * PacketReader
+ * @constructor
+ */
+function PacketReader() {
+ this._buffer = null;
+ this._offset = 0;
+}
+
+/**
+ * Write a buffer value to the internal buffer
+ * @param buffer
+ */
+PacketReader.prototype.write = function (buffer) {
+ this._append(buffer);
+};
+
+//TODO Optimize the performance of this function
+/**
+ * Append a buffer value to the internal buffer
+ * @param newBuffer
+ */
+PacketReader.prototype._append = function (newBuffer) {
+ var oldBuffer = this._buffer;
+
+ if (!oldBuffer) {
+ this._buffer = newBuffer;
+ return;
+ }
+
+ var bytesRemaining = this._bytesRemaining();
+ var newLength = bytesRemaining + newBuffer.length;
+
+ var combinedBuffer = (this._offset > newLength)
+ ? oldBuffer.slice(0, newLength)
+ : new Buffer(newLength);
+
+ oldBuffer.copy(combinedBuffer, 0, this._offset);
+ newBuffer.copy(combinedBuffer, bytesRemaining);
+
+ this._buffer = combinedBuffer;
+ this._offset = 0;
+};
+
+/**
+ * Returns an short value from the internal buffer
+ * @return {Number}
+ */
+PacketReader.prototype._parseShort = function () {
+ var value = 0;
+
+ for (var i = DATA_TYPES.SHORT_SIZEOF - 1; i >= 0; i--) {
+ value += this._buffer[this._offset++] * Math.pow(256, i);
+ }
+
+ if (value & 0x8000) {
+ return value - 0xFFFF - 1;
+ } else {
+ return value;
+ }
+};
+
+/**
+ * Returns an integer value from the internal buffer
+ * @return {Number}
+ */
+PacketReader.prototype._parseInt = function () {
+ var value = 0;
+
+ for (var i = DATA_TYPES.INT_SIZEOF - 1; i >= 0; i--) {
+ value += this._buffer[this._offset++] * Math.pow(256, i);
+ }
+
+ if (value & 0x80000000) {
+ return value - 0xFFFFFFFF - 1;
+ } else {
+ return value;
+ }
+};
+
+/**
+ * Returns a byte value from the internal buffer
+ * @return {Number}
+ */
+PacketReader.prototype._parseByte = function () {
+ return this._buffer[this._offset++];
+};
+
+/**
+ * Returns a bytes array from the internal buffer
+ * @param bytesCount
+ * @return {Array}
+ */
+PacketReader.prototype._parseBytes = function (bytesCount) {
+ var buffer = this._buffer.slice(this._offset, this._offset + bytesCount);
+
+ this._offset += bytesCount;
+
+ return buffer;
+};
+
+/**
+ * Returns a buffer object from the internal buffer
+ * @param bytesCount
+ * @return {*}
+ */
+PacketReader.prototype._parseBuffer = function (bytesCount) {
+ var buffer = this._buffer.slice(this._offset, this._offset + bytesCount);
+
+ this._offset += bytesCount;
+
+ return buffer;
+};
+
+/**
+ * Returns a string value from the internal buffer
+ * @param bytesCount
+ * @return {Buffer}
+ */
+PacketReader.prototype._parseString = function (bytesCount) {
+ if (bytesCount <= 0) {
+ return '';
+ }
+
+ var start = this._offset;
+ var end = start + bytesCount;
+ var buffer = this._buffer.slice(start, end);
+
+ var value = '';
+ for (var i = 0; i < buffer.length; i++) {
+ value += String.fromCharCode(buffer[i]);
+ }
+
+ this._offset = end;
+
+ return value;
+};
+
+/**
+ * Returns a string value from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseNullTerminatedString = function (length) {
+ if (length <= 0) {
+ return '';
+ }
+
+ var valueLen = length - 1; //get the actual null-terminated string length
+ var buffer = this._buffer.slice(this._offset, this._offset + valueLen);
+ var value = '';
+
+ for (var i = 0; i < buffer.length; i++) {
+ value += String.fromCharCode(buffer[i]);
+ }
+
+ this._offset += valueLen;
+ this._parseByte(); //read also the null-terminate
+
+ return value;
+};
+
+/**
+ * Returns a date value from the internal buffer
+ * @return {Date}
+ */
+PacketReader.prototype._parseDate = function () {
+ var year = this._parseShort();
+ var month = this._parseShort();
+ var day = this._parseShort();
+ var hour = 0;
+ var min = 0;
+ var sec = 0;
+ var msec = 0;
+
+ return new Date(year, month, day, hour, min, sec, msec);
+};
+
+/**
+ * Returns a datetime value from the internal buffer
+ * @return {Date}
+ */
+PacketReader.prototype._parseDateTime = function () {
+ var year = this._parseShort();
+ var month = this._parseShort();
+ var day = this._parseShort();
+ var hour = this._parseShort();
+ var min = this._parseShort();
+ var sec = this._parseShort();
+ var msec = this._parseShort();
+
+ return new Date(year, month, day, hour, min, sec, msec);
+};
+
+/**
+ * Returns a time value from the internal buffer
+ * @return {Date}
+ */
+PacketReader.prototype._parseTime = function () {
+ var year = 0;
+ var month = 0;
+ var day = 0;
+ var hour = this._parseShort();
+ var min = this._parseShort();
+ var sec = this._parseShort();
+ var msec = 0;
+
+ return new Date(year, month, day, hour, min, sec, msec);
+};
+
+/**
+ * Returns a timestamp value from the internal buffer
+ * @return {Date}
+ */
+PacketReader.prototype._parseTimeStamp = function () {
+ var year = this._parseShort();
+ var month = this._parseShort();
+ var day = this._parseShort();
+ var hour = this._parseShort();
+ var min = this._parseShort();
+ var sec = this._parseShort();
+ var msec = 0;
+
+ return new Date(year, month, day, hour, min, sec, msec);
+};
+
+/**
+ * Returns a char value from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseChar = function () {
+ var val = this._parseByte();
+
+ return String.fromCharCode(val);
+};
+
+/**
+ * Returns a long value from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseLong = function () {
+ this._offset += DATA_TYPES.LONG_SIZEOF;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Returns a double value from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseDouble = function () {
+ this._offset += DATA_TYPES.DOUBLE_SIZEOF;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Returns a floating point value from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseFloat = function () {
+ this._offset += DATA_TYPES.FLOAT_SIZEOF;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Returns a numeric value from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseNumeric = function (size) {
+ this._offset += size;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Returns a object value from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseObject = function () {
+ this._offset += DATA_TYPES.OBJECT_SIZEOF;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Returns a blob object from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseBlob = function (size) {
+ this._offset += size;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Returns a clob object from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseClob = function (size) {
+ this._offset += size;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Returns a sequence of values from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseSequence = function () {
+ var count = this._parseInt();
+ var size = this._parseInt();
+ this._offset += count * size;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Returns a ResultSet from the internal buffer
+ * @return {String}
+ */
+PacketReader.prototype._parseResultSet = function () {
+ this._offset += DATA_TYPES.RESULTSET_SIZEOF;
+
+ return null; //Not implemented yet!
+};
+
+/**
+ * Return the number of bytes remaining unparsed/unread in the buffer
+ * @return {Number}
+ */
+PacketReader.prototype._bytesRemaining = function () {
+ return this._buffer.length - this._offset;
+};
+
+/**
+ * Return the internal buffer length
+ * @return {Number}
+ */
+PacketReader.prototype._packetLength = function () {
+ return this._buffer.length;
+};
+
diff --git a/src/packets/PacketWriter.js b/src/packets/PacketWriter.js
new file mode 100644
index 0000000..272a9c9
--- /dev/null
+++ b/src/packets/PacketWriter.js
@@ -0,0 +1,240 @@
+var DATA_TYPES = require('./../constants/DataTypes');
+
+module.exports = PacketWriter;
+
+/**
+ * Create a new instance
+ * @constructor
+ */
+function PacketWriter() {
+ this._buffer = new Buffer(0);
+ this._offset = 0;
+}
+
+/**
+ * Write the current buffer content
+ * @return {*}
+ */
+PacketWriter.prototype._toBuffer = function () {
+ return this._buffer.slice(0, this._offset);
+};
+
+/**
+ * Write a byte value to the internal buffer
+ * @param value
+ */
+PacketWriter.prototype._writeByte = function (value) {
+ this._allocate(DATA_TYPES.BYTE_SIZEOF);
+
+ this._buffer[this._offset++] = value & 0xFF;
+};
+
+/**
+ * Write a char value to the internal buffer
+ * @param value
+ */
+PacketWriter.prototype._writeChar = function (value) {
+ this._allocate(DATA_TYPES.BYTE_SIZEOF);
+
+ this._buffer[this._offset++] = value.charCodeAt(0);
+};
+
+/**
+ * Write a bytes array to the internal buffer
+ * @param bytesCount
+ * @param value
+ */
+PacketWriter.prototype._writeBytes = function (bytesCount, value) {
+ this._allocate(bytesCount);
+
+ for (var i = 0; i < bytesCount; i++) {
+ this._buffer[this._offset++] = value[i] & 0xFF;
+ }
+};
+
+/**
+ * Write a short value to the internal buffer
+ * @param value
+ */
+PacketWriter.prototype._writeShort = function (value) {
+ this._allocate(DATA_TYPES.SHORT_SIZEOF);
+
+ this._writeByte((value >> 8) & 0xFF);
+ this._writeByte((value >> 0) & 0xFF);
+};
+
+/**
+ * Write a integer value to the internal buffer
+ * @param value
+ */
+PacketWriter.prototype._writeInt = function (value) {
+ this._allocate(DATA_TYPES.INT_SIZEOF);
+
+ this._writeByte((value >> 24) & 0xFF);
+ this._writeByte((value >> 16) & 0xFF);
+ this._writeByte((value >> 8) & 0xFF);
+ this._writeByte((value >> 0) & 0xFF);
+};
+
+/**
+ * Write the specified value to the internal buffer
+ * @param bytesCount
+ * @param fillerValue
+ */
+PacketWriter.prototype._writeFiller = function (bytesCount, fillerValue) {
+ var fillerVal;
+ this._allocate(bytesCount);
+
+ fillerValue = typeof fillerValue != 'undefined' ? fillerValue : 0x00;
+
+ if (typeof fillerValue == 'string') {
+ fillerVal = fillerValue.charCodeAt(0);
+ } else {
+ fillerVal = fillerValue & 0xFF;
+ }
+
+ for (var i = 0; i < bytesCount; i++) {
+ this._buffer[this._offset++] = fillerVal;
+ }
+};
+
+/**
+ * Write a null-terminate string to the internal buffer
+ * @param value
+ */
+PacketWriter.prototype._writeNullTerminatedString = function (value) {
+ //Typecast undefined into '' and numbers into strings
+ value = value || '';
+ value = value + '';
+
+ var count = DATA_TYPES.INT_SIZEOF + value.length + DATA_TYPES.BYTE_SIZEOF;
+ this._allocate(count);
+
+ //Write length
+ this._writeInt(value.length + 1);
+
+ //Write string content
+ for (var i = 0; i < value.length; i++) {
+ this._buffer[this._offset++] = value.charCodeAt(i);
+ }
+
+ //Write null-terminate
+ this._buffer[this._offset++] = 0;
+};
+
+/**
+ * Write a fixed-length string to the internal buffer
+ * @param value
+ * @param fillerValue
+ * @param fixedLength
+ */
+PacketWriter.prototype._writeFixedLengthString = function (value, fillerValue, fixedLength) {
+ var fillerVal;
+ //Typecast undefined into '' and numbers into strings
+ value = value || '';
+ value = value + '';
+
+ var count = value.length;
+ if (count >= fixedLength) {
+ count = fixedLength;
+ }
+
+ this._allocate(fixedLength);
+
+ for (var i = 0; i < value.length; i++) {
+ this._buffer[this._offset++] = value[i].charCodeAt(0);
+ }
+
+ if (typeof fillerValue == 'string') {
+ fillerVal = fillerValue.charCodeAt(0);
+ } else {
+ fillerVal = fillerValue & 0xFF;
+ }
+
+ for (var j = 1; j <= fixedLength - count; j++) {
+ this._buffer[this._offset++] = fillerVal;
+ }
+};
+
+PacketWriter.prototype._writeDate = function (year, month, day) {
+ this._allocate(DATA_TYPES.DATETIME_SIZEOF);
+
+ this._writeShort(year);
+ this._writeShort(month);
+ this._writeShort(day);
+ this._writeShort(0);
+ this._writeShort(0);
+ this._writeShort(0);
+ this._writeShort(0);
+};
+
+PacketWriter.prototype._writeDateTime = function (year, month, day, hour, min, sec, msec) {
+ this._allocate(DATA_TYPES.DATETIME_SIZEOF);
+
+ this._writeShort(year);
+ this._writeShort(month);
+ this._writeShort(day);
+ this._writeShort(hour);
+ this._writeShort(min);
+ this._writeShort(sec);
+ this._writeShort(msec);
+};
+
+PacketWriter.prototype._writeTime = function (hour, min, sec) {
+ this._allocate(DATA_TYPES.DATETIME_SIZEOF);
+
+ this._writeShort(0);
+ this._writeShort(0);
+ this._writeShort(0);
+ this._writeShort(hour);
+ this._writeShort(min);
+ this._writeShort(sec);
+ this._writeShort(0);
+};
+
+PacketWriter.prototype._writeTimestamp = function (year, month, day, hour, min, sec) {
+ this._allocate(DATA_TYPES.DATETIME_SIZEOF);
+
+ this._writeShort(year);
+ this._writeShort(month);
+ this._writeShort(day);
+ this._writeShort(hour);
+ this._writeShort(min);
+ this._writeShort(sec);
+ this._writeShort(0);
+};
+
+/**
+ * Write a generic object value to the internal buffer
+ * @param value
+ */
+PacketWriter.prototype._writeBuffer = function (value) {
+ var count = value.length;
+
+ this._allocate(count);
+ value.copy(this._buffer, this._offset);
+ this._offset += count;
+};
+
+//TODO Optimize the performance of this function
+/**
+ * Allocate space to the internal buffer
+ * @param count
+ * @private
+ */
+PacketWriter.prototype._allocate = function (count) {
+ if (!this._buffer) {
+ this._buffer = new Buffer(count);
+ return;
+ }
+
+ //Verify if we need to allocate more space
+ var bytesRemaining = this._buffer.length - this._offset;
+ if (bytesRemaining >= count) {
+ return;
+ }
+
+ var oldBuffer = this._buffer;
+ this._buffer = new Buffer(oldBuffer.length + count);
+ oldBuffer.copy(this._buffer);
+};
diff --git a/src/resultset/ColumnMetaData.js b/src/resultset/ColumnMetaData.js
new file mode 100644
index 0000000..6a65a6c
--- /dev/null
+++ b/src/resultset/ColumnMetaData.js
@@ -0,0 +1,28 @@
+var CAS = require('../constants/CASConstants');
+
+module.exports = ColumnMetaData;
+
+/**
+ * Column meta data
+ * @constructor
+ */
+function ColumnMetaData() {
+ this.ColumnType = null;
+ this.CollectionElementType = CAS.CUBRIDDataType.CCI_U_TYPE_UNKNOWN;
+ this.Scale = -1;
+ this.Precision = -1;
+ this.RealName = null;
+ this.TableName = null;
+ this.Name = null;
+ this.IsNullabe = false;
+
+ this.DefaultValue = null;
+ this.IsAutoIncrement = false;
+ this.IsUniqueKey = false;
+ this.IsPrimaryKey = false;
+ this.IsForeignKey = false;
+ this.IsReverseIndex = false;
+ this.IsReverseUnique = false;
+ this.IsShared = false;
+}
+
diff --git a/src/resultset/Result2Array.js b/src/resultset/Result2Array.js
new file mode 100644
index 0000000..17b52c0
--- /dev/null
+++ b/src/resultset/Result2Array.js
@@ -0,0 +1,96 @@
+/**
+ * Returns an array with the query results
+ * @param data
+ * @return {*}
+ * @constructor
+ */
+exports.GetResultsArray = function GetResultsArray(data) {
+ var fullArray = JSON.parse(data);
+ var arr = new Array();
+
+ var rowsCount = fullArray['ColumnValues'].length;
+ if (rowsCount <= 0) {
+ return null;
+ } else {
+ for (var i = 0; i < rowsCount; i++) {
+ arr[i] = fullArray['ColumnValues'][i];
+ }
+ }
+
+ return arr;
+};
+
+/**
+ * Returns an array with the query results column names
+ * @param data
+ * @return {*}
+ * @constructor
+ */
+exports.GetResultsColumnNamesArray = function GetResultsColumnNamesArray(data) {
+ var fullArray = '';
+
+ try {
+ fullArray = JSON.parse(data);
+
+ var rowsCount = fullArray['ColumnNames'].length;
+ if (rowsCount <= 0) {
+ return null;
+ } else {
+ return fullArray['ColumnNames'];
+ }
+ }
+ catch (ex) {
+ return 'error';
+ }
+};
+
+/**
+ * Returns an array with the query results columns data types
+ * @param data
+ * @return {*}
+ * @constructor
+ */
+exports.GetResultsColumnsTypeArray = function GetResultsColumnsTypeArray(data) {
+ var fullArray = '';
+
+ try {
+ fullArray = JSON.parse(data);
+
+ var rowsCount = fullArray['ColumnDataTypes'].length;
+ if (rowsCount <= 0) {
+ return null;
+ } else {
+ return fullArray['ColumnDataTypes'];
+ }
+ }
+ catch (ex) {
+ return 'error';
+ }
+};
+
+/**
+ * Returns the query results rows count
+ * Please note that this is the total query rows count and not the current "batch of data" rows count
+ * @param data
+ * @return {*}
+ * @constructor
+ */
+exports.GetResultsCount = function GetResultsCount(data) {
+ var fullArray = '';
+
+ try {
+ fullArray = JSON.parse(data);
+
+ var rowsCount = fullArray['RowsCount'];
+ if (rowsCount <= 0) {
+ return null;
+ } else {
+ return fullArray['RowsCount'];
+ }
+ }
+ catch (ex) {
+ return -1;
+ }
+};
+
+
diff --git a/src/resultset/ResultInfo.js b/src/resultset/ResultInfo.js
new file mode 100644
index 0000000..2c76e7c
--- /dev/null
+++ b/src/resultset/ResultInfo.js
@@ -0,0 +1,14 @@
+module.exports = ResultInfo;
+
+/**
+ * Result info
+ * @constructor
+ */
+function ResultInfo() {
+ this.StmtType = null;
+ this.ResultCount = 0;
+ this.Oid = null;
+ this.CacheTimeSec = 0;
+ this.CacheTimeUsec = 0;
+}
+
diff --git a/src/unit_tests/test_ActionQueue.js b/src/unit_tests/test_ActionQueue.js
new file mode 100644
index 0000000..031625e
--- /dev/null
+++ b/src/unit_tests/test_ActionQueue.js
@@ -0,0 +1,50 @@
+var assert = require('assert'),
+ ActionQueue = require('../utils/ActionQueue');
+
+var count = 0;
+var startTime = (new Date()).getTime();
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+ActionQueue.enqueue(
+ [
+ function (callback) {
+ callback(null, '1');
+ },
+ function (data, callback) {
+ setTimeout(callback(null, data + ',2'), 5000);
+ },
+ function (data, callback) {
+ setTimeout(callback(null, data + ',3'), 1000);
+ }
+ ,
+ function (data, callback) {
+ callback(null, data + ',4');
+ }
+ ],
+ function (err, results) {
+ assert.equal(results, '1,2,3,4');
+ console.log('enqueue unit test ended OK.');
+ }
+);
+
+ActionQueue.while(
+ function () {
+ return count < 5;
+ },
+ function (callback) {
+ count++;
+ setTimeout(callback, 1000);
+ },
+ function (err) {
+ if (err) {
+ throw err.toString();
+ } else {
+ var endTime = (new Date()).getTime();
+ // 5 seconds have passed
+ assert(endTime - startTime > 5 * 1000);
+ console.log('while unit test ended OK.');
+ }
+ }
+);
+
diff --git a/src/unit_tests/test_BatchExecuteNoQueryPacket.js b/src/unit_tests/test_BatchExecuteNoQueryPacket.js
new file mode 100644
index 0000000..52a55ab
--- /dev/null
+++ b/src/unit_tests/test_BatchExecuteNoQueryPacket.js
@@ -0,0 +1,45 @@
+var PacketReader = require('../packets/PacketReader'),
+ PacketWriter = require('../packets/PacketWriter'),
+ BatchExecuteNoQueryPacket = require('../packets/BatchExecuteNoQueryPacket'),
+ CAS = require('../constants/CASConstants'),
+ assert = require('assert');
+
+function testBatchExecuteNoQueryPacket_01() {
+ var packetReader = new PacketReader();
+ var packetWriter = new PacketWriter();
+ var options = {SQLs : ['create table t1(id int)', 'drop table t1'], casInfo : [0, 255, 255, 255], autoCommitMode : 1};
+ var batchExecuteNoQueryPacket = new BatchExecuteNoQueryPacket(options);
+
+ batchExecuteNoQueryPacket.write(packetWriter);
+ assert.equal(packetWriter._toBuffer()[3], 52); //total length
+
+ assert.equal(packetWriter._toBuffer()[4], 0); //casInfo
+ assert.equal(packetWriter._toBuffer()[5], 255); //casInfo
+ assert.equal(packetWriter._toBuffer()[6], 255); //casInfo
+ assert.equal(packetWriter._toBuffer()[7], 255); //casInfo
+
+ assert.equal(packetWriter._toBuffer()[8], CAS.CASFunctionCode.CAS_FC_EXECUTE_BATCH);
+ assert.equal(packetWriter._toBuffer()[13], 1);
+ assert.equal(packetWriter._toBuffer().slice(18, 41).toString(), 'create table t1(id int)');
+ assert.equal(packetWriter._toBuffer().slice(41 + 1 + 4, 59).toString(), 'drop table t1');
+
+ packetReader.write(new Buffer([0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0]));
+ batchExecuteNoQueryPacket.parse(packetReader);
+
+ assert.equal(batchExecuteNoQueryPacket.casInfo[0], 0); //casInfo
+ assert.equal(batchExecuteNoQueryPacket.casInfo[1], 255); //casInfo
+ assert.equal(batchExecuteNoQueryPacket.casInfo[2], 255); //casInfo
+ assert.equal(batchExecuteNoQueryPacket.casInfo[3], 255); //casInfo
+
+ assert.equal(batchExecuteNoQueryPacket.responseCode, 0);
+
+ assert.equal(batchExecuteNoQueryPacket.errorCode, 0);
+ assert.equal(batchExecuteNoQueryPacket.errorMsg, '');
+}
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+testBatchExecuteNoQueryPacket_01();
+
+console.log('Unit test ended OK.');
+
diff --git a/src/unit_tests/test_Cache.js b/src/unit_tests/test_Cache.js
new file mode 100644
index 0000000..a067e14
--- /dev/null
+++ b/src/unit_tests/test_Cache.js
@@ -0,0 +1,36 @@
+var assert = require('assert'),
+ Cache = require('../utils/Cache');
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+var cache = new Cache();
+
+cache.getSet(1, '1');
+cache.getSet(2, '22');
+cache.getSet(3, '333');
+
+assert.equal(cache.contains(1), true);
+assert.equal(cache.contains(2), true);
+assert.equal(cache.contains(3), true);
+assert.equal(cache.get(1), '1');
+assert.equal(cache.get(2), '22');
+assert.equal(cache.get(3), '333');
+assert.equal(cache.contains(9), false);
+
+cache.clear();
+
+assert.equal(cache.contains(1), false);
+
+var cache2 = new Cache(3);
+
+cache2.getSet(1, '1');
+
+setTimeout(function () {
+ assert.equal(cache2.contains(1), false);
+ console.log('Unit test ended OK.');
+ },
+ 4000
+);
+
+
+
diff --git a/src/unit_tests/test_ClientInfoExchangePacket.js b/src/unit_tests/test_ClientInfoExchangePacket.js
new file mode 100644
index 0000000..e5f0d8b
--- /dev/null
+++ b/src/unit_tests/test_ClientInfoExchangePacket.js
@@ -0,0 +1,25 @@
+var PacketReader = require('../packets/PacketReader'),
+ PacketWriter = require('../packets/PacketWriter'),
+ ClientInfoExchange = require('../packets/ClientInfoExchangePacket'),
+ assert = require('assert');
+
+function testClientInfoExchangePacket_01() {
+ var packetReader = new PacketReader();
+ var packetWriter = new PacketWriter();
+ var clientInfoExchange = new ClientInfoExchange();
+
+ clientInfoExchange.write(packetWriter);
+ assert.equal(packetWriter._toBuffer().slice(0, 5), 'CUBRK');
+ assert.equal(packetWriter._toBuffer()[5], 3);
+
+ packetReader.write(new Buffer([0, 0, 1, 2])); //=258
+ clientInfoExchange.parse(packetReader);
+ assert.equal(clientInfoExchange.newConnectionPort, 258);
+}
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+testClientInfoExchangePacket_01();
+
+console.log('Unit test ended OK.');
+
diff --git a/src/unit_tests/test_CloseDatabasePacket.js b/src/unit_tests/test_CloseDatabasePacket.js
new file mode 100644
index 0000000..d59a797
--- /dev/null
+++ b/src/unit_tests/test_CloseDatabasePacket.js
@@ -0,0 +1,45 @@
+var PacketReader = require('../packets/PacketReader'),
+ PacketWriter = require('../packets/PacketWriter'),
+ CloseDatabasePacket = require('../packets/CloseDatabasePacket'),
+ CAS = require('../constants/CASConstants'),
+ assert = require('assert');
+
+function testCloseConnectionPacket_01() {
+ var packetReader = new PacketReader();
+ var packetWriter = new PacketWriter();
+ var options = {casInfo : [0, 255, 255, 255]};
+ var closeDatabasePacket = new CloseDatabasePacket(options);
+
+ closeDatabasePacket.write(packetWriter);
+ assert.equal(packetWriter._toBuffer()[3], 1); //total length
+
+ assert.equal(packetWriter._toBuffer()[4], 0); //casInfo
+ assert.equal(packetWriter._toBuffer()[5], 255); //casInfo
+ assert.equal(packetWriter._toBuffer()[6], 255); //casInfo
+ assert.equal(packetWriter._toBuffer()[7], 255); //casInfo
+
+ assert.equal(packetWriter._toBuffer()[8], CAS.CASFunctionCode.CAS_FC_CON_CLOSE);
+
+ packetReader.write(new Buffer([0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0]));
+
+ assert.equal(packetReader._packetLength(), 12);
+
+ closeDatabasePacket.parse(packetReader);
+
+ assert.equal(closeDatabasePacket.casInfo[0], 0); //casInfo
+ assert.equal(closeDatabasePacket.casInfo[1], 255); //casInfo
+ assert.equal(closeDatabasePacket.casInfo[2], 255); //casInfo
+ assert.equal(closeDatabasePacket.casInfo[3], 255); //casInfo
+
+ assert.equal(closeDatabasePacket.responseCode, 0);
+
+ assert.equal(closeDatabasePacket.errorCode, 0);
+ assert.equal(closeDatabasePacket.errorMsg, '');
+}
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+testCloseConnectionPacket_01();
+
+console.log('Unit test ended OK.');
+
diff --git a/src/unit_tests/test_ExecuteQueryPacket.js b/src/unit_tests/test_ExecuteQueryPacket.js
new file mode 100644
index 0000000..0a7aac3
--- /dev/null
+++ b/src/unit_tests/test_ExecuteQueryPacket.js
@@ -0,0 +1,52 @@
+var PacketReader = require('../packets/PacketReader'),
+ PacketWriter = require('../packets/PacketWriter'),
+ ExecuteQueryPacket = require('../packets/ExecuteQueryPacket'),
+ CAS = require('../constants/CASConstants'),
+ assert = require('assert');
+
+function testExecuteQueryPacket_01() {
+ var packetReader = new PacketReader();
+ var packetWriter = new PacketWriter();
+ var options = {sql : 'select * from code', casInfo : [0, 255, 255, 255], autoCommitMode : 1};
+ var executeQueryPacket = new ExecuteQueryPacket(options);
+
+ executeQueryPacket.write(packetWriter);
+ assert.equal(packetWriter._toBuffer()[3], 87); //total length
+
+ assert.equal(packetWriter._toBuffer()[4], 0); //casInfo
+ assert.equal(packetWriter._toBuffer()[5], 255); //casInfo
+ assert.equal(packetWriter._toBuffer()[6], 255); //casInfo
+ assert.equal(packetWriter._toBuffer()[7], 255); //casInfo
+
+ assert.equal(packetWriter._toBuffer()[8], CAS.CASFunctionCode.CAS_FC_PREPARE_AND_EXECUTE);
+ assert.equal(packetWriter._toBuffer()[16], 3);
+ assert.equal(packetWriter._toBuffer().slice(21, 39).toString(), 'select * from code');
+ assert.equal(packetWriter._toBuffer()[44], 0);
+ assert.equal(packetWriter._toBuffer()[49], 1);
+ assert.equal(packetWriter._toBuffer()[54], CAS.CCIExecutionOption.CCI_EXEC_QUERY_ALL);
+ assert.equal(packetWriter._toBuffer()[62], 0);
+ assert.equal(packetWriter._toBuffer()[70], 0);
+ assert.equal(packetWriter._toBuffer()[82], 0);
+ assert.equal(packetWriter._toBuffer()[86], 0);
+ assert.equal(packetWriter._toBuffer()[94], 0);
+
+ packetReader.write(new Buffer([0, 0, 1, 57, 0, 255, 255, 255, 0, 0, 0, 4, 255, 255, 255, 255, 21, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 115, 95, 110, 97, 109, 101, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 5, 99, 111, 100, 101, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 102,
+ 95, 110, 97, 109, 101, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 99, 111, 100, 101, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 1, 21, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 88, 0, 0, 0, 0, 6, 77, 105, 120, 101, 100, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 87, 0, 0,
+ 0, 0, 6, 87, 111, 109, 97, 110, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 77, 0, 0, 0, 0, 4, 77, 97, 110, 0, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 66, 0, 0, 0, 0, 7, 66, 114, 111, 110, 122, 101, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 83, 0, 0, 0, 0, 7, 83, 105, 108, 118, 101, 114, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 71, 0, 0, 0, 0, 5,
+ 71, 111, 108, 100, 0]));
+
+ var resultSet = executeQueryPacket.parse(packetReader);
+ assert.equal(resultSet, '{"ColumnNames":["s_name","f_name"],"ColumnDataTypes":["Char","String"],"RowsCount":6,"ColumnValues":[["X","Mixed"],["W","Woman"],["M","Man"],["B","Bronze"],["S","Silver"],["G","Gold"]]}');
+}
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+testExecuteQueryPacket_01();
+
+console.log('Unit test ended OK.');
+
diff --git a/src/unit_tests/test_GetEngineVersionPacket.js b/src/unit_tests/test_GetEngineVersionPacket.js
new file mode 100644
index 0000000..7a6d978
--- /dev/null
+++ b/src/unit_tests/test_GetEngineVersionPacket.js
@@ -0,0 +1,50 @@
+var PacketReader = require('../packets/PacketReader'),
+ PacketWriter = require('../packets/PacketWriter'),
+ GetEngineVersionPacket = require('../packets/GetEngineVersionPacket'),
+ CAS = require('../constants/CASConstants'),
+ assert = require('assert');
+
+function testGetEngineVersionPacket_01() {
+ var packetReader = new PacketReader();
+ var packetWriter = new PacketWriter();
+ var options = {casInfo : [0, 255, 255, 255]};
+ var getEngineVersionPacket = new GetEngineVersionPacket(options);
+
+ getEngineVersionPacket.write(packetWriter);
+ assert.equal(packetWriter._toBuffer()[3], 6); //total length
+
+ assert.equal(packetWriter._toBuffer()[4], 0); //casInfo
+ assert.equal(packetWriter._toBuffer()[5], 255); //casInfo
+ assert.equal(packetWriter._toBuffer()[6], 255); //casInfo
+ assert.equal(packetWriter._toBuffer()[7], 255); //casInfo
+
+ assert.equal(packetWriter._toBuffer()[8], CAS.CASFunctionCode.CAS_FC_GET_DB_VERSION);
+ assert.equal(packetWriter._toBuffer()[12], 1);
+ assert.equal(packetWriter._toBuffer()[13], 1);
+
+ packetReader.write(new Buffer([0, 0, 0, 15,
+ 0, 255, 255, 255,
+ 0, 0, 0, 0]));
+ packetReader._append(new Buffer('8.4.1.0056'));
+ packetReader._append(new Buffer([0]));
+ getEngineVersionPacket.parse(packetReader);
+
+ assert.equal(getEngineVersionPacket.casInfo[0], 0); //casInfo
+ assert.equal(getEngineVersionPacket.casInfo[1], 255); //casInfo
+ assert.equal(getEngineVersionPacket.casInfo[2], 255); //casInfo
+ assert.equal(getEngineVersionPacket.casInfo[3], 255); //casInfo
+
+ assert.equal(getEngineVersionPacket.responseCode, 0);
+
+ assert.equal(getEngineVersionPacket.errorCode, 0);
+ assert.equal(getEngineVersionPacket.errorMsg, '');
+
+ assert.equal(getEngineVersionPacket.engineVersion, '8.4.1.0056');
+}
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+testGetEngineVersionPacket_01();
+
+console.log('Unit test ended OK.');
+
diff --git a/src/unit_tests/test_Helpers.js b/src/unit_tests/test_Helpers.js
new file mode 100644
index 0000000..ab8bbc6
--- /dev/null
+++ b/src/unit_tests/test_Helpers.js
@@ -0,0 +1,29 @@
+var assert = require('assert'),
+ Helpers = require('../utils/Helpers');
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+var buffer = new Buffer(5);
+buffer.write('12345');
+var value1 = ['6', '7', '8'];
+var comb1 = Helpers.combineData(buffer, value1);
+
+assert.equal(comb1.toString(), '12345678');
+
+var value2 = new Buffer('678');
+var comb2 = Helpers.combineData(buffer, value2);
+
+assert.equal(comb2.toString(), '12345678');
+
+var value3 = new Buffer(3);
+value3[0] = '6'.charCodeAt(0);
+value3[1] = '7'.charCodeAt(0);
+value3[2] = '8'.charCodeAt(0);
+
+var comb3 = Helpers.combineData(buffer, value3);
+
+assert.equal(comb3.toString(), '12345678');
+
+console.log('Unit test ended OK.');
+
+
diff --git a/src/unit_tests/test_OpenDatabasePacket.js b/src/unit_tests/test_OpenDatabasePacket.js
new file mode 100644
index 0000000..6a27b3c
--- /dev/null
+++ b/src/unit_tests/test_OpenDatabasePacket.js
@@ -0,0 +1,44 @@
+var PacketReader = require('../packets/PacketReader'),
+ PacketWriter = require('../packets/PacketWriter'),
+ OpenDatabasePacket = require('../packets/OpenDatabasePacket'),
+ CAS = require('../constants/CASConstants'),
+ assert = require('assert');
+
+function testLoginToDatabasePacket_01() {
+ var packetReader = new PacketReader();
+ var packetWriter = new PacketWriter();
+ var options = {database : 'demodb', user : 'public', password : ''};
+ var openDatabasePacket = new OpenDatabasePacket(options);
+
+ openDatabasePacket.write(packetWriter);
+ assert.equal(packetWriter._toBuffer().slice(0, 6).toString(), options.database);
+ assert.equal(packetWriter._toBuffer().slice(32, 38).toString(), options.user);
+ assert.equal(packetWriter._toBuffer().slice(64, 65)[0], 0);
+
+ packetReader.write(new Buffer([0, 0, 0, 15,
+ 0, 255, 255, 255,
+ 0, 0, 0, 0,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 0, 0, 3]));
+ openDatabasePacket.parse(packetReader);
+
+ assert.equal(openDatabasePacket.casInfo[0], 0); //casInfo
+ assert.equal(openDatabasePacket.casInfo[1], 255); //casInfo
+ assert.equal(openDatabasePacket.casInfo[2], 255); //casInfo
+ assert.equal(openDatabasePacket.casInfo[3], 255); //casInfo
+
+ assert.equal(openDatabasePacket.responseCode, 0);
+
+ assert.equal(openDatabasePacket.errorCode, 0);
+ assert.equal(openDatabasePacket.errorMsg, '');
+
+ assert.equal(openDatabasePacket.brokerInfo[0], 5);
+ assert.equal(openDatabasePacket.sessionId, 3);
+}
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+testLoginToDatabasePacket_01();
+
+console.log('Unit test ended OK.');
+
diff --git a/src/unit_tests/test_PacketWriter_PacketReader.js b/src/unit_tests/test_PacketWriter_PacketReader.js
new file mode 100644
index 0000000..3ed2557
--- /dev/null
+++ b/src/unit_tests/test_PacketWriter_PacketReader.js
@@ -0,0 +1,251 @@
+var PacketReader = require('../packets/PacketReader'),
+ PacketWriter = require('../packets/PacketWriter'),
+ assert = require('assert');
+
+var bValue = 0xEF; //=239
+var cValue = 'x';
+var shortValue = 0x70;
+var iValue = 0x7ABC;
+var shortValueSigned = 0x8001;
+var iValueSigned = 0x80000001;
+var sValue = '0987654321';
+var dValue = new Date(2012, 1, 2, 0, 0, 0, 0);
+
+function createPacketReader(bytes) {
+ var buffer = new Buffer(bytes);
+ var parser = new PacketReader();
+
+ parser._append(buffer);
+
+ return parser;
+}
+
+function testByte(value) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeByte(value);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseByte();
+ assert.equal(newValue, value);
+}
+
+function testChar(value) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeChar(value);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseChar();
+ assert.equal(newValue, value);
+}
+
+function testShort(value) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeShort(value);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseShort();
+ assert.equal(newValue, value);
+}
+
+function testShortSigned(value, expectedValue) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeShort(value);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseShort();
+ assert.equal(newValue, expectedValue);
+}
+
+function testInt(value) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeInt(value);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseInt();
+ assert.equal(newValue, value);
+}
+
+function testIntSigned(value, expectedValue) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeInt(value);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseInt();
+ assert.equal(newValue, expectedValue);
+}
+
+function testDate(year, month, day) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeDate(year, month, day);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseDate();
+ assert.equal(newValue.getFullYear(), year);
+ assert.equal(newValue.getMonth(), month);
+ assert.equal(newValue.getDate(), day);
+}
+
+function testTime(hour, min, sec) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeTime(hour, min, sec);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseTime();
+ assert.equal(newValue.getHours(), hour);
+ assert.equal(newValue.getMinutes(), min);
+ assert.equal(newValue.getSeconds(), sec);
+}
+
+function testDateTime(year, month, day, hour, min, sec, msec) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeDateTime(year, month, day, hour, min, sec, msec);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseDateTime();
+ assert.equal(newValue.getFullYear(), year);
+ assert.equal(newValue.getMonth(), month);
+ assert.equal(newValue.getDate(), day);
+ assert.equal(newValue.getHours(), hour);
+ assert.equal(newValue.getMinutes(), min);
+ assert.equal(newValue.getSeconds(), sec);
+ assert.equal(newValue.getMilliseconds(), msec);
+}
+
+function testTimestamp(year, month, day, hour, min, sec) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeTimestamp(year, month, day, hour, min, sec);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseTimeStamp();
+ assert.equal(newValue.getFullYear(), year);
+ assert.equal(newValue.getMonth(), month);
+ assert.equal(newValue.getDate(), day);
+ assert.equal(newValue.getHours(), hour);
+ assert.equal(newValue.getMinutes(), min);
+ assert.equal(newValue.getSeconds(), sec);
+}
+
+function testString(value) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeNullTerminatedString(value);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var len = packetReader._parseInt();
+ var newValue = packetReader._parseNullTerminatedString(len);
+ assert.equal(newValue, value);
+}
+
+function testFixedLengthString(value) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeFixedLengthString(value, 'x', 15);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseString(15);
+ assert.equal(newValue, value + 'xxxxx');
+}
+
+function testFiller() {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeFiller(5, 'x');
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue = packetReader._parseString(5);
+ assert.equal(newValue, 'xxxxx');
+
+ packetWriter = new PacketWriter();
+ packetWriter._writeFiller(5, 120);
+ packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ newValue = packetReader._parseString(5);
+ assert.equal(newValue, 'xxxxx');
+}
+
+function testAllTypes(value1, value2, value3) {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeByte(value1);
+ packetWriter._writeInt(value2);
+ packetWriter._writeNullTerminatedString(value3);
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+
+ var newValue1 = packetReader._parseByte();
+ assert.equal(newValue1, value1);
+
+ var newValue2 = packetReader._parseInt();
+ assert.equal(newValue2, value2);
+
+ var len = packetReader._parseInt();
+ var newValue3 = packetReader._parseNullTerminatedString(len);
+ assert.equal(newValue3, value3);
+}
+
+function testPacketReaderBytes() {
+ var packetReader = createPacketReader([1, 2]);
+
+ var newValue = packetReader._parseBytes(2);
+ assert.equal(newValue[0], 1);
+ assert.equal(newValue[1], 2);
+}
+
+function testPacketReaderBuffer() {
+ var packetWriter = new PacketWriter();
+ packetWriter._writeBuffer(new Buffer([1, 2]));
+
+ var packetReader = new PacketReader();
+ packetReader.write(packetWriter._toBuffer());
+ var newValue = packetReader._parseBuffer(2);
+ assert.equal(newValue[0], 1);
+ assert.equal(newValue[1], 2);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+//Test integer-types
+testByte(bValue);
+testShort(shortValue);
+testInt(iValue);
+
+//Test signed integer-types
+testShortSigned(shortValueSigned, -32767);
+//testShortSigned(shortValueSigned, -1);
+testIntSigned(iValueSigned, -2147483647);
+//testIntSigned(iValueSigned, -1);
+
+//Test strings
+testChar(cValue);
+testString(sValue);
+testFixedLengthString(sValue);
+
+//Test dates
+testDate(dValue.getFullYear(), dValue.getMonth(), dValue.getDate());
+testTime(dValue.getHours(), dValue.getMinutes(), dValue.getSeconds());
+testDateTime(dValue.getFullYear(), dValue.getMonth(), dValue.getDate(),
+ dValue.getHours(), dValue.getMinutes(), dValue.getSeconds(), dValue.getMilliseconds());
+testTimestamp(dValue.getFullYear(), dValue.getMonth(), dValue.getDate(),
+ dValue.getHours(), dValue.getMinutes(), dValue.getSeconds());
+
+//Other tests
+testAllTypes(bValue, iValue, sValue);
+testPacketReaderBytes();
+testPacketReaderBuffer();
+testFiller();
+
+console.log('Unit test ended OK.');
+
+
diff --git a/src/unit_tests/test_Utils.js b/src/unit_tests/test_Utils.js
new file mode 100644
index 0000000..6eda3d9
--- /dev/null
+++ b/src/unit_tests/test_Utils.js
@@ -0,0 +1,19 @@
+var assert = require('assert'),
+ GetResultsArray = require('./../resultset/Result2Array').GetResultsArray,
+ GetResultsColumnNamesArray = require('./../resultset/Result2Array').GetResultsColumnNamesArray,
+ GetResultsColumnTypesArray = require('./../resultset/Result2Array').GetResultsColumnsTypeArray,
+ GetResultsCount = require('./../resultset/Result2Array').GetResultsCount;
+
+var json_str = '{"ColumnNames":["s_name","f_name"],' +
+ '"ColumnDataTypes":["char","string"],' +
+ '"RowsCount":99,' +
+ '"ColumnValues":[["X","Mixed"],["W","Woman"],["M","Man"]]}';
+
+console.log('Unit test ' + module.filename.toString() + ' started...');
+
+assert.equal(GetResultsArray(json_str).toString(), 'X,Mixed,W,Woman,M,Man');
+assert.equal(GetResultsColumnNamesArray(json_str).toString(), 's_name,f_name');
+assert.equal(GetResultsColumnTypesArray(json_str).toString(), 'char,string');
+assert.equal(GetResultsCount(json_str), 99);
+
+console.log('Unit test ended OK.');
diff --git a/src/utils/ActionQueue.js b/src/utils/ActionQueue.js
new file mode 100644
index 0000000..b03dc13
--- /dev/null
+++ b/src/utils/ActionQueue.js
@@ -0,0 +1,103 @@
+/*
+ Based on code originating from the 'async' module - author license included here below:
+
+ Copyright (c) 2010 Caolan McMahon
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+
+(function () {
+ var actionQueue = {};
+ var self = this;
+
+ if (typeof module != 'undefined' && module.exports) {
+ module.exports = actionQueue;
+ } else {
+ self.actionQueue = actionQueue;
+ }
+
+ // nextTick implementation with browser-compatible fallback
+ if (typeof process === 'undefined' || !(process.nextTick)) {
+ actionQueue.nextTick = function (fn) {
+ setTimeout(fn, 0);
+ };
+ } else {
+ actionQueue.nextTick = process.nextTick;
+ }
+
+ actionQueue.enqueue = function (tasks, callback) {
+ callback = callback || function () {
+ };
+ if (!tasks.length) {
+ return callback();
+ }
+ var wrapIterator = function (iterator) {
+ return function (err) {
+ if (err) {
+ callback(err);
+ callback = function () {
+ };
+ } else {
+ var args = Array.prototype.slice.call(arguments, 1);
+ var next = iterator.next();
+ if (next) {
+ args.push(wrapIterator(next));
+ } else {
+ args.push(callback);
+ }
+ actionQueue.nextTick(function () {
+ iterator.apply(null, args);
+ });
+ }
+ };
+ };
+ wrapIterator(actionQueue._iterator(tasks))();
+ };
+
+ actionQueue._iterator = function (tasks) {
+ var makeCallback = function (index) {
+ var fn = function () {
+ if (tasks.length) {
+ tasks[index].apply(null, arguments);
+ }
+ return fn.next();
+ };
+ fn.next = function () {
+ return (index < tasks.length - 1) ? makeCallback(index + 1) : null;
+ };
+ return fn;
+ };
+ return makeCallback(0);
+ };
+
+ actionQueue.while = function (test, iterator, callback) {
+ if (test()) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err);
+ }
+ actionQueue.while(test, iterator, callback);
+ });
+ } else {
+ callback();
+ }
+ };
+
+}());
+
diff --git a/src/utils/Cache.js b/src/utils/Cache.js
new file mode 100644
index 0000000..0fece97
--- /dev/null
+++ b/src/utils/Cache.js
@@ -0,0 +1,60 @@
+var Helpers = require('./Helpers');
+
+/**
+ * Code adapted from MicroCache library:
+ * https://github.com/jeromeetienne/microcache.js
+ * License: https://github.com/jeromeetienne/MicroCache.js/blob/master/MIT-LICENSE.txt
+ */
+
+var Cache = function (expireAfterSeconds) {
+ var _values = {};
+ var createdTime = (new Date()).getTime();
+
+ var _expire = function () {
+ if (typeof expireAfterSeconds != 'undefined' && expireAfterSeconds > 0) {
+ if ((new Date()).getTime() - createdTime >= expireAfterSeconds * 1000) {
+ _values = {};
+ createdTime = (new Date()).getTime();
+ }
+ }
+ };
+
+ return {
+ get : function (key) {
+ _expire();
+ return _values[key];
+ },
+ _set : function (key, value) {
+ _expire();
+ _values[key] = value;
+ },
+ contains : function (key) {
+ _expire();
+ return key in _values;
+ },
+ /**
+ * Get a value from cache; if the value is not found, then add it to the cache
+ */
+ getSet : function (key, value) {
+ _expire();
+ if (!this.contains(key)) {
+ this._set(key, value)
+ } else {
+ Helpers.logInfo('Value found in cache.');
+ }
+ return this.get(key);
+ },
+ /**
+ * Clear all values in cache
+ */
+ clear : function () {
+ _values = {};
+ }
+ }
+};
+
+if (typeof module != 'undefined' && ('exports' in module)) {
+ module.exports = Cache;
+}
+
+
diff --git a/src/utils/DBUtils.js b/src/utils/DBUtils.js
new file mode 100644
index 0000000..2fa0171
--- /dev/null
+++ b/src/utils/DBUtils.js
@@ -0,0 +1,76 @@
+var CUBRIDConnection = require('../CUBRIDConnection'),
+ ActionQueue = require('../utils/ActionQueue'),
+ Helpers = require('../utils/Helpers'),
+ Result2Array = require('../resultset/Result2Array');
+
+exports.getSingleValue = function (sql, brokerServer, brokerPort, user, password, database) {
+ var client = new CUBRIDConnection(brokerServer, brokerPort, user, password, database);
+ var ret = null;
+
+ client.connect(function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ Helpers.logInfo('Connected.');
+ Helpers.logInfo('Querying: ' + sql);
+ client.query(sql, function (err, result, queryHandle) {
+ if (err) {
+ throw err.message;
+ } else {
+ ret = Result2Array.GetResultsArray(result)[0];
+ client.closeRequest(queryHandle, function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ Helpers.logInfo('Query closed.');
+ client.close(function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Result: ' + ret);
+ return ret;
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ });
+};
+
+exports.getSingleValue2 = function (sql, brokerServer, brokerPort, user, password, database) {
+ var client = new CUBRIDConnection(brokerServer, brokerPort, user, password, database);
+ var ret = null;
+
+ ActionQueue.enqueue(
+ [
+ function (cb) {
+ client.connect(cb);
+ },
+ function (cb) {
+ client.query(sql, cb);
+ },
+ function (result, queryHandle, cb) {
+ ret = Result2Array.GetResultsArray(result)[0][0];
+ client.closeRequest(queryHandle, cb);
+ },
+ function (cb) {
+ client.close(cb);
+ }
+ ],
+ function (err) {
+ if (err == null) {
+ Helpers.logInfo('Value: ' + ret);
+ setTimeout(function () {
+ return ret;
+ }, 0);
+ //return ret;
+ } else {
+ throw err.message;
+ }
+ }
+ );
+};
+
diff --git a/src/utils/Helpers.js b/src/utils/Helpers.js
new file mode 100644
index 0000000..2b5e83a
--- /dev/null
+++ b/src/utils/Helpers.js
@@ -0,0 +1,111 @@
+var DEBUG_ENABLED = require('../Config').DEBUG_ENABLED,
+ DATA_TYPES = require('../constants/DataTypes'),
+ ErrorMessages = require('../constants/ErrorMessages'),
+ CAS = require('../constants/CASConstants');
+
+/**
+ * String extension
+ */
+if (typeof String.prototype.startsWith != 'function') {
+ // see below for better implementation!
+ String.prototype.startsWith = function (str) {
+ return this.indexOf(str) == 0;
+ };
+}
+
+exports.combineData = function (buffer, value) {
+ var newBuffer = new Buffer(buffer.length + value.length);
+
+ buffer.copy(newBuffer, 0);
+ if (Array.isArray(value)) {
+ for (var i = 0; i < value.length; i++) {
+ if (typeof value[i] == 'string') {
+ newBuffer[buffer.length + i] = value[i].charCodeAt(0);
+ } else {
+ newBuffer[buffer.length + i] = value[i];
+ }
+ }
+ } else {
+ if (typeof value == 'Buffer') {
+ value.copy(newBuffer, buffer.length);
+ } else {
+ new Buffer(value).copy(newBuffer, buffer.length);
+ }
+ }
+
+ return newBuffer;
+};
+
+/**
+ * Overrides the console output
+ * Logs data to the standard console output
+ * @param data
+ */
+exports.logInfo = function logInfo(data) {
+ if (DEBUG_ENABLED) {
+ if (typeof window != 'undefined') {
+ if (!("console" in window) || !("firebug" in console)) {
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+ window.console = {};
+ for (var i = 0, len = names.length; i < len; ++i) {
+ window.console[names[i]] = function () {
+ };
+ }
+ }
+ }
+
+ console.warn(data);
+ }
+};
+
+/**
+ * Overrides the console output
+ * Logs data to the standard console output
+ * @param data
+ */
+exports.logError = function logError(data) {
+ if (DEBUG_ENABLED) {
+ if (typeof window != 'undefined') {
+ if (!("console" in window) || !("firebug" in console)) {
+ var names = ["log", "debug", "info", "warn", "logError", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+ window.console = {};
+ for (var i = 0, len = names.length; i < len; ++i) {
+ window.console[names[i]] = function () {
+ };
+ }
+ }
+ }
+
+ console.error(data);
+ }
+};
+
+/**
+ * Get expected response length from the server
+ * @param buffer
+ * @return {Number}
+ */
+exports.getExpectedResponseLength = function (buffer) {
+ var value = 0;
+
+ for (var i = 0; i < DATA_TYPES.INT_SIZEOF; i++) {
+ value += buffer[i] * Math.pow(256, DATA_TYPES.INT_SIZEOF - i - 1);
+ }
+
+ return value + DATA_TYPES.DATA_LENGTH_SIZEOF + DATA_TYPES.CAS_INFO_SIZE;
+};
+
+/**
+ * Try to resolve the error code to a CUBRID error message
+ * @param errorCode
+ * @return {*}
+ */
+exports.resolveErrorCode = function (errorCode) {
+ for (var iter = 0; iter < ErrorMessages.CASErrorMsgId.length; iter++) {
+ if (errorCode == ErrorMessages.CASErrorMsgId[iter][1]) {
+ return ErrorMessages.CASErrorMsgId[iter][0];
+ }
+ }
+};
+
+
diff --git a/test/test_BadConnect.js b/test/test_BadConnect.js
new file mode 100644
index 0000000..0794440
--- /dev/null
+++ b/test/test_BadConnect.js
@@ -0,0 +1,16 @@
+var assert = require('assert'),
+ CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers');
+
+var client = new CUBRIDConnection('localhost', 33000, 'public', 'xyz', 'demodb_xyz');
+
+client.connect(function (err) {
+ if (err) {
+ assert(err.message == '-677:Failed to connect to database server, \'demodb_xyz\', on the following host(s): localhost:localhost');
+ Helpers.logInfo('Test passed.');
+ } else {
+ throw 'We should not get here!';
+ }
+});
+
+
diff --git a/test/test_BadSQLSyntax.js b/test/test_BadSQLSyntax.js
new file mode 100644
index 0000000..e124349
--- /dev/null
+++ b/test/test_BadSQLSyntax.js
@@ -0,0 +1,31 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ Helpers.logError(err.message);
+ assert(err.message === '-493:Syntax: Unknown class "game_xyz". select * from game_xyz');
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ Helpers.logInfo('Querying: select * from game_xyz');
+ CUBRIDClient.query('select * from game_xyz', function (err) {
+ if (err) {
+ errorHandler(err);
+ CUBRIDClient.close();
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ } else {
+ throw 'We should never get here!';
+ }
+ });
+ }
+});
+
+
diff --git a/test/test_BasicBatchExecute.js b/test/test_BasicBatchExecute.js
new file mode 100644
index 0000000..714fac8
--- /dev/null
+++ b/test/test_BasicBatchExecute.js
@@ -0,0 +1,45 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ CUBRIDClient.batchExecuteNoQuery(['drop table if exists node_test', 'create table node_test(id int)'], function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.batchExecuteNoQuery(['insert into node_test values(1)'], function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.batchExecuteNoQuery(['drop table node_test'], function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/test/test_BasicBatchExecute_ConnectImplicit.js b/test/test_BasicBatchExecute_ConnectImplicit.js
new file mode 100644
index 0000000..e9f47be
--- /dev/null
+++ b/test/test_BasicBatchExecute_ConnectImplicit.js
@@ -0,0 +1,39 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+Helpers.logInfo('Connected.');
+CUBRIDClient.batchExecuteNoQuery(['drop table if exists node_test', 'create table node_test(id int)'], function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.batchExecuteNoQuery(['insert into node_test values(1)'], function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.batchExecuteNoQuery(['drop table node_test'], function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/test/test_BasicExtendedSelect.js b/test/test_BasicExtendedSelect.js
new file mode 100644
index 0000000..c6a1234
--- /dev/null
+++ b/test/test_BasicExtendedSelect.js
@@ -0,0 +1,81 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ CUBRIDClient.getEngineVersion(function (err, result) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('CUBRID engine version: ' + result);
+ Helpers.logInfo('Querying: select * from game');
+ CUBRIDClient.query('select * from game', function (err, result, queryHandle) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ assert(Result2Array.GetResultsCount(result) === 235);
+ Helpers.logInfo('Query result rows count: ' + Result2Array.GetResultsCount(result));
+ assert(Result2Array.GetResultsColumnNamesArray(result).toString() === 'host_year,event_code,athlete_code,stadium_code,nation_code,medal,game_date');
+ Helpers.logInfo('Query result column names: ' + Result2Array.GetResultsColumnNamesArray(result));
+ assert(Result2Array.GetResultsColumnsTypeArray(result).toString() === 'Int,Int,Int,Int,Char,Char,Date');
+ Helpers.logInfo('Query result column data types: ' + Result2Array.GetResultsColumnsTypeArray(result));
+ Helpers.logInfo('Query results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length == 235);
+ assert(arr[0].toString().startsWith('2004,20021,14345,30116,NGR,B,2004-09-27T') == true);
+ assert(arr[arr.length - 1].toString().startsWith('2004,20317,14457,30124,ITA,G,2004-09-25T') == true);
+ for (var j = 0; j < arr.length; j++) {
+ Helpers.logInfo(arr[j].toString());
+ }
+ CUBRIDClient.fetch(queryHandle, function (err, result) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ if (result) {
+ Helpers.logInfo('Fetch results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length == 241);
+ assert(arr[0].toString().startsWith('2004,20317,14375,30124,GRE,S,2004-09-25T') == true);
+ assert(arr[arr.length - 1].toString().startsWith('2004,20060,14340,30125,JPN,B,2004-09-24T') == true);
+ for (var k = 0; k < arr.length; k++) {
+ Helpers.logInfo(arr[k].toString());
+ }
+ } else {
+ Helpers.logInfo('There is no more data to fetch.');
+ }
+ CUBRIDClient.closeRequest(queryHandle, function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Query closed.');
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ });
+ }
+ });
+ }
+});
+
+
diff --git a/test/test_BasicExtendedSelect_Sequence.js b/test/test_BasicExtendedSelect_Sequence.js
new file mode 100644
index 0000000..ea8c37f
--- /dev/null
+++ b/test/test_BasicExtendedSelect_Sequence.js
@@ -0,0 +1,51 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ ActionQueue = require('../src/utils/ActionQueue'),
+ Helpers = require('../src/utils/Helpers'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+ActionQueue.enqueue(
+ [
+ function (cb) {
+ CUBRIDClient.connect(cb);
+ },
+ function (cb) {
+ CUBRIDClient.getEngineVersion(cb);
+ },
+ function (engineVersion, cb) {
+ Helpers.logInfo('Engine version is: ' + engineVersion);
+ CUBRIDClient.query('select * from code', cb);
+ },
+ function (result, queryHandle, cb) {
+ assert(Result2Array.GetResultsCount(result) === 6);
+ Helpers.logInfo('Query result rows count: ' + Result2Array.GetResultsCount(result));
+ Helpers.logInfo('Query results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length === 6);
+ assert(arr[0].toString() === 'X,Mixed');
+ assert(arr[1].toString() === 'W,Woman');
+ assert(arr[2].toString() === 'M,Man');
+ assert(arr[3].toString() === 'B,Bronze');
+ assert(arr[4].toString() === 'S,Silver');
+ assert(arr[5].toString() === 'G,Gold');
+ for (var k = 0; k < arr.length; k++) {
+ Helpers.logInfo(arr[k].toString());
+ }
+ CUBRIDClient.closeRequest(queryHandle, cb);
+ Helpers.logInfo('Query closed.');
+ },
+ function (cb) {
+ CUBRIDClient.close(cb);
+ Helpers.logInfo('Connection closed.');
+ }
+ ],
+ function (err) {
+ if (err == null) {
+ Helpers.logInfo('Test passed.');
+ } else {
+ throw err.message;
+ }
+ }
+);
diff --git a/test/test_BasicMultiFetch.js b/test/test_BasicMultiFetch.js
new file mode 100644
index 0000000..0e9f9a1
--- /dev/null
+++ b/test/test_BasicMultiFetch.js
@@ -0,0 +1,97 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ ActionQueue = require('../src/utils/ActionQueue'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+var fetchResult;
+
+CUBRIDClient.connect(function (err) {
+ var errHandler = function (err) {
+ Helpers.logInfo('Error - ' + err.message);
+ throw err.message;
+ };
+
+ if (err) {
+ errHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ CUBRIDClient.getEngineVersion(function (err, result) {
+ if (err) {
+ errHandler(err);
+ } else {
+ Helpers.logInfo('CUBRID engine version: ' + result);
+ CUBRIDClient.query('select * from game', function (err, result, queryHandle) {
+ if (err) {
+ errHandler(err);
+ } else {
+ assert(Result2Array.GetResultsCount(result) === 235);
+ Helpers.logInfo('Query result rows count: ' + Result2Array.GetResultsCount(result));
+ assert(Result2Array.GetResultsColumnNamesArray(result).toString() === 'host_year,event_code,athlete_code,stadium_code,nation_code,medal,game_date');
+ Helpers.logInfo('Query result column names: ' + Result2Array.GetResultsColumnNamesArray(result));
+ assert(Result2Array.GetResultsColumnsTypeArray(result).toString() === 'Int,Int,Int,Int,Char,Char,Date');
+ Helpers.logInfo('Query result column data types: ' + Result2Array.GetResultsColumnsTypeArray(result));
+ Helpers.logInfo('Query results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length == 235);
+ assert(arr[0].toString().startsWith('2004,20021,14345,30116,NGR,B,2004-09-27T') == true);
+ assert(arr[arr.length - 1].toString().startsWith('2004,20317,14457,30124,ITA,G,2004-09-25T') == true);
+ for (var j = 0; j < arr.length; j++) {
+ Helpers.logInfo(arr[j].toString());
+ }
+
+ ActionQueue.while(
+ function () {
+ return fetchResult !== null;
+ },
+ function (callback) {
+ CUBRIDClient.fetch(queryHandle, function (err, result) {
+ if (err) {
+ errHandler(err);
+ } else {
+ if (result !== null) {
+ Helpers.logInfo('Fetch results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length == 241 || arr.length == 224);
+ for (var k = 0; k < arr.length; k++) {
+ Helpers.logInfo(arr[k].toString());
+ }
+ } else {
+ Helpers.logInfo('There is no more data to fetch.');
+ }
+ fetchResult = result;
+ callback.call(err);
+ }
+ })
+ },
+ function (err) {
+ if (err) {
+ errHandler(err);
+ } else {
+ CUBRIDClient.closeRequest(queryHandle, function (err) {
+ if (err) {
+ errHandler(err);
+ } else {
+ Helpers.logInfo('Query closed.');
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+ }
+ )
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/test/test_BasicMultiFetch_Sequence.js b/test/test_BasicMultiFetch_Sequence.js
new file mode 100644
index 0000000..0cc2b24
--- /dev/null
+++ b/test/test_BasicMultiFetch_Sequence.js
@@ -0,0 +1,84 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ ActionQueue = require('../src/utils/ActionQueue'),
+ Helpers = require('../src/utils/Helpers'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+var returnedQueryHandle;
+var fetchResult;
+
+ActionQueue.enqueue(
+ [
+ function (cb) {
+ CUBRIDClient.connect(cb);
+ },
+ function (cb) {
+ CUBRIDClient.getEngineVersion(cb);
+ },
+ function (engineVersion, cb) {
+ Helpers.logInfo('EngineVersion is: ' + engineVersion);
+ CUBRIDClient.query('select * from game', cb);
+ },
+ function (result, queryHandle, cb) {
+ assert(Result2Array.GetResultsCount(result) === 235);
+ Helpers.logInfo('Query result rows count: ' + Result2Array.GetResultsCount(result));
+ assert(Result2Array.GetResultsColumnNamesArray(result).toString() === 'host_year,event_code,athlete_code,stadium_code,nation_code,medal,game_date');
+ Helpers.logInfo('Query result column names: ' + Result2Array.GetResultsColumnNamesArray(result));
+ assert(Result2Array.GetResultsColumnsTypeArray(result).toString() === 'Int,Int,Int,Int,Char,Char,Date');
+ Helpers.logInfo('Query result column data types: ' + Result2Array.GetResultsColumnsTypeArray(result));
+ Helpers.logInfo('Query results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length === 235);
+ assert(arr[0].toString().startsWith('2004,20021,14345,30116,NGR,B,2004-09-27T') == true);
+ assert(arr[arr.length - 1].toString().startsWith('2004,20317,14457,30124,ITA,G,2004-09-25T') == true);
+ for (var j = 0; j < arr.length; j++) {
+ Helpers.logInfo(arr[j].toString());
+ }
+ returnedQueryHandle = queryHandle;
+ ActionQueue.while(
+ function () {
+ return fetchResult !== null;
+ },
+ function (callback) {
+ CUBRIDClient.fetch(returnedQueryHandle, function (err, result) {
+ if (result !== null) {
+ Helpers.logInfo('Fetch results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length === 241 || arr.length === 224);
+ for (var k = 0; k < arr.length; k++) {
+ Helpers.logInfo(arr[k].toString());
+ }
+ } else {
+ Helpers.logInfo('There is no more data to fetch.');
+ }
+ fetchResult = result;
+ callback.call(err);
+ }
+ )
+ },
+ function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ cb.call(err);
+ }
+ }
+ )
+ },
+ function (cb) {
+ CUBRIDClient.closeRequest(returnedQueryHandle, cb);
+ },
+ function (cb) {
+ CUBRIDClient.close(cb);
+ }
+ ],
+ function (err) {
+ if (err == null) {
+ Helpers.logInfo('Test passed.');
+ } else {
+ throw 'Error executing test!';
+ }
+ }
+);
diff --git a/test/test_BasicSelect.js b/test/test_BasicSelect.js
new file mode 100644
index 0000000..e8323b2
--- /dev/null
+++ b/test/test_BasicSelect.js
@@ -0,0 +1,51 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ Helpers.logInfo('Querying: select * from nation');
+ CUBRIDClient.query('select * from nation', function (err, result, queryHandle) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ assert(Result2Array.GetResultsCount(result) === 215);
+ Helpers.logInfo('Query result rows count: ' + Result2Array.GetResultsCount(result));
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length === 215);
+ assert(arr[0].toString() === 'SRB,Serbia,Europe,Beograd');
+ assert(arr[arr.length - 1].toString() === 'AFG,Afghanistan,Asia,Kabul');
+ for (var j = 0; j < arr.length; j++) {
+ Helpers.logInfo(arr[j].toString());
+ }
+ CUBRIDClient.closeRequest(queryHandle, function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Query closed.');
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/test/test_BasicSelect_Cache.js b/test/test_BasicSelect_Cache.js
new file mode 100644
index 0000000..af7e1ca
--- /dev/null
+++ b/test/test_BasicSelect_Cache.js
@@ -0,0 +1,61 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb', 1000 * 30); //30 sec. cache lifetime
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ Helpers.logInfo('Querying: select * from game');
+ var startTime1 = (new Date()).getTime();
+ CUBRIDClient.query('select * from game', function (err, result, queryHandle) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ var endTime1 = (new Date()).getTime();
+ Helpers.logInfo('[First] query execution time (ms): ' + (endTime1 - startTime1).toString());
+ assert(Result2Array.GetResultsCount(result) === 8653);
+
+ //Repeat query - results expected to come from cache this time
+ var startTime2 = (new Date()).getTime();
+ CUBRIDClient.query('select * from game', function (err, result, queryHandle) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ var endTime2 = (new Date()).getTime();
+ Helpers.logInfo('[Second] query execution time (ms): ' + (endTime1 - startTime1).toString());
+ assert(endTime2 - startTime2 < 50);
+
+ assert(Result2Array.GetResultsCount(result) === 8653);
+
+ CUBRIDClient.closeRequest(queryHandle, function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Query closed.');
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/test/test_BasicSelect_ConnectImplicit.js b/test/test_BasicSelect_ConnectImplicit.js
new file mode 100644
index 0000000..556cc97
--- /dev/null
+++ b/test/test_BasicSelect_ConnectImplicit.js
@@ -0,0 +1,46 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+Helpers.logInfo('Connected.');
+Helpers.logInfo('Querying: select * from nation');
+CUBRIDClient.query('select * from nation', function (err, result, queryHandle) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ assert(Result2Array.GetResultsCount(result) === 215);
+ Helpers.logInfo('Query result rows count: ' + Result2Array.GetResultsCount(result));
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length === 215);
+ assert(arr[0].toString() === 'SRB,Serbia,Europe,Beograd');
+ assert(arr[arr.length - 1].toString() === 'AFG,Afghanistan,Asia,Kabul');
+ for (var j = 0; j < arr.length; j++) {
+ Helpers.logInfo(arr[j].toString());
+ }
+ CUBRIDClient.closeRequest(queryHandle, function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Query closed.');
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+});
+
+
+
diff --git a/test/test_BatchExecuteVariant.js b/test/test_BatchExecuteVariant.js
new file mode 100644
index 0000000..c29b02a
--- /dev/null
+++ b/test/test_BatchExecuteVariant.js
@@ -0,0 +1,51 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ CUBRIDClient.batchExecuteNoQuery('drop table if exists node_test', function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.batchExecuteNoQuery('create table node_test(id int)', function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.batchExecuteNoQuery('insert into node_test values(1)', function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.batchExecuteNoQuery('drop table node_test', function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/test/test_Connect.js b/test/test_Connect.js
new file mode 100644
index 0000000..57faf0c
--- /dev/null
+++ b/test/test_Connect.js
@@ -0,0 +1,34 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected OK.');
+ CUBRIDClient.getEngineVersion(function (err, result) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('CUBRID engine version: ' + result);
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/test/test_Connect_Sequence.js b/test/test_Connect_Sequence.js
new file mode 100644
index 0000000..0fe0a41
--- /dev/null
+++ b/test/test_Connect_Sequence.js
@@ -0,0 +1,28 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ ActionQueue = require('../src/utils/ActionQueue'),
+ Helpers = require('../src/utils/Helpers');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+ActionQueue.enqueue(
+ [
+ function (callback) {
+ CUBRIDClient.connect(callback);
+ },
+ function (callback) {
+ CUBRIDClient.getEngineVersion(callback);
+ },
+ function (version, callback) {
+ Helpers.logInfo('Engine version: ' + version);
+ CUBRIDClient.close(callback);
+ }
+ ],
+ function (err) {
+ if (err) {
+ throw err.message;
+ } else {
+ Helpers.logInfo('Test passed.');
+ }
+ }
+);
+
diff --git a/test/test_GetEngineVersion_ConnectImplicit.js b/test/test_GetEngineVersion_ConnectImplicit.js
new file mode 100644
index 0000000..06853ef
--- /dev/null
+++ b/test/test_GetEngineVersion_ConnectImplicit.js
@@ -0,0 +1,28 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.getEngineVersion(function (err, result) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('CUBRID engine version: ' + result);
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ assert(result.startsWith('8.4.1.') == true);
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ });
+ }
+});
+
+
diff --git a/test/test_SelectConstant_01.js b/test/test_SelectConstant_01.js
new file mode 100644
index 0000000..383ba62
--- /dev/null
+++ b/test/test_SelectConstant_01.js
@@ -0,0 +1,51 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ Helpers.logInfo('Querying: select 1');
+ CUBRIDClient.query('select 1', function (err, result, queryHandle) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ assert(Result2Array.GetResultsCount(result) === 1);
+ Helpers.logInfo('Query result rows count: ' + Result2Array.GetResultsCount(result));
+ Helpers.logInfo('Query results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length === 1);
+ assert(arr[0].toString() === '1');
+ for (var j = 0; j < arr.length; j++) {
+ Helpers.logInfo(arr[j].toString());
+ }
+ }
+ CUBRIDClient.closeRequest(queryHandle, function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Query closed.');
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ })
+ }
+});
+
+
diff --git a/test/test_SelectConstant_02.js b/test/test_SelectConstant_02.js
new file mode 100644
index 0000000..a6ee888
--- /dev/null
+++ b/test/test_SelectConstant_02.js
@@ -0,0 +1,52 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ Result2Array = require('../src/resultset/Result2Array'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ throw err.message;
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ Helpers.logInfo('Querying: select null from nation where rownum < 3');
+ CUBRIDClient.query('select null from nation where rownum < 3', function (err, result, queryHandle) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ assert(Result2Array.GetResultsCount(result) === 2);
+ Helpers.logInfo('Query result rows count: ' + Result2Array.GetResultsCount(result));
+ Helpers.logInfo('Query results:');
+ var arr = Result2Array.GetResultsArray(result);
+ assert(arr.length === 2);
+ assert(arr[0].toString() === '');
+ assert(arr[1].toString() === '');
+ for (var j = 0; j < arr.length; j++) {
+ Helpers.logInfo(arr[j].toString());
+ }
+ CUBRIDClient.closeRequest(queryHandle, function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Query closed.');
+ CUBRIDClient.close(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connection closed.');
+ Helpers.logInfo('Test passed.');
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+});
+
+
diff --git a/test/test_SocketError.js b/test/test_SocketError.js
new file mode 100644
index 0000000..17d9b8c
--- /dev/null
+++ b/test/test_SocketError.js
@@ -0,0 +1,30 @@
+var CUBRIDConnection = require('../src/CUBRIDConnection'),
+ Helpers = require('../src/utils/Helpers'),
+ assert = require('assert');
+
+var CUBRIDClient = new CUBRIDConnection('localhost', 33000, 'public', '', 'demodb');
+
+function errorHandler(err) {
+ Helpers.logInfo(err.message);
+ assert(err.message == 'This socket is closed.');
+ Helpers.logInfo('Test passed.');
+}
+
+CUBRIDClient.connect(function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('Connected.');
+ Helpers.logInfo('Querying: select * from nation');
+ CUBRIDClient.socket.destroy();
+ CUBRIDClient.query('select * from nation', function (err) {
+ if (err) {
+ errorHandler(err);
+ } else {
+ Helpers.logInfo('We should not get here!');
+ }
+ })
+ }
+});
+
+