yugabyte-ycql-driver 3.2.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +13 -0
  3. data/README.md +242 -0
  4. data/ext/cassandra_murmur3/cassandra_murmur3.c +178 -0
  5. data/ext/cassandra_murmur3/extconf.rb +2 -0
  6. data/lib/cassandra/address_resolution.rb +36 -0
  7. data/lib/cassandra/address_resolution/policies.rb +2 -0
  8. data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +56 -0
  9. data/lib/cassandra/address_resolution/policies/none.rb +35 -0
  10. data/lib/cassandra/aggregate.rb +123 -0
  11. data/lib/cassandra/argument.rb +51 -0
  12. data/lib/cassandra/attr_boolean.rb +33 -0
  13. data/lib/cassandra/auth.rb +100 -0
  14. data/lib/cassandra/auth/providers.rb +17 -0
  15. data/lib/cassandra/auth/providers/password.rb +65 -0
  16. data/lib/cassandra/cassandra_logger.rb +80 -0
  17. data/lib/cassandra/cluster.rb +331 -0
  18. data/lib/cassandra/cluster/client.rb +1612 -0
  19. data/lib/cassandra/cluster/connection_pool.rb +78 -0
  20. data/lib/cassandra/cluster/connector.rb +372 -0
  21. data/lib/cassandra/cluster/control_connection.rb +962 -0
  22. data/lib/cassandra/cluster/failed_connection.rb +35 -0
  23. data/lib/cassandra/cluster/metadata.rb +142 -0
  24. data/lib/cassandra/cluster/options.rb +145 -0
  25. data/lib/cassandra/cluster/registry.rb +284 -0
  26. data/lib/cassandra/cluster/schema.rb +405 -0
  27. data/lib/cassandra/cluster/schema/cql_type_parser.rb +112 -0
  28. data/lib/cassandra/cluster/schema/fetchers.rb +1627 -0
  29. data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +175 -0
  30. data/lib/cassandra/cluster/schema/partitioners.rb +21 -0
  31. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +45 -0
  32. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +37 -0
  33. data/lib/cassandra/cluster/schema/partitioners/random.rb +37 -0
  34. data/lib/cassandra/cluster/schema/replication_strategies.rb +21 -0
  35. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +102 -0
  36. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +39 -0
  37. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +44 -0
  38. data/lib/cassandra/column.rb +66 -0
  39. data/lib/cassandra/column_container.rb +326 -0
  40. data/lib/cassandra/compression.rb +69 -0
  41. data/lib/cassandra/compression/compressors/lz4.rb +73 -0
  42. data/lib/cassandra/compression/compressors/snappy.rb +69 -0
  43. data/lib/cassandra/custom_data.rb +53 -0
  44. data/lib/cassandra/driver.rb +260 -0
  45. data/lib/cassandra/errors.rb +784 -0
  46. data/lib/cassandra/execution/info.rb +69 -0
  47. data/lib/cassandra/execution/options.rb +267 -0
  48. data/lib/cassandra/execution/profile.rb +153 -0
  49. data/lib/cassandra/execution/profile_manager.rb +71 -0
  50. data/lib/cassandra/execution/trace.rb +192 -0
  51. data/lib/cassandra/executors.rb +113 -0
  52. data/lib/cassandra/function.rb +156 -0
  53. data/lib/cassandra/function_collection.rb +85 -0
  54. data/lib/cassandra/future.rb +794 -0
  55. data/lib/cassandra/host.rb +102 -0
  56. data/lib/cassandra/index.rb +118 -0
  57. data/lib/cassandra/keyspace.rb +473 -0
  58. data/lib/cassandra/listener.rb +87 -0
  59. data/lib/cassandra/load_balancing.rb +121 -0
  60. data/lib/cassandra/load_balancing/policies.rb +20 -0
  61. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +172 -0
  62. data/lib/cassandra/load_balancing/policies/round_robin.rb +141 -0
  63. data/lib/cassandra/load_balancing/policies/token_aware.rb +149 -0
  64. data/lib/cassandra/load_balancing/policies/white_list.rb +100 -0
  65. data/lib/cassandra/materialized_view.rb +92 -0
  66. data/lib/cassandra/null_logger.rb +56 -0
  67. data/lib/cassandra/protocol.rb +102 -0
  68. data/lib/cassandra/protocol/coder.rb +1085 -0
  69. data/lib/cassandra/protocol/cql_byte_buffer.rb +418 -0
  70. data/lib/cassandra/protocol/cql_protocol_handler.rb +448 -0
  71. data/lib/cassandra/protocol/request.rb +41 -0
  72. data/lib/cassandra/protocol/requests/auth_response_request.rb +51 -0
  73. data/lib/cassandra/protocol/requests/batch_request.rb +117 -0
  74. data/lib/cassandra/protocol/requests/credentials_request.rb +51 -0
  75. data/lib/cassandra/protocol/requests/execute_request.rb +122 -0
  76. data/lib/cassandra/protocol/requests/options_request.rb +39 -0
  77. data/lib/cassandra/protocol/requests/prepare_request.rb +59 -0
  78. data/lib/cassandra/protocol/requests/query_request.rb +112 -0
  79. data/lib/cassandra/protocol/requests/register_request.rb +38 -0
  80. data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
  81. data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
  82. data/lib/cassandra/protocol/response.rb +28 -0
  83. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +50 -0
  84. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +36 -0
  85. data/lib/cassandra/protocol/responses/auth_success_response.rb +36 -0
  86. data/lib/cassandra/protocol/responses/authenticate_response.rb +36 -0
  87. data/lib/cassandra/protocol/responses/error_response.rb +142 -0
  88. data/lib/cassandra/protocol/responses/event_response.rb +30 -0
  89. data/lib/cassandra/protocol/responses/function_failure_error_response.rb +52 -0
  90. data/lib/cassandra/protocol/responses/prepared_result_response.rb +62 -0
  91. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +59 -0
  92. data/lib/cassandra/protocol/responses/read_failure_error_response.rb +71 -0
  93. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +61 -0
  94. data/lib/cassandra/protocol/responses/ready_response.rb +43 -0
  95. data/lib/cassandra/protocol/responses/result_response.rb +42 -0
  96. data/lib/cassandra/protocol/responses/rows_result_response.rb +39 -0
  97. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +73 -0
  98. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +70 -0
  99. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +37 -0
  100. data/lib/cassandra/protocol/responses/status_change_event_response.rb +39 -0
  101. data/lib/cassandra/protocol/responses/supported_response.rb +36 -0
  102. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +33 -0
  103. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +58 -0
  104. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +48 -0
  105. data/lib/cassandra/protocol/responses/void_result_response.rb +34 -0
  106. data/lib/cassandra/protocol/responses/write_failure_error_response.rb +73 -0
  107. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +63 -0
  108. data/lib/cassandra/protocol/v1.rb +326 -0
  109. data/lib/cassandra/protocol/v3.rb +358 -0
  110. data/lib/cassandra/protocol/v4.rb +478 -0
  111. data/lib/cassandra/reconnection.rb +49 -0
  112. data/lib/cassandra/reconnection/policies.rb +20 -0
  113. data/lib/cassandra/reconnection/policies/constant.rb +46 -0
  114. data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
  115. data/lib/cassandra/result.rb +276 -0
  116. data/lib/cassandra/retry.rb +154 -0
  117. data/lib/cassandra/retry/policies.rb +21 -0
  118. data/lib/cassandra/retry/policies/default.rb +53 -0
  119. data/lib/cassandra/retry/policies/downgrading_consistency.rb +73 -0
  120. data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
  121. data/lib/cassandra/session.rb +270 -0
  122. data/lib/cassandra/statement.rb +32 -0
  123. data/lib/cassandra/statements.rb +23 -0
  124. data/lib/cassandra/statements/batch.rb +146 -0
  125. data/lib/cassandra/statements/bound.rb +65 -0
  126. data/lib/cassandra/statements/prepared.rb +235 -0
  127. data/lib/cassandra/statements/simple.rb +118 -0
  128. data/lib/cassandra/statements/void.rb +38 -0
  129. data/lib/cassandra/table.rb +240 -0
  130. data/lib/cassandra/time.rb +103 -0
  131. data/lib/cassandra/time_uuid.rb +78 -0
  132. data/lib/cassandra/timestamp_generator.rb +37 -0
  133. data/lib/cassandra/timestamp_generator/simple.rb +38 -0
  134. data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
  135. data/lib/cassandra/trigger.rb +67 -0
  136. data/lib/cassandra/tuple.rb +131 -0
  137. data/lib/cassandra/types.rb +1704 -0
  138. data/lib/cassandra/udt.rb +443 -0
  139. data/lib/cassandra/util.rb +464 -0
  140. data/lib/cassandra/uuid.rb +110 -0
  141. data/lib/cassandra/uuid/generator.rb +212 -0
  142. data/lib/cassandra/version.rb +21 -0
  143. data/lib/datastax/cassandra.rb +47 -0
  144. data/lib/ycql.rb +842 -0
  145. metadata +243 -0
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 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
+ class Info
22
+ # @return [Hash<String, String>] a map of string keys and byte buffer
23
+ # values, containing custom payloads sent by custom query handlers
24
+ attr_reader :payload
25
+ # @return [Array<String>] a list of string warnings from the server
26
+ attr_reader :warnings
27
+ # @return [String] keyspace used for the query
28
+ attr_reader :keyspace
29
+ # @return [Cassandra::Statement] original statement
30
+ attr_reader :statement
31
+ # @return [Cassandra::Execution::Options] original execution options
32
+ attr_reader :options
33
+ # @return [Array<Cassandra::Host>] a list of attempted hosts
34
+ attr_reader :hosts
35
+ # Actual consistency used, it can differ from consistency in
36
+ # {Cassandra::Execution::Info#options} if a retry policy modified it.
37
+ # @return [Symbol] one of {Cassandra::CONSISTENCIES}
38
+ attr_reader :consistency
39
+ # @return [Integer] number of retries
40
+ attr_reader :retries
41
+ # Returns {Cassandra::Execution::Trace} if `trace: true` was passed to
42
+ # {Cassandra::Session#execute} or {Cassandra::Session#execute_async}
43
+ # @return [Cassandra::Execution::Trace, nil] a Trace if it has been enabled for
44
+ # request
45
+ attr_reader :trace
46
+
47
+ # @private
48
+ def initialize(payload,
49
+ warnings,
50
+ keyspace,
51
+ statement,
52
+ options,
53
+ hosts,
54
+ consistency,
55
+ retries,
56
+ trace)
57
+ @payload = payload
58
+ @warnings = warnings
59
+ @keyspace = keyspace
60
+ @statement = statement
61
+ @options = options
62
+ @hosts = hosts
63
+ @consistency = consistency
64
+ @retries = retries
65
+ @trace = trace
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,267 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 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
+ class Options
22
+ # @return [Symbol] consistency for request. Must be one of
23
+ # {Cassandra::CONSISTENCIES}
24
+ attr_reader :consistency
25
+ # @return [Symbol] consistency for request with conditional updates
26
+ # (lightweight - compare-and-set, CAS - transactions). Must be one of
27
+ # {Cassandra::SERIAL_CONSISTENCIES}
28
+ attr_reader :serial_consistency
29
+ # @return [Integer] requested page size
30
+ attr_reader :page_size
31
+ # @return [Numeric] request timeout interval
32
+ attr_reader :timeout
33
+ # @return [Array] positional arguments for the statement
34
+ attr_reader :arguments
35
+ # @return [Array] type hints for positional arguments for the statement
36
+ attr_reader :type_hints
37
+
38
+ # @return [String] paging state
39
+ #
40
+ # @note Although this feature exists to allow web applications to store
41
+ # paging state in an [HTTP cookie](http://en.wikipedia.org/wiki/HTTP_cookie),
42
+ # **it is not safe to expose without encrypting or otherwise securing it**.
43
+ # Paging state contains information internal to the Apache Cassandra cluster,
44
+ # such as partition key and data. Additionally, if a paging state is sent with
45
+ # CQL statement, different from the original, the behavior of Cassandra is
46
+ # undefined and will likely cause a server process of the coordinator of
47
+ # such request to abort.
48
+ #
49
+ # @see Cassandra::Result#paging_state
50
+ attr_reader :paging_state
51
+
52
+ # @return [nil, Hash<String, String>] custom outgoing payload, a map of
53
+ # string and byte buffers.
54
+ #
55
+ # @see https://github.com/apache/cassandra/blob/cassandra-3.4/doc/native_protocol_v4.spec#L125-L131 Description
56
+ # of custom payload in Cassandra native protocol v4.
57
+ # @see http://dsdocs30_java/manual/custom_payloads/#enabling-custom-payloads-on-c-nodes
58
+ # Enabling custom payloads on Cassandra nodes.
59
+ #
60
+ # @example Sending a custom payload
61
+ # result = session.execute(payload: {
62
+ # 'some key' => Cassandra::Protocol::CqlByteBuffer.new
63
+ # .append_string('some value')
64
+ # })
65
+ attr_reader :payload
66
+
67
+ # @return [Cassandra::LoadBalancing::Policy] load-balancing policy that determines which node will run the
68
+ # next statement.
69
+ attr_reader :load_balancing_policy
70
+
71
+ # @return [Cassandra::Retry::Policy] retry policy that determines how request retries should be handled for
72
+ # different failure modes.
73
+ attr_reader :retry_policy
74
+
75
+ # @private
76
+ # @param options [Hash] execution options to validate and encapsulate
77
+ # @param trusted_options [Options] (optional) base Execution::Options from which
78
+ # to create this new Options object.
79
+ def initialize(options, trusted_options = nil)
80
+ consistency = options[:consistency]
81
+ page_size = options[:page_size]
82
+ trace = options[:trace]
83
+ timeout = options[:timeout]
84
+ serial_consistency = options[:serial_consistency]
85
+ paging_state = options[:paging_state]
86
+ arguments = options[:arguments]
87
+ type_hints = options[:type_hints]
88
+ idempotent = options[:idempotent]
89
+ payload = options[:payload]
90
+ load_balancing_policy = options[:load_balancing_policy]
91
+ retry_policy = options[:retry_policy]
92
+
93
+ # consistency is a required attribute of an Options object. If we are creating
94
+ # an Options object from scratch (e.g. no trusted_options as base) validate the
95
+ # given consistency value (even if nil). Otherwise we're overlaying and only
96
+ # validate the consistency option if given.
97
+ if trusted_options.nil? || !consistency.nil?
98
+ Util.assert_one_of(CONSISTENCIES, consistency) do
99
+ ":consistency must be one of #{CONSISTENCIES.inspect}, " \
100
+ "#{consistency.inspect} given"
101
+ end
102
+ end
103
+
104
+ # load_balancing_policy and retry_policy are required, but can fallback to trusted_options, just like
105
+ # consistency.
106
+ if trusted_options.nil? || !load_balancing_policy.nil?
107
+ methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :teardown,
108
+ :distance, :plan]
109
+ Util.assert_responds_to_all(methods, load_balancing_policy,
110
+ ":load_balancing_policy #{load_balancing_policy.inspect} must respond " \
111
+ "to #{methods.inspect}, but doesn't")
112
+ end
113
+ if trusted_options.nil? || !retry_policy.nil?
114
+ methods = [:read_timeout, :write_timeout, :unavailable]
115
+ Util.assert_responds_to_all(methods, retry_policy,
116
+ ":retry_policy #{retry_policy.inspect} must respond to #{methods.inspect}, " \
117
+ "but doesn't")
118
+ end
119
+
120
+ unless serial_consistency.nil?
121
+ Util.assert_one_of(SERIAL_CONSISTENCIES, serial_consistency) do
122
+ ":serial_consistency must be one of #{SERIAL_CONSISTENCIES.inspect}, " \
123
+ "#{serial_consistency.inspect} given"
124
+ end
125
+ end
126
+
127
+ unless page_size.nil?
128
+ page_size = Integer(page_size)
129
+ Util.assert(page_size > 0) do
130
+ ":page_size must be a positive integer, #{page_size.inspect} given"
131
+ end
132
+ end
133
+
134
+ unless timeout.nil?
135
+ Util.assert_instance_of(::Numeric, timeout) do
136
+ ":timeout must be a number of seconds, #{timeout} given"
137
+ end
138
+ Util.assert(timeout > 0) { ":timeout must be greater than 0, #{timeout} given" }
139
+ end
140
+
141
+ unless paging_state.nil?
142
+ paging_state = String(paging_state)
143
+ Util.assert_not_empty(paging_state) { ':paging_state must not be empty' }
144
+
145
+ # We require page_size in either the new options or trusted options.
146
+ Util.assert(!page_size.nil? ||
147
+ !(trusted_options.nil? || trusted_options.page_size.nil?)) do
148
+ ':page_size is required when :paging_state is given'
149
+ end
150
+ end
151
+
152
+ # :arguments defaults to empty-list, but we want to delegate to trusted_options
153
+ # if it's set. So the logic is as follows:
154
+ # If an arguments option was given, validate and use it regardless of anything
155
+ # else.
156
+ # Otherwise, if we have trusted_options, leave arguments nil for now so as not
157
+ # to override trusted_options. Finally, if we don't have an arguments option
158
+ # nor do we have trusted_options, fall back to the default empty-list.
159
+ #
160
+ # :type_hints works exactly the same way.
161
+ if !arguments.nil?
162
+ Util.assert_instance_of_one_of([::Array, ::Hash], arguments) do
163
+ ":arguments must be an Array or a Hash, #{arguments.inspect} given"
164
+ end
165
+ elsif trusted_options.nil?
166
+ arguments = EMPTY_LIST
167
+ end
168
+
169
+ if !type_hints.nil?
170
+ Util.assert_instance_of_one_of([::Array, ::Hash], type_hints) do
171
+ ":type_hints must be an Array or a Hash, #{type_hints.inspect} given"
172
+ end
173
+ elsif trusted_options.nil?
174
+ type_hints = EMPTY_LIST
175
+ end
176
+
177
+ unless payload.nil?
178
+ Util.assert_instance_of(::Hash, payload) { ':payload must be a Hash' }
179
+ Util.assert_not_empty(payload) { ':payload must not be empty' }
180
+ Util.assert(payload.size <= 65535) do
181
+ ':payload cannot contain more than 65535 key/value pairs'
182
+ end
183
+
184
+ payload = payload.each_with_object(::Hash.new) do |(key, value), p|
185
+ p[String(key)] = String(value)
186
+ end
187
+ payload.freeze
188
+ end
189
+
190
+ # Ok, validation is done. Time to save off all our values in our instance vars,
191
+ # merging in values from trusted_options if it's set. To keep things readable,
192
+ # we just put this into two branches of an if-else.
193
+
194
+ if trusted_options.nil?
195
+ @consistency = consistency
196
+ @page_size = page_size
197
+ @trace = !!trace
198
+ @timeout = timeout
199
+ @serial_consistency = serial_consistency
200
+ @arguments = arguments
201
+ @type_hints = type_hints
202
+ @load_balancing_policy = load_balancing_policy
203
+ @retry_policy = retry_policy
204
+ else
205
+ @consistency = consistency || trusted_options.consistency
206
+ @page_size = page_size || trusted_options.page_size
207
+ @trace = trace.nil? ? trusted_options.trace? : !!trace
208
+ @timeout = options.key?(:timeout) ? timeout : trusted_options.timeout
209
+ @serial_consistency = serial_consistency || trusted_options.serial_consistency
210
+ @arguments = arguments || trusted_options.arguments
211
+ @type_hints = type_hints || trusted_options.type_hints
212
+ @load_balancing_policy = load_balancing_policy || trusted_options.load_balancing_policy
213
+ @retry_policy = retry_policy || trusted_options.retry_policy
214
+ end
215
+
216
+ # The following fields are *not* inherited from trusted_options, so we always
217
+ # rely on the options we were given.
218
+ @paging_state = paging_state
219
+ @idempotent = !!idempotent
220
+ @payload = payload
221
+ end
222
+
223
+ # @return [Boolean] whether request tracing was enabled
224
+ def trace?
225
+ @trace
226
+ end
227
+
228
+ # @return [Boolean] whether statement can be retried on timeout
229
+ def idempotent?
230
+ @idempotent
231
+ end
232
+
233
+ # @private
234
+ def eql?(other)
235
+ other.is_a?(Options) &&
236
+ other.consistency == @consistency &&
237
+ other.page_size == @page_size &&
238
+ other.trace? == @trace &&
239
+ other.timeout == @timeout &&
240
+ other.serial_consistency == @serial_consistency &&
241
+ other.paging_state == @paging_state &&
242
+ other.arguments == @arguments &&
243
+ other.type_hints == @type_hints &&
244
+ other.load_balancing_policy == @load_balancing_policy &&
245
+ other.retry_policy == @retry_policy
246
+ end
247
+ alias == eql?
248
+
249
+ # @private
250
+ def override(*options)
251
+ merged = options.unshift({}).inject do |base, opts|
252
+ # Skip nil args
253
+ next base unless opts
254
+
255
+ if opts.is_a?(Cassandra::Execution::Profile)
256
+ base.merge!(opts.to_h)
257
+ else
258
+ Util.assert_instance_of(::Hash, opts, "options must be a Hash, #{opts.inspect} given")
259
+ base.merge!(opts)
260
+ end
261
+ end
262
+
263
+ Options.new(merged, self)
264
+ end
265
+ end
266
+ end
267
+ end
@@ -0,0 +1,153 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 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
+ # A profile is a collection of settings to use when executing and preparing statements. Register different
22
+ # profiles when creating the {Cassandra::Cluster} and execute/prepare statements with a particular profile
23
+ # by providing its name to the relevant method in {Session}.
24
+ #
25
+ # @see Cassandra.cluster
26
+ # @see Session#execute_async
27
+ # @see Session#execute
28
+ # @see Session#prepare_async
29
+ # @see Session#prepare
30
+ class Profile
31
+ # @return [Cassandra::LoadBalancing::Policy] load-balancing policy that determines which node will run the
32
+ # next statement.
33
+ attr_reader :load_balancing_policy
34
+
35
+ # @return [Cassandra::Retry::Policy] retry policy that determines how request retries should be handled for
36
+ # different failure modes.
37
+ attr_reader :retry_policy
38
+
39
+ # @return [Symbol] consistency level with which to run statements.
40
+ attr_reader :consistency
41
+
42
+ # @return [Numeric] request execution timeout in seconds. `nil` means there is no timeout.
43
+ attr_reader :timeout
44
+
45
+ # @private
46
+ DEFAULT_OPTIONS = { consistency: :quorum, timeout: 12 }.freeze
47
+
48
+ # @param options [Hash] hash of attributes. Unspecified attributes fall back to system defaults.
49
+ # @option options [Numeric] :timeout (12) Request execution timeout in
50
+ # seconds. Setting value to `nil` will remove request timeout.
51
+ # @option options [Cassandra::LoadBalancing::Policy] :load_balancing_policy (
52
+ # LoadBalancing::Policies::TokenAware(LoadBalancing::Policies::DCAwareRoundRobin)) Load-balancing policy
53
+ # that determines which node will run the next statement.
54
+ # @option options [Cassandra::Retry::Policy] :retry_policy (Retry::Policies::Default) Retry policy that
55
+ # determines how request retries should be handled for different failure modes.
56
+ # @option options [Symbol] :consistency (:quorum) Consistency level with which to run statements. Must be one
57
+ # of {Cassandra::CONSISTENCIES}.
58
+ def initialize(options = {})
59
+ validate(options)
60
+ options = DEFAULT_OPTIONS.merge(options)
61
+ @load_balancing_policy = options[:load_balancing_policy] ||
62
+ LoadBalancing::Policies::TokenAware.new(
63
+ LoadBalancing::Policies::DCAwareRoundRobin.new,
64
+ true)
65
+ @retry_policy = options[:retry_policy] || Retry::Policies::Default.new
66
+ @consistency = options[:consistency]
67
+ @timeout = options[:timeout]
68
+ end
69
+
70
+ # @private
71
+ def to_h
72
+ {
73
+ load_balancing_policy: @load_balancing_policy,
74
+ retry_policy: @retry_policy,
75
+ consistency: @consistency,
76
+ timeout: @timeout
77
+ }
78
+ end
79
+
80
+ # @private
81
+ def eql?(other)
82
+ other.is_a?(Profile) && \
83
+ @load_balancing_policy == other.load_balancing_policy && \
84
+ @retry_policy == other.retry_policy && \
85
+ @consistency == other.consistency && \
86
+ @timeout == other.timeout
87
+ end
88
+ alias == eql?
89
+
90
+ # @private
91
+ def hash
92
+ @hash ||= begin
93
+ h = 17
94
+ h = 31 * h + @load_balancing_policy.hash
95
+ h = 31 * h + @retry_policy.hash
96
+ h = 31 * h + @consistency.hash
97
+ h = 31 * h + @timeout.hash
98
+ h
99
+ end
100
+ end
101
+
102
+ # @private
103
+ def inspect
104
+ "#<#{self.class.name}:0x#{object_id.to_s(16)} " \
105
+ "load_balancing_policy=#{@load_balancing_policy.inspect}, " \
106
+ "retry_policy=#{@retry_policy.inspect}, " \
107
+ "consistency=#{@consistency.inspect}, " \
108
+ "timeout=#{@timeout.inspect}>"
109
+ end
110
+
111
+ # @private
112
+ def validate(options)
113
+ if options.key?(:timeout)
114
+ timeout = options[:timeout]
115
+
116
+ unless timeout.nil?
117
+ Util.assert_instance_of(::Numeric,
118
+ timeout,
119
+ ":timeout must be a number of seconds,
120
+ #{timeout.inspect} given")
121
+ Util.assert(timeout > 0, ":timeout must be greater than 0, #{timeout} given")
122
+ end
123
+ end
124
+
125
+ if options.key?(:load_balancing_policy)
126
+ load_balancing_policy = options[:load_balancing_policy]
127
+ methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :teardown,
128
+ :distance, :plan]
129
+ Util.assert_responds_to_all(methods, load_balancing_policy) do
130
+ ":load_balancing_policy #{load_balancing_policy.inspect} must respond " \
131
+ "to #{methods.inspect}, but doesn't"
132
+ end
133
+ end
134
+
135
+ if options.key?(:retry_policy)
136
+ retry_policy = options[:retry_policy]
137
+ methods = [:read_timeout, :write_timeout, :unavailable]
138
+ Util.assert_responds_to_all(methods, retry_policy) do
139
+ ":retry_policy #{retry_policy.inspect} must respond to #{methods.inspect}, " \
140
+ "but doesn't"
141
+ end
142
+ end
143
+
144
+ if options.key?(:consistency)
145
+ consistency = options[:consistency]
146
+ Util.assert_one_of(CONSISTENCIES, consistency,
147
+ ":consistency must be one of #{CONSISTENCIES.inspect}, " \
148
+ "#{consistency.inspect} given")
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end