cassandra-driver 3.2.1 → 3.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +24 -27
- data/lib/cassandra.rb +2 -1
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +3 -2
- data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +3 -4
- data/lib/cassandra/duration.rb +100 -0
- data/lib/cassandra/future.rb +8 -2
- data/lib/cassandra/protocol/cql_byte_buffer.rb +62 -14
- data/lib/cassandra/protocol/cql_protocol_handler.rb +1 -2
- data/lib/cassandra/protocol/requests/query_request.rb +10 -2
- data/lib/cassandra/protocol/v4.rb +3 -0
- data/lib/cassandra/table.rb +1 -1
- data/lib/cassandra/types.rb +72 -1
- data/lib/cassandra/util.rb +20 -0
- data/lib/cassandra/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e8c5a43dbb0d9f94193939527fc90de1e0f0d52c3860626c6344f22a5f42dd70
|
4
|
+
data.tar.gz: 1de98d478a133db7eb1c21812562c9397a882483db11f2da5b976e9cbf0b2b8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 638e6bbee952fd60df5aead9e71072b64ffa0d4c93ed8b85abc57fd40733c12972be228af587adbb8a86fa798d776329b82c492e02d95bf069323c821b9685c8
|
7
|
+
data.tar.gz: a6f0e1760b0cefacecae677961c4a8bcefd40d2a71df85e1ac1dd086a4b12214859aba362c36cd8b6b4de749079f49415de0224d196f95369d4a31164401fae6
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
:warning: **The Ruby driver is in maintenance mode. We are still accepting pull-requests and we will occasionally release critical bug fixes, but no ongoing active development is being done currently.**
|
2
|
+
|
1
3
|
# Datastax Ruby Driver for Apache Cassandra
|
2
4
|
|
3
5
|
*If you're reading this on GitHub, please note that this is the readme for the development version and that some
|
@@ -9,7 +11,7 @@ version [here](http://docs.datastax.com/en/developer/ruby-driver/latest).*
|
|
9
11
|
A Ruby client driver for Apache Cassandra. This driver works exclusively with
|
10
12
|
the Cassandra Query Language version 3 (CQL3) and Cassandra's native protocol.
|
11
13
|
|
12
|
-
Use the [Ruby DSE driver](https://
|
14
|
+
Use the [Ruby DSE driver](https://docs.datastax.com/en/developer/ruby-driver-dse/2.1/) for
|
13
15
|
better compatibility and support for DataStax Enterprise.
|
14
16
|
|
15
17
|
- Code: https://github.com/datastax/ruby-driver
|
@@ -21,14 +23,14 @@ better compatibility and support for DataStax Enterprise.
|
|
21
23
|
|
22
24
|
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:
|
23
25
|
|
24
|
-
* [Asynchronous execution](http://docs.datastax.com/en/developer/ruby-driver/3.
|
25
|
-
* One-off, [prepared](http://docs.datastax.com/en/developer/ruby-driver/3.
|
26
|
-
* Automatic peer discovery and cluster metadata with [support for change notifications](http://docs.datastax.com/en/developer/ruby-driver/3.
|
27
|
-
* Various [load-balancing](http://docs.datastax.com/en/developer/ruby-driver/3.
|
28
|
-
* [SSL encryption](http://docs.datastax.com/en/developer/ruby-driver/3.
|
29
|
-
* [Flexible and robust error handling](http://docs.datastax.com/en/developer/ruby-driver/3.
|
30
|
-
* [Per-request execution information and tracing](http://docs.datastax.com/en/developer/ruby-driver/3.
|
31
|
-
* [Configurable address resolution](http://docs.datastax.com/en/developer/ruby-driver/3.
|
26
|
+
* [Asynchronous execution](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/asynchronous_io/)
|
27
|
+
* One-off, [prepared](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/basics/prepared_statements/) and [batch statements](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/basics/batch_statements/)
|
28
|
+
* Automatic peer discovery and cluster metadata with [support for change notifications](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/state_listeners/)
|
29
|
+
* Various [load-balancing](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/load_balancing/), [retry](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/retry_policies/) and [reconnection](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/reconnection/) policies with [ability to write your own](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/load_balancing/implementing_a_policy/)
|
30
|
+
* [SSL encryption](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/security/ssl_encryption/)
|
31
|
+
* [Flexible and robust error handling](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/error_handling/)
|
32
|
+
* [Per-request execution information and tracing](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/debugging/)
|
33
|
+
* [Configurable address resolution](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/address_resolution/)
|
32
34
|
|
33
35
|
[Check out the slides from Ruby Driver Explained](https://speakerdeck.com/avalanche123/ruby-driver-explained) for a detailed overview of the Ruby Driver architecture.
|
34
36
|
|
@@ -37,7 +39,7 @@ This driver is based on [the cql-rb gem](https://github.com/iconara/cql-rb) by [
|
|
37
39
|
This driver works exclusively with the Cassandra Query Language v3 (CQL3) and Cassandra's native protocol. The current version works with:
|
38
40
|
|
39
41
|
* Apache Cassandra versions 2.1, 2.2, and 3.x
|
40
|
-
* DataStax Enterprise 4.8 and above. However, the [Ruby DSE driver](https://
|
42
|
+
* DataStax Enterprise 4.8 and above. However, the [Ruby DSE driver](https://docs.datastax.com/en/developer/ruby-driver-dse/2.1/) provides more features and is recommended for use with DataStax Enterprise.
|
41
43
|
* Ruby (MRI) 2.2, 2.3, 2.4
|
42
44
|
* JRuby 9k
|
43
45
|
|
@@ -45,10 +47,6 @@ __Note__: Rubinius is not supported.
|
|
45
47
|
|
46
48
|
__Note__: Big-endian systems are not supported.
|
47
49
|
|
48
|
-
## Feedback Requested
|
49
|
-
|
50
|
-
*Help us focus our efforts!* [Provide your input](http://goo.gl/forms/pCs8PTpHLf) on the Ruby Driver Platform and Runtime Survey (we kept it short).
|
51
|
-
|
52
50
|
## Quick start
|
53
51
|
|
54
52
|
```ruby
|
@@ -76,9 +74,9 @@ __Note__: The host you specify is just a seed node, the driver will automaticall
|
|
76
74
|
|
77
75
|
Read more:
|
78
76
|
|
79
|
-
* [`Cassandra.cluster` options](http://docs.datastax.com/en/developer/ruby-driver/3.
|
80
|
-
* [`Session#execute_async` options](http://docs.datastax.com/en/developer/ruby-driver/3.
|
81
|
-
* [Usage documentation](http://docs.datastax.com/en/developer/ruby-driver/3.
|
77
|
+
* [`Cassandra.cluster` options](http://docs.datastax.com/en/developer/ruby-driver/3.2/api/cassandra/#cluster-class_method)
|
78
|
+
* [`Session#execute_async` options](http://docs.datastax.com/en/developer/ruby-driver/3.2/api/cassandra/session/#execute_async-instance_method)
|
79
|
+
* [Usage documentation](http://docs.datastax.com/en/developer/ruby-driver/3.2/features)
|
82
80
|
|
83
81
|
## Installation
|
84
82
|
|
@@ -94,25 +92,24 @@ Install via Gemfile
|
|
94
92
|
gem 'cassandra-driver'
|
95
93
|
```
|
96
94
|
|
97
|
-
__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://docs.datastax.com/en/developer/ruby-driver/3.
|
95
|
+
__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://docs.datastax.com/en/developer/ruby-driver/3.2/features/#compression)
|
98
96
|
|
99
97
|
|
100
98
|
## Upgrading from cql-rb
|
101
99
|
|
102
100
|
Some of the new features added to the driver have unfortunately led to changes in the original cql-rb API.
|
103
101
|
In the examples directory, you can find [an example of how to wrap the ruby driver to achieve almost complete
|
104
|
-
interface parity with cql-rb](https://github.com/datastax/ruby-driver/blob/v3.2.
|
102
|
+
interface parity with cql-rb](https://github.com/datastax/ruby-driver/blob/v3.2.5/examples/cql-rb-wrapper.rb)
|
105
103
|
to assist you with gradual upgrade.
|
106
104
|
|
107
|
-
If you are upgrading to DataStax Enterprise, use the [Ruby DSE driver](https://
|
108
|
-
for more features and better compatibility.
|
105
|
+
If you are upgrading to DataStax Enterprise, use the [Ruby DSE driver](https://docs.datastax.com/en/developer/ruby-driver-dse/2.1/) for more features and better compatibility.
|
109
106
|
|
110
107
|
## What's new in v3.2
|
111
108
|
This minor release adds support for MRI 2.4.x and also contains a few miscellaneous defect fixes. It also removes
|
112
109
|
support for Ruby versions prior to 2.2. This was already officially the case, but the minimum version limit is
|
113
110
|
now enforced.
|
114
111
|
|
115
|
-
See the [changelog](https://github.com/datastax/ruby-driver/blob/v3.2.
|
112
|
+
See the [changelog](https://github.com/datastax/ruby-driver/blob/v3.2.5/CHANGELOG.md) for more information on all
|
116
113
|
changes in this version and past versions.
|
117
114
|
|
118
115
|
## What's new in v3.1
|
@@ -180,7 +177,7 @@ examples in the `features/` directory.
|
|
180
177
|
## Running tests
|
181
178
|
|
182
179
|
If you don't feel like reading through the following instructions on how to run
|
183
|
-
ruby-driver tests, feel free to [check out .travis.yml for the entire build code](https://github.com/datastax/ruby-driver/blob/v3.2.
|
180
|
+
ruby-driver tests, feel free to [check out .travis.yml for the entire build code](https://github.com/datastax/ruby-driver/blob/v3.2.5/.travis.yml).
|
184
181
|
|
185
182
|
* Check out the driver codebase and install test dependencies:
|
186
183
|
|
@@ -204,7 +201,7 @@ CASSANDRA_VERSION=2.1.12 bundle exec rake test # run both as well as integration
|
|
204
201
|
## Changelog & versioning
|
205
202
|
|
206
203
|
Check out the [releases on GitHub](https://github.com/datastax/ruby-driver/releases) and
|
207
|
-
[changelog](https://github.com/datastax/ruby-driver/blob/v3.2.
|
204
|
+
[changelog](https://github.com/datastax/ruby-driver/blob/v3.2.5/CHANGELOG.md). Version
|
208
205
|
numbering follows the [semantic versioning](http://semver.org/) scheme.
|
209
206
|
|
210
207
|
Private and experimental APIs, defined as whatever is not in the
|
@@ -227,7 +224,7 @@ the release.
|
|
227
224
|
* Because the driver reactor is using `IO.select`, the maximum number of tcp connections allowed is 1024.
|
228
225
|
* Because the driver uses `IO#write_nonblock`, Windows is not supported.
|
229
226
|
|
230
|
-
Please [refer to the usage documentation for more information on common pitfalls](http://docs.datastax.com/en/developer/ruby-driver/3.
|
227
|
+
Please [refer to the usage documentation for more information on common pitfalls](http://docs.datastax.com/en/developer/ruby-driver/3.2/features/)
|
231
228
|
|
232
229
|
## Contributing
|
233
230
|
|
@@ -245,7 +242,7 @@ Driver for Apache Cassandra will continue on this project, while
|
|
245
242
|
|
246
243
|
## Copyright
|
247
244
|
|
248
|
-
|
245
|
+
© DataStax, Inc.
|
249
246
|
|
250
247
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
251
248
|
except in compliance with the License. You may obtain a copy of the License at
|
@@ -257,4 +254,4 @@ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
257
254
|
either express or implied. See the License for the specific language governing permissions
|
258
255
|
and limitations under the License.
|
259
256
|
|
260
|
-
[1]: http://docs.datastax.com/en/developer/ruby-driver/3.
|
257
|
+
[1]: http://docs.datastax.com/en/developer/ruby-driver/3.2/api
|
data/lib/cassandra.rb
CHANGED
@@ -777,6 +777,8 @@ require 'cassandra/udt'
|
|
777
777
|
require 'cassandra/time'
|
778
778
|
|
779
779
|
require 'cassandra/types'
|
780
|
+
require 'cassandra/custom_data'
|
781
|
+
require 'cassandra/duration'
|
780
782
|
|
781
783
|
require 'cassandra/errors'
|
782
784
|
require 'cassandra/compression'
|
@@ -788,7 +790,6 @@ require 'cassandra/null_logger'
|
|
788
790
|
require 'cassandra/executors'
|
789
791
|
require 'cassandra/future'
|
790
792
|
require 'cassandra/cluster'
|
791
|
-
require 'cassandra/custom_data'
|
792
793
|
require 'cassandra/driver'
|
793
794
|
require 'cassandra/host'
|
794
795
|
require 'cassandra/session'
|
@@ -40,8 +40,6 @@ module Cassandra
|
|
40
40
|
private
|
41
41
|
|
42
42
|
def lookup_type(node, types)
|
43
|
-
return lookup_type(node.children.first, types) if node.name == 'frozen'
|
44
|
-
|
45
43
|
case node.name
|
46
44
|
when 'text' then Cassandra::Types.text
|
47
45
|
when 'blob' then Cassandra::Types.blob
|
@@ -62,6 +60,7 @@ module Cassandra
|
|
62
60
|
when 'smallint' then Cassandra::Types.smallint
|
63
61
|
when 'time' then Cassandra::Types.time
|
64
62
|
when 'tinyint' then Cassandra::Types.tinyint
|
63
|
+
when 'duration' then Cassandra::Types.duration
|
65
64
|
when 'map' then
|
66
65
|
Cassandra::Types.map(*node.children.map { |t| lookup_type(t, types)})
|
67
66
|
when 'set' then
|
@@ -70,6 +69,8 @@ module Cassandra
|
|
70
69
|
Cassandra::Types.list(lookup_type(node.children.first, types))
|
71
70
|
when 'tuple' then
|
72
71
|
Cassandra::Types.tuple(*node.children.map { |t| lookup_type(t, types)})
|
72
|
+
when 'frozen' then
|
73
|
+
Cassandra::Types.frozen(lookup_type(node.children.first, types))
|
73
74
|
when 'empty' then
|
74
75
|
Cassandra::Types.custom('org.apache.cassandra.db.marshal.EmptyType')
|
75
76
|
when /\A'/ then
|
@@ -50,7 +50,8 @@ module Cassandra
|
|
50
50
|
'org.apache.cassandra.db.marshal.ShortType' => :smallint,
|
51
51
|
'org.apache.cassandra.db.marshal.ByteType' => :tinyint,
|
52
52
|
'org.apache.cassandra.db.marshal.TimeType' => :time,
|
53
|
-
'org.apache.cassandra.db.marshal.SimpleDateType' => :date
|
53
|
+
'org.apache.cassandra.db.marshal.SimpleDateType' => :date,
|
54
|
+
'org.apache.cassandra.db.marshal.FrozenType' => :frozen
|
54
55
|
}.freeze
|
55
56
|
|
56
57
|
def parse(string)
|
@@ -109,14 +110,12 @@ module Cassandra
|
|
109
110
|
end
|
110
111
|
|
111
112
|
def lookup_type(node)
|
112
|
-
return lookup_type(node.children.first) if node.name == 'org.apache.cassandra.db.marshal.FrozenType'
|
113
|
-
|
114
113
|
type = @@types.fetch(node.name) do
|
115
114
|
return Cassandra::Types.custom(dump_node(node))
|
116
115
|
end
|
117
116
|
|
118
117
|
case type
|
119
|
-
when :set, :list
|
118
|
+
when :set, :list, :frozen
|
120
119
|
Cassandra::Types.send(type, lookup_type(node.children.first))
|
121
120
|
when :map
|
122
121
|
Cassandra::Types.map(*node.children.map(&method(:lookup_type)))
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 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
|
+
module Cassandra
|
19
|
+
module Types
|
20
|
+
|
21
|
+
class Duration < Type
|
22
|
+
include CustomData
|
23
|
+
|
24
|
+
@@four_byte_max = 2 ** 32
|
25
|
+
@@eight_byte_max = 2 ** 64
|
26
|
+
|
27
|
+
# @private
|
28
|
+
attr_reader :months, :days, :nanos
|
29
|
+
|
30
|
+
# @private
|
31
|
+
def initialize(months, days, nanos)
|
32
|
+
super(:duration)
|
33
|
+
@months = months
|
34
|
+
@days = days
|
35
|
+
@nanos = nanos
|
36
|
+
end
|
37
|
+
|
38
|
+
def new(*values)
|
39
|
+
Util.assert_size(3, values, "Duration type expects three values, #{values.size} were provided")
|
40
|
+
values.each { |v| Util.assert_type(Int, v) }
|
41
|
+
Util.assert (Util.encode_zigzag32(values[0]) < @@four_byte_max), "Months value must be a valid 32-bit integer"
|
42
|
+
Util.assert (Util.encode_zigzag32(values[1]) < @@four_byte_max), "Days value must be a valid 32-bit integer"
|
43
|
+
Util.assert (Util.encode_zigzag64(values[2]) < @@eight_byte_max), "Nanos value must be a valid 64-bit integer"
|
44
|
+
all_positive = values.all? {|i| i >= 0 }
|
45
|
+
all_negative = values.all? {|i| i <= 0 }
|
46
|
+
Util.assert (all_positive or all_negative), "Values in a duration must be uniformly positive or negative"
|
47
|
+
Duration.new *values
|
48
|
+
end
|
49
|
+
|
50
|
+
def assert(value, message = nil, &block)
|
51
|
+
Util.assert_instance_of(Duration, value, message, &block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
"Duration: months => #{@months}, days => #{@days}, nanos => #{@nanos}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def hash
|
59
|
+
@hash ||= begin
|
60
|
+
h = 17
|
61
|
+
h = 31 * h + @months.hash
|
62
|
+
h = 31 * h + @days.hash
|
63
|
+
h = 31 * h + @nanos.hash
|
64
|
+
h
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def eql?(other)
|
69
|
+
other.is_a?(Duration) &&
|
70
|
+
@months == other.months &&
|
71
|
+
@days == other.days &&
|
72
|
+
@nanos == other.nanos
|
73
|
+
end
|
74
|
+
|
75
|
+
alias == eql?
|
76
|
+
|
77
|
+
def self.cql_type
|
78
|
+
Type.new(@kind)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Requirements for CustomData module
|
82
|
+
def self.deserialize(bytestr)
|
83
|
+
buffer = Cassandra::Protocol::CqlByteBuffer.new.append(bytestr)
|
84
|
+
Cassandra::Types::Duration.new(buffer.read_signed_vint,buffer.read_signed_vint,buffer.read_signed_vint)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.type
|
88
|
+
Cassandra::Types::Custom.new('org.apache.cassandra.db.marshal.DurationType')
|
89
|
+
end
|
90
|
+
|
91
|
+
def serialize
|
92
|
+
rv = Cassandra::Protocol::CqlByteBuffer.new
|
93
|
+
rv.append_signed_vint32(@months)
|
94
|
+
rv.append_signed_vint32(@days)
|
95
|
+
rv.append_signed_vint64(@nanos)
|
96
|
+
rv
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/cassandra/future.rb
CHANGED
@@ -204,7 +204,13 @@ module Cassandra
|
|
204
204
|
end
|
205
205
|
|
206
206
|
def all(*futures)
|
207
|
-
|
207
|
+
# May get called with varargs or an array of futures. In the latter case,
|
208
|
+
# the first element in futures is the array of futures. Promote it.
|
209
|
+
futures = Array(futures.first) if futures.one?
|
210
|
+
|
211
|
+
# Special case where there are no futures to aggregate.
|
212
|
+
return Value.new([]) if futures.empty?
|
213
|
+
|
208
214
|
monitor = Monitor.new
|
209
215
|
promise = Promise.new(@executor)
|
210
216
|
remaining = futures.length
|
@@ -609,9 +615,9 @@ module Cassandra
|
|
609
615
|
@waiting += 1
|
610
616
|
while @state == :pending
|
611
617
|
if deadline
|
618
|
+
break if now >= deadline
|
612
619
|
@cond.wait(deadline - now)
|
613
620
|
now = ::Time.now
|
614
|
-
break if now >= deadline
|
615
621
|
else
|
616
622
|
@cond.wait
|
617
623
|
end
|
@@ -53,24 +53,30 @@ module Cassandra
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def read_decimal(len = bytesize)
|
56
|
-
|
56
|
+
scale = read_signed_int
|
57
57
|
number_string = read_varint(len - 4).to_s
|
58
|
-
if
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
if scale <= 0
|
59
|
+
# Special case where the actual scale is positive; scale in the protocol is actually negative of
|
60
|
+
# reality.
|
61
|
+
BigDecimal(number_string + '0' * -scale)
|
62
|
+
else
|
63
|
+
if number_string.length <= scale
|
64
|
+
if number_string.start_with?(MINUS)
|
65
|
+
number_string = number_string[1, number_string.length - 1]
|
66
|
+
fraction_string = MINUS + ZERO << DECIMAL_POINT
|
67
|
+
else
|
68
|
+
fraction_string = ZERO + DECIMAL_POINT
|
69
|
+
end
|
70
|
+
(scale - number_string.length).times { fraction_string << ZERO }
|
71
|
+
fraction_string << number_string
|
62
72
|
else
|
63
|
-
fraction_string =
|
73
|
+
fraction_string = number_string[0, number_string.length - scale]
|
74
|
+
fraction_string << DECIMAL_POINT
|
75
|
+
fraction_string <<
|
76
|
+
number_string[number_string.length - scale, number_string.length]
|
64
77
|
end
|
65
|
-
(
|
66
|
-
fraction_string << number_string
|
67
|
-
else
|
68
|
-
fraction_string = number_string[0, number_string.length - size]
|
69
|
-
fraction_string << DECIMAL_POINT
|
70
|
-
fraction_string <<
|
71
|
-
number_string[number_string.length - size, number_string.length]
|
78
|
+
BigDecimal(fraction_string)
|
72
79
|
end
|
73
|
-
BigDecimal.new(fraction_string)
|
74
80
|
rescue Errors::DecodingError => e
|
75
81
|
raise Errors::DecodingError, e.message, e.backtrace
|
76
82
|
end
|
@@ -281,6 +287,29 @@ module Cassandra
|
|
281
287
|
"Not enough bytes available to decode a tinyint: #{e.message}", e.backtrace
|
282
288
|
end
|
283
289
|
|
290
|
+
def read_vint
|
291
|
+
n = read_byte
|
292
|
+
|
293
|
+
# Bits are indexed in Integer in little-endian order
|
294
|
+
bytes_to_read = 7.downto(0).take_while {|i| n[i] == 1}.size
|
295
|
+
return n unless bytes_to_read > 0
|
296
|
+
|
297
|
+
rv = n & (0xff >> bytes_to_read)
|
298
|
+
1.upto(bytes_to_read) do |idx|
|
299
|
+
new_byte = read_byte
|
300
|
+
rv <<= 8
|
301
|
+
rv |= (new_byte & 0xff)
|
302
|
+
end
|
303
|
+
|
304
|
+
rv
|
305
|
+
rescue RangeError => e
|
306
|
+
raise Errors::DecodingError, e.message, e.backtrace
|
307
|
+
end
|
308
|
+
|
309
|
+
def read_signed_vint
|
310
|
+
Util.decode_zigzag(read_vint)
|
311
|
+
end
|
312
|
+
|
284
313
|
def append_tinyint(n)
|
285
314
|
append([n].pack(Formats::CHAR_FORMAT))
|
286
315
|
end
|
@@ -403,6 +432,25 @@ module Cassandra
|
|
403
432
|
append([n].pack(Formats::FLOAT_FORMAT))
|
404
433
|
end
|
405
434
|
|
435
|
+
def append_vint(n)
|
436
|
+
send_bytes = Util.to_min_byte_array(n)
|
437
|
+
send_cnt = send_bytes.length
|
438
|
+
|
439
|
+
raise Errors::EncodingError, "Too many bytes (#{bytes_to_send.length}) to send!" if send_cnt > 8
|
440
|
+
|
441
|
+
send_cnt_byte = (0xff << (8 - send_cnt)) & 0xff
|
442
|
+
append([send_cnt_byte].pack(Formats::BYTES_FORMAT))
|
443
|
+
append(send_bytes.pack(Formats::BYTES_FORMAT))
|
444
|
+
end
|
445
|
+
|
446
|
+
def append_signed_vint32(n)
|
447
|
+
append_vint(Util.encode_zigzag32(n))
|
448
|
+
end
|
449
|
+
|
450
|
+
def append_signed_vint64(n)
|
451
|
+
append_vint(Util.encode_zigzag64(n))
|
452
|
+
end
|
453
|
+
|
406
454
|
def eql?(other)
|
407
455
|
other.eql?(to_str)
|
408
456
|
end
|
@@ -264,15 +264,14 @@ module Cassandra
|
|
264
264
|
@timed_out = false
|
265
265
|
@scheduler = scheduler
|
266
266
|
@lock = Mutex.new
|
267
|
+
@timer = nil
|
267
268
|
super()
|
268
269
|
end
|
269
270
|
|
270
271
|
def time_out!
|
271
272
|
unless future.completed?
|
272
273
|
@timed_out = true
|
273
|
-
# rubocop:disable Style/SignalException
|
274
274
|
fail(Errors::TimeoutError.new('Timed out'))
|
275
|
-
# rubocop:enable Style/SignalException
|
276
275
|
end
|
277
276
|
end
|
278
277
|
|
@@ -51,6 +51,14 @@ module Cassandra
|
|
51
51
|
!!@payload
|
52
52
|
end
|
53
53
|
|
54
|
+
def append_flags(buffer,flags,protocol_version)
|
55
|
+
if protocol_version < 5
|
56
|
+
buffer.append(flags.chr)
|
57
|
+
else
|
58
|
+
buffer.append_int(flags)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
54
62
|
def write(buffer, protocol_version, encoder)
|
55
63
|
buffer.append_long_string(@cql)
|
56
64
|
buffer.append_consistency(@consistency)
|
@@ -63,10 +71,10 @@ module Cassandra
|
|
63
71
|
if @values && !@values.empty?
|
64
72
|
flags |= 0x01
|
65
73
|
flags |= 0x40 if protocol_version > 2 && !@names.empty?
|
66
|
-
buffer
|
74
|
+
append_flags(buffer, flags, protocol_version)
|
67
75
|
encoder.write_parameters(buffer, @values, @type_hints, @names)
|
68
76
|
else
|
69
|
-
buffer
|
77
|
+
append_flags(buffer, flags, protocol_version)
|
70
78
|
end
|
71
79
|
buffer.append_int(@page_size) if @page_size
|
72
80
|
buffer.append_bytes(@paging_state) if @paging_state
|
@@ -61,6 +61,9 @@ module Cassandra
|
|
61
61
|
|
62
62
|
class Decoder
|
63
63
|
def initialize(handler, compressor = nil, custom_type_handlers = {})
|
64
|
+
# In v4 the duration type is represented as a custom type so we always want to have
|
65
|
+
# a handler included here. This handler can be overridden via the connection options.
|
66
|
+
custom_type_handlers[Cassandra::Types::Duration.type] ||= Cassandra::Types::Duration
|
64
67
|
@handler = handler
|
65
68
|
@compressor = compressor
|
66
69
|
@state = :initial
|
data/lib/cassandra/table.rb
CHANGED
@@ -169,7 +169,7 @@ module Cassandra
|
|
169
169
|
|
170
170
|
cql << "\n)\nWITH "
|
171
171
|
|
172
|
-
if
|
172
|
+
if !@clustering_order.empty? && !@clustering_columns.empty?
|
173
173
|
cql << 'CLUSTERING ORDER BY ('
|
174
174
|
first = true
|
175
175
|
@clustering_columns.zip(@clustering_order) do |column, order|
|
data/lib/cassandra/types.rb
CHANGED
@@ -158,7 +158,7 @@ module Cassandra
|
|
158
158
|
end
|
159
159
|
|
160
160
|
def new_decimal(value)
|
161
|
-
|
161
|
+
BigDecimal(value)
|
162
162
|
end
|
163
163
|
|
164
164
|
def assert_decimal(value, message, &block)
|
@@ -1414,6 +1414,73 @@ module Cassandra
|
|
1414
1414
|
alias == eql?
|
1415
1415
|
end
|
1416
1416
|
|
1417
|
+
class Frozen < Type
|
1418
|
+
# @private
|
1419
|
+
attr_reader :value_type
|
1420
|
+
|
1421
|
+
# @private
|
1422
|
+
def initialize(value_type)
|
1423
|
+
super(:frozen)
|
1424
|
+
@value_type = value_type
|
1425
|
+
end
|
1426
|
+
|
1427
|
+
# Coerces the value to Array
|
1428
|
+
# @param value [Object] original value
|
1429
|
+
# @return [Array] value
|
1430
|
+
# @see Cassandra::Type#new
|
1431
|
+
def new(*value)
|
1432
|
+
value = Array(value.first) if value.one?
|
1433
|
+
|
1434
|
+
value.each do |v|
|
1435
|
+
Util.assert_type(@value_type, v)
|
1436
|
+
end
|
1437
|
+
value
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
# Asserts that a given value is an Array
|
1441
|
+
# @param value [Object] value to be validated
|
1442
|
+
# @param message [String] error message to use when assertion fails
|
1443
|
+
# @yieldreturn [String] error message to use when assertion fails
|
1444
|
+
# @raise [ArgumentError] if the value is not an Array
|
1445
|
+
# @return [void]
|
1446
|
+
# @see Cassandra::Type#assert
|
1447
|
+
def assert(value, message = nil, &block)
|
1448
|
+
Util.assert_instance_of(::Array, value, message, &block)
|
1449
|
+
value.each do |v|
|
1450
|
+
Util.assert_type(@value_type, v, message, &block)
|
1451
|
+
end
|
1452
|
+
nil
|
1453
|
+
end
|
1454
|
+
|
1455
|
+
# @return [String] `"list<type>"`
|
1456
|
+
# @see Cassandra::Type#to_s
|
1457
|
+
def to_s
|
1458
|
+
"frozen<#{@value_type}>"
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
def hash
|
1462
|
+
@hash ||= begin
|
1463
|
+
h = 17
|
1464
|
+
h = 31 * h + @kind.hash
|
1465
|
+
h = 31 * h + @value_type.hash
|
1466
|
+
h
|
1467
|
+
end
|
1468
|
+
end
|
1469
|
+
|
1470
|
+
def eql?(other)
|
1471
|
+
other.is_a?(List) && @value_type == other.value_type
|
1472
|
+
end
|
1473
|
+
|
1474
|
+
alias == eql?
|
1475
|
+
end
|
1476
|
+
|
1477
|
+
def frozen(value_type)
|
1478
|
+
Util.assert_instance_of(Cassandra::Type, value_type,
|
1479
|
+
"frozen type must be a Cassandra::Type, #{value_type.inspect} given")
|
1480
|
+
|
1481
|
+
Frozen.new(value_type)
|
1482
|
+
end
|
1483
|
+
|
1417
1484
|
# @return [Cassandra::Types::Text] text type since varchar is an alias for text
|
1418
1485
|
def varchar
|
1419
1486
|
Text
|
@@ -1633,5 +1700,9 @@ module Cassandra
|
|
1633
1700
|
def custom(name)
|
1634
1701
|
Custom.new(name)
|
1635
1702
|
end
|
1703
|
+
|
1704
|
+
def duration
|
1705
|
+
Duration.new 0,0,0
|
1706
|
+
end
|
1636
1707
|
end
|
1637
1708
|
end
|
data/lib/cassandra/util.rb
CHANGED
@@ -302,6 +302,26 @@ module Cassandra
|
|
302
302
|
end
|
303
303
|
end
|
304
304
|
|
305
|
+
def to_byte_array(n)
|
306
|
+
[n].pack("Q>").unpack("C*")
|
307
|
+
end
|
308
|
+
|
309
|
+
def to_min_byte_array(n)
|
310
|
+
to_byte_array(n).drop_while {|i| i == 0}
|
311
|
+
end
|
312
|
+
|
313
|
+
def decode_zigzag(n)
|
314
|
+
(n >> 1) ^ -(n & 1)
|
315
|
+
end
|
316
|
+
|
317
|
+
def encode_zigzag32(n)
|
318
|
+
(n >> 31) ^ (n << 1)
|
319
|
+
end
|
320
|
+
|
321
|
+
def encode_zigzag64(n)
|
322
|
+
(n >> 63) ^ (n << 1)
|
323
|
+
end
|
324
|
+
|
305
325
|
# @private
|
306
326
|
LOWERCASE_REGEXP = /[[:lower:]\_]*/
|
307
327
|
# @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: 3.2.
|
4
|
+
version: 3.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Theo Hultberg
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2020-10-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: ione
|
@@ -46,14 +46,14 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '13.0'
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
56
|
+
version: '13.0'
|
57
57
|
description: A pure Ruby driver for Apache Cassandra
|
58
58
|
email:
|
59
59
|
- theo@iconara.net
|
@@ -109,6 +109,7 @@ files:
|
|
109
109
|
- lib/cassandra/compression/compressors/snappy.rb
|
110
110
|
- lib/cassandra/custom_data.rb
|
111
111
|
- lib/cassandra/driver.rb
|
112
|
+
- lib/cassandra/duration.rb
|
112
113
|
- lib/cassandra/errors.rb
|
113
114
|
- lib/cassandra/execution/info.rb
|
114
115
|
- lib/cassandra/execution/options.rb
|
@@ -232,8 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
233
|
- !ruby/object:Gem::Version
|
233
234
|
version: '0'
|
234
235
|
requirements: []
|
235
|
-
|
236
|
-
rubygems_version: 2.4.5.1
|
236
|
+
rubygems_version: 3.0.8
|
237
237
|
signing_key:
|
238
238
|
specification_version: 4
|
239
239
|
summary: Datastax Ruby Driver for Apache Cassandra
|