simplereach / helenus Goto Github PK
View Code? Open in Web Editor NEWNodeJS Cassandra Driver
NodeJS Cassandra Driver
The user should be able to let the driver know what type of marshaller to use when storing data on the thrift side of the driver. This should override what the schema says.
Cassandra's IntegerType is implemented as arbitrary precision Java BigIntegers and DecimalType is implemented as arbitrary precision Java BigDecimals, see the documentation and the marshallers from the cassandra source:
How should this be handled in the node driver? For now (since I haven't had a use case yet) I'm ok with just using javascript numbers, but maybe we'll have to switch to something like node-bigint at some point? What do you thing?
We should probably allow mulitple connections per host. I'm open to ideas on implementation. What I had in mind was a parameter on ConnectionPool like connections_per_node
, that will tell the pool to open up N connections to each node. This may provide a performance increase and resiliency in high volume applications.
If Helenus is currently connected to an existing node and that node drops, the driver will bubble up the error. This error should be caught and the connection should be re-attempted until it reconnects. The driver should only throw if no connection to any node can be made or if all connections are lost.
Hi,
Would it be feasable to allow arrays as parameters?
This would allow for multi-get operations such as:
pool.cql('SELECT ?,? FROM Users WHERE user_id IN (?)', ['name', 'address', ['simong', 'johndoe'] ], function(err, results){
results.forEach(function(row) {
console.log(row.get('name').value + ' lives on ' + row.get('address').name);
});
});
The change is trivial of course but the impact might not be as some people are perhaps relying on this behaviour?
One line 111 in connection.js
replace the quote encapsulation by
return sanitized.join(',');
When calling Connection.cql()
like
var userControlledInput = "X'='ChoosenValue', 'ChoosenColumnName";
connection.cql("UPDATE MyColumnFamily SET '%s'='MyValue' WHERE KEY='MyKey';", [userControlledInput], cb);
the attacker could at least set arbitrary column names and values. I am not yet firm with cql semantics, so i am not providing a patch, but i guess single quotes (and backslashes) in the arguments needs to be escaped. Even better would be a server-side placeholder semantic.
The conversion from command and arguments to the cql that is sent to the server happens in connection.js
at:
if(args){
args.unshift(cmd);
cql = new Buffer(util.format.apply(this, args));
} else {
cql = new Buffer(cmd);
}
Could it be my cassandra.yaml? Looks like the delete test case is expecting "ghosts" but on my instance it is deleted appropriately.
I'm not sure why the bad user input test would be expected to pass. The single-quote is escaped to create the query:
SELECT foo FROM cql_test WHERE id='''foobar'
There is no row with that ID so it should be expected to return zero rows.
Let me know and I can fix these tests and submit a patch.
12:02:07 [doki_pen@nyan ~/src/helenus][master]$ npm test
[email protected] test /home/doki_pen/src/helenus
make test
NODE_PATH=lib/ node_modules/whiskey/bin/whiskey --real-time --scope-leaks --tests "test/units.js test/cql3.js test/cql2.js test/thrift.js"
/home/doki_pen/src/helenus/test/units.js
setUp [OK]
test uuid library [OK]
/home/doki_pen/src/helenus/test/cql3.js
setUp [OK]
test cql create keyspace [OK]
test cql use keyspace [OK]
test cql static CF create column family [OK]
test cql static CF update [OK]
test cql static CF update with no callback [OK]
test cql static CF select [OK]
test cql static CF select with bad user input [FAIL]
Exception
AssertionError: false == true
at Object.ok (/home/doki_pen/src/helenus/node_modules/whiskey/lib/assert.js:333:29)
at /home/doki_pen/src/helenus/test/cql3.js:72:12
at /home/doki_pen/src/helenus/test/cql3.js:14:7
at onReturn (/home/doki_pen/src/helenus/lib/connection.js:435:7)
at onReturn (/home/doki_pen/src/helenus/lib/connection.js:370:7)
at /home/doki_pen/src/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:80:11
at Object.recv_execute_cql_query (/home/doki_pen/src/helenus/lib/cassandra/Cassandra.js:6968:12)
at /home/doki_pen/src/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:83:36
at Socket. (/home/doki_pen/src/helenus/node_modules/helenus-thrift/lib/thrift/transport.js:70:9)
at Socket.emit (events.js:67:17)
test cql static CF count [OK]
test cql static CF error [OK]
test cql static CF count with gzip [OK]
test cql static CF delete [FAIL]
Exception
AssertionError: 0 === 1
at Object.strictEqual (/home/doki_pen/src/helenus/node_modules/whiskey/lib/assert.js:333:29)
at /home/doki_pen/src/helenus/test/cql3.js:116:16
at onReturn (/home/doki_pen/src/helenus/lib/connection.js:435:7)
at onReturn (/home/doki_pen/src/helenus/lib/connection.js:370:7)
at /home/doki_pen/src/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:80:11
at Object.recv_execute_cql_query (/home/doki_pen/src/helenus/lib/cassandra/Cassandra.js:6968:12)
at /home/doki_pen/src/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:83:36
at Socket. (/home/doki_pen/src/helenus/node_modules/helenus-thrift/lib/thrift/transport.js:70:9)
at Socket.emit (events.js:67:17)
at TCP.onread (net.js:367:14)
test cql static CF drop static column family [OK]
test cql dynamic CF create column family [OK]
test cql dynamic CF update 1 [OK]
test cql dynamic CF update 2 [OK]
test cql dynamic CF update 3 [OK]
test cql dynamic CF select by row [OK]
test cql dynamic CF by row and column [OK]
test cql dense composite CF create column family [OK]
test cql dense composite CF update 1 [OK]
test cql dense composite CF update 2 [OK]
test cql dense composite CF update 3 [OK]
test cql dense composite CF select by row [OK]
test cql dense composite CF by row and column [OK]
test cql sparse composite CF create column family [OK]
test cql sparse composite CF update 1 [OK]
test cql sparse composite CF update 2 [OK]
test cql sparse composite CF update 3 [OK]
test cql sparse composite CF select by row [OK]
test cql sparse composite CF by row and column [OK]
test cql drop keyspace [OK]
tearDown [OK]
/home/doki_pen/src/helenus/test/cql2.js
setUp [OK]
test cql create keyspace [OK]
test cql use keyspace [OK]
test cql create column family [OK]
test cql update [OK]
test cql update with no callback [OK]
test cql select [OK]
test cql select with bad user input [OK]
test cql count [OK]
test cql error [OK]
test cql count with gzip [OK]
test cql delete [OK]
test cql drop column family [OK]
test cql drop keyspace [OK]
test too many cql params [OK]
test too few cql params [OK]
tearDown [OK]
/home/doki_pen/src/helenus/test/thrift.js
setUp [OK]
test pool.connect without keyspace [OK]
test pool.close without keyspace [OK]
test pool.connect with keyspace [OK]
test pool.createKeyspace [OK]
test pool.use [OK]
test keyspace.createColumnFamily [OK]
test keyspace.createColumnFamily with composite type [OK]
test keyspace.createSuperColumnFamily [OK]
test keyspace.get [OK]
test keyspace.get composite [OK]
test keyspace.get supercolumn [OK]
test keyspace.get from cache [OK]
test keyspace.get from index [OK]
test keyspace.get invalid cf [OK]
test standard cf.insert [OK]
test standard cf.insert into composite cf [OK]
test standard cf.get [OK]
test standard cf.get for composite column family [OK]
test standard cf.get with options [OK]
test standard cf.get with columns names [OK]
test composite cf.get with columns names [OK]
test standard cf.get with error [OK]
test standard cf with Index [OK]
test standard cf with BytestType [OK]
test standard cf with LongType [OK]
test standard cf with IntegerType [OK]
test standard cf with UTF8Type [OK]
test standard cf with AsciiType [OK]
test standard cf with LexicalUUIDType [OK]
test standard cf with TimeUUIDType [OK]
test standard cf with FloatType [OK]
test standard cf with DoubleType [OK]
test standard cf with DateType [OK]
test standard cf with BooleanType [OK]
test standard cf with UUIDType [OK]
test row.nameSlice [OK]
test row.slice [OK]
test row.toString and row.inspect [OK]
test row.forEach [OK]
test standard cf remove column [OK]
test standard cf remove row [OK]
test standard cf truncate [OK]
test keyspace.dropColumnFamily [OK]
test pool.dropKeyspace [OK]
test pool.close [OK]
Ran 99 tests in 9.566s
Successes: 97
Failures: 2
Timeouts: 0
Skipped: 0
FAILED
Leaked Variables
units.js: no leaks detected
cql3.js: errno
cql2.js: errno
thrift.js: errno
make: *** [test] Error 2
npm ERR! [email protected] test: make test
npm ERR! sh "-c" "make test"
failed with 2
npm ERR!
npm ERR! Failed at the [email protected] test script.
npm ERR! This is most likely a problem with the helenus package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! make test
npm ERR! You can get their info via:
npm ERR! npm owner ls helenus
npm ERR! There is likely additional logging output above.
npm ERR!
npm ERR! System Linux 3.3.8-1-ARCH
npm ERR! command "node" "/home/doki_pen/nvm/v0.6.18/bin/npm" "test"
npm ERR! cwd /home/doki_pen/src/helenus
npm ERR! node -v v0.6.18
npm ERR! npm -v 1.1.21
npm ERR! code ELIFECYCLE
npm ERR! message [email protected] test: make test
npm ERR! message sh "-c" "make test"
failed with 2
npm ERR! errno {}
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/doki_pen/src/helenus/npm-debug.log
npm not ok
The Thrift interface currently does not support incrementing column families
Currently composite columns do not support slices very well the intended functionality should be similar to pycassa where give a set of composites like:
a:123, b:123, c:123, d:123
doing:
cf.get({ start: ['a'], end:['c'] ])
will return:
a:123, b:123,c:123
and doing an exclusive query
cf.get({ start: [['a', false]], end:[['c', false]] ])
will return
b:123
I'm trying to store a column value that contains double quotes, by substituting a placeholder using a string, e.g.,
var data = '{username: "bob"}';
pool.cql("INSERT INTO MyColumnFamily (id, data) VALUES ('1', %s)", [data], function(err){
...
the value that ends up being stored is this:
cqlsh:keyspace1> select * from MyColumnFamily where id = '1';
id | data
----+-----------------------
1 | {username: \\"bob\\"}
when what I really want is this:
cqlsh:keyspace1> select * from MyColumnFamily where id = '1';
id | data
----+-----------------------
1 | {username: "bob"}
there doesn't seem to be any way around this, unless I specify the value directly in the query (no substitution).
Might be related to issue #36
CQL select return result of 1 even if row is not present, this is due to KEY returned from cql request.
It would be nice if we make result transparent to number of rows returned ie considering only row which has column in it.
https://github.com/simplereach/helenus/blob/master/lib/connection.js#L444
res.rows.length=1;
{ key: '[email protected]',
columns:
[ { name: 'KEY',
value: '[email protected]',
timestamp: 18446744073709552000,
ttl: null } ] }
Row: Key: '[email protected]', ColumnCount: 0, Columns: [ '' ]
res.rows.length=1;
{ key: '[email protected]',
columns:
[ { name: 'KEY',
value: '[email protected]',
timestamp: 18446744073709552000,
ttl: null },
{ name: '_uid',
value: 'da394c47-8ef7-11e1-ba7f-bbdb9a24f338',
timestamp: 1335373096718000,
ttl: null },
{ name: 'email',
value: '[email protected]',
timestamp: 1335373096718001,
ttl: null },
{ name: 'password',
value: '40bd001563085fc35165329ea1ff5c5ecbdbbeef',
timestamp: 1335373096718003,
ttl: null },
{ name: 'verified',
value: '0',
timestamp: 1335374968062000,
ttl: null },
] }
Hello,
Is it possible to have the list of all the rows in a column family, in the Thrift style?
Thank you so much!!
Phil
We should integrate the tests with travis-ci, it seems to be gaining popularity.
As discussed in #29 throw an error whenever somebody tries to use SuperColumns.
The thrift interface currently does not support rowCount.
the tests are reporting a global variable leak of the variable errno
coming from the thift.js
test file.
after merging #70 and #72, we are now getting timeouts and double callbacks on connections.
$ make test
NODE_PATH=lib/ node_modules/whiskey/bin/whiskey --real-time --scope-leaks --tests "test/cql2.js test/cql3.js test/thriftHostPool.js test/thrift.js test/units.js"
/home/travis/builds/simplereach/helenus/test/cql2.js
set_cql_version not supported, unsetting cqlVersion
whiskey.common: test.finish in [bold]test a bad connection will return an error[/bold] has been called twice, possible double callback in your code! {"name":"test a bad connection will return an error"}
setUp [OK]
test a bad connection will return an error [OK]
test cql create keyspace [OK]
test cql use keyspace [OK]
test cql create column family [OK]
test cql create counter column family [OK]
test cql create reversed column family [OK]
test cql update [OK]
test cql update reversed [OK]
test cql update with no callback [OK]
test cql incr [OK]
test cql select [OK]
test cql select reversed [OK]
test cql select * [OK]
test cql select counter [OK]
test cql incr and select [OK]
test cql select with bad user input [OK]
test cql count [OK]
test cql error [OK]
test cql count with gzip [OK]
test cql delete [OK]
test cql drop column family [OK]
test cql drop keyspace [OK]
test too many cql params [OK]
test too few cql params [OK]
tearDown [OK]
timeout [TIMEOUT]
/home/travis/builds/simplereach/helenus/test/cql3.js
set_cql_version not supported, skipping CQL3 tests
/home/travis/builds/simplereach/helenus/test/thriftHostPool.js
whiskey.common: test.finish in [bold]test bad pool connect[/bold] has been called twice, possible double callback in your code! {"name":"test bad pool connect"}
setUp [OK]
test pool.connect without keyspace [OK]
test pool.close without keyspace [OK]
test pool.connect with keyspace [OK]
test bad pool connect [OK]
test pool.createKeyspace [OK]
test pool.use [OK]
test keyspace.createColumnFamily [OK]
test keyspace.createColumnFamily with composite type [OK]
test keyspace.createSuperColumnFamily [OK]
test keyspace.createCounterFamily [OK]
test keyspace.get [OK]
test keyspace.get composite [OK]
test keyspace.get supercolumn [OK]
test keyspace.get counter [OK]
test keyspace.get from cache [OK]
test keyspace.get from index [OK]
test keyspace.get invalid cf [OK]
test standard cf.insert [OK]
test standard cf.insert with custom CL [OK]
test standard cf.insert into composite cf [OK]
test counter cf.incr [OK]
test standard cf.get [OK]
test standard cf.get for composite column family [OK]
test standard cf.get with options [OK]
test standard cf.get with custom CL [OK]
test standard cf.get with columns names [OK]
test composite cf.get with columns names [OK]
test counter cf.get with columns names [OK]
test standard cf.get with error [OK]
test standard cf with Index [OK]
test standard cf with BytestType [OK]
test standard cf with LongType [OK]
test standard cf with IntegerType [OK]
test standard cf with UTF8Type [OK]
test standard cf with AsciiType [OK]
test standard cf with LexicalUUIDType [OK]
test standard cf with TimeUUIDType [OK]
test standard cf with FloatType [OK]
test standard cf with DoubleType [OK]
test standard cf with DateType [OK]
test standard cf with BooleanType [OK]
test standard cf with UUIDType [OK]
test row.nameSlice [OK]
test row.slice [OK]
test row.toString and row.inspect [OK]
test row.forEach [OK]
test standard cf remove column [OK]
test composite cf remove column [OK]
test standard cf remove row [OK]
test standard cf truncate [OK]
test keyspace.dropColumnFamily [OK]
test pool.dropKeyspace [OK]
test pool.close [OK]
tearDown [OK]
timeout [TIMEOUT]
/home/travis/builds/simplereach/helenus/test/thrift.js
whiskey.common: test.finish in [bold]test bad pool connect[/bold] has been called twice, possible double callback in your code! {"name":"test bad pool connect"}
setUp [OK]
test pool.connect without keyspace [OK]
test pool.close without keyspace [OK]
test pool.connect with keyspace [OK]
test bad pool connect [OK]
test pool.createKeyspace [OK]
test pool.use [OK]
test keyspace.createColumnFamily [OK]
test keyspace.createColumnFamily with composite type [OK]
test keyspace.createSuperColumnFamily [OK]
test keyspace.createCounterFamily [OK]
test keyspace.get [OK]
test keyspace.get composite [OK]
test keyspace.get supercolumn [OK]
test keyspace.get counter [OK]
test keyspace.get from cache [OK]
test keyspace.get from index [OK]
test keyspace.get invalid cf [OK]
test standard cf.insert [OK]
test standard cf.insert with custom CL [OK]
test standard cf.insert into composite cf [OK]
test counter cf.incr [OK]
test standard cf.get [OK]
test standard cf.get for composite column family [OK]
test standard cf.get with options [OK]
test standard cf.get with custom CL [OK]
test standard cf.get with columns names [OK]
test composite cf.get with columns names [OK]
test counter cf.get with columns names [OK]
test standard cf.get with error [OK]
test standard cf with Index [OK]
test standard cf with BytestType [OK]
test standard cf with LongType [OK]
test standard cf with IntegerType [OK]
test standard cf with UTF8Type [OK]
test standard cf with AsciiType [OK]
test standard cf with LexicalUUIDType [OK]
test standard cf with TimeUUIDType [OK]
test standard cf with FloatType [OK]
test standard cf with DoubleType [OK]
test standard cf with DateType [OK]
test standard cf with BooleanType [OK]
test standard cf with UUIDType [OK]
test row.nameSlice [OK]
test row.slice [OK]
test row.toString and row.inspect [OK]
test row.forEach [OK]
test standard cf remove column [OK]
test composite cf remove column [OK]
test standard cf remove row [OK]
test standard cf truncate [OK]
test keyspace.dropColumnFamily [OK]
test pool.dropKeyspace [OK]
test pool.close [OK]
tearDown [OK]
timeout [TIMEOUT]
/home/travis/builds/simplereach/helenus/test/units.js
setUp [OK]
test uuid library [OK]
---------------------------------------------------------------------------------
Ran 138 tests in 45.345s
Successes: 138
Failures: 0
Timeouts: 3
Skipped: 0
FAILED
Leaked Variables
cql2.js: errno
thriftHostPool.js: errno
thrift.js: errno
units.js: no leaks detected
make: *** [test] Error 3
Done. Build script exited with: 1
Running
pool.cql("UPDATE KeyValue SET value='?' WHERE key='?'", [value, key, 'additional field'], cb)
leads to a cql error, because 'additional field'
gets concatenated to the cql statement by util.format()
Created a column family cf1 with no columns defined and an unset cqlVersion.
Run the following CQL using helenus:
insert into cf1 (KEY, new3,new4) values ('test', 0, 1) ;
...and the following error is received:
{ [HelenusInvalidRequestException: Unknown identifier new3] name: 'HelenusInvalidRequestException' }
My understanding is that dynamic columns are supported in insert statements in CQL2, and the insert works fine in cqlsh. Would you expect the insert to work OK using helenus?
There are CQL 2/3 Errors in the 1.2.0~beta1 version of C*.
CQL2 times out during query execution.
CQL 3 has the following error when creating a keyspace using the "old style":
HelenusInvalidRequestException: line 1:89 mismatched input ':' expecting '='
at onReturn (/home/travis/builds/simplereach/helenus/lib/connection.js:355:23)
at /home/travis/builds/simplereach/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:80:11
at Object.recv_execute_cql_query (/home/travis/builds/simplereach/helenus/lib/cassandra/Cassandra.js:6956:12)
at /home/travis/builds/simplereach/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:83:36
at Socket.<anonymous> (/home/travis/builds/simplereach/helenus/node_modules/helenus-thrift/lib/thrift/transport.js:70:9)
at Socket.emit (events.js:67:17)
at TCP.onread (net.js:372:14)
Hi,
Given a CF with the following definition:
CfDef ({
keyspace : keyspaceName,
name : 'friends',
column_type : 'Standard',
comparator_type : 'UUIDType',
default_validation_class : 'UTF8Type',
key_validation_class : 'UUIDType',
column_metadata : [ ]
})
These are the statements I'm using and the results they give in CQLSH:
SELECT * FROM friends WHERE key = 'd6080750-83c2-11e1-b890-5765c53d0889';
KEY |
d6080750-83c2-11e1-b890-5765c53d0889 |
SELECT KEY, '7933d83b-1fce-4390-8903-6dde41ef04d3' FROM friends WHERE key = 'd6080750-83c2-11e1-b890-5765c53d0889';
KEY | 7933d83b-1fce-4390-8903-6dde41ef04d3 |
d6080750-83c2-11e1-b890-5765c53d0889 | None |
Using helenus, (1.) works and gives a row with no columns as you'd expect but (2.) results in the following error:
/home/ubuntu/node.js/gog/node_modules/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:90
throw e;
^
TypeError: Cannot read property 'length' of null
at new Buffer (buffer.js:234:37)
at /home/ubuntu/node.js/gog/node_modules/helenus/lib/marshal/deserializers.js:59:10
at new <anonymous> (/home/ubuntu/node.js/gog/node_modules/helenus/lib/row.js:34:33)
at onReturn (/home/ubuntu/node.js/gog/node_modules/helenus/lib/connection.js:351:19)
at onReturn (/home/ubuntu/node.js/gog/node_modules/helenus/lib/connection.js:283:7)
at /home/ubuntu/node.js/gog/node_modules/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:80:11
at Object.recv_execute_cql_query (/home/ubuntu/node.js/gog/node_modules/helenus/lib/cassandra/1.0/Cassandra.js:6592:12)
at /home/ubuntu/node.js/gog/node_modules/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:83:36
at Socket.<anonymous> (/home/ubuntu/node.js/gog/node_modules/helenus/node_modules/helenus-thrift/lib/thrift/transport.js:70:9)
at Socket.emit (events.js:67:17)
I added the following before line 34 in row.js to try and track the issue down:
if (!item.value) console.log('Attempting to deserialise null/undefined' );
And it gets printed directly before the error is thrown.
I've deleted my copy of helenus and fetched it again from npm to rule out any changes I made (when I was finding my way around earlier!) and the error still happens.
I've also tried changing the column name to various other UUIDs, both to ones that have never existed and ones that have been deleted but not compacted-away.
I'm going to "fix" the issue locally before the deserializer is called in row.js but thought I would raise an issue given that the root cause is likely to be elsewhere; perhaps somewhere in cassandra.js or cassandra_types.js which are far to big for me to go poking around in with limited understanding.
Thanks,
Daniel
https://github.com/simplereach/helenus/blob/master/Readme.md#rowforeach
The line; row.forEach(function(name,value,ts,tttl){
should be: row.forEach(function(name,value,ts,ttl){
Regards,
JC
Hi,
how is it possible to do a RangeSlicesQuery?
Regards,
Philippe
Hi!!
Thanks for your last answer.
Is it possible to remove a column in a row?
Best,
Philippe
The Thrift interface currently does not support counting columns in slice queries
cf.insert 'test-row', {'test-col3': new Buffer [0, 0xFF, 0x20]}, (e) ->
cf.get 'test-row', (e, row) ->
console.log row.get('test-col3')
โ
{ name: <Buffer 74 65 73 74 2d 63 6f 6c 33>,
value: <Buffer 00 fd 20>,
timestamp: Thu, 15 Jan 1970 08:48:08 GMT,
ttl: null }
With pycassa, I confirmed that the value saved is 00 FD 20
I know this sounds silly, but is there a way to escape question marks in CQL statements?
Yes, I agree that I should be using parameterized queries but, without going into details, that would be a challenge in my current environment.
Many thanks,
-- Doug
It would be nice to be able to write CQL queries like
conn.cql('UPDATE users SET name = ?, age = ?, hometown = ? WHERE id = ?', ['Chris', 54, 'NYC', 100]);
Which should be translated to the following CQL string by the driver:
UPDATE users SET name = 'Chris', age = 54, hometown = 'NYC' WHERE id = 100
To make things simpler we could also just put single quotes around any unquoted placeholder.
The following line:
cf.get('foo', {consistency:Helenus.ConsistencyLevel.ONE} function(err, row){
from sample code in [https://github.com/simplereach/helenus#thrift]
throws this exception:
node_modules/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:90
throw e;
^
ReferenceError: Helenus is not defined
here is a simple patch that fixes it:
diff --git a/Readme.md b/Readme.md
index 17d6885..70ad57a 100644
--- a/Readme.md
+++ b/Readme.md
@@ -96,7 +96,7 @@ If you do not want to use CQL, you can make calls using the thrift dri
//get what we just put in
//the driver will return a Helenus.Row object just like CQL
- cf.get('foo', {consistency:Helenus.ConsistencyLevel.ONE} function(err, row){
+ cf.get('foo', {consistency:helenus.ConsistencyLevel.ONE} function(err, row){
if(err){
throw(err);
}
The current testing framework is using whiskey, the once problem is that setup and teardowns need to be in the test file. This is making the test files get out of hand. I recommend going to Mocha, the only requirement that I have is that is is not BDD and the it supports code coverage.
Tests are failing for delete
and select by row
using C* 1.1.0~rc1 for details see: http://travis-ci.org/#!/simplereach/helenus/jobs/1139784
As we are a driver, we need to strive for 100% test coverage. This should be completed before published the 1.0.0 version.
We should support creating CounterColumns in CounterColumn CFs, we should also probably do some checking to ensure that bad queries are trying to be run on CounterColumn CFs and counts aren't trying to be done on Standard CFs.
I'd like to be able to set values with an expiration, similar to the way that the java or python clients work.
Something like:
cf.insert('foo', { bar : 'baz' }, { ttl : 4000 }, callback);
I think I ran across this problem earlier today in our cassandra cluster.
The new onConnect
method waits until all the callbacks in the pool have completed before returning the keyspace.
However, if you have one node which is down, it will generally be the one at the end, which then gets called back last without a keyspace.
Ideally, I'd like to have the first good connection callback immediately, but as @hpainter notes dcf4a09, it complicates use
call. I'm not sure of a way around it right at this moment, but I'll think on it for a couple days. I submitted a fix which should work and doesn't break the tests. Let me know if you guys have thoughts.
The Thrift interface currently does not support truncating a CF.
Hi,
When I do "cf.insert('foo', {'bar':'baz'}, function(err){})", the timestamp linked to this column is undefined (1970-01-16 10:43:07.898).
Why doesn't it the actual time?
Regards,
Philippe
Row keys don't seem to deserialize properly when executing CQL queries
Even though it is considered bad practice, we should probably fully support SuperColumns
Hi,
When I try to SELECT like this :
pool.cql("SELECT * FROM '%s' WHERE KEY = '%s'", ['cfTest','rowTest'], function(err, results){
console.log('CQL RESULTS : ');
console.log(err, results);
});
I get this error :
HelenusInvalidRequestException: cannot parse 'rowTest' as hew bytes.
Thank you,
Phil
Tests are failing on 1.1.1, it seems to be an issue with thrift, not sure if we need to recompile or not:
Exception
161TypeError: Cannot read property 'length' of undefined
162 at Object.read (/home/vagrant/builds/simplereach/helenus/lib/cassandra/cassandra_types.js:3258:29)
163 at Object.read (/home/vagrant/builds/simplereach/helenus/lib/cassandra/cassandra_types.js:3444:21)
164 at Object.read (/home/vagrant/builds/simplereach/helenus/lib/cassandra/Cassandra.js:5163:22)
165 at Object.recv_execute_cql_query (/home/vagrant/builds/simplereach/helenus/lib/cassandra/Cassandra.js:6977:10)
166 at /home/vagrant/builds/simplereach/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:83:36
167 at Socket.<anonymous> (/home/vagrant/builds/simplereach/helenus/node_modules/helenus-thrift/lib/thrift/transport.js:70:9)
168 at Socket.emit (events.js:67:17)
169 at TCP.onread (net.js:367:14)
I have an app where I'd like to maintain availability even when I can't connect to my cassandra cluster. The rest of the app can try to make requests to the DB, and on a failure I can just put messages in a queue to be processed later.
Currently when there are no hosts available, the pool will emit an error but then proceed to throw an uncaught exception caused by accessing a property of an undefined var.
From the Pool
connection code:
Pool.prototype.getConnection = function(){
var len = this.clients.length,
rnd = Math.floor(Math.random() * len),
host = this.clients[rnd];
if (!host){
this.emit('error', new Error('No Available Connections'));
}
if (host.ready){ // causes exception!!
return host;
} else {
...
}
I'd like to convert this to look more like the other query functions where if the database is unavailable for any reason, I will get an unavailable exception on querying. My app can then choose whether to re-connect in the pool and how to handle the failure.
Anything I'm missing here?
I'd suggest using the debian packages from http://www.apache.org/dist/cassandra/debian/pool/main/c/cassandra/ for CI.
They run smoothly under ubuntu and they will put all output to /var/log/cassandra/
so it won't mix up with the actual test output. If we're interested in the cassandra output for debugging purposes we can still cat
the log files after the test suite has run.
With 1.1.1 CQL-queries don't return range ghosts any more, see https://issues.apache.org/jira/browse/CASSANDRA-3982
Probably we'll have to change the tests accordingly: https://github.com/simplereach/helenus/blob/master/test/cql3.js#L100-125
I've seen you have added travis-ci, which is great! What about adding some linting to enforce consistent code style? I'm usually using the following make targets to achieve that:
test: jshint gjslint
# start testsuite here
JSHINT = node_modules/jshint/bin/hint {lib,test,bin}/**/*.js \
--config share/jshint-config.json
jshint:
@shopt -s globstar && echo '$(JSHINT)' && $(JSHINT)
gjslint:
gjslint --debug_indentation --nojsdoc --unix_mode \
-e test/fixtures \
-r lib -r test -r bin
Here's the jshint-config. It's tuned to follow the Google Javascript Style-Guide.
I have cqlVersion : '3.0.0' set for my pool. I take my C* server down and bring it back up, and a new connection is established, initiated by checkDead(). However, the connect() function used for this does not set the cqlVersion (and so subsequent queries fail). The patch below will fix the problem, however, there might be a better fix that reuses the code for creating connections.
--- helenus.orig/lib/pool.js 2012-05-14 10:43:47.000000000 -0700
+++ helenus/lib/pool.js 2012-05-14 10:45:34.000000000 -0700
@@ -234,7 +234,8 @@ Pool.prototype.monitorConnections = func
keyspace: self.keyspace,
user: self.user,
password: self.password,
- timeout: self.timeout
+ timeout: self.timeout,
+ cqlVersion: self.cqlVersion
});
connection.on('error', function(err){
The following CQL works in cqlsh -3
CREATE KEYSPACE test WITH strategy_class='NetworkTopologyStrategy' AND strategy_options:"us-east"=2
but not via Helenus, which raises the error
{ [HelenusInvalidRequestException: line 1:105 no viable alternative at character '"'] name: 'HelenusInvalidRequestException' }
Quotes have been allowed since CASSANDRA-4278.
Created a table and updated the counter column using the following CQL:
CREATE TABLE testcount (key varchar PRIMARY KEY, cnt counter)
UPDATE testcount SET cnt=cnt+1 WHERE key=1
Then reading the value using:
pool.cql('SELECT cnt FROM testcount', [], function(err, results){
console.log(results[0].get('cnt'));
});
..gives the following result:
{ name: 'cnt',
value: '\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0004',
timestamp: Fri, 16 Jan 1970 12:43:53 GMT,
ttl: null }
Is this as expected? I would have thought that the counter value would be returned as an integer whereas it looks like some kind of Buffer. Have tried the core buffer methods but they don't return anything sensible. Running the query in CQLSH shows an integer.
Cassandra 1.1 adds support for prepared CQL queries. These should be supported by helenus as well.
The underlying thrift calls are:
CassandraClient.prototype.prepare_cql_query = function(query, compression, callback) {}
CassandraClient.prototype.execute_prepared_cql_query = function(itemId, values, callback) {}
If nobody else has already looked into that I'll try to provide a patch soonish.
I have a CF and its column type is 'UTF8(reversed=true)'. The schema is as follows
create column family CF
with column_type = 'Standard'
and comparator = 'UTF8Type(reversed=true)'
and default_validation_class = 'UTF8Type'
and key_validation_class = 'UTF8Type';
While I'm using the Helenus cql() function such as 'select * from CF', an exception 'TypeError: Cannot read property 'ser' of undefined' occurs. The error stack is as follows:
/node_modules/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:90
throw e;
^
TypeError: Cannot read property 'ser' of undefined
at getSerializer (/node_modules/helenus/lib/marshal/index.js:179:23)
at new Marshal (/node_modules/helenus/lib/marshal/index.js:223:20)
at new Row (/node_modules/helenus/lib/row.js:15:32)
at onReturn (/node_modules/helenus/lib/connection.js:433:19)
at onReturn (/node_modules/helenus/lib/connection.js:370:7)
at exports.Connection.connection.addListener.self.transport.receiver.client._reqs.(anonymous function) (/node_modules/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:80:11)
at Object.CassandraClient.recv_execute_cql_query (/node_modules/helenus/lib/cassandra/Cassandra.js:6968:12)
at exports.Connection (/Users/neil/Documents/work/java/HinewsNode/node_modules/helenus/node_modules/helenus-thrift/lib/thrift/connection.js:83:37)
at Socket.TFramedTransport.receiver (/node_modules/helenus/node_modules/helenus-thrift/lib/thrift/transport.js:70:9)
I tried to trace the source, and found the problem is the string passed to parseTypeString() in '/lib/marshal/index.js' is only 'ReversedType', instead of 'ReversedType(org.apache.cassandra.db.marshal.UTF8Type)' where I can see it with cassandra-cli. As a result, the parseTypeString() function parsed my type from 'ReversedType' to 'ReversedTyp' due to the condition Line 94 in '/lib/marshal/index.js'.
I could only trace to here and have no idea to go further.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.