cql-rb 1.0.0.pre1 → 1.0.0.pre2
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.
- data/README.md +1 -0
- data/lib/cql/client.rb +27 -13
- data/lib/cql/protocol/decoding.rb +13 -13
- data/lib/cql/protocol/encoding.rb +8 -4
- data/lib/cql/version.rb +1 -1
- data/spec/cql/client_spec.rb +19 -6
- data/spec/cql/io/io_reactor_spec.rb +2 -2
- data/spec/cql/protocol/encoding_spec.rb +60 -0
- data/spec/integration/client_spec.rb +2 -0
- metadata +2 -2
data/README.md
CHANGED
data/lib/cql/client.rb
CHANGED
|
@@ -84,9 +84,6 @@ module Cql
|
|
|
84
84
|
def start!
|
|
85
85
|
@lock.synchronize do
|
|
86
86
|
return if @started
|
|
87
|
-
@started = true
|
|
88
|
-
end
|
|
89
|
-
begin
|
|
90
87
|
@io_reactor.start
|
|
91
88
|
hosts = @host.split(',')
|
|
92
89
|
start_request = Protocol::StartupRequest.new
|
|
@@ -96,11 +93,9 @@ module Cql
|
|
|
96
93
|
end
|
|
97
94
|
end
|
|
98
95
|
@connection_ids = Future.combine(*connection_futures).get
|
|
99
|
-
|
|
100
|
-
rescue
|
|
101
|
-
@started = false
|
|
102
|
-
raise
|
|
96
|
+
@started = true
|
|
103
97
|
end
|
|
98
|
+
use(@initial_keyspace) if @initial_keyspace
|
|
104
99
|
self
|
|
105
100
|
end
|
|
106
101
|
|
|
@@ -110,7 +105,7 @@ module Cql
|
|
|
110
105
|
#
|
|
111
106
|
def shutdown!
|
|
112
107
|
@lock.synchronize do
|
|
113
|
-
return if @shut_down
|
|
108
|
+
return if @shut_down || !@started
|
|
114
109
|
@shut_down = true
|
|
115
110
|
@started = false
|
|
116
111
|
end
|
|
@@ -140,7 +135,7 @@ module Cql
|
|
|
140
135
|
# @raise [Cql::NotConnectedError] raised when the client is not connected
|
|
141
136
|
#
|
|
142
137
|
def use(keyspace, connection_ids=@connection_ids)
|
|
143
|
-
raise NotConnectedError unless
|
|
138
|
+
raise NotConnectedError unless connected?
|
|
144
139
|
if check_keyspace_name!(keyspace)
|
|
145
140
|
@lock.synchronize do
|
|
146
141
|
connection_ids = connection_ids.select { |id| @connection_keyspaces[id] != keyspace }
|
|
@@ -165,7 +160,8 @@ module Cql
|
|
|
165
160
|
# `nil`, but `SELECT` statements return an `Enumerable` of rows
|
|
166
161
|
# (see {QueryResult}).
|
|
167
162
|
#
|
|
168
|
-
def execute(cql, consistency
|
|
163
|
+
def execute(cql, consistency=DEFAULT_CONSISTENCY_LEVEL)
|
|
164
|
+
raise NotConnectedError unless connected?
|
|
169
165
|
result = execute_request(Protocol::QueryRequest.new(cql, consistency)).value
|
|
170
166
|
ensure_keyspace!
|
|
171
167
|
result
|
|
@@ -173,7 +169,8 @@ module Cql
|
|
|
173
169
|
|
|
174
170
|
# @private
|
|
175
171
|
def execute_statement(connection_id, statement_id, metadata, values, consistency)
|
|
176
|
-
|
|
172
|
+
raise NotConnectedError unless connected?
|
|
173
|
+
execute_request(Protocol::ExecuteRequest.new(statement_id, metadata, values, consistency || DEFAULT_CONSISTENCY_LEVEL), connection_id).value
|
|
177
174
|
end
|
|
178
175
|
|
|
179
176
|
# Returns a prepared statement that can be run over and over again with
|
|
@@ -183,12 +180,14 @@ module Cql
|
|
|
183
180
|
# @return [Cql::PreparedStatement] an object encapsulating the prepared statement
|
|
184
181
|
#
|
|
185
182
|
def prepare(cql)
|
|
183
|
+
raise NotConnectedError unless connected?
|
|
186
184
|
execute_request(Protocol::PrepareRequest.new(cql)).value
|
|
187
185
|
end
|
|
188
186
|
|
|
189
187
|
private
|
|
190
188
|
|
|
191
189
|
KEYSPACE_NAME_PATTERN = /^\w[\w\d_]*$/
|
|
190
|
+
DEFAULT_CONSISTENCY_LEVEL = :quorum
|
|
192
191
|
|
|
193
192
|
def check_keyspace_name!(name)
|
|
194
193
|
if name !~ KEYSPACE_NAME_PATTERN
|
|
@@ -198,7 +197,6 @@ module Cql
|
|
|
198
197
|
end
|
|
199
198
|
|
|
200
199
|
def execute_request(request, connection_id=nil)
|
|
201
|
-
raise NotConnectedError unless @started
|
|
202
200
|
@io_reactor.queue_request(request, connection_id).map do |response, connection_id|
|
|
203
201
|
interpret_response!(response, connection_id)
|
|
204
202
|
end
|
|
@@ -233,6 +231,11 @@ module Cql
|
|
|
233
231
|
|
|
234
232
|
public
|
|
235
233
|
|
|
234
|
+
# The representation of a prepared statement.
|
|
235
|
+
#
|
|
236
|
+
# Prepared statements are parsed once and stored on the server, allowing
|
|
237
|
+
# you to execute them over and over again but only send values for the bound
|
|
238
|
+
# parameters.
|
|
236
239
|
#
|
|
237
240
|
class PreparedStatement
|
|
238
241
|
# @return [ResultMetadata]
|
|
@@ -245,8 +248,19 @@ module Cql
|
|
|
245
248
|
|
|
246
249
|
# Execute the prepared statement with a list of values for the bound parameters.
|
|
247
250
|
#
|
|
251
|
+
# The number of arguments must equal the number of bound parameters.
|
|
252
|
+
# To set the consistency level for the request you pass a consistency
|
|
253
|
+
# level (as a symbol) as the last argument. Needless to say, if you pass
|
|
254
|
+
# the value for one bound parameter too few, and then a consistency level,
|
|
255
|
+
# or if you pass too many values, you will get weird errors.
|
|
256
|
+
#
|
|
257
|
+
# @param args [Array] the values for the bound parameters, and optionally
|
|
258
|
+
# the desired consistency level, as a symbol (defaults to :quorum)
|
|
259
|
+
#
|
|
248
260
|
def execute(*args)
|
|
249
|
-
|
|
261
|
+
bound_args = args.shift(@raw_metadata.size)
|
|
262
|
+
consistency_level = args.shift
|
|
263
|
+
@client.execute_statement(@connection_id, @statement_id, @raw_metadata, bound_args, consistency_level)
|
|
250
264
|
end
|
|
251
265
|
end
|
|
252
266
|
|
|
@@ -12,7 +12,7 @@ module Cql
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def read_varint!(buffer, length=buffer.length, signed=true)
|
|
15
|
-
raise DecodingError, "Length #{length} specifed but only #{buffer.
|
|
15
|
+
raise DecodingError, "Length #{length} specifed but only #{buffer.bytesize} bytes given" if buffer.bytesize < length
|
|
16
16
|
bytes = buffer.slice!(0, length)
|
|
17
17
|
n = 0
|
|
18
18
|
bytes.each_byte do |b|
|
|
@@ -25,7 +25,7 @@ module Cql
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def read_decimal!(buffer, length=buffer.length)
|
|
28
|
-
raise DecodingError, "Length #{length} specifed but only #{buffer.
|
|
28
|
+
raise DecodingError, "Length #{length} specifed but only #{buffer.bytesize} bytes given" if buffer.bytesize < length
|
|
29
29
|
size = read_int!(buffer)
|
|
30
30
|
number_bytes = buffer.slice!(0, length - 4)
|
|
31
31
|
number_string = read_varint!(number_bytes).to_s
|
|
@@ -34,34 +34,34 @@ module Cql
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def read_long!(buffer)
|
|
37
|
-
raise DecodingError, "Need eight bytes to decode long, only #{buffer.
|
|
37
|
+
raise DecodingError, "Need eight bytes to decode long, only #{buffer.bytesize} bytes given" if buffer.bytesize < 8
|
|
38
38
|
top, bottom = buffer.slice!(0, 8).unpack(Formats::TWO_INTS_FORMAT)
|
|
39
39
|
(top << 32) | bottom
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def read_double!(buffer)
|
|
43
|
-
raise DecodingError, "Need eight bytes to decode double, only #{buffer.
|
|
43
|
+
raise DecodingError, "Need eight bytes to decode double, only #{buffer.bytesize} bytes given" if buffer.bytesize < 8
|
|
44
44
|
buffer.slice!(0, 8).unpack(Formats::DOUBLE_FORMAT).first
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def read_float!(buffer)
|
|
48
|
-
raise DecodingError, "Need four bytes to decode float, only #{buffer.
|
|
48
|
+
raise DecodingError, "Need four bytes to decode float, only #{buffer.bytesize} bytes given" if buffer.bytesize < 4
|
|
49
49
|
buffer.slice!(0, 4).unpack(Formats::FLOAT_FORMAT).first
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def read_int!(buffer)
|
|
53
|
-
raise DecodingError, "Need four bytes to decode an int, only #{buffer.
|
|
53
|
+
raise DecodingError, "Need four bytes to decode an int, only #{buffer.bytesize} bytes given" if buffer.bytesize < 4
|
|
54
54
|
buffer.slice!(0, 4).unpack(Formats::INT_FORMAT).first
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def read_short!(buffer)
|
|
58
|
-
raise DecodingError, "Need two bytes to decode a short, only #{buffer.
|
|
58
|
+
raise DecodingError, "Need two bytes to decode a short, only #{buffer.bytesize} bytes given" if buffer.bytesize < 2
|
|
59
59
|
buffer.slice!(0, 2).unpack(Formats::SHORT_FORMAT).first
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def read_string!(buffer)
|
|
63
63
|
length = read_short!(buffer)
|
|
64
|
-
raise DecodingError, "String length is #{length}, but only #{buffer.
|
|
64
|
+
raise DecodingError, "String length is #{length}, but only #{buffer.bytesize} bytes given" if buffer.bytesize < length
|
|
65
65
|
string = buffer.slice!(0, length)
|
|
66
66
|
string.force_encoding(::Encoding::UTF_8)
|
|
67
67
|
string
|
|
@@ -69,14 +69,14 @@ module Cql
|
|
|
69
69
|
|
|
70
70
|
def read_long_string!(buffer)
|
|
71
71
|
length = read_int!(buffer)
|
|
72
|
-
raise DecodingError, "String length is #{length}, but only #{buffer.
|
|
72
|
+
raise DecodingError, "String length is #{length}, but only #{buffer.bytesize} bytes given" if buffer.bytesize < length
|
|
73
73
|
string = buffer.slice!(0, length)
|
|
74
74
|
string.force_encoding(::Encoding::UTF_8)
|
|
75
75
|
string
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def read_uuid!(buffer)
|
|
79
|
-
raise DecodingError, "UUID requires 16 bytes, but only #{buffer.
|
|
79
|
+
raise DecodingError, "UUID requires 16 bytes, but only #{buffer.bytesize} bytes given" if buffer.bytesize < 16
|
|
80
80
|
Uuid.new(read_varint!(buffer, 16, false))
|
|
81
81
|
end
|
|
82
82
|
|
|
@@ -90,7 +90,7 @@ module Cql
|
|
|
90
90
|
def read_bytes!(buffer)
|
|
91
91
|
size = read_int!(buffer)
|
|
92
92
|
return nil if size & 0x80000000 == 0x80000000
|
|
93
|
-
raise DecodingError, "Byte array length is #{size}, but only #{buffer.
|
|
93
|
+
raise DecodingError, "Byte array length is #{size}, but only #{buffer.bytesize} bytes given" if buffer.bytesize < size
|
|
94
94
|
bytes = buffer.slice!(0, size)
|
|
95
95
|
bytes.force_encoding(::Encoding::BINARY)
|
|
96
96
|
bytes
|
|
@@ -99,7 +99,7 @@ module Cql
|
|
|
99
99
|
def read_short_bytes!(buffer)
|
|
100
100
|
size = read_short!(buffer)
|
|
101
101
|
return nil if size & 0x8000 == 0x8000
|
|
102
|
-
raise DecodingError, "Byte array length is #{size}, but only #{buffer.
|
|
102
|
+
raise DecodingError, "Byte array length is #{size}, but only #{buffer.bytesize} bytes given" if buffer.bytesize < size
|
|
103
103
|
bytes = buffer.slice!(0, size)
|
|
104
104
|
bytes.force_encoding(::Encoding::BINARY)
|
|
105
105
|
bytes
|
|
@@ -116,7 +116,7 @@ module Cql
|
|
|
116
116
|
|
|
117
117
|
def read_inet!(buffer)
|
|
118
118
|
size = read_byte!(buffer)
|
|
119
|
-
raise DecodingError, "Inet requires #{size} bytes, but only #{buffer.
|
|
119
|
+
raise DecodingError, "Inet requires #{size} bytes, but only #{buffer.bytesize} bytes given" if buffer.bytesize < size
|
|
120
120
|
ip_addr = IPAddr.new_ntoh(buffer.slice!(0, size))
|
|
121
121
|
port = read_int!(buffer)
|
|
122
122
|
[ip_addr, port]
|
|
@@ -14,14 +14,16 @@ module Cql
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def write_string(buffer, str)
|
|
17
|
-
buffer << [str.
|
|
17
|
+
buffer << [str.bytesize].pack(Formats::SHORT_FORMAT)
|
|
18
18
|
buffer << str
|
|
19
|
+
buffer.force_encoding(::Encoding::BINARY)
|
|
19
20
|
buffer
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def write_long_string(buffer, str)
|
|
23
|
-
buffer << [str.
|
|
24
|
+
buffer << [str.bytesize].pack(Formats::INT_FORMAT)
|
|
24
25
|
buffer << str
|
|
26
|
+
buffer.force_encoding(::Encoding::BINARY)
|
|
25
27
|
buffer
|
|
26
28
|
end
|
|
27
29
|
|
|
@@ -39,21 +41,23 @@ module Cql
|
|
|
39
41
|
|
|
40
42
|
def write_bytes(buffer, bytes)
|
|
41
43
|
if bytes
|
|
42
|
-
write_int(buffer, bytes.
|
|
44
|
+
write_int(buffer, bytes.bytesize)
|
|
43
45
|
buffer << bytes
|
|
44
46
|
else
|
|
45
47
|
write_int(buffer, -1)
|
|
46
48
|
end
|
|
49
|
+
buffer.force_encoding(::Encoding::BINARY)
|
|
47
50
|
buffer
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def write_short_bytes(buffer, bytes)
|
|
51
54
|
if bytes
|
|
52
|
-
write_short(buffer, bytes.
|
|
55
|
+
write_short(buffer, bytes.bytesize)
|
|
53
56
|
buffer << bytes
|
|
54
57
|
else
|
|
55
58
|
write_short(buffer, -1)
|
|
56
59
|
end
|
|
60
|
+
buffer.force_encoding(::Encoding::BINARY)
|
|
57
61
|
buffer
|
|
58
62
|
end
|
|
59
63
|
|
data/lib/cql/version.rb
CHANGED
data/spec/cql/client_spec.rb
CHANGED
|
@@ -123,6 +123,10 @@ module Cql
|
|
|
123
123
|
io_reactor.should_not be_running
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
+
it 'does nothing when called before #start!' do
|
|
127
|
+
client.shutdown!
|
|
128
|
+
end
|
|
129
|
+
|
|
126
130
|
it 'accepts multiple calls to #shutdown!' do
|
|
127
131
|
client.start!
|
|
128
132
|
client.shutdown!
|
|
@@ -286,6 +290,14 @@ module Cql
|
|
|
286
290
|
end
|
|
287
291
|
|
|
288
292
|
describe '#prepare' do
|
|
293
|
+
let :id do
|
|
294
|
+
'A' * 32
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
let :metadata do
|
|
298
|
+
[['stuff', 'things', 'item', :varchar]]
|
|
299
|
+
end
|
|
300
|
+
|
|
289
301
|
before do
|
|
290
302
|
client.start!
|
|
291
303
|
end
|
|
@@ -302,8 +314,6 @@ module Cql
|
|
|
302
314
|
end
|
|
303
315
|
|
|
304
316
|
it 'executes a prepared statement' do
|
|
305
|
-
id = 'A' * 32
|
|
306
|
-
metadata = [['stuff', 'things', 'item', :varchar]]
|
|
307
317
|
io_reactor.queue_response(Protocol::PreparedResultResponse.new(id, metadata))
|
|
308
318
|
statement = client.prepare('SELECT * FROM stuff.things WHERE item = ?')
|
|
309
319
|
statement.execute('foo')
|
|
@@ -311,20 +321,23 @@ module Cql
|
|
|
311
321
|
end
|
|
312
322
|
|
|
313
323
|
it 'returns a prepared statement that knows the metadata' do
|
|
314
|
-
id = 'A' * 32
|
|
315
|
-
metadata = [['stuff', 'things', 'item', :varchar]]
|
|
316
324
|
io_reactor.queue_response(Protocol::PreparedResultResponse.new(id, metadata))
|
|
317
325
|
statement = client.prepare('SELECT * FROM stuff.things WHERE item = ?')
|
|
318
326
|
statement.metadata['item'].type == :varchar
|
|
319
327
|
end
|
|
320
328
|
|
|
329
|
+
it 'executes a prepared statement with a specific consistency level' do
|
|
330
|
+
io_reactor.queue_response(Protocol::PreparedResultResponse.new(id, metadata))
|
|
331
|
+
statement = client.prepare('SELECT * FROM stuff.things WHERE item = ?')
|
|
332
|
+
statement.execute('thing', :local_quorum)
|
|
333
|
+
last_request.should == Protocol::ExecuteRequest.new(id, metadata, ['thing'], :local_quorum)
|
|
334
|
+
end
|
|
335
|
+
|
|
321
336
|
it 'executes a prepared statement using the right connection' do
|
|
322
337
|
client.shutdown!
|
|
323
338
|
io_reactor.stop.get
|
|
324
339
|
io_reactor.start.get
|
|
325
340
|
|
|
326
|
-
metadata = [['stuff', 'things', 'item', :varchar]]
|
|
327
|
-
|
|
328
341
|
c = described_class.new(connection_options.merge(host: 'h1.example.com,h2.example.com,h3.example.com'))
|
|
329
342
|
c.start!
|
|
330
343
|
|
|
@@ -142,7 +142,7 @@ module Cql
|
|
|
142
142
|
io_reactor.start
|
|
143
143
|
io_reactor.add_connection(host, port).get
|
|
144
144
|
io_reactor.queue_request(Cql::Protocol::StartupRequest.new)
|
|
145
|
-
await { server.received_bytes.
|
|
145
|
+
await { server.received_bytes.bytesize > 0 }
|
|
146
146
|
server.received_bytes[3, 1].should == "\x01"
|
|
147
147
|
end
|
|
148
148
|
|
|
@@ -150,7 +150,7 @@ module Cql
|
|
|
150
150
|
io_reactor.queue_request(Cql::Protocol::StartupRequest.new)
|
|
151
151
|
io_reactor.start
|
|
152
152
|
io_reactor.add_connection(host, port).get
|
|
153
|
-
await { server.received_bytes.
|
|
153
|
+
await { server.received_bytes.bytesize > 0 }
|
|
154
154
|
server.received_bytes[3, 1].should == "\x01"
|
|
155
155
|
end
|
|
156
156
|
|
|
@@ -52,6 +52,18 @@ module Cql
|
|
|
52
52
|
buffer.should == "\x00\x05hello"
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
it 'returns a binary string' do
|
|
56
|
+
str = 'I love π'.force_encoding(::Encoding::UTF_8)
|
|
57
|
+
Encoding.write_string(buffer, str)
|
|
58
|
+
buffer.encoding.should == ::Encoding::BINARY
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'encodes a string with multibyte characters' do
|
|
62
|
+
str = 'I love π'.force_encoding(::Encoding::UTF_8)
|
|
63
|
+
Encoding.write_string(buffer, str)
|
|
64
|
+
buffer.should == "\x00\x09I love π"
|
|
65
|
+
end
|
|
66
|
+
|
|
55
67
|
it 'encodes an empty string' do
|
|
56
68
|
Encoding.write_string(buffer, '')
|
|
57
69
|
buffer.should == "\x00\x00"
|
|
@@ -75,6 +87,18 @@ module Cql
|
|
|
75
87
|
buffer.should start_with("\x00\x12\x4f\x80hello world hello world hello world hello")
|
|
76
88
|
end
|
|
77
89
|
|
|
90
|
+
it 'returns a binary string' do
|
|
91
|
+
str = 'I love π'.force_encoding(::Encoding::UTF_8)
|
|
92
|
+
Encoding.write_long_string(buffer, str)
|
|
93
|
+
buffer.encoding.should == ::Encoding::BINARY
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'encodes a string with multibyte characters' do
|
|
97
|
+
str = 'I love π'.force_encoding(::Encoding::UTF_8)
|
|
98
|
+
Encoding.write_long_string(buffer, str)
|
|
99
|
+
buffer.should == "\x00\x00\x00\x09I love π"
|
|
100
|
+
end
|
|
101
|
+
|
|
78
102
|
it 'encodes an empty string' do
|
|
79
103
|
Encoding.write_long_string(buffer, '')
|
|
80
104
|
buffer.should == "\x00\x00\x00\x00"
|
|
@@ -120,6 +144,18 @@ module Cql
|
|
|
120
144
|
buffer.should == "\x00\x04\x00\x03foo\x00\x03bar\x00\x05hello\x00\x05world"
|
|
121
145
|
end
|
|
122
146
|
|
|
147
|
+
it 'returns a binary string' do
|
|
148
|
+
str = %w[I love π].map { |str| str.force_encoding(::Encoding::UTF_8) }
|
|
149
|
+
Encoding.write_string_list(buffer, str)
|
|
150
|
+
buffer.encoding.should == ::Encoding::BINARY
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it 'encodes a string with multibyte characters' do
|
|
154
|
+
str = %w[I love π].map { |str| str.force_encoding(::Encoding::UTF_8) }
|
|
155
|
+
Encoding.write_string_list(buffer, str)
|
|
156
|
+
buffer.should == "\x00\x03\x00\x01I\x00\x04love\x00\x02π"
|
|
157
|
+
end
|
|
158
|
+
|
|
123
159
|
it 'encodes an empty string list' do
|
|
124
160
|
Encoding.write_string_list(buffer, [])
|
|
125
161
|
buffer.should == "\x00\x00"
|
|
@@ -143,6 +179,18 @@ module Cql
|
|
|
143
179
|
buffer.should == ("\x00\x00\x07\xd0" << ("\xaa" * 2000))
|
|
144
180
|
end
|
|
145
181
|
|
|
182
|
+
it 'returns a binary string' do
|
|
183
|
+
str = 'I love π'.force_encoding(::Encoding::UTF_8)
|
|
184
|
+
Encoding.write_bytes(buffer, str)
|
|
185
|
+
buffer.encoding.should == ::Encoding::BINARY
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it 'encodes a string with multibyte characters' do
|
|
189
|
+
str = 'I love π'.force_encoding(::Encoding::UTF_8)
|
|
190
|
+
Encoding.write_bytes(buffer, str)
|
|
191
|
+
buffer.should == "\x00\x00\x00\x09I love π"
|
|
192
|
+
end
|
|
193
|
+
|
|
146
194
|
it 'encodes nil' do
|
|
147
195
|
Encoding.write_bytes(buffer, nil)
|
|
148
196
|
buffer.should == "\xff\xff\xff\xff"
|
|
@@ -166,6 +214,18 @@ module Cql
|
|
|
166
214
|
buffer.should == "\x00\x03\xaa\xbb\xcc"
|
|
167
215
|
end
|
|
168
216
|
|
|
217
|
+
it 'returns a binary string' do
|
|
218
|
+
str = 'I love π'.force_encoding(::Encoding::UTF_8)
|
|
219
|
+
Encoding.write_short_bytes(buffer, str)
|
|
220
|
+
buffer.encoding.should == ::Encoding::BINARY
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it 'encodes a string with multibyte characters' do
|
|
224
|
+
str = 'I love π'.force_encoding(::Encoding::UTF_8)
|
|
225
|
+
Encoding.write_short_bytes(buffer, str)
|
|
226
|
+
buffer.should == "\x00\x09I love π"
|
|
227
|
+
end
|
|
228
|
+
|
|
169
229
|
it 'encodes nil' do
|
|
170
230
|
Encoding.write_short_bytes(buffer, nil)
|
|
171
231
|
buffer.should == "\xff\xff"
|
|
@@ -56,6 +56,8 @@ describe 'A CQL client' do
|
|
|
56
56
|
statement = client.prepare('SELECT * FROM system.schema_keyspaces WHERE keyspace_name = ?')
|
|
57
57
|
result = statement.execute('system')
|
|
58
58
|
result.should have(1).item
|
|
59
|
+
result = statement.execute('system', :one)
|
|
60
|
+
result.should have(1).item
|
|
59
61
|
end
|
|
60
62
|
|
|
61
63
|
context 'with multiple connections' do
|
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.
|
|
4
|
+
version: 1.0.0.pre2
|
|
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-
|
|
12
|
+
date: 2013-03-08 00:00:00.000000000 Z
|
|
13
13
|
dependencies: []
|
|
14
14
|
description: A pure Ruby CQL3 driver for Cassandra
|
|
15
15
|
email:
|