cql-rb 1.2.2 → 2.0.0.pre0

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 (108) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -0
  3. data/README.md +139 -17
  4. data/lib/cql/client.rb +237 -8
  5. data/lib/cql/client/asynchronous_client.rb +138 -54
  6. data/lib/cql/client/asynchronous_prepared_statement.rb +41 -6
  7. data/lib/cql/client/authenticators.rb +46 -0
  8. data/lib/cql/client/batch.rb +115 -0
  9. data/lib/cql/client/connector.rb +255 -0
  10. data/lib/cql/client/execute_options_decoder.rb +25 -9
  11. data/lib/cql/client/keyspace_changer.rb +5 -5
  12. data/lib/cql/client/peer_discovery.rb +33 -0
  13. data/lib/cql/client/query_result.rb +124 -1
  14. data/lib/cql/client/request_runner.rb +4 -2
  15. data/lib/cql/client/synchronous_client.rb +14 -2
  16. data/lib/cql/client/synchronous_prepared_statement.rb +19 -1
  17. data/lib/cql/future.rb +97 -50
  18. data/lib/cql/io/connection.rb +0 -1
  19. data/lib/cql/io/io_reactor.rb +1 -1
  20. data/lib/cql/protocol.rb +8 -1
  21. data/lib/cql/protocol/cql_protocol_handler.rb +2 -2
  22. data/lib/cql/protocol/decoding.rb +10 -15
  23. data/lib/cql/protocol/frame_decoder.rb +2 -1
  24. data/lib/cql/protocol/frame_encoder.rb +5 -4
  25. data/lib/cql/protocol/requests/auth_response_request.rb +31 -0
  26. data/lib/cql/protocol/requests/batch_request.rb +59 -0
  27. data/lib/cql/protocol/requests/credentials_request.rb +1 -1
  28. data/lib/cql/protocol/requests/execute_request.rb +45 -17
  29. data/lib/cql/protocol/requests/options_request.rb +1 -1
  30. data/lib/cql/protocol/requests/prepare_request.rb +1 -1
  31. data/lib/cql/protocol/requests/query_request.rb +97 -5
  32. data/lib/cql/protocol/requests/register_request.rb +1 -1
  33. data/lib/cql/protocol/requests/startup_request.rb +4 -4
  34. data/lib/cql/protocol/response.rb +2 -2
  35. data/lib/cql/protocol/responses/auth_challenge_response.rb +25 -0
  36. data/lib/cql/protocol/responses/auth_success_response.rb +25 -0
  37. data/lib/cql/protocol/responses/authenticate_response.rb +1 -1
  38. data/lib/cql/protocol/responses/detailed_error_response.rb +1 -1
  39. data/lib/cql/protocol/responses/error_response.rb +3 -2
  40. data/lib/cql/protocol/responses/event_response.rb +3 -2
  41. data/lib/cql/protocol/responses/prepared_result_response.rb +10 -6
  42. data/lib/cql/protocol/responses/raw_rows_result_response.rb +27 -0
  43. data/lib/cql/protocol/responses/ready_response.rb +1 -1
  44. data/lib/cql/protocol/responses/result_response.rb +2 -2
  45. data/lib/cql/protocol/responses/rows_result_response.rb +43 -23
  46. data/lib/cql/protocol/responses/schema_change_event_response.rb +1 -1
  47. data/lib/cql/protocol/responses/schema_change_result_response.rb +1 -1
  48. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +1 -1
  49. data/lib/cql/protocol/responses/status_change_event_response.rb +1 -1
  50. data/lib/cql/protocol/responses/supported_response.rb +1 -1
  51. data/lib/cql/protocol/responses/void_result_response.rb +1 -1
  52. data/lib/cql/protocol/type_converter.rb +2 -2
  53. data/lib/cql/uuid.rb +2 -2
  54. data/lib/cql/version.rb +1 -1
  55. data/spec/cql/client/asynchronous_client_spec.rb +493 -50
  56. data/spec/cql/client/asynchronous_prepared_statement_spec.rb +193 -11
  57. data/spec/cql/client/authenticators_spec.rb +56 -0
  58. data/spec/cql/client/batch_spec.rb +277 -0
  59. data/spec/cql/client/connector_spec.rb +606 -0
  60. data/spec/cql/client/execute_options_decoder_spec.rb +95 -0
  61. data/spec/cql/client/keyspace_changer_spec.rb +8 -8
  62. data/spec/cql/client/peer_discovery_spec.rb +92 -0
  63. data/spec/cql/client/query_result_spec.rb +352 -0
  64. data/spec/cql/client/request_runner_spec.rb +31 -5
  65. data/spec/cql/client/synchronous_client_spec.rb +44 -1
  66. data/spec/cql/client/synchronous_prepared_statement_spec.rb +63 -1
  67. data/spec/cql/future_spec.rb +50 -2
  68. data/spec/cql/protocol/cql_protocol_handler_spec.rb +16 -5
  69. data/spec/cql/protocol/decoding_spec.rb +16 -6
  70. data/spec/cql/protocol/encoding_spec.rb +3 -1
  71. data/spec/cql/protocol/frame_encoder_spec.rb +99 -50
  72. data/spec/cql/protocol/requests/auth_response_request_spec.rb +62 -0
  73. data/spec/cql/protocol/requests/batch_request_spec.rb +155 -0
  74. data/spec/cql/protocol/requests/credentials_request_spec.rb +1 -1
  75. data/spec/cql/protocol/requests/execute_request_spec.rb +184 -71
  76. data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
  77. data/spec/cql/protocol/requests/prepare_request_spec.rb +1 -1
  78. data/spec/cql/protocol/requests/query_request_spec.rb +255 -32
  79. data/spec/cql/protocol/requests/register_request_spec.rb +1 -1
  80. data/spec/cql/protocol/requests/startup_request_spec.rb +12 -6
  81. data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +31 -0
  82. data/spec/cql/protocol/responses/auth_success_response_spec.rb +31 -0
  83. data/spec/cql/protocol/responses/authenticate_response_spec.rb +2 -1
  84. data/spec/cql/protocol/responses/detailed_error_response_spec.rb +14 -7
  85. data/spec/cql/protocol/responses/error_response_spec.rb +4 -2
  86. data/spec/cql/protocol/responses/event_response_spec.rb +7 -4
  87. data/spec/cql/protocol/responses/prepared_result_response_spec.rb +89 -34
  88. data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +66 -0
  89. data/spec/cql/protocol/responses/ready_response_spec.rb +1 -1
  90. data/spec/cql/protocol/responses/result_response_spec.rb +19 -7
  91. data/spec/cql/protocol/responses/rows_result_response_spec.rb +56 -11
  92. data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +2 -1
  93. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +2 -1
  94. data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +1 -1
  95. data/spec/cql/protocol/responses/status_change_event_response_spec.rb +2 -1
  96. data/spec/cql/protocol/responses/supported_response_spec.rb +2 -1
  97. data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +2 -1
  98. data/spec/cql/protocol/responses/void_result_response_spec.rb +1 -1
  99. data/spec/cql/protocol/type_converter_spec.rb +21 -4
  100. data/spec/cql/uuid_spec.rb +10 -3
  101. data/spec/integration/client_spec.rb +251 -28
  102. data/spec/integration/protocol_spec.rb +213 -62
  103. data/spec/integration/regression_spec.rb +4 -1
  104. data/spec/integration/uuid_spec.rb +4 -1
  105. data/spec/support/fake_io_reactor.rb +5 -5
  106. metadata +36 -7
  107. data/lib/cql/client/connection_helper.rb +0 -181
  108. data/spec/cql/client/connection_helper_spec.rb +0 -429
