cql-rb 2.0.0.pre0 → 2.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -2
  3. data/lib/cql.rb +8 -3
  4. data/lib/cql/client.rb +21 -356
  5. data/lib/cql/client/authenticators.rb +70 -0
  6. data/lib/cql/client/batch.rb +54 -0
  7. data/lib/cql/client/{asynchronous_client.rb → client.rb} +241 -6
  8. data/lib/cql/client/connector.rb +3 -2
  9. data/lib/cql/client/{asynchronous_prepared_statement.rb → prepared_statement.rb} +103 -0
  10. data/lib/cql/protocol.rb +1 -2
  11. data/lib/cql/protocol/cql_byte_buffer.rb +285 -0
  12. data/lib/cql/protocol/cql_protocol_handler.rb +3 -3
  13. data/lib/cql/protocol/frame_decoder.rb +3 -3
  14. data/lib/cql/protocol/frame_encoder.rb +2 -2
  15. data/lib/cql/protocol/request.rb +0 -2
  16. data/lib/cql/protocol/requests/auth_response_request.rb +2 -2
  17. data/lib/cql/protocol/requests/batch_request.rb +10 -10
  18. data/lib/cql/protocol/requests/credentials_request.rb +2 -2
  19. data/lib/cql/protocol/requests/execute_request.rb +13 -13
  20. data/lib/cql/protocol/requests/options_request.rb +2 -2
  21. data/lib/cql/protocol/requests/prepare_request.rb +2 -2
  22. data/lib/cql/protocol/requests/query_request.rb +13 -13
  23. data/lib/cql/protocol/requests/register_request.rb +2 -2
  24. data/lib/cql/protocol/requests/startup_request.rb +2 -2
  25. data/lib/cql/protocol/response.rb +2 -4
  26. data/lib/cql/protocol/responses/auth_challenge_response.rb +2 -2
  27. data/lib/cql/protocol/responses/auth_success_response.rb +2 -2
  28. data/lib/cql/protocol/responses/authenticate_response.rb +2 -2
  29. data/lib/cql/protocol/responses/detailed_error_response.rb +15 -15
  30. data/lib/cql/protocol/responses/error_response.rb +4 -4
  31. data/lib/cql/protocol/responses/event_response.rb +3 -3
  32. data/lib/cql/protocol/responses/prepared_result_response.rb +4 -4
  33. data/lib/cql/protocol/responses/raw_rows_result_response.rb +1 -1
  34. data/lib/cql/protocol/responses/ready_response.rb +1 -1
  35. data/lib/cql/protocol/responses/result_response.rb +3 -3
  36. data/lib/cql/protocol/responses/rows_result_response.rb +22 -22
  37. data/lib/cql/protocol/responses/schema_change_event_response.rb +2 -2
  38. data/lib/cql/protocol/responses/schema_change_result_response.rb +2 -2
  39. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +2 -2
  40. data/lib/cql/protocol/responses/status_change_event_response.rb +2 -2
  41. data/lib/cql/protocol/responses/supported_response.rb +2 -2
  42. data/lib/cql/protocol/responses/void_result_response.rb +1 -1
  43. data/lib/cql/protocol/type_converter.rb +78 -81
  44. data/lib/cql/time_uuid.rb +6 -0
  45. data/lib/cql/uuid.rb +2 -1
  46. data/lib/cql/version.rb +1 -1
  47. data/spec/cql/client/batch_spec.rb +8 -8
  48. data/spec/cql/client/{asynchronous_client_spec.rb → client_spec.rb} +162 -0
  49. data/spec/cql/client/connector_spec.rb +13 -3
  50. data/spec/cql/client/{asynchronous_prepared_statement_spec.rb → prepared_statement_spec.rb} +148 -1
  51. data/spec/cql/client/request_runner_spec.rb +2 -2
  52. data/spec/cql/protocol/cql_byte_buffer_spec.rb +895 -0
  53. data/spec/cql/protocol/cql_protocol_handler_spec.rb +1 -1
  54. data/spec/cql/protocol/frame_decoder_spec.rb +14 -14
  55. data/spec/cql/protocol/frame_encoder_spec.rb +7 -7
  56. data/spec/cql/protocol/requests/auth_response_request_spec.rb +4 -4
  57. data/spec/cql/protocol/requests/batch_request_spec.rb +21 -21
  58. data/spec/cql/protocol/requests/credentials_request_spec.rb +2 -2
  59. data/spec/cql/protocol/requests/execute_request_spec.rb +13 -13
  60. data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
  61. data/spec/cql/protocol/requests/prepare_request_spec.rb +2 -2
  62. data/spec/cql/protocol/requests/query_request_spec.rb +13 -13
  63. data/spec/cql/protocol/requests/register_request_spec.rb +2 -2
  64. data/spec/cql/protocol/requests/startup_request_spec.rb +4 -4
  65. data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +5 -5
  66. data/spec/cql/protocol/responses/auth_success_response_spec.rb +5 -5
  67. data/spec/cql/protocol/responses/authenticate_response_spec.rb +3 -3
  68. data/spec/cql/protocol/responses/detailed_error_response_spec.rb +15 -15
  69. data/spec/cql/protocol/responses/error_response_spec.rb +5 -5
  70. data/spec/cql/protocol/responses/event_response_spec.rb +8 -8
  71. data/spec/cql/protocol/responses/prepared_result_response_spec.rb +7 -7
  72. data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +1 -1
  73. data/spec/cql/protocol/responses/ready_response_spec.rb +2 -2
  74. data/spec/cql/protocol/responses/result_response_spec.rb +16 -16
  75. data/spec/cql/protocol/responses/rows_result_response_spec.rb +21 -21
  76. data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +3 -3
  77. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +3 -3
  78. data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +2 -2
  79. data/spec/cql/protocol/responses/status_change_event_response_spec.rb +3 -3
  80. data/spec/cql/protocol/responses/supported_response_spec.rb +3 -3
  81. data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +3 -3
  82. data/spec/cql/protocol/responses/void_result_response_spec.rb +2 -2
  83. data/spec/cql/protocol/type_converter_spec.rb +25 -13
  84. data/spec/cql/time_uuid_spec.rb +17 -4
  85. data/spec/cql/uuid_spec.rb +5 -1
  86. data/spec/integration/protocol_spec.rb +48 -42
  87. data/spec/spec_helper.rb +0 -1
  88. metadata +27 -39
  89. data/lib/cql/byte_buffer.rb +0 -177
  90. data/lib/cql/client/synchronous_client.rb +0 -79
  91. data/lib/cql/client/synchronous_prepared_statement.rb +0 -63
  92. data/lib/cql/future.rb +0 -515
  93. data/lib/cql/io.rb +0 -15
  94. data/lib/cql/io/connection.rb +0 -220
  95. data/lib/cql/io/io_reactor.rb +0 -349
  96. data/lib/cql/protocol/decoding.rb +0 -187
  97. data/lib/cql/protocol/encoding.rb +0 -114
  98. data/spec/cql/byte_buffer_spec.rb +0 -337
  99. data/spec/cql/client/synchronous_client_spec.rb +0 -170
  100. data/spec/cql/client/synchronous_prepared_statement_spec.rb +0 -155
  101. data/spec/cql/future_spec.rb +0 -737
  102. data/spec/cql/io/connection_spec.rb +0 -484
  103. data/spec/cql/io/io_reactor_spec.rb +0 -402
  104. data/spec/cql/protocol/decoding_spec.rb +0 -547
  105. data/spec/cql/protocol/encoding_spec.rb +0 -386
  106. data/spec/integration/io_spec.rb +0 -283
  107. data/spec/support/fake_server.rb +0 -106
