cql-rb 1.0.3 → 1.0.4

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.
@@ -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