cassandra-driver 2.1.7-java → 3.0.0.beta.1-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 +31 -53
- data/lib/cassandra.rb +22 -3
- data/lib/cassandra/aggregate.rb +109 -0
- data/lib/cassandra/argument.rb +51 -0
- data/lib/cassandra/auth/providers/password.rb +7 -4
- data/lib/cassandra/cluster.rb +14 -3
- data/lib/cassandra/cluster/client.rb +56 -34
- data/lib/cassandra/cluster/connector.rb +6 -6
- data/lib/cassandra/cluster/control_connection.rb +204 -251
- data/lib/cassandra/cluster/metadata.rb +2 -0
- data/lib/cassandra/cluster/schema.rb +131 -209
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +104 -0
- data/lib/cassandra/cluster/schema/fetchers.rb +1174 -0
- data/lib/cassandra/cluster/schema/{type_parser.rb → fqcn_type_parser.rb} +7 -3
- data/lib/cassandra/column.rb +2 -2
- data/lib/cassandra/driver.rb +27 -9
- data/lib/cassandra/errors.rb +179 -25
- data/lib/cassandra/execution/info.rb +8 -1
- data/lib/cassandra/execution/options.rb +34 -0
- data/lib/cassandra/execution/trace.rb +42 -10
- data/lib/cassandra/function.rb +150 -0
- data/lib/cassandra/future.rb +66 -35
- data/lib/cassandra/host.rb +7 -4
- data/lib/cassandra/keyspace.rb +112 -13
- data/lib/cassandra/load_balancing.rb +1 -1
- data/lib/cassandra/protocol.rb +9 -3
- data/lib/cassandra/protocol/coder.rb +434 -155
- data/lib/cassandra/protocol/cql_byte_buffer.rb +43 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +4 -1
- data/lib/cassandra/protocol/request.rb +4 -0
- data/lib/cassandra/protocol/requests/auth_response_request.rb +5 -1
- data/lib/cassandra/protocol/requests/batch_request.rb +7 -2
- data/lib/cassandra/protocol/requests/credentials_request.rb +5 -1
- data/lib/cassandra/protocol/requests/execute_request.rb +16 -10
- data/lib/cassandra/protocol/requests/prepare_request.rb +12 -3
- data/lib/cassandra/protocol/requests/query_request.rb +20 -11
- data/lib/cassandra/protocol/responses/already_exists_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/error_response.rb +14 -14
- data/lib/cassandra/protocol/responses/function_failure_error_response.rb +41 -0
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +12 -9
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +5 -3
- data/lib/cassandra/protocol/responses/read_failure_error_response.rb +43 -0
- data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/ready_response.rb +5 -1
- data/lib/cassandra/protocol/responses/result_response.rb +3 -3
- data/lib/cassandra/protocol/responses/rows_result_response.rb +2 -2
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +25 -24
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +20 -23
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +2 -2
- data/lib/cassandra/protocol/responses/unavailable_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/unprepared_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/write_failure_error_response.rb +45 -0
- data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +4 -4
- data/lib/cassandra/protocol/v1.rb +38 -13
- data/lib/cassandra/protocol/v3.rb +34 -29
- data/lib/cassandra/protocol/v4.rb +334 -0
- data/lib/cassandra/result.rb +10 -9
- data/lib/cassandra/retry.rb +17 -3
- data/lib/cassandra/retry/policies/default.rb +9 -3
- data/lib/cassandra/session.rb +15 -7
- data/lib/cassandra/statement.rb +5 -0
- data/lib/cassandra/statements/batch.rb +36 -12
- data/lib/cassandra/statements/bound.rb +2 -1
- data/lib/cassandra/statements/prepared.rb +106 -35
- data/lib/cassandra/statements/simple.rb +4 -2
- data/lib/cassandra/table.rb +70 -105
- data/lib/cassandra/time.rb +98 -0
- data/lib/cassandra/time_uuid.rb +1 -1
- data/lib/cassandra/tuple.rb +7 -0
- data/lib/cassandra/types.rb +472 -272
- data/lib/cassandra/udt.rb +10 -0
- data/lib/cassandra/util.rb +32 -1
- data/lib/cassandra/uuid.rb +6 -1
- data/lib/cassandra/uuid/generator.rb +7 -7
- data/lib/cassandra/version.rb +1 -1
- data/lib/cassandra_murmur3.jar +0 -0
- data/lib/datastax/cassandra.rb +5 -2
- metadata +27 -17
data/lib/cassandra/result.rb
CHANGED
@@ -23,7 +23,7 @@ module Cassandra
|
|
23
23
|
# Query execution information, such as number of retries and all tried hosts, etc.
|
24
24
|
# @return [Cassandra::Execution::Info]
|
25
25
|
def execution_info
|
26
|
-
@info ||= Execution::Info.new(@keyspace, @statement, @options, @hosts, @consistency, @retries, @trace_id ? Execution::Trace.new(@trace_id, @client) : nil)
|
26
|
+
@info ||= Execution::Info.new(@payload, @warnings, @keyspace, @statement, @options, @hosts, @consistency, @retries, @trace_id ? Execution::Trace.new(@trace_id, @client) : nil)
|
27
27
|
end
|
28
28
|
|
29
29
|
# @return [Boolean] whether it has any rows
|
@@ -96,7 +96,9 @@ module Cassandra
|
|
96
96
|
class Paged < Result
|
97
97
|
attr_reader :paging_state
|
98
98
|
|
99
|
-
def initialize(rows, paging_state, trace_id, keyspace, statement, options, hosts, consistency, retries, client, futures_factory)
|
99
|
+
def initialize(payload, warnings, rows, paging_state, trace_id, keyspace, statement, options, hosts, consistency, retries, client, futures_factory)
|
100
|
+
@payload = payload
|
101
|
+
@warnings = warnings
|
100
102
|
@rows = rows
|
101
103
|
@paging_state = paging_state
|
102
104
|
@trace_id = trace_id
|
@@ -156,13 +158,16 @@ module Cassandra
|
|
156
158
|
end
|
157
159
|
end
|
158
160
|
|
161
|
+
# @private
|
159
162
|
def inspect
|
160
163
|
"#<Cassandra::Result:0x#{self.object_id.to_s(16)} @rows=#{@rows.inspect} @last_page=#{@paging_state.nil?}>"
|
161
164
|
end
|
162
165
|
end
|
163
166
|
|
164
167
|
class Void < Result
|
165
|
-
def initialize(trace_id, keyspace, statement, options, hosts, consistency, retries, client, futures_factory)
|
168
|
+
def initialize(payload, warnings, trace_id, keyspace, statement, options, hosts, consistency, retries, client, futures_factory)
|
169
|
+
@payload = payload
|
170
|
+
@warnings = warnings
|
166
171
|
@trace_id = trace_id
|
167
172
|
@keyspace = keyspace
|
168
173
|
@statement = statement
|
@@ -191,10 +196,10 @@ module Cassandra
|
|
191
196
|
# @return [Cassandra::Result]
|
192
197
|
def each(&block)
|
193
198
|
if block_given?
|
194
|
-
|
199
|
+
EMPTY_LIST.each(&block)
|
195
200
|
self
|
196
201
|
else
|
197
|
-
|
202
|
+
EMPTY_LIST.each
|
198
203
|
end
|
199
204
|
end
|
200
205
|
alias :rows :each
|
@@ -231,10 +236,6 @@ module Cassandra
|
|
231
236
|
def inspect
|
232
237
|
"#<Cassandra::Result:0x#{self.object_id.to_s(16)} @rows=[] @last_page=true>"
|
233
238
|
end
|
234
|
-
|
235
|
-
private
|
236
|
-
|
237
|
-
NO_ROWS = [].freeze
|
238
239
|
end
|
239
240
|
end
|
240
241
|
end
|
data/lib/cassandra/retry.rb
CHANGED
@@ -106,11 +106,20 @@ module Cassandra
|
|
106
106
|
|
107
107
|
# Returns a decision that signals to driver to ignore the error
|
108
108
|
#
|
109
|
-
# @return [Cassandra::Policies::Retry::Decision] tell driver to ignore
|
110
|
-
# and return an empty result to the application
|
109
|
+
# @return [Cassandra::Policies::Retry::Decision] tell driver to ignore
|
110
|
+
# the error and return an empty result to the application
|
111
111
|
def ignore
|
112
112
|
DECISION_IGNORE
|
113
113
|
end
|
114
|
+
|
115
|
+
# Returns a decision that signals to the driver attempt execution on the
|
116
|
+
# next host in the load balancing plan
|
117
|
+
#
|
118
|
+
# @return [Cassandra::Policies::Retry::Decision] tell the driver to
|
119
|
+
# re-execute the statement on another host
|
120
|
+
def try_next_host
|
121
|
+
DECISION_TRY_NEXT_HOST
|
122
|
+
end
|
114
123
|
end
|
115
124
|
|
116
125
|
# @private
|
@@ -128,12 +137,17 @@ module Cassandra
|
|
128
137
|
|
129
138
|
class Ignore
|
130
139
|
end
|
140
|
+
|
141
|
+
class TryNextHost
|
142
|
+
end
|
131
143
|
end
|
132
144
|
|
133
145
|
# @private
|
134
146
|
DECISION_RERAISE = Decisions::Reraise.new
|
135
147
|
# @private
|
136
|
-
DECISION_IGNORE
|
148
|
+
DECISION_IGNORE = Decisions::Ignore.new
|
149
|
+
# @private
|
150
|
+
DECISION_TRY_NEXT_HOST = Decisions::TryNextHost.new
|
137
151
|
end
|
138
152
|
end
|
139
153
|
|
@@ -28,18 +28,24 @@ module Cassandra
|
|
28
28
|
if received >= required && !retrieved
|
29
29
|
try_again(consistency)
|
30
30
|
else
|
31
|
-
|
31
|
+
try_next_host
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
def write_timeout(statement, consistency, type, required, received, retries)
|
36
36
|
return reraise if retries > 0
|
37
37
|
|
38
|
-
|
38
|
+
if statement.idempotent? && received.zero?
|
39
|
+
try_next_host
|
40
|
+
elsif type == :batch_log
|
41
|
+
try_again(consistency)
|
42
|
+
else
|
43
|
+
reraise
|
44
|
+
end
|
39
45
|
end
|
40
46
|
|
41
47
|
def unavailable(statement, consistency, required, alive, retries)
|
42
|
-
|
48
|
+
try_next_host
|
43
49
|
end
|
44
50
|
end
|
45
51
|
end
|
data/lib/cassandra/session.rb
CHANGED
@@ -57,9 +57,13 @@ module Cassandra
|
|
57
57
|
# initial request.
|
58
58
|
# @option options [Array, Hash] :arguments (nil) positional or named
|
59
59
|
# arguments for the statement.
|
60
|
-
# @option options [Array, Hash] :type_hints (nil) override Util.guess_type
|
61
|
-
# determine the CQL type for an argument; nil elements will fall-back
|
60
|
+
# @option options [Array, Hash] :type_hints (nil) override Util.guess_type
|
61
|
+
# to determine the CQL type for an argument; nil elements will fall-back
|
62
62
|
# to Util.guess_type.
|
63
|
+
# @option options [Boolean] :idempotent (false) specify whether this
|
64
|
+
# statement can be retried safely on timeout.
|
65
|
+
# @option options [Hash<[String, Symbol], String>] :payload (nil) custom
|
66
|
+
# outgoing payload to be sent with the request.
|
63
67
|
#
|
64
68
|
# @see Cassandra.cluster Options that can be specified on the cluster-level
|
65
69
|
# and their default values.
|
@@ -83,7 +87,7 @@ module Cassandra
|
|
83
87
|
|
84
88
|
case statement
|
85
89
|
when ::String
|
86
|
-
@client.query(Statements::Simple.new(statement, options.arguments, options.type_hints), options)
|
90
|
+
@client.query(Statements::Simple.new(statement, options.arguments, options.type_hints, options.idempotent?), options)
|
87
91
|
when Statements::Simple
|
88
92
|
@client.query(statement, options)
|
89
93
|
when Statements::Prepared
|
@@ -91,6 +95,7 @@ module Cassandra
|
|
91
95
|
when Statements::Bound
|
92
96
|
@client.execute(statement, options)
|
93
97
|
when Statements::Batch
|
98
|
+
Util.assert_not_empty(statement.statements) { "batch cannot be empty" }
|
94
99
|
@client.batch(statement, options)
|
95
100
|
else
|
96
101
|
@futures.error(::ArgumentError.new("unsupported statement #{statement.inspect}"))
|
@@ -131,6 +136,9 @@ module Cassandra
|
|
131
136
|
# @option options [Boolean] :trace (false) whether to enable request tracing
|
132
137
|
# @option options [Numeric] :timeout (nil) if specified, it is a number of
|
133
138
|
# seconds after which to time out the request if it hasn't completed
|
139
|
+
# @option options [Boolean] :idempotent (false) specify whether the
|
140
|
+
# statement being prepared can be retried safely on timeout during
|
141
|
+
# execution.
|
134
142
|
#
|
135
143
|
# @return [Cassandra::Future<Cassandra::Statements::Prepared>] future
|
136
144
|
# prepared statement
|
@@ -169,7 +177,7 @@ module Cassandra
|
|
169
177
|
# @yieldparam batch [Statements::Batch] a logged batch
|
170
178
|
# @return [Statements::Batch] a logged batch
|
171
179
|
def logged_batch(&block)
|
172
|
-
statement = Statements::Batch::Logged.new
|
180
|
+
statement = Statements::Batch::Logged.new(@options)
|
173
181
|
yield(statement) if block_given?
|
174
182
|
statement
|
175
183
|
end
|
@@ -180,7 +188,7 @@ module Cassandra
|
|
180
188
|
# @yieldparam batch [Statements::Batch] an unlogged batch
|
181
189
|
# @return [Statements::Batch] an unlogged batch
|
182
190
|
def unlogged_batch
|
183
|
-
statement = Statements::Batch::Unlogged.new
|
191
|
+
statement = Statements::Batch::Unlogged.new(@options)
|
184
192
|
yield(statement) if block_given?
|
185
193
|
statement
|
186
194
|
end
|
@@ -190,7 +198,7 @@ module Cassandra
|
|
190
198
|
# @yieldparam batch [Statements::Batch] a counter batch
|
191
199
|
# @return [Statements::Batch] a counter batch
|
192
200
|
def counter_batch
|
193
|
-
statement = Statements::Batch::Counter.new
|
201
|
+
statement = Statements::Batch::Counter.new(@options)
|
194
202
|
yield(statement) if block_given?
|
195
203
|
statement
|
196
204
|
end
|
@@ -222,7 +230,7 @@ module Cassandra
|
|
222
230
|
close_async.get
|
223
231
|
end
|
224
232
|
|
225
|
-
# @
|
233
|
+
# @private
|
226
234
|
def inspect
|
227
235
|
"#<#{self.class.name}:0x#{self.object_id.to_s(16)}>"
|
228
236
|
end
|
data/lib/cassandra/statement.rb
CHANGED
@@ -18,7 +18,8 @@
|
|
18
18
|
|
19
19
|
module Cassandra
|
20
20
|
module Statements
|
21
|
-
# Batch statement groups several {Cassandra::Statement}. There are several
|
21
|
+
# Batch statement groups several {Cassandra::Statement}. There are several
|
22
|
+
# types of Batch statements available:
|
22
23
|
# @see Cassandra::Session#batch
|
23
24
|
# @see Cassandra::Session#logged_batch
|
24
25
|
# @see Cassandra::Session#unlogged_batch
|
@@ -43,6 +44,13 @@ module Cassandra
|
|
43
44
|
def type
|
44
45
|
:counter
|
45
46
|
end
|
47
|
+
|
48
|
+
# Determines whether or not the statement is safe to retry on timeout
|
49
|
+
# Counter batches are never considered idempotent.
|
50
|
+
# @return [Boolean] whether the statement is safe to retry on timeout
|
51
|
+
def idempotent?
|
52
|
+
false
|
53
|
+
end
|
46
54
|
end
|
47
55
|
|
48
56
|
include Statement
|
@@ -51,7 +59,8 @@ module Cassandra
|
|
51
59
|
attr_reader :statements
|
52
60
|
|
53
61
|
# @private
|
54
|
-
def initialize
|
62
|
+
def initialize(options)
|
63
|
+
@options = options
|
55
64
|
@statements = []
|
56
65
|
end
|
57
66
|
|
@@ -60,11 +69,16 @@ module Cassandra
|
|
60
69
|
# @param statement [String, Cassandra::Statements::Simple,
|
61
70
|
# Cassandra::Statements::Prepared, Cassandra::Statements::Bound]
|
62
71
|
# statement to add.
|
63
|
-
# @param
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
72
|
+
# @param options [Hash] (nil) a customizable set of options
|
73
|
+
# @option options [Array, Hash] :arguments (nil) positional or named
|
74
|
+
# arguments to bind, must contain the same number of parameters as the
|
75
|
+
# number of positional (`?`) or named (`:name`) markers in the CQL
|
76
|
+
# passed.
|
77
|
+
# @option options [Array, Hash] :type_hints (nil) override Util.guess_type
|
78
|
+
# to determine the CQL type for an argument; nil elements will fall-back
|
79
|
+
# to Util.guess_type.
|
80
|
+
# @option options [Boolean] :idempotent (false) specify whether this
|
81
|
+
# statement can be retried safely on timeout.
|
68
82
|
#
|
69
83
|
# @note Positional arguments for simple statements are only supported
|
70
84
|
# starting with Apache Cassandra 2.0 and above.
|
@@ -73,15 +87,18 @@ module Cassandra
|
|
73
87
|
# starting with Apache Cassandra 2.1 and above.
|
74
88
|
#
|
75
89
|
# @return [self]
|
76
|
-
def add(statement,
|
77
|
-
|
78
|
-
|
90
|
+
def add(statement, options = nil)
|
91
|
+
if options.is_a?(::Hash)
|
92
|
+
options = @options.override(options)
|
93
|
+
else
|
94
|
+
options = @options
|
95
|
+
end
|
79
96
|
|
80
97
|
case statement
|
81
98
|
when String
|
82
|
-
@statements << Simple.new(statement,
|
99
|
+
@statements << Simple.new(statement, options.arguments, options.type_hints, options.idempotent?)
|
83
100
|
when Prepared
|
84
|
-
@statements << statement.bind(
|
101
|
+
@statements << statement.bind(options.arguments)
|
85
102
|
when Bound, Simple
|
86
103
|
@statements << statement
|
87
104
|
else
|
@@ -91,6 +108,13 @@ module Cassandra
|
|
91
108
|
self
|
92
109
|
end
|
93
110
|
|
111
|
+
# Determines whether or not the statement is safe to retry on timeout
|
112
|
+
# Batches are idempotent only when all statements in a batch are.
|
113
|
+
# @return [Boolean] whether the statement is safe to retry on timeout
|
114
|
+
def idempotent?
|
115
|
+
@statements.all?(&:idempotent?)
|
116
|
+
end
|
117
|
+
|
94
118
|
# A batch statement doesn't really have any cql of its own as it is composed of multiple different statements
|
95
119
|
# @return [nil] nothing
|
96
120
|
def cql
|
@@ -30,13 +30,14 @@ module Cassandra
|
|
30
30
|
attr_reader :params_types, :result_metadata, :keyspace, :partition_key
|
31
31
|
|
32
32
|
# @private
|
33
|
-
def initialize(cql, params_types, result_metadata, params, keyspace = nil, partition_key = nil)
|
33
|
+
def initialize(cql, params_types, result_metadata, params, keyspace = nil, partition_key = nil, idempotent = false)
|
34
34
|
@cql = cql
|
35
35
|
@params_types = params_types
|
36
36
|
@result_metadata = result_metadata
|
37
37
|
@params = params
|
38
38
|
@keyspace = keyspace
|
39
39
|
@partition_key = partition_key
|
40
|
+
@idempotent = idempotent
|
40
41
|
end
|
41
42
|
|
42
43
|
# @return [String] a CLI-friendly bound statement representation
|
@@ -29,19 +29,24 @@ module Cassandra
|
|
29
29
|
attr_reader :result_metadata
|
30
30
|
|
31
31
|
# @private
|
32
|
-
def initialize(cql, params_metadata, result_metadata, trace_id, keyspace, statement, options, hosts, consistency, retries, client,
|
33
|
-
@
|
34
|
-
@
|
35
|
-
@
|
36
|
-
@
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@
|
32
|
+
def initialize(payload, warnings, cql, params_metadata, result_metadata, partition_key, trace_id, keyspace, statement, options, hosts, consistency, retries, client, connection_options)
|
33
|
+
@payload = payload
|
34
|
+
@warnings = warnings
|
35
|
+
@cql = cql
|
36
|
+
@params_metadata = params_metadata
|
37
|
+
@result_metadata = result_metadata
|
38
|
+
@partition_key = partition_key
|
39
|
+
@trace_id = trace_id
|
40
|
+
@keyspace = keyspace
|
41
|
+
@statement = statement
|
42
|
+
@options = options
|
43
|
+
@hosts = hosts
|
44
|
+
@consistency = consistency
|
45
|
+
@retries = retries
|
46
|
+
@client = client
|
47
|
+
@connection_options = connection_options
|
48
|
+
@idempotent = options.idempotent?
|
49
|
+
@payload = payload
|
45
50
|
end
|
46
51
|
|
47
52
|
# Creates a statement bound with specific arguments
|
@@ -59,48 +64,114 @@ module Cassandra
|
|
59
64
|
args = EMPTY_LIST
|
60
65
|
end
|
61
66
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
+
params = []
|
68
|
+
param_types = []
|
69
|
+
|
70
|
+
if args.is_a?(::Hash)
|
71
|
+
@params_metadata.each do |(_, _, name, type)|
|
72
|
+
name = name.to_sym unless args.has_key?(name)
|
73
|
+
value = args.fetch(name, NOT_SET)
|
74
|
+
|
75
|
+
if NOT_SET.eql?(value)
|
76
|
+
if @connection_options.protocol_version < 4
|
77
|
+
raise ::ArgumentError, "argument #{name.inspect} it not present in #{args.inspect}"
|
78
|
+
end
|
79
|
+
else
|
80
|
+
Util.assert_type(type, value) { "argument for #{name.inspect} must be #{type}, #{value} given" }
|
67
81
|
end
|
68
82
|
|
69
|
-
|
83
|
+
params << value
|
84
|
+
param_types << type
|
70
85
|
end
|
71
86
|
else
|
72
87
|
Util.assert_equal(@params_metadata.size, args.size) { "expecting exactly #{@params_metadata.size} bind parameters, #{args.size} given" }
|
73
|
-
|
88
|
+
@params_metadata.zip(args) do |(_, _, name, type), value|
|
89
|
+
if NOT_SET.eql?(value)
|
90
|
+
if @connection_options.protocol_version < 4
|
91
|
+
raise ::ArgumentError, "argument #{name.inspect} it not present in #{args.inspect}"
|
92
|
+
end
|
93
|
+
else
|
94
|
+
Util.assert_type(type, value) { "argument for #{name.inspect} must be #{type}, #{value} given" }
|
95
|
+
end
|
74
96
|
|
75
|
-
|
76
|
-
|
77
|
-
|
97
|
+
params << value
|
98
|
+
param_types << type
|
99
|
+
end
|
78
100
|
end
|
79
101
|
|
80
|
-
|
81
|
-
|
82
|
-
keyspace, table, _, _ = @params_metadata.first
|
83
|
-
return Bound.new(@cql, params_types, @result_metadata, args, keyspace) unless keyspace && table
|
84
|
-
|
85
|
-
values = ::Hash.new
|
86
|
-
@params_metadata.zip(args) do |(keyspace, table, column, type), value|
|
87
|
-
values[column] = value
|
88
|
-
end
|
102
|
+
keyspace_name, _ = @params_metadata.first
|
89
103
|
|
90
|
-
partition_key =
|
104
|
+
partition_key = create_partition_key(params)
|
91
105
|
|
92
|
-
Bound.new(@cql,
|
106
|
+
Bound.new(@cql, param_types, @result_metadata, params, keyspace_name, partition_key, @idempotent)
|
93
107
|
end
|
94
108
|
|
95
109
|
# @return [Cassandra::Execution::Info] execution info for PREPARE request
|
96
110
|
def execution_info
|
97
|
-
@info ||= Execution::Info.new(@keyspace, @statement, @options, @hosts, @consistency, @retries, @trace_id ? Execution::Trace.new(@trace_id, @client) : nil)
|
111
|
+
@info ||= Execution::Info.new(@payload, @warnings, @keyspace, @statement, @options, @hosts, @consistency, @retries, @trace_id ? Execution::Trace.new(@trace_id, @client) : nil)
|
98
112
|
end
|
99
113
|
|
100
114
|
# @return [String] a CLI-friendly prepared statement representation
|
101
115
|
def inspect
|
102
116
|
"#<#{self.class.name}:0x#{self.object_id.to_s(16)} @cql=#{@cql.inspect}>"
|
103
117
|
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def create_partition_key(values)
|
122
|
+
partition_key = @partition_key
|
123
|
+
return nil if partition_key.empty? || partition_key.size > values.size
|
124
|
+
params_metadata = @params_metadata
|
125
|
+
|
126
|
+
buffer = Protocol::CqlByteBuffer.new
|
127
|
+
if partition_key.one?
|
128
|
+
i = partition_key.first
|
129
|
+
value = values[i]
|
130
|
+
metadata = params_metadata[i]
|
131
|
+
name = metadata[2]
|
132
|
+
type = metadata[3]
|
133
|
+
|
134
|
+
if NOT_SET.eql?(value)
|
135
|
+
raise ::ArgumentError, "argument #{name.inspect} is a part of " \
|
136
|
+
"the partition key and must be present."
|
137
|
+
end
|
138
|
+
|
139
|
+
if @connection_options.protocol_version >= 3
|
140
|
+
Protocol::Coder.write_value_v3(buffer, value, type)
|
141
|
+
else
|
142
|
+
Protocol::Coder.write_value_v1(buffer, value, type)
|
143
|
+
end
|
144
|
+
|
145
|
+
buffer.discard(4) # discard size
|
146
|
+
else
|
147
|
+
buf = Protocol::CqlByteBuffer.new
|
148
|
+
partition_key.each do |i|
|
149
|
+
value = values[i]
|
150
|
+
metadata = params_metadata[i]
|
151
|
+
name = metadata[2]
|
152
|
+
type = metadata[3]
|
153
|
+
|
154
|
+
if NOT_SET.eql?(value)
|
155
|
+
raise ::ArgumentError, "argument #{name.inspect} is a part of " \
|
156
|
+
"the partition key and must be present."
|
157
|
+
end
|
158
|
+
|
159
|
+
if @connection_options.protocol_version >= 3
|
160
|
+
Protocol::Coder.write_value_v3(buf, value, type)
|
161
|
+
else
|
162
|
+
Protocol::Coder.write_value_v1(buf, value, type)
|
163
|
+
end
|
164
|
+
|
165
|
+
buf.discard(4) # discard size
|
166
|
+
|
167
|
+
size = buf.length
|
168
|
+
buffer.append_short(size)
|
169
|
+
buffer << buf.read(size) << NULL_BYTE
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
buffer.to_str
|
174
|
+
end
|
104
175
|
end
|
105
176
|
end
|
106
177
|
end
|