Node.js and Cassandra: Improved Javascript Type Support
There are a lot of new features in the Node.js Driver for Apache Cassandra that we hope every Node.js developer will love.
This new version of the DataStax Node.js Driver improves the data type support in Javascript, delivering types not available in the Ecmascript standard that will make working with Cassandra data types a lot easier. We also added support for the new ES 6 Map/Set built-in types.
We introduced support for batches of prepared statements and named parameters for prepared statements, allowing the use of javascript objects to pass in parameter values.
Now, let’s have a more detailed look at the new features:
Improved Javascript type support
The Ecmascript specification, on which Javascript is based, is very poor in terms of built-in types: Numbers for representing int32/float/doubles, no int64 support, etc. Apache Cassandra, on the other side, is very rich in terms of type support, thanks to Java primitive types and classes.
To overcome this, we have to build our own Javascript types and include some of the Google Closure Math module classes.
Numerical types
We now use our own BigDecimal representation for Cassandra decimal support and Google Closure Integer for varint. These classes provide string representation and most common operations such as add()/substract()/etc.
Uuid and timeuuids/h3>
We used to depend on node-uuid module to support uuid generation. As we wanted to provide a more tuneable UUID generation and proper date decoding of TimeUuids, we rolled our own Uuid and TimeUuid classes:
var cassandra = require('cassandra-driver'); var id = cassandra.types.Uuid.random(); //new uuid v4 var timeId = cassandra.types.TimeUuid.now() //new instance based on current date var date = timeId.getDate(); //date representation
Ecmascript 6 Map and Set
Coinciding with the release of Node.js 0.12 that supports the most stable Ecmascript 6 (ES6) features, the new Map and Set built-in types can be used to represent Cassandra map and set values. To enable this option, you should specify the constructors in the client options:
var options = { contactPoints: contactPoints, encoding: { map: Map, set: Set } }; var client = new cassandra.Client(options);
Named parameters
Previous versions of the driver only supported positional parameters (specified by ? markers). Starting with this new version, you can use Javascript objects to bind parameter by names, when using Cassandra 2.0 or above:
var query = 'INSERT INTO tbl (id, name) VALUES (:id, :name)'; var params = { name: 'Keith Richards', id: 'krichards'}; client.execute(query, params, { prepare: true }, callback);
Batch of prepared statements
By preparing your queries, you will get the best performance and your Javascript parameters will be correctly encoded to Cassandra types. The driver will prepare each query once on each host and execute the batch every time with the different set of parameters provided.
var query1 = 'UPDATE user_profiles SET email=? WHERE key=?'; var query2 = 'INSERT INTO user_track (key, text, date) VALUES (?, ?, ?)'; var queries = [ { query: query1, params: [emailAddress, 'hendrix'] }, { query: query2, params: ['hendrix', 'Changed email', new Date()] } ]; client.batch(queries, { prepare: true}, function (err) { //all queries have been executed successfully //or none of the changes have been applied (err) });
Version 2.0 of the Node.js driver is available on npm, we hope you'll enjoy it!