Permalink
Browse files

added better support for composites [ closes #82 ]

  • Loading branch information...
1 parent 154790c commit ca9edd823fce77d4b2c1d10e61dc4fd6cbaf61de @devdazed devdazed committed Oct 17, 2012
Showing with 110 additions and 10 deletions.
  1. +12 −5 lib/column_family.js
  2. +38 −5 lib/marshal/index.js
  3. +60 −0 test/thrift.js
View
@@ -150,11 +150,11 @@ function getSlicePredicate(options, serializer){
predicate.column_names = cols;
} else {
if(options.start){
- start = serializer.serialize(options.start);
+ start = serializer.serialize(options.start, !options.reversed);
}
if(options.end){
- end = serializer.serialize(options.end);
+ end = serializer.serialize(options.end, !!options.reversed);
}
predicate.slice_range = new ttype.SliceRange({
@@ -270,8 +270,15 @@ ColumnFamily.prototype.remove = function() {
* @param {String} key The key to get
* @param {Object} options Options for the get, can have start, end, max, consistencyLevel
* <ul>
- * <li>start: the from part of the column name</li>
- * <li>end: the to part of the column name</li>
+ * <li>
+ * start: the from part of the column name, for composites pass an array. By default the
+ * composite queries are inclusive, to make them exclusive pass an array of arrays where the
+ * inner array is [ value, false ].
+ * </li>
+ * start: the end part of the column name, for composites pass an array. By default the
+ * composite queries are inclusive, to make them exclusive pass an array of arrays where the
+ * inner array is [ value, false ].
+ * <li>reversed: {Boolean} to whether the range is reversed or not</li>
* <li>max: the max amount of columns to return</li>
* <li>columns: an {Array} of column names to get</li>
* <li>consistencyLevel: the read consistency level</li>
@@ -319,7 +326,7 @@ ColumnFamily.prototype.truncate = function(callback){
* Gets rows by their indexed fields
* @param {Object} query Options for the rows part of the get
* <ul>
- * <li>fields: an array of objects thjat contain { column:column_name, operator: 'EQ', value:value }
+ * <li>fields: an array of objects that contain { column:column_name, operator: 'EQ', value:value }
* <ul>
* <li>column: {String} The name of the column with the index</li>
* <li>operator: {String} The operator to use, can be EQ, GTE, GT, LTE, ot LT</li>
View
@@ -107,7 +107,7 @@ function parseTypeString(type){
* @memberOf Marshal
*/
function compositeSerializer(serializers){
- return function(vals){
+ return function(vals, sliceStart){
var i = 0, buffers = [], totalLength = 0,
valLength = vals.length, val;
@@ -117,23 +117,56 @@ function compositeSerializer(serializers){
}
for(; i < valLength; i += 1){
- val = serializers[i](vals[i]);
+ if (Array.isArray(vals[i])){
+ val = [serializers[i](vals[i][0]), vals[i][1]];
+ totalLength += val[0].length + 3;
+ } else {
+ val = serializers[i](vals[i]);
+ totalLength += val.length + 3;
+ }
+
buffers.push(val);
- totalLength += val.length + 3;
}
var buf = new Buffer(totalLength),
buffersLength = buffers.length,
- writtenLength = 0;
+ writtenLength = 0, eoc, inclusive;
i = 0;
for(; i < buffersLength; i += 1){
val = buffers[i];
+ eoc = new Buffer('00', 'hex');
+ inclusive = true;
+
+ if (Array.isArray(val)){
+ inclusive = val[1];
+ val = val[0];
+ if(inclusive){
+ if (sliceStart){
+ eoc = new Buffer('ff', 'hex');
+ } else if (sliceStart === false){
+ eoc = new Buffer('01', 'hex');
+ }
+ } else {
+ if (sliceStart){
+ eoc = new Buffer('01', 'hex');
+ } else if (sliceStart === false){
+ eoc = new Buffer('ff', 'hex');
+ }
+ }
+ } else if (i === buffersLength - 1){
+ if (sliceStart){
+ eoc = new Buffer('ff', 'hex');
+ } else if (sliceStart === false){
+ eoc = new Buffer('01', 'hex');
+ }
+ }
+
buf.writeUInt16BE(val.length, writtenLength);
writtenLength += 2;
val.copy(buf, writtenLength, 0);
writtenLength += val.length;
- buf.write('\x00', writtenLength);
+ eoc.copy(buf, writtenLength, 0);
writtenLength += 1;
}
View
@@ -229,6 +229,8 @@ module.exports = {
assert.ifError(err);
assert.ok(row instanceof Helenus.Row);
assert.ok(row.get([12345678912345, new Date(1326400762701)]).value === 'some value');
+
+
test.finish();
});
},
@@ -245,6 +247,64 @@ module.exports = {
});
},
+ 'test standard cf with composite column slice':function(test, assert){
+ var values = [
+ new Helenus.Column([1, new Date(1)], 'a'),
+ new Helenus.Column([2, new Date(2)], 'b'),
+ new Helenus.Column([3, new Date(3)], 'c'),
+ new Helenus.Column([4, new Date(4)], 'd'),
+ new Helenus.Column([5, new Date(5)], 'e'),
+ new Helenus.Column([6, new Date(6)], 'f'),
+ new Helenus.Column([7, new Date(7)], 'g')
+ ],
+ key = [ 'comp_range_1', new Helenus.UUID('e491d6ac-b124-4795-9ab3-c8a0cf92615c') ];
+
+ cf_composite.insert(key, values, function(err){
+ assert.ifError(err);
+ var options = {
+ start: [3],
+ end: [5]
+ };
+
+ cf_composite.get(key, options, function(err, row){
+ assert.ifError(err);
+ assert.ok(row.count === 3);
+ assert.ok(row[0].name[0] === 3);
+ assert.ok(row[1].name[0] === 4);
+ assert.ok(row[2].name[0] === 5);
+ test.finish();
+ });
+ });
+ },
+
+ 'test standard cf with exclusive composite column slice':function(test, assert){
+ var values = [
+ new Helenus.Column([1, new Date(1)], 'a'),
+ new Helenus.Column([2, new Date(2)], 'b'),
+ new Helenus.Column([3, new Date(3)], 'c'),
+ new Helenus.Column([4, new Date(4)], 'd'),
+ new Helenus.Column([5, new Date(5)], 'e'),
+ new Helenus.Column([6, new Date(6)], 'f'),
+ new Helenus.Column([7, new Date(7)], 'g')
+ ],
+ key = [ 'comp_range_1', new Helenus.UUID('e491d6ac-b124-4795-9ab3-c8a0cf92615c') ];
+
+ cf_composite.insert(key, values, function(err){
+ assert.ifError(err);
+ var options = {
+ start: [[3, false]],
+ end: [[5, false]]
+ };
+
+ cf_composite.get(key, options, function(err, row){
+ assert.ifError(err);
+ assert.ok(row.count === 1);
+ assert.ok(row[0].name[0] === 4);
+ test.finish();
+ });
+ });
+ },
+
'test standard cf.get with custom CL':function(test, assert){
cf_standard.get(config.standard_row_key,
{ consistency : Helenus.ConsistencyLevel.ONE }, function(err, row){

0 comments on commit ca9edd8

Please sign in to comment.