@@ -4,11 +4,13 @@ module Cql
4
4
  module Client
5
5
  # @private
6
6
  class RequestRunner
7
- def execute(connection, request, timeout=nil)
7
+ def execute(connection, request, timeout=nil, raw_metadata=nil)
8
8
  connection.send_request(request, timeout).map do |response|
9
9
  case response
10
+ when Protocol::RawRowsResultResponse
11
+ LazyQueryResult.new(raw_metadata, response, response.trace_id, response.paging_state)
10
12
  when Protocol::RowsResultResponse
11
- QueryResult.new(response.metadata, response.rows, response.trace_id)
13
+ QueryResult.new(response.metadata, response.rows, response.trace_id, response.paging_state)
12
14
  when Protocol::VoidResultResponse
13
15
  response.trace_id ? VoidResult.new(response.trace_id) : VoidResult::INSTANCE
14
16
  when Protocol::ErrorResponse
@@ -50,8 +50,12 @@ module Cql
50
50
  synchronous_backtrace { @async_client.use(keyspace).value }
51
51
  end
52
52
 
53
- def execute(cql, consistency=nil)
54
- synchronous_backtrace { @async_client.execute(cql, consistency).value }
53
+ def execute(cql, *args)
54
+ synchronous_backtrace do
55
+ result = @async_client.execute(cql, *args).value
56
+ result = SynchronousPagedQueryResult.new(result) if result.is_a?(PagedQueryResult)
57
+ result
58
+ end
55
59
  end
