cassandra-driver 1.0.0.rc.1 → 1.0.0
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 +8 -8
- data/README.md +45 -10
- data/lib/cassandra.rb +82 -82
- data/lib/cassandra/cluster.rb +3 -0
- data/lib/cassandra/cluster/client.rb +17 -5
- data/lib/cassandra/{client/connection_manager.rb → cluster/connection_pool.rb} +3 -3
- data/lib/cassandra/cluster/connector.rb +101 -30
- data/lib/cassandra/cluster/control_connection.rb +6 -7
- data/lib/cassandra/{client/null_logger.rb → cluster/failed_connection.rb} +12 -14
- data/lib/cassandra/cluster/options.rb +8 -0
- data/lib/cassandra/column.rb +5 -0
- data/lib/cassandra/driver.rb +3 -3
- data/lib/cassandra/errors.rb +5 -5
- data/lib/cassandra/execution/options.rb +13 -6
- data/lib/cassandra/execution/trace.rb +4 -4
- data/lib/cassandra/future.rb +4 -0
- data/lib/cassandra/keyspace.rb +5 -0
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +7 -2
- data/lib/cassandra/load_balancing/policies/token_aware.rb +1 -3
- data/lib/cassandra/load_balancing/policies/white_list.rb +3 -6
- data/lib/cassandra/null_logger.rb +35 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +4 -0
- data/lib/cassandra/protocol/requests/query_request.rb +1 -11
- data/lib/cassandra/result.rb +4 -6
- data/lib/cassandra/session.rb +3 -0
- data/lib/cassandra/statements/prepared.rb +5 -1
- data/lib/cassandra/table.rb +5 -0
- data/lib/cassandra/util.rb +130 -0
- data/lib/cassandra/version.rb +1 -1
- metadata +9 -20
- data/lib/cassandra/client.rb +0 -144
- data/lib/cassandra/client/batch.rb +0 -212
- data/lib/cassandra/client/client.rb +0 -591
- data/lib/cassandra/client/column_metadata.rb +0 -54
- data/lib/cassandra/client/connector.rb +0 -273
- data/lib/cassandra/client/execute_options_decoder.rb +0 -59
- data/lib/cassandra/client/peer_discovery.rb +0 -50
- data/lib/cassandra/client/prepared_statement.rb +0 -314
- data/lib/cassandra/client/query_result.rb +0 -230
- data/lib/cassandra/client/request_runner.rb +0 -70
- data/lib/cassandra/client/result_metadata.rb +0 -48
- data/lib/cassandra/client/void_result.rb +0 -78
data/lib/cassandra/future.rb
CHANGED
@@ -48,6 +48,8 @@ module Cassandra
|
|
48
48
|
def initialize(error)
|
49
49
|
raise ::ArgumentError, "error must be an exception, #{error.inspect} given" unless error.is_a?(::Exception)
|
50
50
|
|
51
|
+
error.set_backtrace(caller) unless error.backtrace
|
52
|
+
|
51
53
|
@error = error
|
52
54
|
end
|
53
55
|
|
@@ -471,6 +473,8 @@ module Cassandra
|
|
471
473
|
raise ::ArgumentError, "error must be an exception, #{error.inspect} given"
|
472
474
|
end
|
473
475
|
|
476
|
+
error.set_backtrace(caller) unless error.backtrace
|
477
|
+
|
474
478
|
return unless @state == :pending
|
475
479
|
|
476
480
|
listeners = nil
|
data/lib/cassandra/keyspace.rb
CHANGED
@@ -106,6 +106,11 @@ module Cassandra
|
|
106
106
|
end
|
107
107
|
alias :== :eql?
|
108
108
|
|
109
|
+
# @return [String] a CLI-friendly keyspace representation
|
110
|
+
def inspect
|
111
|
+
"#<#{self.class.name}:0x#{self.object_id.to_s(16)} @name=#{@name}>"
|
112
|
+
end
|
113
|
+
|
109
114
|
# @private
|
110
115
|
def update_table(table)
|
111
116
|
tables = @tables.dup
|
@@ -60,8 +60,13 @@ module Cassandra
|
|
60
60
|
datacenter = datacenter && String(datacenter)
|
61
61
|
max_remote_hosts_to_use = max_remote_hosts_to_use && Integer(max_remote_hosts_to_use)
|
62
62
|
|
63
|
-
|
64
|
-
|
63
|
+
unless datacenter.nil?
|
64
|
+
Util.assert_not_empty(datacenter) { "datacenter cannot be empty" }
|
65
|
+
end
|
66
|
+
|
67
|
+
unless max_remote_hosts_to_use.nil?
|
68
|
+
Util.assert(max_remote_hosts_to_use >= 0) { "max_remote_hosts_to_use must be nil or >= 0" }
|
69
|
+
end
|
65
70
|
|
66
71
|
@datacenter = datacenter
|
67
72
|
@max_remote = max_remote_hosts_to_use
|
@@ -92,9 +92,7 @@ module Cassandra
|
|
92
92
|
def initialize(wrapped_policy)
|
93
93
|
methods = [:host_up, :host_down, :host_found, :host_lost, :distance, :plan]
|
94
94
|
|
95
|
-
|
96
|
-
raise ::ArgumentError, "supplied policy must be a Cassandra::LoadBalancing::Policy, #{wrapped_policy.inspect} given"
|
97
|
-
end
|
95
|
+
Util.assert_responds_to_all(methods, wrapped_policy) { "supplied policy must respond to #{methods.inspect}, but doesn't" }
|
98
96
|
|
99
97
|
@policy = wrapped_policy
|
100
98
|
end
|
@@ -35,12 +35,9 @@ module Cassandra
|
|
35
35
|
# @param wrapped_policy [Cassandra::LoadBalancing::Policy] actual policy to filter
|
36
36
|
# @raise [ArgumentError] if arguments are of unexpected types
|
37
37
|
def initialize(ips, wrapped_policy)
|
38
|
-
|
38
|
+
Util.assert_instance_of(::Enumerable, ips) { "ips must be an Enumerable, #{ips.inspect} given" }
|
39
39
|
methods = [:host_up, :host_down, :host_found, :host_lost, :distance, :plan]
|
40
|
-
|
41
|
-
unless methods.all? {|method| wrapped_policy.respond_to?(method)}
|
42
|
-
raise ::ArgumentError, "supplied policy must be a Cassandra::LoadBalancing::Policy, #{wrapped_policy.inspect} given"
|
43
|
-
end
|
40
|
+
Util.assert_responds_to_all(methods, wrapped_policy) { "supplied policy must respond to #{methods.inspect}, but doesn't" }
|
44
41
|
|
45
42
|
@ips = ::Set.new
|
46
43
|
@policy = wrapped_policy
|
@@ -52,7 +49,7 @@ module Cassandra
|
|
52
49
|
when ::String
|
53
50
|
@ips << ::IPAddr.new(ip)
|
54
51
|
else
|
55
|
-
raise ::ArgumentError, "
|
52
|
+
raise ::ArgumentError, "each ip must be a String or IPAddr, #{ip.inspect} given"
|
56
53
|
end
|
57
54
|
end
|
58
55
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2013-2014 DataStax, Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#++
|
18
|
+
|
19
|
+
module Cassandra
|
20
|
+
# @private
|
21
|
+
class NullLogger
|
22
|
+
def close(*); end
|
23
|
+
def debug(*); end
|
24
|
+
def debug?; false end
|
25
|
+
def error(*); end
|
26
|
+
def error?; false end
|
27
|
+
def fatal(*); end
|
28
|
+
def fatal?; false end
|
29
|
+
def info(*); end
|
30
|
+
def info?; false end
|
31
|
+
def unknown(*); end
|
32
|
+
def warn(*); end
|
33
|
+
def warn?; false end
|
34
|
+
end
|
35
|
+
end
|
@@ -344,6 +344,8 @@ module Cassandra
|
|
344
344
|
end
|
345
345
|
|
346
346
|
def schedule_heartbeat
|
347
|
+
return unless @heartbeat_interval
|
348
|
+
|
347
349
|
timer = nil
|
348
350
|
|
349
351
|
@lock.synchronize do
|
@@ -360,6 +362,8 @@ module Cassandra
|
|
360
362
|
end
|
361
363
|
|
362
364
|
def reschedule_termination
|
365
|
+
return unless @idle_timeout
|
366
|
+
|
363
367
|
timer = nil
|
364
368
|
|
365
369
|
@lock.synchronize do
|
@@ -39,11 +39,7 @@ module Cassandra
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def write(protocol_version, buffer)
|
42
|
-
|
43
|
-
buffer.append_long_string(@cql)
|
44
|
-
else
|
45
|
-
buffer.append_long_string(serialized_cql)
|
46
|
-
end
|
42
|
+
buffer.append_long_string(@cql)
|
47
43
|
buffer.append_consistency(@consistency)
|
48
44
|
if protocol_version > 1
|
49
45
|
flags = 0
|
@@ -108,12 +104,6 @@ module Cassandra
|
|
108
104
|
|
109
105
|
private
|
110
106
|
|
111
|
-
def serialized_cql
|
112
|
-
return @cql if @values.nil? || @values.empty?
|
113
|
-
i = -1
|
114
|
-
@cql.gsub('?') { Util.encode(@values[i += 1]) }
|
115
|
-
end
|
116
|
-
|
117
107
|
def self.guess_type(value)
|
118
108
|
type = TYPE_GUESSES[value.class]
|
119
109
|
if type == :map
|
data/lib/cassandra/result.rb
CHANGED
@@ -180,10 +180,9 @@ module Cassandra
|
|
180
180
|
# Returns true when there are no more pages to load.
|
181
181
|
#
|
182
182
|
# This is only relevant when you have requested paging of the results with
|
183
|
-
# the `:page_size` option to {Cassandra::
|
184
|
-
# {Cassandra::Client::PreparedStatement#execute}.
|
183
|
+
# the `:page_size` option to {Cassandra::Session#execute}.
|
185
184
|
#
|
186
|
-
# @see Cassandra::
|
185
|
+
# @see Cassandra::Session#execute
|
187
186
|
def last_page?
|
188
187
|
true
|
189
188
|
end
|
@@ -191,10 +190,9 @@ module Cassandra
|
|
191
190
|
# Returns the next page or nil when there is no next page.
|
192
191
|
#
|
193
192
|
# This is only relevant when you have requested paging of the results with
|
194
|
-
# the `:page_size` option to {Cassandra::
|
195
|
-
# {Cassandra::Client::PreparedStatement#execute}.
|
193
|
+
# the `:page_size` option to {Cassandra::Session#execute_async}.
|
196
194
|
#
|
197
|
-
# @see Cassandra::
|
195
|
+
# @see Cassandra::Session#execute_async
|
198
196
|
def next_page_async(options = nil)
|
199
197
|
@futures.value(nil)
|
200
198
|
end
|
data/lib/cassandra/session.rb
CHANGED
@@ -61,6 +61,9 @@ module Cassandra
|
|
61
61
|
# Therefore, make sure to pass empty `options` when executing a statement
|
62
62
|
# with the last parameter required to be a map datatype.
|
63
63
|
#
|
64
|
+
# @note Positional arguments are only supported on Apache Cassandra 2.0 and
|
65
|
+
# above.
|
66
|
+
#
|
64
67
|
# @return [Cassandra::Future<Cassandra::Result>]
|
65
68
|
#
|
66
69
|
# @see Cassandra::Session#execute A list of errors this future can be
|
@@ -50,7 +50,11 @@ module Cassandra
|
|
50
50
|
# original cql passed to {Cassandra::Session#prepare}
|
51
51
|
# @return [Cassandra::Statements::Bound] bound statement
|
52
52
|
def bind(*args)
|
53
|
-
|
53
|
+
Util.assert_equal(@params_metadata.size, args.size) { "expecting exactly #{@params_metadata.size} bind parameters, #{args.size} given" }
|
54
|
+
|
55
|
+
@params_metadata.each_with_index do |metadata, i|
|
56
|
+
Util.assert_type(metadata[3], args[i]) { "argument for #{metadata[2].inspect} must be #{metadata[3].inspect}, #{args[i]} given" }
|
57
|
+
end
|
54
58
|
|
55
59
|
return Bound.new(@cql, @params_metadata, @result_metadata, args) if @params_metadata.empty?
|
56
60
|
|
data/lib/cassandra/table.rb
CHANGED
@@ -231,6 +231,11 @@ module Cassandra
|
|
231
231
|
cql << ';'
|
232
232
|
end
|
233
233
|
|
234
|
+
# @return [String] a CLI-friendly table representation
|
235
|
+
def inspect
|
236
|
+
"#<#{self.class.name}:0x#{self.object_id.to_s(16)} @keyspace=#{@keyspace} @name=#{@name}>"
|
237
|
+
end
|
238
|
+
|
234
239
|
# @return [Boolean] whether this table is equal to the other
|
235
240
|
def eql?(other)
|
236
241
|
other.is_a?(Table) &&
|
data/lib/cassandra/util.rb
CHANGED
@@ -137,6 +137,136 @@ module Cassandra
|
|
137
137
|
DBL_QUOT + name + DBL_QUOT
|
138
138
|
end
|
139
139
|
|
140
|
+
def assert_type(type, value, message = nil, &block)
|
141
|
+
return if value.nil?
|
142
|
+
|
143
|
+
case type
|
144
|
+
when ::Array
|
145
|
+
case type.first
|
146
|
+
when :list
|
147
|
+
assert_instance_of(::Array, value, message, &block)
|
148
|
+
value.each do |v|
|
149
|
+
assert_type(type[1], v)
|
150
|
+
end
|
151
|
+
when :set
|
152
|
+
assert_instance_of(::Set, value, message, &block)
|
153
|
+
value.each do |v|
|
154
|
+
assert_type(type[1], v)
|
155
|
+
end
|
156
|
+
when :map
|
157
|
+
assert_instance_of(::Hash, value, message, &block)
|
158
|
+
value.each do |k, v|
|
159
|
+
assert_type(type[1], k)
|
160
|
+
assert_type(type[2], v)
|
161
|
+
end
|
162
|
+
else
|
163
|
+
raise ::RuntimeError, "unsupported complex type #{type.inspect}"
|
164
|
+
end
|
165
|
+
else
|
166
|
+
case type
|
167
|
+
when :ascii then assert_instance_of(::String, value, message, &block)
|
168
|
+
when :bigint then assert_instance_of(::Numeric, value, message, &block)
|
169
|
+
when :blob then assert_instance_of(::String, value, message, &block)
|
170
|
+
when :boolean then assert_instance_of_one_of([::TrueClass, ::FalseClass], value, message, &block)
|
171
|
+
when :counter then assert_instance_of(::Numeric, value, message, &block)
|
172
|
+
when :decimal then assert_instance_of(::BigDecimal, value, message, &block)
|
173
|
+
when :double then assert_instance_of(::Float, value, message, &block)
|
174
|
+
when :float then assert_instance_of(::Float, value, message, &block)
|
175
|
+
when :inet then assert_instance_of(::IPAddr, value, message, &block)
|
176
|
+
when :int then assert_instance_of(::Numeric, value, message, &block)
|
177
|
+
when :text then assert_instance_of(::String, value, message, &block)
|
178
|
+
when :varchar then assert_instance_of(::String, value, message, &block)
|
179
|
+
when :timestamp then assert_instance_of(::Time, value, message, &block)
|
180
|
+
when :timeuuid then assert_instance_of(TimeUuid, value, message, &block)
|
181
|
+
when :uuid then assert_instance_of(Uuid, value, message, &block)
|
182
|
+
when :varint then assert_instance_of(::Numeric, value, message, &block)
|
183
|
+
else
|
184
|
+
raise ::RuntimeError, "unsupported type #{type.inspect}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def assert_instance_of(kind, value, message = nil, &block)
|
190
|
+
unless value.is_a?(kind)
|
191
|
+
message = yield if block_given?
|
192
|
+
message ||= "value must be an instance of #{kind}, #{value.inspect} given"
|
193
|
+
|
194
|
+
raise ::ArgumentError, message
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def assert_instance_of_one_of(kinds, value, message = nil, &block)
|
199
|
+
unless kinds.any? {|kind| value.is_a?(kind)}
|
200
|
+
message = yield if block_given?
|
201
|
+
message ||= "value must be an instance of one of #{kinds.inspect}, #{value.inspect} given"
|
202
|
+
|
203
|
+
raise ::ArgumentError, message
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def assert_responds_to(method, value, message = nil, &block)
|
208
|
+
unless value.respond_to?(method)
|
209
|
+
message = yield if block_given?
|
210
|
+
message ||= "value #{value.inspect} must respond to #{method.inspect}, but doesn't"
|
211
|
+
|
212
|
+
raise ::ArgumentError, message
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def assert_responds_to_all(methods, value, message = nil, &block)
|
217
|
+
unless methods.all? {|method| value.respond_to?(method)}
|
218
|
+
message = yield if block_given?
|
219
|
+
message ||= "value #{value.inspect} must respond to all methods #{methods.inspect}, but doesn't"
|
220
|
+
|
221
|
+
raise ::ArgumentError, message
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def assert_not_empty(value, message = nil, &block)
|
226
|
+
if value.empty?
|
227
|
+
message = yield if block_given?
|
228
|
+
message ||= "value cannot be empty"
|
229
|
+
|
230
|
+
raise ::ArgumentError, message
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def assert_file_exists(path, message = nil, &block)
|
235
|
+
unless ::File.exists?(path)
|
236
|
+
message = yield if block_given?
|
237
|
+
message ||= "expected file at #{path.inspect} to exist, but it doesn't"
|
238
|
+
|
239
|
+
raise ::ArgumentError, message
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def assert_one_of(range, value, message = nil, &block)
|
244
|
+
unless range.include?(value)
|
245
|
+
message = yield if block_given?
|
246
|
+
message ||= "value must be included in #{value.inspect}, #{value.inspect} given"
|
247
|
+
|
248
|
+
raise ::ArgumentError, message
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def assert(condition, message = nil, &block)
|
253
|
+
unless condition
|
254
|
+
message = yield if block_given?
|
255
|
+
message ||= "assertion failed"
|
256
|
+
|
257
|
+
raise ::ArgumentError, message
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def assert_equal(expected, actual, message = nil, &block)
|
262
|
+
unless expected == actual
|
263
|
+
message = yield if block_given?
|
264
|
+
message ||= "expected #{actual.inspect} to equal #{expected.inspect}"
|
265
|
+
|
266
|
+
raise ::ArgumentError, message
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
140
270
|
# @private
|
141
271
|
LOWERCASE_REGEXP = /[[:lower:]\_]*/
|
142
272
|
# @private
|
data/lib/cassandra/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cassandra-driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Theo Hultberg
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ione
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.2
|
20
|
+
version: '1.2'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ~>
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.2
|
27
|
+
version: '1.2'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: bundler
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,24 +75,12 @@ files:
|
|
75
75
|
- lib/cassandra/auth.rb
|
76
76
|
- lib/cassandra/auth/providers.rb
|
77
77
|
- lib/cassandra/auth/providers/password.rb
|
78
|
-
- lib/cassandra/client.rb
|
79
|
-
- lib/cassandra/client/batch.rb
|
80
|
-
- lib/cassandra/client/client.rb
|
81
|
-
- lib/cassandra/client/column_metadata.rb
|
82
|
-
- lib/cassandra/client/connection_manager.rb
|
83
|
-
- lib/cassandra/client/connector.rb
|
84
|
-
- lib/cassandra/client/execute_options_decoder.rb
|
85
|
-
- lib/cassandra/client/null_logger.rb
|
86
|
-
- lib/cassandra/client/peer_discovery.rb
|
87
|
-
- lib/cassandra/client/prepared_statement.rb
|
88
|
-
- lib/cassandra/client/query_result.rb
|
89
|
-
- lib/cassandra/client/request_runner.rb
|
90
|
-
- lib/cassandra/client/result_metadata.rb
|
91
|
-
- lib/cassandra/client/void_result.rb
|
92
78
|
- lib/cassandra/cluster.rb
|
93
79
|
- lib/cassandra/cluster/client.rb
|
80
|
+
- lib/cassandra/cluster/connection_pool.rb
|
94
81
|
- lib/cassandra/cluster/connector.rb
|
95
82
|
- lib/cassandra/cluster/control_connection.rb
|
83
|
+
- lib/cassandra/cluster/failed_connection.rb
|
96
84
|
- lib/cassandra/cluster/metadata.rb
|
97
85
|
- lib/cassandra/cluster/options.rb
|
98
86
|
- lib/cassandra/cluster/registry.rb
|
@@ -125,6 +113,7 @@ files:
|
|
125
113
|
- lib/cassandra/load_balancing/policies/round_robin.rb
|
126
114
|
- lib/cassandra/load_balancing/policies/token_aware.rb
|
127
115
|
- lib/cassandra/load_balancing/policies/white_list.rb
|
116
|
+
- lib/cassandra/null_logger.rb
|
128
117
|
- lib/cassandra/protocol.rb
|
129
118
|
- lib/cassandra/protocol/cql_byte_buffer.rb
|
130
119
|
- lib/cassandra/protocol/cql_protocol_handler.rb
|
@@ -205,9 +194,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
205
194
|
version: 1.9.3
|
206
195
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
207
196
|
requirements:
|
208
|
-
- - ! '
|
197
|
+
- - ! '>='
|
209
198
|
- !ruby/object:Gem::Version
|
210
|
-
version:
|
199
|
+
version: '0'
|
211
200
|
requirements: []
|
212
201
|
rubyforge_project:
|
213
202
|
rubygems_version: 2.4.2
|