cql-rb 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,7 +31,20 @@ module Cql
31
31
  def read_decimal!(buffer, length=buffer.length)
32
32
  size = read_int!(buffer)
33
33
  number_string = read_varint!(buffer, length - 4).to_s
34
- fraction_string = number_string[0, number_string.length - size] << DECIMAL_POINT << number_string[number_string.length - size, number_string.length]
34
+ if number_string.length < size
35
+ if number_string.start_with?(MINUS)
36
+ number_string = number_string[1, number_string.length - 1]
37
+ fraction_string = MINUS + ZERO << DECIMAL_POINT
38
+ else
39
+ fraction_string = ZERO + DECIMAL_POINT
40
+ end
41
+ (size - number_string.length).times { fraction_string << ZERO }
42
+ fraction_string << number_string
43
+ else
44
+ fraction_string = number_string[0, number_string.length - size]
45
+ fraction_string << DECIMAL_POINT
46
+ fraction_string << number_string[number_string.length - size, number_string.length]
47
+ end
35
48
  BigDecimal.new(fraction_string)
36
49
  rescue RangeError => e
37
50
  raise DecodingError, e.message, e.backtrace
@@ -171,6 +184,8 @@ module Cql
171
184
 
172
185
  private
173
186
 
187
+ MINUS = '-'.freeze
188
+ ZERO = '0'.freeze
174
189
  DECIMAL_POINT = '.'.freeze
175
190
  end
176
191
  end
@@ -36,27 +36,35 @@ module Cql
36
36
  def to_bytes(io, type, value, size_bytes=4)
37
37
  case type
38
38
  when Array
39
- unless value.is_a?(Enumerable)
39
+ unless value.nil? || value.is_a?(Enumerable)
40
40
  raise InvalidValueError, 'Value for collection must be enumerable'
41
41
  end
42
42
  case type.first
43
43
  when :list, :set
44
44
  _, sub_type = type
45
- raw = ''
46
- write_short(raw, value.size)
47
- value.each do |element|
48
- to_bytes(raw, sub_type, element, 2)
45
+ if value
46
+ raw = ''
47
+ write_short(raw, value.size)
48
+ value.each do |element|
49
+ to_bytes(raw, sub_type, element, 2)
50
+ end
51
+ write_bytes(io, raw)
52
+ else
53
+ nil_to_bytes(io, size_bytes)
49
54
  end
50
- write_bytes(io, raw)
51
55
  when :map
52
56
  _, key_type, value_type = type
53
- raw = ''
54
- write_short(raw, value.size)
55
- value.each do |key, value|
56
- to_bytes(raw, key_type, key, 2)
57
- to_bytes(raw, value_type, value, 2)
57
+ if value
58
+ raw = ''
59
+ write_short(raw, value.size)
60
+ value.each do |key, value|
61
+ to_bytes(raw, key_type, key, 2)
62
+ to_bytes(raw, value_type, value, 2)
63
+ end
64
+ write_bytes(io, raw)
65
+ else
66
+ nil_to_bytes(io, size_bytes)
58
67
  end
59
- write_bytes(io, raw)
60
68
  else