56
60
 
57
61
  def prepare(cql)
@@ -59,6 +63,14 @@ module Cql
59
63
  SynchronousPreparedStatement.new(async_statement)
60
64
  end
61
65
 
66
+ def batch(type=:logged, options={}, &block)
67
+ if block_given?
68
+ synchronous_backtrace { @async_client.batch(type, options, &block).value }
69
+ else
70
+ SynchronousBatch.new(@async_client.batch(type, options))
71
+ end
72
+ end
73
+
62
74
  def async
63
75
  @async_client
64
76
  end
@@ -9,10 +9,23 @@ module Cql
9
9
  def initialize(async_statement)
10
10
  @async_statement = async_statement
11
11
  @metadata = async_statement.metadata
12
+ @result_metadata = async_statement.result_metadata
12
13
  end
13
14
 
14
15
  def execute(*args)
15
- synchronous_backtrace { @async_statement.execute(*args).value }
16
+ synchronous_backtrace do
17
+ result = @async_statement.execute(*args).value
18
+ result = SynchronousPagedQueryResult.new(result) if result.is_a?(PagedQueryResult)
19
+ result
20
+ end
21
+ end
22
+
23
+ def batch(type=:logged, options=nil, &block)
24
+ if block_given?
25
+ synchronous_backtrace { @async_statement.batch(type, options, &block).value }
26
+ else
27
+ SynchronousPreparedStatementBatch.new(@async_statement.batch(type, options))
28
+ end
16
29
  end
17
30
 
18
31
  def pipeline
@@ -24,6 +37,11 @@ module Cql
24
37
  def async
25
38
  @async_statement
26
39
  end
40
+
41
+ # @private
42
+ def add_to_batch(batch, connection, bound_arguments)
43
+ @async_statement.add_to_batch(batch, connection, bound_arguments)
44
+ end
27
45
  end
28
46
 
29
47
  # @private
@@ -88,11 +88,8 @@ module Cql
88
88
  # @return [Cql::Future<Array>] an array of the values of the constituent
89
89
  # futures
90
90
  def all(*futures)
91
- if futures.any?
92
- CombinedFuture.new(futures)
93
- else
94
- resolved([])
95
- end
91
+ return resolved([]) if futures.empty?
92
+ CombinedFuture.new(futures)
96
93
  end
97
94
 
98
95
  # Returns a future which will be resolved with the value of the first
@@ -102,11 +99,8 @@ module Cql
102
99
  # @param [Array<Cql::Future>] futures the futures to monitor
103
100
  # @return [Cql::Future] a future which represents the first completing future
104
101
  def first(*futures)
105
- if futures.any?
106
- FirstFuture.new(futures)
107
- else
108
- resolved
109
- end
102
+ return resolved if futures.empty?
103
+ FirstFuture.new(futures)
110
104
  end
111
105
 
112
106
  # Creates a new pre-resolved future.
@@ -133,16 +127,15 @@ module Cql
133
127
  # @example
134
128
  # future2 = future1.map { |value| value * 2 }
135
129
  #
130
+ # @param [Object] value the value of this future (when no block is given)
136
131
  # @yieldparam [Object] value the value of this future
137
132
  # @yieldreturn [Object] the transformed value
138
133
  # @return [Cql::Future] a new future representing the transformed value
139
- def map(&block)
140
- p = Promise.new
141
- on_failure { |e| p.fail(e) }
142
- on_value do |v|
143
- p.try(v, &block)
134
+ def map(value=nil, &block)
135
+ CompletableFuture.new.tap do |f|
136
+ on_failure { |e| f.fail(e) }
137
+ on_value { |v| run(f, value, block, v) }
144
138
  end
145
- p.future
146
139
  end
147
140
 
148
141
  # Returns a new future representing a transformation of this future's value,
