cql-rb 1.0.0.pre2 → 1.0.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cql/protocol.rb CHANGED
@@ -8,6 +8,7 @@ module Cql
8
8
  DecodingError = Class.new(ProtocolError)
9
9
  EncodingError = Class.new(ProtocolError)
10
10
  InvalidStreamIdError = Class.new(ProtocolError)
11
+ InvalidValueError = Class.new(ProtocolError)
11
12
  UnsupportedOperationError = Class.new(ProtocolError)
12
13
  UnsupportedFrameTypeError = Class.new(ProtocolError)
13
14
  UnsupportedResultKindError = Class.new(ProtocolError)
@@ -15,14 +15,14 @@ module Cql
15
15
 
16
16
  def write_string(buffer, str)
17
17
  buffer << [str.bytesize].pack(Formats::SHORT_FORMAT)
18
- buffer << str
18
+ buffer << binary_cast(str)
19
19
  buffer.force_encoding(::Encoding::BINARY)
20
20
  buffer
21
21
  end
22
22
 
23
23
  def write_long_string(buffer, str)
24
24
  buffer << [str.bytesize].pack(Formats::INT_FORMAT)
25
- buffer << str
25
+ buffer << binary_cast(str)
26
26
  buffer.force_encoding(::Encoding::BINARY)
27
27
  buffer
28
28
  end
@@ -42,7 +42,7 @@ module Cql
42
42
  def write_bytes(buffer, bytes)
43
43
  if bytes
44
44
  write_int(buffer, bytes.bytesize)
45
- buffer << bytes
45
+ buffer << binary_cast(bytes)
46
46
  else
47
47
  write_int(buffer, -1)
48
48
  end
@@ -53,7 +53,7 @@ module Cql
53
53
  def write_short_bytes(buffer, bytes)
54
54
  if bytes
55
55
  write_short(buffer, bytes.bytesize)
56
- buffer << bytes
56
+ buffer << binary_cast(bytes)
57
57
  else
58
58
  write_short(buffer, -1)
59
59
  end
@@ -108,6 +108,13 @@ module Cql
108
108
  def write_float(buffer, n)
109
109
  buffer << [n].pack(Formats::FLOAT_FORMAT)
110
110
  end
111
+
112
+ private
113
+
114
+ def binary_cast(str)
115
+ return str if str.ascii_only?
116
+ str.dup.force_encoding(::Encoding::BINARY)
117
+ end
111
118
  end
112
119
  end
113
120
  end
@@ -177,48 +177,79 @@ module Cql
177
177
  private
178
178
 
179
179
  def write_value(io, value, type)
