cql-rb 1.0.0.pre6 → 1.0.0.pre7

Sign up to get free protection for your applications and to get access to all the features.
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