@@ -157,17 +150,10 @@ module Cql
157
150
  # @yieldreturn [Cql::Future] a future representing the transformed value
158
151
  # @return [Cql::Future] a new future representing the transformed value
159
152
  def flat_map(&block)
160
- p = Promise.new
161
- on_failure { |e| p.fail(e) }
162
- on_value do |v|
163
- begin
164
- f = block.call(v)
165
- p.observe(f)
166
- rescue => e
167
- p.fail(e)
168
- end
153
+ CompletableFuture.new.tap do |f|
154
+ on_failure { |e| f.fail(e) }
155
+ on_value { |v| chain(f, block, v) }
169
156
  end
170
- p.future
171
157
  end
172
158
 
173
159
  # Returns a new future which represents either the value of the original
@@ -185,18 +171,15 @@ module Cql
185
171
  # future1.fail(error)
186
172
  # future2.value # => 'foo'
187
173
  #
174
+ # @param [Object] value the value when no block is given
188
175
  # @yieldparam [Object] error the error from the original future
189
176
  # @yieldreturn [Object] the value of the new future
190
177
  # @return [Cql::Future] a new future representing a value recovered from the error
191
- def recover(&block)
192
- p = Promise.new
193
- on_failure do |e|
194
- p.try(e, &block)
195
- end
196
- on_value do |v|
197
- p.fulfill(v)
178
+ def recover(value=nil, &block)
179
+ CompletableFuture.new.tap do |f|
180
+ on_failure { |e| run(f, value, block, e) }
181
+ on_value { |v| f.resolve(v) }
198
182
  end
199
- p.future
200
183
  end
201
184
 
202
185
  # Returns a new future which represents either the value of the original
@@ -222,19 +205,27 @@ module Cql
222
205
  # @return [Cql::Future] a new future representing a value recovered from the
223
206
  # error
224
207
  def fallback(&block)
225
- p = Promise.new
226
- on_failure do |e|
227
- begin
228
- f = block.call(e)
229
- p.observe(f)
230
- rescue => e
231
- p.fail(e)
232
- end
233
- end
234
- on_value do |v|
235
- p.fulfill(v)
208
+ CompletableFuture.new.tap do |f|
209
+ on_failure { |e| chain(f, block, e) }
210
+ on_value { |v| f.resolve(v) }
236
211
  end
237
- p.future
212
+ end
213
+
214
+ private
215
+
216
+ def run(f, value, producer, arg)
217
+ value = producer ? producer.call(arg) : value
218
+ f.resolve(value)
219
+ rescue => e
220
+ f.fail(e)
221
+ end
222
+
223
+ def chain(f, constructor, arg)
224
+ ff = constructor.call(arg)
225
+ ff.on_failure { |e| f.fail(e) }
226
+ ff.on_value { |v| f.resolve(v) }
227
+ rescue => e
228
+ f.fail(e)
238
229
  end
239
230
  end
240
231
 
@@ -451,18 +442,74 @@ module Cql
451
442
  # @private
452
443
  class ResolvedFuture < Future
453
444
  def initialize(value=nil)
454
- super()
455
- @value = value
456
445
  @resolved = true
446
+ @failed = false
447
+ @value = value
448
+ @error = nil
449
+ end
450
+
451
+ def value
452
+ @value
453
+ end
454
+
455
+ def completed?
456
+ true
457
+ end
458
+
459
+ def resolved?
460
+ true
461
+ end
462
+
463
+ def failed?
464
+ false
465
+ end
466
+
467
+ def on_complete(&listener)
468
+ listener.call(self) rescue nil
469
+ end
470
+
471
+ def on_value(&listener)
472
+ listener.call(value) rescue nil
473
+ end
474
+
475
+ def on_failure
457
476
  end
458
477
  end
459
478
 
460
479
  # @private
461
480
  class FailedFuture < Future
462
481
  def initialize(error)
463
- super()
464
- @error = error
482
+ @resolved = false
465
483
  @failed = true
484
+ @value = nil
485
+ @error = error
486
+ end
487
+
488
+ def value
489
+ raise @error
490
+ end
491
+
492
+ def completed?
493
+ true
494
+ end
495
+
496
+ def resolved?
497
+ false
498
+ end
499
+
500
+ def failed?
501
+ true
502
+ end
503
+
504
+ def on_complete(&listener)
505
+ listener.call(self) rescue nil
506
+ end
507
+
508
+ def on_value
509
+ end
510
+
511
+ def on_failure(&listener)
512
+ listener.call(@error) rescue nil
466
513
  end
