cql-rb 2.0.0.pre0 → 2.0.0.pre1

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 (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