cql-rb 1.2.2 → 2.0.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -0
  3. data/README.md +139 -17
  4. data/lib/cql/client.rb +237 -8
  5. data/lib/cql/client/asynchronous_client.rb +138 -54
  6. data/lib/cql/client/asynchronous_prepared_statement.rb +41 -6
  7. data/lib/cql/client/authenticators.rb +46 -0
  8. data/lib/cql/client/batch.rb +115 -0
  9. data/lib/cql/client/connector.rb +255 -0
  10. data/lib/cql/client/execute_options_decoder.rb +25 -9
  11. data/lib/cql/client/keyspace_changer.rb +5 -5
  12. data/lib/cql/client/peer_discovery.rb +33 -0
  13. data/lib/cql/client/query_result.rb +124 -1
  14. data/lib/cql/client/request_runner.rb +4 -2
  15. data/lib/cql/client/synchronous_client.rb +14 -2
  16. data/lib/cql/client/synchronous_prepared_statement.rb +19 -1
  17. data/lib/cql/future.rb +97 -50
  18. data/lib/cql/io/connection.rb +0 -1
  19. data/lib/cql/io/io_reactor.rb +1 -1
  20. data/lib/cql/protocol.rb +8 -1
  21. data/lib/cql/protocol/cql_protocol_handler.rb +2 -2
  22. data/lib/cql/protocol/decoding.rb +10 -15
  23. data/lib/cql/protocol/frame_decoder.rb +2 -1
  24. data/lib/cql/protocol/frame_encoder.rb +5 -4
  25. data/lib/cql/protocol/requests/auth_response_request.rb +31 -0
  26. data/lib/cql/protocol/requests/batch_request.rb +59 -0
  27. data/lib/cql/protocol/requests/credentials_request.rb +1 -1
  28. data/lib/cql/protocol/requests/execute_request.rb +45 -17
  29. data/lib/cql/protocol/requests/options_request.rb +1 -1
  30. data/lib/cql/protocol/requests/prepare_request.rb +1 -1
  31. data/lib/cql/protocol/requests/query_request.rb +97 -5
  32. data/lib/cql/protocol/requests/register_request.rb +1 -1
  33. data/lib/cql/protocol/requests/startup_request.rb +4 -4
  34. data/lib/cql/protocol/response.rb +2 -2
  35. data/lib/cql/protocol/responses/auth_challenge_response.rb +25 -0
  36. data/lib/cql/protocol/responses/auth_success_response.rb +25 -0
  37. data/lib/cql/protocol/responses/authenticate_response.rb +1 -1
  38. data/lib/cql/protocol/responses/detailed_error_response.rb +1 -1
  39. data/lib/cql/protocol/responses/error_response.rb +3 -2
  40. data/lib/cql/protocol/responses/event_response.rb +3 -2
  41. data/lib/cql/protocol/responses/prepared_result_response.rb +10 -6
  42. data/lib/cql/protocol/responses/raw_rows_result_response.rb +27 -0
  43. data/lib/cql/protocol/responses/ready_response.rb +1 -1
  44. data/lib/cql/protocol/responses/result_response.rb +2 -2
  45. data/lib/cql/protocol/responses/rows_result_response.rb +43 -23
  46. data/lib/cql/protocol/responses/schema_change_event_response.rb +1 -1
  47. data/lib/cql/protocol/responses/schema_change_result_response.rb +1 -1
  48. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +1 -1
  49. data/lib/cql/protocol/responses/status_change_event_response.rb +1 -1
  50. data/lib/cql/protocol/responses/supported_response.rb +1 -1
  51. data/lib/cql/protocol/responses/void_result_response.rb +1 -1
  52. data/lib/cql/protocol/type_converter.rb +2 -2
  53. data/lib/cql/uuid.rb +2 -2
  54. data/lib/cql/version.rb +1 -1
  55. data/spec/cql/client/asynchronous_client_spec.rb +493 -50
  56. data/spec/cql/client/asynchronous_prepared_statement_spec.rb +193 -11
  57. data/spec/cql/client/authenticators_spec.rb +56 -0
  58. data/spec/cql/client/batch_spec.rb +277 -0
  59. data/spec/cql/client/connector_spec.rb +606 -0
  60. data/spec/cql/client/execute_options_decoder_spec.rb +95 -0
  61. data/spec/cql/client/keyspace_changer_spec.rb +8 -8
  62. data/spec/cql/client/peer_discovery_spec.rb +92 -0
  63. data/spec/cql/client/query_result_spec.rb +352 -0
  64. data/spec/cql/client/request_runner_spec.rb +31 -5
  65. data/spec/cql/client/synchronous_client_spec.rb +44 -1
  66. data/spec/cql/client/synchronous_prepared_statement_spec.rb +63 -1
  67. data/spec/cql/future_spec.rb +50 -2
  68. data/spec/cql/protocol/cql_protocol_handler_spec.rb +16 -5
  69. data/spec/cql/protocol/decoding_spec.rb +16 -6
  70. data/spec/cql/protocol/encoding_spec.rb +3 -1
  71. data/spec/cql/protocol/frame_encoder_spec.rb +99 -50
  72. data/spec/cql/protocol/requests/auth_response_request_spec.rb +62 -0
  73. data/spec/cql/protocol/requests/batch_request_spec.rb +155 -0
  74. data/spec/cql/protocol/requests/credentials_request_spec.rb +1 -1
  75. data/spec/cql/protocol/requests/execute_request_spec.rb +184 -71
  76. data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
  77. data/spec/cql/protocol/requests/prepare_request_spec.rb +1 -1
  78. data/spec/cql/protocol/requests/query_request_spec.rb +255 -32
  79. data/spec/cql/protocol/requests/register_request_spec.rb +1 -1
  80. data/spec/cql/protocol/requests/startup_request_spec.rb +12 -6
  81. data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +31 -0
  82. data/spec/cql/protocol/responses/auth_success_response_spec.rb +31 -0
  83. data/spec/cql/protocol/responses/authenticate_response_spec.rb +2 -1
  84. data/spec/cql/protocol/responses/detailed_error_response_spec.rb +14 -7
  85. data/spec/cql/protocol/responses/error_response_spec.rb +4 -2
  86. data/spec/cql/protocol/responses/event_response_spec.rb +7 -4
  87. data/spec/cql/protocol/responses/prepared_result_response_spec.rb +89 -34
  88. data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +66 -0
  89. data/spec/cql/protocol/responses/ready_response_spec.rb +1 -1
  90. data/spec/cql/protocol/responses/result_response_spec.rb +19 -7
  91. data/spec/cql/protocol/responses/rows_result_response_spec.rb +56 -11
  92. data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +2 -1
  93. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +2 -1
  94. data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +1 -1
  95. data/spec/cql/protocol/responses/status_change_event_response_spec.rb +2 -1
  96. data/spec/cql/protocol/responses/supported_response_spec.rb +2 -1
  97. data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +2 -1
  98. data/spec/cql/protocol/responses/void_result_response_spec.rb +1 -1
  99. data/spec/cql/protocol/type_converter_spec.rb +21 -4
  100. data/spec/cql/uuid_spec.rb +10 -3
  101. data/spec/integration/client_spec.rb +251 -28
  102. data/spec/integration/protocol_spec.rb +213 -62
  103. data/spec/integration/regression_spec.rb +4 -1
  104. data/spec/integration/uuid_spec.rb +4 -1
  105. data/spec/support/fake_io_reactor.rb +5 -5
  106. metadata +36 -7
  107. data/lib/cql/client/connection_helper.rb +0 -181
  108. 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