180
- case type
181
- when :ascii
182
- write_bytes(io, value.encode(::Encoding::ASCII))
183
- when :bigint
184
- write_int(io, 8)
185
- write_long(io, value)
186
- when :blob
187
- write_bytes(io, value.encode(::Encoding::BINARY))
188
- when :boolean
189
- write_int(io, 1)
190
- io << (value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
191
- when :decimal
192
- raw = write_decimal('', value)
193
- write_int(io, raw.size)
194
- io << raw
195
- when :double
196
- write_int(io, 8)
197
- write_double(io, value)
198
- when :float
199
- write_int(io, 4)
200
- write_float(io, value)
201
- when :inet
202
- write_int(io, value.ipv6? ? 16 : 4)
203
- io << value.hton
204
- when :int
205
- write_int(io, 4)
206
- write_int(io, value)
207
- when :text, :varchar
208
- write_bytes(io, value.encode(::Encoding::UTF_8))
209
- when :timestamp
210
- ms = (value.to_f * 1000).to_i
211
- write_int(io, 8)
212
- write_long(io, ms)
213
- when :timeuuid, :uuid
214
- write_int(io, 16)
215
- write_uuid(io, value)
216
- when :varint
217
- raw = write_varint('', value)
218
- write_int(io, raw.length)
219
- io << raw
180
+ if Array === type
181
+ raise InvalidValueError, 'Value for collection must be enumerable' unless value.is_a?(Enumerable)
182
+ case type.first
183
+ when :list, :set
184
+ _, sub_type = type
185
+ raw = ''
186
+ write_short(raw, value.size)
187
+ value.each do |element|
188
+ rr = ''
189
+ write_value(rr, element, sub_type)
190
+ raw << rr[2, rr.length - 2]
191
+ end
192
+ write_bytes(io, raw)
193
+ when :map
194
+ _, key_type, value_type = type
195
+ raw = ''
196
+ write_short(raw, value.size)
197
+ value.each do |key, value|
198
+ rr = ''
199
+ write_value(rr, key, key_type)
200
+ raw << rr[2, rr.length - 2]
201
+ rr = ''
202
+ write_value(rr, value, value_type)
203
+ raw << rr[2, rr.length - 2]
204
+ end
205
+ write_bytes(io, raw)
206
+ else
207
+ raise UnsupportedColumnTypeError, %(Unsupported column collection type: #{type.first})
208
+ end
220
209
  else
221
- raise UnsupportedColumnTypeError, %(Unsupported column type: #{type})
210
+ case type
211
+ when :ascii
212
+ write_bytes(io, value.encode(::Encoding::ASCII))
213
+ when :bigint
214
+ write_int(io, 8)
215
+ write_long(io, value)
216
+ when :blob
217
+ write_bytes(io, value.encode(::Encoding::BINARY))
218
+ when :boolean
219
+ write_int(io, 1)
220
+ io << (value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
221
+ when :decimal
222
+ raw = write_decimal('', value)
223
+ write_int(io, raw.size)
224
+ io << raw
225
+ when :double
226
+ write_int(io, 8)
227
+ write_double(io, value)
228
+ when :float
229
+ write_int(io, 4)
230
+ write_float(io, value)
231
+ when :inet
232
+ write_int(io, value.ipv6? ? 16 : 4)
233
+ io << value.hton
234
+ when :int
235
+ write_int(io, 4)
236
+ write_int(io, value)
237
+ when :text, :varchar
238
+ write_bytes(io, value.encode(::Encoding::UTF_8))
239
+ when :timestamp
240
+ ms = (value.to_f * 1000).to_i
241
+ write_int(io, 8)
242
+ write_long(io, ms)
243
+ when :timeuuid, :uuid
244
+ write_int(io, 16)
245
+ write_uuid(io, value)
246
+ when :varint
247
+ raw = write_varint('', value)
248
+ write_int(io, raw.length)
249
+ io << raw
250
+ else
251
+ raise UnsupportedColumnTypeError, %(Unsupported column type: #{type})
252
+ end
222
253
  end
223
254
  rescue TypeError => e
224
255
  raise TypeError, %("#{value}" cannot be encoded as #{type.to_s.upcase}: #{e.message}), e.backtrace
data/lib/cql/uuid.rb CHANGED
@@ -36,6 +36,10 @@ module Cql
36
36
  end
37
37
  end
38
38
 
39
+ def hash
40
+ @h = (@n & 0xffffffffffffffff) ^ ((@n >> 64) & 0xffffffffffffffff)
41
+ end
42
+
39
43
  # Returns the numerical representation of this UUID
40
44
  #
41
45
  # @return [Bignum] the 128 bit numerical representation
data/lib/cql/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cql
4
- VERSION = '1.0.0.pre2'.freeze
4
+ VERSION = '1.0.0.pre3'.freeze
5
5
  end
@@ -1,4 +1,4 @@
1
- # encoding: ascii-8bit
1
+ # encoding: utf-8
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -7,19 +7,20 @@ module Cql
7
7
  module Protocol
8
8
  describe Encoding do
9
9
  let :buffer do
10
- ''
10
+ ''.force_encoding(::Encoding::BINARY)
11
11
  end
12
12
 
13
13
  describe '#write_int' do
14
14
  it 'encodes an int' do
15
15
  Encoding.write_int(buffer, 2323234234)
16
- buffer.should == "\x8a\x79\xbd\xba"
16
+ buffer.should eql_bytes("\x8a\x79\xbd\xba")
17
17
  end
18
18
 
19
19
  it 'appends to the buffer' do
20
20
  buffer << "\xab"
21
+ buffer.force_encoding(::Encoding::BINARY)
21
22
  Encoding.write_int(buffer, 10)
22
- buffer.should == "\xab\x00\x00\x00\x0a"
23
+ buffer.should eql_bytes("\xab\x00\x00\x00\x0a")
23
24
  end
24
25
 
25
26
  it 'returns the buffer' do
@@ -31,13 +32,14 @@ module Cql
31
32
  describe '#write_short' do
32
33
  it 'encodes a short' do
33
34
  Encoding.write_short(buffer, 0xabcd)
34
- buffer.should == "\xab\xcd"
35
+ buffer.should eql_bytes("\xab\xcd")
35
36
  end
36
37
 
37
38
  it 'appends to the buffer' do
38
39
  buffer << "\xab"
40
+ buffer.force_encoding(::Encoding::BINARY)
39
41
  Encoding.write_short(buffer, 10)
40
- buffer.should == "\xab\x00\x0a"
42
+ buffer.should eql_bytes("\xab\x00\x0a")
41
43
  end
42
44
 
43
45
  it 'returns the buffer' do
@@ -49,30 +51,33 @@ module Cql
49
51
  describe '#write_string' do
50
52
  it 'encodes a string' do
51
53
  Encoding.write_string(buffer, 'hello')
52
- buffer.should == "\x00\x05hello"
54
+ buffer.should eql_bytes("\x00\x05hello")
53
55
  end
54
56
 
55
57
  it 'returns a binary string' do
56
- str = 'I love π'.force_encoding(::Encoding::UTF_8)
58
+ str = 'I love π'
57
59
  Encoding.write_string(buffer, str)
58
60
  buffer.encoding.should == ::Encoding::BINARY
59
61
  end
60
62
 
61
63
  it 'encodes a string with multibyte characters' do
62
- str = 'I love π'.force_encoding(::Encoding::UTF_8)
64
+ buffer << "\xff"
65
+ buffer.force_encoding(::Encoding::BINARY)
66
+ str = 'I love π'
63
67
  Encoding.write_string(buffer, str)
64
- buffer.should == "\x00\x09I love π"
68
+ buffer.should eql_bytes("\xff\x00\x09I love π")
65
69
  end
66
70
 
67
71
  it 'encodes an empty string' do
68
72
  Encoding.write_string(buffer, '')
69
- buffer.should == "\x00\x00"
73
+ buffer.should eql_bytes("\x00\x00")
70
74
  end
71
75
 
72
76
  it 'appends to the buffer' do
73
77
  buffer << "\xab"
78
+ buffer.force_encoding(::Encoding::BINARY)
74
79
  Encoding.write_string(buffer, 'foo')
75
- buffer.should == "\xab\x00\x03foo"
80
+ buffer.should eql_bytes("\xab\x00\x03foo")
76
81
  end
77
82
 
78
83
  it 'returns the buffer' do
@@ -84,30 +89,33 @@ module Cql
84
89
  describe '#write_long_string' do
85
90
  it 'encodes a string' do
86
91
  Encoding.write_long_string(buffer, 'hello world ' * 100_000)
87
- buffer.should start_with("\x00\x12\x4f\x80hello world hello world hello world hello")
92
+ buffer[0, 45].should eql_bytes("\x00\x12\x4f\x80hello world hello world hello world hello")
88
93
  end
89
94
 
90
95
  it 'returns a binary string' do
91
- str = 'I love π'.force_encoding(::Encoding::UTF_8)
96
+ str = 'I love π'
92
97
  Encoding.write_long_string(buffer, str)
93
98
  buffer.encoding.should == ::Encoding::BINARY
94
99
  end
95
100
 
96
101
  it 'encodes a string with multibyte characters' do
97
- str = 'I love π'.force_encoding(::Encoding::UTF_8)
102
+ buffer << "\xff"
103
+ buffer.force_encoding(::Encoding::BINARY)
104
+ str = 'I love π'
98
105
  Encoding.write_long_string(buffer, str)
99
- buffer.should == "\x00\x00\x00\x09I love π"
106
+ buffer.should eql_bytes("\xff\x00\x00\x00\x09I love π")
100
107
  end
101
108
 
102
109
  it 'encodes an empty string' do
103
110
  Encoding.write_long_string(buffer, '')
104
- buffer.should == "\x00\x00\x00\x00"
111
+ buffer.should eql_bytes("\x00\x00\x00\x00")
105
112
  end
106
113
 
107
114
  it 'appends to the buffer' do
108
115
  buffer << "\xab"
116
+ buffer.force_encoding(::Encoding::BINARY)
109
117
  Encoding.write_long_string(buffer, 'foo')
110
- buffer.should == "\xab\x00\x00\x00\x03foo"
118
+ buffer.should eql_bytes("\xab\x00\x00\x00\x03foo")
111
119
  end
112
120
 
113
121
  it 'returns the buffer' do
@@ -123,11 +131,12 @@ module Cql
123
131
 
124
132
  it 'encodes an UUID' do
125
133
  Encoding.write_uuid(buffer, uuid)
126
- buffer.should == "\xA4\xA7\t\x00$\xE1\x11\xDF\x89$\x00\x1F\xF3Y\x17\x11"
134
+ buffer.should eql_bytes("\xA4\xA7\t\x00$\xE1\x11\xDF\x89$\x00\x1F\xF3Y\x17\x11")
127
135
  end
128
136
 
129
137
  it 'appends to the buffer' do
130
138
  buffer << 'FOO'
139
+ buffer.force_encoding(::Encoding::BINARY)
131
140
  Encoding.write_uuid(buffer, uuid)
132
141
  buffer.should start_with('FOO')
133
142
  end
@@ -141,19 +150,21 @@ module Cql
141
150
  describe '#write_string_list' do
142
151
  it 'encodes a string list' do
143
152
  Encoding.write_string_list(buffer, %w[foo bar hello world])
144
- buffer.should == "\x00\x04\x00\x03foo\x00\x03bar\x00\x05hello\x00\x05world"
153
+ buffer.should eql_bytes("\x00\x04\x00\x03foo\x00\x03bar\x00\x05hello\x00\x05world")
145
154
  end
146
155
 
147
156
  it 'returns a binary string' do
148
- str = %w[I love π].map { |str| str.force_encoding(::Encoding::UTF_8) }
157
+ str = %w[I love π]
149
158
  Encoding.write_string_list(buffer, str)
150
159
  buffer.encoding.should == ::Encoding::BINARY
151
160
  end
152
161
 
153
162
  it 'encodes a string with multibyte characters' do
154
- str = %w[I love π].map { |str| str.force_encoding(::Encoding::UTF_8) }
163
+ buffer << "\xff"
164
+ buffer.force_encoding(::Encoding::BINARY)
165
+ str = %w[I love π]
155
166
  Encoding.write_string_list(buffer, str)
156
- buffer.should == "\x00\x03\x00\x01I\x00\x04love\x00\x02π"
167
+ buffer.should eql_bytes("\xff\x00\x03\x00\x01I\x00\x04love\x00\x02π")
157
168
  end
158
169
 
159
170
  it 'encodes an empty string list' do
@@ -163,8 +174,9 @@ module Cql
163
174
 
164
175
  it 'appends to the buffer' do
165
176
  buffer << "\xab"
177
+ buffer.force_encoding(::Encoding::BINARY)
166
178
  Encoding.write_string_list(buffer, %w[foo bar])
167
- buffer.should == "\xab\x00\x02\x00\x03foo\x00\x03bar"
179
+ buffer.should eql_bytes("\xab\x00\x02\x00\x03foo\x00\x03bar")
168
180
  end
169
181
 
170
182
  it 'returns the buffer' do
@@ -176,30 +188,33 @@ module Cql
176
188
  describe '#write_bytes' do
177
189
  it 'encodes a byte array' do
178
190
  Encoding.write_bytes(buffer, "\xaa" * 2000)
179
- buffer.should == ("\x00\x00\x07\xd0" << ("\xaa" * 2000))
191
+ buffer.should eql_bytes("\x00\x00\x07\xd0" << ("\xaa" * 2000))
180
192
  end
181
193
 
182
194
  it 'returns a binary string' do
183
- str = 'I love π'.force_encoding(::Encoding::UTF_8)
195
+ str = 'I love π'
184
196
  Encoding.write_bytes(buffer, str)
185
197
  buffer.encoding.should == ::Encoding::BINARY
186
198
  end
187
199
 
188
200
  it 'encodes a string with multibyte characters' do
189
- str = 'I love π'.force_encoding(::Encoding::UTF_8)
201
+ buffer << "\xff"
202
+ buffer.force_encoding(::Encoding::BINARY)
203
+ str = 'I love π'
190
204
  Encoding.write_bytes(buffer, str)
191
- buffer.should == "\x00\x00\x00\x09I love π"
205
+ buffer.should eql_bytes("\xff\x00\x00\x00\x09I love π")
192
206
  end
193
207
 
194
208
  it 'encodes nil' do
195
209
  Encoding.write_bytes(buffer, nil)
196
- buffer.should == "\xff\xff\xff\xff"
210
+ buffer.should eql_bytes("\xff\xff\xff\xff")
197
211
  end
198
212
 
199
213
  it 'appends to the buffer' do
200
214
  buffer << "\xab"
215
+ buffer.force_encoding(::Encoding::BINARY)
201
216
  Encoding.write_bytes(buffer, "\xf0\x0b\xbar")
202
- buffer.should == "\xab\x00\x00\x00\x04\xf0\x0b\xbar"
217
+ buffer.should eql_bytes("\xab\x00\x00\x00\x04\xf0\x0b\xbar")
203
218
  end
204
219
 
205
220
  it 'returns the buffer' do
@@ -211,30 +226,33 @@ module Cql
211
226
  describe '#write_short_bytes' do
212
227
  it 'encodes a byte array' do
213
228
  Encoding.write_short_bytes(buffer, "\xaa\xbb\xcc")
214
- buffer.should == "\x00\x03\xaa\xbb\xcc"
229
+ buffer.should eql_bytes("\x00\x03\xaa\xbb\xcc")
215
230
  end
216
231
 
217
232
  it 'returns a binary string' do
218
- str = 'I love π'.force_encoding(::Encoding::UTF_8)
233
+ str = 'I love π'
219
234
  Encoding.write_short_bytes(buffer, str)
220
235
  buffer.encoding.should == ::Encoding::BINARY
221
236
  end
222
237
 
223
238
  it 'encodes a string with multibyte characters' do
224
- str = 'I love π'.force_encoding(::Encoding::UTF_8)
239
+ buffer << "\xff"
240
+ buffer.force_encoding(::Encoding::BINARY)
241
+ str = 'I love π'
225
242
  Encoding.write_short_bytes(buffer, str)
226
- buffer.should == "\x00\x09I love π"
243
+ buffer.should eql_bytes("\xff\x00\x09I love π")
227
244
  end
228
245
 
229
246
  it 'encodes nil' do
230
247
  Encoding.write_short_bytes(buffer, nil)
231
- buffer.should == "\xff\xff"
248
+ buffer.should eql_bytes("\xff\xff")
232
249
  end
233
250
 
234
251
  it 'appends to the buffer' do
235
252
  buffer << "\xab"
253
+ buffer.force_encoding(::Encoding::BINARY)
236
254
  Encoding.write_short_bytes(buffer, "\xf0\x0b\xbar")
237
- buffer.should == "\xab\x00\x04\xf0\x0b\xbar"
255
+ buffer.should eql_bytes("\xab\x00\x04\xf0\x0b\xbar")
238
256
  end
239
257
 
240
258
  it 'returns the buffer' do
@@ -266,8 +284,9 @@ module Cql
266
284
 
267
285
  it 'appends to the buffer' do
268
286
  buffer << "\xab"
287
+ buffer.force_encoding(::Encoding::BINARY)
269
288
  Encoding.write_consistency(buffer, :one)
270
- buffer.should == "\xab\x00\x01"
289
+ buffer.should eql_bytes("\xab\x00\x01")
271
290
  end
272
291
 
273
292
  it 'returns the buffer' do
@@ -279,18 +298,19 @@ module Cql
279
298
  describe '#write_string_map' do
280
299
  it 'encodes a string map' do
281
300
  Encoding.write_string_map(buffer, 'HELLO' => 'world', 'foo' => 'bar')
282
- buffer.should == "\x00\x02\x00\x05HELLO\x00\x05world\x00\x03foo\x00\x03bar"
301
+ buffer.should eql_bytes("\x00\x02\x00\x05HELLO\x00\x05world\x00\x03foo\x00\x03bar")
283
302
  end
284
303
 
285
304
  it 'encodes an empty map' do
286
305
  Encoding.write_string_map(buffer, {})
287
- buffer.should == "\x00\x00"
306
+ buffer.should eql_bytes("\x00\x00")
288
307
  end
289
308
 
290
309
  it 'appends to the buffer' do
291
310
  buffer << "\xab"
311
+ buffer.force_encoding(::Encoding::BINARY)
292
312
  Encoding.write_string_map(buffer, 'foo' => 'bar')
293
- buffer.should == "\xab\x00\x01\x00\x03foo\x00\x03bar"
313
+ buffer.should eql_bytes("\xab\x00\x01\x00\x03foo\x00\x03bar")
294
314
  end
295
315
 
296
316
  it 'returns the buffer' do
@@ -302,13 +322,14 @@ module Cql
302
322
  describe '#write_long' do
303
323
  it 'encodes a long' do
304
324
  Encoding.write_long(buffer, 0x0123456789)
305
- buffer.should == "\x00\x00\x00\x01\x23\x45\x67\x89"
325
+ buffer.should eql_bytes("\x00\x00\x00\x01\x23\x45\x67\x89")
306
326
  end
307
327
 
308
328
  it 'appends to the buffer' do
309
329
  buffer << "\x99"
330
+ buffer.force_encoding(::Encoding::BINARY)
310
331
  Encoding.write_long(buffer, 0x0123456789)
311
- buffer.should == "\x99\x00\x00\x00\x01\x23\x45\x67\x89"
332
+ buffer.should eql_bytes("\x99\x00\x00\x00\x01\x23\x45\x67\x89")
312
333
  end
313
334
 
314
335
  it 'returns the buffer' do
@@ -320,18 +341,19 @@ module Cql
320
341
  describe '#write_varint' do
321
342
  it 'encodes a variable length integer' do
322
343
  Encoding.write_varint(buffer, 1231312312331283012830129382342342412123)
323
- buffer.should == "\x03\x9EV \x15\f\x03\x9DK\x18\xCDI\\$?\a["
344
+ buffer.should eql_bytes("\x03\x9EV \x15\f\x03\x9DK\x18\xCDI\\$?\a[")
324
345
  end
325
346
 
326
347
  it 'encodes a negative variable length integer' do
327
348
  Encoding.write_varint(buffer, -234234234234)
328
- buffer.should == "\xC9v\x8D:\x86"
349
+ buffer.should eql_bytes("\xC9v\x8D:\x86")
329
350
  end
330
351
 
331
352
  it 'appends to the buffer' do
332
353
  buffer << "\x99"
354
+ buffer.force_encoding(::Encoding::BINARY)
333
355
  Encoding.write_varint(buffer, -234234234234)
334
- buffer.should == "\x99\xC9v\x8D:\x86"
356
+ buffer.should eql_bytes("\x99\xC9v\x8D:\x86")
335
357
  end
336
358
 
337
359
  it 'returns the buffer' do
@@ -343,13 +365,14 @@ module Cql
343
365
  describe '#write_decimal' do
344
366
  it 'encodes a BigDecimal as a decimal' do
345
367
  Encoding.write_decimal(buffer, BigDecimal.new('1042342234234.123423435647768234'))
346
- buffer.should == "\x00\x00\x00\x12\r'\xFDI\xAD\x80f\x11g\xDCfV\xAA"
368
+ buffer.should eql_bytes("\x00\x00\x00\x12\r'\xFDI\xAD\x80f\x11g\xDCfV\xAA")
347
369
  end
348
370
 
349
371
  it 'appends to the buffer' do
350
372
  buffer << "\x99"
373
+ buffer.force_encoding(::Encoding::BINARY)
351
374
  Encoding.write_decimal(buffer, BigDecimal.new('1042342234234.123423435647768234'))
352
- buffer.should start_with("\x99")
375
+ buffer[0].should eql_bytes("\x99")
353
376
  end
354
377
 
355
378
  it 'returns the buffer' do
@@ -361,11 +384,12 @@ module Cql
361
384
  describe '#write_double' do
362
385
  it 'encodes a double' do
363
386
  Encoding.write_double(buffer, 10000.123123123)
364
- buffer.should == "@\xC3\x88\x0F\xC2\x7F\x9DU"
387
+ buffer.should eql_bytes("@\xC3\x88\x0F\xC2\x7F\x9DU")
365
388
  end
366
389
 
367
390
  it 'appends to the buffer' do
368
391
  buffer << 'BEFORE'
392
+ buffer.force_encoding(::Encoding::BINARY)
369
393
  Encoding.write_double(buffer, 10000.123123123)
370
394
  buffer.should start_with('BEFORE')
371
395
  end
@@ -379,7 +403,7 @@ module Cql
379
403
  describe '#write_float' do
380
404
  it 'encodes a float' do
381
405
  Encoding.write_float(buffer, 12.13)
382
- buffer.should == "AB\x14{"
406
+ buffer.should eql_bytes("AB\x14{")
383
407
  end
384
408
 
385
409
  it 'appends to the buffer' do
@@ -78,7 +78,15 @@ module Cql
78
78
  [:uuid, Uuid.new('cfd66ccc-d857-4e90-b1e5-df98a3d40cd6'), "\xCF\xD6l\xCC\xD8WN\x90\xB1\xE5\xDF\x98\xA3\xD4\f\xD6"],
79
79
  [:varchar, 'hello', 'hello'],
80
80
  [:varint, 1231312312331283012830129382342342412123, "\x03\x9EV \x15\f\x03\x9DK\x18\xCDI\\$?\a["],
81
- [:varint, -234234234234, "\xC9v\x8D:\x86"]
81
+ [:varint, -234234234234, "\xC9v\x8D:\x86"],
82
+ [[:list, :timestamp], [Time.at(1358013521.123)], "\x00\x01" + "\x00\x08\x00\x00\x01</\xE9\xDC\xE3"],
83
+ [[:list, :boolean], [true, false, true, true], "\x00\x04" + "\x00\x01\x01" + "\x00\x01\x00" + "\x00\x01\x01" + "\x00\x01\x01"],
84
+ [[:map, :uuid, :int], {Uuid.new('cfd66ccc-d857-4e90-b1e5-df98a3d40cd6') => 45345, Uuid.new('a4a70900-24e1-11df-8924-001ff3591711') => 98765}, "\x00\x02" + "\x00\x10\xCF\xD6l\xCC\xD8WN\x90\xB1\xE5\xDF\x98\xA3\xD4\f\xD6" + "\x00\x04\x00\x00\xb1\x21" + "\x00\x10\xA4\xA7\t\x00$\xE1\x11\xDF\x89$\x00\x1F\xF3Y\x17\x11" + "\x00\x04\x00\x01\x81\xcd"],
85
+ [[:map, :ascii, :blob], {'hello' => 'world', 'one' => "\x01", 'two' => "\x02"}, "\x00\x03" + "\x00\x05hello" + "\x00\x05world" + "\x00\x03one" + "\x00\x01\x01" + "\x00\x03two" + "\x00\x01\x02"],
86
+ [[:set, :int], Set.new([13, 3453, 456456, 123, 768678]), "\x00\x05" + "\x00\x04\x00\x00\x00\x0d" + "\x00\x04\x00\x00\x0d\x7d" + "\x00\x04\x00\x06\xf7\x08" + "\x00\x04\x00\x00\x00\x7b" + "\x00\x04\x00\x0b\xba\xa6"],
87
+ [[:set, :varchar], Set.new(['foo', 'bar', 'baz']), "\x00\x03" + "\x00\x03foo" + "\x00\x03bar" + "\x00\x03baz"],
88
+ [[:set, :int], [13, 3453, 456456, 123, 768678], "\x00\x05" + "\x00\x04\x00\x00\x00\x0d" + "\x00\x04\x00\x00\x0d\x7d" + "\x00\x04\x00\x06\xf7\x08" + "\x00\x04\x00\x00\x00\x7b" + "\x00\x04\x00\x0b\xba\xa6"],
89
+ [[:set, :varchar], ['foo', 'bar', 'baz'], "\x00\x03" + "\x00\x03foo" + "\x00\x03bar" + "\x00\x03baz"]
82
90
  ]
83
91
  specs.each do |type, value, expected_bytes|
84
92
  it "encodes #{type} values" do
@@ -100,6 +108,16 @@ module Cql
100
108
  expect { RequestFrame.new(ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], :each_quorum)).write('') }.to raise_error(UnsupportedColumnTypeError)
101
109
  end
102
110
 
111
+ it 'raises an error for unsupported column collection types' do
112
+ column_metadata[2][3] = [:imaginary, :varchar]
113
+ expect { RequestFrame.new(ExecuteRequest.new(id, column_metadata, ['hello', 42, ['foo']], :each_quorum)).write('') }.to raise_error(UnsupportedColumnTypeError)
114
+ end
115
+
116
+ it 'raises an error when collection values are not enumerable' do
117
+ column_metadata[2][3] = [:set, :varchar]
118
+ expect { RequestFrame.new(ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], :each_quorum)).write('') }.to raise_error(InvalidValueError)
119
+ end
120
+
103
121
  it 'raises an error when it cannot encode the argument' do
104
122
  expect { ExecuteRequest.new(id, column_metadata, ['hello', 'not an int', 'foo'], :each_quorum).write('') }.to raise_error(TypeError, /cannot be encoded as INT/)
105
123
  end
@@ -47,6 +47,26 @@ module Cql
47
47
  end
48
48
  end
49
49
 
50
+ describe '#hash' do
51
+ it 'calculates a 64 bit hash of the UUID' do
52
+ h = Uuid.new(276263553384940695775376958868900023510).hash
53
+ h.should be < 2**63
54
+ h.should be > -2**63
55
+ end
56
+
57
+ it 'has the same hash code when #eql?' do
58
+ uuid1 = Uuid.new('a4a70900-24e1-11df-8924-001ff3591711')
59
+ uuid2 = Uuid.new('a4a70900-24e1-11df-8924-001ff3591711')
60
+ uuid1.hash.should == uuid2.hash
61
+ end
62
+
63
+ it 'has a different hash when not #eql?' do
64
+ uuid1 = Uuid.new('a4a70900-24e1-11df-8924-001ff3591711')
65
+ uuid2 = Uuid.new('b4a70900-24e1-11df-8924-001ff3591711')
66
+ uuid1.hash.should_not == uuid2.hash
67
+ end
68
+ end
69
+
50
70
  describe '#value' do
51
71
  it 'returns the numeric value' do
52
72
  Uuid.new('cfd66ccc-d857-4e90-b1e5-df98a3d40cd6').value.should == 276263553384940695775376958868900023510
data/spec/spec_helper.rb CHANGED
@@ -7,6 +7,7 @@ require 'cql'
7
7
  ENV['CASSANDRA_HOST'] ||= 'localhost'
8
8
 
9
9
 
10
+ require 'support/bytes_helper'
10
11
  require 'support/await_helper'
11
12
  require 'support/fake_server'
12
13
  require 'support/fake_io_reactor'
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec::Matchers.define :eql_bytes do |expected|
4
+ match do |actual|
5
+ actual.unpack('c*') == expected.unpack('c*')
6
+ end
7
+ 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.0.pre2
4
+ version: 1.0.0.pre3
5
5
  prerelease: 6
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-03-08 00:00:00.000000000 Z
12
+ date: 2013-03-18 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A pure Ruby CQL3 driver for Cassandra
15
15
  email:
@@ -44,6 +44,7 @@ files:
44
44
  - spec/integration/protocol_spec.rb
45
45
  - spec/spec_helper.rb
46
46
  - spec/support/await_helper.rb
47
+ - spec/support/bytes_helper.rb
47
48
  - spec/support/fake_io_reactor.rb
48
49
  - spec/support/fake_server.rb
49
50
  homepage: http://github.com/iconara/cql-rb
@@ -84,6 +85,7 @@ test_files:
84
85
  - spec/integration/protocol_spec.rb
85
86
  - spec/spec_helper.rb
86
87
  - spec/support/await_helper.rb
88
+ - spec/support/bytes_helper.rb
87
89
  - spec/support/fake_io_reactor.rb
88
90
  - spec/support/fake_server.rb
89
91
  has_rdoc: