A ORM (Object-relational mapping) libraby for Cassandra ontop of the data-stax cassandra driver. This library will abstract the need to write raw insert/update/select statements.
(use at your own risk!, higly unstable)
$ npm install cqlify
Uses all of the same connection options as the data-stax cassandra driver. Here is an exmple of a basic C*(Cassandra) database with basic authentication:
var cassandra = require('cassandra-driver');
var connectionOptions = {
contactPoints: ["2.2.2.2","3.3.3.3"],
keyspace: "keyspace",
policies: {},
authProvider: new cassandra.auth.PlainTextAuthProvider("user", "password")
};
var cqlify = require('./cqlify');
cqlify.createConnection(connectionOptions);
Now that you have a connection you can create a model. In your model you will specify the schema, which describes the format of your object. Let's take an example table:
Column | Type |
---|---|
id | timeuuid |
first_name | text |
address | text |
user_model.js
var userModel = function(cqlify) {
var schema = {
id: {
type: cqlify.types.TIMEUUID,
key_type: cqlify.types.PRIMARY_KEY,
key_order: 1
},
first_name: {
type: cqlify.types.TEXT,
},
address: {
type: cqlify.types.TEXT
}
};
var model = cqlify.model(schema, {
tableName: 'user'
});
model._pre(function(obj) {
if(obj.isNew) {
obj.id = cqlify.types.getTimeUuid().now();
}
});
return model;
};
module.exports = userModel;
- TimeUUID - C* type
- TimeStamp - C* type
- Int - C* type
- BigInt - C* type
- Boolean - C* type
- UUID - C* type
- JSONTOTEXT - Propietry type which will allow you to specify your field as a JSON object. Cqlify will convert that object to JSON and store it as text in the DB.
- ENUMTOTEXT - Like JSON to text you can specify a Javascript enum value, and in turn cqlify will handle the conversions to text and back.
- Map : Supported on Insert and Get.. will eventually support update with a future enhancement
- List : Supported on Insert and Get.. will eventually support update with a future enhancement
- Counter : No support.. to come.. you could an Int for now, however, need to build in logic for incremental updates.. i.e. "counter + 1"
In this section we will cover how to select data using cqlify. It is a very easy process to select out data
Lookup with one field
var user = new userModel(cqlify); //create your model
user.find([{
name:'id', value: user.id, comparer: cqlify.comparer.EQUALS //specify the query type and field name
}], function(err, data) {
if(err){
//handle errors here
}
console.log(data[0].toObject()) //log the first object
});
Lookup with multi-field, c always treats this as an AND*
var user = new userModel(cqlify); //create your model
var query = {
params: [
{name:'id', value: 'idvalue', comparer: cqlify.comparer.EQUALS},
{name:'first_name', value: 'first_name', comparer: cqlify.comparer.EQUALS},
]
};
user.find(query, function(err, data) {
if(err){
//handle errors here
}
console.log(data[0].toObject()) //log the first object
});
- EQUALS : cqlify.types.EQUALS : Standard equals operator .. i.e. field="value"
- GREATER_THAN :cqlify.types.GREATER_THAN : count > 10
- LESS_THAN :cqlify.types.LESS_THAN : count < 10
- IN : cqlify.types.IN : value in ("value1","value2","value3)
var user = new userModel(cqlify);
user.id = cqlify.types.getTimeUuid().now();
user.first_name = "Robert";
user.address = "some address";
var query = {};
user.insert(query, function(err, data) {
if(err){
//handle errors here
}
console.log(data[0].toObject()) //log the first object
});
Here is an example of pulling a record from the database and then updating one field (address in this case).
var user = new userModel(cqlify);
var query = {
params: [{
name:'id', value: user.id, comparer: cqlify.comparer.EQUALS
}]
};
user.find(query, function(err, data) {
if (err) throw err;
var user_from_db = data[0];
user_from_db.address = "new address";
user_from_db.update(
[{name: 'id', value: user.id, comparer: cqlify.comparer.EQUALS}] //specify the update criteria.. we could automate this in the future..
, function (err, data) {
if (err) throw err;
console.log('saved user');
});
});
Counters are kind of a special animal when it comes to CQL.. To insert a Counter you actually have to do an Update.. even if it is new.. odd I know.. Counters must always be incremented or decremented, thus CQLify enforces a format like '+0' '+1' '-5' etc.. Thus, here is how you would create a new counter..
Model
var pageCountModel = function() {
var schema = {
counter_value: {
type: cqlify.types.COUNTER
},
url_name: {
type: cqlify.types.TEXT
},
page_name: {
type: cqlify.types.TEXT
}
};
var opts = {
tableName: 'counts'
};
var model = cqlify.model(schema, opts);
return model;
}();
Code
var page = new pageCountModel();
page.page_name = 'cnn';
page.url_name = 'www.cnn.com';
page._markClean(); //this is kind of a hack for now.. basically you never want the primary keys being marked as dirty, which then puts it on the update set.
page.counter_value = "+0"; //must always increment or decrement .. cannot set a value
var query = {
params: [
{name: "page_name", value: page.page_name, comparer: cqlify.comparer.EQUALS},
{name: "url_name", value: page.url_name, comparer: cqlify.comparer.EQUALS},
]
};
page.update(query, function(err, data) {
if(err) {
console.log('ERROR:' + err);
}
});
Out of the box we validate certain fields to ensure they meet the specification to insert into the database. The fields we do contstraint validation on :
- TimeUuid
- Text
- Int(Int32)
- bigint(Int64)
- Date
- Boolean
All schema types allow for custom validation, all you need to do is add a "validators" array to a schema element.
Validate first name must be atleast 5 characters
var userModel = function () {
var schema = {
id: {
type: cqlify.types.TIMEUUID,
key_type: cqlify.types.PRIMARY_KEY,
key_order: 1
},
first_name: {
type: cqlify.types.TEXT,
validators: [
function (obj) {
if (obj && obj.length < 5){
return cqlify.util.constructValidationMessage(false, "First name must be atleast 5 characters"); //construct the error message.
}
return true; //return back the object is valid
}
]
}
}
});
You can always validate manually by invoking the _validate method
var isValid = user._validate();
See https://github.com/robpolak/cqlify/issues.
The MIT License (MIT)