cql-rb 2.0.0.rc0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +38 -33
- data/lib/cql/time_uuid.rb +21 -7
- data/lib/cql/version.rb +1 -1
- data/spec/cql/time_uuid_spec.rb +10 -6
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fddc76ac77bf418eab2dfd497c342b5104481a99
|
4
|
+
data.tar.gz: f8b91abc145bf42ff716fb0af17b50d3a24b19cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8af6c7c7acc157843d1f0f0c101a2a42da30e8f0433f7d53f870a1ceadbf233416dfa2254af425a35ecc6a3c8aa2b6a54e4ad82c3cb0b342526d792e9b7ea06d
|
7
|
+
data.tar.gz: 7f3472cda89cccb1674424a7bcef58bd52cdaacfa579eba56c83c6dbf2d826b4fe2ca0707c8b94eff2009e6b6377f514655ba49c8a80286adacb4b691c8c3185
|
data/README.md
CHANGED
@@ -134,10 +134,14 @@ The driver supports prepared statements. Use `#prepare` to create a statement ob
|
|
134
134
|
|
135
135
|
```ruby
|
136
136
|
statement = client.prepare('SELECT date, description FROM events WHERE id = ?')
|
137
|
-
|
137
|
+
|
138
|
+
[123, 234, 345].each do |id|
|
139
|
+
rows = statement.execute(id)
|
140
|
+
# ...
|
141
|
+
end
|
138
142
|
```
|
139
143
|
|
140
|
-
A prepared statement can be run many times, but the CQL parsing will only be done once. Use prepared statements for queries you run over and over again.
|
144
|
+
A prepared statement can be run many times, but the CQL parsing will only be done once on each node. Use prepared statements for queries you run over and over again.
|
141
145
|
|
142
146
|
`INSERT`, `UPDATE`, `DELETE` and `SELECT` statements can be prepared, other statements may raise `QueryError`.
|
143
147
|
|
@@ -190,28 +194,6 @@ client.batch(:counter) do |batch|
|
|
190
194
|
end
|
191
195
|
```
|
192
196
|
|
193
|
-
You can also specify the regular options such as consistency, timeout and whether or not to enable tracing:
|
194
|
-
|
195
|
-
```ruby
|
196
|
-
client.batch(:unlogged, trace: true) do |batch|
|
197
|
-
# ...
|
198
|
-
end
|
199
|
-
|
200
|
-
client.batch(trace: true, consistency: :all) do |batch|
|
201
|
-
# ...
|
202
|
-
end
|
203
|
-
|
204
|
-
batch = client.batch
|
205
|
-
# ...
|
206
|
-
batch.execute(consistency: :quorum)
|
207
|
-
|
208
|
-
batch = client.batch(trace: true)
|
209
|
-
# ...
|
210
|
-
batch.execute(consistency: :quorum)
|
211
|
-
```
|
212
|
-
|
213
|
-
As you can see you can specify the options either when creating the batch or when sending it (when using the variant where you call `#execute` yourself). The options given to `#execute` take precedence. You can omit the batch type and specify the options as the only parameter when you want to use the the default batch type.
|
214
|
-
|
215
197
|
If you want to execute the same prepared statement multiple times in a batch there is a special variant of the batching feature available from `PreparedStatement`:
|
216
198
|
|
217
199
|
```ruby
|
@@ -247,19 +229,28 @@ You can specify the default consistency to use when you create a new `Client`:
|
|
247
229
|
client = Cql::Client.connect(hosts: %w[localhost], default_consistency: :all)
|
248
230
|
```
|
249
231
|
|
250
|
-
The `#execute` (of `Client` and `
|
232
|
+
The `#execute` (of `Client`, `PreparedStatement` and `Batch`) method also supports setting the desired consistency level on a per-request basis:
|
251
233
|
|
252
234
|
```ruby
|
253
|
-
client.execute('SELECT * FROM
|
254
|
-
```
|
235
|
+
client.execute('SELECT * FROM users', consistency: :local_quorum)
|
255
236
|
|
256
|
-
|
237
|
+
statement = client.prepared('SELECT * FROM users')
|
238
|
+
statement.execute(consistency: :one)
|
257
239
|
|
258
|
-
|
259
|
-
|
240
|
+
batch = client.batch
|
241
|
+
batch.add("UPDATE users SET email = 'sue@foobar.com' WHERE id = 'sue'")
|
242
|
+
batch.add("UPDATE users SET email = 'tom@foobar.com' WHERE id = 'tom'")
|
243
|
+
batch.execute(consistency: :all)
|
244
|
+
|
245
|
+
batch = client.batch(consistency: :quorum) do |batch|
|
246
|
+
batch.add("UPDATE users SET email = 'sue@foobar.com' WHERE id = 'sue'")
|
247
|
+
batch.add("UPDATE users SET email = 'tom@foobar.com' WHERE id = 'tom'")
|
248
|
+
end
|
260
249
|
```
|
261
250
|
|
262
|
-
|
251
|
+
For batches the options given to `#execute` take precedence over options given to `#batch`.
|
252
|
+
|
253
|
+
The possible values for consistency are:
|
263
254
|
|
264
255
|
* `:any`
|
265
256
|
* `:one`
|
@@ -300,6 +291,20 @@ client = Cql::Client.connect(logger: Logger.new($stderr))
|
|
300
291
|
|
301
292
|
Most of the logging will be when the driver connects and discovers new nodes, when connections fail and so on, but also when statements are prepared. The logging is designed to not cause much overhead and only relatively rare events are logged (e.g. normal requests are not logged).
|
302
293
|
|
294
|
+
## Tracing
|
295
|
+
|
296
|
+
You can request that Cassandra traces a request and records what each node had to do to process the request. To request that a query is traced you can specify the `:trace` option to `#execute`. The request will proceed as normal, but you will also get a trace ID back in your response. This ID can then be used to load up the trace data:
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
result = client.execute("SELECT * FROM users", trace: true)
|
300
|
+
session_result = client.execute("SELECT * FROM system_traces.sessions WHERE session_id = ?", result.trace_id, consistency: :one)
|
301
|
+
events_result = client.execute("SELECT * FROM system_traces.events WHERE session_id = ?", result.trace_id, consistency: :one)
|
302
|
+
```
|
303
|
+
|
304
|
+
Notice how you can query tables in other keyspaces by prefixing their names with the keyspace name.
|
305
|
+
|
306
|
+
The `system_traces.sessions` table contains information about the request itself; which node was the coordinator, the CQL, the total duration, etc. (if the `duration` column is `null` the trace hasn't been completely written yet and you should load it again later). The `events` table contains information about what happened on each node and at what time. Note that each event only contains the number of seconds that elapsed from when the node started processing the request – you can't easily sort these events in a global order.
|
307
|
+
|
303
308
|
## Thread safety
|
304
309
|
|
305
310
|
Except for results and batches everything in cql-rb is thread safe. You only need a single client object in your application, in fact creating more than one is a bad idea. Similarily prepared statements are thread safe and should be shared.
|
@@ -370,7 +375,7 @@ Please open an issue. It should be working, but it's hard to set up and write au
|
|
370
375
|
|
371
376
|
If you are using DataStax Enterprise earlier than 3.1 authentication is unfortunately not supported. Please open an issue and we might be able to get it working, I just need someone who's willing to test it out. DataStax backported the authentication from Cassandra 2.0 into DSE 3.0, even though it only uses Cassandra 1.2. The authentication logic might not be able to handle this and will try to authenticate with DSE using an earlier version of the protocol. In short, DSE before 3.1 uses a non-standard protocol, but it should be possible to get it working. DSE 3.1 and 4.0 have been confirmed to work.
|
372
377
|
|
373
|
-
## I'm connecting to port 9160 and it doesn't work
|
378
|
+
## I get "end of file reached" / I'm connecting to port 9160 and it doesn't work
|
374
379
|
|
375
380
|
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.
|
376
381
|
|
@@ -410,7 +415,7 @@ Compression works best for large requests, so if you use batching you should ben
|
|
410
415
|
|
411
416
|
# Try experimental features
|
412
417
|
|
413
|
-
To get maximum performance you can't wait for a request to complete before sending the next. At it's core cql-rb embraces this completely and uses non-blocking IO and
|
418
|
+
To get maximum performance you can't wait for a request to complete before sending the next. At it's core cql-rb embraces this completely and uses non-blocking IO and an asynchronous model for the request processing. The synchronous API that you use is just a thin façade on top that exists for convenience. If you need to scale to thousands of requests per second, have a look at the client code and look at the asynchronous core, it works very much like the public API, _but using it they should be considererd **experimental**_. Experimental in this context does not mean buggy, it is the core of cql-rb after all, but it means that you cannot rely on it being backwards compatible.
|
414
419
|
|
415
420
|
# Changelog & versioning
|
416
421
|
|
data/lib/cql/time_uuid.rb
CHANGED
@@ -11,21 +11,35 @@ module Cql
|
|
11
11
|
# @return [Time]
|
12
12
|
#
|
13
13
|
def to_time
|
14
|
-
|
15
|
-
t = 0
|
16
|
-
t |= (n & 0x0000000000000fff) << 48
|
17
|
-
t |= (n & 0x00000000ffff0000) << 16
|
18
|
-
t |= (n & 0xffffffff00000000) >> 32
|
19
|
-
t -= GREGORIAN_OFFSET
|
14
|
+
t = time_bits - GREGORIAN_OFFSET
|
20
15
|
seconds = t/10_000_000
|
21
16
|
microseconds = (t - seconds * 10_000_000)/10.0
|
22
17
|
Time.at(seconds, microseconds).utc
|
23
18
|
end
|
24
19
|
|
25
20
|
def <=>(other)
|
26
|
-
self.
|
21
|
+
c = self.time_bits <=> other.time_bits
|
22
|
+
return c unless c == 0
|
23
|
+
(self.value & LOWER_HALF_MASK) <=> (other.value & LOWER_HALF_MASK)
|
27
24
|
end
|
28
25
|
|
26
|
+
protected
|
27
|
+
|
28
|
+
def time_bits
|
29
|
+
n = (value >> 64)
|
30
|
+
t = 0
|
31
|
+
t |= (n & 0x0000000000000fff) << 48
|
32
|
+
t |= (n & 0x00000000ffff0000) << 16
|
33
|
+
t |= (n & 0xffffffff00000000) >> 32
|
34
|
+
t
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
LOWER_HALF_MASK = 0xffffffff_ffffffff
|
40
|
+
|
41
|
+
public
|
42
|
+
|
29
43
|
# A UUID version 1, variant 1 generator. It can generate a sequence of UUIDs
|
30
44
|
# with reasonable uniqueness guarantees:
|
31
45
|
#
|
data/lib/cql/version.rb
CHANGED
data/spec/cql/time_uuid_spec.rb
CHANGED
@@ -14,14 +14,18 @@ module Cql
|
|
14
14
|
end
|
15
15
|
|
16
16
|
describe '#<=>' do
|
17
|
+
let :generator do
|
18
|
+
TimeUuid::Generator.new
|
19
|
+
end
|
20
|
+
|
17
21
|
let :uuids do
|
18
22
|
[
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
generator.from_time(Time.utc(2014, 5, 1, 2, 3, 4, 1), 0),
|
24
|
+
generator.from_time(Time.utc(2014, 5, 1, 2, 3, 4, 2), 0),
|
25
|
+
generator.from_time(Time.utc(2014, 5, 1, 2, 3, 5, 0), 0),
|
26
|
+
generator.from_time(Time.utc(2014, 5, 11, 14, 3, 4, 0), 0),
|
27
|
+
generator.from_time(Time.utc(2014, 5, 20, 2, 3, 4, 0), 0),
|
28
|
+
generator.from_time(Time.utc(2014, 6, 7, 2, 3, 4, 0), 0),
|
25
29
|
]
|
26
30
|
end
|
27
31
|
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cql-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Theo Hultberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ione
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1'
|
27
27
|
description: A pure Ruby CQL3 driver for Cassandra
|
28
28
|
email:
|
29
29
|
- theo@iconara.net
|
@@ -163,9 +163,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
163
|
version: 1.9.3
|
164
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
165
|
requirements:
|
166
|
-
- - '
|
166
|
+
- - '>='
|
167
167
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
168
|
+
version: '0'
|
169
169
|
requirements: []
|
170
170
|
rubyforge_project:
|
171
171
|
rubygems_version: 2.2.1
|