467
514
  end
468
515
  end
@@ -167,7 +167,6 @@ module Cql
167
167
  def flush
168
168
  if writable?
169
169
  @lock.synchronize do
170
- s = @write_buffer.cheap_peek.dup
171
170
  bytes_written = @io.write_nonblock(@write_buffer.cheap_peek)
172
171
  @write_buffer.discard(bytes_written)
173
172
  end
@@ -192,7 +192,7 @@ module Cql
192
192
  protocol_handler = @protocol_handler_factory.call(connection, self)
193
193
  @io_loop.add_socket(connection)
194
194
  @unblocker.unblock!
195
- f.map { protocol_handler }
195
+ f.map(protocol_handler)
196
196
  end
197
197
 
198
198
  # Returns a future that completes after the specified number of seconds.
@@ -14,9 +14,11 @@ module Cql
14
14
  UnsupportedResultKindError = Class.new(ProtocolError)
15
15
  UnsupportedColumnTypeError = Class.new(ProtocolError)
16
16
  UnsupportedEventTypeError = Class.new(ProtocolError)
17
+ UnsupportedFeatureError = Class.new(ProtocolError)
17
18
  UnexpectedCompressionError = Class.new(ProtocolError)
19
+ UnmaterializedRowsError = Class.new(ProtocolError)
18
20
 
19
- CONSISTENCIES = [:any, :one, :two, :three, :quorum, :all, :local_quorum, :each_quorum, nil, nil, nil, nil, nil, nil, nil, nil, :local_one].freeze
21
+ CONSISTENCIES = [:any, :one, :two, :three, :quorum, :all, :local_quorum, :each_quorum, :serial, :local_serial, :local_one].freeze
20
22
 
21
23
  module Formats
22
24
  CHAR_FORMAT = 'c'.freeze
@@ -43,6 +45,8 @@ require 'cql/protocol/encoding'
43
45
  require 'cql/protocol/decoding'
44
46
  require 'cql/protocol/type_converter'
45
47
  require 'cql/protocol/response'
48
+ require 'cql/protocol/responses/auth_challenge_response'
49
+ require 'cql/protocol/responses/auth_success_response'
46
50
  require 'cql/protocol/responses/error_response'
47
51
  require 'cql/protocol/responses/detailed_error_response'
48
52
  require 'cql/protocol/responses/ready_response'
@@ -51,6 +55,7 @@ require 'cql/protocol/responses/supported_response'
51
55
  require 'cql/protocol/responses/result_response'
52
56
  require 'cql/protocol/responses/void_result_response'
53
57
  require 'cql/protocol/responses/rows_result_response'
58
+ require 'cql/protocol/responses/raw_rows_result_response'
54
59
  require 'cql/protocol/responses/set_keyspace_result_response'
55
60
  require 'cql/protocol/responses/prepared_result_response'
56
61
  require 'cql/protocol/responses/schema_change_result_response'
@@ -59,6 +64,8 @@ require 'cql/protocol/responses/schema_change_event_response'
59
64
  require 'cql/protocol/responses/status_change_event_response'
60
65
  require 'cql/protocol/responses/topology_change_event_response'
61
66
  require 'cql/protocol/request'
67
+ require 'cql/protocol/requests/auth_response_request'
68
+ require 'cql/protocol/requests/batch_request'
62
69
  require 'cql/protocol/requests/startup_request'
63
70
  require 'cql/protocol/requests/credentials_request'
64
71
  require 'cql/protocol/requests/options_request'
@@ -19,7 +19,7 @@ module Cql
19
19
  # @return [String] the current keyspace for the underlying connection
20
20
  attr_reader :keyspace
21
21
 
22
- def initialize(connection, scheduler, compressor=nil)
22
+ def initialize(connection, scheduler, protocol_version, compressor=nil)
23
23
  @connection = connection
24
24
  @scheduler = scheduler
25
25
  @compressor = compressor
@@ -27,7 +27,7 @@ module Cql
27
27
  @connection.on_closed(&method(:socket_closed))
28
28
  @promises = Array.new(128) { nil }
29
29
  @read_buffer = ByteBuffer.new
30
- @frame_encoder = FrameEncoder.new(@compressor)
30
+ @frame_encoder = FrameEncoder.new(protocol_version, @compressor)
31
31
  @frame_decoder = FrameDecoder.new(@compressor)
