cql-rb 1.0.0.pre8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +67 -8
- data/lib/cql/io/node_connection.rb +1 -1
- data/lib/cql/protocol/request.rb +2 -1
- data/lib/cql/version.rb +1 -1
- data/spec/cql/protocol/request_spec.rb +14 -2
- metadata +8 -5
data/README.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# Ruby CQL3 driver
|
2
2
|
|
3
|
-
_There has not yet been a stable release of this project._
|
4
|
-
|
5
3
|
[![Build Status](https://travis-ci.org/iconara/cql-rb.png?branch=master)](https://travis-ci.org/iconara/cql-rb)
|
6
4
|
|
7
5
|
# Requirements
|
@@ -10,11 +8,11 @@ Cassandra 1.2 with the native transport protocol turned on and a modern Ruby. Te
|
|
10
8
|
|
11
9
|
# Installation
|
12
10
|
|
13
|
-
gem install
|
11
|
+
gem install cql-rb
|
14
12
|
|
15
13
|
## Configure Cassandra
|
16
14
|
|
17
|
-
|
15
|
+
If you're running Cassandra 1.2.5 the native transport protocol is enabled by default, if you're running an earlier version (but later than 1.2) you must enable it by editing `cassandra.yaml` and setting `start_native_transport` to `true`.
|
18
16
|
|
19
17
|
# Quick start
|
20
18
|
|
@@ -25,12 +23,14 @@ client = Cql::Client.connect(host: 'cassandra.example.com')
|
|
25
23
|
client.use('system')
|
26
24
|
rows = client.execute('SELECT keyspace_name, columnfamily_name FROM schema_columnfamilies')
|
27
25
|
rows.each do |row|
|
28
|
-
puts "The keyspace #{row['keyspace_name']} has a table called #{row['columnfamily_name']}"
|
26
|
+
puts "The keyspace #{row['keyspace_name']} has a table called #{row['columnfamily_name']}"
|
29
27
|
end
|
30
28
|
```
|
31
29
|
|
32
30
|
when you're done you can call `#close` to disconnect from Cassandra. You can connect to multiple Cassandra nodes by passing multiple comma separated host names to the `:host` option.
|
33
31
|
|
32
|
+
# Usage
|
33
|
+
|
34
34
|
## Changing keyspaces
|
35
35
|
|
36
36
|
```ruby
|
@@ -117,7 +117,7 @@ At this time prepared statements are local to a single connection. Even if you c
|
|
117
117
|
|
118
118
|
# Consistency levels
|
119
119
|
|
120
|
-
The `#execute` method supports setting the desired consistency level for the statement:
|
120
|
+
The `#execute` (of `Client` and `PreparedStatement`) method supports setting the desired consistency level for the statement:
|
121
121
|
|
122
122
|
```ruby
|
123
123
|
client.execute('SELECT * FROM peers', :local_quorum)
|
@@ -144,14 +144,73 @@ This is just a driver for the Cassandra native CQL protocol, it doesn't really k
|
|
144
144
|
|
145
145
|
Read more about CQL3 in the [CQL3 syntax documentation](https://github.com/apache/cassandra/blob/cassandra-1.2/doc/cql3/CQL.textile) and the [Cassandra query documentation](http://www.datastax.com/docs/1.2/cql_cli/querying_cql).
|
146
146
|
|
147
|
+
# Troubleshooting
|
148
|
+
|
149
|
+
## I get "Deadlock detected" errors
|
150
|
+
|
151
|
+
This means that the driver's IO reactor has crashed hard. Most of the time it means that you're using a framework, server or runtime that forks and you call `Client.connect` in the parent process. Check the documentation and see if there's any way you can register to run some piece of code in the child process just after a fork.
|
152
|
+
|
153
|
+
This is how you do it in Resque:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
Resque.after_fork = proc do
|
157
|
+
# ...
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
and this is how you do it in Passenger:
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
165
|
+
if forked
|
166
|
+
# ...
|
167
|
+
end
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
in Unicorn you do it in the config file:
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
after_fork do |server, worker|
|
175
|
+
# ...
|
176
|
+
end
|
177
|
+
```
|
178
|
+
|
179
|
+
If your process does not fork and you still encounter deadlock errors, it might also be a bug. All IO is done is a dedicated thread, and if something happens that makes that thread shut down, Ruby will detect that the locks that the client code is waiting on can't be unlocked.
|
180
|
+
|
181
|
+
## I'm not getting all elements back from my list/set/map
|
182
|
+
|
183
|
+
There's a known issue with collections that get too big. The protocol uses a short for the size of collections, but there is no way for Cassandra to stop you from creating a collection bigger than 65536 elements, so when you do the size field overflows with strange results. The data is there, you just can't get it back.
|
184
|
+
|
185
|
+
## The error backtraces are weird
|
186
|
+
|
187
|
+
Yeah, sorry. All IO is asynchronous, and when an error is returned from Cassandra the call stack from when the request was issued is gone. `QueryError` has a `#cql` field that contains the CQL for the request that failed, hopefully that gives you enough information to understand where the error originated.
|
188
|
+
|
189
|
+
## Authentication doesn't work
|
190
|
+
|
191
|
+
Please open an issue. It should be working, but it's hard to write tests for, so there may be edge cases that aren't covered.
|
192
|
+
|
193
|
+
## I'm connecting to port 9160 and it doesn't work
|
194
|
+
|
195
|
+
Port 9160 is the old Thrift interface, the binary protocol runs on 9042. This is also the default port for cql-rb, so unless you've changed the port in `cassandra.yaml`, don't override the port.
|
196
|
+
|
197
|
+
## One of my Cassandra nodes crashed, and my application crashed, isn't Cassandra supposed to be fault tolerant?
|
198
|
+
|
199
|
+
Yes it is, and your data is probably safe. cql-rb is just not completely there yet. Ideally it should handle connectivity issues and just talk to the nodes it can talk to and reconnect when things get back to normal. It's on the roadmap.
|
200
|
+
|
201
|
+
## Something else is not working
|
202
|
+
|
203
|
+
Open an issue and I'll do my best to help you. Please include the gem version, Casandra version and Ruby version, and explain as much about what you're doing as you can, preferably the smallest piece of code that reliably triggers the problem.
|
204
|
+
|
147
205
|
# Known bugs & limitations
|
148
206
|
|
149
|
-
* There are still edge cases around connection errors, and there is no automatic reconnection.
|
150
|
-
* JRuby 1.6.8 is not supported, although it should be. The only known issue is that connection failures aren't handled gracefully.
|
151
207
|
* No automatic peer discovery.
|
208
|
+
* No automatic reconnection on connection failures.
|
209
|
+
* JRuby 1.6.8 and earlier is not supported, although it probably works fine. The only known issue is that connection failures aren't handled gracefully.
|
152
210
|
* Compression is not supported.
|
153
211
|
* Large results are buffered in memory until the whole response has been loaded, the protocol makes it possible to start to deliver rows to the client code as soon as the metadata is loaded, but this is not supported yet.
|
154
212
|
* There is no cluster introspection utilities (like the `DESCRIBE` commands in `cqlsh`).
|
213
|
+
* No support for request tracing.
|
155
214
|
|
156
215
|
## Copyright
|
157
216
|
|
data/lib/cql/protocol/request.rb
CHANGED
@@ -13,9 +13,10 @@ module Cql
|
|
13
13
|
|
14
14
|
def encode_frame(stream_id=0, buffer=ByteBuffer.new)
|
15
15
|
raise InvalidStreamIdError, 'The stream ID must be between 0 and 127' unless 0 <= stream_id && stream_id < 128
|
16
|
+
offset = buffer.bytesize
|
16
17
|
buffer << [1, 0, stream_id, opcode, 0].pack(Formats::HEADER_FORMAT)
|
17
18
|
write(buffer)
|
18
|
-
buffer.update(4, [(buffer.bytesize - 8)].pack(Formats::INT_FORMAT))
|
19
|
+
buffer.update(offset + 4, [(buffer.bytesize - offset - 8)].pack(Formats::INT_FORMAT))
|
19
20
|
buffer
|
20
21
|
end
|
21
22
|
end
|
data/lib/cql/version.rb
CHANGED
@@ -8,8 +8,20 @@ module Cql
|
|
8
8
|
describe Request do
|
9
9
|
describe '#encode_frame' do
|
10
10
|
it 'returns a rendered request frame for the specified channel' do
|
11
|
-
|
12
|
-
|
11
|
+
encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3)
|
12
|
+
encoded_frame.to_s.should == "\x01\x00\x03\x09\x00\x00\x00\x18\x00\x00\x00\x14SELECT * FROM things"
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'appends a rendered request frame to the specified buffer' do
|
16
|
+
buffer = ByteBuffer.new('hello')
|
17
|
+
encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3, buffer)
|
18
|
+
buffer.to_s.should == "hello\x01\x00\x03\x09\x00\x00\x00\x18\x00\x00\x00\x14SELECT * FROM things"
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns the specified buffer' do
|
22
|
+
buffer = ByteBuffer.new('hello')
|
23
|
+
encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3, buffer)
|
24
|
+
encoded_frame.should equal(buffer)
|
13
25
|
end
|
14
26
|
end
|
15
27
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cql-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Theo Hultberg
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A pure Ruby CQL3 driver for Cassandra
|
15
15
|
email:
|
@@ -108,9 +108,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
109
|
none: false
|
110
110
|
requirements:
|
111
|
-
- - ! '
|
111
|
+
- - ! '>='
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
version:
|
113
|
+
version: '0'
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
hash: -3274197899140325066
|
114
117
|
requirements: []
|
115
118
|
rubyforge_project:
|
116
119
|
rubygems_version: 1.8.23
|