cql-rb 1.2.2 → 2.0.0.pre0
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.
- checksums.yaml +4 -4
- data/.yardopts +4 -0
- data/README.md +139 -17
- data/lib/cql/client.rb +237 -8
- data/lib/cql/client/asynchronous_client.rb +138 -54
- data/lib/cql/client/asynchronous_prepared_statement.rb +41 -6
- data/lib/cql/client/authenticators.rb +46 -0
- data/lib/cql/client/batch.rb +115 -0
- data/lib/cql/client/connector.rb +255 -0
- data/lib/cql/client/execute_options_decoder.rb +25 -9
- data/lib/cql/client/keyspace_changer.rb +5 -5
- data/lib/cql/client/peer_discovery.rb +33 -0
- data/lib/cql/client/query_result.rb +124 -1
- data/lib/cql/client/request_runner.rb +4 -2
- data/lib/cql/client/synchronous_client.rb +14 -2
- data/lib/cql/client/synchronous_prepared_statement.rb +19 -1
- data/lib/cql/future.rb +97 -50
- data/lib/cql/io/connection.rb +0 -1
- data/lib/cql/io/io_reactor.rb +1 -1
- data/lib/cql/protocol.rb +8 -1
- data/lib/cql/protocol/cql_protocol_handler.rb +2 -2
- data/lib/cql/protocol/decoding.rb +10 -15
- data/lib/cql/protocol/frame_decoder.rb +2 -1
- data/lib/cql/protocol/frame_encoder.rb +5 -4
- data/lib/cql/protocol/requests/auth_response_request.rb +31 -0
- data/lib/cql/protocol/requests/batch_request.rb +59 -0
- data/lib/cql/protocol/requests/credentials_request.rb +1 -1
- data/lib/cql/protocol/requests/execute_request.rb +45 -17
- data/lib/cql/protocol/requests/options_request.rb +1 -1
- data/lib/cql/protocol/requests/prepare_request.rb +1 -1
- data/lib/cql/protocol/requests/query_request.rb +97 -5
- data/lib/cql/protocol/requests/register_request.rb +1 -1
- data/lib/cql/protocol/requests/startup_request.rb +4 -4
- data/lib/cql/protocol/response.rb +2 -2
- data/lib/cql/protocol/responses/auth_challenge_response.rb +25 -0
- data/lib/cql/protocol/responses/auth_success_response.rb +25 -0
- data/lib/cql/protocol/responses/authenticate_response.rb +1 -1
- data/lib/cql/protocol/responses/detailed_error_response.rb +1 -1
- data/lib/cql/protocol/responses/error_response.rb +3 -2
- data/lib/cql/protocol/responses/event_response.rb +3 -2
- data/lib/cql/protocol/responses/prepared_result_response.rb +10 -6
- data/lib/cql/protocol/responses/raw_rows_result_response.rb +27 -0
- data/lib/cql/protocol/responses/ready_response.rb +1 -1
- data/lib/cql/protocol/responses/result_response.rb +2 -2
- data/lib/cql/protocol/responses/rows_result_response.rb +43 -23
- data/lib/cql/protocol/responses/schema_change_event_response.rb +1 -1
- data/lib/cql/protocol/responses/schema_change_result_response.rb +1 -1
- data/lib/cql/protocol/responses/set_keyspace_result_response.rb +1 -1
- data/lib/cql/protocol/responses/status_change_event_response.rb +1 -1
- data/lib/cql/protocol/responses/supported_response.rb +1 -1
- data/lib/cql/protocol/responses/void_result_response.rb +1 -1
- data/lib/cql/protocol/type_converter.rb +2 -2
- data/lib/cql/uuid.rb +2 -2
- data/lib/cql/version.rb +1 -1
- data/spec/cql/client/asynchronous_client_spec.rb +493 -50
- data/spec/cql/client/asynchronous_prepared_statement_spec.rb +193 -11
- data/spec/cql/client/authenticators_spec.rb +56 -0
- data/spec/cql/client/batch_spec.rb +277 -0
- data/spec/cql/client/connector_spec.rb +606 -0
- data/spec/cql/client/execute_options_decoder_spec.rb +95 -0
- data/spec/cql/client/keyspace_changer_spec.rb +8 -8
- data/spec/cql/client/peer_discovery_spec.rb +92 -0
- data/spec/cql/client/query_result_spec.rb +352 -0
- data/spec/cql/client/request_runner_spec.rb +31 -5
- data/spec/cql/client/synchronous_client_spec.rb +44 -1
- data/spec/cql/client/synchronous_prepared_statement_spec.rb +63 -1
- data/spec/cql/future_spec.rb +50 -2
- data/spec/cql/protocol/cql_protocol_handler_spec.rb +16 -5
- data/spec/cql/protocol/decoding_spec.rb +16 -6
- data/spec/cql/protocol/encoding_spec.rb +3 -1
- data/spec/cql/protocol/frame_encoder_spec.rb +99 -50
- data/spec/cql/protocol/requests/auth_response_request_spec.rb +62 -0
- data/spec/cql/protocol/requests/batch_request_spec.rb +155 -0
- data/spec/cql/protocol/requests/credentials_request_spec.rb +1 -1
- data/spec/cql/protocol/requests/execute_request_spec.rb +184 -71
- data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
- data/spec/cql/protocol/requests/prepare_request_spec.rb +1 -1
- data/spec/cql/protocol/requests/query_request_spec.rb +255 -32
- data/spec/cql/protocol/requests/register_request_spec.rb +1 -1
- data/spec/cql/protocol/requests/startup_request_spec.rb +12 -6
- data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +31 -0
- data/spec/cql/protocol/responses/auth_success_response_spec.rb +31 -0
- data/spec/cql/protocol/responses/authenticate_response_spec.rb +2 -1
- data/spec/cql/protocol/responses/detailed_error_response_spec.rb +14 -7
- data/spec/cql/protocol/responses/error_response_spec.rb +4 -2
- data/spec/cql/protocol/responses/event_response_spec.rb +7 -4
- data/spec/cql/protocol/responses/prepared_result_response_spec.rb +89 -34
- data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +66 -0
- data/spec/cql/protocol/responses/ready_response_spec.rb +1 -1
- data/spec/cql/protocol/responses/result_response_spec.rb +19 -7
- data/spec/cql/protocol/responses/rows_result_response_spec.rb +56 -11
- data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +2 -1
- data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +2 -1
- data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +1 -1
- data/spec/cql/protocol/responses/status_change_event_response_spec.rb +2 -1
- data/spec/cql/protocol/responses/supported_response_spec.rb +2 -1
- data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +2 -1
- data/spec/cql/protocol/responses/void_result_response_spec.rb +1 -1
- data/spec/cql/protocol/type_converter_spec.rb +21 -4
- data/spec/cql/uuid_spec.rb +10 -3
- data/spec/integration/client_spec.rb +251 -28
- data/spec/integration/protocol_spec.rb +213 -62
- data/spec/integration/regression_spec.rb +4 -1
- data/spec/integration/uuid_spec.rb +4 -1
- data/spec/support/fake_io_reactor.rb +5 -5
- metadata +36 -7
- data/lib/cql/client/connection_helper.rb +0 -181
- data/spec/cql/client/connection_helper_spec.rb +0 -429
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
|
6
|
+
module Cql
|
7
|
+
module Protocol
|
8
|
+
describe AuthResponseRequest do
|
9
|
+
describe '#write' do
|
10
|
+
it 'encodes an AUTH_RESPONSE request frame' do
|
11
|
+
bytes = described_class.new('bingbongpong').write(2, '')
|
12
|
+
bytes.should == "\x00\x00\x00\x0cbingbongpong"
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'encodes a nil token' do
|
16
|
+
bytes = described_class.new(nil).write(2, '')
|
17
|
+
bytes.should == "\xff\xff\xff\xff"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#to_s' do
|
22
|
+
it 'returns a string representation including the number of bytes in the token' do
|
23
|
+
described_class.new('bingbongpong').to_s.should == 'AUTH_RESPONSE 12'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#eql?' do
|
28
|
+
it 'is equal to another with the same token' do
|
29
|
+
r1 = described_class.new('foo')
|
30
|
+
r2 = described_class.new('foo')
|
31
|
+
r1.should eql(r2)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'is not equal when the token is different' do
|
35
|
+
r1 = described_class.new('foo')
|
36
|
+
r2 = described_class.new('bar')
|
37
|
+
r1.should_not eql(r2)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'is aliased as #==' do
|
41
|
+
r1 = described_class.new('foo')
|
42
|
+
r2 = described_class.new('foo')
|
43
|
+
r1.should == r2
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#hash' do
|
48
|
+
it 'is the same when the token is the same' do
|
49
|
+
r1 = described_class.new('foo')
|
50
|
+
r2 = described_class.new('foo')
|
51
|
+
r1.hash.should == r2.hash
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'is not the same when the token is different' do
|
55
|
+
r1 = described_class.new('foo')
|
56
|
+
r2 = described_class.new('bar')
|
57
|
+
r1.hash.should_not == r2.hash
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
|
6
|
+
module Cql
|
7
|
+
module Protocol
|
8
|
+
describe BatchRequest do
|
9
|
+
let :statement_id do
|
10
|
+
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
11
|
+
end
|
12
|
+
|
13
|
+
let :metadata do
|
14
|
+
[['ks', 'tbl', 'things', :varchar], ['ks', 'tbl', 'things', :int]]
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#write' do
|
18
|
+
it 'encodes a BATCH request frame with a single prepared query' do
|
19
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :two)
|
20
|
+
batch.add_prepared(statement_id, metadata, ['arg', 3])
|
21
|
+
bytes = batch.write(2, '')
|
22
|
+
bytes.should == (
|
23
|
+
"\x00" +
|
24
|
+
"\x00\x01" +
|
25
|
+
"\x01" +
|
26
|
+
"\x00\x10" + statement_id +
|
27
|
+
"\x00\x02" + "\x00\x00\x00\x03arg" + "\x00\x00\x00\x04\x00\x00\x00\x03" +
|
28
|
+
"\x00\x02"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'encodes a BATCH request frame with a single query' do
|
33
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :one)
|
34
|
+
batch.add_query(%<INSERT INTO things (a, b) VALUES ('foo', 3)>)
|
35
|
+
bytes = batch.write(2, '')
|
36
|
+
bytes.should == (
|
37
|
+
"\x00" +
|
38
|
+
"\x00\x01" +
|
39
|
+
"\x00" +
|
40
|
+
"\x00\x00\x00\x2bINSERT INTO things (a, b) VALUES ('foo', 3)" +
|
41
|
+
"\x00\x00" +
|
42
|
+
"\x00\x01"
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'encodes a BATCH request frame with a single query with on-the-fly bound values' do
|
47
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :two)
|
48
|
+
batch.add_query('INSERT INTO things (a, b) VALUES (?, ?)', ['foo', 5])
|
49
|
+
bytes = batch.write(2, '')
|
50
|
+
bytes.should == (
|
51
|
+
"\x00" +
|
52
|
+
"\x00\x01" +
|
53
|
+
"\x00" +
|
54
|
+
"\x00\x00\x00\x27INSERT INTO things (a, b) VALUES (?, ?)" +
|
55
|
+
"\x00\x02" + "\x00\x00\x00\x03foo" + "\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x05" +
|
56
|
+
"\x00\x02"
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'encodes a BATCH request frame with a a mix of prepared and non-prepared queries' do
|
61
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :two)
|
62
|
+
batch.add_prepared(statement_id, metadata, ['arg', 3])
|
63
|
+
batch.add_query(%<INSERT INTO things (a, b) VALUES (?, ?)>, ['foo', 5])
|
64
|
+
batch.add_query(%<INSERT INTO things (a, b) VALUES ('foo', 3)>)
|
65
|
+
bytes = batch.write(2, '')
|
66
|
+
bytes.should == (
|
67
|
+
"\x00" +
|
68
|
+
"\x00\x03" +
|
69
|
+
"\x01" +
|
70
|
+
"\x00\x10" + statement_id +
|
71
|
+
"\x00\x02" + "\x00\x00\x00\x03arg" + "\x00\x00\x00\x04\x00\x00\x00\x03" +
|
72
|
+
"\x00" +
|
73
|
+
"\x00\x00\x00\x27INSERT INTO things (a, b) VALUES (?, ?)" +
|
74
|
+
"\x00\x02" + "\x00\x00\x00\x03foo" + "\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x05" +
|
75
|
+
"\x00" +
|
76
|
+
"\x00\x00\x00\x2bINSERT INTO things (a, b) VALUES ('foo', 3)" +
|
77
|
+
"\x00\x00" +
|
78
|
+
"\x00\x02"
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'encodes the type when it is "logged"' do
|
83
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :two)
|
84
|
+
batch.add_prepared(statement_id, metadata, ['arg', 3])
|
85
|
+
bytes = batch.write(2, '')
|
86
|
+
bytes[0].should == "\x00"
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'encodes the type when it is "unlogged"' do
|
90
|
+
batch = described_class.new(described_class::UNLOGGED_TYPE, :two)
|
91
|
+
batch.add_prepared(statement_id, metadata, ['arg', 3])
|
92
|
+
bytes = batch.write(2, '')
|
93
|
+
bytes[0].should == "\x01"
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'encodes the type when it is "counter"' do
|
97
|
+
batch = described_class.new(described_class::COUNTER_TYPE, :two)
|
98
|
+
batch.add_prepared(statement_id, metadata, ['arg', 3])
|
99
|
+
bytes = batch.write(2, '')
|
100
|
+
bytes[0].should == "\x02"
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'encodes the number of statements in the batch' do
|
104
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :two)
|
105
|
+
batch.add_prepared(statement_id, metadata, ['arg', 3])
|
106
|
+
batch.add_prepared(statement_id, metadata, ['foo', 4])
|
107
|
+
batch.add_prepared(statement_id, metadata, ['bar', 5])
|
108
|
+
bytes = batch.write(2, '')
|
109
|
+
bytes[1, 2].should == "\x00\x03"
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'encodes the type of each statement' do
|
113
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :two)
|
114
|
+
batch.add_prepared(statement_id, metadata, ['arg', 3])
|
115
|
+
batch.add_query(%<INSERT INTO things (a, b) VALUES ('arg', 3)>)
|
116
|
+
bytes = batch.write(2, '')
|
117
|
+
bytes[3, 1].should == "\x01"
|
118
|
+
bytes[39, 1].should == "\x00"
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'uses the type hints given to #add_query' do
|
122
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :two)
|
123
|
+
batch.add_query(%<INSERT INTO things (a, b) VALUES (?, ?)>, ['foo', 3], [nil, :int])
|
124
|
+
bytes = batch.write(2, '')
|
125
|
+
bytes[56, 8].should == "\x00\x00\x00\x04\x00\x00\x00\x03"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#to_s' do
|
130
|
+
context 'when the type is LOGGED' do
|
131
|
+
it 'returns a string representation of the batch request' do
|
132
|
+
batch = described_class.new(described_class::LOGGED_TYPE, :local_quorum)
|
133
|
+
batch.add_prepared(statement_id, metadata, ['arg', 3])
|
134
|
+
batch.add_query(%<INSERT INTO things (a, b) VALUES ('arg', 3)>)
|
135
|
+
batch.to_s.should == %(BATCH LOGGED 2 LOCAL_QUORUM)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when the type is UNLOGGED' do
|
140
|
+
it 'returns a string representation of the batch request' do
|
141
|
+
batch = described_class.new(described_class::UNLOGGED_TYPE, :one)
|
142
|
+
batch.to_s.should == %(BATCH UNLOGGED 0 ONE)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when the type is COUNTER' do
|
147
|
+
it 'returns a string representation of the batch request' do
|
148
|
+
batch = described_class.new(described_class::COUNTER_TYPE, :two)
|
149
|
+
batch.to_s.should == %(BATCH COUNTER 0 TWO)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -8,7 +8,7 @@ module Cql
|
|
8
8
|
describe CredentialsRequest do
|
9
9
|
describe '#write' do
|
10
10
|
it 'encodes a CREDENTIALS request frame' do
|
11
|
-
bytes = CredentialsRequest.new('username' => 'cassandra', 'password' => 'ardnassac').write('')
|
11
|
+
bytes = CredentialsRequest.new('username' => 'cassandra', 'password' => 'ardnassac').write(1, '')
|
12
12
|
bytes.should == (
|
13
13
|
"\x00\x02" +
|
14
14
|
"\x00\x08username" +
|
@@ -24,152 +24,265 @@ module Cql
|
|
24
24
|
|
25
25
|
describe '#initialize' do
|
26
26
|
it 'raises an error when the metadata and values don\'t have the same size' do
|
27
|
-
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42], :each_quorum) }.to raise_error(ArgumentError)
|
27
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42], true, :each_quorum, nil, nil, nil, false) }.to raise_error(ArgumentError)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'raises an error when the consistency is nil' do
|
31
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, nil, nil, nil, nil, false) }.to raise_error(ArgumentError)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'raises an error when the consistency is invalid' do
|
35
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :hello, nil, nil, nil, false) }.to raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'raises an error when the serial consistency is invalid' do
|
39
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :quorum, :foo, nil, nil, false) }.to raise_error(ArgumentError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'raises an error when paging state is given but no page size' do
|
43
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :quorum, nil, nil, 'foo', false) }.to raise_error(ArgumentError)
|
28
44
|
end
|
29
45
|
|
30
46
|
it 'raises an error for unsupported column types' do
|
31
47
|
column_metadata[2][3] = :imaginary
|
32
|
-
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], :each_quorum) }.to raise_error(UnsupportedColumnTypeError)
|
48
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :each_quorum, nil, nil, nil, false) }.to raise_error(UnsupportedColumnTypeError)
|
33
49
|
end
|
34
50
|
|
35
51
|
it 'raises an error for unsupported column collection types' do
|
36
52
|
column_metadata[2][3] = [:imaginary, :varchar]
|
37
|
-
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, ['foo']], :each_quorum) }.to raise_error(UnsupportedColumnTypeError)
|
53
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, ['foo']], true, :each_quorum, nil, nil, nil, false) }.to raise_error(UnsupportedColumnTypeError)
|
38
54
|
end
|
39
55
|
|
40
56
|
it 'raises an error when collection values are not enumerable' do
|
41
57
|
column_metadata[2][3] = [:set, :varchar]
|
42
|
-
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], :each_quorum) }.to raise_error(InvalidValueError)
|
58
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :each_quorum, nil, nil, nil, false) }.to raise_error(InvalidValueError)
|
43
59
|
end
|
44
60
|
|
45
61
|
it 'raises an error when it cannot encode the argument' do
|
46
|
-
expect { ExecuteRequest.new(id, column_metadata, ['hello', 'not an int', 'foo'], :each_quorum) }.to raise_error(TypeError, /cannot be encoded as INT/)
|
62
|
+
expect { ExecuteRequest.new(id, column_metadata, ['hello', 'not an int', 'foo'], true, :each_quorum, nil, nil, nil, false) }.to raise_error(TypeError, /cannot be encoded as INT/)
|
47
63
|
end
|
48
64
|
end
|
49
65
|
|
50
66
|
describe '#write' do
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
it
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
67
|
+
context 'when the protocol version is 1' do
|
68
|
+
let :frame_bytes do
|
69
|
+
ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :each_quorum, nil, nil, nil, false).write(1, '')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'writes the statement ID' do
|
73
|
+
frame_bytes.to_s[0, 18].should == "\x00\x10\xCAH\x7F\x1Ez\x82\xD2<N\x8A\xF35Qq\xA5/"
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'writes the number of bound variables' do
|
77
|
+
frame_bytes.to_s[18, 2].should == "\x00\x03"
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'writes the bound variables' do
|
81
|
+
frame_bytes.to_s[20, 24].should == "\x00\x00\x00\x05hello\x00\x00\x00\x04\x00\x00\x00\x2a\x00\x00\x00\x03foo"
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'writes the consistency' do
|
85
|
+
frame_bytes.to_s[44, 999].should == "\x00\x07"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when the protocol version is 2' do
|
90
|
+
let :frame_bytes do
|
91
|
+
ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :each_quorum, nil, nil, nil, false).write(2, '')
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'writes the statement ID' do
|
95
|
+
frame_bytes.to_s[0, 18].should == "\x00\x10\xCAH\x7F\x1Ez\x82\xD2<N\x8A\xF35Qq\xA5/"
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'writes the consistency' do
|
99
|
+
frame_bytes.to_s[18, 2].should == "\x00\x07"
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'writes flags saying that there will be bound values values' do
|
103
|
+
frame_bytes.to_s[20, 1].should == "\x01"
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'does not write the bound values flag when there are no values, and does not write anything more' do
|
107
|
+
frame_bytes = ExecuteRequest.new(id, [], [], true, :each_quorum, nil, nil, nil, false).write(2, '')
|
108
|
+
frame_bytes.to_s[20, 999].should == "\x00"
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'writes flags saying that the result doesn\'t need to contain metadata' do
|
112
|
+
frame_bytes = ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], false, :each_quorum, nil, nil, nil, false).write(2, '')
|
113
|
+
frame_bytes.to_s[20, 1].should == "\x03"
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'writes the number of bound values' do
|
117
|
+
frame_bytes.to_s[21, 2].should == "\x00\x03"
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'writes the bound values' do
|
121
|
+
frame_bytes.to_s[23, 999].should == "\x00\x00\x00\x05hello\x00\x00\x00\x04\x00\x00\x00\x2a\x00\x00\x00\x03foo"
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'sets the serial flag and includes the serial consistency' do
|
125
|
+
frame_bytes = ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], false, :each_quorum, :local_serial, false).write(2, '')
|
126
|
+
frame_bytes.to_s[20, 1].should == "\x13"
|
127
|
+
frame_bytes.to_s[47, 2].should == "\x00\x09"
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'writes the page size flag and page size' do
|
131
|
+
frame_bytes = ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :one, nil, 10, nil, false).write(2, '')
|
132
|
+
(frame_bytes[20, 1].ord & 0x04).should == 0x04
|
133
|
+
frame_bytes[47, 4].should == "\x00\x00\x00\x0a"
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'writes the page size and paging state flag and the page size and paging state' do
|
137
|
+
frame_bytes = ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], true, :one, nil, 10, 'foobar', false).write(2, '')
|
138
|
+
(frame_bytes[20, 1].ord & 0x0c).should == 0x0c
|
139
|
+
frame_bytes[47, 4].should == "\x00\x00\x00\x0a"
|
140
|
+
frame_bytes[51, 10].should == "\x00\x00\x00\x06foobar"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'with different data types' do
|
145
|
+
specs = [
|
146
|
+
[:ascii, 'test', "test"],
|
147
|
+
[:bigint, 1012312312414123, "\x00\x03\x98\xB1S\xC8\x7F\xAB"],
|
148
|
+
[:blob, "\xab\xcd", "\xab\xcd"],
|
149
|
+
[:boolean, false, "\x00"],
|
150
|
+
[:boolean, true, "\x01"],
|
151
|
+
[:decimal, BigDecimal.new('1042342234234.123423435647768234'), "\x00\x00\x00\x12\r'\xFDI\xAD\x80f\x11g\xDCfV\xAA"],
|
152
|
+
[:double, 10000.123123123, "@\xC3\x88\x0F\xC2\x7F\x9DU"],
|
153
|
+
[:float, 12.13, "AB\x14{"],
|
154
|
+
[:inet, IPAddr.new('8.8.8.8'), "\x08\x08\x08\x08"],
|
155
|
+
[:inet, IPAddr.new('::1'), "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"],
|
156
|
+
[:int, 12348098, "\x00\xBCj\xC2"],
|
157
|
+
[:text, 'FOOBAR', 'FOOBAR'],
|
158
|
+
[:timestamp, Time.at(1358013521.123), "\x00\x00\x01</\xE9\xDC\xE3"],
|
159
|
+
[:timeuuid, Uuid.new('a4a70900-24e1-11df-8924-001ff3591711'), "\xA4\xA7\t\x00$\xE1\x11\xDF\x89$\x00\x1F\xF3Y\x17\x11"],
|
160
|
+
[:uuid, Uuid.new('cfd66ccc-d857-4e90-b1e5-df98a3d40cd6'), "\xCF\xD6l\xCC\xD8WN\x90\xB1\xE5\xDF\x98\xA3\xD4\f\xD6"],
|
161
|
+
[:varchar, 'hello', 'hello'],
|
162
|
+
[:varint, 1231312312331283012830129382342342412123, "\x03\x9EV \x15\f\x03\x9DK\x18\xCDI\\$?\a["],
|
163
|
+
[:varint, -234234234234, "\xC9v\x8D:\x86"],
|
164
|
+
[[:list, :timestamp], [Time.at(1358013521.123)], "\x00\x01" + "\x00\x08\x00\x00\x01</\xE9\xDC\xE3"],
|
165
|
+
[[:list, :boolean], [true, false, true, true], "\x00\x04" + "\x00\x01\x01" + "\x00\x01\x00" + "\x00\x01\x01" + "\x00\x01\x01"],
|
166
|
+
[[: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"],
|
167
|
+
[[: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"],
|
168
|
+
[[: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"],
|
169
|
+
[[:set, :varchar], Set.new(['foo', 'bar', 'baz']), "\x00\x03" + "\x00\x03foo" + "\x00\x03bar" + "\x00\x03baz"],
|
170
|
+
[[: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"],
|
171
|
+
[[:set, :varchar], ['foo', 'bar', 'baz'], "\x00\x03" + "\x00\x03foo" + "\x00\x03bar" + "\x00\x03baz"]
|
172
|
+
]
|
173
|
+
specs.each do |type, value, expected_bytes|
|
174
|
+
it "encodes #{type} values" do
|
175
|
+
metadata = [['ks', 'tbl', 'id_column', type]]
|
176
|
+
buffer = ExecuteRequest.new(id, metadata, [value], true, :one, nil, nil, nil, false).write(1, ByteBuffer.new)
|
177
|
+
buffer.discard(2 + 16 + 2)
|
178
|
+
length = buffer.read_int
|
179
|
+
result_bytes = buffer.read(length)
|
180
|
+
result_bytes.should eql_bytes(expected_bytes)
|
181
|
+
end
|
93
182
|
end
|
94
183
|
end
|
95
184
|
end
|
96
185
|
|
97
186
|
describe '#to_s' do
|
98
187
|
it 'returns a pretty string' do
|
99
|
-
request = ExecuteRequest.new(id, column_metadata, values, :each_quorum)
|
188
|
+
request = ExecuteRequest.new(id, column_metadata, values, true, :each_quorum, nil, nil, nil, false)
|
100
189
|
request.to_s.should == 'EXECUTE ca487f1e7a82d23c4e8af3355171a52f ["hello", 42, "foo"] EACH_QUORUM'
|
101
190
|
end
|
102
191
|
end
|
103
192
|
|
104
193
|
describe '#eql?' do
|
105
194
|
it 'returns true when the ID, metadata, values and consistency are the same' do
|
106
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
107
|
-
e2 = ExecuteRequest.new(id, column_metadata, values, :one)
|
195
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
196
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
108
197
|
e1.should eql(e2)
|
109
198
|
end
|
110
199
|
|
111
200
|
it 'returns false when the ID is different' do
|
112
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
113
|
-
e2 = ExecuteRequest.new(id.reverse, column_metadata, values, :one)
|
201
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
202
|
+
e2 = ExecuteRequest.new(id.reverse, column_metadata, values, true, :one, nil, nil, nil, false)
|
114
203
|
e1.should_not eql(e2)
|
115
204
|
end
|
116
205
|
|
117
206
|
it 'returns false when the metadata is different' do
|
118
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
119
|
-
e2 = ExecuteRequest.new(id, column_metadata.reverse, values, :one)
|
207
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
208
|
+
e2 = ExecuteRequest.new(id, column_metadata.reverse, values, true, :one, nil, nil, nil, false)
|
120
209
|
e1.should_not eql(e2)
|
121
210
|
end
|
122
211
|
|
123
212
|
it 'returns false when the values are different' do
|
124
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
125
|
-
e2 = ExecuteRequest.new(id, column_metadata, values.reverse, :one)
|
213
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
214
|
+
e2 = ExecuteRequest.new(id, column_metadata, values.reverse, true, :one, nil, nil, nil, false)
|
126
215
|
e1.should_not eql(e2)
|
127
216
|
end
|
128
217
|
|
129
218
|
it 'returns false when the consistency is different' do
|
130
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
131
|
-
e2 = ExecuteRequest.new(id, column_metadata, values, :two)
|
219
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
220
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :two, nil, nil, nil, false)
|
221
|
+
e1.should_not eql(e2)
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'returns false when the serial consistency is different' do
|
225
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, :serial, nil, nil, false)
|
226
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :one, :local_serial, nil, nil, false)
|
227
|
+
e1.should_not eql(e2)
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'returns false when the page size is different' do
|
231
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, 10, nil, false)
|
232
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, 20, nil, false)
|
233
|
+
e1.should_not eql(e2)
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'returns false when the paging state is different' do
|
237
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, 10, 'foo', false)
|
238
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, 10, 'bar', false)
|
132
239
|
e1.should_not eql(e2)
|
133
240
|
end
|
134
241
|
|
135
242
|
it 'is aliased as ==' do
|
136
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
137
|
-
e2 = ExecuteRequest.new(id, column_metadata, values, :one)
|
243
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
244
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
138
245
|
e1.should == e2
|
139
246
|
end
|
140
247
|
end
|
141
248
|
|
142
249
|
describe '#hash' do
|
143
250
|
it 'has the same hash code as another identical object' do
|
144
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
145
|
-
e2 = ExecuteRequest.new(id, column_metadata, values, :one)
|
251
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
252
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
146
253
|
e1.hash.should == e2.hash
|
147
254
|
end
|
148
255
|
|
149
256
|
it 'does not have the same hash code when the ID is different' do
|
150
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
151
|
-
e2 = ExecuteRequest.new(id.reverse, column_metadata, values, :one)
|
257
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
258
|
+
e2 = ExecuteRequest.new(id.reverse, column_metadata, values, true, :one, nil, nil, nil, false)
|
152
259
|
e1.hash.should_not == e2.hash
|
153
260
|
end
|
154
261
|
|
155
262
|
it 'does not have the same hash code when the metadata is different' do
|
156
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
157
|
-
e2 = ExecuteRequest.new(id, column_metadata.reverse, values, :one)
|
263
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
264
|
+
e2 = ExecuteRequest.new(id, column_metadata.reverse, values, true, :one, nil, nil, nil, false)
|
158
265
|
e1.hash.should_not == e2.hash
|
159
266
|
end
|
160
267
|
|
161
268
|
it 'does not have the same hash code when the values are different' do
|
162
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
163
|
-
e2 = ExecuteRequest.new(id, column_metadata, values.reverse, :one)
|
269
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
270
|
+
e2 = ExecuteRequest.new(id, column_metadata, values.reverse, true, :one, nil, nil, nil, false)
|
164
271
|
e1.hash.should_not == e2.hash
|
165
272
|
end
|
166
273
|
|
167
274
|
it 'does not have the same hash code when the consistency is different' do
|
168
|
-
e1 = ExecuteRequest.new(id, column_metadata, values, :one)
|
169
|
-
e2 = ExecuteRequest.new(id, column_metadata, values, :two)
|
275
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
276
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :two, nil, nil, nil, false)
|
277
|
+
e1.hash.should_not == e2.hash
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'does not have the same hash code when the serial consistency is different' do
|
281
|
+
e1 = ExecuteRequest.new(id, column_metadata, values, true, :one, nil, nil, nil, false)
|
282
|
+
e2 = ExecuteRequest.new(id, column_metadata, values, true, :one, :serial, nil, nil, false)
|
170
283
|
e1.hash.should_not == e2.hash
|
171
284
|
end
|
172
285
|
end
|
173
286
|
end
|
174
287
|
end
|
175
|
-
end
|
288
|
+
end
|