cql-rb 1.0.6 → 1.1.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/README.md +4 -9
  2. data/lib/cql.rb +1 -0
  3. data/lib/cql/byte_buffer.rb +23 -7
  4. data/lib/cql/client.rb +11 -6
  5. data/lib/cql/client/asynchronous_client.rb +37 -83
  6. data/lib/cql/client/asynchronous_prepared_statement.rb +10 -4
  7. data/lib/cql/client/column_metadata.rb +16 -0
  8. data/lib/cql/client/request_runner.rb +46 -0
  9. data/lib/cql/future.rb +4 -5
  10. data/lib/cql/io.rb +2 -5
  11. data/lib/cql/io/connection.rb +220 -0
  12. data/lib/cql/io/io_reactor.rb +213 -185
  13. data/lib/cql/protocol.rb +1 -0
  14. data/lib/cql/protocol/cql_protocol_handler.rb +201 -0
  15. data/lib/cql/protocol/decoding.rb +6 -31
  16. data/lib/cql/protocol/encoding.rb +1 -5
  17. data/lib/cql/protocol/request.rb +4 -0
  18. data/lib/cql/protocol/responses/schema_change_result_response.rb +15 -0
  19. data/lib/cql/protocol/type_converter.rb +56 -76
  20. data/lib/cql/time_uuid.rb +104 -0
  21. data/lib/cql/uuid.rb +4 -2
  22. data/lib/cql/version.rb +1 -1
  23. data/spec/cql/client/asynchronous_client_spec.rb +47 -71
  24. data/spec/cql/client/asynchronous_prepared_statement_spec.rb +68 -0
  25. data/spec/cql/client/client_shared.rb +3 -3
  26. data/spec/cql/client/column_metadata_spec.rb +80 -0
  27. data/spec/cql/client/request_runner_spec.rb +120 -0
  28. data/spec/cql/future_spec.rb +26 -11
  29. data/spec/cql/io/connection_spec.rb +460 -0
  30. data/spec/cql/io/io_reactor_spec.rb +212 -265
  31. data/spec/cql/protocol/cql_protocol_handler_spec.rb +216 -0
  32. data/spec/cql/protocol/decoding_spec.rb +9 -28
  33. data/spec/cql/protocol/encoding_spec.rb +0 -5
  34. data/spec/cql/protocol/request_spec.rb +16 -0
  35. data/spec/cql/protocol/response_frame_spec.rb +2 -2
  36. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +70 -0
  37. data/spec/cql/time_uuid_spec.rb +136 -0
  38. data/spec/cql/uuid_spec.rb +1 -5
  39. data/spec/integration/client_spec.rb +34 -38
  40. data/spec/integration/io_spec.rb +283 -0
  41. data/spec/integration/protocol_spec.rb +53 -113
  42. data/spec/integration/regression_spec.rb +124 -0
  43. data/spec/integration/uuid_spec.rb +76 -0
  44. data/spec/spec_helper.rb +12 -9
  45. data/spec/support/fake_io_reactor.rb +52 -21
  46. data/spec/support/fake_server.rb +2 -2
  47. metadata +33 -10
  48. checksums.yaml +0 -15
  49. data/lib/cql/io/node_connection.rb +0 -209
  50. data/spec/cql/protocol/type_converter_spec.rb +0 -52
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZDk1YTJjZWRjODBkYTMyNjIyYjBhYjZkN2NjYzA5MWE1YzJkNTVjMw==
5
- data.tar.gz: !binary |-
6
- ZjI5MjQ2Mzc1MDE3MzRjYzg4MzVjMmY5YTMyM2U4ODY0ODY4ZTg0OQ==
7
- SHA512:
8
- metadata.gz: !binary |-
9
- Y2IxNTg3NGYxOWM1MzY3ZmViYTY4MjcxNDhkNDAzZjkxMmY5MTBjYjc4YzJi
10
- MDMwMjI1Y2NmZjI2OTAyNTM3ZWQ5ODk2M2YwMjNjODU5ODlkNjI5ZDUxNDk2
11
- Y2NhNWZlMjk3ZWUzNTU4YzM2Y2UyZWI5M2YyODQyMjVmODczODU=
12
- data.tar.gz: !binary |-
13
- YjJhNDIwN2M1NTg4ZjMxMWNiYjA1NGFlMjZiMDc1ODgxZDhmMDAyZTUzZDEx
14
- ZDE2OGNlZTAzN2IwNTVmNWYzNjcxYzNhNTdlNzk0Mzg3Zjk4ZDhjZjE1ZmY5
15
- MjQ4NzE3NzUyNDQ5NTc5NDE5ODQ4MmE2MGZkMjIyMjlhMjk4NWQ=
@@ -1,209 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'socket'
4
-
5
-
6
- module Cql
7
- module Io
8
- # @private
9
- class NodeConnection
10
- def initialize(*args)
11
- @host, @port, @connection_timeout = args
12
- @connected_future = Future.new
13
- @io = nil
14
- @addrinfo = nil
15
- @write_buffer = ByteBuffer.new
16
- @read_buffer = ByteBuffer.new
17
- @current_frame = Protocol::ResponseFrame.new(@read_buffer)
18
- @response_tasks = [nil] * 128
19
- @event_listeners = Hash.new { |h, k| h[k] = [] }
20
- end
21
-
22
- def open
23
- @connection_started_at = Time.now
24
- begin
25
- addrinfo = Socket.getaddrinfo(@host, @port, Socket::AF_INET, Socket::SOCK_STREAM)
26
- _, port, _, ip, address_family, socket_type = addrinfo.first
27
- @sockaddr = Socket.sockaddr_in(port, ip)
28
- @io = Socket.new(address_family, socket_type, 0)
29
- @io.connect_nonblock(@sockaddr)
30
- rescue Errno::EINPROGRESS
31
- # NOTE not connected yet, this is expected
32
- rescue SystemCallError, SocketError => e
33
- fail_connection!(e)
34
- end
35
- @connected_future
36
- end
37
-
38
- def connection_id
39
- self.object_id
40
- end
41
-
42
- def to_io
43
- @io
44
- end
45
-
46
- def on_event(&listener)
47
- @event_listeners[:event] << listener
48
- end
49
-
50
- def on_close(&listener)
51
- @event_listeners[:close] << listener
52
- end
53
-
54
- def connected?
55
- @io && !connecting?
56
- end
57
-
58
- def connecting?
59
- @io && !(@connected_future.complete? || @connected_future.failed?)
60
- end
61
-
62
- def closed?
63
- @io.nil? && !connecting?
64
- end
65
-
66
- def has_capacity?
67
- !!next_stream_id && connected?
68
- end
69
-
70
- def can_write?
71
- @io && (!@write_buffer.empty? || connecting?)
72
- end
73
-
74
- def handle_read
75
- new_bytes = @io.read_nonblock(2**16)
76
- @current_frame << new_bytes
77
- while @current_frame.complete?
78
- stream_id = @current_frame.stream_id
79
- if stream_id == EVENT_STREAM_ID
80
- @event_listeners[:event].each { |listener| listener.call(@current_frame.body) }
81
- elsif @response_tasks[stream_id]
82
- @response_tasks[stream_id].complete!([@current_frame.body, connection_id])
83
- @response_tasks[stream_id] = nil
84
- else
85
- # TODO dropping the request on the floor here, but we didn't send it
86
- end
87
- @current_frame = Protocol::ResponseFrame.new(@read_buffer)
88
- end
89
- rescue => e
90
- force_close(e)
91
- end
92
-
93
- def perform_request(request, future)
94
- stream_id = next_stream_id
95
- request.encode_frame(stream_id, @write_buffer)
96
- @response_tasks[stream_id] = future
97
- rescue => e
98
- case e
99
- when CqlError
100
- error = e
101
- else
102
- error = IoError.new(e.message)
103
- error.set_backtrace(e.backtrace)
104
- end
105
- @response_tasks.delete(stream_id)
106
- future.fail!(error)
107
- end
108
-
109
- def handle_write
110
- if connecting?
111
- handle_connecting
112
- else
113
- if !@write_buffer.empty?
114
- bytes_written = @io.write_nonblock(@write_buffer.cheap_peek)
115
- @write_buffer.discard(bytes_written)
116
- end
117
- end
118
- rescue => e
119
- force_close(e)
120
- end
121
-
122
- def handle_connecting
123
- if connecting_timed_out?
124
- fail_connection!(ConnectionTimeoutError.new("Could not connect to #{@host}:#{@port} within #{@connection_timeout}s"))
125
- else
126
- @io.connect_nonblock(@sockaddr)
127
- succeed_connection!
128
- end
129
- rescue Errno::EALREADY, Errno::EINPROGRESS
130
- # NOTE still not connected
131
- rescue Errno::EISCONN
132
- succeed_connection!
133
- rescue SystemCallError, SocketError => e
134
- fail_connection!(e)
135
- end
136
-
137
- def close
138
- if @io
139
- begin
140
- @io.close
141
- rescue SystemCallError
142
- # NOTE nothing to do, it wasn't open
143
- end
144
- if connecting?
145
- succeed_connection!
146
- end
147
- @io = nil
148
- @event_listeners[:close].each { |listener| listener.call(self) }
149
- end
150
- end
151
-
152
- def to_s
153
- state = begin
154
- if connected? then 'connected'
155
- elsif connecting? then 'connecting'
156
- else 'not connected'
157
- end
158
- end
159
- %<NodeConnection(#{@host}:#{@port}, #{state})>
160
- end
161
-
162
- private
163
-
164
- EVENT_STREAM_ID = -1
165
-
166
- def connecting_timed_out?
167
- (Time.now - @connection_started_at) > @connection_timeout
168
- end
169
-
170
- def succeed_connection!
171
- @connected_future.complete!(connection_id)
172
- end
173
-
174
- def fail_connection!(e)
175
- case e
176
- when ConnectionError
177
- error = e
178
- else
179
- message = "Could not connect to #{@host}:#{@port}: #{e.message} (#{e.class.name})"
180
- error = ConnectionError.new(message)
181
- error.set_backtrace(e.backtrace)
182
- end
183
- @connected_future.fail!(error)
184
- force_close(error)
185
- end
186
-
187
- def force_close(e)
188
- case e
189
- when CqlError
190
- error = e
191
- else
192
- error = IoError.new(e.message)
193
- error.set_backtrace(e.backtrace)
194
- end
195
- @response_tasks.each do |listener|
196
- listener.fail!(error) if listener
197
- end
198
- close
199
- end
200
-
201
- def next_stream_id
202
- @response_tasks.each_with_index do |task, index|
203
- return index if task.nil?
204
- end
205
- nil
206
- end
207
- end
208
- end
209
- end
@@ -1,52 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- require 'spec_helper'
4
-
5
-
6
- module Cql
7
- module Protocol
8
- describe TypeConverter do
9
- let :converter do
10
- described_class.new
11
- end
12
-
13
- let :buffer do
14
- ''
15
- end
16
-
17
- TYPES = [:ascii, :bigint, :blob, :boolean, :counter, :decimal, :double, :float, :inet, :int, :text, :varchar, :timestamp, :timeuuid, :uuid, :varint].freeze
18
-
19
- describe '#to_bytes' do
20
- context 'when encoding normal value' do
21
- TYPES.each do |type|
22
- it "encodes a null #{type.upcase}" do
23
- converter.to_bytes(buffer, type, nil, 4).should == "\xff\xff\xff\xff"
24
- end
25
- end
26
-
27
- it 'encodes a null LIST' do
28
- converter.to_bytes(buffer, [:list, :int], nil, 4).should == "\xff\xff\xff\xff"
29
- end
30
-
31
- it 'encodes a null MAP' do
32
- converter.to_bytes(buffer, [:map, :text, :text], nil, 4).should == "\xff\xff\xff\xff"
33
-
34
- end
35
-
36
- it 'encodes a null SET' do
37
- converter.to_bytes(buffer, [:set, :uuid], nil, 4).should == "\xff\xff\xff\xff"
38
-
39
- end
40
- end
41
-
42
- context 'when encoding collection values' do
43
- TYPES.each do |type|
44
- it "encodes a null #{type.upcase}" do
45
- converter.to_bytes(buffer, type, nil, 2).should == "\xff\xff"
46
- end
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end