cassandra-driver 3.0.3-java → 3.1.0-java
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 +4 -4
- data/README.md +46 -31
- data/lib/cassandra.rb +35 -44
- data/lib/cassandra/cluster.rb +40 -11
- data/lib/cassandra/cluster/client.rb +193 -159
- data/lib/cassandra/cluster/connector.rb +12 -10
- data/lib/cassandra/cluster/control_connection.rb +38 -10
- data/lib/cassandra/cluster/options.rb +8 -4
- data/lib/cassandra/cluster/registry.rb +1 -2
- data/lib/cassandra/cluster/schema/fetchers.rb +122 -26
- data/lib/cassandra/column_container.rb +9 -4
- data/lib/cassandra/custom_data.rb +24 -22
- data/lib/cassandra/driver.rb +30 -13
- data/lib/cassandra/errors.rb +12 -2
- data/lib/cassandra/execution/options.rb +52 -16
- data/lib/cassandra/execution/profile.rb +150 -0
- data/lib/cassandra/execution/profile_manager.rb +71 -0
- data/lib/cassandra/execution/trace.rb +5 -4
- data/lib/cassandra/executors.rb +1 -1
- data/lib/cassandra/index.rb +1 -1
- data/lib/cassandra/keyspace.rb +36 -1
- data/lib/cassandra/protocol.rb +5 -0
- data/lib/cassandra/protocol/coder.rb +2 -1
- data/lib/cassandra/protocol/cql_byte_buffer.rb +21 -0
- data/lib/cassandra/protocol/responses/read_failure_error_response.rb +10 -4
- data/lib/cassandra/protocol/responses/write_failure_error_response.rb +14 -8
- data/lib/cassandra/protocol/v3.rb +2 -1
- data/lib/cassandra/protocol/v4.rb +58 -20
- data/lib/cassandra/result.rb +1 -1
- data/lib/cassandra/session.rb +43 -16
- data/lib/cassandra/statements/bound.rb +5 -1
- data/lib/cassandra/statements/prepared.rb +8 -3
- data/lib/cassandra/table.rb +72 -0
- data/lib/cassandra/trigger.rb +67 -0
- data/lib/cassandra/types.rb +12 -24
- data/lib/cassandra/udt.rb +3 -6
- data/lib/cassandra/uuid/generator.rb +6 -3
- data/lib/cassandra/version.rb +1 -1
- data/lib/cassandra_murmur3.jar +0 -0
- metadata +5 -2
@@ -0,0 +1,71 @@
|
|
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 Execution
|
21
|
+
# @private
|
22
|
+
class ProfileManager
|
23
|
+
attr_reader :profiles
|
24
|
+
attr_reader :load_balancing_policies
|
25
|
+
|
26
|
+
def initialize(default_profile, profiles)
|
27
|
+
# default_profile is the default profile that we constructed internally. However, the user can override it
|
28
|
+
# with their own :default profile. If that happens, ignore the internally generated default profile.
|
29
|
+
|
30
|
+
profiles[:default] = default_profile unless profiles.key?(:default)
|
31
|
+
|
32
|
+
# Save off all of the load-balancing policies for easy access.
|
33
|
+
@load_balancing_policies = Set.new
|
34
|
+
profiles.each do |name, profile|
|
35
|
+
@load_balancing_policies << profile.load_balancing_policy
|
36
|
+
end
|
37
|
+
@profiles = profiles
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_profile
|
41
|
+
@profiles[:default]
|
42
|
+
end
|
43
|
+
|
44
|
+
def distance(host)
|
45
|
+
# Return the min distance to the host, as per each lbp.
|
46
|
+
distances = Set.new
|
47
|
+
@load_balancing_policies.each do |lbp|
|
48
|
+
distances.add(lbp.distance(host))
|
49
|
+
end
|
50
|
+
return :local if distances.include?(:local)
|
51
|
+
return :remote if distances.include?(:remote)
|
52
|
+
|
53
|
+
# Fall back to ignore the host.
|
54
|
+
:ignore
|
55
|
+
end
|
56
|
+
|
57
|
+
# NOTE: It's only safe to call add_profile when setting up the cluster object. In particular,
|
58
|
+
# this is only ok before calling Driver#connect.
|
59
|
+
def add_profile(name, profile)
|
60
|
+
@profiles[name] = profile
|
61
|
+
@load_balancing_policies << profile.load_balancing_policy
|
62
|
+
end
|
63
|
+
|
64
|
+
# @private
|
65
|
+
def inspect
|
66
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
67
|
+
"profiles=#{@profiles.inspect}>"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -53,7 +53,7 @@ module Cassandra
|
|
53
53
|
attr_reader :id
|
54
54
|
|
55
55
|
# @private
|
56
|
-
def initialize(id, client)
|
56
|
+
def initialize(id, client, load_balancing_policy)
|
57
57
|
@id = id
|
58
58
|
@client = client
|
59
59
|
@coordinator = nil
|
@@ -65,6 +65,7 @@ module Cassandra
|
|
65
65
|
@client_ip = nil
|
66
66
|
@loaded = false
|
67
67
|
@loaded_events = false
|
68
|
+
@load_balancing_policy = load_balancing_policy
|
68
69
|
|
69
70
|
mon_initialize
|
70
71
|
end
|
@@ -141,12 +142,12 @@ module Cassandra
|
|
141
142
|
|
142
143
|
attempt = 1
|
143
144
|
data = @client.query(Statements::Simple.new(SELECT_SESSION % @id),
|
144
|
-
VOID_OPTIONS).get.first
|
145
|
+
VOID_OPTIONS.override(load_balancing_policy: @load_balancing_policy)).get.first
|
145
146
|
|
146
147
|
while data.nil? && attempt <= 5
|
147
148
|
sleep(attempt * 0.4)
|
148
149
|
data = @client.query(Statements::Simple.new(SELECT_SESSION % @id),
|
149
|
-
VOID_OPTIONS).get.first
|
150
|
+
VOID_OPTIONS.override(load_balancing_policy: @load_balancing_policy)).get.first
|
150
151
|
break if data
|
151
152
|
attempt += 1
|
152
153
|
end
|
@@ -173,7 +174,7 @@ module Cassandra
|
|
173
174
|
@events = []
|
174
175
|
|
175
176
|
@client.query(Statements::Simple.new(SELECT_EVENTS % @id),
|
176
|
-
VOID_OPTIONS).get.each do |row|
|
177
|
+
VOID_OPTIONS.override(load_balancing_policy: @load_balancing_policy)).get.each do |row|
|
177
178
|
@events << Event.new(row['event_id'],
|
178
179
|
row['activity'],
|
179
180
|
row['source'],
|
data/lib/cassandra/executors.rb
CHANGED
data/lib/cassandra/index.rb
CHANGED
@@ -62,7 +62,7 @@ module Cassandra
|
|
62
62
|
@options['class_name']
|
63
63
|
end
|
64
64
|
|
65
|
-
# @return [String] a cql representation of this
|
65
|
+
# @return [String] a cql representation of this index
|
66
66
|
def to_cql
|
67
67
|
keyspace_name = Util.escape_name(@table.keyspace.name)
|
68
68
|
table_name = Util.escape_name(@table.name)
|
data/lib/cassandra/keyspace.rb
CHANGED
@@ -69,11 +69,18 @@ module Cassandra
|
|
69
69
|
@views = views
|
70
70
|
|
71
71
|
# Set the keyspace attribute on the tables and views.
|
72
|
+
# Also set up the index collection on the keyspace and the view-collection on each table.
|
73
|
+
@indexes_hash = {}
|
72
74
|
@tables.each_value do |t|
|
73
75
|
t.set_keyspace(self)
|
76
|
+
t.each_index do |index|
|
77
|
+
@indexes_hash[index.name] = index
|
78
|
+
end
|
74
79
|
end
|
75
80
|
@views.each_value do |v|
|
76
81
|
v.set_keyspace(self)
|
82
|
+
table = v.base_table
|
83
|
+
table.add_view(v) if table
|
77
84
|
end
|
78
85
|
end
|
79
86
|
|
@@ -110,6 +117,34 @@ module Cassandra
|
|
110
117
|
end
|
111
118
|
alias tables each_table
|
112
119
|
|
120
|
+
# @return [Boolean] whether this keyspace has an index with the given name
|
121
|
+
# @param name [String] index name
|
122
|
+
def has_index?(name)
|
123
|
+
@indexes_hash.key?(name)
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return [Cassandra::Index, nil] an index or nil
|
127
|
+
# @param name [String] index name
|
128
|
+
def index(name)
|
129
|
+
@indexes_hash[name]
|
130
|
+
end
|
131
|
+
|
132
|
+
# Yield or enumerate each index defined in this keyspace
|
133
|
+
# @overload each_index
|
134
|
+
# @yieldparam index [Cassandra::Index] current index
|
135
|
+
# @return [Cassandra::Keyspace] self
|
136
|
+
# @overload each_index
|
137
|
+
# @return [Array<Cassandra::Index>] a list of indexes
|
138
|
+
def each_index(&block)
|
139
|
+
if block_given?
|
140
|
+
@indexes_hash.each_value(&block)
|
141
|
+
self
|
142
|
+
else
|
143
|
+
@indexes_hash.values
|
144
|
+
end
|
145
|
+
end
|
146
|
+
alias indexes each_index
|
147
|
+
|
113
148
|
# @return [Boolean] whether this keyspace has a materialized view with the given name
|
114
149
|
# @param name [String] materialized view name
|
115
150
|
def has_materialized_view?(name)
|
@@ -133,7 +168,7 @@ module Cassandra
|
|
133
168
|
def each_materialized_view(&block)
|
134
169
|
if block_given?
|
135
170
|
@views.each_value do |v|
|
136
|
-
|
171
|
+
yield(v) if v.base_table
|
137
172
|
end
|
138
173
|
self
|
139
174
|
else
|
data/lib/cassandra/protocol.rb
CHANGED
@@ -268,7 +268,8 @@ module Cassandra
|
|
268
268
|
value = ::Hash.new
|
269
269
|
|
270
270
|
buffer.read_signed_int.times do
|
271
|
-
value[read_value_v4(buffer, key_type, custom_type_handlers)] =
|
271
|
+
value[read_value_v4(buffer, key_type, custom_type_handlers)] =
|
272
|
+
read_value_v4(buffer, value_type, custom_type_handlers)
|
272
273
|
end
|
273
274
|
|
274
275
|
value
|
@@ -204,6 +204,15 @@ module Cassandra
|
|
204
204
|
e.backtrace
|
205
205
|
end
|
206
206
|
|
207
|
+
def read_inet_addr
|
208
|
+
size = read_byte
|
209
|
+
IPAddr.new_ntoh(read(size))
|
210
|
+
rescue RangeError => e
|
211
|
+
raise Errors::DecodingError,
|
212
|
+
"Not enough bytes available to decode an INET addr: #{e.message}",
|
213
|
+
e.backtrace
|
214
|
+
end
|
215
|
+
|
207
216
|
def read_consistency
|
208
217
|
index = read_unsigned_short
|
209
218
|
if index >= CONSISTENCIES.size || CONSISTENCIES[index].nil?
|
@@ -232,6 +241,18 @@ module Cassandra
|
|
232
241
|
map
|
233
242
|
end
|
234
243
|
|
244
|
+
def read_reason_map
|
245
|
+
# reason_map is new in v5. Starts with an int indicating the number of key-value pairs, followed by
|
246
|
+
# the key-value pairs. Keys are inet's, values are short int's.
|
247
|
+
map = {}
|
248
|
+
map_size = read_int
|
249
|
+
map_size.times do
|
250
|
+
key = read_inet_addr
|
251
|
+
map[key] = read_short
|
252
|
+
end
|
253
|
+
map
|
254
|
+
end
|
255
|
+
|
235
256
|
def read_string_multimap
|
236
257
|
map = {}
|
237
258
|
map_size = read_unsigned_short
|
@@ -19,7 +19,7 @@
|
|
19
19
|
module Cassandra
|
20
20
|
module Protocol
|
21
21
|
class ReadFailureErrorResponse < ErrorResponse
|
22
|
-
attr_reader :consistency, :received, :blockfor, :numfailures, :data_present
|
22
|
+
attr_reader :consistency, :received, :blockfor, :numfailures, :data_present, :failures_by_node
|
23
23
|
|
24
24
|
def initialize(custom_payload,
|
25
25
|
warnings,
|
@@ -29,14 +29,19 @@ module Cassandra
|
|
29
29
|
received,
|
30
30
|
blockfor,
|
31
31
|
numfailures,
|
32
|
-
data_present
|
32
|
+
data_present,
|
33
|
+
failures_by_node)
|
33
34
|
super(custom_payload, warnings, code, message)
|
34
35
|
|
35
36
|
@consistency = consistency
|
36
37
|
@received = received
|
37
38
|
@blockfor = blockfor
|
38
|
-
@numfailures = numfailures
|
39
39
|
@data_present = data_present
|
40
|
+
@failures_by_node = failures_by_node
|
41
|
+
|
42
|
+
# If failures_by_node is set, numfailures isn't, and v.v. Set @numfailures to the size of the failure-map
|
43
|
+
# if numfailures is nil.
|
44
|
+
@numfailures = numfailures || @failures_by_node.size
|
40
45
|
end
|
41
46
|
|
42
47
|
def to_error(keyspace, statement, options, hosts, consistency, retries)
|
@@ -53,7 +58,8 @@ module Cassandra
|
|
53
58
|
@consistency,
|
54
59
|
@blockfor,
|
55
60
|
@numfailures,
|
56
|
-
@received
|
61
|
+
@received,
|
62
|
+
@failures_by_node)
|
57
63
|
end
|
58
64
|
|
59
65
|
def to_s
|
@@ -19,7 +19,7 @@
|
|
19
19
|
module Cassandra
|
20
20
|
module Protocol
|
21
21
|
class WriteFailureErrorResponse < ErrorResponse
|
22
|
-
attr_reader :consistency, :received, :blockfor, :numfailures, :write_type
|
22
|
+
attr_reader :consistency, :received, :blockfor, :numfailures, :write_type, :failures_by_node
|
23
23
|
|
24
24
|
def initialize(custom_payload,
|
25
25
|
warnings,
|
@@ -29,16 +29,21 @@ module Cassandra
|
|
29
29
|
received,
|
30
30
|
blockfor,
|
31
31
|
numfailures,
|
32
|
-
write_type
|
32
|
+
write_type,
|
33
|
+
failures_by_node)
|
33
34
|
super(custom_payload, warnings, code, message)
|
34
35
|
|
35
36
|
write_type.downcase!
|
36
37
|
|
37
|
-
@consistency
|
38
|
-
@received
|
39
|
-
@blockfor
|
40
|
-
@
|
41
|
-
@
|
38
|
+
@consistency = consistency
|
39
|
+
@received = received
|
40
|
+
@blockfor = blockfor
|
41
|
+
@write_type = write_type.to_sym
|
42
|
+
@failures_by_node = failures_by_node
|
43
|
+
|
44
|
+
# If failures_by_node is set, numfailures isn't, and v.v. Set @numfailures to the size of the failure-map
|
45
|
+
# if numfailures is nil.
|
46
|
+
@numfailures = numfailures || @failures_by_node.size
|
42
47
|
end
|
43
48
|
|
44
49
|
def to_error(keyspace, statement, options, hosts, consistency, retries)
|
@@ -55,7 +60,8 @@ module Cassandra
|
|
55
60
|
@consistency,
|
56
61
|
@blockfor,
|
57
62
|
@numfailures,
|
58
|
-
@received
|
63
|
+
@received,
|
64
|
+
@failures_by_node)
|
59
65
|
end
|
60
66
|
|
61
67
|
def to_s
|
@@ -166,7 +166,8 @@ module Cassandra
|
|
166
166
|
if compression == 1
|
167
167
|
if @compressor
|
168
168
|
buffer = CqlByteBuffer.new(
|
169
|
-
@compressor.decompress(buffer.read(frame_length))
|
169
|
+
@compressor.decompress(buffer.read(frame_length))
|
170
|
+
)
|
170
171
|
frame_length = buffer.size
|
171
172
|
else
|
172
173
|
raise Errors::DecodingError,
|
@@ -23,7 +23,7 @@ module Cassandra
|
|
23
23
|
class Encoder
|
24
24
|
HEADER_FORMAT = 'c2ncN'.freeze
|
25
25
|
|
26
|
-
def initialize(compressor
|
26
|
+
def initialize(compressor, protocol_version)
|
27
27
|
@compressor = compressor
|
28
28
|
@protocol_version = protocol_version
|
29
29
|
end
|
@@ -31,6 +31,7 @@ module Cassandra
|
|
31
31
|
def encode(buffer, request, stream_id)
|
32
32
|
flags = 0
|
33
33
|
flags |= 0x02 if request.trace?
|
34
|
+
flags |= 0x10 if @protocol_version == Cassandra::Protocol::Versions::BETA_VERSION
|
34
35
|
|
35
36
|
body = CqlByteBuffer.new
|
36
37
|
|
@@ -178,7 +179,8 @@ module Cassandra
|
|
178
179
|
if compression
|
179
180
|
if @compressor
|
180
181
|
buffer = CqlByteBuffer.new(
|
181
|
-
@compressor.decompress(buffer.read(frame_length))
|
182
|
+
@compressor.decompress(buffer.read(frame_length))
|
183
|
+
)
|
182
184
|
frame_length = buffer.size
|
183
185
|
else
|
184
186
|
raise Errors::DecodingError,
|
@@ -259,15 +261,33 @@ module Cassandra
|
|
259
261
|
buffer.read_int,
|
260
262
|
(buffer.read_byte != 0))
|
261
263
|
when 0x1300
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
264
|
+
cl = buffer.read_consistency
|
265
|
+
received = buffer.read_int
|
266
|
+
block_for = buffer.read_int
|
267
|
+
if protocol_version < 5
|
268
|
+
ReadFailureErrorResponse.new(custom_payload,
|
269
|
+
warnings,
|
270
|
+
code,
|
271
|
+
message,
|
272
|
+
cl,
|
273
|
+
received,
|
274
|
+
block_for,
|
275
|
+
buffer.read_int,
|
276
|
+
(buffer.read_byte != 0),
|
277
|
+
nil)
|
278
|
+
else
|
279
|
+
failures_by_node = buffer.read_reason_map
|
280
|
+
ReadFailureErrorResponse.new(custom_payload,
|
281
|
+
warnings,
|
282
|
+
code,
|
283
|
+
message,
|
284
|
+
cl,
|
285
|
+
received,
|
286
|
+
block_for,
|
287
|
+
nil,
|
288
|
+
(buffer.read_byte != 0),
|
289
|
+
failures_by_node)
|
290
|
+
end
|
271
291
|
when 0x1400
|
272
292
|
FunctionFailureErrorResponse.new(custom_payload,
|
273
293
|
warnings,
|
@@ -277,15 +297,33 @@ module Cassandra
|
|
277
297
|
buffer.read_string,
|
278
298
|
buffer.read_string_list)
|
279
299
|
when 0x1500
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
300
|
+
cl = buffer.read_consistency
|
301
|
+
received = buffer.read_int
|
302
|
+
block_for = buffer.read_int
|
303
|
+
if protocol_version < 5
|
304
|
+
WriteFailureErrorResponse.new(custom_payload,
|
305
|
+
warnings,
|
306
|
+
code,
|
307
|
+
message,
|
308
|
+
cl,
|
309
|
+
received,
|
310
|
+
block_for,
|
311
|
+
buffer.read_int,
|
312
|
+
buffer.read_string,
|
313
|
+
nil)
|
314
|
+
else
|
315
|
+
failures_by_node = buffer.read_reason_map
|
316
|
+
WriteFailureErrorResponse.new(custom_payload,
|
317
|
+
warnings,
|
318
|
+
code,
|
319
|
+
message,
|
320
|
+
cl,
|
321
|
+
received,
|
322
|
+
block_for,
|
323
|
+
nil,
|
324
|
+
buffer.read_string,
|
325
|
+
failures_by_node)
|
326
|
+
end
|
289
327
|
when 0x2400
|
290
328
|
AlreadyExistsErrorResponse.new(custom_payload,
|
291
329
|
warnings,
|