cassandra-driver 3.0.0.rc.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
[](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
|