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.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +4 -0
  3. data/README.md +125 -0
  4. data/lib/cassandra/auth/providers/password.rb +73 -0
  5. data/lib/cassandra/auth/providers.rb +16 -0
  6. data/lib/cassandra/auth.rb +97 -0
  7. data/lib/cassandra/client/batch.rb +212 -0
  8. data/lib/cassandra/client/client.rb +591 -0
  9. data/lib/cassandra/client/column_metadata.rb +54 -0
  10. data/lib/cassandra/client/connection_manager.rb +72 -0
  11. data/lib/cassandra/client/connector.rb +277 -0
  12. data/lib/cassandra/client/execute_options_decoder.rb +59 -0
  13. data/lib/cassandra/client/null_logger.rb +37 -0
  14. data/lib/cassandra/client/peer_discovery.rb +50 -0
  15. data/lib/cassandra/client/prepared_statement.rb +314 -0
  16. data/lib/cassandra/client/query_result.rb +230 -0
  17. data/lib/cassandra/client/request_runner.rb +71 -0
  18. data/lib/cassandra/client/result_metadata.rb +48 -0
  19. data/lib/cassandra/client/void_result.rb +78 -0
  20. data/lib/cassandra/client.rb +144 -0
  21. data/lib/cassandra/cluster/client.rb +768 -0
  22. data/lib/cassandra/cluster/connector.rb +244 -0
  23. data/lib/cassandra/cluster/control_connection.rb +425 -0
  24. data/lib/cassandra/cluster/metadata.rb +124 -0
  25. data/lib/cassandra/cluster/options.rb +42 -0
  26. data/lib/cassandra/cluster/registry.rb +198 -0
  27. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +47 -0
  28. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +37 -0
  29. data/lib/cassandra/cluster/schema/partitioners/random.rb +37 -0
  30. data/lib/cassandra/cluster/schema/partitioners.rb +21 -0
  31. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +92 -0
  32. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +39 -0
  33. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +44 -0
  34. data/lib/cassandra/cluster/schema/replication_strategies.rb +21 -0
  35. data/lib/cassandra/cluster/schema/type_parser.rb +138 -0
  36. data/lib/cassandra/cluster/schema.rb +340 -0
  37. data/lib/cassandra/cluster.rb +215 -0
  38. data/lib/cassandra/column.rb +92 -0
  39. data/lib/cassandra/compression/compressors/lz4.rb +72 -0
  40. data/lib/cassandra/compression/compressors/snappy.rb +66 -0
  41. data/lib/cassandra/compression.rb +66 -0
  42. data/lib/cassandra/driver.rb +111 -0
  43. data/lib/cassandra/errors.rb +79 -0
  44. data/lib/cassandra/execution/info.rb +51 -0
  45. data/lib/cassandra/execution/options.rb +80 -0
  46. data/lib/cassandra/execution/trace.rb +152 -0
  47. data/lib/cassandra/future.rb +675 -0
  48. data/lib/cassandra/host.rb +79 -0
  49. data/lib/cassandra/keyspace.rb +133 -0
  50. data/lib/cassandra/listener.rb +87 -0
  51. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +149 -0
  52. data/lib/cassandra/load_balancing/policies/round_robin.rb +132 -0
  53. data/lib/cassandra/load_balancing/policies/token_aware.rb +119 -0
  54. data/lib/cassandra/load_balancing/policies/white_list.rb +90 -0
  55. data/lib/cassandra/load_balancing/policies.rb +19 -0
  56. data/lib/cassandra/load_balancing.rb +113 -0
  57. data/lib/cassandra/protocol/cql_byte_buffer.rb +307 -0
  58. data/lib/cassandra/protocol/cql_protocol_handler.rb +323 -0
  59. data/lib/cassandra/protocol/frame_decoder.rb +128 -0
  60. data/lib/cassandra/protocol/frame_encoder.rb +48 -0
  61. data/lib/cassandra/protocol/request.rb +38 -0
  62. data/lib/cassandra/protocol/requests/auth_response_request.rb +47 -0
  63. data/lib/cassandra/protocol/requests/batch_request.rb +76 -0
  64. data/lib/cassandra/protocol/requests/credentials_request.rb +47 -0
  65. data/lib/cassandra/protocol/requests/execute_request.rb +103 -0
  66. data/lib/cassandra/protocol/requests/options_request.rb +39 -0
  67. data/lib/cassandra/protocol/requests/prepare_request.rb +50 -0
  68. data/lib/cassandra/protocol/requests/query_request.rb +153 -0
  69. data/lib/cassandra/protocol/requests/register_request.rb +38 -0
  70. data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
  71. data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
  72. data/lib/cassandra/protocol/response.rb +38 -0
  73. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +41 -0
  74. data/lib/cassandra/protocol/responses/auth_success_response.rb +41 -0
  75. data/lib/cassandra/protocol/responses/authenticate_response.rb +41 -0
  76. data/lib/cassandra/protocol/responses/detailed_error_response.rb +60 -0
  77. data/lib/cassandra/protocol/responses/error_response.rb +50 -0
  78. data/lib/cassandra/protocol/responses/event_response.rb +39 -0
  79. data/lib/cassandra/protocol/responses/prepared_result_response.rb +64 -0
  80. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +43 -0
  81. data/lib/cassandra/protocol/responses/ready_response.rb +44 -0
  82. data/lib/cassandra/protocol/responses/result_response.rb +48 -0
  83. data/lib/cassandra/protocol/responses/rows_result_response.rb +139 -0
  84. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +60 -0
  85. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +57 -0
  86. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +42 -0
  87. data/lib/cassandra/protocol/responses/status_change_event_response.rb +44 -0
  88. data/lib/cassandra/protocol/responses/supported_response.rb +41 -0
  89. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +34 -0
  90. data/lib/cassandra/protocol/responses/void_result_response.rb +39 -0
  91. data/lib/cassandra/protocol/type_converter.rb +384 -0
  92. data/lib/cassandra/protocol.rb +93 -0
  93. data/lib/cassandra/reconnection/policies/constant.rb +48 -0
  94. data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
  95. data/lib/cassandra/reconnection/policies.rb +20 -0
  96. data/lib/cassandra/reconnection.rb +49 -0
  97. data/lib/cassandra/result.rb +215 -0
  98. data/lib/cassandra/retry/policies/default.rb +47 -0
  99. data/lib/cassandra/retry/policies/downgrading_consistency.rb +71 -0
  100. data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
  101. data/lib/cassandra/retry/policies.rb +21 -0
  102. data/lib/cassandra/retry.rb +142 -0
  103. data/lib/cassandra/session.rb +202 -0
  104. data/lib/cassandra/statement.rb +22 -0
  105. data/lib/cassandra/statements/batch.rb +95 -0
  106. data/lib/cassandra/statements/bound.rb +48 -0
  107. data/lib/cassandra/statements/prepared.rb +81 -0
  108. data/lib/cassandra/statements/simple.rb +58 -0
  109. data/lib/cassandra/statements/void.rb +33 -0
  110. data/lib/cassandra/statements.rb +23 -0
  111. data/lib/cassandra/table.rb +299 -0
  112. data/lib/cassandra/time_uuid.rb +142 -0
  113. data/lib/cassandra/util.rb +167 -0
  114. data/lib/cassandra/uuid.rb +104 -0
  115. data/lib/cassandra/version.rb +21 -0
  116. data/lib/cassandra.rb +428 -0
  117. data/lib/cassandra_murmur3.jar +0 -0
  118. 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
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ --markup markdown
3
+ lib/**/*.rb
4
+ -- README
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