@@ -3,7 +3,7 @@
3
3
  module Cql
4
4
  module Protocol
5
5
  class VoidResultResponse < ResultResponse
6
- def self.decode!(protocol_version, buffer, length, trace_id=nil)
6
+ def self.decode(protocol_version, buffer, length, trace_id=nil)
7
7
  new(trace_id)
8
8
  end
9
9
 
@@ -7,9 +7,6 @@ require 'set'
7
7
  module Cql
8
8
  module Protocol
9
9
  class TypeConverter
10
- include Decoding
11
- include Encoding
12
-
13
10
  def initialize
14
11
  @from_bytes_converters = from_bytes_converters
15
12
  @to_bytes_converters = to_bytes_converters
@@ -33,7 +30,7 @@ module Cql
33
30
  end
34
31
  end
35
32
 
36
- def to_bytes(io, type, value, size_bytes=4)
33
+ def to_bytes(buffer, type, value, size_bytes=4)
37
34
  case type
38
35
  when Array
39
36
  unless value.nil? || value.is_a?(Enumerable)
@@ -43,27 +40,27 @@ module Cql
43
40
  when :list, :set
44
41
  _, sub_type = type
45
42
  if value
46
- raw = ''
47
- write_short(raw, value.size)
43
+ raw = CqlByteBuffer.new
44
+ raw.append_short(value.size)
48
45
  value.each do |element|