- it 'encodes an EXECUTE request frame' do
52
- bytes = ExecuteRequest.new(id, column_metadata, ['hello', 42, 'foo'], :each_quorum).write('')
53
- bytes.should == "\x00\x10\xCAH\x7F\x1Ez\x82\xD2<N\x8A\xF35Qq\xA5/\x00\x03\x00\x00\x00\x05hello\x00\x00\x00\x04\x00\x00\x00\x2a\x00\x00\x00\x03foo\x00\x07"
54
- end
55
-
56
- specs = [
57
- [:ascii, 'test', "test"],
58
- [:bigint, 1012312312414123, "\x00\x03\x98\xB1S\xC8\x7F\xAB"],
59
- [:blob, "\xab\xcd", "\xab\xcd"],
60
- [:boolean, false, "\x00"],
61
- [:boolean, true, "\x01"],
62
- [:decimal, BigDecimal.new('1042342234234.123423435647768234'), "\x00\x00\x00\x12\r'\xFDI\xAD\x80f\x11g\xDCfV\xAA"],
63
- [:double, 10000.123123123, "@\xC3\x88\x0F\xC2\x7F\x9DU"],
64
- [:float, 12.13, "AB\x14{"],
65
- [:inet, IPAddr.new('8.8.8.8'), "\x08\x08\x08\x08"],
66
- [:inet, IPAddr.new('::1'), "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"],
67
- [:int, 12348098, "\x00\xBCj\xC2"],
68
- [:text, 'FOOBAR', 'FOOBAR'],
69
- [:timestamp, Time.at(1358013521.123), "\x00\x00\x01</\xE9\xDC\xE3"],
70
- [:timeuuid, Uuid.new('a4a70900-24e1-11df-8924-001ff3591711'), "\xA4\xA7\t\x00$\xE1\x11\xDF\x89$\x00\x1F\xF3Y\x17\x11"],
71
- [:uuid, Uuid.new('cfd66ccc-d857-4e90-b1e5-df98a3d40cd6'), "\xCF\xD6l\xCC\xD8WN\x90\xB1\xE5\xDF\x98\xA3\xD4\f\xD6"],
72
- [:varchar, 'hello', 'hello'],
73
- [:varint, 1231312312331283012830129382342342412123, "\x03\x9EV \x15\f\x03\x9DK\x18\xCDI\\$?\a["],
74
- [:varint, -234234234234, "\xC9v\x8D:\x86"],
75
- [[:list, :timestamp], [Time.at(1358013521.123)], "\x00\x01" + "\x00\x08\x00\x00\x01</\xE9\xDC\xE3"],
76
- [[:list, :boolean], [true, false, true, true], "\x00\x04" + "\x00\x01\x01" + "\x00\x01\x00" + "\x00\x01\x01" + "\x00\x01\x01"],
77
- [[: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"],
78
- [[: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"],
79
- [[:map, :varchar, :float], {'hello' => 1, 'würld'.force_encoding('utf-8') => 2.0}, "\x00\x02" + "\x00\x05hello" + "\x00\x04?\x80\x00\x00" + "\x00\x06w\xC3\xBCrld" + "\x00\x04@\x00\x00\x00"],
80
- [[: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"],
81
- [[:set, :varchar], Set.new(['foo', 'bar', 'baz']), "\x00\x03" + "\x00\x03foo" + "\x00\x03bar" + "\x00\x03baz"],
82
- [[: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"],
83
- [[:set, :varchar], ['foo', 'bar', 'baz'], "\x00\x03" + "\x00\x03foo" + "\x00\x03bar" + "\x00\x03baz"]
84
- ]
85
- specs.each do |type, value, expected_bytes|
86
- it "encodes #{type} values" do
87
- metadata = [['ks', 'tbl', 'id_column', type]]
88
- buffer = ExecuteRequest.new(id, metadata, [value], :one).write(ByteBuffer.new)
89
- buffer.discard(2 + 16 + 2)
90
- length = buffer.read_int
91
- result_bytes = buffer.read(length)
92
- result_bytes.should eql_bytes(expected_bytes)
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