Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit.

  • Loading branch information...
commit 94d37a27afc092f3994c60d6b953469d699ab509 0 parents
@yojimbo87 authored
29 .gitignore
@@ -0,0 +1,29 @@
+
+#ignore thumbnails created by windows
+Thumbs.db
+#Ignore files build by Visual Studio
+*.obj
+*.exe
+*.pdb
+*.user
+*.aps
+*.pch
+*.vspscc
+*_i.c
+*_p.c
+*.ncb
+*.suo
+*.tlb
+*.tlh
+*.bak
+*.cache
+*.ilk
+*.log
+[Bb]in
+[Dd]ebug*/
+*.lib
+*.sbr
+obj/
+[Rr]elease*/
+_ReSharper*/
+[Tt]est[Rr]esult*
24 LICENSE.md
@@ -0,0 +1,24 @@
+The MIT X11 License covers libraries in the minotaur project.
+Some third party libraries come from different projects, and
+are licensed under their own terms.
+
+Copyright (c) [2011 - present] Tomas Bosak, http://yojimbo87.github.com/
+
+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.
14 README.md
@@ -0,0 +1,14 @@
+East
+====
+
+East is a [network binary protocol](http://code.google.com/p/orient/wiki/NetworkBinaryProtocol) driver for [OrientDB](http://www.orientechnologies.com/orient-db.htm) NoSQL database.
+
+Due to lack of time it's currently abandoned.
+
+
+Network binary protocol implementation status:
+----------------------------------------------
+
+ * Binary parser (done)
+ * Operation types (done)
+ * DbOpen (done)
43 examples/simple/simple.js
@@ -0,0 +1,43 @@
+var Client = require("../../lib/East");
+
+var client = new Client({database: "test", port: 2425, logOperations: true});
+
+setTimeout(function() {
+ client.dbOpen(function(error, result) {
+ console.log("CLIENT:");
+ if(error) {
+ console.log("error!");
+ }
+
+ if(result) {
+ console.log("CLUSTERS:" + result.clustersCount);
+ /*for(i = 0; i < result.clustersCount; i++) {
+ var foo = result.clusters[i];
+ var str = "";
+ for(var item in foo) {
+ str += foo[item] + ", ";
+ }
+ console.log(i + ": " + str);
+ }*/
+ }
+ });
+
+ client.dbOpen(function(error, result) {
+ console.log("CLIENT:");
+ if(error) {
+ console.log("error!");
+ }
+
+ if(result) {
+ console.log("CLUSTERS:" + result.clustersCount);
+ /*for(i = 0; i < result.clustersCount; i++) {
+ var foo = result.clusters[i];
+ var str = "";
+ for(var item in foo) {
+ str += foo[item] + ", ";
+ }
+ console.log(i + ": " + str);
+ }*/
+ }
+ });
+}, 5000);
71 lib/East.js
@@ -0,0 +1,71 @@
+var debug = require("./commands/Debug"),
+ Manager = require("./commands/Manager"),
+ OPERATION_TYPE = require("./commands/OperationType");
+
+/*------------------------------------------------------------------------------
+ (public) East
+
+ + options {host, port, database, user, password}
+ - void
+
+ Set up east module.
+------------------------------------------------------------------------------*/
+var East = module.exports = function East(options) {
+ var clientOptions = options || {};
+
+ this._options = {
+ host: clientOptions.host || "localhost",
+ port: clientOptions.port || 2424,
+ database: clientOptions.database || "demo",
+ user: clientOptions.user || "admin",
+ password: clientOptions.password || "admin",
+ logOperations: clientOptions.logOperations || false,
+ logErrors: clientOptions.logErrors || false
+ };
+
+ // set up logging options
+ debug.options({
+ logOperations: this._options.logOperations,
+ logErrors: this._options.logErrors
+ });
+
+ // initiate new manager which connects to the server with given options
+ this._manager = new Manager(this._options);
+
+ // listen to the respone event emitted when processed command is sent back
+ // to the client with error or result and invoke particular callback
+ this._manager.on("response", function(error, result, command) {
+ //console.log("!!! response event !!! " + command.sequence);
+ command.callback(error, result);
+ });
+
+ // listen to the respone event emitted when processed command is sent back
+ // to the client with error or result and invoke particular callback
+ if(this._options.logErrors) {
+ this._manager.on("response_error", function(error, command) {
+ debug.log();
+ });
+ }
+};
+
+/*------------------------------------------------------------------------------
+ (public) dbOpen
+
+ + callback(error, result)
+ - void
+
+ Executes DB_OPEN operation.
+------------------------------------------------------------------------------*/
+East.prototype.dbOpen = function(callback) {
+ var self = this;
+
+ self._manager._writeRequest(
+ OPERATION_TYPE.DB_OPEN,
+ {
+ database: self._options.database,
+ user: self._options.user,
+ password: self._options.password
+ },
+ callback
+ );
+};
155 lib/commands/DbOpen.js
@@ -0,0 +1,155 @@
+var parser = require("./Parser"),
+ OPERATIONTYPE = require("./OperationType");
+
+/*------------------------------------------------------------------------------
+ (public) DbOpen
+
+ + none
+ - void
+
+ Constructor - set up parser.
+------------------------------------------------------------------------------*/
+var DbOpen = module.exports = function DbOpen() {
+ this._indexCursor = 13;
+};
+
+/*------------------------------------------------------------------------------
+ (public) read
+
+ + data
+ + callback
+ - void
+
+ Read respone from server and emits response event.
+------------------------------------------------------------------------------*/
+DbOpen.prototype.read = function(data, callback) {
+ var self = this,
+ indexCursor = this._indexCursor,
+ result = {
+ status: 0,
+ sessionID: 0,
+ clustersCount: 0,
+ clusters: [],
+ clusterConfig: null
+ },
+ cluster = {},
+ i, j, tempInt;
+
+ // status
+ result.status = parser.readByte(data[0]);
+ //console.log("status: " + result.status);
+ if(result.status === 1) {
+ callback(
+ data,
+ undefined
+ );
+ return;
+ }
+
+ // session ID
+ result.sessionID = parser.readInt([
+ data.charCodeAt(5),
+ data.charCodeAt(6),
+ data.charCodeAt(7),
+ data.charCodeAt(8)
+ ]);
+ //console.log("session ID: " + result.sessionID);
+
+ // number of clusters
+ result.clustersCount = parser.readInt([
+ data.charCodeAt(9),
+ data.charCodeAt(10),
+ data.charCodeAt(11),
+ data.charCodeAt(12)
+ ]);
+ //console.log("number of clusters: " + result.clustersCount);
+
+ // clusters
+ for(i = 0; i < result.clustersCount; i++) {
+ // cluster name length
+ tempInt = parser.readInt([
+ data.charCodeAt(indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor)
+ ]);
+
+ // cluster name
+ cluster["name"] = data.substring(
+ ++indexCursor,
+ indexCursor + tempInt
+ );
+
+ // cluster id
+ indexCursor = indexCursor + tempInt;
+ cluster["id"] = parser.readInt([
+ data.charCodeAt(indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor)
+ ]);
+
+ //cluster type length
+ tempInt = parser.readInt([
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor)
+ ]);
+
+ // cluster type
+ cluster["type"] = data.substring(
+ ++indexCursor,
+ indexCursor + tempInt
+ );
+
+ // insert cluster into collection
+ result.clusters.push(cluster);
+ // clear cluster object
+ cluster = {};
+ // set index cursor to next value
+ indexCursor = indexCursor + tempInt;
+ }
+
+ callback(undefined, result);
+};
+
+/*------------------------------------------------------------------------------
+ (public) write
+
+ + socket
+ + sessionID
+ + data
+ + callback
+ - void
+
+ Write request to server and emits request event.
+------------------------------------------------------------------------------*/
+DbOpen.prototype.write = function(socket, sessionID, data, callback) {
+ var buffer;
+
+ // operation type
+ //socket.write(parser.writeByte(OPERATIONTYPE.DB_OPEN, true));
+ socket.write(parser.writeByte(500, true));
+
+ // invoke callback imidiately when the operation is sent to the server
+ callback();
+
+ // session ID
+ socket.write(parser.writeInt(sessionID, true));
+
+ // database name
+ buffer = new Buffer(data.database);
+ socket.write(parser.writeInt(buffer.length, true));
+ socket.write(buffer);
+
+ // user name
+ buffer = new Buffer(data.user);
+ socket.write(parser.writeInt(buffer.length, true));
+ socket.write(buffer);
+
+ // password
+ buffer = new Buffer(data.password);
+ socket.write(parser.writeInt(buffer.length, true));
+ socket.write(buffer);
+};
50 lib/commands/Debug.js
@@ -0,0 +1,50 @@
+var util = require("util"),
+ options;
+
+/*------------------------------------------------------------------------------
+ (public) options
+
+ + options
+ - void
+
+ Constructor - set up debug.
+------------------------------------------------------------------------------*/
+module.exports.options = function(optionsArg) {
+ options = {
+ logOperations: optionsArg.logOperations || false,
+ logErrors: optionsArg.logErrors || false,
+ color: 1
+ };
+};
+
+/*------------------------------------------------------------------------------
+ (public) log
+
+ + message
+
+ Output message to stdout.
+------------------------------------------------------------------------------*/
+module.exports.log = function(message) {
+ if(options.logOperations) {
+ util.log(
+ "East debug: " +
+ message
+ );
+ }
+};
+
+/* recursive through objects */
+
+module.exports.look = function(obj) {
+ var A= [], tem;
+ for(var p in obj){
+ if(obj.hasOwnProperty(p)){
+ tem= obj[p];
+ if(tem && typeof tem=='object'){
+ A[A.length]= p+':{ '+arguments.callee(tem).join(', ')+'}';
+ }
+ else A[A.length]= ["\t" +p+':'+tem.toString()+"\n"];
+ }
+ }
+ return A;
+};
62 lib/commands/Error.js
@@ -0,0 +1,62 @@
+var parser = require("./Parser"),
+ debug = require("./Debug");
+
+
+
+module.exports.parse = function(data) {
+ var indexCursor = 0,
+ response = {pairs: []},
+ tempInt, tempClass, tempMessage;
+
+ var more = parser.readByte(data[indexCursor]);
+
+ // session ID
+ var sid = parser.readInt([
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor)
+ ]);
+
+ more = parser.readByte(data[++indexCursor]);
+
+ while(more) {
+ // exception class string length
+ tempInt = parser.readInt([
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor)
+ ]);
+
+ // exception class string
+ tempClass = data.substring(
+ ++indexCursor,
+ indexCursor + tempInt
+ );
+
+ indexCursor = indexCursor + tempInt;
+
+ // exception message string length
+ tempInt = parser.readInt([
+ data.charCodeAt(indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor),
+ data.charCodeAt(++indexCursor)
+ ]);
+
+ // exception message string
+ tempMessage = data.substring(
+ ++indexCursor,
+ indexCursor + tempInt
+ );
+
+ indexCursor = indexCursor + tempInt;
+
+ response.pairs.push({class: tempClass, message: tempMessage});
+
+ more = parser.readByte(data[indexCursor]);
+ }
+
+ return response;
+};
196 lib/commands/Manager.js
@@ -0,0 +1,196 @@
+var net = require("net"),
+ debug = require("./Debug"),
+ parser = require("./Parser"),
+ error = require("./Error"),
+ OPERATION_TYPE = require("./OperationType"),
+ DbOpen = require("./DbOpen");
+
+/*------------------------------------------------------------------------------
+ (public) Manager
+
+ + options {host, port, database, user, password}
+ - void
+
+ Set up connection manager.
+------------------------------------------------------------------------------*/
+var Manager = module.exports = function Manager(options) {
+ this._options = options;
+
+ // hash of the supported operations
+ this._operations = {
+ dbOpen: new DbOpen()
+ };
+
+ // protocol version which this client is using
+ this._PROTOCOL_VERSION = 5;
+ this._socket = null;
+
+ // set up logging options
+ debug.options({
+ logOperations: options.logOperations,
+ logErrors: options.logErrors
+ });
+
+ // session ID
+ this._sessionID = -1;
+
+ // count of commands executed from the module initiation
+ this._commandsCount = 0;
+
+ // queue with currently executing commands
+ this._commandQueue = [];
+
+ // initiate connection with the server
+ this._init();
+};
+
+Manager.prototype = new process.EventEmitter();
+
+/*------------------------------------------------------------------------------
+ (private) _init
+
+ + none
+ - void
+
+ Initiate connection with the server.
+------------------------------------------------------------------------------*/
+Manager.prototype._init = function() {
+ var self = this,
+ first = true;
+
+ self._socket = net.createConnection(
+ self._options.port,
+ self._options.host
+ );
+ self._socket.setEncoding("utf8");
+ debug.log("Connecting");
+
+ self._socket.on("connect", function() {
+ debug.log("Connected");
+ });
+
+ self._socket.on("data", function (data) {
+ if(first) {
+
+ if(self._PROTOCOL_VERSION !== parser.readShort(data)) {
+ debug.log(
+ "Server protocol version is not supported - " +
+ "This driver supports only version " +
+ self._PROTOCOL_VERSION
+ );
+ self._socket.destroy();
+ return;
+ }
+ first = false;
+ } else {
+ self._readResponse(data);
+ }
+ });
+
+ self._socket.on("close", function (hadError) {
+ debug.log("Closed " + hadError);
+ });
+};
+
+/*------------------------------------------------------------------------------
+ (private) _readResponse
+
+ + data
+ - void
+
+ Parse data received from socket.
+------------------------------------------------------------------------------*/
+Manager.prototype._readResponse = function(data) {
+ var self = this,
+ command;
+
+ command = self._commandQueue.shift();
+
+ debug.log(
+ "Response - " +
+ data.length + " B - " +
+ "Operation " +
+ command.operationType +
+ " Sequence " + command.sequence
+ );
+
+ switch(command.operationType) {
+ case OPERATION_TYPE.SHUTDOWN:
+ break;
+ case OPERATION_TYPE.CONNECT:
+ break;
+ case OPERATION_TYPE.DB_OPEN:
+ self._operations.dbOpen.read(data, function(errorData, result) {
+ if(errorData) {
+ var foo = error.parse(errorData);
+
+
+ debug.log(debug.look(foo).join("\n"));
+ }
+
+ if(result) {
+ self._sessionID = result.sessionID;
+ }
+ self.emit("response", errorData, result, command);
+ });
+ break;
+ default:
+ break;
+ }
+};
+
+/*------------------------------------------------------------------------------
+ (private) _writeRequest
+
+ + operationType
+ + data
+ + callback
+ - void
+
+ Send operation request to the server.
+------------------------------------------------------------------------------*/
+Manager.prototype._writeRequest = function(operationType, data, cmdCallback) {
+ var self = this,
+ command;
+
+ command = {
+ sequence: ++self._commandsCount,
+ operationType: operationType,
+ callback: cmdCallback
+ };
+
+ if((self._sessionID !== -1) ||
+ (operationType === OPERATION_TYPE.CONNECT) ||
+ (operationType === OPERATION_TYPE.DB_OPEN)) {
+ switch(operationType) {
+ case OPERATION_TYPE.SHUTDOWN:
+ break;
+ case OPERATION_TYPE.CONNECT:
+ break;
+ case OPERATION_TYPE.DB_OPEN:
+ self._operations.dbOpen.write(
+ self._socket,
+ self._sessionID,
+ data,
+ function() {
+ self._commandQueue.push(command);
+ }
+ );
+ break;
+ default:
+ break;
+ }
+ } else {
+ debug.log(
+ "Cannot send request - " +
+ "Client has no session ID assigned"
+ );
+ }
+
+ debug.log(
+ "Request - Operation " +
+ command.operationType +
+ " - Sequence " +
+ command.sequence
+ );
+};
27 lib/commands/OperationType.js
@@ -0,0 +1,27 @@
+module.exports = {
+ SHUTDOWN: 1,
+ CONNECT: 2,
+ DB_OPEN: 3,
+ DB_CREATE: 4,
+ DB_CLOSE: 5,
+ DB_EXIST: 6,
+ DB_DELETE: 7,
+ DB_SIZE: 8,
+ DB_COUNTRECORDS: 9,
+ DATACLUSTER_ADD: 10,
+ DATACLUSTER_REMOVE: 11,
+ DATACLUSTER_COUNT: 12,
+ DATACLUSTER_DATARANGE: 13,
+ DATASEGMENT_ADD: 20,
+ DATASEGMENT_REMOVE: 21,
+ RECORD_LOAD: 30,
+ RECORD_CREATE: 31,
+ RECORD_UPDATE: 32,
+ RECORD_DELETE: 33,
+ COUNT: 40,
+ COMMAND: 41,
+ TX_COMMIT: 60,
+ CONFIG_GET: 70,
+ CONFIG_SET: 71,
+ CONFIG_LIST: 72
+};
106 lib/commands/Parser.js
@@ -0,0 +1,106 @@
+/*------------------------------------------------------------------------------
+ (public) readByte
+
+ + byte
+ - byte representing character code
+
+ Parse byte to readable number.
+------------------------------------------------------------------------------*/
+module.exports.readByte = function(byte) {
+ return byte.charCodeAt(0);
+};
+
+/*------------------------------------------------------------------------------
+ (public) readInt
+
+ + bytes
+ - string
+
+ Parse bytes to readable number.
+------------------------------------------------------------------------------*/
+module.exports.readInt = function(bytes) {
+ return (bytes[0] << 24) +
+ (bytes[1] << 16) +
+ (bytes[2] << 8) +
+ bytes[3];
+};
+
+/*------------------------------------------------------------------------------
+ (public) readShort
+
+ + bytes
+ - string
+
+ Parse bytes to readable number.
+------------------------------------------------------------------------------*/
+module.exports.readShort = function(bytes) {
+ /*var i = 0,
+ len = data.length,
+ str = "";
+
+ for (; i < len; i++) {
+ str += data.charCodeAt(i);
+ }
+
+ return str;*/
+
+ /*return (bytes[0] << 8) +
+ bytes[1];*/
+
+ return bytes.charCodeAt(0) +
+ bytes.charCodeAt(1);
+};
+
+/*------------------------------------------------------------------------------
+ (public) writeByte
+
+ + data
+ + useBuffer (optional) - when returned value should be a buffer
+ - bytes or buffer
+
+ Parse data to 4 bytes which represents integer value.
+------------------------------------------------------------------------------*/
+module.exports.writeByte = function(data, useBuffer) {
+ var byte = [data];
+
+ if(useBuffer) {
+ return new Buffer(byte);
+ } else {
+ return byte;
+ }
+};
+
+/*------------------------------------------------------------------------------
+ (public) writeInt
+
+ + data
+ + useBuffer (optional) - when returned value should be a buffer
+ - bytes or buffer
+
+ Parse data to 4 bytes which represents integer value.
+------------------------------------------------------------------------------*/
+module.exports.writeInt = function(data, useBuffer) {
+ var bytes = [];
+ bytes[3] = data & (255);
+ bytes[2] = (data & (65280))/256;
+ bytes[1] = (data & (16711680))/65536;
+ bytes[0] = (data & (4278190080))/16777216;
+
+ if(useBuffer) {
+ return new Buffer(bytes);
+ } else {
+ return bytes;
+ }
+};
+
+/*------------------------------------------------------------------------------
+ (public) writeString
+
+ + data
+ - buffer
+
+ Parse string data to buffer with UTF-8 encoding.
+------------------------------------------------------------------------------*/
+module.exports.writeString = function(data) {
+ return new Buffer(data, "utf8");
+};
Please sign in to comment.
Something went wrong with that request. Please try again.