cassandra-driver 1.0.0.beta.2-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +4 -0
- data/README.md +125 -0
- data/lib/cassandra/auth/providers/password.rb +73 -0
- data/lib/cassandra/auth/providers.rb +16 -0
- data/lib/cassandra/auth.rb +97 -0
- data/lib/cassandra/client/batch.rb +212 -0
- data/lib/cassandra/client/client.rb +591 -0
- data/lib/cassandra/client/column_metadata.rb +54 -0
- data/lib/cassandra/client/connection_manager.rb +72 -0
- data/lib/cassandra/client/connector.rb +277 -0
- data/lib/cassandra/client/execute_options_decoder.rb +59 -0
- data/lib/cassandra/client/null_logger.rb +37 -0
- data/lib/cassandra/client/peer_discovery.rb +50 -0
- data/lib/cassandra/client/prepared_statement.rb +314 -0
- data/lib/cassandra/client/query_result.rb +230 -0
- data/lib/cassandra/client/request_runner.rb +71 -0
- data/lib/cassandra/client/result_metadata.rb +48 -0
- data/lib/cassandra/client/void_result.rb +78 -0
- data/lib/cassandra/client.rb +144 -0
- data/lib/cassandra/cluster/client.rb +768 -0
- data/lib/cassandra/cluster/connector.rb +244 -0
- data/lib/cassandra/cluster/control_connection.rb +425 -0
- data/lib/cassandra/cluster/metadata.rb +124 -0
- data/lib/cassandra/cluster/options.rb +42 -0
- data/lib/cassandra/cluster/registry.rb +198 -0
- data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +47 -0
- data/lib/cassandra/cluster/schema/partitioners/ordered.rb +37 -0
- data/lib/cassandra/cluster/schema/partitioners/random.rb +37 -0
- data/lib/cassandra/cluster/schema/partitioners.rb +21 -0
- data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +92 -0
- data/lib/cassandra/cluster/schema/replication_strategies/none.rb +39 -0
- data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +44 -0
- data/lib/cassandra/cluster/schema/replication_strategies.rb +21 -0
- data/lib/cassandra/cluster/schema/type_parser.rb +138 -0
- data/lib/cassandra/cluster/schema.rb +340 -0
- data/lib/cassandra/cluster.rb +215 -0
- data/lib/cassandra/column.rb +92 -0
- data/lib/cassandra/compression/compressors/lz4.rb +72 -0
- data/lib/cassandra/compression/compressors/snappy.rb +66 -0
- data/lib/cassandra/compression.rb +66 -0
- data/lib/cassandra/driver.rb +111 -0
- data/lib/cassandra/errors.rb +79 -0
- data/lib/cassandra/execution/info.rb +51 -0
- data/lib/cassandra/execution/options.rb +80 -0
- data/lib/cassandra/execution/trace.rb +152 -0
- data/lib/cassandra/future.rb +675 -0
- data/lib/cassandra/host.rb +79 -0
- data/lib/cassandra/keyspace.rb +133 -0
- data/lib/cassandra/listener.rb +87 -0
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +149 -0
- data/lib/cassandra/load_balancing/policies/round_robin.rb +132 -0
- data/lib/cassandra/load_balancing/policies/token_aware.rb +119 -0
- data/lib/cassandra/load_balancing/policies/white_list.rb +90 -0
- data/lib/cassandra/load_balancing/policies.rb +19 -0
- data/lib/cassandra/load_balancing.rb +113 -0
- data/lib/cassandra/protocol/cql_byte_buffer.rb +307 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +323 -0
- data/lib/cassandra/protocol/frame_decoder.rb +128 -0
- data/lib/cassandra/protocol/frame_encoder.rb +48 -0
- data/lib/cassandra/protocol/request.rb +38 -0
- data/lib/cassandra/protocol/requests/auth_response_request.rb +47 -0
- data/lib/cassandra/protocol/requests/batch_request.rb +76 -0
- data/lib/cassandra/protocol/requests/credentials_request.rb +47 -0
- data/lib/cassandra/protocol/requests/execute_request.rb +103 -0
- data/lib/cassandra/protocol/requests/options_request.rb +39 -0
- data/lib/cassandra/protocol/requests/prepare_request.rb +50 -0
- data/lib/cassandra/protocol/requests/query_request.rb +153 -0
- data/lib/cassandra/protocol/requests/register_request.rb +38 -0
- data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
- data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
- data/lib/cassandra/protocol/response.rb +38 -0
- data/lib/cassandra/protocol/responses/auth_challenge_response.rb +41 -0
- data/lib/cassandra/protocol/responses/auth_success_response.rb +41 -0
- data/lib/cassandra/protocol/responses/authenticate_response.rb +41 -0
- data/lib/cassandra/protocol/responses/detailed_error_response.rb +60 -0
- data/lib/cassandra/protocol/responses/error_response.rb +50 -0
- data/lib/cassandra/protocol/responses/event_response.rb +39 -0
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +64 -0
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +43 -0
- data/lib/cassandra/protocol/responses/ready_response.rb +44 -0
- data/lib/cassandra/protocol/responses/result_response.rb +48 -0
- data/lib/cassandra/protocol/responses/rows_result_response.rb +139 -0
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +60 -0
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +57 -0
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +42 -0
- data/lib/cassandra/protocol/responses/status_change_event_response.rb +44 -0
- data/lib/cassandra/protocol/responses/supported_response.rb +41 -0
- data/lib/cassandra/protocol/responses/topology_change_event_response.rb +34 -0
- data/lib/cassandra/protocol/responses/void_result_response.rb +39 -0
- data/lib/cassandra/protocol/type_converter.rb +384 -0
- data/lib/cassandra/protocol.rb +93 -0
- data/lib/cassandra/reconnection/policies/constant.rb +48 -0
- data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
- data/lib/cassandra/reconnection/policies.rb +20 -0
- data/lib/cassandra/reconnection.rb +49 -0
- data/lib/cassandra/result.rb +215 -0
- data/lib/cassandra/retry/policies/default.rb +47 -0
- data/lib/cassandra/retry/policies/downgrading_consistency.rb +71 -0
- data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
- data/lib/cassandra/retry/policies.rb +21 -0
- data/lib/cassandra/retry.rb +142 -0
- data/lib/cassandra/session.rb +202 -0
- data/lib/cassandra/statement.rb +22 -0
- data/lib/cassandra/statements/batch.rb +95 -0
- data/lib/cassandra/statements/bound.rb +48 -0
- data/lib/cassandra/statements/prepared.rb +81 -0
- data/lib/cassandra/statements/simple.rb +58 -0
- data/lib/cassandra/statements/void.rb +33 -0
- data/lib/cassandra/statements.rb +23 -0
- data/lib/cassandra/table.rb +299 -0
- data/lib/cassandra/time_uuid.rb +142 -0
- data/lib/cassandra/util.rb +167 -0
- data/lib/cassandra/uuid.rb +104 -0
- data/lib/cassandra/version.rb +21 -0
- data/lib/cassandra.rb +428 -0
- data/lib/cassandra_murmur3.jar +0 -0
- metadata +211 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1f273c3e73482362317afef768c8bccfbe88d6a0
|
4
|
+
data.tar.gz: d94cb5c4c732c8bfba726f4e87ee43a8c3f927b6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 35193ec4431c65f84ecc1baf5271925dcfab5cdf5ece7d8fc069427f10fc255c7c47515dd47c6a58b0939dbbedda8f70768da7c1e6cbf8d45097f291d132b144
|
7
|
+
data.tar.gz: 3223ac7e2459bd6c0f3ed7bbda85534284ddf88981207b3ed7aff448da78b5289fee230da6d5cc63cbbc2e947122cc779df8edd20194554c43be5e064d79f522
|
data/.yardopts
ADDED
data/README.md
ADDED
@@ -0,0 +1,125 @@
|
|
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 added support for:
|
16
|
+
|
17
|
+
* [asynchronous execution](http://datastax.github.io/ruby-driver/features/asynchronous_io/)
|
18
|
+
* one-off, [prepared](http://datastax.github.io/ruby-driver/features/basics/prepared_statements/) and [batch statements](http://datastax.github.io/ruby-driver/features/basics/batch_statements/)
|
19
|
+
* automatic peer discovery and cluster metadata
|
20
|
+
* various [load-balancing](http://datastax.github.io/ruby-driver/features/load_balancing/), [retry](http://datastax.github.io/ruby-driver/features/retry_policies/) and reconnection policies, [with ability to write your own](http://datastax.github.io/ruby-driver/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_host 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
|
+
* [`Cassandra.connect` options](http://datastax.github.io/ruby-driver/api/#connect-class_method)
|
61
|
+
* [`Session#execute_async` options](http://datastax.github.io/ruby-driver/api/session/#execute_async-instance_method)
|
62
|
+
* [Usage documentation](http://datastax.github.io/ruby-driver/features)
|
63
|
+
|
64
|
+
## Installation
|
65
|
+
|
66
|
+
Install via rubygems
|
67
|
+
|
68
|
+
```bash
|
69
|
+
gem install cassandra-driver --pre
|
70
|
+
```
|
71
|
+
|
72
|
+
Install via Gemfile
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
gem 'cassandra-driver', '~> 1.0.0.beta'
|
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.](http://datastax.github.io/ruby-driver/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
|
+
## What's new in v1.0.0.beta.2
|
86
|
+
|
87
|
+
Current release introduces the following new features:
|
88
|
+
|
89
|
+
* TokenAware load balancing policy
|
90
|
+
* Domain names
|
91
|
+
* SSL encryption
|
92
|
+
|
93
|
+
## Changelog & versioning
|
94
|
+
|
95
|
+
Check out the [releases on GitHub](https://github.com/datastax/ruby-driver/releases) and [changelog](https://github.com/datastax/ruby-driver/blob/master/CHANGELOG.md). Version numbering follows the [semantic versioning](http://semver.org/) scheme.
|
96
|
+
|
97
|
+
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.
|
98
|
+
|
99
|
+
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.
|
100
|
+
|
101
|
+
## Known bugs & limitations
|
102
|
+
|
103
|
+
* 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.
|
104
|
+
* Because the driver reactor is using `IO.select`, the maximum number of tcp connections allowed is 1024.
|
105
|
+
|
106
|
+
|
107
|
+
## Credits
|
108
|
+
|
109
|
+
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.
|
110
|
+
|
111
|
+
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.
|
112
|
+
|
113
|
+
|
114
|
+
## Copyright
|
115
|
+
|
116
|
+
Copyright 2013-2014 DataStax, Inc.
|
117
|
+
|
118
|
+
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
|
119
|
+
|
120
|
+
[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
121
|
+
|
122
|
+
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.
|
123
|
+
|
124
|
+
[1]: http://datastax.github.io/ruby-driver/api
|
125
|
+
|
@@ -0,0 +1,73 @@
|
|
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
|
+
module Providers
|
22
|
+
# Auth provider used for Cassandra's built in authentication.
|
23
|
+
#
|
24
|
+
# @note No need to instantiate this class manually, use `:username` and
|
25
|
+
# `:password` options when calling {Cassandra.connect} and one will be
|
26
|
+
# created automatically for you.
|
27
|
+
class Password < Provider
|
28
|
+
# Authenticator used for Cassandra's built in authentication,
|
29
|
+
# see {Cassandra::Auth::Providers::Password}
|
30
|
+
# @private
|
31
|
+
class Authenticator
|
32
|
+
# @private
|
33
|
+
def initialize(username, password)
|
34
|
+
@username = username
|
35
|
+
@password = password
|
36
|
+
end
|
37
|
+
|
38
|
+
def initial_response
|
39
|
+
"\x00#{@username}\x00#{@password}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def challenge_response(token)
|
43
|
+
end
|
44
|
+
|
45
|
+
def authentication_successful(token)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param username [String] username to use for authentication to Cassandra
|
50
|
+
# @param password [String] password to use for authentication to Cassandra
|
51
|
+
def initialize(username, password)
|
52
|
+
@username = username
|
53
|
+
@password = password
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns a Password Authenticator only if `org.apache.cassandra.auth.PasswordAuthenticator` is given.
|
57
|
+
# @param authentication_class [String] must equal to `org.apache.cassandra.auth.PasswordAuthenticator`
|
58
|
+
# @return [Cassandra::Auth::Authenticator] when `authentication_class == "org.apache.cassandra.auth.PasswordAuthenticator"`
|
59
|
+
# @return [nil] for all other values of `authentication_class`
|
60
|
+
def create_authenticator(authentication_class)
|
61
|
+
if authentication_class == PASSWORD_AUTHENTICATOR_FQCN
|
62
|
+
Authenticator.new(@username, @password)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# @private
|
69
|
+
PASSWORD_AUTHENTICATOR_FQCN = 'org.apache.cassandra.auth.PasswordAuthenticator'.freeze
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Copyright 2013-2014 DataStax, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
#++
|
15
|
+
|
16
|
+
require 'cassandra/auth/providers/password'
|
@@ -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
|
+
# @abstract Authenticators created by auth providers don't need to be
|
59
|
+
# subclasses of this class, but need to implement the same methods. This
|
60
|
+
# class exists 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#create_authenticator
|
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'
|
@@ -0,0 +1,212 @@
|
|
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 Client
|
21
|
+
# Batches let you send multiple queries (`INSERT`, `UPDATE` and `DELETE`) in
|
22
|
+
# one go. This can lead to better performance, and depending on the options
|
23
|
+
# you specify can also give you different consistency guarantees.
|
24
|
+
#
|
25
|
+
# Batches can contain a mix of different queries and prepared statements.
|
26
|
+
#
|
27
|
+
# @see Cassandra::Client::Client#batch
|
28
|
+
class Batch
|
29
|
+
# @!method add(cql_or_prepared_statement, *bound_values)
|
30
|
+
#
|
31
|
+
# Add a query or a prepared statement to the batch.
|
32
|
+
#
|
33
|
+
# @example Adding a mix of statements to a batch
|
34
|
+
# batch.add(%(UPDATE people SET name = 'Miriam' WHERE id = 3435))
|
35
|
+
# batch.add(%(UPDATE people SET name = ? WHERE id = ?), 'Miriam', 3435)
|
36
|
+
# batch.add(prepared_statement, 'Miriam', 3435)
|
37
|
+
#
|
38
|
+
# @param [String, Cassandra::Client::PreparedStatement] cql_or_prepared_statement
|
39
|
+
# a CQL string or a prepared statement object (obtained through
|
40
|
+
# {Cassandra::Client::Client#prepare})
|
41
|
+
# @param [Array] bound_values a list of bound values -- only applies when
|
42
|
+
# adding prepared statements and when there are binding markers in the
|
43
|
+
# given CQL. If the last argument is a hash and it has the key
|
44
|
+
# `:type_hints` this will be passed as type hints to the request encoder
|
45
|
+
# (if the last argument is any other hash it will be assumed to be a
|
46
|
+
# bound value of type MAP). See {Cassandra::Client::Client#execute} for more
|
47
|
+
# info on type hints.
|
48
|
+
# @return [nil]
|
49
|
+
|
50
|
+
# @!method execute(options={})
|
51
|
+
#
|
52
|
+
# Execute the batch and return the result.
|
53
|
+
#
|
54
|
+
# @param [Hash] options an options hash or a symbol (as a shortcut for
|
55
|
+
# specifying the consistency), see {Cassandra::Client::Client#execute} for
|
56
|
+
# full details about how this value is interpreted.
|
57
|
+
# @raise [Cassandra::Errors::QueryError] raised when there is an error on the server side
|
58
|
+
# @raise [Cassandra::Errors::NotPreparedError] raised in the unlikely event that a
|
59
|
+
# prepared statement was not prepared on the chosen connection
|
60
|
+
# @return [Cassandra::Client::VoidResult] a batch always returns a void result
|
61
|
+
end
|
62
|
+
|
63
|
+
# A convenient wrapper that makes it easy to build batches of multiple
|
64
|
+
# executions of the same prepared statement.
|
65
|
+
#
|
66
|
+
# @see Cassandra::Client::PreparedStatement#batch
|
67
|
+
class PreparedStatementBatch
|
68
|
+
# @!method add(*bound_values)
|
69
|
+
#
|
70
|
+
# Add the statement to the batch with the specified bound values.
|
71
|
+
#
|
72
|
+
# @param [Array] bound_values the values to bind to the added statement,
|
73
|
+
# see {Cassandra::Client::PreparedStatement#execute}.
|
74
|
+
# @return [nil]
|
75
|
+
|
76
|
+
# @!method execute(options={})
|
77
|
+
#
|
78
|
+
# Execute the batch and return the result.
|
79
|
+
#
|
80
|
+
# @raise [Cassandra::Errors::QueryError] raised when there is an error on the server side
|
81
|
+
# @raise [Cassandra::Errors::NotPreparedError] raised in the unlikely event that a
|
82
|
+
# prepared statement was not prepared on the chosen connection
|
83
|
+
# @return [Cassandra::Client::VoidResult] a batch always returns a void result
|
84
|
+
end
|
85
|
+
|
86
|
+
# @private
|
87
|
+
class AsynchronousBatch < Batch
|
88
|
+
def initialize(type, execute_options_decoder, connection_manager, options=nil)
|
89
|
+
raise ArgumentError, "Unknown batch type: #{type}" unless BATCH_TYPES.include?(type)
|
90
|
+
@type = type
|
91
|
+
@execute_options_decoder = execute_options_decoder
|
92
|
+
@connection_manager = connection_manager
|
93
|
+
@options = options
|
94
|
+
@request_runner = RequestRunner.new
|
95
|
+
@parts = []
|
96
|
+
end
|
97
|
+
|
98
|
+
def add(*args)
|
99
|
+
@parts << args
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
|
103
|
+
def execute(options=nil)
|
104
|
+
options = @execute_options_decoder.decode_options(@options, options)
|
105
|
+
connection = @connection_manager.random_connection
|
106
|
+
request = Protocol::BatchRequest.new(BATCH_TYPES[@type], options[:consistency], options[:trace])
|
107
|
+
unprepared_statements = nil
|
108
|
+
@parts.each do |part, *bound_args|
|
109
|
+
if part.is_a?(String) || part.prepared?(connection)
|
110
|
+
add_part(connection, request, part, bound_args)
|
111
|
+
else
|
112
|
+
unprepared_statements ||= []
|
113
|
+
unprepared_statements << [part, bound_args]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
@parts = []
|
117
|
+
if unprepared_statements.nil?
|
118
|
+
@request_runner.execute(connection, request, options[:timeout])
|
119
|
+
else
|
120
|
+
fs = unprepared_statements.map do |statement, _|
|
121
|
+
if statement.respond_to?(:async)
|
122
|
+
statement.async.prepare(connection)
|
123
|
+
else
|
124
|
+
statement.prepare(connection)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
Ione::Future.all(*fs).flat_map do
|
128
|
+
unprepared_statements.each do |statement, bound_args|
|
129
|
+
add_part(connection, request, statement, bound_args)
|
130
|
+
end
|
131
|
+
@request_runner.execute(connection, request, options[:timeout])
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
BATCH_TYPES = {
|
139
|
+
:logged => Protocol::BatchRequest::LOGGED_TYPE,
|
140
|
+
:unlogged => Protocol::BatchRequest::UNLOGGED_TYPE,
|
141
|
+
:counter => Protocol::BatchRequest::COUNTER_TYPE,
|
142
|
+
}.freeze
|
143
|
+
|
144
|
+
def add_part(connection, request, part, bound_args)
|
145
|
+
if part.is_a?(String)
|
146
|
+
type_hints = nil
|
147
|
+
if bound_args.last.is_a?(Hash) && bound_args.last.include?(:type_hints)
|
148
|
+
bound_args = bound_args.dup
|
149
|
+
type_hints = bound_args.pop[:type_hints]
|
150
|
+
end
|
151
|
+
request.add_query(part, bound_args, type_hints)
|
152
|
+
else
|
153
|
+
part.add_to_batch(request, connection, bound_args)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# @private
|
159
|
+
class SynchronousBatch < Batch
|
160
|
+
include SynchronousBacktrace
|
161
|
+
|
162
|
+
def initialize(asynchronous_batch)
|
163
|
+
@asynchronous_batch = asynchronous_batch
|
164
|
+
end
|
165
|
+
|
166
|
+
def async
|
167
|
+
@asynchronous_batch
|
168
|
+
end
|
169
|
+
|
170
|
+
def add(*args)
|
171
|
+
@asynchronous_batch.add(*args)
|
172
|
+
end
|
173
|
+
|
174
|
+
def execute(options=nil)
|
175
|
+
synchronous_backtrace { @asynchronous_batch.execute(options).value }
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# @private
|
180
|
+
class AsynchronousPreparedStatementBatch < PreparedStatementBatch
|
181
|
+
def initialize(prepared_statement, batch)
|
182
|
+
@prepared_statement = prepared_statement
|
183
|
+
@batch = batch
|
184
|
+
end
|
185
|
+
|
186
|
+
def add(*args)
|
187
|
+
@batch.add(@prepared_statement, *args)
|
188
|
+
end
|
189
|
+
|
190
|
+
def execute(options=nil)
|
191
|
+
@batch.execute(options)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# @private
|
196
|
+
class SynchronousPreparedStatementBatch < PreparedStatementBatch
|
197
|
+
include SynchronousBacktrace
|
198
|
+
|
199
|
+
def initialize(asynchronous_batch)
|
200
|
+
@asynchronous_batch = asynchronous_batch
|
201
|
+
end
|
202
|
+
|
203
|
+
def add(*args)
|
204
|
+
@asynchronous_batch.add(*args)
|
205
|
+
end
|
206
|
+
|
207
|
+
def execute(options=nil)
|
208
|
+
synchronous_backtrace { @asynchronous_batch.execute(options).value }
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|