Skip to content

Loading…

feat: adds Date support to escapeCQL function #131

Merged
merged 6 commits into from

2 participants

@tim-dev

Just allows for handling of the Date object.

@devdazed
SimpleReach member

hey thanks! lets write some tests for it, then I think it will be good to merge.

@tim-dev

Cool, will do. I'm thinking pre-1970 date, current date, and future date. Should we worry about invalid dates or leave that to the developer?

@devdazed
SimpleReach member

i think we should check for an invalid date, C* may not like the response given by one

> d = new Date('asdfsg')
Invalid Date
> d instanceof Date
true
> d.getTime()
NaN
@tim-dev

I can verify that C* doesn't want a NaN. I'll have it throw if getTime returns a NaN.

@tim-dev

Ok, I think that'll do it. Had to use an ISO date string rather than an integer because C* < 2 complained about negative integers being invalid.

@devdazed
SimpleReach member

Interesting, is there a reason why toISOString() didn't work? also, from the looks of it, this will limit the resolution to the second rather than the millisecond?

@tim-dev

After some more in-depth research, here are the major hurdles:

My third commit had different logic for negative pre-epoch times, and tried to use toISOString(), but that failed with an unable to coerce to a formatted date error in all C* versions due to the patterns mentioned above.

As the date string loses millisecond precision, I'm thinking it should use getTime() for all but the pre-epoch dates, which I assume no longer care about millisecond precision. To get fully smart, it could examine the C* version and only use the date format for earlier versions. Do you happen to know off the top of your head how to check the C* version here, or if that's even reasonable?

@tim-dev

I commited a change that uses the long unless it's negative. Let me know if that passes muster.

@devdazed devdazed merged commit 5905031 into simplereach:master

1 check passed

Details default The Travis CI build passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Showing with 48 additions and 0 deletions.
  1. +22 −0 lib/connection.js
  2. +19 −0 test/cql3.js
  3. +7 −0 test/helpers/cql3.json
View
22 lib/connection.js
@@ -16,6 +16,10 @@ var util = require('util'),
* @memberOf Connection
*/
var NOOP = function(){};
+/**
+ * Adds zero left-padding to numbers, when necessary
+ */
+var zero_pad = function(n){ return n < 10 ? "0" + n : n }
/**
* Default port for cassandra
@@ -102,6 +106,24 @@ function escapeCQL(val) {
return val.toString();
}
+ if(val instanceof Date){
+ _val = val.getTime()
+ if(isNaN(_val)){
+ throw errors.create(new Error('Invalid Date'));
+ }
+ // C* < 2.0.2 doesn't work with negative longs
+ if(_val<0){
+ return "'" + val.getUTCFullYear()
+ + '-' + zero_pad(val.getUTCMonth() + 1)
+ + '-' + zero_pad(val.getUTCDate())
+ + ' ' + zero_pad(val.getUTCHours())
+ + ':' + zero_pad(val.getUTCMinutes())
+ + ':' + zero_pad(val.getUTCSeconds())
+ + "'"
+ }
+ return _val
+ }
+
if(typeof val === 'number' || typeof val === 'boolean'){
return val.toString();
}
View
19 test/cql3.js
@@ -67,6 +67,14 @@ function testResultless(){
return testCql.apply(testCql, args);
}
+function makeDates(dates_array){
+ var ret = [], i = 0, len = dates_array.length;
+ for(i;i<len;i++){
+ ret.push(new Date(dates_array[i]));
+ }
+ return ret;
+}
+
module.exports = {
'setUp':function(test, assert){
Helenus = require('helenus');
@@ -293,6 +301,17 @@ module.exports = {
assert.strictEqual(res[0].get('varnumber').value, -8388607);//test a 3 byte-long variable integer
}),
+ 'test cql timestamp create table':testResultless(config['timestamp_create']),
+ 'test cql timestamp update1':testResultless(config['timestamp_update#cql'], makeDates(config['timestamp_update#vals1'])),
+ 'test cql timestamp update2':testResultless(config['timestamp_update#cql'], makeDates(config['timestamp_update#vals2'])),
+ 'test cql timestamp update3':testResultless(config['timestamp_update#cql'], makeDates(config['timestamp_update#vals3'])),
+ 'test cql timestamp invalid date': function(test, assert) {
+ assert.throws(function(){
+ conn.cql(config['timestamp_invalid#cql'], makeDates(config['timestamp_invalid#vals']))
+ }, Error)
+ test.finish();
+ },
+
'test cql drop keyspace':testResultless(config['drop_ks#cql']),
'tearDown':function(test, assert){
View
7 test/helpers/cql3.json
@@ -51,6 +51,13 @@
"integers_select2#cql" : "SELECT * FROM integers where number = -1",
"integers_select3#cql" : "SELECT * FROM integers where number = -2",
+ "timestamp_create" : "CREATE TABLE timestamps (ts1 timestamp, ts2 timestamp, PRIMARY KEY (ts1))",
+ "timestamp_update#cql" : "UPDATE timestamps SET ts2 = ? WHERE ts1 = ?",
+ "timestamp_update#vals1" : [null, null],
+ "timestamp_update#vals2" : [null, "2100-01-01"],
+ "timestamp_update#vals3" : [null, "1969-07-20"],
+ "timestamp_invalid#cql" : "UPDATE timestamps SET ts2 = ? ts1 old = ?",
+ "timestamp_invalid#vals" : [null, "THIS ISNT A DATE"],
"prepare#cql" : "SELECT * FROM ? WHERE KEY = ?",
"error#cql" : "SOME INVALID CQL"
Something went wrong with that request. Please try again.