cassandra-driver 3.0.0.rc.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +30 -20
- data/lib/cassandra.rb +39 -7
- data/lib/cassandra/cluster.rb +14 -3
- data/lib/cassandra/cluster/client.rb +60 -30
- data/lib/cassandra/cluster/metadata.rb +1 -1
- data/lib/cassandra/cluster/options.rb +1 -3
- data/lib/cassandra/driver.rb +4 -5
- data/lib/cassandra/index.rb +22 -8
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +19 -1
- data/lib/cassandra/load_balancing/policies/round_robin.rb +7 -0
- data/lib/cassandra/load_balancing/policies/token_aware.rb +7 -0
- data/lib/cassandra/load_balancing/policies/white_list.rb +7 -0
- data/lib/cassandra/protocol/cql_byte_buffer.rb +0 -4
- data/lib/cassandra/protocol/requests/batch_request.rb +1 -1
- data/lib/cassandra/protocol/requests/execute_request.rb +1 -1
- data/lib/cassandra/protocol/requests/query_request.rb +1 -1
- data/lib/cassandra/session.rb +3 -1
- data/lib/cassandra/table.rb +5 -5
- data/lib/cassandra/timestamp_generator.rb +37 -0
- data/lib/cassandra/timestamp_generator/simple.rb +38 -0
- data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
- data/lib/cassandra/util.rb +135 -2
- data/lib/cassandra/version.rb +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YjE4OWU5NjliOWY2YjgwM2RkMzJlNmMyZWU0YzdlOWFlYzNkYjUxOQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
M2E5YTgyMTllNTg2ZGI2NjgyN2VjZTJmN2Q0MGI4ZDAwNGU1YjkxMw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZTBmMzYzMTQwMDEwYTQ4YjljNmNhMWQwMGI0ZWZjYTVlOTczMjkxNzUzNTMz
|
10
|
+
YzY5MzhjNjUyMjc2Mjc2NGVhODE4NDYwOTRiOTViZWY5MGE4YmQ1NTg1MGY0
|
11
|
+
MTYwZDgwZDg2MDQzNTViNmI0NDk2ZWRjMWRhMWMxZTQ5MTVkODQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZmQ5MGM4ZTI1ZTFmN2QzNjE5OGNmNjg4MzVmZTJkYjM0NTM0MzI4MWIxNGJk
|
14
|
+
MDY3NTRmOWQ0YWM5NWUzY2Q2NTFmOWIwOGExZDI5MWQ0ODIyOWVmMjVkNjll
|
15
|
+
MGRhMWJkOGExZThlNWQzOWMzYTE1YzZmNTM5YWJjZmNhMTllNWE=
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Datastax Ruby Driver for Apache Cassandra
|
2
2
|
|
3
|
-
*If you're reading this on GitHub, please note that this is the readme for the development version and that some features described here might not yet have been released. You can [find the documentation for latest version through ruby driver docs](http://datastax.github.io/ruby-driver/) or via the release tags, [e.g. v3.0.0
|
3
|
+
*If you're reading this on GitHub, please note that this is the readme for the development version and that some features described here might not yet have been released. You can [find the documentation for latest version through ruby driver docs](http://datastax.github.io/ruby-driver/) or via the release tags, [e.g. v3.0.0](https://github.com/datastax/ruby-driver/tree/v3.0.0).*
|
4
4
|
|
5
5
|
[![Build Status](https://travis-ci.org/datastax/ruby-driver.svg?branch=master)](https://travis-ci.org/datastax/ruby-driver)
|
6
6
|
|
@@ -31,8 +31,8 @@ This driver is based on [the cql-rb gem](https://github.com/iconara/cql-rb) by [
|
|
31
31
|
|
32
32
|
This driver works exclusively with the Cassandra Query Language v3 (CQL3) and Cassandra's native protocol. The current version works with:
|
33
33
|
|
34
|
-
* Apache Cassandra versions 1.2, 2.0, 2.1, and 3.x
|
35
|
-
* DataStax Enterprise 4.0
|
34
|
+
* Apache Cassandra versions 1.2, 2.0, 2.1, 2.2, and 3.x
|
35
|
+
* DataStax Enterprise 4.0 and above.
|
36
36
|
* Ruby (MRI) 2.2, 2.3
|
37
37
|
* JRuby 1.7
|
38
38
|
|
@@ -96,28 +96,33 @@ Some of the new features added to the driver have unfortunately led to changes i
|
|
96
96
|
|
97
97
|
### Features:
|
98
98
|
|
99
|
-
* Apache Cassandra native protocol v4
|
100
|
-
* Add support for smallint, tinyint, date (Cassandra::Date) and time (Cassandra::Time) data types.
|
99
|
+
* Add support for Apache Cassandra native protocol v4
|
100
|
+
* Add support for smallint, tinyint, date (`Cassandra::Date`) and time (`Cassandra::Time`) data types.
|
101
101
|
* Include schema metadata for User Defined Functions and User Defined Aggregates.
|
102
|
+
* Augment the `Cassandra::Table` object to expose many more attributes: `id`, `options`, `keyspace`, `partition_key`, `clustering_columns`, and `clustering_order`. This makes it significantly easier to write administration scripts that report various attributes of your schema, which may help to highlight areas for improvement.
|
102
103
|
* Include client ip addresses in request traces, only on Cassandra 3.x.
|
103
|
-
* Add new retry policy decision Cassandra::Retry::Policy#try_next_host
|
104
|
-
* Support specifying statement idempotence with the new
|
105
|
-
* Support sending custom payloads when preparing or executing statements using the new
|
106
|
-
* Expose custom payloads received with responses on server exceptions and Cassandra::Execution::Info instances.
|
107
|
-
* Expose server warnings on server exceptions and Cassandra::Execution::Info instances.
|
108
|
-
* Add connections_per_local_node
|
109
|
-
* Add Cassandra::Logger class to make it easy for users to enable debug logging in the client.
|
110
|
-
* Add protocol_version configuration option to allow the user to force the protocol version to use for communication with nodes.
|
104
|
+
* Add new retry policy decision `Cassandra::Retry::Policy#try_next_host`.
|
105
|
+
* Support specifying statement idempotence with the new `idempotent` option when executing.
|
106
|
+
* Support sending custom payloads when preparing or executing statements using the new `payload` option.
|
107
|
+
* Expose custom payloads received with responses on server exceptions and `Cassandra::Execution::Info` instances.
|
108
|
+
* Expose server warnings on server exceptions and `Cassandra::Execution::Info` instances.
|
109
|
+
* Add `connections_per_local_node`, `connections_per_remote_node`, `requests_per_connection` cluster configuration options to tune parallel query execution and resource usage.
|
110
|
+
* Add `Cassandra::Logger` class to make it easy for users to enable debug logging in the client.
|
111
|
+
* Add `protocol_version` configuration option to allow the user to force the protocol version to use for communication with nodes.
|
111
112
|
* Add support for materialized views and indexes in the schema metadata.
|
113
|
+
* Support the `ReadError`, `WriteError`, and `FunctionCallError` Cassandra error responses introduced in Cassandra 2.2.
|
114
|
+
* Add support for unset variables in bound statements.
|
115
|
+
* Support DSE security (`DseAuthenticator`, configured for LDAP).
|
116
|
+
* Add a timeout option to `Cassandra::Future#get`.
|
112
117
|
|
113
|
-
### Breaking Changes:
|
118
|
+
### Breaking Changes from 2.x:
|
114
119
|
|
115
|
-
* Cassandra::Future#join is now an alias to Cassandra::Future#get and will raise an error if the future is resolved with one.
|
120
|
+
* `Cassandra::Future#join` is now an alias to Cassandra::Future#get and will raise an error if the future is resolved with one.
|
116
121
|
* Default consistency level is now LOCAL_ONE.
|
117
122
|
* Enable tcp no-delay by default.
|
118
123
|
* Unavailable errors are retried on the next host in the load balancing plan by default.
|
119
|
-
* Statement execution no longer retried on timeouts, unless
|
120
|
-
* Cassandra::Statements::Batch#add
|
124
|
+
* Statement execution no longer retried on timeouts, unless the statement is marked as idempotent in the call to `Cassandra::Session#execute*` or when creating a `Cassandra::Statement` object.
|
125
|
+
* `Cassandra::Statements::Batch#add` and `Cassandra::Session#execute*` signatures have changed in how one specifies query parameters. Specify the query parameters array as the value of the arguments key:
|
121
126
|
|
122
127
|
```ruby
|
123
128
|
batch.add(query, ['val1', 'val2'])
|
@@ -128,6 +133,10 @@ batch.add(query, {p1: 'val1'})
|
|
128
133
|
# becomes
|
129
134
|
batch.add(query, arguments: {p1: 'val1'})
|
130
135
|
```
|
136
|
+
* The Datacenter-aware load balancing policy (`Cassandra::LoadBalancing::Policies::DCAwareRoundRobin`) defaults to using
|
137
|
+
nodes in the local DC only. In prior releases, the policy would fall back to remote nodes after exhausting local nodes.
|
138
|
+
Specify a positive value (or nil for unlimited) for `max_remote_hosts_to_use` when initializing the policy to allow remote node use.
|
139
|
+
* Unspecified variables in statements previously resulted in an exception. Now they are essentially ignored or treated as null.
|
131
140
|
|
132
141
|
### Bug Fixes:
|
133
142
|
|
@@ -135,12 +144,13 @@ batch.add(query, arguments: {p1: 'val1'})
|
|
135
144
|
* [[RUBY-143](https://datastax-oss.atlassian.net/browse/RUBY-143)] Retry querying system table for metadata of new hosts when prior attempts fail, ultimately enabling use of new hosts.
|
136
145
|
* [[RUBY-150](https://datastax-oss.atlassian.net/browse/RUBY-150)] Fixed a protocol decoding error that occurred when multiple messages are available in a stream.
|
137
146
|
* [[RUBY-151](https://datastax-oss.atlassian.net/browse/RUBY-151)] Decode incomplete UDTs properly.
|
138
|
-
* [[RUBY-
|
147
|
+
* [[RUBY-155](https://datastax-oss.atlassian.net/browse/RUBY-155)] Request timeout timer should not include request queuing time.
|
148
|
+
* [[RUBY-161](https://datastax-oss.atlassian.net/browse/RUBY-161)] Protocol version negotiation in mixed version clusters should not fall back to v1 unless it is truly warranted.
|
149
|
+
* [[RUBY-214](https://datastax-oss.atlassian.net/browse/RUBY-214)] Ensure client timestamps have microsecond precision in JRuby. Previously, some row updates would get lost in high transaction environments.
|
139
150
|
|
140
151
|
## Feedback Requested
|
141
152
|
|
142
|
-
*Help us focus our efforts!* [Provide your input](http://goo.gl/forms/pCs8PTpHLf)
|
143
|
-
on the Ruby Driver Platform and Runtime Survey (we kept it short).
|
153
|
+
*Help us focus our efforts!* [Provide your input](http://goo.gl/forms/pCs8PTpHLf) on the Ruby Driver Platform and Runtime Survey (we kept it short).
|
144
154
|
|
145
155
|
## Code examples
|
146
156
|
|
data/lib/cassandra.rb
CHANGED
@@ -187,14 +187,17 @@ module Cassandra
|
|
187
187
|
# v2 or earlier protocol.
|
188
188
|
#
|
189
189
|
# @option options [Integer] :protocol_version (nil) Version of protocol to speak to
|
190
|
-
# nodes. By default, this is auto-negotiated to the
|
190
|
+
# nodes. By default, this is auto-negotiated to the highest common protocol version
|
191
191
|
# that all nodes in `:hosts` speak.
|
192
192
|
#
|
193
|
-
# @option options [Boolean] :client_timestamps (false) whether the driver
|
194
|
-
# should send timestamps for each executed statement. Enabling this
|
195
|
-
#
|
196
|
-
#
|
197
|
-
#
|
193
|
+
# @option options [Boolean, Cassandra::TimestampGenerator] :client_timestamps (false) whether the driver
|
194
|
+
# should send timestamps for each executed statement and possibly which timestamp generator to use. Enabling this
|
195
|
+
# setting helps mitigate Cassandra cluster clock skew because the timestamp of the client machine will be used.
|
196
|
+
# This does not help mitigate application cluster clock skew. Also accepts an initialized
|
197
|
+
# {Cassandra::TimestampGenerator}, `:simple` (indicating an instance of {Cassandra::TimestampGenerator::Simple}),
|
198
|
+
# or `:monotonic` (indicating an instance of {Cassandra::TimestampGenerator::TickingOnDuplicate}). If set to true,
|
199
|
+
# it defaults to {Cassandra::TimestampGenerator::Simple} for all Ruby flavors except JRuby. On JRuby, it defaults to
|
200
|
+
# {Cassandra::TimestampGenerator::TickingOnDuplicate}.
|
198
201
|
#
|
199
202
|
# @option options [Boolean] :synchronize_schema (true) whether the driver
|
200
203
|
# should automatically keep schema metadata synchronized. When enabled, the
|
@@ -682,7 +685,35 @@ module Cassandra
|
|
682
685
|
end
|
683
686
|
|
684
687
|
options[:synchronize_schema] = !!options[:synchronize_schema] if options.key?(:synchronize_schema)
|
685
|
-
|
688
|
+
|
689
|
+
if options.key?(:client_timestamps)
|
690
|
+
timestamp_generator = case options[:client_timestamps]
|
691
|
+
when true
|
692
|
+
if RUBY_ENGINE == 'jruby'
|
693
|
+
Cassandra::TimestampGenerator::TickingOnDuplicate.new
|
694
|
+
else
|
695
|
+
Cassandra::TimestampGenerator::Simple.new
|
696
|
+
end
|
697
|
+
when false
|
698
|
+
nil
|
699
|
+
when :simple
|
700
|
+
Cassandra::TimestampGenerator::Simple.new
|
701
|
+
when :monotonic
|
702
|
+
Cassandra::TimestampGenerator::TickingOnDuplicate.new
|
703
|
+
else
|
704
|
+
# The value must be a generator instance.
|
705
|
+
options[:client_timestamps]
|
706
|
+
end
|
707
|
+
|
708
|
+
if timestamp_generator
|
709
|
+
Util.assert_responds_to(:next, timestamp_generator) do
|
710
|
+
":client_timestamps #{options[:client_timestamps].inspect} must be a boolean, :simple, :monotonic, or " \
|
711
|
+
'an object that responds to :next'
|
712
|
+
end
|
713
|
+
end
|
714
|
+
options.delete(:client_timestamps)
|
715
|
+
options[:timestamp_generator] = timestamp_generator
|
716
|
+
end
|
686
717
|
|
687
718
|
if options.key?(:connections_per_local_node)
|
688
719
|
connections_per_node = options[:connections_per_local_node]
|
@@ -793,6 +824,7 @@ require 'cassandra/load_balancing'
|
|
793
824
|
require 'cassandra/reconnection'
|
794
825
|
require 'cassandra/retry'
|
795
826
|
require 'cassandra/address_resolution'
|
827
|
+
require 'cassandra/timestamp_generator'
|
796
828
|
|
797
829
|
require 'cassandra/util'
|
798
830
|
|
data/lib/cassandra/cluster.rb
CHANGED
@@ -41,7 +41,8 @@ module Cassandra
|
|
41
41
|
retry_policy,
|
42
42
|
address_resolution_policy,
|
43
43
|
connector,
|
44
|
-
futures_factory
|
44
|
+
futures_factory,
|
45
|
+
timestamp_generator)
|
45
46
|
@logger = logger
|
46
47
|
@io_reactor = io_reactor
|
47
48
|
@executor = executor
|
@@ -57,6 +58,7 @@ module Cassandra
|
|
57
58
|
@address_resolver = address_resolution_policy
|
58
59
|
@connector = connector
|
59
60
|
@futures = futures_factory
|
61
|
+
@timestamp_generator = timestamp_generator
|
60
62
|
|
61
63
|
@control_connection.on_close do |_cause|
|
62
64
|
begin
|
@@ -204,7 +206,8 @@ module Cassandra
|
|
204
206
|
@retry_policy,
|
205
207
|
@address_resolver,
|
206
208
|
@connection_options,
|
207
|
-
@futures
|
209
|
+
@futures,
|
210
|
+
@timestamp_generator)
|
208
211
|
session = Session.new(client, @execution_options, @futures)
|
209
212
|
promise = @futures.promise
|
210
213
|
|
@@ -275,7 +278,15 @@ module Cassandra
|
|
275
278
|
|
276
279
|
# @private
|
277
280
|
def inspect
|
278
|
-
"#<#{self.class.name}:0x#{object_id.to_s(16)}
|
281
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
282
|
+
"name=#{name.inspect}, " \
|
283
|
+
"port=#{@connection_options.port}, " \
|
284
|
+
"protocol_version=#{@connection_options.protocol_version}, " \
|
285
|
+
"load_balancing_policy=#{@load_balancing_policy.inspect}, " \
|
286
|
+
"consistency=#{@execution_options.consistency.inspect}, " \
|
287
|
+
"timeout=#{@execution_options.timeout.inspect}, " \
|
288
|
+
"hosts=#{hosts.inspect}, " \
|
289
|
+
"keyspaces=#{keyspaces.inspect}>"
|
279
290
|
end
|
280
291
|
end
|
281
292
|
end
|
@@ -34,7 +34,8 @@ module Cassandra
|
|
34
34
|
retry_policy,
|
35
35
|
address_resolution_policy,
|
36
36
|
connection_options,
|
37
|
-
futures_factory
|
37
|
+
futures_factory,
|
38
|
+
timestamp_generator)
|
38
39
|
@logger = logger
|
39
40
|
@registry = cluster_registry
|
40
41
|
@schema = cluster_schema
|
@@ -52,6 +53,7 @@ module Cassandra
|
|
52
53
|
@pending_connections = ::Hash.new
|
53
54
|
@keyspace = nil
|
54
55
|
@state = :idle
|
56
|
+
@timestamp_generator = timestamp_generator
|
55
57
|
|
56
58
|
mon_initialize
|
57
59
|
end
|
@@ -228,11 +230,7 @@ module Cassandra
|
|
228
230
|
'Apache Cassandra'))
|
229
231
|
end
|
230
232
|
|
231
|
-
timestamp =
|
232
|
-
if @connection_options.client_timestamps? &&
|
233
|
-
@connection_options.protocol_version > 2
|
234
|
-
timestamp = ::Time.now
|
235
|
-
end
|
233
|
+
timestamp = @timestamp_generator.next if @timestamp_generator && @connection_options.protocol_version > 2
|
236
234
|
payload = nil
|
237
235
|
payload = options.payload if @connection_options.protocol_version >= 4
|
238
236
|
request = Protocol::QueryRequest.new(statement.cql,
|
@@ -286,11 +284,7 @@ module Cassandra
|
|
286
284
|
end
|
287
285
|
|
288
286
|
def execute(statement, options)
|
289
|
-
timestamp =
|
290
|
-
if @connection_options.client_timestamps? &&
|
291
|
-
@connection_options.protocol_version > 2
|
292
|
-
timestamp = ::Time.now
|
293
|
-
end
|
287
|
+
timestamp = @timestamp_generator.next if @timestamp_generator && @connection_options.protocol_version > 2
|
294
288
|
payload = nil
|
295
289
|
payload = options.payload if @connection_options.protocol_version >= 4
|
296
290
|
timeout = options.timeout
|
@@ -324,11 +318,7 @@ module Cassandra
|
|
324
318
|
'Apache Cassandra'))
|
325
319
|
end
|
326
320
|
|
327
|
-
timestamp =
|
328
|
-
if @connection_options.client_timestamps? &&
|
329
|
-
@connection_options.protocol_version > 2
|
330
|
-
timestamp = ::Time.now
|
331
|
-
end
|
321
|
+
timestamp = @timestamp_generator.next if @timestamp_generator && @connection_options.protocol_version > 2
|
332
322
|
payload = nil
|
333
323
|
payload = options.payload if @connection_options.protocol_version >= 4
|
334
324
|
timeout = options.timeout
|
@@ -644,7 +634,15 @@ module Cassandra
|
|
644
634
|
errors,
|
645
635
|
hosts)
|
646
636
|
cql = statement.cql
|
647
|
-
id
|
637
|
+
id = nil
|
638
|
+
host_is_up = true
|
639
|
+
synchronize do
|
640
|
+
if @prepared_statements[host].nil?
|
641
|
+
host_is_up = false
|
642
|
+
else
|
643
|
+
id = @prepared_statements[host][cql]
|
644
|
+
end
|
645
|
+
end
|
648
646
|
|
649
647
|
if id
|
650
648
|
request.id = id
|
@@ -659,6 +657,19 @@ module Cassandra
|
|
659
657
|
timeout,
|
660
658
|
errors,
|
661
659
|
hosts)
|
660
|
+
elsif !host_is_up
|
661
|
+
# We've hit a race condition where the plan says we can query this host, but the host has gone
|
662
|
+
# down in the mean time. Just execute the plan again on the next host.
|
663
|
+
@logger.debug("#{host} is down; executing plan on next host")
|
664
|
+
execute_by_plan(promise,
|
665
|
+
keyspace,
|
666
|
+
statement,
|
667
|
+
options,
|
668
|
+
request,
|
669
|
+
plan,
|
670
|
+
timeout,
|
671
|
+
errors,
|
672
|
+
hosts)
|
662
673
|
else
|
663
674
|
prepare = prepare_statement(host, connection, cql, timeout)
|
664
675
|
prepare.on_complete do |_|
|
@@ -816,10 +827,29 @@ module Cassandra
|
|
816
827
|
cql = statement.cql
|
817
828
|
|
818
829
|
if statement.is_a?(Statements::Bound)
|
819
|
-
|
830
|
+
host_is_up = true
|
831
|
+
id = nil
|
832
|
+
synchronize do
|
833
|
+
if @prepared_statements[host].nil?
|
834
|
+
host_is_up = false
|
835
|
+
else
|
836
|
+
id = @prepared_statements[host][cql]
|
837
|
+
end
|
838
|
+
end
|
820
839
|
|
821
840
|
if id
|
822
841
|
request.add_prepared(id, statement.params, statement.params_types)
|
842
|
+
elsif !host_is_up
|
843
|
+
@logger.debug("#{host} is down; executing on next host in plan")
|
844
|
+
return batch_by_plan(promise,
|
845
|
+
keyspace,
|
846
|
+
batch_statement,
|
847
|
+
options,
|
848
|
+
request,
|
849
|
+
plan,
|
850
|
+
timeout,
|
851
|
+
errors,
|
852
|
+
hosts)
|
823
853
|
else
|
824
854
|
unprepared[cql] << statement
|
825
855
|
end
|
@@ -1156,17 +1186,17 @@ module Cassandra
|
|
1156
1186
|
end
|
1157
1187
|
when Protocol::SetKeyspaceResultResponse
|
1158
1188
|
@keyspace = r.keyspace
|
1159
|
-
promise.fulfill(Results::Void.new(r.custom_payload,
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1189
|
+
promise.fulfill(Cassandra::Results::Void.new(r.custom_payload,
|
1190
|
+
r.warnings,
|
1191
|
+
r.trace_id,
|
1192
|
+
keyspace,
|
1193
|
+
statement,
|
1194
|
+
options,
|
1195
|
+
hosts,
|
1196
|
+
request.consistency,
|
1197
|
+
retries,
|
1198
|
+
self,
|
1199
|
+
@futures))
|
1170
1200
|
when Protocol::PreparedResultResponse
|
1171
1201
|
cql = request.cql
|
1172
1202
|
synchronize do
|
@@ -1328,7 +1358,7 @@ module Cassandra
|
|
1328
1358
|
promise.fulfill(
|
1329
1359
|
Results::Void.new(r.custom_payload,
|
1330
1360
|
r.warnings,
|
1331
|
-
|
1361
|
+
nil,
|
1332
1362
|
keyspace,
|
1333
1363
|
statement,
|
1334
1364
|
options,
|
@@ -25,7 +25,7 @@ module Cassandra
|
|
25
25
|
attr_reader :auth_provider, :compressor, :connect_timeout, :credentials,
|
26
26
|
:heartbeat_interval, :idle_timeout, :port, :schema_refresh_delay,
|
27
27
|
:schema_refresh_timeout, :ssl
|
28
|
-
attr_boolean :protocol_negotiable, :synchronize_schema, :
|
28
|
+
attr_boolean :protocol_negotiable, :synchronize_schema, :nodelay
|
29
29
|
|
30
30
|
attr_accessor :protocol_version
|
31
31
|
|
@@ -44,7 +44,6 @@ module Cassandra
|
|
44
44
|
synchronize_schema,
|
45
45
|
schema_refresh_delay,
|
46
46
|
schema_refresh_timeout,
|
47
|
-
client_timestamps,
|
48
47
|
nodelay,
|
49
48
|
requests_per_connection)
|
50
49
|
@logger = logger
|
@@ -60,7 +59,6 @@ module Cassandra
|
|
60
59
|
@synchronize_schema = synchronize_schema
|
61
60
|
@schema_refresh_delay = schema_refresh_delay
|
62
61
|
@schema_refresh_timeout = schema_refresh_timeout
|
63
|
-
@client_timestamps = client_timestamps
|
64
62
|
@nodelay = nodelay
|
65
63
|
|
66
64
|
@connections_per_local_node = connections_per_local_node
|
data/lib/cassandra/driver.rb
CHANGED
@@ -107,7 +107,8 @@ module Cassandra
|
|
107
107
|
retry_policy,
|
108
108
|
address_resolution_policy,
|
109
109
|
connector,
|
110
|
-
futures_factory
|
110
|
+
futures_factory,
|
111
|
+
timestamp_generator)
|
111
112
|
end
|
112
113
|
|
113
114
|
let(:execution_options) do
|
@@ -135,7 +136,6 @@ module Cassandra
|
|
135
136
|
synchronize_schema,
|
136
137
|
schema_refresh_delay,
|
137
138
|
schema_refresh_timeout,
|
138
|
-
client_timestamps,
|
139
139
|
nodelay,
|
140
140
|
requests_per_connection
|
141
141
|
)
|
@@ -165,15 +165,14 @@ module Cassandra
|
|
165
165
|
let(:page_size) { 10000 }
|
166
166
|
let(:heartbeat_interval) { 30 }
|
167
167
|
let(:idle_timeout) { 60 }
|
168
|
-
let(:timeout) {
|
168
|
+
let(:timeout) { 12 }
|
169
169
|
let(:synchronize_schema) { true }
|
170
170
|
let(:schema_refresh_delay) { 1 }
|
171
171
|
let(:schema_refresh_timeout) { 10 }
|
172
172
|
let(:thread_pool_size) { 4 }
|
173
173
|
let(:shuffle_replicas) { true }
|
174
|
-
let(:client_timestamps) { false }
|
175
174
|
let(:nodelay) { true }
|
176
|
-
|
175
|
+
let(:timestamp_generator) { nil }
|
177
176
|
let(:connections_per_local_node) { nil }
|
178
177
|
let(:connections_per_remote_node) { nil }
|
179
178
|
let(:requests_per_connection) { nil }
|
data/lib/cassandra/index.rb
CHANGED
@@ -39,8 +39,17 @@ module Cassandra
|
|
39
39
|
@table = table
|
40
40
|
@name = name.freeze
|
41
41
|
@kind = kind
|
42
|
-
@target = target.freeze
|
43
42
|
@options = options.freeze
|
43
|
+
|
44
|
+
# Target is a bit tricky; it may be an escaped name or not
|
45
|
+
# depending on C* version. Unify to be unescaped since a user
|
46
|
+
# who wants to know the target would want the bare column name.
|
47
|
+
|
48
|
+
@target = if target[0] == '"'
|
49
|
+
target[1..-2]
|
50
|
+
else
|
51
|
+
target
|
52
|
+
end.freeze
|
44
53
|
end
|
45
54
|
|
46
55
|
# @return [Boolean] whether or not this index uses a custom class.
|
@@ -57,13 +66,18 @@ module Cassandra
|
|
57
66
|
def to_cql
|
58
67
|
keyspace_name = Util.escape_name(@table.keyspace.name)
|
59
68
|
table_name = Util.escape_name(@table.name)
|
60
|
-
index_name = Util.escape_name(name)
|
69
|
+
index_name = Util.escape_name(@name)
|
70
|
+
|
71
|
+
# Target is interesting in that it's not necessarily a column name,
|
72
|
+
# so we can't simply escape it. If it contains a paren, we take it as is,
|
73
|
+
# otherwise assume it's a column name and escape accordingly.
|
74
|
+
escaped_target = @target.include?('(') ? @target : Util.escape_name(@target)
|
61
75
|
|
62
76
|
if custom_index?
|
63
|
-
"CREATE CUSTOM INDEX #{index_name} ON #{keyspace_name}.#{table_name} (#{
|
64
|
-
"USING '#{@options['class_name']}'
|
77
|
+
"CREATE CUSTOM INDEX #{index_name} ON #{keyspace_name}.#{table_name} (#{escaped_target}) " \
|
78
|
+
"USING '#{@options['class_name']}'#{options_cql};"
|
65
79
|
else
|
66
|
-
"CREATE INDEX #{index_name} ON #{keyspace_name}.#{table_name} (#{
|
80
|
+
"CREATE INDEX #{index_name} ON #{keyspace_name}.#{table_name} (#{escaped_target});"
|
67
81
|
end
|
68
82
|
end
|
69
83
|
|
@@ -81,7 +95,7 @@ module Cassandra
|
|
81
95
|
# @private
|
82
96
|
def inspect
|
83
97
|
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
84
|
-
"@name=#{@name}
|
98
|
+
"@name=#{@name.inspect} @table=#{@table.inspect} @kind=#{@kind.inspect} @target=#{@target.inspect}>"
|
85
99
|
end
|
86
100
|
|
87
101
|
private
|
@@ -93,9 +107,9 @@ module Cassandra
|
|
93
107
|
end
|
94
108
|
return '' if filtered_options.empty?
|
95
109
|
|
96
|
-
result = 'WITH OPTIONS = {'
|
110
|
+
result = ' WITH OPTIONS = {'
|
97
111
|
result << filtered_options.map do |key, value|
|
98
|
-
"'#{key}':'#{value}'"
|
112
|
+
"'#{key}': '#{value}'"
|
99
113
|
end.join(', ')
|
100
114
|
result << '}'
|
101
115
|
result
|
@@ -62,7 +62,7 @@ module Cassandra
|
|
62
62
|
include MonitorMixin
|
63
63
|
|
64
64
|
def initialize(datacenter = nil,
|
65
|
-
max_remote_hosts_to_use =
|
65
|
+
max_remote_hosts_to_use = 0,
|
66
66
|
use_remote_hosts_for_local_consistency = false)
|
67
67
|
datacenter &&= String(datacenter)
|
68
68
|
max_remote_hosts_to_use &&= Integer(max_remote_hosts_to_use)
|
@@ -75,6 +75,13 @@ module Cassandra
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
# If use_remote* is true, max_remote* must be > 0
|
79
|
+
if use_remote_hosts_for_local_consistency
|
80
|
+
Util.assert(max_remote_hosts_to_use.nil? || max_remote_hosts_to_use > 0,
|
81
|
+
'max_remote_hosts_to_use must be nil (meaning unlimited) or > 0 when ' \
|
82
|
+
'use_remote_hosts_for_local_consistency is true')
|
83
|
+
end
|
84
|
+
|
78
85
|
@datacenter = datacenter
|
79
86
|
@max_remote = max_remote_hosts_to_use
|
80
87
|
@local = ::Array.new
|
@@ -148,6 +155,17 @@ module Cassandra
|
|
148
155
|
|
149
156
|
Plan.new(local, remote, position)
|
150
157
|
end
|
158
|
+
|
159
|
+
# @private
|
160
|
+
def inspect
|
161
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
162
|
+
"datacenter=#{@datacenter.inspect}, " \
|
163
|
+
"use_remote=#{@use_remote.inspect}, " \
|
164
|
+
"max_remote=#{@max_remote.inspect}, " \
|
165
|
+
"local=#{@local.inspect}, " \
|
166
|
+
"remote=#{@remote.inspect}, " \
|
167
|
+
"position=#{@position.inspect}>"
|
168
|
+
end
|
151
169
|
end
|
152
170
|
end
|
153
171
|
end
|
@@ -128,6 +128,13 @@ module Cassandra
|
|
128
128
|
|
129
129
|
Plan.new(hosts, position)
|
130
130
|
end
|
131
|
+
|
132
|
+
# @private
|
133
|
+
def inspect
|
134
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
135
|
+
"hosts=#{@hosts.inspect}, " \
|
136
|
+
"position=#{@position.inspect}>"
|
137
|
+
end
|
131
138
|
end
|
132
139
|
end
|
133
140
|
end
|
@@ -136,6 +136,13 @@ module Cassandra
|
|
136
136
|
|
137
137
|
Plan.new(replicas, @policy, keyspace, statement, options)
|
138
138
|
end
|
139
|
+
|
140
|
+
# @private
|
141
|
+
def inspect
|
142
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
143
|
+
"policy=#{@policy.inspect}, " \
|
144
|
+
"shuffle=#{@shuffle.inspect}>"
|
145
|
+
end
|
139
146
|
end
|
140
147
|
end
|
141
148
|
end
|
@@ -87,6 +87,13 @@ module Cassandra
|
|
87
87
|
def host_down(host)
|
88
88
|
@policy.host_down(host) if @ips.include?(host.ip)
|
89
89
|
end
|
90
|
+
|
91
|
+
# @private
|
92
|
+
def inspect
|
93
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
94
|
+
"policy=#{@policy.inspect}, " \
|
95
|
+
"ips=#{@ips.inspect}>"
|
96
|
+
end
|
90
97
|
end
|
91
98
|
end
|
92
99
|
end
|
@@ -78,7 +78,7 @@ module Cassandra
|
|
78
78
|
buffer.append_int(@page_size) if @page_size
|
79
79
|
buffer.append_bytes(@paging_state) if @paging_state
|
80
80
|
buffer.append_consistency(@serial_consistency) if @serial_consistency
|
81
|
-
buffer.
|
81
|
+
buffer.append_long(@timestamp) if protocol_version > 2 && @timestamp
|
82
82
|
else
|
83
83
|
encoder.write_parameters(buffer, @values, @metadata)
|
84
84
|
buffer.append_consistency(@consistency)
|
@@ -71,7 +71,7 @@ module Cassandra
|
|
71
71
|
buffer.append_int(@page_size) if @page_size
|
72
72
|
buffer.append_bytes(@paging_state) if @paging_state
|
73
73
|
buffer.append_consistency(@serial_consistency) if @serial_consistency
|
74
|
-
buffer.
|
74
|
+
buffer.append_long(@timestamp) if protocol_version > 2 && @timestamp
|
75
75
|
end
|
76
76
|
buffer
|
77
77
|
end
|
data/lib/cassandra/session.rb
CHANGED
@@ -238,7 +238,9 @@ module Cassandra
|
|
238
238
|
|
239
239
|
# @private
|
240
240
|
def inspect
|
241
|
-
"#<#{self.class.name}:0x#{object_id.to_s(16)}
|
241
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
242
|
+
"@keyspace=#{keyspace.inspect}, " \
|
243
|
+
"@options=#{@options.inspect}>"
|
242
244
|
end
|
243
245
|
end
|
244
246
|
end
|
data/lib/cassandra/table.rb
CHANGED
@@ -80,14 +80,14 @@ module Cassandra
|
|
80
80
|
else
|
81
81
|
cql << ",\n"
|
82
82
|
end
|
83
|
-
cql << " #{column.name} #{type_to_cql(column.type, column.frozen?)}"
|
83
|
+
cql << " #{Util.escape_name(column.name)} #{type_to_cql(column.type, column.frozen?)}"
|
84
84
|
cql << ' PRIMARY KEY' if primary_key && column.name == primary_key
|
85
85
|
end
|
86
86
|
|
87
87
|
unless primary_key
|
88
88
|
cql << ",\n PRIMARY KEY ("
|
89
89
|
if @partition_key.one?
|
90
|
-
cql << @partition_key.first.name
|
90
|
+
cql << Util.escape_name(@partition_key.first.name)
|
91
91
|
else
|
92
92
|
cql << '('
|
93
93
|
first = true
|
@@ -97,12 +97,12 @@ module Cassandra
|
|
97
97
|
else
|
98
98
|
cql << ', '
|
99
99
|
end
|
100
|
-
cql << column.name
|
100
|
+
cql << Util.escape_name(column.name)
|
101
101
|
end
|
102
102
|
cql << ')'
|
103
103
|
end
|
104
104
|
@clustering_columns.each do |column|
|
105
|
-
cql << ", #{column.name}"
|
105
|
+
cql << ", #{Util.escape_name(column.name)}"
|
106
106
|
end
|
107
107
|
cql << ')'
|
108
108
|
end
|
@@ -118,7 +118,7 @@ module Cassandra
|
|
118
118
|
else
|
119
119
|
cql << ', '
|
120
120
|
end
|
121
|
-
cql << "#{column.name} #{order.to_s.upcase}"
|
121
|
+
cql << "#{Util.escape_name(column.name)} #{order.to_s.upcase}"
|
122
122
|
end
|
123
123
|
cql << ")\n AND "
|
124
124
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#++
|
18
|
+
|
19
|
+
module Cassandra
|
20
|
+
# A generator is used to create client-timestamps (in the form of long integers) to send with C* requests when
|
21
|
+
# the `:client_timestamps` cluster option is set to true.
|
22
|
+
#
|
23
|
+
# @abstract A timestamp generator given to {Cassandra.cluster} doesn't need to include this module, but needs to
|
24
|
+
# implement the same methods. This module exists only for documentation purposes.
|
25
|
+
module TimestampGenerator
|
26
|
+
# Create a new timestamp, as a 64-bit integer. Calls must return monotonically increasing values.
|
27
|
+
#
|
28
|
+
# @return [Integer] an integer representing a timestamp in microseconds.
|
29
|
+
# @raise [NotImplementedError] if a class including this module does not define this method.
|
30
|
+
def next
|
31
|
+
raise NotImplementedError, "#{self.class} class must implement the 'next' method"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'cassandra/timestamp_generator/ticking_on_duplicate'
|
37
|
+
require 'cassandra/timestamp_generator/simple'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#++
|
18
|
+
|
19
|
+
module Cassandra
|
20
|
+
module TimestampGenerator
|
21
|
+
# Generate long integer timestamps from current time. This implementation relies on the {::Time} class to return
|
22
|
+
# microsecond precision time.
|
23
|
+
# @note It is not appropriate for use with JRuby because its {::Time#now} returns millisecond precision time.
|
24
|
+
class Simple
|
25
|
+
include TimestampGenerator
|
26
|
+
|
27
|
+
# Create a new timestamp, as a 64-bit integer. This is just a wrapper around Time::now.
|
28
|
+
#
|
29
|
+
# @return [Integer] an integer representing a timestamp in microseconds.
|
30
|
+
def next
|
31
|
+
# Use Time.now, which has microsecond precision on MRI (and probably Rubinius) to make an int representing
|
32
|
+
# client timestamp in protocol requests.
|
33
|
+
timestamp = ::Time.now
|
34
|
+
timestamp.tv_sec * 1000000 + timestamp.tv_usec
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#++
|
18
|
+
|
19
|
+
module Cassandra
|
20
|
+
module TimestampGenerator
|
21
|
+
# In JRuby, {::Time} has millisecond precision. We require client timestamps to have microsecond precision to
|
22
|
+
# minimize clashes in C*. This generator keeps track of the last generated timestamp, and if the current-time
|
23
|
+
# is within the same millisecond as the last, it fills the microsecond portion of the new timestamp with the
|
24
|
+
# value of an incrementing counter.
|
25
|
+
#
|
26
|
+
# For example, if the generator triggers twice at time 12345678000 (microsecond granularity, but ms precisions
|
27
|
+
# as shown by 0's for the three least-significant digits), it'll return 12345678000 and 12345678001.
|
28
|
+
class TickingOnDuplicate
|
29
|
+
include MonitorMixin
|
30
|
+
include TimestampGenerator
|
31
|
+
|
32
|
+
# @private
|
33
|
+
def initialize
|
34
|
+
mon_initialize
|
35
|
+
@last = 0
|
36
|
+
end
|
37
|
+
|
38
|
+
# Create a new timestamp, as a 64-bit integer.
|
39
|
+
#
|
40
|
+
# @return [Integer] an integer representing a timestamp in microseconds.
|
41
|
+
def next
|
42
|
+
now = ::Time.now
|
43
|
+
now_millis = now.tv_sec * 1000 + now.tv_usec / 1000
|
44
|
+
synchronize do
|
45
|
+
millis = @last / 1000
|
46
|
+
counter = @last % 1000
|
47
|
+
if millis >= now_millis
|
48
|
+
counter += 1
|
49
|
+
else
|
50
|
+
millis = now_millis
|
51
|
+
counter = 0
|
52
|
+
end
|
53
|
+
@last = millis * 1000 + counter
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/cassandra/util.rb
CHANGED
@@ -162,8 +162,13 @@ module Cassandra
|
|
162
162
|
end
|
163
163
|
|
164
164
|
def escape_name(name)
|
165
|
-
|
166
|
-
|
165
|
+
# If name only contains lower-case chars and it's not a reserved word, return it
|
166
|
+
# as-is. Otherwise, quote.
|
167
|
+
return name if name[LOWERCASE_REGEXP] == name && !RESERVED_WORDS.include?(name)
|
168
|
+
|
169
|
+
# Replace double-quotes within name with two double-quotes (if any) and surround the whole
|
170
|
+
# thing with double-quotes
|
171
|
+
DBL_QUOT + name.gsub('"', '""') + DBL_QUOT
|
167
172
|
end
|
168
173
|
|
169
174
|
def guess_type(object)
|
@@ -327,5 +332,133 @@ module Cassandra
|
|
327
332
|
PRN_OPN = '('.freeze
|
328
333
|
# @private
|
329
334
|
PRN_CLS = ')'.freeze
|
335
|
+
RESERVED_WORDS = Set.new(%w(
|
336
|
+
add
|
337
|
+
aggregate
|
338
|
+
all
|
339
|
+
allow
|
340
|
+
alter
|
341
|
+
and
|
342
|
+
apply
|
343
|
+
as
|
344
|
+
asc
|
345
|
+
ascii
|
346
|
+
authorize
|
347
|
+
batch
|
348
|
+
begin
|
349
|
+
bigint
|
350
|
+
blob
|
351
|
+
boolean
|
352
|
+
by
|
353
|
+
called
|
354
|
+
clustering
|
355
|
+
columnfamily
|
356
|
+
compact
|
357
|
+
contains
|
358
|
+
count
|
359
|
+
counter
|
360
|
+
create
|
361
|
+
custom
|
362
|
+
date
|
363
|
+
decimal
|
364
|
+
delete
|
365
|
+
desc
|
366
|
+
describe
|
367
|
+
distinct
|
368
|
+
double
|
369
|
+
drop
|
370
|
+
entries
|
371
|
+
execute
|
372
|
+
exists
|
373
|
+
filtering
|
374
|
+
finalfunc
|
375
|
+
float
|
376
|
+
from
|
377
|
+
frozen
|
378
|
+
full
|
379
|
+
function
|
380
|
+
functions
|
381
|
+
grant
|
382
|
+
if
|
383
|
+
in
|
384
|
+
index
|
385
|
+
inet
|
386
|
+
infinity
|
387
|
+
initcond
|
388
|
+
input
|
389
|
+
insert
|
390
|
+
int
|
391
|
+
into
|
392
|
+
is
|
393
|
+
json
|
394
|
+
key
|
395
|
+
keys
|
396
|
+
keyspace
|
397
|
+
keyspaces
|
398
|
+
language
|
399
|
+
limit
|
400
|
+
list
|
401
|
+
login
|
402
|
+
map
|
403
|
+
materialized
|
404
|
+
modify
|
405
|
+
nan
|
406
|
+
nologin
|
407
|
+
norecursive
|
408
|
+
nosuperuser
|
409
|
+
not
|
410
|
+
null
|
411
|
+
of
|
412
|
+
on
|
413
|
+
options
|
414
|
+
or
|
415
|
+
order
|
416
|
+
password
|
417
|
+
permission
|
418
|
+
permissions
|
419
|
+
primary
|
420
|
+
rename
|
421
|
+
replace
|
422
|
+
returns
|
423
|
+
revoke
|
424
|
+
role
|
425
|
+
roles
|
426
|
+
schema
|
427
|
+
select
|
428
|
+
set
|
429
|
+
sfunc
|
430
|
+
smallint
|
431
|
+
static
|
432
|
+
storage
|
433
|
+
stype
|
434
|
+
superuser
|
435
|
+
table
|
436
|
+
text
|
437
|
+
time
|
438
|
+
timestamp
|
439
|
+
timeuuid
|
440
|
+
tinyint
|
441
|
+
to
|
442
|
+
token
|
443
|
+
trigger
|
444
|
+
truncate
|
445
|
+
ttl
|
446
|
+
tuple
|
447
|
+
type
|
448
|
+
unlogged
|
449
|
+
update
|
450
|
+
use
|
451
|
+
user
|
452
|
+
users
|
453
|
+
using
|
454
|
+
uuid
|
455
|
+
values
|
456
|
+
varchar
|
457
|
+
varint
|
458
|
+
view
|
459
|
+
where
|
460
|
+
with
|
461
|
+
writetime
|
462
|
+
)).freeze
|
330
463
|
end
|
331
464
|
end
|
data/lib/cassandra/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cassandra-driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Theo Hultberg
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-05-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: ione
|
@@ -193,6 +193,9 @@ files:
|
|
193
193
|
- lib/cassandra/table.rb
|
194
194
|
- lib/cassandra/time.rb
|
195
195
|
- lib/cassandra/time_uuid.rb
|
196
|
+
- lib/cassandra/timestamp_generator.rb
|
197
|
+
- lib/cassandra/timestamp_generator/simple.rb
|
198
|
+
- lib/cassandra/timestamp_generator/ticking_on_duplicate.rb
|
196
199
|
- lib/cassandra/tuple.rb
|
197
200
|
- lib/cassandra/types.rb
|
198
201
|
- lib/cassandra/udt.rb
|
@@ -221,9 +224,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
221
224
|
version: 1.9.3
|
222
225
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
226
|
requirements:
|
224
|
-
- - ! '
|
227
|
+
- - ! '>='
|
225
228
|
- !ruby/object:Gem::Version
|
226
|
-
version:
|
229
|
+
version: '0'
|
227
230
|
requirements: []
|
228
231
|
rubyforge_project:
|
229
232
|
rubygems_version: 2.5.0
|