cassandra-driver 1.0.0.beta.2-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.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +4 -0
  3. data/README.md +125 -0
  4. data/lib/cassandra/auth/providers/password.rb +73 -0
  5. data/lib/cassandra/auth/providers.rb +16 -0
  6. data/lib/cassandra/auth.rb +97 -0
  7. data/lib/cassandra/client/batch.rb +212 -0
  8. data/lib/cassandra/client/client.rb +591 -0
  9. data/lib/cassandra/client/column_metadata.rb +54 -0
  10. data/lib/cassandra/client/connection_manager.rb +72 -0
  11. data/lib/cassandra/client/connector.rb +277 -0
  12. data/lib/cassandra/client/execute_options_decoder.rb +59 -0
  13. data/lib/cassandra/client/null_logger.rb +37 -0
  14. data/lib/cassandra/client/peer_discovery.rb +50 -0
  15. data/lib/cassandra/client/prepared_statement.rb +314 -0
  16. data/lib/cassandra/client/query_result.rb +230 -0
  17. data/lib/cassandra/client/request_runner.rb +71 -0
  18. data/lib/cassandra/client/result_metadata.rb +48 -0
  19. data/lib/cassandra/client/void_result.rb +78 -0
  20. data/lib/cassandra/client.rb +144 -0
  21. data/lib/cassandra/cluster/client.rb +768 -0
  22. data/lib/cassandra/cluster/connector.rb +244 -0
  23. data/lib/cassandra/cluster/control_connection.rb +425 -0
  24. data/lib/cassandra/cluster/metadata.rb +124 -0
  25. data/lib/cassandra/cluster/options.rb +42 -0
  26. data/lib/cassandra/cluster/registry.rb +198 -0
  27. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +47 -0
  28. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +37 -0
  29. data/lib/cassandra/cluster/schema/partitioners/random.rb +37 -0
  30. data/lib/cassandra/cluster/schema/partitioners.rb +21 -0
  31. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +92 -0
  32. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +39 -0
  33. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +44 -0
  34. data/lib/cassandra/cluster/schema/replication_strategies.rb +21 -0
  35. data/lib/cassandra/cluster/schema/type_parser.rb +138 -0
  36. data/lib/cassandra/cluster/schema.rb +340 -0
  37. data/lib/cassandra/cluster.rb +215 -0
  38. data/lib/cassandra/column.rb +92 -0
  39. data/lib/cassandra/compression/compressors/lz4.rb +72 -0
  40. data/lib/cassandra/compression/compressors/snappy.rb +66 -0
  41. data/lib/cassandra/compression.rb +66 -0
  42. data/lib/cassandra/driver.rb +111 -0
  43. data/lib/cassandra/errors.rb +79 -0
  44. data/lib/cassandra/execution/info.rb +51 -0
  45. data/lib/cassandra/execution/options.rb +80 -0
  46. data/lib/cassandra/execution/trace.rb +152 -0
  47. data/lib/cassandra/future.rb +675 -0
  48. data/lib/cassandra/host.rb +79 -0
  49. data/lib/cassandra/keyspace.rb +133 -0
  50. data/lib/cassandra/listener.rb +87 -0
  51. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +149 -0
  52. data/lib/cassandra/load_balancing/policies/round_robin.rb +132 -0
  53. data/lib/cassandra/load_balancing/policies/token_aware.rb +119 -0
  54. data/lib/cassandra/load_balancing/policies/white_list.rb +90 -0
  55. data/lib/cassandra/load_balancing/policies.rb +19 -0
  56. data/lib/cassandra/load_balancing.rb +113 -0
  57. data/lib/cassandra/protocol/cql_byte_buffer.rb +307 -0
  58. data/lib/cassandra/protocol/cql_protocol_handler.rb +323 -0
  59. data/lib/cassandra/protocol/frame_decoder.rb +128 -0
  60. data/lib/cassandra/protocol/frame_encoder.rb +48 -0
  61. data/lib/cassandra/protocol/request.rb +38 -0
  62. data/lib/cassandra/protocol/requests/auth_response_request.rb +47 -0
  63. data/lib/cassandra/protocol/requests/batch_request.rb +76 -0
  64. data/lib/cassandra/protocol/requests/credentials_request.rb +47 -0
  65. data/lib/cassandra/protocol/requests/execute_request.rb +103 -0
  66. data/lib/cassandra/protocol/requests/options_request.rb +39 -0
  67. data/lib/cassandra/protocol/requests/prepare_request.rb +50 -0
  68. data/lib/cassandra/protocol/requests/query_request.rb +153 -0
  69. data/lib/cassandra/protocol/requests/register_request.rb +38 -0
  70. data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
  71. data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
  72. data/lib/cassandra/protocol/response.rb +38 -0
  73. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +41 -0
  74. data/lib/cassandra/protocol/responses/auth_success_response.rb +41 -0
  75. data/lib/cassandra/protocol/responses/authenticate_response.rb +41 -0
  76. data/lib/cassandra/protocol/responses/detailed_error_response.rb +60 -0
  77. data/lib/cassandra/protocol/responses/error_response.rb +50 -0
  78. data/lib/cassandra/protocol/responses/event_response.rb +39 -0
  79. data/lib/cassandra/protocol/responses/prepared_result_response.rb +64 -0
  80. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +43 -0
  81. data/lib/cassandra/protocol/responses/ready_response.rb +44 -0
  82. data/lib/cassandra/protocol/responses/result_response.rb +48 -0
  83. data/lib/cassandra/protocol/responses/rows_result_response.rb +139 -0
  84. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +60 -0
  85. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +57 -0
  86. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +42 -0
  87. data/lib/cassandra/protocol/responses/status_change_event_response.rb +44 -0
  88. data/lib/cassandra/protocol/responses/supported_response.rb +41 -0
  89. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +34 -0
  90. data/lib/cassandra/protocol/responses/void_result_response.rb +39 -0
  91. data/lib/cassandra/protocol/type_converter.rb +384 -0
  92. data/lib/cassandra/protocol.rb +93 -0
  93. data/lib/cassandra/reconnection/policies/constant.rb +48 -0
  94. data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
  95. data/lib/cassandra/reconnection/policies.rb +20 -0
  96. data/lib/cassandra/reconnection.rb +49 -0
  97. data/lib/cassandra/result.rb +215 -0
  98. data/lib/cassandra/retry/policies/default.rb +47 -0
  99. data/lib/cassandra/retry/policies/downgrading_consistency.rb +71 -0
  100. data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
  101. data/lib/cassandra/retry/policies.rb +21 -0
  102. data/lib/cassandra/retry.rb +142 -0
  103. data/lib/cassandra/session.rb +202 -0
  104. data/lib/cassandra/statement.rb +22 -0
  105. data/lib/cassandra/statements/batch.rb +95 -0
  106. data/lib/cassandra/statements/bound.rb +48 -0
  107. data/lib/cassandra/statements/prepared.rb +81 -0
  108. data/lib/cassandra/statements/simple.rb +58 -0
  109. data/lib/cassandra/statements/void.rb +33 -0
  110. data/lib/cassandra/statements.rb +23 -0
  111. data/lib/cassandra/table.rb +299 -0
  112. data/lib/cassandra/time_uuid.rb +142 -0
  113. data/lib/cassandra/util.rb +167 -0
  114. data/lib/cassandra/uuid.rb +104 -0
  115. data/lib/cassandra/version.rb +21 -0
  116. data/lib/cassandra.rb +428 -0
  117. data/lib/cassandra_murmur3.jar +0 -0
  118. metadata +211 -0
