cassandra-driver 3.0.0.beta.1-java → 3.0.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 +106 -39
- data/lib/cassandra.rb +396 -148
- 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/attr_boolean.rb +33 -0
- data/lib/cassandra/auth.rb +6 -5
- data/lib/cassandra/auth/providers.rb +1 -1
- data/lib/cassandra/auth/providers/password.rb +5 -13
- data/lib/cassandra/cassandra_logger.rb +80 -0
- data/lib/cassandra/cluster.rb +49 -9
- data/lib/cassandra/cluster/client.rb +835 -209
- data/lib/cassandra/cluster/connection_pool.rb +2 -2
- data/lib/cassandra/cluster/connector.rb +86 -27
- data/lib/cassandra/cluster/control_connection.rb +222 -95
- data/lib/cassandra/cluster/failed_connection.rb +1 -1
- data/lib/cassandra/cluster/metadata.rb +14 -8
- data/lib/cassandra/cluster/options.rb +68 -22
- data/lib/cassandra/cluster/registry.rb +81 -17
- data/lib/cassandra/cluster/schema.rb +70 -8
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +15 -10
- data/lib/cassandra/cluster/schema/fetchers.rb +601 -241
- data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +39 -38
- data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
- data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +6 -8
- 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 +4 -23
- data/lib/cassandra/column_container.rb +322 -0
- data/lib/cassandra/compression.rb +1 -1
- data/lib/cassandra/compression/compressors/lz4.rb +7 -8
- data/lib/cassandra/compression/compressors/snappy.rb +4 -3
- data/lib/cassandra/driver.rb +107 -46
- data/lib/cassandra/errors.rb +303 -52
- data/lib/cassandra/execution/info.rb +16 -5
- data/lib/cassandra/execution/options.rb +102 -55
- 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 +101 -49
- data/lib/cassandra/host.rb +25 -5
- data/lib/cassandra/index.rb +118 -0
- data/lib/cassandra/keyspace.rb +169 -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 +39 -25
- data/lib/cassandra/load_balancing/policies/round_robin.rb +8 -1
- data/lib/cassandra/load_balancing/policies/token_aware.rb +22 -13
- data/lib/cassandra/load_balancing/policies/white_list.rb +18 -5
- data/lib/cassandra/materialized_view.rb +90 -0
- data/lib/cassandra/null_logger.rb +27 -6
- data/lib/cassandra/protocol.rb +1 -1
- data/lib/cassandra/protocol/coder.rb +81 -42
- data/lib/cassandra/protocol/cql_byte_buffer.rb +58 -44
- data/lib/cassandra/protocol/cql_protocol_handler.rb +57 -54
- data/lib/cassandra/protocol/request.rb +6 -7
- data/lib/cassandra/protocol/requests/auth_response_request.rb +3 -3
- data/lib/cassandra/protocol/requests/batch_request.rb +17 -8
- data/lib/cassandra/protocol/requests/credentials_request.rb +3 -3
- data/lib/cassandra/protocol/requests/execute_request.rb +39 -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 +28 -23
- data/lib/cassandra/protocol/requests/register_request.rb +2 -2
- data/lib/cassandra/protocol/requests/startup_request.rb +8 -8
- data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
- data/lib/cassandra/protocol/response.rb +3 -4
- data/lib/cassandra/protocol/responses/already_exists_error_response.rb +12 -2
- data/lib/cassandra/protocol/responses/auth_challenge_response.rb +4 -5
- data/lib/cassandra/protocol/responses/auth_success_response.rb +4 -5
- data/lib/cassandra/protocol/responses/authenticate_response.rb +4 -5
- data/lib/cassandra/protocol/responses/error_response.rb +104 -17
- data/lib/cassandra/protocol/responses/event_response.rb +3 -4
- data/lib/cassandra/protocol/responses/function_failure_error_response.rb +13 -2
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +14 -9
- 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 +6 -7
- data/lib/cassandra/protocol/responses/result_response.rb +11 -10
- data/lib/cassandra/protocol/responses/rows_result_response.rb +8 -7
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +8 -8
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +19 -13
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +5 -6
- data/lib/cassandra/protocol/responses/status_change_event_response.rb +5 -6
- data/lib/cassandra/protocol/responses/supported_response.rb +4 -5
- data/lib/cassandra/protocol/responses/topology_change_event_response.rb +4 -5
- 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 +4 -5
- 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 +98 -37
- data/lib/cassandra/protocol/v3.rb +121 -50
- 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 +55 -20
- 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 +4 -2
- data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
- data/lib/cassandra/session.rb +24 -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 +62 -18
- data/lib/cassandra/statements/simple.rb +23 -10
- data/lib/cassandra/statements/void.rb +1 -1
- data/lib/cassandra/table.rb +53 -185
- data/lib/cassandra/time.rb +11 -6
- data/lib/cassandra/time_uuid.rb +12 -14
- 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/tuple.rb +4 -4
- data/lib/cassandra/types.rb +109 -71
- data/lib/cassandra/udt.rb +66 -50
- data/lib/cassandra/util.rb +155 -15
- data/lib/cassandra/uuid.rb +20 -21
- data/lib/cassandra/uuid/generator.rb +7 -5
- data/lib/cassandra/version.rb +2 -2
- data/lib/cassandra_murmur3.jar +0 -0
- data/lib/datastax/cassandra.rb +1 -1
- metadata +27 -16
@@ -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.
|
@@ -19,6 +19,9 @@
|
|
19
19
|
module Cassandra
|
20
20
|
module Protocol
|
21
21
|
class VoidResultResponse < ResultResponse
|
22
|
+
# @private
|
23
|
+
RESULT_TYPES[0x01] = self
|
24
|
+
|
22
25
|
def to_s
|
23
26
|
%(RESULT VOID)
|
24
27
|
end
|
@@ -26,10 +29,6 @@ module Cassandra
|
|
26
29
|
def void?
|
27
30
|
true
|
28
31
|
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
RESULT_TYPES[0x01] = self
|
33
32
|
end
|
34
33
|
end
|
35
34
|
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,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)
|
@@ -156,8 +155,6 @@ module Cassandra
|
|
156
155
|
end
|
157
156
|
end
|
158
157
|
|
159
|
-
private
|
160
|
-
|
161
158
|
CODE_ERROR = 0x00
|
162
159
|
CODE_READY = 0x02
|
163
160
|
CODE_AUTHENTICATE = 0x03
|
@@ -168,22 +165,61 @@ module Cassandra
|
|
168
165
|
CODE_AUTH_SUCCESS = 0x10
|
169
166
|
|
170
167
|
def decode_response(opcode, protocol_version, buffer, size, trace_id)
|
171
|
-
|
172
|
-
when CODE_READY
|
173
|
-
|
174
|
-
when
|
175
|
-
|
176
|
-
when
|
168
|
+
case opcode
|
169
|
+
when CODE_READY then
|
170
|
+
READY
|
171
|
+
when CODE_AUTHENTICATE then
|
172
|
+
AuthenticateResponse.new(buffer.read_string)
|
173
|
+
when CODE_AUTH_CHALLENGE then
|
174
|
+
AuthChallengeResponse.new(buffer.read_bytes)
|
175
|
+
when CODE_AUTH_SUCCESS then
|
176
|
+
AuthSuccessResponse.new(buffer.read_bytes)
|
177
|
+
when CODE_SUPPORTED then
|
178
|
+
SupportedResponse.new(buffer.read_string_multimap)
|
177
179
|
when CODE_ERROR
|
178
|
-
code
|
180
|
+
code = buffer.read_int
|
179
181
|
message = buffer.read_string
|
180
182
|
|
181
183
|
case code
|
182
|
-
when 0x1000 then
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
184
|
+
when 0x1000 then
|
185
|
+
UnavailableErrorResponse.new(nil,
|
186
|
+
nil,
|
187
|
+
code,
|
188
|
+
message,
|
189
|
+
buffer.read_consistency,
|
190
|
+
buffer.read_int,
|
191
|
+
buffer.read_int)
|
192
|
+
when 0x1100 then
|
193
|
+
WriteTimeoutErrorResponse.new(nil,
|
194
|
+
nil,
|
195
|
+
code,
|
196
|
+
message,
|
197
|
+
buffer.read_consistency,
|
198
|
+
buffer.read_int,
|
199
|
+
buffer.read_int,
|
200
|
+
buffer.read_string)
|
201
|
+
when 0x1200 then
|
202
|
+
ReadTimeoutErrorResponse.new(nil,
|
203
|
+
nil,
|
204
|
+
code,
|
205
|
+
message,
|
206
|
+
buffer.read_consistency,
|
207
|
+
buffer.read_int,
|
208
|
+
buffer.read_int,
|
209
|
+
(buffer.read_byte != 0))
|
210
|
+
when 0x2400 then
|
211
|
+
AlreadyExistsErrorResponse.new(nil,
|
212
|
+
nil,
|
213
|
+
code,
|
214
|
+
message,
|
215
|
+
buffer.read_string,
|
216
|
+
buffer.read_string)
|
217
|
+
when 0x2500 then
|
218
|
+
UnpreparedErrorResponse.new(nil,
|
219
|
+
nil,
|
220
|
+
code,
|
221
|
+
message,
|
222
|
+
buffer.read_short_bytes)
|
187
223
|
else
|
188
224
|
ErrorResponse.new(nil, nil, code, message)
|
189
225
|
end
|
@@ -197,50 +233,75 @@ module Cassandra
|
|
197
233
|
column_specs, paging_state = Coder.read_metadata_v1(buffer)
|
198
234
|
|
199
235
|
if column_specs.nil?
|
200
|
-
consumed_bytes
|
201
|
-
remaining_bytes =
|
202
|
-
|
236
|
+
consumed_bytes = original_buffer_length - buffer.length
|
237
|
+
remaining_bytes =
|
238
|
+
CqlByteBuffer.new(buffer.read(size - consumed_bytes - 4))
|
239
|
+
RawRowsResultResponse.new(nil,
|
240
|
+
nil,
|
241
|
+
protocol_version,
|
242
|
+
remaining_bytes,
|
243
|
+
paging_state,
|
244
|
+
trace_id)
|
203
245
|
else
|
204
|
-
RowsResultResponse.new(nil,
|
246
|
+
RowsResultResponse.new(nil,
|
247
|
+
nil,
|
248
|
+
Coder.read_values_v1(buffer, column_specs),
|
249
|
+
column_specs,
|
250
|
+
paging_state,
|
251
|
+
trace_id)
|
205
252
|
end
|
206
253
|
when 0x0003 # SetKeyspace
|
207
254
|
SetKeyspaceResultResponse.new(nil, nil, buffer.read_string, trace_id)
|
208
255
|
when 0x0004 # Prepared
|
209
|
-
id
|
256
|
+
id = buffer.read_short_bytes
|
210
257
|
params_metadata = Coder.read_metadata_v1(buffer).first
|
211
258
|
result_metadata = nil
|
212
259
|
result_metadata = Coder.read_metadata_v1(buffer).first if protocol_version > 1
|
213
260
|
|
214
|
-
PreparedResultResponse.new(nil,
|
261
|
+
PreparedResultResponse.new(nil,
|
262
|
+
nil,
|
263
|
+
id,
|
264
|
+
params_metadata,
|
265
|
+
result_metadata,
|
266
|
+
nil,
|
267
|
+
trace_id)
|
215
268
|
when 0x0005 # SchemaChange
|
216
|
-
change
|
217
|
-
keyspace
|
218
|
-
name
|
269
|
+
change = buffer.read_string
|
270
|
+
keyspace = buffer.read_string
|
271
|
+
name = buffer.read_string
|
219
272
|
arguments = EMPTY_LIST
|
220
|
-
target
|
273
|
+
target = nil
|
221
274
|
|
222
275
|
if name.empty?
|
223
|
-
name
|
276
|
+
name = nil
|
224
277
|
target = Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
|
225
278
|
else
|
226
279
|
target = Constants::SCHEMA_CHANGE_TARGET_TABLE
|
227
280
|
end
|
228
281
|
|
229
|
-
SchemaChangeResultResponse.new(nil,
|
282
|
+
SchemaChangeResultResponse.new(nil,
|
283
|
+
nil,
|
284
|
+
change,
|
285
|
+
keyspace,
|
286
|
+
name,
|
287
|
+
target,
|
288
|
+
arguments,
|
289
|
+
nil)
|
230
290
|
else
|
231
|
-
raise Errors::DecodingError,
|
291
|
+
raise Errors::DecodingError,
|
292
|
+
"Unsupported result type: #{result_type.inspect}"
|
232
293
|
end
|
233
294
|
when CODE_EVENT
|
234
295
|
event_type = buffer.read_string
|
235
296
|
case event_type
|
236
297
|
when 'SCHEMA_CHANGE'
|
237
|
-
change
|
238
|
-
keyspace
|
239
|
-
name
|
298
|
+
change = buffer.read_string
|
299
|
+
keyspace = buffer.read_string
|
300
|
+
name = buffer.read_string
|
240
301
|
arguments = EMPTY_LIST
|
241
302
|
|
242
303
|
if name.empty?
|
243
|
-
name
|
304
|
+
name = nil
|
244
305
|
target = Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
|
245
306
|
else
|
246
307
|
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,70 @@ 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
|
result_metadata = Coder.read_metadata_v3(buffer).first if protocol_version > 1
|
235
294
|
|
236
|
-
PreparedResultResponse.new(nil,
|
295
|
+
PreparedResultResponse.new(nil,
|
296
|
+
nil,
|
297
|
+
id,
|
298
|
+
params_metadata,
|
299
|
+
result_metadata,
|
300
|
+
nil,
|
301
|
+
trace_id)
|
237
302
|
when 0x0005 # SchemaChange
|
238
|
-
change
|
239
|
-
target
|
240
|
-
keyspace
|
303
|
+
change = buffer.read_string
|
304
|
+
target = buffer.read_string
|
305
|
+
keyspace = buffer.read_string
|
241
306
|
arguments = EMPTY_LIST
|
242
|
-
name
|
243
|
-
|
244
|
-
if target == Constants::SCHEMA_CHANGE_TARGET_TABLE
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
307
|
+
name = nil
|
308
|
+
|
309
|
+
name = buffer.read_string if target == Constants::SCHEMA_CHANGE_TARGET_TABLE
|
310
|
+
|
311
|
+
SchemaChangeResultResponse.new(nil,
|
312
|
+
nil,
|
313
|
+
change,
|
314
|
+
keyspace,
|
315
|
+
name,
|
316
|
+
target,
|
317
|
+
arguments,
|
318
|
+
nil)
|
249
319
|
else
|
250
|
-
raise Errors::DecodingError,
|
320
|
+
raise Errors::DecodingError,
|
321
|
+
"Unsupported result type: #{result_type.inspect}"
|
251
322
|
end
|
252
323
|
when 0x0C # EVENT
|
253
324
|
event_type = buffer.read_string
|
254
325
|
case event_type
|
255
326
|
when 'SCHEMA_CHANGE'
|
256
|
-
change
|
257
|
-
target
|
258
|
-
keyspace
|
259
|
-
name
|
327
|
+
change = buffer.read_string
|
328
|
+
target = buffer.read_string
|
329
|
+
keyspace = buffer.read_string
|
330
|
+
name = nil
|
260
331
|
arguments = EMPTY_LIST
|
261
332
|
|
262
|
-
if target == Constants::SCHEMA_CHANGE_TARGET_TABLE
|
263
|
-
name = buffer.read_string
|
264
|
-
end
|
333
|
+
name = buffer.read_string if target == Constants::SCHEMA_CHANGE_TARGET_TABLE
|
265
334
|
|
266
335
|
SchemaChangeEventResponse.new(change, keyspace, name, target, arguments)
|
267
336
|
when 'STATUS_CHANGE'
|
@@ -269,14 +338,16 @@ module Cassandra
|
|
269
338
|
when 'TOPOLOGY_CHANGE'
|
270
339
|
TopologyChangeEventResponse.new(buffer.read_string, *buffer.read_inet)
|
271
340
|
else
|
272
|
-
raise Errors::DecodingError,
|
341
|
+
raise Errors::DecodingError,
|
342
|
+
"Unsupported event type: #{event_type.inspect}"
|
273
343
|
end
|
274
344
|
when 0x0E # AUTH_CHALLENGE
|
275
345
|
AuthChallengeResponse.new(buffer.read_bytes)
|
276
346
|
when 0x10 # AUTH_SUCCESS
|
277
347
|
AuthSuccessResponse.new(buffer.read_bytes)
|
278
348
|
else
|
279
|
-
raise Errors::DecodingError,
|
349
|
+
raise Errors::DecodingError,
|
350
|
+
"Unsupported response opcode: #{opcode.inspect}"
|
280
351
|
end
|
281
352
|
end
|
282
353
|
end
|