Permalink
Browse files

Full CQL Support, Proper Serialization/Deserialization of Types, bump…

… to v0.1.0
  • Loading branch information...
1 parent 03a5320 commit deda6491587e4da93f78ae2406bfb35f70b92b69 @devdazed devdazed committed Jan 4, 2012
Showing with 731 additions and 257 deletions.
  1. +9 −1 History.md
  2. +79 −9 Readme.md
  3. +0 −180 lib/client.js
  4. +296 −0 lib/connection.js
  5. +2 −1 lib/helenus.js
  6. +98 −0 lib/marshal/deserializers.js
  7. +3 −3 lib/marshal/index.js
  8. +15 −1 lib/marshal/serializers.js
  9. +81 −45 lib/pool.js
  10. +117 −0 lib/row.js
  11. +1 −1 package.json
  12. +30 −16 test/test.js
View
@@ -1,5 +1,13 @@
-0.0.1 / 2010-01-03
+0.0.1 / 2011-12-22
==================
* Initial release
+
+0.1.0 / 2012-01-04
+==================
+
+ * Added CQL Support
+ * More Robust Connection Pooling
+ * Respond with JS errors, not TException objects
+ * Added proper serialization/deserialization support for all types
View
@@ -3,32 +3,102 @@
NodeJS Bindings for Cassandra
+ Currently the driver has full CQL support and we are currently adding
+ support for additional "non-cql" commands.
+
This is very much work in progress, if you would like to contribute, please contact Russ Bradberry <rbradberry@simplereach.com>
-# installation
+## Installation
npm install helenus
-# usage
+## Usage
+
```javascript
var helenus = require('helenus'),
- pool = new helenus.ConnectionPool(['localhost:9160','localhost:9161']);
+ pool = new helenus.ConnectionPool({
+ hosts : ['localhost:9160'],
+ keyspace : 'helenus_test',
+ user : 'test',
+ password : 'test1233',
+ timeout : 3000
+ });
+ //if you don't listen for error, it will bubble up to `process.uncaughtException`
pool.on('error', function(err){
- console.log('ERROR:' + err);
+ console.error(err.name, err.message);
});
- //connect to the local machine
- pool.connect('node_cassandra_test', function(err, keyspace){
+ //makes a connection to the pool, this will return once there is at least one
+ //valid connection, other connections may still be pending
+ pool.connect(function(err, keyspace){
if(err){
throw(err);
} else {
- keyspace.cf_one.insert('abcd', { 'column':'value' }, { ttl:1234, consistencyLevel:1 }, function(err){
- //TODO: Be able to get fields
- });
+ //keyspace is the object for interacting the the specific column families
+ //in the keyspace, it is accessed like this: `keyspace.cf_one.insert(...)`
+ //or `keyspace.cf_two.get(...)`, **this is currently being built out**
+
+ //to use cql, access the pool object once connected
+ //the first argument is the CQL string, the second is an `Array` of items
+ //to interpolate into the format string, the last is the callback
+ //for formatting specific see `http://nodejs.org/docs/latest/api/util.html#util.format`
+ //results is an array of row objects
+
+ pool.cql("SELECT '%s' FROM '%s' WHERE key='%s'", ['col','cf_one','key123'], function(err, results){
+ console.log(err, results);
+ });
}
});
```
+
+## Row
+
+The Helenus Row object acts like an array but contains some helper methods to
+make your life a bit easier when dealing with dynamic columns in Cassandra
+
+### row.count
+
+Returns the number of columns in the row
+
+### row[N]
+
+This will return the column at index N
+
+ results.forEach(function(row){
+ //gets the 5th column of each row
+ console.log(row[5]);
+ });
+
+### row.get(name)
+
+This will return the column with a specific name
+
+ results.forEach(function(row){
+ //gets the column with the name 'foo' of each row
+ console.log(row.get('foo'));
+ });
+
+### row.slice(start, finish)
+
+Slices columns in the row based on their numeric index, this allows you to get
+columns x through y, it returns a Helenus row object of columns that match the slice.
+
+ results.forEach(function(row){
+ //gets the first 5 columns of each row
+ console.log(row.slice(0,5));
+ });
+
+### row.nameSlice(start, finish)
+
+Slices the columns based on part of their column name. returns a helenus row of columns
+that match the slice
+
+ results.forEach(function(row){
+ //gets all columns that start with a, b, c, or d
+ console.log(row.slice('a','e'));
+ });
+
## License
(The MIT License)
View
@@ -1,180 +0,0 @@
-
-var util = require('util'),
- thrift = require('thrift'),
- Cassandra = require('./cassandra/1.0/Cassandra'),
- ttype = require('./cassandra/1.0/cassandra_types'),
- ColumnFamily = require('./column_family');
-
-/**
- * A No-Op function for default callbacks
- */
-var NOOP = function(){};
-/**
- * Default port for cassandra
- * @private
- */
-var DEFAULT_PORT = 9160;
-
-/**
- * Default host
- * @private
- */
-var DEFAULT_HOST = 'localhost';
-
-/**
- * The Cassandra Client
- *
- * @param {Number} port The port to connect on, defaults to 9160
- * @param {String} host The host to connect to, defaults to localhost
- * @contructor
- */
-var Client = function(port, host){
- if (typeof port === 'string' && port.indexOf(':') > -1){
- var parts = port.split(':');
- port = parts[1];
- host = parts[0];
- }
-
- /**
- * The port to connect to
- */
- this.port = port || DEFAULT_PORT;
-
- /**
- * The host to connect to
- */
- this.host = host;
-
- /**
- * Ready state of the client
- */
- this.ready = false;
-};
-util.inherits(Client, process.EventEmitter);
-
-/**
- * Connects to the cassandra cluster
- */
-Client.prototype.connect = function(keyspace, options, callback){
- var self = this;
-
- if (typeof keyspace === 'function'){
- callback = keyspace;
- keyspace = undefined;
- }
-
- if (typeof options === 'function'){
- callback = options;
- options = {};
- }
-
- //set callback to a noop to prevent explosion
- callback = callback || NOOP;
-
- /**
- * Thrift Connection
- */
- this._connection = thrift.createConnection(this.host, this.port);
-
- //bubble up all errors
- this._connection.on('error', this.emit);
- this._connection.on('close', function(){
- self.ready = false;
- self.emit('error', new Error(self.host + ':' + self.port + ' Client Disconnect'));
- });
-
- /**
- * Thrift Client
- */
- this._client = thrift.createClient(Cassandra, this._connection);
-
- /**
- * Handles what happens when we connect to the cassandra cluster
- *
- * @private
- * @param {Error} err A connection error with cassandra
- */
- function onConnect(err) {
- if (err){
- callback(err);
- return;
- }
-
- //set the state to ready
- self.ready = true;
-
- // if keyspace is specified, use that ks
- if (keyspace !== undefined){
- self.use(keyspace, callback);
- } else {
- callback();
- }
- }
- this._connection.on('connect', onConnect);
-};
-
-/**
- * Sets the current keyspace
- *
- * @param {String} keyspace The keyspace to use
- */
-Client.prototype.use = function(keyspace, callback){
- var self = this;
- callback = callback || NOOP;
-
- function onKeyspace(err, definition){
- if (err) {
- callback(err);
- return;
- }
-
- /**
- * Callback for the Keyspace Set function
- *
- * @param {Error} err An error object
- * @private
- */
- function onKeyspaceSet(err){
- callback(err);
- }
- self._client.set_keyspace(keyspace, onKeyspaceSet);
- }
-
- this._client.describe_keyspace(keyspace, onKeyspace);
-};
-
-/**
- * Executes a command via the thrift connection
- * @param {String} command The command to execute
- * additional params are supplied to the command to be executed
- */
-Client.prototype.execute = function(){
- var args = Array.prototype.slice.apply(arguments),
- command = args.shift();
-
- this._client[command].apply(this._client, args);
-};
-
-/**
- * Executes a CQL Query Against the DB.
- * @param {String} cmd A string representation of the query: 'select %s, %s from MyCf where key=%s'
- * @param {arguments} args0...argsN An Array of arguments for the string ['arg0', 'arg1', 'arg2']
- * @param {Function} callback The callback function for the results
- */
-Client.prototype.cql = function(cmd){
- var args = Array.prototype.slice.call(arguments, 1),
- callback = args.pop();
-
- if(typeof callback !== 'function'){
- args.push(callback);
- callback = function(){};
- }
-
- args.unshift(cmd);
- var cql = new Buffer(util.format.apply(this, args));
- console.log(cql.toString())
- this.execute('execute_cql_query', cql, ttype.Compression.NONE, callback);
-};
-
-//export our client
-module.exports = Client;
Oops, something went wrong.

0 comments on commit deda649

Please sign in to comment.