cql-rb 1.0.0.pre6 → 1.0.0.pre7

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 (34) hide show
  1. data/bin/cqlexec +2 -2
  2. data/lib/cql/protocol.rb +26 -1
  3. data/lib/cql/protocol/decoding.rb +3 -0
  4. data/lib/cql/protocol/request_body.rb +15 -0
  5. data/lib/cql/protocol/request_frame.rb +1 -266
  6. data/lib/cql/protocol/requests/credentials_request.rb +31 -0
  7. data/lib/cql/protocol/requests/execute_request.rb +129 -0
  8. data/lib/cql/protocol/requests/options_request.rb +19 -0
  9. data/lib/cql/protocol/requests/prepare_request.rb +31 -0
  10. data/lib/cql/protocol/requests/query_request.rb +33 -0
  11. data/lib/cql/protocol/requests/register_request.rb +20 -0
  12. data/lib/cql/protocol/requests/startup_request.rb +27 -0
  13. data/lib/cql/protocol/response_body.rb +13 -0
  14. data/lib/cql/protocol/response_frame.rb +1 -533
  15. data/lib/cql/protocol/responses/authenticate_response.rb +21 -0
  16. data/lib/cql/protocol/responses/detailed_error_response.rb +44 -0
  17. data/lib/cql/protocol/responses/error_response.rb +28 -0
  18. data/lib/cql/protocol/responses/event_response.rb +21 -0
  19. data/lib/cql/protocol/responses/prepared_result_response.rb +23 -0
  20. data/lib/cql/protocol/responses/ready_response.rb +24 -0
  21. data/lib/cql/protocol/responses/result_response.rb +29 -0
  22. data/lib/cql/protocol/responses/rows_result_response.rb +100 -0
  23. data/lib/cql/protocol/responses/schema_change_event_result_response.rb +40 -0
  24. data/lib/cql/protocol/responses/schema_change_result_response.rb +21 -0
  25. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +21 -0
  26. data/lib/cql/protocol/responses/status_change_event_result_response.rb +24 -0
  27. data/lib/cql/protocol/responses/supported_response.rb +21 -0
  28. data/lib/cql/protocol/responses/topology_change_event_result_response.rb +14 -0
  29. data/lib/cql/protocol/responses/void_result_response.rb +19 -0
  30. data/lib/cql/protocol/type_converter.rb +165 -0
  31. data/lib/cql/version.rb +1 -1
  32. data/spec/cql/protocol/response_frame_spec.rb +31 -0
  33. data/spec/integration/regression_spec.rb +56 -9
  34. metadata +27 -2
data/bin/cqlexec CHANGED
@@ -14,7 +14,7 @@ class CqlExecutor
14
14
  end
15
15
 
16
16
  def run(io)
17
- @client = Cql::Client.new(host: @options[:host], port: @options[:port]).start!
17
+ @client = Cql::Client.connect(host: @options[:host], port: @options[:port])
18
18
 
19
19
  # TODO register for events
20
20
 
@@ -33,7 +33,7 @@ class CqlExecutor
33
33
  rescue Interrupt
34
34
  exit
35
35
  ensure
36
- @client.shutdown!
36
+ @client.close
37
37
  end
38
38
  end
39
39
 
data/lib/cql/protocol.rb CHANGED
@@ -38,5 +38,30 @@ end
38
38
 
39
39
  require 'cql/protocol/encoding'
40
40
  require 'cql/protocol/decoding'
41
+ require 'cql/protocol/type_converter'
42
+ require 'cql/protocol/response_body'
43
+ require 'cql/protocol/responses/error_response'
44
+ require 'cql/protocol/responses/detailed_error_response'
45
+ require 'cql/protocol/responses/ready_response'
46
+ require 'cql/protocol/responses/authenticate_response'
47
+ require 'cql/protocol/responses/supported_response'
48
+ require 'cql/protocol/responses/result_response'
49
+ require 'cql/protocol/responses/void_result_response'
50
+ require 'cql/protocol/responses/rows_result_response'
51
+ require 'cql/protocol/responses/set_keyspace_result_response'
52
+ require 'cql/protocol/responses/prepared_result_response'
53
+ require 'cql/protocol/responses/schema_change_result_response'
54
+ require 'cql/protocol/responses/event_response'
55
+ require 'cql/protocol/responses/schema_change_event_result_response'
56
+ require 'cql/protocol/responses/status_change_event_result_response'
57
+ require 'cql/protocol/responses/topology_change_event_result_response'
58
+ require 'cql/protocol/request_body'
59
+ require 'cql/protocol/requests/startup_request'
60
+ require 'cql/protocol/requests/credentials_request'
61
+ require 'cql/protocol/requests/options_request'
62
+ require 'cql/protocol/requests/register_request'
63
+ require 'cql/protocol/requests/query_request'
64
+ require 'cql/protocol/requests/prepare_request'
65
+ require 'cql/protocol/requests/execute_request'
41
66
  require 'cql/protocol/response_frame'