61
69
  raise UnsupportedColumnTypeError, %(Unsupported column collection type: #{type.first})
62
70
  end
@@ -224,7 +232,7 @@ module Cql
224
232
  end
225
233
 
226
234
  def ascii_to_bytes(io, value, size_bytes)
227
- v = value.encode(::Encoding::ASCII)
235
+ v = value && value.encode(::Encoding::ASCII)
228
236
  if size_bytes == 4
229
237
  write_bytes(io, v)
230
238
  else
@@ -233,16 +241,16 @@ module Cql
233
241
  end
234
242
 
235
243
  def bigint_to_bytes(io, value, size_bytes)
236
- if size_bytes == 4
237
- write_int(io, 8)
244
+ if value
245
+ size_to_bytes(io, 8, size_bytes)
246
+ write_long(io, value)
238
247
  else
239
- write_short(io, 8)
248
+ nil_to_bytes(io, size_bytes)
240
249
  end
241
- write_long(io, value)
242
250
  end
243
251
 
244
252
  def blob_to_bytes(io, value, size_bytes)
245
- v = value.encode(::Encoding::BINARY)
253
+ v = value && value.encode(::Encoding::BINARY)
246
254
  if size_bytes == 4
247
255
  write_bytes(io, v)
248
256
  else
@@ -251,16 +259,16 @@ module Cql
251
259
  end
252
260
 
253
261
  def boolean_to_bytes(io, value, size_bytes)
254
- if size_bytes == 4
255
- write_int(io, 1)
262
+ if !value.nil?
263
+ size_to_bytes(io, 1, size_bytes)
264
+ io << (value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
256
265
  else
257
- write_short(io, 1)
266
+ nil_to_bytes(io, size_bytes)
258
267
  end
259
- io << (value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
260
268
  end
261
269
 
262
270
  def decimal_to_bytes(io, value, size_bytes)
263
- raw = write_decimal('', value)
271
+ raw = value && write_decimal('', value)
264
272
  if size_bytes == 4
265
273
  write_bytes(io, raw)
266
274
  else
@@ -269,43 +277,43 @@ module Cql
269
277
  end
270
278
 
271
279
  def double_to_bytes(io, value, size_bytes)
272
- if size_bytes == 4
273
- write_int(io, 8)
280
+ if value
281
+ size_to_bytes(io, 8, size_bytes)
282
+ write_double(io, value)
274
283
  else
275
- write_short(io, 8)
284
+ nil_to_bytes(io, size_bytes)
276
285
  end
277
- write_double(io, value)
278
286
  end
279
287
 
280
288
  def float_to_bytes(io, value, size_bytes)
281
- if size_bytes == 4
282
- write_int(io, 4)
289
+ if value
290
+ size_to_bytes(io, 4, size_bytes)
291
+ write_float(io, value)
283
292
  else
284
- write_short(io, 4)
293
+ nil_to_bytes(io, size_bytes)
285
294
  end
286
- write_float(io, value)
287
295
  end
288
296
 
289
297
  def inet_to_bytes(io, value, size_bytes)
290
- if size_bytes == 4
291
- write_int(io, value.ipv6? ? 16 : 4)
298
+ if value
299
+ size_to_bytes(io, value.ipv6? ? 16 : 4, size_bytes)
300
+ io << value.hton
292
301
  else
293
- write_short(io, value.ipv6? ? 16 : 4)
302
+ nil_to_bytes(io, size_bytes)
294
303
  end
295
- io << value.hton
296
304
  end
297
305
 
298
306
  def int_to_bytes(io, value, size_bytes)
299
- if size_bytes == 4
300
- write_int(io, 4)
307
+ if value
308
+ size_to_bytes(io, 4, size_bytes)
309
+ write_int(io, value)
301
310
  else
302
- write_short(io, 4)
311
+ nil_to_bytes(io, size_bytes)
303
312
  end
304
- write_int(io, value)
305
313
  end
306
314
 
307
315
  def varchar_to_bytes(io, value, size_bytes)
308
- v = value.encode(::Encoding::UTF_8)
316
+ v = value && value.encode(::Encoding::UTF_8)
309
317
  if size_bytes == 4
310
318
  write_bytes(io, v)
311
319
  else
@@ -314,32 +322,48 @@ module Cql
314
322
  end
315
323
 
316
324
  def timestamp_to_bytes(io, value, size_bytes)
317
- ms = (value.to_f * 1000).to_i
318
- if size_bytes == 4
319
- write_int(io, 8)
325
+ if value
326
+ ms = (value.to_f * 1000).to_i
327
+ size_to_bytes(io, 8, size_bytes)
328
+ write_long(io, ms)
320
329
  else
321
- write_short(io, 8)
330
+ nil_to_bytes(io, size_bytes)
322
331
  end
323
- write_long(io, ms)
324
332
  end
325
333
 
326
334
  def uuid_to_bytes(io, value, size_bytes)
327
- if size_bytes == 4
328
- write_int(io, 16)
335
+ if value
336
+ size_to_bytes(io, 16, size_bytes)
337
+ write_uuid(io, value)
329
338
  else
330
- write_short(io, 16)
339
+ nil_to_bytes(io, size_bytes)
331
340
  end
332
- write_uuid(io, value)
333
341
  end
334
342
 
335
343
  def varint_to_bytes(io, value, size_bytes)
336
- raw = write_varint('', value)
344
+ raw = value && write_varint('', value)
337
345
  if size_bytes == 4
338
346
  write_bytes(io, raw)
339
347
  else
340
348
  write_short_bytes(io, raw)
341
349
  end
342
350
  end
351
+
352
+ def size_to_bytes(io, size, size_bytes)
353
+ if size_bytes == 4
354
+ write_int(io, size)
355
+ else
356
+ write_short(io, size)
357
+ end
358
+ end
359
+
360
+ def nil_to_bytes(io, size_bytes)
361
+ if size_bytes == 4
362
+ write_int(io, -1)
363
+ else
364
+ write_short(io, -1)
365
+ end
366
+ end
343
367
  end
344
368
  end
345
369
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cql
4
- VERSION = '1.0.3'.freeze
4
+ VERSION = '1.0.4'.freeze
5
5
  end
@@ -62,6 +62,21 @@ module Cql
62
62
  Decoding.read_decimal!(buffer).should == BigDecimal.new('1042342234234.123423435647768234')
63
63
  end
64
64
 
65
+ it 'decodes a negative decimal' do
66
+ buffer = ByteBuffer.new("\x00\x00\x00\x12\xF2\xD8\x02\xB6R\x7F\x99\xEE\x98#\x99\xA9V")
67
+ Decoding.read_decimal!(buffer).should == BigDecimal.new('-1042342234234.123423435647768234')
68
+ end
69
+
70
+ it 'decodes a positive decimal with only fractions' do
71
+ buffer = ByteBuffer.new("\x00\x00\x00\x13*\xF8\xC4\xDF\xEB]o")
72
+ Decoding.read_decimal!(buffer).should == BigDecimal.new('0.0012095473475870063')
73
+ end
74
+
75
+ it 'decodes a negative decimal with only fractions' do
76
+ buffer = ByteBuffer.new("\x00\x00\x00\x13\xD5\a;\x20\x14\xA2\x91")
77
+ Decoding.read_decimal!(buffer).should == BigDecimal.new('-0.0012095473475870063')
78
+ end
79
+
65
80
  it 'consumes the bytes' do
66
81
  buffer << 'HELLO'
67
82
  Decoding.read_decimal!(buffer, buffer.length - 5)
@@ -0,0 +1,52 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require 'spec_helper'
4
+
5
+
6
+ module Cql
7
+ module Protocol
8
+ describe TypeConverter do
9
+ let :converter do
10
+ described_class.new
11
+ end
12
+
13
+ let :buffer do
14
+ ''
15
+ end
16
+
17
+ TYPES = [:ascii, :bigint, :blob, :boolean, :decimal, :double, :float, :inet, :int, :text, :varchar, :timestamp, :timeuuid, :uuid, :varint].freeze
18
+
19
+ describe '#to_bytes' do
20
+ context 'when encoding normal value' do
21
+ TYPES.each do |type|
22
+ it "encodes a null #{type.upcase}" do
23
+ converter.to_bytes(buffer, type, nil, 4).should == "\xff\xff\xff\xff"
24
+ end
25
+ end
26
+
27
+ it 'encodes a null LIST' do
28
+ converter.to_bytes(buffer, [:list, :int], nil, 4).should == "\xff\xff\xff\xff"
29
+ end
30
+
31
+ it 'encodes a null MAP' do
32
+ converter.to_bytes(buffer, [:map, :text, :text], nil, 4).should == "\xff\xff\xff\xff"
33
+
34
+ end
35
+
36
+ it 'encodes a null SET' do
37
+ converter.to_bytes(buffer, [:set, :uuid], nil, 4).should == "\xff\xff\xff\xff"
38
+
39
+ end
40
+ end
41
+
42
+ context 'when encoding collection values' do
43
+ TYPES.each do |type|
44
+ it "encodes a null #{type.upcase}" do
45
+ converter.to_bytes(buffer, type, nil, 2).should == "\xff\xff"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cql-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-04 00:00:00.000000000 Z
12
+ date: 2013-08-06 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A pure Ruby CQL3 driver for Cassandra
15
15
  email:
@@ -83,6 +83,7 @@ files:
83
83
  - spec/cql/protocol/requests/register_request_spec.rb
84
84
  - spec/cql/protocol/requests/startup_request_spec.rb
85
85
  - spec/cql/protocol/response_frame_spec.rb
86
+ - spec/cql/protocol/type_converter_spec.rb
86
87
  - spec/cql/uuid_spec.rb
87
88
  - spec/integration/client_spec.rb
88
89
  - spec/integration/protocol_spec.rb
@@ -112,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
113
  version: '0'
113
114
  segments:
114
115
  - 0
115
- hash: -3215276701075097941
116
+ hash: 16971366414174556
116
117
  requirements: []
117
118
  rubyforge_project:
118
119
  rubygems_version: 1.8.23
@@ -138,6 +139,7 @@ test_files:
138
139
  - spec/cql/protocol/requests/register_request_spec.rb
139
140
  - spec/cql/protocol/requests/startup_request_spec.rb
140
141
  - spec/cql/protocol/response_frame_spec.rb
142
+ - spec/cql/protocol/type_converter_spec.rb
141
143
  - spec/cql/uuid_spec.rb
142
144
  - spec/integration/client_spec.rb
143
145
  - spec/integration/protocol_spec.rb