@@ -0,0 +1,314 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2014 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 Client
21
+ # A prepared statement are CQL queries that have been sent to the server
22
+ # to be precompiled, so that when executed only their ID and not the whole
23
+ # CQL string need to be sent. They support bound values, or placeholders
24
+ # for values.
25
+ #
26
+ # Using a prepared statement for any query that you execute more than once
27
+ # is highly recommended. Besides the benefit of having less network overhead,
28
+ # and less processing overhead on the server side, they don't require you
29
+ # to build CQL strings and escape special characters, or format non-character
30
+ # data such as UUIDs, different numeric types, or collections, in the
31
+ # correct way.
32
+ #
33
+ # You should only prepare a statement once and reuse the prepared statement
34
+ # object every time you want to execute that particular query. The statement
35
+ # object will make sure that it is prepared on all connections, and will
36
+ # (lazily, but transparently) make sure it is prepared on any new connections.
37
+ #
38
+ # It is an anti-pattern to prepare the same query over and over again. It is
39
+ # bad for performance, since every preparation requires a roundtrip to all
40
+ # connected servers, and because of some bookeeping that is done to support
41
+ # automatic preparation on new connections, it will lead to unnecessary
42
+ # extra memory usage. There is no performance benefit in creating multiple
43
+ # prepared statement objects for the same query.
44
+ #
45
+ # Prepared statement objects are completely thread safe and can be shared
46
+ # across all threads in your application.
47
+ #
48
+ # @see Cassandra::Client::Client#prepare
49
+ class PreparedStatement
50
+ # Metadata describing the bound values
51
+ #
52
+ # @return [ResultMetadata]
53
+ attr_reader :metadata
54
+
55
+ # Metadata about the result (i.e. rows) that is returned when executing
56
+ # this prepared statement.
57
+ #
58
+ # @return [ResultMetadata]
59
+ attr_reader :result_metadata
60
+
61
+ # Execute the prepared statement with a list of values to be bound to the
62
+ # statements parameters.
63
+ #
64
+ # The number of arguments must equal the number of bound parameters. You
65
+ # can also specify options as the last argument, or a symbol as a shortcut
66
+ # for just specifying the consistency.
67
+ #
68
+ # Because you can specify options, or not, there is an edge case where if
69
+ # the last parameter of your prepared statement is a map, and you forget
70
+ # to specify a value for your map, the options will end up being sent to
71
+ # Cassandra. Most other cases when you specify the wrong number of
72
+ # arguments should result in an `ArgumentError` or `TypeError` being
73
+ # raised.
74
+ #
75
+ # @example Preparing and executing an `INSERT` statement
76
+ # statement = client.prepare(%(INSERT INTO metrics (id, time, value) VALUES (?, NOW(), ?)))
77
+ # statement.execute(1234, 23432)
78
+ # statement.execute(2345, 34543, tracing: true)
79
+ # statement.execute(3456, 45654, consistency: :one)
80
+ #
81
+ # @example Preparing and executing a `SELECT` statement
82
+ # statement = client.prepare(%(SELECT * FROM metrics WHERE id = ? AND time > ?))
83
+ # result = statement.execute(1234, Time.now - 3600)
84
+ # result.each do |row|
85
+ # p row
86
+ # end
87
+ #
88
+ # @param args [Array] the values for the bound parameters, and an optional
89
+ # hash of options as last argument – see {Cassandra::Client::Client#execute}
90
+ # for details on which options are available.
91
+ # @raise [ArgumentError] raised when number of argument does not match
92
+ # the number of parameters needed to be bound to the statement.
93
+ # @raise [Cassandra::Errors::NotConnectedError] raised when the client is not connected
94
+ # @raise [Cassandra::Errors::IoError] raised when there is an IO error, for example
95
+ # if the server suddenly closes the connection
96
+ # @raise [Cassandra::Errors::QueryError] raised when there is an error on the server side
97
+ # @return [nil, Cassandra::Client::QueryResult, Cassandra::Client::VoidResult] Some
98
+ # queries have no result and return `nil`, but `SELECT` statements
99
+ # return an `Enumerable` of rows (see {Cassandra::Client::QueryResult}), and
100
+ # `INSERT` and `UPDATE` return a similar type
101
+ # (see {Cassandra::Client::VoidResult}).
102
+ def execute(*args)
103
+ end
104
+
105
+ # Yields a batch when called with a block. The batch is automatically
106
+ # executed at the end of the block and the result is returned.
107
+ #
108
+ # Returns a batch when called wihtout a block. The batch will remember
109
+ # the options given and merge these with any additional options given
110
+ # when {Cassandra::Client::PreparedStatementBatch#execute} is called.
111
+ #
112
+ # The batch yielded or returned by this method is not identical to the
113
+ # regular batch objects yielded or returned by {Cassandra::Client::Client#batch}.
114
+ # These prepared statement batch objects can be used only to add multiple
115
+ # executions of the same prepared statement.
116
+ #
117
+ # Please note that the batch object returned by this method _is not thread
118
+ # safe_.
119
+ #
120
+ # The type parameter can be ommitted and the options can then be given
121
+ # as first parameter.
122
+ #
123
+ # @example Executing a prepared statement in a batch
124
+ # statement = client.prepare(%(INSERT INTO metrics (id, time, value) VALUES (?, NOW(), ?)))
125
+ # statement.batch do |batch|
126
+ # batch.add(1234, 23423)
127
+ # batch.add(2346, 13)
128
+ # batch.add(2342, 2367)
129
+ # batch.add(4562, 1231)
130
+ # end
131
+ #
132
+ # @see Cassandra::Client::PreparedStatementBatch
133
+ # @see Cassandra::Client::Client#batch
134
+ # @param [Symbol] type the type of batch, must be one of `:logged`,
135
+ # `:unlogged` and `:counter`. The precise meaning of these is defined
136
+ # in the CQL specification.
137
+ # @yieldparam [Cassandra::Client::PreparedStatementBatch] batch the batch
138
+ # @return [Cassandra::Client::VoidResult, Cassandra::Client::Batch] when no block is
139
+ # given the batch is returned, when a block is given the result of
140
+ # executing the batch is returned (see {Cassandra::Client::Batch#execute}).
141
+ def batch(type=:logged, options={})
142
+ end
143
+ end
144
+
145
+ # @private
146
+ class AsynchronousPreparedStatement < PreparedStatement
147
+ # @private
148
+ def initialize(cql, execute_options_decoder, connection_manager, logger)
149
+ @cql = cql
150
+ @execute_options_decoder = execute_options_decoder
151
+ @connection_manager = connection_manager
152
+ @logger = logger
153
+ @request_runner = RequestRunner.new
154
+ end
155
+
156
+ def self.prepare(cql, execute_options_decoder, connection_manager, logger)
157
+ statement = new(cql, execute_options_decoder, connection_manager, logger)
158
+ futures = connection_manager.map do |connection|
159
+ statement.prepare(connection)
160
+ end
161
+ Ione::Future.all(*futures).map(statement)
162
+ rescue => e
163
+ Ione::Future.failed(e)
164
+ end
165
+
166
+ def execute(*args)
167
+ connection = @connection_manager.random_connection
168
+ if connection[self]
169
+ run(args, connection)
170
+ else
171
+ prepare(connection).flat_map do
172
+ run(args, connection)
173
+ end
174
+ end
175
+ rescue => e
176
+ Ione::Future.failed(e)
177
+ end
178
+
179
+ def batch(type=:logged, options=nil)
180
+ if type.is_a?(Hash)
181
+ options = type
182
+ type = :logged
183
+ end
184
+ b = AsynchronousBatch.new(type, @execute_options_decoder, @connection_manager, options)
185
+ pb = AsynchronousPreparedStatementBatch.new(self, b)
186
+ if block_given?
187
+ yield pb
188
+ pb.execute
189
+ else
190
+ pb
191
+ end
192
+ end
193
+
194
+ # @private
195
+ def prepare(connection)
196
+ prepare_request = Protocol::PrepareRequest.new(@cql)
197
+ f = @request_runner.execute(connection, prepare_request) do |response|
198
+ connection[self] = response.id
199
+ unless @raw_metadata
200
+ # NOTE: this is not thread safe, but the worst that could happen
201
+ # is that we assign the same data multiple times
202
+ @raw_metadata = response.metadata
203
+ @metadata = ResultMetadata.new(@raw_metadata)
204
+ @raw_result_metadata = response.result_metadata
205
+ if @raw_result_metadata
206
+ @result_metadata = ResultMetadata.new(@raw_result_metadata)
207
+ end
208
+ end
209
+ hex_id = response.id.each_byte.map { |x| x.to_s(16).rjust(2, '0') }.join('')
210
+ @logger.debug('Statement %s prepared on node %s (%s:%d)' % [hex_id, connection[:host_id].to_s, connection.host, connection.port])
211
+ end
212
+ f.map(self)
213
+ end
214
+
215
+ # @private
216
+ def prepared?(connection)
217
+ !!connection[self]
218
+ end
219
+
220
+ # @private
221
+ def add_to_batch(batch, connection, bound_args)
222
+ statement_id = connection[self]
223
+ unless statement_id
224
+ raise Errors::NotPreparedError
225
+ end
226
+ unless bound_args.size == @raw_metadata.size
227
+ raise ArgumentError, "Expected #{@raw_metadata.size} arguments, got #{bound_args.size}"
228
+ end
229
+ batch.add_prepared(statement_id, @raw_metadata, bound_args)
230
+ end
231
+
232
+ private
233
+
234
+ def run(args, connection)
235
+ bound_args = args.shift(@raw_metadata.size)
236
+ unless bound_args.size == @raw_metadata.size && args.size <= 1
237
+ raise ArgumentError, "Expected #{@raw_metadata.size} arguments, got #{bound_args.size}"
238
+ end
239
+ options = @execute_options_decoder.decode_options(args.last)
240
+ statement_id = connection[self]
241
+ request_metadata = @raw_result_metadata.nil?
242
+ request = Protocol::ExecuteRequest.new(statement_id, @raw_metadata, bound_args, request_metadata, options[:consistency], options[:serial_consistency], options[:page_size], options[:paging_state], options[:trace])
243
+ f = @request_runner.execute(connection, request, options[:timeout], @raw_result_metadata)
244
+ if options.include?(:page_size)
245
+ f = f.map { |result| AsynchronousPreparedPagedQueryResult.new(self, request, result, options) }
246
+ end
247
+ f
248
+ end
249
+ end
250
+
251
+ # @private
252
+ class SynchronousPreparedStatement < PreparedStatement
253
+ include SynchronousBacktrace
254
+
255
+ def initialize(async_statement)
256
+ @async_statement = async_statement
257
+ @metadata = async_statement.metadata
258
+ @result_metadata = async_statement.result_metadata
259
+ end
260
+
261
+ def execute(*args)
262
+ synchronous_backtrace do
263
+ result = @async_statement.execute(*args).value
264
+ result = SynchronousPagedQueryResult.new(result) if result.is_a?(PagedQueryResult)
265
+ result
266
+ end
267
+ end
268
+
269
+ def batch(type=:logged, options=nil, &block)
270
+ if block_given?
271
+ synchronous_backtrace { @async_statement.batch(type, options, &block).value }
272
+ else
273
+ SynchronousPreparedStatementBatch.new(@async_statement.batch(type, options))
274
+ end
275
+ end
276
+
277
+ def pipeline
278
+ pl = Pipeline.new(@async_statement)
279
+ yield pl
280
+ synchronous_backtrace { pl.value }
281
+ end
282
+
283
+ def async
284
+ @async_statement
285
+ end
286
+
287
+ # @private
288
+ def prepared?(connection)
289
+ @async_statement.prepared?(connection)
290
+ end
291
+
292
+ # @private
293
+ def add_to_batch(batch, connection, bound_arguments)
294
+ @async_statement.add_to_batch(batch, connection, bound_arguments)
295
+ end
296
+ end
297
+
298
+ # @private
299
+ class Pipeline
300
+ def initialize(async_statement)
301
+ @async_statement = async_statement
302
+ @futures = []
303
+ end
304
+
305
+ def execute(*args)
306
+ @futures << @async_statement.execute(*args)
307
+ end
308
+
309
+ def value
310
+ Ione::Future.all(*@futures).value
311
+ end
312
+ end
313
+ end
314
+ end
@@ -0,0 +1,230 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2014 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 Client
21
+ # Query results encapsulate the rows returned by a query.
22
+ #
23
+ # In addition to containing the rows it contains metadata about the data
24
+ # types of the columns of the rows, and it knows the ID of the trace,
25
+ # if tracing was requested for the query.
26
+ #
27
+ # When paging over a big result you can use {#last_page?} to find out if the
28
+ # page is the last, or {#next_page} to retrieve the next page.
29
+ #
30
+ # `QueryResult` is an `Enumerable` so it can be mapped, filtered, reduced, etc.
31
+ class QueryResult
32
+ include Enumerable
33
+
34
+ # @return [ResultMetadata]
35
+ attr_reader :metadata
36
+
37
+ # The ID of the query trace associated with the query, if any.
38
+ #
39
+ # @return [Cassandra::Uuid]
40
+ attr_reader :trace_id
41
+
42
+ # @private
43
+ attr_reader :paging_state
44
+
45
+ # @private
46
+ def initialize(metadata, rows, trace_id, paging_state)
47
+ @metadata = ResultMetadata.new(metadata)
48
+ @rows = rows
49
+ @trace_id = trace_id
50
+ @paging_state = paging_state
51
+ end
52
+
53
+ # Returns whether or not there are any rows in this result set
54
+ def empty?
55
+ @rows.empty?
56
+ end
57
+
58
+ # Returns count of underlying rows
59
+ def size
60
+ @rows.size
61
+ end
62
+ alias :length :size
63
+
64
+ # Iterates over each row in the result set.
65
+ #
66
+ # @yieldparam [Hash] row each row in the result set as a hash
67
+ # @return [Enumerable<Hash>]
68
+ def each(&block)
69
+ @rows.each(&block)
70
+ end
71
+ alias_method :each_row, :each
72
+
73
+ # Returns true when there are no more pages to load.
74
+ #
75
+ # This is only relevant when you have requested paging of the results with
76
+ # the `:page_size` option to {Cassandra::Client::Client#execute} or
77
+ # {Cassandra::Client::PreparedStatement#execute}.
78
+ #
79
+ # @see Cassandra::Client::Client#execute
80
+ def last_page?
81
+ true
82
+ end
83
+
84
+ # Returns the next page or nil when there is no next page.
85
+ #
86
+ # This is only relevant when you have requested paging of the results with
87
+ # the `:page_size` option to {Cassandra::Client::Client#execute} or
88
+ # {Cassandra::Client::PreparedStatement#execute}.
89
+ #
90
+ # @see Cassandra::Client::Client#execute
91
+ def next_page
92
+ nil
93
+ end
94
+ end
95
+
96
+ # @private
97
+ class PagedQueryResult < QueryResult
98
+ def metadata
99
+ @result.metadata
100
+ end
101
+
102
+ def trace_id
103
+ @result.trace_id
104
+ end
105
+
106
+ def paging_state
107
+ @result.paging_state
108
+ end
109
+
110
+ def empty?
111
+ @result.empty?
112
+ end
113
+
114
+ def each(&block)
115
+ @result.each(&block)
116
+ end
117
+ alias_method :each_row, :each
118
+
119
+ def last_page?
120
+ @last_page
121
+ end
122
+
123
+ def next_page
124
+ end
125
+ end
126
+
127
+ # @private
128
+ class AsynchronousPagedQueryResult < PagedQueryResult
129
+ def initialize(request, result, options)
130
+ @request = request
131
+ @result = result
132
+ @result = result
133
+ @options = options.merge(paging_state: result.paging_state)
134
+ @last_page = !result.paging_state
135
+ end
136
+ end
137
+
138
+ # @private
139
+ class AsynchronousQueryPagedQueryResult < AsynchronousPagedQueryResult
140
+ def initialize(client, request, result, options)
141
+ super(request, result, options)
142
+ @client = client
143
+ end
144
+
145
+ def next_page
146
+ return Ione::Future.resolved(nil) if last_page?
147
+ @client.execute(@request.cql, *@request.values, @options)
148
+ end
149
+ end
150
+
151
+ # @private
152
+ class AsynchronousPreparedPagedQueryResult < AsynchronousPagedQueryResult
153
+ def initialize(prepared_statement, request, result, options)
154
+ super(request, result, options)
155
+ @prepared_statement = prepared_statement
156
+ end
157
+
158
+ def next_page
159
+ return Ione::Future.resolved(nil) if last_page?
160
+ @prepared_statement.execute(*@request.values, @options)
161
+ end
162
+ end
163
+
164
+ # @private
165
+ class SynchronousPagedQueryResult < PagedQueryResult
166
+ include SynchronousBacktrace
167
+
168
+ def initialize(asynchronous_result)
169
+ @result = asynchronous_result
170
+ end
171
+
172
+ def async
173
+ @result
174
+ end
175
+
176
+ def last_page?
177
+ @result.last_page?
178
+ end
179
+
180
+ def next_page
181
+ synchronous_backtrace do
182
+ asynchronous_result = @result.next_page.value
183
+ asynchronous_result && self.class.new(asynchronous_result)
184
+ end
185
+ end
186
+ end
187
+
188
+ # @private
189
+ class LazyQueryResult < QueryResult
190
+ def initialize(metadata, lazy_rows, trace_id, paging_state)
191
+ super(metadata, nil, trace_id, paging_state)
192
+ @raw_metadata = metadata
193
+ @lazy_rows = lazy_rows
194
+ @lock = Mutex.new
195
+ end
196
+
197
+ def empty?
198
+ ensure_materialized
199
+ super
200
+ end
201
+
202
+ def size
203
+ ensure_materialized
204
+ super
205
+ end
206
+ alias :length :size
207
+
208
+ def each(&block)
209
+ ensure_materialized
210
+ super
211
+ end
212
+ alias_method :each_row, :each
213
+
214
+ private
215
+
216
+ def ensure_materialized
217
+ unless @rows
218
+ @lock.lock
219
+ begin
220
+ unless @rows
221
+ @rows = @lazy_rows.materialize(@raw_metadata)
222
+ end
223
+ ensure
224
+ @lock.unlock
225
+ end
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2014 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 Client
21
+ # @private
22
+ class RequestRunner
23
+ def execute(connection, request, timeout=nil, raw_metadata=nil)
24
+ connection.send_request(request, timeout).map do |response|
25
+ case response
26
+ when Protocol::RawRowsResultResponse
27
+ LazyQueryResult.new(raw_metadata, response, response.trace_id, response.paging_state)
28
+ when Protocol::RowsResultResponse
29
+ QueryResult.new(response.metadata, response.rows, response.trace_id, response.paging_state)
30
+ when Protocol::VoidResultResponse
31
+ response.trace_id ? VoidResult.new(response.trace_id) : VoidResult::INSTANCE
32
+ when Protocol::ErrorResponse
33
+ cql = request.is_a?(Protocol::QueryRequest) ? request.cql : nil
34
+ details = response.respond_to?(:details) ? response.details : nil
35
+ raise Errors::QueryError.new(response.code, response.message, cql, details)
36
+ when Protocol::SetKeyspaceResultResponse
37
+ KeyspaceChanged.new(response.keyspace)
38
+ when Protocol::AuthenticateResponse
39
+ AuthenticationRequired.new(response.authentication_class)
40
+ when Protocol::SupportedResponse
41
+ response.options
42
+ else
43
+ if block_given?
44
+ yield response
45
+ else
46
+ nil
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ # @private
54
+ class AuthenticationRequired
55
+ attr_reader :authentication_class
56
+
57
+ def initialize(authentication_class)
58
+ @authentication_class = authentication_class
59
+ end
60
+ end
61
+
62
+ # @private
63
+ class KeyspaceChanged
64
+ attr_reader :keyspace
65
+
66
+ def initialize(keyspace)
67
+ @keyspace = keyspace
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2014 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 Client
21
+ # A collection of metadata (keyspace, table, name and type) of a result set.
22
+ #
23
+ # @see Cassandra::Client::ColumnMetadata
24
+ class ResultMetadata
25
+ include Enumerable
26
+
27
+ # @private
28
+ def initialize(metadata)
29
+ @metadata = metadata.each_with_object({}) { |m, h| h[m[2]] = ColumnMetadata.new(*m) }
30
+ end
31
+
32
+ # Returns the column metadata
33
+ #
34
+ # @return [ColumnMetadata] column_metadata the metadata for the column
35
+ def [](column_name)
36
+ @metadata[column_name]
37
+ end
38
+
39
+ # Iterates over the metadata for each column
40
+ #
41
+ # @yieldparam [ColumnMetadata] metadata the metadata for each column
42
+ # @return [Enumerable<ColumnMetadata>]
43
+ def each(&block)
44
+ @metadata.each_value(&block)
45
+ end
46
+ end
47
+ end
48
+ end