42
- require 'cql/protocol/request_frame'
67
+ require 'cql/protocol/request_frame'
@@ -1,5 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'bigdecimal'
4
+
5
+
3
6
  module Cql
4
7
  module Protocol
5
8
  module Decoding
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class RequestBody
6
+ include Encoding
7
+
8
+ attr_reader :opcode
9
+
10
+ def initialize(opcode)
11
+ @opcode = opcode
12
+ end
13
+ end
14
+ end
15
+ end
@@ -16,270 +16,5 @@ module Cql
16
16
  io << buffer
17
17
  end
18
18
  end
19
-
20
- class RequestBody
21
- include Encoding
22
-
23
- attr_reader :opcode
24
-
25
- def initialize(opcode)
26
- @opcode = opcode
27
- end
28
- end
29
-
30
- class StartupRequest < RequestBody
31
- def initialize(cql_version='3.0.0', compression=nil)
32
- super(1)
33
- @arguments = {CQL_VERSION => cql_version}
34
- @arguments[COMPRESSION] = compression if compression
35
- end
36
-
37
- def write(io)
38
- write_string_map(io, @arguments)
39
- io
40
- end
41
-
42
- def to_s
43
- %(STARTUP #@arguments)
44
- end
45
-
46
- private
47
-
48
- CQL_VERSION = 'CQL_VERSION'.freeze
49
- COMPRESSION = 'COMPRESSION'.freeze
50
- end
51
-
52
- class CredentialsRequest < RequestBody
53
- attr_reader :credentials
54
-
55
- def initialize(credentials)
56
- super(4)
57
- @credentials = credentials.dup.freeze
58
- end
59
-
60
- def write(io)
61
- write_string_map(io, @credentials)
62
- end
63
-
64
- def to_s
65
- %(CREDENTIALS #{@credentials})
66
- end
67
-
68
- def eql?(rq)
69
- self.class === rq && rq.credentials.eql?(@credentials)
70
- end
71
- alias_method :==, :eql?
72
-
73
- def hash
74
- @h ||= @credentials.hash
75
- end
76
- end
77
-
78
- class OptionsRequest < RequestBody
79
- def initialize
80
- super(5)
81
- end
82
-
83
- def write(io)
84
- io
85
- end
86
-
87
- def to_s
88
- %(OPTIONS)
89
- end
90
- end
91
-
92
- class RegisterRequest < RequestBody
93
- def initialize(*events)
94
- super(11)
95
- @events = events
96
- end
97
-
98
- def write(io)
99
- write_string_list(io, @events)
100
- end
101
-
102
- def to_s
103
- %(REGISTER #@events)
104
- end
105
- end
106
-
107
- class QueryRequest < RequestBody
108
- attr_reader :cql, :consistency
109
-
110
- def initialize(cql, consistency)
111
- super(7)
112
- @cql = cql
113
- @consistency = consistency
114
- end
115
-
116
- def write(io)
117
- write_long_string(io, @cql)
118
- write_consistency(io, @consistency)
119
- end
120
-
121
- def to_s
122
- %(QUERY "#@cql" #{@consistency.to_s.upcase})
123
- end
124
-
125
- def eql?(rq)
126
- self.class === rq && rq.cql.eql?(self.cql) && rq.consistency.eql?(self.consistency)
127
- end
128
- alias_method :==, :eql?
129
-
130
- def hash
131
- @h ||= (@cql.hash * 31) ^ consistency.hash
132
- end
133
- end
134
-
135
- class PrepareRequest < RequestBody
136
- attr_reader :cql
137
-
138
- def initialize(cql)
139
- super(9)
140
- @cql = cql
141
- end
142
-
143
- def write(io)
144
- write_long_string(io, @cql)
145
- end
146
-
147
- def to_s
148
- %(PREPARE "#@cql")
149
- end
150
-
151
- def eql?(rq)
152
- self.class === rq && rq.cql == self.cql
153
- end
154
- alias_method :==, :eql?
155
-
156
- def hash
157
- @h ||= @cql.hash
158
- end
159
- end
160
-
161
- class ExecuteRequest < RequestBody
162
- attr_reader :id, :metadata, :values, :consistency
163
-
164
- def initialize(id, metadata, values, consistency)
165
- super(10)
166
- raise ArgumentError, "Metadata for #{metadata.size} columns, but #{values.size} values given" if metadata.size != values.size
167
- @id = id
168
- @metadata = metadata
169
- @values = values
170
- @consistency = consistency
171
- end
172
-
173
- def write(io)
174
- write_short_bytes(io, @id)
175
- write_short(io, @metadata.size)
176
- @metadata.each_with_index do |(_, _, _, type), index|
177
- write_value(io, @values[index], type)
178
- end
179
- write_consistency(io, @consistency)
180
- end
181
-
182
- def to_s
183
- id = @id.each_byte.map { |x| x.to_s(16) }.join('')
184
- %(EXECUTE #{id} #@values #{@consistency.to_s.upcase})
185
- end
186
-
187
- def eql?(rq)
188
- self.class === rq && rq.id == self.id && rq.metadata == self.metadata && rq.values == self.values && rq.consistency == self.consistency
189
- end
190
- alias_method :==, :eql?
191
-
192
- def hash
193
- @h ||= begin
194
- h = 0
195
- h = ((h & 33554431) * 31) ^ @id.hash
196
- h = ((h & 33554431) * 31) ^ @metadata.hash
197
- h = ((h & 33554431) * 31) ^ @values.hash
198
- h = ((h & 33554431) * 31) ^ @consistency.hash
199
- h
200
- end
201
- end
202
-
203
- private
204
-
205
- def write_value(io, value, type)
206
- if Array === type
207
- raise InvalidValueError, 'Value for collection must be enumerable' unless value.is_a?(Enumerable)
208
- case type.first
209
- when :list, :set
210
- _, sub_type = type
211
- raw = ''
212
- write_short(raw, value.size)
213
- value.each do |element|
214
- rr = ''
215
- write_value(rr, element, sub_type)
216
- raw << rr[2, rr.length - 2]
217
- end
218
- write_bytes(io, raw)
219
- when :map
220
- _, key_type, value_type = type
221
- raw = ''
222
- write_short(raw, value.size)
223
- value.each do |key, value|
224
- rr = ''
225
- write_value(rr, key, key_type)
226
- raw << rr[2, rr.length - 2]
227
- rr = ''
228
- write_value(rr, value, value_type)
229
- raw << rr[2, rr.length - 2]
230
- end
231
- write_bytes(io, raw)
232
- else
233
- raise UnsupportedColumnTypeError, %(Unsupported column collection type: #{type.first})
234
- end
235
- else
236
- case type
237
- when :ascii
238
- write_bytes(io, value.encode(::Encoding::ASCII))
239
- when :bigint
240
- write_int(io, 8)
241
- write_long(io, value)
242
- when :blob
243
- write_bytes(io, value.encode(::Encoding::BINARY))
244
- when :boolean
245
- write_int(io, 1)
246
- io << (value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
247
- when :decimal
248
- raw = write_decimal('', value)
249
- write_int(io, raw.size)
250
- io << raw
251
- when :double
252
- write_int(io, 8)
253
- write_double(io, value)
254
- when :float
255
- write_int(io, 4)
256
- write_float(io, value)
257
- when :inet
258
- write_int(io, value.ipv6? ? 16 : 4)
259
- io << value.hton
260
- when :int
261
- write_int(io, 4)
262
- write_int(io, value)
263
- when :text, :varchar
264
- write_bytes(io, value.encode(::Encoding::UTF_8))
265
- when :timestamp
266
- ms = (value.to_f * 1000).to_i
267
- write_int(io, 8)
268
- write_long(io, ms)
269
- when :timeuuid, :uuid
270
- write_int(io, 16)
271
- write_uuid(io, value)
272
- when :varint
273
- raw = write_varint('', value)
274
- write_int(io, raw.length)
275
- io << raw
276
- else
277
- raise UnsupportedColumnTypeError, %(Unsupported column type: #{type})
278
- end
279
- end
280
- rescue TypeError => e
281
- raise TypeError, %("#{value}" cannot be encoded as #{type.to_s.upcase}: #{e.message}), e.backtrace
282
- end
283
- end
284
19
  end
285
- end
20
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class CredentialsRequest < RequestBody
6
+ attr_reader :credentials
7
+
8
+ def initialize(credentials)
9
+ super(4)
10
+ @credentials = credentials.dup.freeze
11
+ end
12
+
13
+ def write(io)
14
+ write_string_map(io, @credentials)
15
+ end
16
+
17
+ def to_s
18
+ %(CREDENTIALS #{@credentials})
19
+ end
20
+
21
+ def eql?(rq)
22
+ self.class === rq && rq.credentials.eql?(@credentials)
23
+ end
24
+ alias_method :==, :eql?
25
+
26
+ def hash
27
+ @h ||= @credentials.hash
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,129 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class ExecuteRequest < RequestBody
6
+ attr_reader :id, :metadata, :values, :consistency
7
+
8
+ def initialize(id, metadata, values, consistency)
9
+ super(10)
10
+ raise ArgumentError, "Metadata for #{metadata.size} columns, but #{values.size} values given" if metadata.size != values.size
11
+ @id = id
12
+ @metadata = metadata
13
+ @values = values
14
+ @consistency = consistency
15
+ end
16
+
17
+ def write(io)
18
+ write_short_bytes(io, @id)
19
+ write_short(io, @metadata.size)
20
+ @metadata.each_with_index do |(_, _, _, type), index|
21
+ write_value(io, @values[index], type)
22
+ end
23
+ write_consistency(io, @consistency)
24
+ end
25
+
26
+ def to_s
27
+ id = @id.each_byte.map { |x| x.to_s(16) }.join('')
28
+ %(EXECUTE #{id} #@values #{@consistency.to_s.upcase})
29
+ end
30
+
31
+ def eql?(rq)
32
+ self.class === rq && rq.id == self.id && rq.metadata == self.metadata && rq.values == self.values && rq.consistency == self.consistency
33
+ end
34
+ alias_method :==, :eql?
35
+
36
+ def hash
37
+ @h ||= begin
38
+ h = 0
39
+ h = ((h & 33554431) * 31) ^ @id.hash
40
+ h = ((h & 33554431) * 31) ^ @metadata.hash
41
+ h = ((h & 33554431) * 31) ^ @values.hash
42
+ h = ((h & 33554431) * 31) ^ @consistency.hash
43
+ h
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def write_value(io, value, type)
50
+ if Array === type
51
+ raise InvalidValueError, 'Value for collection must be enumerable' unless value.is_a?(Enumerable)
52
+ case type.first
53
+ when :list, :set
54
+ _, sub_type = type
55
+ raw = ''
56
+ write_short(raw, value.size)
57
+ value.each do |element|
58
+ rr = ''
59
+ write_value(rr, element, sub_type)
60
+ raw << rr[2, rr.length - 2]
61
+ end
62
+ write_bytes(io, raw)
63
+ when :map
64
+ _, key_type, value_type = type
65
+ raw = ''
66
+ write_short(raw, value.size)
67
+ value.each do |key, value|
68
+ rr = ''
69
+ write_value(rr, key, key_type)
70
+ raw << rr[2, rr.length - 2]
71
+ rr = ''
72
+ write_value(rr, value, value_type)
73
+ raw << rr[2, rr.length - 2]
74
+ end
75
+ write_bytes(io, raw)
76
+ else
77
+ raise UnsupportedColumnTypeError, %(Unsupported column collection type: #{type.first})
78
+ end
79
+ else
80
+ case type
81
+ when :ascii
82
+ write_bytes(io, value.encode(::Encoding::ASCII))
83
+ when :bigint
84
+ write_int(io, 8)
85
+ write_long(io, value)
86
+ when :blob
87
+ write_bytes(io, value.encode(::Encoding::BINARY))
88
+ when :boolean
89
+ write_int(io, 1)
90
+ io << (value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
91
+ when :decimal
92
+ raw = write_decimal('', value)
93
+ write_int(io, raw.size)
94
+ io << raw
95
+ when :double
96
+ write_int(io, 8)
97
+ write_double(io, value)
98
+ when :float
99
+ write_int(io, 4)
100
+ write_float(io, value)
101
+ when :inet
102
+ write_int(io, value.ipv6? ? 16 : 4)
103
+ io << value.hton
104
+ when :int
105
+ write_int(io, 4)
106
+ write_int(io, value)
107
+ when :text, :varchar
108
+ write_bytes(io, value.encode(::Encoding::UTF_8))
109
+ when :timestamp
110
+ ms = (value.to_f * 1000).to_i
111
+ write_int(io, 8)
112
+ write_long(io, ms)
113
+ when :timeuuid, :uuid
114
+ write_int(io, 16)
115
+ write_uuid(io, value)
116
+ when :varint
117
+ raw = write_varint('', value)
118
+ write_int(io, raw.length)
119
+ io << raw
120
+ else
121
+ raise UnsupportedColumnTypeError, %(Unsupported column type: #{type})
122
+ end
123
+ end
124
+ rescue TypeError => e
125
+ raise TypeError, %("#{value}" cannot be encoded as #{type.to_s.upcase}: #{e.message}), e.backtrace
126
+ end
127
+ end
128
+ end
129
+ end