cassandra-driver 3.0.0.beta.1 → 3.0.0.rc.1
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 +90 -38
- data/ext/cassandra_murmur3/cassandra_murmur3.c +1 -1
- data/lib/cassandra.rb +327 -130
- data/lib/cassandra/address_resolution.rb +1 -1
- data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +1 -1
- data/lib/cassandra/address_resolution/policies/none.rb +1 -1
- data/lib/cassandra/aggregate.rb +21 -7
- data/lib/cassandra/argument.rb +2 -2
- data/lib/cassandra/auth.rb +4 -4
- data/lib/cassandra/auth/providers.rb +1 -1
- data/lib/cassandra/auth/providers/password.rb +9 -5
- data/lib/cassandra/cassandra_logger.rb +80 -0
- data/lib/cassandra/cluster.rb +38 -9
- data/lib/cassandra/cluster/client.rb +801 -205
- data/lib/cassandra/cluster/connection_pool.rb +2 -2
- data/lib/cassandra/cluster/connector.rb +74 -25
- data/lib/cassandra/cluster/control_connection.rb +217 -82
- data/lib/cassandra/cluster/failed_connection.rb +1 -1
- data/lib/cassandra/cluster/metadata.rb +12 -4
- data/lib/cassandra/cluster/options.rb +60 -11
- data/lib/cassandra/cluster/registry.rb +69 -16
- data/lib/cassandra/cluster/schema.rb +25 -7
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +15 -10
- data/lib/cassandra/cluster/schema/fetchers.rb +263 -106
- data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +41 -36
- data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
- data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +3 -3
- data/lib/cassandra/cluster/schema/partitioners/ordered.rb +1 -1
- data/lib/cassandra/cluster/schema/partitioners/random.rb +1 -1
- data/lib/cassandra/cluster/schema/replication_strategies.rb +1 -1
- data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +19 -18
- data/lib/cassandra/cluster/schema/replication_strategies/none.rb +1 -1
- data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +1 -1
- data/lib/cassandra/column.rb +3 -3
- data/lib/cassandra/compression.rb +1 -1
- data/lib/cassandra/compression/compressors/lz4.rb +4 -3
- data/lib/cassandra/compression/compressors/snappy.rb +4 -3
- data/lib/cassandra/driver.rb +103 -41
- data/lib/cassandra/errors.rb +265 -30
- data/lib/cassandra/execution/info.rb +16 -5
- data/lib/cassandra/execution/options.rb +99 -54
- data/lib/cassandra/execution/trace.rb +16 -9
- data/lib/cassandra/executors.rb +1 -1
- data/lib/cassandra/function.rb +19 -13
- data/lib/cassandra/function_collection.rb +85 -0
- data/lib/cassandra/future.rb +106 -48
- data/lib/cassandra/host.rb +10 -4
- data/lib/cassandra/keyspace.rb +90 -33
- data/lib/cassandra/listener.rb +1 -1
- data/lib/cassandra/load_balancing.rb +2 -2
- data/lib/cassandra/load_balancing/policies.rb +1 -1
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +18 -18
- data/lib/cassandra/load_balancing/policies/round_robin.rb +1 -1
- data/lib/cassandra/load_balancing/policies/token_aware.rb +15 -13
- data/lib/cassandra/load_balancing/policies/white_list.rb +11 -5
- data/lib/cassandra/null_logger.rb +27 -6
- data/lib/cassandra/protocol.rb +1 -1
- data/lib/cassandra/protocol/coder.rb +78 -39
- data/lib/cassandra/protocol/cql_byte_buffer.rb +50 -33
- data/lib/cassandra/protocol/cql_protocol_handler.rb +44 -45
- data/lib/cassandra/protocol/request.rb +2 -2
- data/lib/cassandra/protocol/requests/auth_response_request.rb +3 -3
- data/lib/cassandra/protocol/requests/batch_request.rb +16 -7
- data/lib/cassandra/protocol/requests/credentials_request.rb +3 -3
- data/lib/cassandra/protocol/requests/execute_request.rb +41 -20
- data/lib/cassandra/protocol/requests/options_request.rb +1 -1
- data/lib/cassandra/protocol/requests/prepare_request.rb +5 -5
- data/lib/cassandra/protocol/requests/query_request.rb +27 -22
- data/lib/cassandra/protocol/requests/register_request.rb +2 -2
- data/lib/cassandra/protocol/requests/startup_request.rb +6 -4
- data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
- data/lib/cassandra/protocol/response.rb +2 -2
- data/lib/cassandra/protocol/responses/already_exists_error_response.rb +12 -2
- data/lib/cassandra/protocol/responses/auth_challenge_response.rb +1 -1
- data/lib/cassandra/protocol/responses/auth_success_response.rb +1 -1
- data/lib/cassandra/protocol/responses/authenticate_response.rb +1 -1
- data/lib/cassandra/protocol/responses/error_response.rb +101 -13
- data/lib/cassandra/protocol/responses/event_response.rb +1 -1
- data/lib/cassandra/protocol/responses/function_failure_error_response.rb +13 -2
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +11 -5
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +14 -9
- data/lib/cassandra/protocol/responses/read_failure_error_response.rb +26 -4
- data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +22 -3
- data/lib/cassandra/protocol/responses/ready_response.rb +3 -3
- data/lib/cassandra/protocol/responses/result_response.rb +4 -2
- data/lib/cassandra/protocol/responses/rows_result_response.rb +5 -3
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +5 -4
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +16 -9
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +2 -2
- data/lib/cassandra/protocol/responses/status_change_event_response.rb +2 -2
- data/lib/cassandra/protocol/responses/supported_response.rb +1 -1
- data/lib/cassandra/protocol/responses/topology_change_event_response.rb +1 -1
- data/lib/cassandra/protocol/responses/unavailable_error_response.rb +20 -3
- data/lib/cassandra/protocol/responses/unprepared_error_response.rb +11 -2
- data/lib/cassandra/protocol/responses/void_result_response.rb +1 -1
- data/lib/cassandra/protocol/responses/write_failure_error_response.rb +26 -4
- data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +22 -3
- data/lib/cassandra/protocol/v1.rb +101 -36
- data/lib/cassandra/protocol/v3.rb +124 -51
- data/lib/cassandra/protocol/v4.rb +172 -68
- data/lib/cassandra/reconnection.rb +1 -1
- data/lib/cassandra/reconnection/policies.rb +1 -1
- data/lib/cassandra/reconnection/policies/constant.rb +2 -4
- data/lib/cassandra/reconnection/policies/exponential.rb +6 -6
- data/lib/cassandra/result.rb +53 -19
- data/lib/cassandra/retry.rb +8 -8
- data/lib/cassandra/retry/policies.rb +1 -1
- data/lib/cassandra/retry/policies/default.rb +1 -1
- data/lib/cassandra/retry/policies/downgrading_consistency.rb +7 -3
- data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
- data/lib/cassandra/session.rb +22 -16
- data/lib/cassandra/statement.rb +1 -1
- data/lib/cassandra/statements.rb +1 -1
- data/lib/cassandra/statements/batch.rb +16 -10
- data/lib/cassandra/statements/bound.rb +10 -3
- data/lib/cassandra/statements/prepared.rb +59 -15
- data/lib/cassandra/statements/simple.rb +23 -10
- data/lib/cassandra/statements/void.rb +1 -1
- data/lib/cassandra/table.rb +79 -30
- data/lib/cassandra/time.rb +11 -6
- data/lib/cassandra/time_uuid.rb +7 -7
- data/lib/cassandra/tuple.rb +16 -8
- data/lib/cassandra/types.rb +20 -9
- data/lib/cassandra/udt.rb +32 -36
- data/lib/cassandra/util.rb +20 -13
- data/lib/cassandra/uuid.rb +22 -15
- data/lib/cassandra/uuid/generator.rb +7 -5
- data/lib/cassandra/version.rb +2 -2
- data/lib/datastax/cassandra.rb +1 -1
- metadata +5 -3
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright 2013-
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -28,7 +28,16 @@ module Cassandra
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def to_error(keyspace, statement, options, hosts, consistency, retries)
|
31
|
-
Errors::UnpreparedError.new(@message,
|
31
|
+
Errors::UnpreparedError.new(@message,
|
32
|
+
@custom_payload,
|
33
|
+
@warnings,
|
34
|
+
keyspace,
|
35
|
+
statement,
|
36
|
+
options,
|
37
|
+
hosts,
|
38
|
+
consistency,
|
39
|
+
retries,
|
40
|
+
@id)
|
32
41
|
end
|
33
42
|
|
34
43
|
def to_s
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright 2013-
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -21,7 +21,15 @@ module Cassandra
|
|
21
21
|
class WriteFailureErrorResponse < ErrorResponse
|
22
22
|
attr_reader :consistency, :received, :blockfor, :numfailures, :write_type
|
23
23
|
|
24
|
-
def initialize(custom_payload,
|
24
|
+
def initialize(custom_payload,
|
25
|
+
warnings,
|
26
|
+
code,
|
27
|
+
message,
|
28
|
+
consistency,
|
29
|
+
received,
|
30
|
+
blockfor,
|
31
|
+
numfailures,
|
32
|
+
write_type)
|
25
33
|
super(custom_payload, warnings, code, message)
|
26
34
|
|
27
35
|
write_type.downcase!
|
@@ -34,11 +42,25 @@ module Cassandra
|
|
34
42
|
end
|
35
43
|
|
36
44
|
def to_error(keyspace, statement, options, hosts, consistency, retries)
|
37
|
-
Errors::WriteError.new(@message,
|
45
|
+
Errors::WriteError.new(@message,
|
46
|
+
@custom_payload,
|
47
|
+
@warnings,
|
48
|
+
keyspace,
|
49
|
+
statement,
|
50
|
+
options,
|
51
|
+
hosts,
|
52
|
+
consistency,
|
53
|
+
retries,
|
54
|
+
@write_type,
|
55
|
+
@consistency,
|
56
|
+
@blockfor,
|
57
|
+
@numfailures,
|
58
|
+
@received)
|
38
59
|
end
|
39
60
|
|
40
61
|
def to_s
|
41
|
-
"#{super} #{@write_type} #{@consistency} #{@blockfor}
|
62
|
+
"#{super} #{@write_type} #{@consistency} #{@blockfor} " \
|
63
|
+
"#{@numfailures} #{@received}"
|
42
64
|
end
|
43
65
|
end
|
44
66
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright 2013-
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -21,7 +21,14 @@ module Cassandra
|
|
21
21
|
class WriteTimeoutErrorResponse < ErrorResponse
|
22
22
|
attr_reader :consistency, :received, :blockfor, :write_type
|
23
23
|
|
24
|
-
def initialize(custom_payload,
|
24
|
+
def initialize(custom_payload,
|
25
|
+
warnings,
|
26
|
+
code,
|
27
|
+
message,
|
28
|
+
consistency,
|
29
|
+
received,
|
30
|
+
blockfor,
|
31
|
+
write_type)
|
25
32
|
super(custom_payload, warnings, code, message)
|
26
33
|
|
27
34
|
write_type.downcase!
|
@@ -33,7 +40,19 @@ module Cassandra
|
|
33
40
|
end
|
34
41
|
|
35
42
|
def to_error(keyspace, statement, options, hosts, consistency, retries)
|
36
|
-
Errors::WriteTimeoutError.new(@message,
|
43
|
+
Errors::WriteTimeoutError.new(@message,
|
44
|
+
@custom_payload,
|
45
|
+
@warnings,
|
46
|
+
keyspace,
|
47
|
+
statement,
|
48
|
+
options,
|
49
|
+
hosts,
|
50
|
+
consistency,
|
51
|
+
retries,
|
52
|
+
@write_type,
|
53
|
+
@consistency,
|
54
|
+
@blockfor,
|
55
|
+
@received)
|
37
56
|
end
|
38
57
|
|
39
58
|
def to_s
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright 2013-
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -37,7 +37,7 @@ module Cassandra
|
|
37
37
|
body = @compressor.compress(body)
|
38
38
|
end
|
39
39
|
|
40
|
-
header
|
40
|
+
header = [@protocol_version, flags, stream_id, request.opcode, body.bytesize]
|
41
41
|
buffer << header.pack(HEADER_FORMAT)
|
42
42
|
buffer << body
|
43
43
|
buffer
|
@@ -131,7 +131,8 @@ module Cassandra
|
|
131
131
|
buffer = CqlByteBuffer.new(@compressor.decompress(buffer.read(size)))
|
132
132
|
size = buffer.size
|
133
133
|
else
|
134
|
-
raise Errors::DecodingError,
|
134
|
+
raise Errors::DecodingError,
|
135
|
+
'Compressed frame received, but no compressor configured'
|
135
136
|
end
|
136
137
|
end
|
137
138
|
|
@@ -145,9 +146,7 @@ module Cassandra
|
|
145
146
|
extra_length = buffer.length - size
|
146
147
|
response = decode_response(opcode, protocol_version, buffer, size, trace_id)
|
147
148
|
|
148
|
-
if buffer.length > extra_length
|
149
|
-
buffer.discard(buffer.length - extra_length)
|
150
|
-
end
|
149
|
+
buffer.discard(buffer.length - extra_length) if buffer.length > extra_length
|
151
150
|
|
152
151
|
if stream_id == -1
|
153
152
|
@handler.notify_event_listeners(response)
|
@@ -168,22 +167,61 @@ module Cassandra
|
|
168
167
|
CODE_AUTH_SUCCESS = 0x10
|
169
168
|
|
170
169
|
def decode_response(opcode, protocol_version, buffer, size, trace_id)
|
171
|
-
|
172
|
-
when CODE_READY
|
173
|
-
|
174
|
-
when
|
175
|
-
|
176
|
-
when
|
170
|
+
case opcode
|
171
|
+
when CODE_READY then
|
172
|
+
READY
|
173
|
+
when CODE_AUTHENTICATE then
|
174
|
+
AuthenticateResponse.new(buffer.read_string)
|
175
|
+
when CODE_AUTH_CHALLENGE then
|
176
|
+
AuthChallengeResponse.new(buffer.read_bytes)
|
177
|
+
when CODE_AUTH_SUCCESS then
|
178
|
+
AuthSuccessResponse.new(buffer.read_bytes)
|
179
|
+
when CODE_SUPPORTED then
|
180
|
+
SupportedResponse.new(buffer.read_string_multimap)
|
177
181
|
when CODE_ERROR
|
178
|
-
code
|
182
|
+
code = buffer.read_int
|
179
183
|
message = buffer.read_string
|
180
184
|
|
181
185
|
case code
|
182
|
-
when 0x1000 then
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
186
|
+
when 0x1000 then
|
187
|
+
UnavailableErrorResponse.new(nil,
|
188
|
+
nil,
|
189
|
+
code,
|
190
|
+
message,
|
191
|
+
buffer.read_consistency,
|
192
|
+
buffer.read_int,
|
193
|
+
buffer.read_int)
|
194
|
+
when 0x1100 then
|
195
|
+
WriteTimeoutErrorResponse.new(nil,
|
196
|
+
nil,
|
197
|
+
code,
|
198
|
+
message,
|
199
|
+
buffer.read_consistency,
|
200
|
+
buffer.read_int,
|
201
|
+
buffer.read_int,
|
202
|
+
buffer.read_string)
|
203
|
+
when 0x1200 then
|
204
|
+
ReadTimeoutErrorResponse.new(nil,
|
205
|
+
nil,
|
206
|
+
code,
|
207
|
+
message,
|
208
|
+
buffer.read_consistency,
|
209
|
+
buffer.read_int,
|
210
|
+
buffer.read_int,
|
211
|
+
(buffer.read_byte != 0))
|
212
|
+
when 0x2400 then
|
213
|
+
AlreadyExistsErrorResponse.new(nil,
|
214
|
+
nil,
|
215
|
+
code,
|
216
|
+
message,
|
217
|
+
buffer.read_string,
|
218
|
+
buffer.read_string)
|
219
|
+
when 0x2500 then
|
220
|
+
UnpreparedErrorResponse.new(nil,
|
221
|
+
nil,
|
222
|
+
code,
|
223
|
+
message,
|
224
|
+
buffer.read_short_bytes)
|
187
225
|
else
|
188
226
|
ErrorResponse.new(nil, nil, code, message)
|
189
227
|
end
|
@@ -197,50 +235,77 @@ module Cassandra
|
|
197
235
|
column_specs, paging_state = Coder.read_metadata_v1(buffer)
|
198
236
|
|
199
237
|
if column_specs.nil?
|
200
|
-
consumed_bytes
|
201
|
-
remaining_bytes =
|
202
|
-
|
238
|
+
consumed_bytes = original_buffer_length - buffer.length
|
239
|
+
remaining_bytes =
|
240
|
+
CqlByteBuffer.new(buffer.read(size - consumed_bytes - 4))
|
241
|
+
RawRowsResultResponse.new(nil,
|
242
|
+
nil,
|
243
|
+
protocol_version,
|
244
|
+
remaining_bytes,
|
245
|
+
paging_state,
|
246
|
+
trace_id)
|
203
247
|
else
|
204
|
-
RowsResultResponse.new(nil,
|
248
|
+
RowsResultResponse.new(nil,
|
249
|
+
nil,
|
250
|
+
Coder.read_values_v1(buffer, column_specs),
|
251
|
+
column_specs,
|
252
|
+
paging_state,
|
253
|
+
trace_id)
|
205
254
|
end
|
206
255
|
when 0x0003 # SetKeyspace
|
207
256
|
SetKeyspaceResultResponse.new(nil, nil, buffer.read_string, trace_id)
|
208
257
|
when 0x0004 # Prepared
|
209
|
-
id
|
258
|
+
id = buffer.read_short_bytes
|
210
259
|
params_metadata = Coder.read_metadata_v1(buffer).first
|
211
260
|
result_metadata = nil
|
212
|
-
|
261
|
+
if protocol_version > 1
|
262
|
+
result_metadata = Coder.read_metadata_v1(buffer).first
|
263
|
+
end
|
213
264
|
|
214
|
-
PreparedResultResponse.new(nil,
|
265
|
+
PreparedResultResponse.new(nil,
|
266
|
+
nil,
|
267
|
+
id,
|
268
|
+
params_metadata,
|
269
|
+
result_metadata,
|
270
|
+
nil,
|
271
|
+
trace_id)
|
215
272
|
when 0x0005 # SchemaChange
|
216
|
-
change
|
217
|
-
keyspace
|
218
|
-
name
|
273
|
+
change = buffer.read_string
|
274
|
+
keyspace = buffer.read_string
|
275
|
+
name = buffer.read_string
|
219
276
|
arguments = EMPTY_LIST
|
220
|
-
target
|
277
|
+
target = nil
|
221
278
|
|
222
279
|
if name.empty?
|
223
|
-
name
|
280
|
+
name = nil
|
224
281
|
target = Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
|
225
282
|
else
|
226
283
|
target = Constants::SCHEMA_CHANGE_TARGET_TABLE
|
227
284
|
end
|
228
285
|
|
229
|
-
SchemaChangeResultResponse.new(nil,
|
286
|
+
SchemaChangeResultResponse.new(nil,
|
287
|
+
nil,
|
288
|
+
change,
|
289
|
+
keyspace,
|
290
|
+
name,
|
291
|
+
target,
|
292
|
+
arguments,
|
293
|
+
nil)
|
230
294
|
else
|
231
|
-
raise Errors::DecodingError,
|
295
|
+
raise Errors::DecodingError,
|
296
|
+
"Unsupported result type: #{result_type.inspect}"
|
232
297
|
end
|
233
298
|
when CODE_EVENT
|
234
299
|
event_type = buffer.read_string
|
235
300
|
case event_type
|
236
301
|
when 'SCHEMA_CHANGE'
|
237
|
-
change
|
238
|
-
keyspace
|
239
|
-
name
|
302
|
+
change = buffer.read_string
|
303
|
+
keyspace = buffer.read_string
|
304
|
+
name = buffer.read_string
|
240
305
|
arguments = EMPTY_LIST
|
241
306
|
|
242
307
|
if name.empty?
|
243
|
-
name
|
308
|
+
name = nil
|
244
309
|
target = Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
|
245
310
|
else
|
246
311
|
target = Constants::SCHEMA_CHANGE_TARGET_TABLE
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright 2013-
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -37,7 +37,7 @@ module Cassandra
|
|
37
37
|
body = @compressor.compress(body)
|
38
38
|
end
|
39
39
|
|
40
|
-
header
|
40
|
+
header = [@protocol_version, flags, stream_id, request.opcode, body.bytesize]
|
41
41
|
buffer << header.pack(HEADER_FORMAT)
|
42
42
|
buffer << body
|
43
43
|
|
@@ -81,7 +81,9 @@ module Cassandra
|
|
81
81
|
stream_id = (frame_header >> 8) & 0xff
|
82
82
|
stream_id = (stream_id & 0x7f) - (stream_id & 0x80)
|
83
83
|
|
84
|
-
|
84
|
+
error_response = ErrorResponse.new(nil, nil, 0x000A,
|
85
|
+
'Invalid or unsupported protocol version')
|
86
|
+
@handler.complete_request(stream_id, error_response)
|
85
87
|
|
86
88
|
return
|
87
89
|
end
|
@@ -150,7 +152,7 @@ module Cassandra
|
|
150
152
|
nil
|
151
153
|
end
|
152
154
|
|
153
|
-
def actual_decode(buffer, fields,
|
155
|
+
def actual_decode(buffer, fields, frame_length, code)
|
154
156
|
protocol_version = (fields >> 24) & 0x7f
|
155
157
|
compression = (fields >> 16) & 0x01
|
156
158
|
tracing = (fields >> 16) & 0x02
|
@@ -158,28 +160,40 @@ module Cassandra
|
|
158
160
|
stream_id = (stream_id & 0x7fff) - (stream_id & 0x8000)
|
159
161
|
opcode = code & 0xff
|
160
162
|
|
163
|
+
# If we're dealing with a compressed body, read the whole body, decompress,
|
164
|
+
# and treat the uncompressed body as if that's what we got in the first place.
|
165
|
+
# This means we must reset frame_length to that uncompressed size.
|
161
166
|
if compression == 1
|
162
167
|
if @compressor
|
163
|
-
buffer = CqlByteBuffer.new(
|
164
|
-
|
168
|
+
buffer = CqlByteBuffer.new(
|
169
|
+
@compressor.decompress(buffer.read(frame_length)))
|
170
|
+
frame_length = buffer.size
|
165
171
|
else
|
166
|
-
raise Errors::DecodingError,
|
172
|
+
raise Errors::DecodingError,
|
173
|
+
'Compressed frame received, but no compressor configured'
|
167
174
|
end
|
168
175
|
end
|
169
176
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
177
|
+
# We want to read one full frame; but after we read/parse chunks of the body
|
178
|
+
# there may be more cruft left in the frame that we don't care about. So,
|
179
|
+
# we save off the current size of the buffer, do all our reads for the
|
180
|
+
# frame, get the final remaining size, and based on that discard possible
|
181
|
+
# remaining bytes in the frame. In particular, we account for the possibility
|
182
|
+
# that the buffer contains some/all of a subsequent frame as well, and we
|
183
|
+
# don't want to mess with that.
|
176
184
|
|
177
|
-
|
178
|
-
response = decode_response(opcode, protocol_version, buffer, size, trace_id)
|
185
|
+
buffer_starting_length = buffer.length
|
179
186
|
|
180
|
-
|
181
|
-
|
182
|
-
|
187
|
+
trace_id = (buffer.read_uuid if tracing == 2)
|
188
|
+
|
189
|
+
remaining_frame_length = frame_length -
|
190
|
+
(buffer_starting_length - buffer.length)
|
191
|
+
response = decode_response(opcode, protocol_version, buffer,
|
192
|
+
remaining_frame_length, trace_id)
|
193
|
+
|
194
|
+
# Calculate and discard remaining cruft in the frame.
|
195
|
+
extra_length = frame_length - (buffer_starting_length - buffer.length)
|
196
|
+
buffer.discard(extra_length) if extra_length > 0
|
183
197
|
|
184
198
|
if stream_id == -1
|
185
199
|
@handler.notify_event_listeners(response)
|
@@ -191,15 +205,49 @@ module Cassandra
|
|
191
205
|
def decode_response(opcode, protocol_version, buffer, size, trace_id)
|
192
206
|
case opcode
|
193
207
|
when 0x00 # ERROR
|
194
|
-
code
|
208
|
+
code = buffer.read_int
|
195
209
|
message = buffer.read_string
|
196
210
|
|
197
211
|
case code
|
198
|
-
when 0x1000
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
212
|
+
when 0x1000
|
213
|
+
UnavailableErrorResponse.new(nil,
|
214
|
+
nil,
|
215
|
+
code,
|
216
|
+
message,
|
217
|
+
buffer.read_consistency,
|
218
|
+
buffer.read_int,
|
219
|
+
buffer.read_int)
|
220
|
+
when 0x1100
|
221
|
+
WriteTimeoutErrorResponse.new(nil,
|
222
|
+
nil,
|
223
|
+
code,
|
224
|
+
message,
|
225
|
+
buffer.read_consistency,
|
226
|
+
buffer.read_int,
|
227
|
+
buffer.read_int,
|
228
|
+
buffer.read_string)
|
229
|
+
when 0x1200
|
230
|
+
ReadTimeoutErrorResponse.new(nil,
|
231
|
+
nil,
|
232
|
+
code,
|
233
|
+
message,
|
234
|
+
buffer.read_consistency,
|
235
|
+
buffer.read_int,
|
236
|
+
buffer.read_int,
|
237
|
+
(buffer.read_byte != 0))
|
238
|
+
when 0x2400
|
239
|
+
AlreadyExistsErrorResponse.new(nil,
|
240
|
+
nil,
|
241
|
+
code,
|
242
|
+
message,
|
243
|
+
buffer.read_string,
|
244
|
+
buffer.read_string)
|
245
|
+
when 0x2500
|
246
|
+
UnpreparedErrorResponse.new(nil,
|
247
|
+
nil,
|
248
|
+
code,
|
249
|
+
message,
|
250
|
+
buffer.read_short_bytes)
|
203
251
|
else
|
204
252
|
ErrorResponse.new(nil, nil, code, message)
|
205
253
|
end
|
@@ -219,49 +267,72 @@ module Cassandra
|
|
219
267
|
column_specs, paging_state = Coder.read_metadata_v3(buffer)
|
220
268
|
|
221
269
|
if column_specs.nil?
|
222
|
-
consumed_bytes
|
223
|
-
remaining_bytes =
|
224
|
-
|
270
|
+
consumed_bytes = original_buffer_length - buffer.length
|
271
|
+
remaining_bytes =
|
272
|
+
CqlByteBuffer.new(buffer.read(size - consumed_bytes - 4))
|
273
|
+
RawRowsResultResponse.new(nil,
|
274
|
+
nil,
|
275
|
+
protocol_version,
|
276
|
+
remaining_bytes,
|
277
|
+
paging_state,
|
278
|
+
trace_id)
|
225
279
|
else
|
226
|
-
RowsResultResponse.new(nil,
|
280
|
+
RowsResultResponse.new(nil,
|
281
|
+
nil,
|
282
|
+
Coder.read_values_v3(buffer, column_specs),
|
283
|
+
column_specs,
|
284
|
+
paging_state,
|
285
|
+
trace_id)
|
227
286
|
end
|
228
287
|
when 0x0003 # SetKeyspace
|
229
288
|
SetKeyspaceResultResponse.new(nil, nil, buffer.read_string, trace_id)
|
230
289
|
when 0x0004 # Prepared
|
231
|
-
id
|
290
|
+
id = buffer.read_short_bytes
|
232
291
|
params_metadata = Coder.read_metadata_v3(buffer).first
|
233
292
|
result_metadata = nil
|
234
|
-
|
293
|
+
if protocol_version > 1
|
294
|
+
result_metadata = Coder.read_metadata_v3(buffer).first
|
295
|
+
end
|
235
296
|
|
236
|
-
PreparedResultResponse.new(nil,
|
297
|
+
PreparedResultResponse.new(nil,
|
298
|
+
nil,
|
299
|
+
id,
|
300
|
+
params_metadata,
|
301
|
+
result_metadata,
|
302
|
+
nil,
|
303
|
+
trace_id)
|
237
304
|
when 0x0005 # SchemaChange
|
238
|
-
change
|
239
|
-
target
|
240
|
-
keyspace
|
305
|
+
change = buffer.read_string
|
306
|
+
target = buffer.read_string
|
307
|
+
keyspace = buffer.read_string
|
241
308
|
arguments = EMPTY_LIST
|
242
|
-
name
|
243
|
-
|
244
|
-
if target == Constants::SCHEMA_CHANGE_TARGET_TABLE
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
309
|
+
name = nil
|
310
|
+
|
311
|
+
name = buffer.read_string if target == Constants::SCHEMA_CHANGE_TARGET_TABLE
|
312
|
+
|
313
|
+
SchemaChangeResultResponse.new(nil,
|
314
|
+
nil,
|
315
|
+
change,
|
316
|
+
keyspace,
|
317
|
+
name,
|
318
|
+
target,
|
319
|
+
arguments,
|
320
|
+
nil)
|
249
321
|
else
|
250
|
-
raise Errors::DecodingError,
|
322
|
+
raise Errors::DecodingError,
|
323
|
+
"Unsupported result type: #{result_type.inspect}"
|
251
324
|
end
|
252
325
|
when 0x0C # EVENT
|
253
326
|
event_type = buffer.read_string
|
254
327
|
case event_type
|
255
328
|
when 'SCHEMA_CHANGE'
|
256
|
-
change
|
257
|
-
target
|
258
|
-
keyspace
|
259
|
-
name
|
329
|
+
change = buffer.read_string
|
330
|
+
target = buffer.read_string
|
331
|
+
keyspace = buffer.read_string
|
332
|
+
name = nil
|
260
333
|
arguments = EMPTY_LIST
|
261
334
|
|
262
|
-
if target == Constants::SCHEMA_CHANGE_TARGET_TABLE
|
263
|
-
name = buffer.read_string
|
264
|
-
end
|
335
|
+
name = buffer.read_string if target == Constants::SCHEMA_CHANGE_TARGET_TABLE
|
265
336
|
|
266
337
|
SchemaChangeEventResponse.new(change, keyspace, name, target, arguments)
|
267
338
|
when 'STATUS_CHANGE'
|
@@ -269,14 +340,16 @@ module Cassandra
|
|
269
340
|
when 'TOPOLOGY_CHANGE'
|
270
341
|
TopologyChangeEventResponse.new(buffer.read_string, *buffer.read_inet)
|
271
342
|
else
|
272
|
-
raise Errors::DecodingError,
|
343
|
+
raise Errors::DecodingError,
|
344
|
+
"Unsupported event type: #{event_type.inspect}"
|
273
345
|
end
|
274
346
|
when 0x0E # AUTH_CHALLENGE
|
275
347
|
AuthChallengeResponse.new(buffer.read_bytes)
|
276
348
|
when 0x10 # AUTH_SUCCESS
|
277
349
|
AuthSuccessResponse.new(buffer.read_bytes)
|
278
350
|
else
|
279
|
-
raise Errors::DecodingError,
|
351
|
+
raise Errors::DecodingError,
|
352
|
+
"Unsupported response opcode: #{opcode.inspect}"
|
280
353
|
end
|
281
354
|
end
|
282
355
|
end
|