49
46
  to_bytes(raw, sub_type, element, 2)
50
47
  end
51
- write_bytes(io, raw)
48
+ buffer.append_bytes(raw)
52
49
  else
53
- nil_to_bytes(io, size_bytes)
50
+ nil_to_bytes(buffer, size_bytes)
54
51
  end
55
52
  when :map
56
53
  _, key_type, value_type = type
57
54
  if value
58
- raw = ''
59
- write_short(raw, value.size)
55
+ raw = CqlByteBuffer.new
56
+ raw.append_short(value.size)
60
57
  value.each do |key, value|
61
58
  to_bytes(raw, key_type, key, 2)
62
59
  to_bytes(raw, value_type, value, 2)
63
60
  end
64
- write_bytes(io, raw)
61
+ buffer.append_bytes(raw)
65
62
  else
66
- nil_to_bytes(io, size_bytes)
63
+ nil_to_bytes(buffer, size_bytes)
67
64
  end
68
65
  else
69
66
  raise UnsupportedColumnTypeError, %(Unsupported column collection type: #{type.first})
@@ -73,7 +70,7 @@ module Cql
73
70
  unless converter
74
71
  raise UnsupportedColumnTypeError, %(Unsupported column type: #{type})
75
72
  end
76
- converter.call(io, value, size_bytes)
73
+ converter.call(buffer, value, size_bytes)
77
74
  end
78
75
  rescue TypeError => e
79
76
  raise TypeError, %("#{value}" cannot be encoded as #{type.to_s.upcase}: #{e.message}), e.backtrace
@@ -128,24 +125,24 @@ module Cql
128
125
  size = buffer.read_short
129
126
  return nil if size & 0x8000 == 0x8000
130
127
  else
131
- size = buffer.read_int
128
+ size = buffer.read_signed_int
132
129
  return nil if size & 0x80000000 == 0x80000000
133
130
  end
134
131
  size
135
132
  end
136
133
 
137
134
  def bytes_to_ascii(buffer, size_bytes)
138
- bytes = size_bytes == 4 ? read_bytes!(buffer) : read_short_bytes!(buffer)
135
+ bytes = size_bytes == 4 ? buffer.read_bytes : buffer.read_short_bytes
139
136
  bytes ? bytes.force_encoding(::Encoding::ASCII) : nil
140
137
  end
141
138
 
142
139
  def bytes_to_bigint(buffer, size_bytes)
143
140
  return nil unless read_size(buffer, size_bytes)
144
- read_long!(buffer)
141
+ buffer.read_long
145
142
  end
146
143
 
147
144
  def bytes_to_blob(buffer, size_bytes)
148
- bytes = size_bytes == 4 ? read_bytes!(buffer) : read_short_bytes!(buffer)
145
+ bytes = size_bytes == 4 ? buffer.read_bytes : buffer.read_short_bytes
149
146
  bytes ? bytes : nil
150
147
  end
151
148
 
@@ -157,49 +154,49 @@ module Cql
157
154
  def bytes_to_decimal(buffer, size_bytes)
158
155
  size = read_size(buffer, size_bytes)
159
156
  return nil unless size
160
- read_decimal!(buffer, size)
157
+ buffer.read_decimal(size)
161
158
  end
162
159
 
163
160
  def bytes_to_double(buffer, size_bytes)
164
161
  return nil unless read_size(buffer, size_bytes)
165
- read_double!(buffer)
162
+ buffer.read_double
166
163
  end
167
164
 
168
165
  def bytes_to_float(buffer, size_bytes)
169
166
  return nil unless read_size(buffer, size_bytes)
170
- read_float!(buffer)
167
+ buffer.read_float
171
168
  end
172
169
 
173
170
  def bytes_to_int(buffer, size_bytes)
174
171
  return nil unless read_size(buffer, size_bytes)
175
- read_int!(buffer)
172
+ buffer.read_signed_int
176
173
  end
177
174
 
178
175
  def bytes_to_timestamp(buffer, size_bytes)
179
176
  return nil unless read_size(buffer, size_bytes)
180
- timestamp = read_long!(buffer)
177
+ timestamp = buffer.read_long
181
178
  Time.at(timestamp/1000.0)
182
179
  end
183
180
 
184
181
  def bytes_to_varchar(buffer, size_bytes)
185
- bytes = size_bytes == 4 ? read_bytes!(buffer) : read_short_bytes!(buffer)
182
+ bytes = size_bytes == 4 ? buffer.read_bytes : buffer.read_short_bytes
186
183
  bytes ? bytes.force_encoding(::Encoding::UTF_8) : nil
187
184
  end
188
185
 
189
186
  def bytes_to_varint(buffer, size_bytes)
190
187
  size = read_size(buffer, size_bytes)
191
188
  return nil unless size
192
- read_varint!(buffer, size)
189
+ buffer.read_varint(size)
193
190
  end
194
191
 
195
192
  def bytes_to_uuid(buffer, size_bytes)
196
193
  return nil unless read_size(buffer, size_bytes)
197
- read_uuid!(buffer)
194
+ buffer.read_uuid
198
195
  end
199
196
 
200
197
  def bytes_to_timeuuid(buffer, size_bytes)
201
198
  return nil unless read_size(buffer, size_bytes)
202
- read_uuid!(buffer, TimeUuid)
199
+ buffer.read_uuid(TimeUuid)
203
200
  end
204
201
 
205
202
  def bytes_to_inet(buffer, size_bytes)
@@ -237,137 +234,137 @@ module Cql
237
234
  set
238
235
  end
239
236
 
240
- def ascii_to_bytes(io, value, size_bytes)
237
+ def ascii_to_bytes(buffer, value, size_bytes)
241
238
  v = value && value.encode(::Encoding::ASCII)
242
239
  if size_bytes == 4
243
- write_bytes(io, v)
240
+ buffer.append_bytes(v)
244
241
  else
245
- write_short_bytes(io, v)
242
+ buffer.append_short_bytes(v)
246
243
  end
247
244
  end
248
245
 
249
- def bigint_to_bytes(io, value, size_bytes)
246
+ def bigint_to_bytes(buffer, value, size_bytes)
250
247
  if value
251
- size_to_bytes(io, 8, size_bytes)
252
- write_long(io, value)
248
+ size_to_bytes(buffer, 8, size_bytes)
249
+ buffer.append_long(value)
253
250
  else
254
- nil_to_bytes(io, size_bytes)
251
+ nil_to_bytes(buffer, size_bytes)
255
252
  end
256
253
  end
257
254
 
258
- def blob_to_bytes(io, value, size_bytes)
255
+ def blob_to_bytes(buffer, value, size_bytes)
259
256
  v = value && value.encode(::Encoding::BINARY)
260
257
  if size_bytes == 4
261
- write_bytes(io, v)
258
+ buffer.append_bytes(v)
262
259
  else
263
- write_short_bytes(io, v)
260
+ buffer.append_short_bytes(v)
264
261
  end
265
262
  end
266
263
 
267
- def boolean_to_bytes(io, value, size_bytes)
264
+ def boolean_to_bytes(buffer, value, size_bytes)
268
265
  if !value.nil?
269
- size_to_bytes(io, 1, size_bytes)
270
- io << (value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
266
+ size_to_bytes(buffer, 1, size_bytes)
267
+ buffer.append(value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
271
268
  else
272
- nil_to_bytes(io, size_bytes)
269
+ nil_to_bytes(buffer, size_bytes)
273
270
  end
274
271
  end
275
272
 
276
- def decimal_to_bytes(io, value, size_bytes)
277
- raw = value && write_decimal('', value)
273
+ def decimal_to_bytes(buffer, value, size_bytes)
274
+ raw = value && CqlByteBuffer.new.append_decimal(value)
278
275
  if size_bytes == 4
279
- write_bytes(io, raw)
276
+ buffer.append_bytes(raw)
280
277
  else
281
- write_short_bytes(io, raw)
278
+ buffer.append_short_bytes(raw)
282
279
  end
283
280
  end
284
281
 
285
- def double_to_bytes(io, value, size_bytes)
282
+ def double_to_bytes(buffer, value, size_bytes)
286
283
  if value
287
- size_to_bytes(io, 8, size_bytes)
288
- write_double(io, value)
284
+ size_to_bytes(buffer, 8, size_bytes)
285
+ buffer.append_double(value)
289
286
  else
290
- nil_to_bytes(io, size_bytes)
287
+ nil_to_bytes(buffer, size_bytes)
291
288
  end
292
289
  end
293
290
 
294
- def float_to_bytes(io, value, size_bytes)
291
+ def float_to_bytes(buffer, value, size_bytes)
295
292
  if value
296
- size_to_bytes(io, 4, size_bytes)
297
- write_float(io, value)
293
+ size_to_bytes(buffer, 4, size_bytes)
294
+ buffer.append_float(value)
298
295
  else
299
- nil_to_bytes(io, size_bytes)
296
+ nil_to_bytes(buffer, size_bytes)
300
297
  end
301
298
  end
302
299
 
303
- def inet_to_bytes(io, value, size_bytes)
300
+ def inet_to_bytes(buffer, value, size_bytes)
304
301
  if value
305
- size_to_bytes(io, value.ipv6? ? 16 : 4, size_bytes)
306
- io << value.hton
302
+ size_to_bytes(buffer, value.ipv6? ? 16 : 4, size_bytes)
303
+ buffer.append(value.hton)
307
304
  else
308
- nil_to_bytes(io, size_bytes)
305
+ nil_to_bytes(buffer, size_bytes)
309
306
  end
310
307
  end
311
308
 
312
- def int_to_bytes(io, value, size_bytes)
309
+ def int_to_bytes(buffer, value, size_bytes)
313
310
  if value
314
- size_to_bytes(io, 4, size_bytes)
315
- write_int(io, value)
311
+ size_to_bytes(buffer, 4, size_bytes)
312
+ buffer.append_int(value)
316
313
  else
317
- nil_to_bytes(io, size_bytes)
314
+ nil_to_bytes(buffer, size_bytes)
318
315
  end
319
316
  end
320
317
 
321
- def varchar_to_bytes(io, value, size_bytes)
318
+ def varchar_to_bytes(buffer, value, size_bytes)
322
319
  v = value && value.encode(::Encoding::UTF_8)
323
320
  if size_bytes == 4
324
- write_bytes(io, v)
321
+ buffer.append_bytes(v)
325
322
  else
326
- write_short_bytes(io, v)
323
+ buffer.append_short_bytes(v)
327
324
  end
328
325
  end
329
326
 
330
- def timestamp_to_bytes(io, value, size_bytes)
327
+ def timestamp_to_bytes(buffer, value, size_bytes)
331
328
  if value
332
329
  ms = (value.to_f * 1000).to_i
333
- size_to_bytes(io, 8, size_bytes)
334
- write_long(io, ms)
330
+ size_to_bytes(buffer, 8, size_bytes)
331
+ buffer.append_long(ms)
335
332
  else
336
- nil_to_bytes(io, size_bytes)
333
+ nil_to_bytes(buffer, size_bytes)
337
334
  end
338
335
  end
339
336
 
340
- def uuid_to_bytes(io, value, size_bytes)
337
+ def uuid_to_bytes(buffer, value, size_bytes)
341
338
  if value
342
- size_to_bytes(io, 16, size_bytes)
343
- write_uuid(io, value)
339
+ size_to_bytes(buffer, 16, size_bytes)
340
+ buffer.append_uuid(value)
344
341
  else
345
- nil_to_bytes(io, size_bytes)
342
+ nil_to_bytes(buffer, size_bytes)
346
343
  end
347
344
  end
348
345
 
349
- def varint_to_bytes(io, value, size_bytes)
350
- raw = value && write_varint('', value)
346
+ def varint_to_bytes(buffer, value, size_bytes)
347
+ raw = value && CqlByteBuffer.new.append_varint(value)
351
348
  if size_bytes == 4
352
- write_bytes(io, raw)
349
+ buffer.append_bytes(raw)
353
350
  else
354
- write_short_bytes(io, raw)
351
+ buffer.append_short_bytes(raw)
355
352
  end
356
353
  end
357
354
 
358
- def size_to_bytes(io, size, size_bytes)
355
+ def size_to_bytes(buffer, size, size_bytes)
359
356
  if size_bytes == 4
360
- write_int(io, size)
357
+ buffer.append_int(size)
361
358
  else
362
- write_short(io, size)
359
+ buffer.append_short(size)
363
360
  end
364
361
  end
365
362
 
366
- def nil_to_bytes(io, size_bytes)
363
+ def nil_to_bytes(buffer, size_bytes)
367
364
  if size_bytes == 4
368
- write_int(io, -1)
365
+ buffer.append_int(-1)
369
366
  else
370
- write_short(io, -1)
367
+ buffer.append_short(-1)
371
368
  end
372
369
  end
373
370
  end
data/lib/cql/time_uuid.rb CHANGED
@@ -4,6 +4,8 @@ module Cql
4
4
  # A variant of UUID which can extract its time component.
5
5
  #
6
6
  class TimeUuid < Uuid
7
+ include Comparable
8
+
7
9
  # Returns the time component from this UUID as a Time.
8
10
  #
9
11
  # @return [Time]
@@ -20,6 +22,10 @@ module Cql
20
22
  Time.at(seconds, microseconds).utc
21
23
  end
22
24
 
25
+ def <=>(other)
26
+ self.value <=> other.value
27
+ end
28
+
23
29
  # A UUID version 1, variant 1 generator. It can generate a sequence of UUIDs
24
30
  # with reasonable uniqueness guarantees:
25
31
  #
data/lib/cql/uuid.rb CHANGED
@@ -39,7 +39,7 @@ module Cql
39
39
  end
40
40
 
41
41
  def hash
42
- @h = (@n & 0xffffffffffffffff) ^ ((@n >> 64) & 0xffffffffffffffff)
42
+ @h ||= 0x7fffffffffffffff - ((@n & 0xffffffffffffffff) ^ ((@n >> 64) & 0xffffffffffffffff))
43
43
  end
44
44
 
45
45
  # Returns the numerical representation of this UUID
@@ -49,6 +49,7 @@ module Cql
49
49
  def value
50
50
  @n
51
51
  end
52
+ alias_method :to_i, :value
52
53
 
53
54
  # @private
54
55
  def eql?(other)
data/lib/cql/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cql
4
- VERSION = '2.0.0.pre0'.freeze
4
+ VERSION = '2.0.0.pre1'.freeze
5
5
  end
@@ -78,19 +78,19 @@ module Cql
78
78
  batch.add('UPDATE x SET y = 2 WHERE z = ?', 3)
79
79
  batch.add(prepared_statement, 3, 'foo')
80
80
  batch.execute.value
81
- encoded_frame = last_request.write(1, '')
82
- encoded_frame.should include('UPDATE x SET y = 1 WHERE z = 2')
83
- encoded_frame.should include('UPDATE x SET y = 2 WHERE z = ?')
84
- encoded_frame.should include(Protocol::QueryRequest.encode_values('', [3], nil))
85
- encoded_frame.should include('XXXXXXXXXXXXXXXX')
86
- encoded_frame.should include(Protocol::ExecuteRequest.encode_values('', metadata, [3, 'foo']))
81
+ encoded_frame = last_request.write(1, Protocol::CqlByteBuffer.new)
82
+ encoded_frame.to_s.should include('UPDATE x SET y = 1 WHERE z = 2')
83
+ encoded_frame.to_s.should include('UPDATE x SET y = 2 WHERE z = ?')
84
+ encoded_frame.to_s.should include(Protocol::QueryRequest.encode_values(Protocol::CqlByteBuffer.new, [3], nil))
85
+ encoded_frame.to_s.should include('XXXXXXXXXXXXXXXX')
86
+ encoded_frame.to_s.should include(Protocol::ExecuteRequest.encode_values(Protocol::CqlByteBuffer.new, metadata, [3, 'foo']))
87
87
  end
88
88
 
89
89
  it 'uses the provided type hints' do
90
90
  batch.add('UPDATE x SET y = 2 WHERE z = ?', 3, type_hints: [:int])
91
91
  batch.execute.value
92
- encoded_frame = last_request.write(1, '')
93
- encoded_frame.should include(Protocol::QueryRequest.encode_values('', [3], [:int]))
92
+ encoded_frame = last_request.write(1, Protocol::CqlByteBuffer.new)
93
+ encoded_frame.to_s.should include(Protocol::QueryRequest.encode_values(Protocol::CqlByteBuffer.new, [3], [:int]))
94
94
  end
95
95
 
96
96
  it 'tries again when a prepared statement raises NotPreparedError' do
@@ -1460,5 +1460,167 @@ module Cql
1460
1460
  end
1461
1461
  end
1462
1462
  end
1463
+
1464
+ describe SynchronousClient do
1465
+ let :client do
1466
+ described_class.new(async_client)
1467
+ end
1468
+
1469
+ let :async_client do
1470
+ double(:async_client)
1471
+ end
1472
+
1473
+ let :future do
1474
+ double(:future, value: nil)
1475
+ end
1476
+
1477
+ describe '#connect' do
1478
+ it 'calls #connect on the async client and waits for the result' do
1479
+ async_client.should_receive(:connect).and_return(future)
1480
+ future.should_receive(:value)
1481
+ client.connect
1482
+ end
1483
+
1484
+ it 'returns self' do
1485
+ async_client.stub(:connect).and_return(future)
1486
+ client.connect.should equal(client)
1487
+ end
1488
+ end
1489
+
1490
+ describe '#close' do
1491
+ it 'calls #close on the async client and waits for the result' do
1492
+ async_client.should_receive(:close).and_return(future)
1493
+ future.should_receive(:value)
1494
+ client.close
1495
+ end
1496
+
1497
+ it 'returns self' do
1498
+ async_client.stub(:close).and_return(future)
1499
+ client.close.should equal(client)
1500
+ end
1501
+ end
1502
+
1503
+ describe '#connected?' do
1504
+ it 'delegates to the async client' do
1505
+ async_client.stub(:connected?).and_return(true)
1506
+ client.connected?.should be_true
1507
+ async_client.stub(:connected?).and_return(false)
1508
+ client.connected?.should be_false
1509
+ end
1510
+ end
1511
+
1512
+ describe '#keyspace' do
1513
+ it 'delegates to the async client' do
1514
+ async_client.stub(:keyspace).and_return('foo')
1515
+ client.keyspace.should == 'foo'
1516
+ end
1517
+ end
1518
+
1519
+ describe '#use' do
1520
+ it 'calls #use on the async client and waits for the result' do
1521
+ async_client.should_receive(:use).with('foo').and_return(future)
1522
+ future.should_receive(:value)
1523
+ client.use('foo')
1524
+ end
1525
+ end
1526
+
1527
+ describe '#execute' do
1528
+ it 'calls #execute on the async client and waits for, and returns the result' do
1529
+ result = double(:result)
1530
+ async_client.stub(:execute).with('SELECT * FROM something', :one).and_return(future)
1531
+ future.stub(:value).and_return(result)
1532
+ client.execute('SELECT * FROM something', :one).should equal(result)
1533
+ end
1534
+
1535
+ it 'wraps AsynchronousPagedQueryResult in a synchronous wrapper' do
1536
+ cql = 'SELECT * FROM something'
1537
+ request = double(:request, cql: cql, values: [])
1538
+ async_result = double(:result, paging_state: 'somepagingstate')
1539
+ options = {:page_size => 10}
1540
+ async_client.stub(:execute).and_return(Future.resolved(AsynchronousQueryPagedQueryResult.new(async_client, request, async_result, options)))
1541
+ result1 = client.execute(cql, options)
1542
+ result2 = result1.next_page
1543
+ async_client.should have_received(:execute).with('SELECT * FROM something', page_size: 10, paging_state: 'somepagingstate')
1544
+ result2.should be_a(SynchronousPagedQueryResult)
1545
+ end
1546
+ end
1547
+
1548
+ describe '#prepare' do
1549
+ it 'calls #prepare on the async client, waits for the result and returns a SynchronousFuture' do
1550
+ result = double(:result)
1551
+ metadata = double(:metadata)
1552
+ result_metadata = double(:result_metadata)
1553
+ async_statement = double(:async_statement, metadata: metadata, result_metadata: result_metadata)
1554
+ another_future = double(:another_future)
1555
+ async_client.stub(:prepare).with('SELECT * FROM something').and_return(future)
1556
+ future.stub(:value).and_return(async_statement)
1557
+ statement = client.prepare('SELECT * FROM something')
1558
+ async_statement.should_receive(:execute).and_return(another_future)
1559
+ another_future.stub(:value).and_return(result)
1560
+ statement.execute.should equal(result)
1561
+ statement.metadata.should equal(metadata)
1562
+ end
1563
+ end
1564
+
1565
+ describe '#batch' do
1566
+ let :batch do
1567
+ double(:batch)
1568
+ end
1569
+
1570
+ context 'when called without a block' do
1571
+ it 'delegates to the asynchronous client and wraps the returned object in a synchronous wrapper' do
1572
+ async_client.stub(:batch).with(:unlogged, trace: true).and_return(batch)
1573
+ batch.stub(:execute).and_return(Cql::Future.resolved(VoidResult.new))
1574
+ b = client.batch(:unlogged, trace: true)
1575
+ b.execute.should be_a(VoidResult)
1576
+ end
1577
+ end
1578
+
1579
+ context 'when called with a block' do
1580
+ it 'delegates to the asynchronous client' do
1581
+ async_client.stub(:batch).with(:counter, trace: true).and_yield(batch).and_return(Cql::Future.resolved(VoidResult.new))
1582
+ yielded_batch = nil
1583
+ client.batch(:counter, trace: true) { |b| yielded_batch = b }
1584
+ yielded_batch.should equal(batch)
1585
+ end
1586
+
1587
+ it 'waits for the operation to complete' do
1588
+ async_client.stub(:batch).with(:counter, {}).and_yield(batch).and_return(Cql::Future.resolved(VoidResult.new))
1589
+ result = client.batch(:counter) { |b| }
1590
+ result.should be_a(VoidResult)
1591
+ end
1592
+ end
1593
+ end
1594
+
1595
+ describe '#async' do
1596
+ it 'returns an asynchronous client' do
1597
+ client.async.should equal(async_client)
1598
+ end
1599
+ end
1600
+
1601
+ context 'when exceptions are raised' do
1602
+ it 'replaces the backtrace of the asynchronous call to make it less confusing' do
1603
+ error = CqlError.new('Bork')
1604
+ error.set_backtrace(['Hello', 'World'])
1605
+ future.stub(:value).and_raise(error)
1606
+ async_client.stub(:execute).and_return(future)
1607
+ begin
1608
+ client.execute('SELECT * FROM something')
1609
+ rescue CqlError => e
1610
+ e.backtrace.first.should match(%r{/client.rb:\d+:in `execute'})
1611
+ end
1612
+ end
1613
+
1614
+ it 'does not replace the backtrace of non-CqlError errors' do
1615
+ future.stub(:value).and_raise('Bork')
1616
+ async_client.stub(:execute).and_return(future)
1617
+ begin
1618
+ client.execute('SELECT * FROM something')
1619
+ rescue => e
1620
+ e.backtrace.first.should_not match(%r{/client.rb:\d+:in `execute'})
1621
+ end
1622
+ end
1623
+ end
1624
+ end
1463
1625
  end
1464
1626
  end