32
32
  @current_frame = FrameDecoder::NULL_FRAME
33
33
  @request_queue_in = []
@@ -46,19 +46,16 @@ module Cql
46
46
  fraction_string << number_string[number_string.length - size, number_string.length]
47
47
  end
48
48
  BigDecimal.new(fraction_string)
49
- rescue RangeError => e
49
+ rescue DecodingError => e
50
50
  raise DecodingError, e.message, e.backtrace
51
51
  end
52
52
 
53
53
  def read_long!(buffer)
54
- hi, lo = buffer.read(8).unpack(Formats::TWO_INTS_FORMAT)
55
- if (hi > 0x7fffffff)
56
- hi ^= 0xffffffff
57
- lo ^= 0xffffffff
58
- 0 - (hi << 32) - lo - 1
59
- else
60
- (hi << 32) + lo
61
- end
54
+ top, bottom = buffer.read(8).unpack(Formats::TWO_INTS_FORMAT)
55
+ return (top << 32) | bottom if top <= 0x7fffffff
56
+ top ^= 0xffffffff
57
+ bottom ^= 0xffffffff
58
+ -((top << 32) | bottom) - 1
62
59
  rescue RangeError => e
63
60
  raise DecodingError, e.message, e.backtrace
64
61
  end
@@ -76,11 +73,9 @@ module Cql
76
73
  end
77
74
 
78
75
  def read_int!(buffer)
79
- val = buffer.read_int
80
- if (val > 0x7fffffff)
81
- val = 0 - ((val - 1) ^ 0xffffffff)
82
- end
83
- val
76
+ n = buffer.read_int
77
+ return n if n <= 0x7fffffff
78
+ n - 0xffffffff - 1
84
79
  rescue RangeError => e
85
80
  raise DecodingError, "Not enough bytes available to decode an int: #{e.message}", e.backtrace
86
81
  end
@@ -111,7 +106,7 @@ module Cql
111
106
 
112
107
  def read_uuid!(buffer, impl=Uuid)
113
108
  impl.new(read_varint!(buffer, 16, false))
114
- rescue RangeError => e
109
+ rescue DecodingError => e
115
110
  raise DecodingError, "Not enough bytes available to decode a UUID: #{e.message}", e.backtrace
116
111
  end
117
112
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Cql
4
4
  module Protocol
5
+ # @private
5
6
  class FrameDecoder
6
7
  def initialize(compressor=nil)
7
8
  @compressor = compressor
@@ -44,7 +45,7 @@ module Cql
44
45
  end
45
46
  extra_length = buffer.length - size
46
47
  trace_id = tracing == 2 ? Decoding.read_uuid!(buffer) : nil
47
- response = Response.decode!(opcode, buffer, trace_id)
48
+ response = Response.decode!(opcode, protocol_version, buffer, size, trace_id)
48
49
  if buffer.length > extra_length
49
50
  buffer.discard(buffer.length - extra_length)
50
51
  end
@@ -2,22 +2,23 @@
2
2
 
3
3
  module Cql
4
4
  module Protocol
5
+ # @private
5
6
  class FrameEncoder
6
- def initialize(compressor=nil)
7
+ def initialize(protocol_version=1, compressor=nil)
8
+ @protocol_version = protocol_version
7
9
  @compressor = compressor
8
10
  end
9
11
 
10
12
  def encode_frame(request, stream_id=0, buffer=nil)
11
13
  raise InvalidStreamIdError, 'The stream ID must be between 0 and 127' unless 0 <= stream_id && stream_id < 128
12
14
  buffer ||= ByteBuffer.new
13
- offset = buffer.bytesize
14
15
  flags = request.trace? ? 2 : 0
15
- body = request.write(ByteBuffer.new)
16
+ body = request.write(@protocol_version, ByteBuffer.new)
16
17
  if @compressor && request.compressable? && @compressor.compress?(body)
17
18
  flags |= 1
18
19
  body = @compressor.compress(body)
19
20
  end
20
- header = [1, flags, stream_id, request.opcode, body.bytesize]
21
+ header = [@protocol_version, flags, stream_id, request.opcode, body.bytesize]
21
22
  buffer << header.pack(Formats::HEADER_FORMAT)
22
23
  buffer << body
23
24
  buffer