cassandra-driver 0.1.0.alpha1 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/.yardopts +4 -0
  2. data/README.md +117 -0
  3. data/lib/cassandra.rb +320 -0
  4. data/lib/cassandra/auth.rb +97 -0
  5. data/lib/cassandra/auth/providers.rb +16 -0
  6. data/lib/cassandra/auth/providers/password.rb +73 -0
  7. data/lib/cassandra/client.rb +144 -0
  8. data/lib/cassandra/client/batch.rb +212 -0
  9. data/lib/cassandra/client/client.rb +591 -0
  10. data/lib/cassandra/client/column_metadata.rb +54 -0
  11. data/lib/cassandra/client/connection_manager.rb +72 -0
  12. data/lib/cassandra/client/connector.rb +272 -0
  13. data/lib/cassandra/client/execute_options_decoder.rb +59 -0
  14. data/lib/cassandra/client/null_logger.rb +37 -0
  15. data/lib/cassandra/client/peer_discovery.rb +50 -0
  16. data/lib/cassandra/client/prepared_statement.rb +314 -0
  17. data/lib/cassandra/client/query_result.rb +230 -0
  18. data/lib/cassandra/client/request_runner.rb +71 -0
  19. data/lib/cassandra/client/result_metadata.rb +48 -0
  20. data/lib/cassandra/client/void_result.rb +78 -0
  21. data/lib/cassandra/cluster.rb +191 -0
  22. data/lib/cassandra/cluster/client.rb +767 -0
  23. data/lib/cassandra/cluster/connector.rb +231 -0
  24. data/lib/cassandra/cluster/control_connection.rb +420 -0
  25. data/lib/cassandra/cluster/options.rb +40 -0
  26. data/lib/cassandra/cluster/registry.rb +181 -0
  27. data/lib/cassandra/cluster/schema.rb +321 -0
  28. data/lib/cassandra/cluster/schema/type_parser.rb +138 -0
  29. data/lib/cassandra/column.rb +92 -0
  30. data/lib/cassandra/compression.rb +66 -0
  31. data/lib/cassandra/compression/compressors/lz4.rb +72 -0
  32. data/lib/cassandra/compression/compressors/snappy.rb +66 -0
  33. data/lib/cassandra/driver.rb +86 -0
  34. data/lib/cassandra/errors.rb +79 -0
  35. data/lib/cassandra/execution/info.rb +51 -0
  36. data/lib/cassandra/execution/options.rb +77 -0
  37. data/lib/cassandra/execution/trace.rb +152 -0
  38. data/lib/cassandra/future.rb +675 -0
  39. data/lib/cassandra/host.rb +75 -0
  40. data/lib/cassandra/keyspace.rb +120 -0
  41. data/lib/cassandra/listener.rb +87 -0
  42. data/lib/cassandra/load_balancing.rb +112 -0
  43. data/lib/cassandra/load_balancing/policies.rb +18 -0
  44. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +149 -0
  45. data/lib/cassandra/load_balancing/policies/round_robin.rb +95 -0
  46. data/lib/cassandra/load_balancing/policies/white_list.rb +90 -0
  47. data/lib/cassandra/protocol.rb +93 -0
  48. data/lib/cassandra/protocol/cql_byte_buffer.rb +307 -0
  49. data/lib/cassandra/protocol/cql_protocol_handler.rb +323 -0
  50. data/lib/cassandra/protocol/frame_decoder.rb +128 -0
  51. data/lib/cassandra/protocol/frame_encoder.rb +48 -0
  52. data/lib/cassandra/protocol/request.rb +38 -0
  53. data/lib/cassandra/protocol/requests/auth_response_request.rb +47 -0
  54. data/lib/cassandra/protocol/requests/batch_request.rb +76 -0
  55. data/lib/cassandra/protocol/requests/credentials_request.rb +47 -0
  56. data/lib/cassandra/protocol/requests/execute_request.rb +103 -0
  57. data/lib/cassandra/protocol/requests/options_request.rb +39 -0
  58. data/lib/cassandra/protocol/requests/prepare_request.rb +50 -0
  59. data/lib/cassandra/protocol/requests/query_request.rb +153 -0
  60. data/lib/cassandra/protocol/requests/register_request.rb +38 -0
  61. data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
  62. data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
  63. data/lib/cassandra/protocol/response.rb +38 -0
  64. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +41 -0
  65. data/lib/cassandra/protocol/responses/auth_success_response.rb +41 -0
  66. data/lib/cassandra/protocol/responses/authenticate_response.rb +41 -0
  67. data/lib/cassandra/protocol/responses/detailed_error_response.rb +60 -0
  68. data/lib/cassandra/protocol/responses/error_response.rb +50 -0
  69. data/lib/cassandra/protocol/responses/event_response.rb +39 -0
  70. data/lib/cassandra/protocol/responses/prepared_result_response.rb +64 -0
  71. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +43 -0
  72. data/lib/cassandra/protocol/responses/ready_response.rb +44 -0
  73. data/lib/cassandra/protocol/responses/result_response.rb +48 -0
  74. data/lib/cassandra/protocol/responses/rows_result_response.rb +139 -0
  75. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +60 -0
  76. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +57 -0
  77. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +42 -0
  78. data/lib/cassandra/protocol/responses/status_change_event_response.rb +44 -0
  79. data/lib/cassandra/protocol/responses/supported_response.rb +41 -0
  80. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +34 -0
  81. data/lib/cassandra/protocol/responses/void_result_response.rb +39 -0
  82. data/lib/cassandra/protocol/type_converter.rb +384 -0
  83. data/lib/cassandra/reconnection.rb +49 -0
  84. data/lib/cassandra/reconnection/policies.rb +20 -0
  85. data/lib/cassandra/reconnection/policies/constant.rb +48 -0
  86. data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
  87. data/lib/cassandra/result.rb +215 -0
  88. data/lib/cassandra/retry.rb +142 -0
  89. data/lib/cassandra/retry/policies.rb +21 -0
  90. data/lib/cassandra/retry/policies/default.rb +47 -0
  91. data/lib/cassandra/retry/policies/downgrading_consistency.rb +71 -0
  92. data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
  93. data/lib/cassandra/session.rb +195 -0
  94. data/lib/cassandra/statement.rb +22 -0
  95. data/lib/cassandra/statements.rb +23 -0
  96. data/lib/cassandra/statements/batch.rb +95 -0
  97. data/lib/cassandra/statements/bound.rb +46 -0
  98. data/lib/cassandra/statements/prepared.rb +59 -0
  99. data/lib/cassandra/statements/simple.rb +58 -0
  100. data/lib/cassandra/statements/void.rb +33 -0
  101. data/lib/cassandra/table.rb +254 -0
  102. data/lib/cassandra/time_uuid.rb +141 -0
  103. data/lib/cassandra/util.rb +169 -0
  104. data/lib/cassandra/uuid.rb +104 -0
  105. data/lib/cassandra/version.rb +17 -1
  106. metadata +134 -8
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ --markup markdown
3
+ lib/**/*.rb
4
+ -- README
@@ -0,0 +1,117 @@
1
+ # Datastax Ruby Driver for Apache Cassandra
2
+
3
+ [![Build Status](https://travis-ci.org/datastax/ruby-driver.svg?branch=master)](https://travis-ci.org/datastax/ruby-driver)
4
+
5
+ A Ruby client driver for Apache Cassandra. This driver works exclusively with
6
+ the Cassandra Query Language version 3 (CQL3) and Cassandra's native protocol.
7
+
8
+ - Code: https://github.com/datastax/ruby-driver
9
+ - Docs: http://datastax.github.io/ruby-driver/
10
+ - JIRA: https://datastax-oss.atlassian.net/browse/RUBY
11
+ - MAILING LIST: https://groups.google.com/a/lists.datastax.com/forum/#!forum/ruby-driver-user
12
+ - IRC: #datastax-drivers on [irc.freenode.net](http://freenode.net>)
13
+ - TWITTER: Follow the latest news about DataStax Drivers - [@avalanche123](http://twitter.com/avalanche123), [@mfiguiere](http://twitter.com/mfiguiere), [@al3xandru](https://twitter.com/al3xandru)
14
+
15
+ This driver is based on [the cql-rb gem](https://github.com/iconara/cql-rb) by [Theo Hultberg](https://github.com/iconara) and we addded support for:
16
+
17
+ * [asynchronous execution](/features/asynchronous_io/)
18
+ * one-off, [prepared](/features/prepared_statements/) and [batch statements](/features/batch_statements/)
19
+ * automatic peer discovery and cluster metadata
20
+ * various [load-balancing](/features/load_balancing/), [retry](/features/retry_policies/) and reconnection policies, [with ability to write your own](/features/load_balancing/implementing_a_policy/)
21
+
22
+ ## Compability
23
+
24
+ This driver works exclusively with the Cassandra Query Language v3 (CQL3) and Cassandra's native protocol. The current version works with:
25
+
26
+ * Cassandra versions 1.2 and 2.0
27
+ * Ruby 1.9.3 and 2.0
28
+ * JRuby 1.7
29
+ * Rubinius 2.1
30
+
31
+ __Note__: JRuby 1.6 is not officially supported, although 1.6.8 should work.
32
+
33
+ ## Quick start
34
+
35
+ ```ruby
36
+ require 'cassandra'
37
+
38
+ cluster = Cassandra.connect # connects to localhost by default
39
+
40
+ cluster.each_hosts do |host| # automatically discovers all peers
41
+ puts "Host #{host.ip}: id=#{host.id} datacenter=#{host.datacenter} rack=#{host.rack}"
42
+ end
43
+
44
+ keyspace = 'system'
45
+ session = cluster.connect(keyspace) # create session, optionally scoped to a keyspace, to execute queries
46
+
47
+ future = session.execute_async('SELECT keyspace_name, columnfamily_name FROM schema_columnfamilies') # fully asynchronous api
48
+ future.on_success do |rows|
49
+ rows.each do |row|
50
+ puts "The keyspace #{row['keyspace_name']} has a table called #{row['columnfamily_name']}"
51
+ end
52
+ end
53
+ future.join
54
+ ```
55
+
56
+ The host you specify is just a seed node, the driver will automatically discover all peers in the cluster.
57
+
58
+ Read more:
59
+
60
+ * [`Cql.connect` options](/api/#connect-class_method)
61
+ * [`Session#execute_async` options](/api/session/#execute_async-instance_method)
62
+ * [Usage documentation](/features)
63
+
64
+ ## Installation
65
+
66
+ Install via rubygems
67
+
68
+ ```bash
69
+ gem install cassandra-driver
70
+ ```
71
+
72
+ Install via Gemfile
73
+
74
+ ```ruby
75
+ gem 'cassandra-driver'
76
+ ```
77
+
78
+ Note: if you want to use compression you should also install [snappy](http://rubygems.org/gems/snappy) or [lz4-ruby](http://rubygems.org/gems/lz4-ruby). [Read more about compression.](/features/#compression)
79
+
80
+
81
+ ## Upgrading from cql-rb
82
+
83
+ Some of the new features added to the driver have unfortunately led to changes in the original cql-rb API. In the examples directory, you can find [an example of how to wrap the ruby driver to achieve almost complete interface parity with cql-rb](https://github.com/datastax/ruby-driver/blob/master/examples/cql-rb-wrapper.rb) to assist you with gradual upgrade.
84
+
85
+ ## Changelog & versioning
86
+
87
+ Check out the [releases on GitHub](https://github.com/datastax/ruby-driver/releases). Version numbering follows the [semantic versioning](http://semver.org/) scheme.
88
+
89
+ Private and experimental APIs, defined as whatever is not in the [public API documentation][1], i.e. classes and methods marked as `@private`, will change without warning. If you've been recommended to try an experimental API by the maintainers, please let them know if you depend on that API. Experimental APIs will eventually become public, and knowing how they are used helps in determining their maturity.
90
+
91
+ Prereleases will be stable, in the sense that they will have finished and properly tested features only, but may introduce APIs that will change before the final release. Please use the prereleases and report bugs, but don't deploy them to production without consulting the maintainers, or doing extensive testing yourself. If you do deploy to production please let the maintainers know as this helps determining the maturity of the release.
92
+
93
+ ## Known bugs & limitations
94
+
95
+ * JRuby 1.6 is not officially supported, although 1.6.8 should work, if you're stuck in JRuby 1.6.8 try and see if it works for you.
96
+ * Because the driver reactor is using `IO.select`, the maximum number of tcp connections allowed is 1024.
97
+
98
+
99
+ ## Credits
100
+
101
+ This driver is based on the original work of [Theo Hultberg](https://github.com/iconara) on [cql-rb](https://github.com/iconara/cql-rb/) and adds a series of advanced features that are common across all other DataStax drivers for Apache Cassandra.
102
+
103
+ The development effort to provide an up to date, high performance, fully featured Ruby Driver for Apache Cassandra will continue on this project, while [cql-rb](https://github.com/iconara/cql-rb/) will be discontinued.
104
+
105
+
106
+ ## Copyright
107
+
108
+ Copyright 2013-2014 DataStax, Inc.
109
+
110
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
111
+
112
+ [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
113
+
114
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
115
+
116
+ [1]: http://datastax.github.io/ruby-driver/api
117
+
@@ -0,0 +1,320 @@
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
+
20
+ require 'ione'
21
+ require 'json'
22
+
23
+ require 'monitor'
24
+ require 'ipaddr'
25
+ require 'set'
26
+ require 'bigdecimal'
27
+ require 'forwardable'
28
+ require 'timeout'
29
+
30
+ module Cassandra
31
+ # A list of all supported request consistencies
32
+ # @see Cassandra::Session#execute_async
33
+ CONSISTENCIES = [ :any, :one, :two, :three, :quorum, :all, :local_quorum,
34
+ :each_quorum, :serial, :local_serial, :local_one ].freeze
35
+
36
+ # A list of all supported serial consistencies
37
+ # @see Cassandra::Session#execute_async
38
+ SERIAL_CONSISTENCIES = [:serial, :local_serial].freeze
39
+
40
+ # Creates a {Cassandra::Cluster} instance
41
+ #
42
+ # @option options [Array<String, IPAddr>] :hosts (['127.0.0.1']) a list of
43
+ # initial addresses. Note that the entire list of cluster members will be
44
+ # discovered automatically once a connection to any hosts from the original
45
+ # list is successful
46
+ #
47
+ # @option options [Integer] :port (9042) cassandra native protocol port
48
+ #
49
+ # @option options [String] :username (none) username to use for
50
+ # authentication to cassandra. Note that you must also specify `:password`
51
+ #
52
+ # @option options [String] :password (none) password to use for
53
+ # authentication to cassandra. Note that you must also specify `:username`
54
+ #
55
+ # @option options [Symbol] :compression (none) compression to use. Must be
56
+ # either `:snappy` or `:lz4`. Also note, that in order for compression to
57
+ # work, you must install 'snappy' or 'lz4-ruby' gems
58
+ #
59
+ # @option options [Cassandra::LoadBalancing::Policy] :load_balancing_policy
60
+ # default: {Cassandra::LoadBalancing::Policies::RoundRobin}
61
+ #
62
+ # @option options [Cassandra::Reconnection::Policy] :reconnection_policy
63
+ # default: {Cassandra::Reconnection::Policies::Exponential}. Note that the
64
+ # default policy is configured with
65
+ # `Reconnection::Policies::Exponential.new(0.5, 30, 2)`
66
+ #
67
+ # @option options [Cassandra::Retry::Policy] :retry_policy default:
68
+ # {Cassandra::Retry::Policies::Default}
69
+ #
70
+ # @option options [Logger] :logger (none) logger. a {Logger} instance from the
71
+ # standard library or any object responding to standard log methods
72
+ # (`#debug`, `#info`, `#warn`, `#error` and `#fatal`)
73
+ #
74
+ # @option options [Enumerable<Cassandra::Listener>] :listeners (none)
75
+ # initial listeners. A list of initial cluster state listeners. Note that a
76
+ # load_balancing policy is automatically registered with the cluster.
77
+ #
78
+ # @option options [Symbol] :consistency (:quorum) default consistency to use
79
+ # for all requests. Must be one of {Cassandra::CONSISTENCIES}
80
+ #
81
+ # @option options [Boolean] :trace (false) whether or not to trace all
82
+ # requests by default
83
+ #
84
+ # @option options [Integer] :page_size (nil) default page size for all select
85
+ # queries
86
+ #
87
+ # @option options [Hash{String => String}] :credentials (none) a hash of credentials - to be used with [credentials authentication in cassandra 1.2](https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L238-L250). Note that if you specified `:username` and `:password` options, those credentials are configured automatically
88
+ #
89
+ # @option options [Cassandra::Auth::Provider] :auth_provider (none) a custom auth provider to be used with [SASL authentication in cassandra 2.0](https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v2.spec#L257-L273). Note that if you have specified `:username` and `:password`, then a {Cassandra::Auth::Providers::Password} will be used automatically
90
+ #
91
+ # @option options [Cassandra::Compressor] :compressor (none) a custom
92
+ # compressor. Note that if you have specified `:compression`, an
93
+ # appropriate compressor will be provided automatically
94
+ #
95
+ # @option options [Object<#all, #error, #value, #promise>] :futures_factory
96
+ # (none) a custom futures factory to assist with integration into existing
97
+ # futures library. Note that promises returned by this object must conform
98
+ # to {Cassandra::Promise} api, which is not yet public. Things may change,
99
+ # use at your own risk.
100
+ #
101
+ # @example Connecting to localhost
102
+ # cluster = Cassandra.connect
103
+ #
104
+ # @example Configuring {Cassandra::Cluster}
105
+ # cluster = Cassandra.connect(
106
+ # username: username,
107
+ # password: password,
108
+ # hosts: ['10.0.1.1', '10.0.1.2', '10.0.1.3']
109
+ # )
110
+ #
111
+ # @return [Cassandra::Cluster] a cluster instance
112
+ def self.connect(options = {})
113
+ options.select! do |key, value|
114
+ [ :credentials, :auth_provider, :compression, :hosts, :logger, :port,
115
+ :load_balancing_policy, :reconnection_policy, :retry_policy, :listeners,
116
+ :consistency, :trace, :page_size, :compressor, :username, :password,
117
+ :futures_factory
118
+ ].include?(key)
119
+ end
120
+
121
+ has_username = options.has_key?(:username)
122
+ has_password = options.has_key?(:password)
123
+ if has_username || has_password
124
+ if has_username && !has_password
125
+ raise ::ArgumentError, "both :username and :password options must be specified, but only :username given"
126
+ end
127
+
128
+ if !has_username && has_password
129
+ raise ::ArgumentError, "both :username and :password options must be specified, but only :password given"
130
+ end
131
+
132
+ username = String(options.delete(:username))
133
+ password = String(options.delete(:password))
134
+
135
+ raise ::ArgumentError, ":username cannot be empty" if username.empty?
136
+ raise ::ArgumentError, ":password cannot be empty" if password.empty?
137
+
138
+ options[:credentials] = {:username => username, :password => password}
139
+ options[:auth_provider] = Auth::Providers::Password.new(username, password)
140
+ end
141
+
142
+ if options.has_key?(:credentials)
143
+ credentials = options[:credentials]
144
+
145
+ unless credentials.is_a?(Hash)
146
+ raise ::ArgumentError, ":credentials must be a hash, #{credentials.inspect} given"
147
+ end
148
+ end
149
+
150
+ if options.has_key?(:auth_provider)
151
+ auth_provider = options[:auth_provider]
152
+
153
+ unless auth_provider.respond_to?(:create_authenticator)
154
+ raise ::ArgumentError, ":auth_provider #{auth_provider.inspect} must respond to :create_authenticator, but doesn't"
155
+ end
156
+ end
157
+
158
+ if options.has_key?(:compression)
159
+ compression = options.delete(:compression)
160
+
161
+ case compression
162
+ when :snappy
163
+ require 'cassandra/compression/compressors/snappy'
164
+ options[:compressor] = Compression::Compressors::Snappy.new
165
+ when :lz4
166
+ require 'cassandra/compression/compressors/lz4'
167
+ options[:compressor] = Compression::Compressors::Lz4.new
168
+ else
169
+ raise ::ArgumentError, ":compression must be either :snappy or :lz4, #{compression.inspect} given"
170
+ end
171
+ end
172
+
173
+ if options.has_key?(:compressor)
174
+ compressor = options[:compressor]
175
+ methods = [:algorithm, :compress?, :compress, :decompress]
176
+
177
+ unless methods.all? {|method| compressor.respond_to?(method)}
178
+ raise ::ArgumentError, ":compressor #{compressor.inspect} must respond to #{methods.inspect}, but doesn't"
179
+ end
180
+ end
181
+
182
+ if options.has_key?(:logger)
183
+ logger = options[:logger]
184
+ methods = [:debug, :info, :warn, :error, :fatal]
185
+
186
+ unless methods.all? {|method| logger.respond_to?(method)}
187
+ raise ::ArgumentError, ":logger #{logger.inspect} must respond to #{methods.inspect}, but doesn't"
188
+ end
189
+ end
190
+
191
+ if options.has_key?(:port)
192
+ port = options[:port] = Integer(options[:port])
193
+
194
+ if port < 0 || port > 65536
195
+ raise ::ArgumentError, ":port must be a valid ip port, #{port.given}"
196
+ end
197
+ end
198
+
199
+ if options.has_key?(:load_balancing_policy)
200
+ load_balancing_policy = options[:load_balancing_policy]
201
+ methods = [:host_up, :host_down, :host_found, :host_lost, :distance, :plan]
202
+
203
+ unless methods.all? {|method| load_balancing_policy.respond_to?(method)}
204
+ raise ::ArgumentError, ":load_balancing_policy #{load_balancing_policy.inspect} must respond to #{methods.inspect}, but doesn't"
205
+ end
206
+ end
207
+
208
+ if options.has_key?(:reconnection_policy)
209
+ reconnection_policy = options[:reconnection_policy]
210
+
211
+ unless reconnection_policy.respond_to?(:schedule)
212
+ raise ::ArgumentError, ":reconnection_policy #{reconnection_policy.inspect} must respond to :schedule, but doesn't"
213
+ end
214
+ end
215
+
216
+ if options.has_key?(:retry_policy)
217
+ retry_policy = options[:retry_policy]
218
+ methods = [:read_timeout, :write_timeout, :unavailable]
219
+
220
+ unless methods.all? {|method| retry_policy.respond_to?(method)}
221
+ raise ::ArgumentError, ":retry_policy #{retry_policy.inspect} must respond to #{methods.inspect}, but doesn't"
222
+ end
223
+ end
224
+
225
+ if options.has_key?(:listeners)
226
+ listeners = options[:listeners]
227
+
228
+ unless listeners.respond_to?(:each)
229
+ raise ::ArgumentError, ":listeners must be an Enumerable, #{listeners.inspect} given"
230
+ end
231
+ end
232
+
233
+ if options.has_key?(:consistency)
234
+ consistency = options[:consistency]
235
+
236
+ unless CONSISTENCIES.include?(consistency)
237
+ raise ::ArgumentError, ":consistency must be one of #{CONSISTENCIES.inspect}, #{consistency.inspect} given"
238
+ end
239
+ end
240
+
241
+ if options.has_key?(:trace)
242
+ options[:trace] = !!options[:trace]
243
+ end
244
+
245
+ if options.has_key?(:page_size)
246
+ page_size = options[:page_size] = Integer(options[:page_size])
247
+
248
+ if page_size <= 0
249
+ raise ::ArgumentError, ":page_size must be a positive integer, #{page_size.inspect} given"
250
+ end
251
+ end
252
+
253
+ if options.has_key?(:futures_factory)
254
+ futures_factory = options[:futures_factory]
255
+ methods = [:error, :value, :promise, :all]
256
+
257
+ unless methods.all? {|method| futures_factory.respond_to?(method)}
258
+ raise ::ArgumentError, ":futures_factory #{futures_factory.inspect} must respond to #{methods.inspect}, but doesn't"
259
+ end
260
+ end
261
+
262
+ hosts = options.fetch(:hosts, [])
263
+ hosts << ::IPAddr.new('127.0.0.1') if hosts.empty?
264
+
265
+ hosts.map! do |host|
266
+ case host
267
+ when ::IPAddr
268
+ host
269
+ when ::String
270
+ ::IPAddr.new(host)
271
+ else
272
+ raise ::ArgumentError, ":hosts must be String or IPAddr, #{host.inspect} given"
273
+ end
274
+ end
275
+
276
+ Driver.new(options).connect(hosts).value
277
+ end
278
+ end
279
+
280
+ require 'cassandra/errors'
281
+ require 'cassandra/uuid'
282
+ require 'cassandra/time_uuid'
283
+ require 'cassandra/compression'
284
+ require 'cassandra/protocol'
285
+ require 'cassandra/auth'
286
+ require 'cassandra/client'
287
+
288
+ require 'cassandra/future'
289
+ require 'cassandra/cluster'
290
+ require 'cassandra/driver'
291
+ require 'cassandra/host'
292
+ require 'cassandra/session'
293
+ require 'cassandra/result'
294
+ require 'cassandra/statement'
295
+ require 'cassandra/statements'
296
+
297
+ require 'cassandra/column'
298
+ require 'cassandra/table'
299
+ require 'cassandra/keyspace'
300
+
301
+ require 'cassandra/execution/info'
302
+ require 'cassandra/execution/options'
303
+ require 'cassandra/execution/trace'
304
+
305
+ require 'cassandra/load_balancing'
306
+ require 'cassandra/reconnection'
307
+ require 'cassandra/retry'
308
+
309
+ require 'cassandra/util'
310
+
311
+ module Cassandra
312
+ # @private
313
+ Io = Ione::Io
314
+ # @private
315
+ VOID_STATEMENT = Statements::Void.new
316
+ # @private
317
+ VOID_OPTIONS = Execution::Options.new({:consistency => :one})
318
+ # @private
319
+ NO_HOSTS = Errors::NoHostsAvailable.new
320
+ end
@@ -0,0 +1,97 @@
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
+ module Auth
21
+ # An auth provider is a factory for {Cassandra::Auth::Authenticator} instances
22
+ # (or objects matching that interface). Its {#create_authenticator} will be
23
+ # called once for each connection that requires authentication.
24
+ #
25
+ # If the authentication requires keeping state, keep that in the
26
+ # authenticator instances, not in the auth provider.
27
+ #
28
+ # @note Creating an authenticator must absolutely not block, or the whole
29
+ # connection process will block.
30
+ #
31
+ # @abstract Auth providers given to {Cassandra.connect} don't need to be
32
+ # subclasses of this class, but need to implement the same methods. This
33
+ # class exists only for documentation purposes.
34
+ #
35
+ # @see Cassandra::Auth::Providers
36
+ class Provider
37
+ # @!method create_authenticator(authentication_class, protocol_version)
38
+ #
39
+ # Create a new authenticator object. This method will be called once per
40
+ # connection that requires authentication. The auth provider can create
41
+ # different authenticators for different authentication classes, or return
42
+ # nil if it does not support the authentication class.
43
+ #
44
+ # @note This method must absolutely not block.
45
+ #
46
+ # @param authentication_class [String] the authentication class used by
47
+ # the server.
48
+ # @return [Cassandra::Auth::Authenticator, nil] an object with an
49
+ # interface matching {Cassandra::Auth::Authenticator} or nil if the
50
+ # authentication class is not supported.
51
+ end
52
+
53
+ # An authenticator handles the authentication challenge/response cycles of
54
+ # a single connection. It can be stateful, but it must not for any reason
55
+ # block. If any of the method calls block, the whole connection process
56
+ # will be blocked.
57
+ #
58
+ # @note Authenticators created by auth providers don't need to be subclasses
59
+ # of this class, but need to implement the same methods. This class exists
60
+ # only for documentation purposes.
61
+ #
62
+ # @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v2.spec#L257-L273 Cassandra native protocol v2 SASL authentication
63
+ # @see Cassandra::Auth::Provider
64
+ class Authenticator
65
+ # @!method initial_response
66
+ #
67
+ # This method must return the initial authentication token to be sent to
68
+ # the server.
69
+ #
70
+ # @note This method must absolutely not block.
71
+ #
72
+ # @return [String] the initial authentication token
73
+
74
+ # @!method challenge_response(token)
75
+ #
76
+ # If the authentication requires multiple challenge/response cycles this
77
+ # method will be called when a challenge is returned by the server. A
78
+ # response token must be created and will be sent back to the server.
79
+ #
80
+ # @note This method must absolutely not block.
81
+ #
82
+ # @param token [String] a challenge token sent by the server
83
+ # @return [String] the authentication token to send back to the server
84
+
85
+ # @!method authentication_successful(token)
86
+ #
87
+ # Called when the authentication is successful.
88
+ #
89
+ # @note This method must absolutely not block.
90
+ #
91
+ # @param token [String] a token sent by the server
92
+ # @return [void]
93
+ end
94
+ end
95
+ end
96
+
97
+ require 'cassandra/auth/providers'