dse-driver 1.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/README.md +70 -5
- data/lib/dse.rb +47 -18
- data/lib/dse/cluster.rb +13 -11
- data/lib/dse/graph.rb +1 -0
- data/lib/dse/graph/execution_profile.rb +88 -0
- data/lib/dse/graph/options.rb +35 -105
- data/lib/dse/graph/statement.rb +27 -18
- data/lib/dse/session.rb +21 -8
- data/lib/dse/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OWQ3OTgyN2JlZWI5MWZkZmU3YWU5ZmY5MmI1ZWJjMjlkY2RmN2FiMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YWUzMjJkMWIwZjI5N2RlOGJiYjI5M2QzOTEwMTJlNmIyM2M5YjcxYg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ODViODg2OTU5ZDQ2ZmYzODJhYzZhNWM2ODNmNTllNTk3YmM3ODJhYWIzZmRj
|
10
|
+
YTE0ZjRhYzRlNTc4ZTBiNmQ2ZjRkYzVlYmNhMTA4YTgyOGMzNDhmYTdmZWFh
|
11
|
+
ODNjYTY4ZmQwYTM2NGVhMzY2ODY3MjU1MmNhZDcxOWRlNDg1ZjA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MDM2ZTQyNTkzODg2MDZhZTE5NmJjNTFlMzg0M2E1YmFmMThhYTBhMjI2Y2Iy
|
14
|
+
MDlmNWU5YTE0OGNkNzZhZmEwYjJmZTc4NDRjMDM5Yjk1OTMwOTRiM2E0YzBj
|
15
|
+
NGViN2FjZjYwY2NhYzNmOGEzM2ZhYTcwNmQ4MTc2ODMyMjk3OTg=
|
data/README.md
CHANGED
@@ -2,15 +2,14 @@
|
|
2
2
|
|
3
3
|
*NOTE: The DataStax Enterprise Ruby Driver can be used solely with DataStax Enterprise. Please consult [the license](http://www.datastax.com/terms/datastax-dse-driver-license-terms).*
|
4
4
|
|
5
|
-
This driver is built on top of the [DataStax Ruby driver for Apache Cassandra](http://
|
5
|
+
This driver is built on top of the [DataStax Ruby driver for Apache Cassandra](http://dsdocs30)
|
6
6
|
and enhanced for the adaptive data management and mixed workload capabilities
|
7
7
|
provided by DSE. Therefore a lot of the underlying concepts are the same.
|
8
8
|
|
9
9
|
## Documentation
|
10
|
-
Driver documentation can be found [here](http://docs.datastax.com/en/
|
10
|
+
Driver documentation can be found [here](http://docs.datastax.com/en/developer/ruby-driver-dse).
|
11
11
|
|
12
|
-
In particular, you'll find our [Features](
|
13
|
-
[API](http://docs.datastax.com/en/latest-dse-ruby-driver/supplemental/api) sections very enlightening.
|
12
|
+
In particular, you'll find our [Features](features) and [API](api) sections very enlightening.
|
14
13
|
|
15
14
|
## Feedback Requested
|
16
15
|
*Help us focus our efforts!* [Provide your input](http://goo.gl/forms/pCs8PTpHLf) on the Ruby Driver
|
@@ -51,6 +50,72 @@ session = cluster.connect
|
|
51
50
|
rs = session.execute('select * from system.local')
|
52
51
|
```
|
53
52
|
|
53
|
+
|
54
|
+
## Breaking changes in 2.0
|
55
|
+
This release adds support for [graph execution profiles](features/graph#execution-profiles). As a result, the cluster-level `graph_options` object has
|
56
|
+
been removed. That object is effectively stored in the `:default_graph` execution profile. However, since execution
|
57
|
+
profiles are read-only, graph options in profiles cannot be manipulated. Instead, either specify new graph
|
58
|
+
options at query execution time, or use separate execution profiles for your different scenarios.
|
59
|
+
|
60
|
+
Furthermore, the `Dse::Graph::Options` class is no longer in the public api. Instead of constructing a
|
61
|
+
`Dse::Graph::Options` object and passing it to `Session.execute_graph*`, you must now pass the primitive graph options
|
62
|
+
or specify the name of an execution profile that encapsulates the desired graph options. Similarly, when creating a
|
63
|
+
`Dse::Graph::Statement`, you must specify primitive graph options instead of a `Dse::Graph::Options` object.
|
64
|
+
|
65
|
+
Since execution profiles are immutable, you must set expert options at construction time with the `expert_options`
|
66
|
+
hash. See the [documentation](features/graph#expert-options) for more details.
|
67
|
+
|
68
|
+
Another behavior change is that in v1.x, graph query timeout defaulted to unlimited. This caused queries to fall back to
|
69
|
+
server timeouts. The default was set this way to accommodate multi-day analytics queries and multi-second OLTP queries
|
70
|
+
without requiring intervention / special handling from the user. The introduction of execution profiles into the driver
|
71
|
+
enables the user to more easily run different types of queries:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# Use the default graph profile with its OLTP-motivated timeout (30 seconds)
|
75
|
+
rs = session.execute_graph('g.V()')
|
76
|
+
# Use the default graph analytics profile for an OLAP query (timeout 7 days)
|
77
|
+
rs = session.execute_graph('g.V()', execution_profile: :default_graph_analytics
|
78
|
+
# Use the default system query profile for graph system queries (timeout 3 minutes)
|
79
|
+
rs = session.execute_graph("system.graph('mygraph').exists()",
|
80
|
+
execution_profile: :default_graph_system)
|
81
|
+
```
|
82
|
+
Thus, no query runs with unlimited timeout by default as of this version of the driver.
|
83
|
+
|
84
|
+
Finally, in v1.x, graph query timeout was specified via the `:timeout` option in calls to `Session.execute_graph*` or
|
85
|
+
packaged up in a graph options object. Since the graph execution profile now assumes the role of graph options, use
|
86
|
+
the `:timeout` attribute in the graph execution profile to specify graph timeout. In particular, to set the default
|
87
|
+
graph timeout for graph queries, you must define your own `:default_graph` execution profile that will take precedence
|
88
|
+
over one that would normally be generated by the driver:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
cluster = Dse.cluster(execution_profiles: {
|
92
|
+
default_graph: Dse::Graph::ExecutionProfile.new(timeout: 17, graph_name: 'mygraph')
|
93
|
+
})
|
94
|
+
```
|
95
|
+
|
96
|
+
In the example above, the default graph timeout is set to 17 seconds. Note that you are not permitted to mix
|
97
|
+
primitive options (that are now available in execution profiles) with an execution_profiles hash when creating
|
98
|
+
the cluster object:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
# Illegal!
|
102
|
+
cluster = Dse.cluster(execution_profiles: {
|
103
|
+
default_graph: Dse::Graph::ExecutionProfile.new(timeout: 17, graph_name: 'mygraph')
|
104
|
+
}, timeout: 7)
|
105
|
+
|
106
|
+
```
|
107
|
+
|
108
|
+
Thus, in order to specify that non-graph queries should execute with a timeout of 7 seconds by default, you must
|
109
|
+
override the Cassandra default execution profile, named `:default`:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
# Legal.
|
113
|
+
cluster = Dse.cluster(execution_profiles: {
|
114
|
+
default_graph: Dse::Graph::ExecutionProfile.new(timeout: 17, graph_name: 'mygraph'),
|
115
|
+
default: Cassandra::Execution::Profile.new(timeout: 7)
|
116
|
+
})
|
117
|
+
```
|
118
|
+
|
54
119
|
## Determining driver versions
|
55
120
|
Within a script or irb, you can determine the exact versions of the dse and core drivers by accessing the VERSION
|
56
121
|
constant of the appropriate module:
|
@@ -69,4 +134,4 @@ previous versions of DSE.
|
|
69
134
|
## License
|
70
135
|
Copyright (C) 2016 DataStax Inc.
|
71
136
|
|
72
|
-
The full license terms are available at http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
137
|
+
The full license terms are available at http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
data/lib/dse.rb
CHANGED
@@ -22,8 +22,6 @@ module Dse
|
|
22
22
|
# The API is identical, except that it returns a {Dse::Session Dse::Session} (see below). It takes all of the same
|
23
23
|
# options as Cassandra.cluster and the following extra options.
|
24
24
|
#
|
25
|
-
# @option options [Dse::Graph::Options] :graph_options options for the DSE graph statement handler. Takes
|
26
|
-
# priority over other `:graph_*` options specified below.
|
27
25
|
# @option options [String] :graph_name name of graph to use in graph statements
|
28
26
|
# @option options [String] :graph_source graph traversal source
|
29
27
|
# @option options [String] :graph_language language used in graph queries
|
@@ -54,16 +52,20 @@ module Dse
|
|
54
52
|
# @return [Cassandra::Future<Dse::Cluster>] a future resolving to the
|
55
53
|
# cluster instance.
|
56
54
|
def self.cluster_async(options = {})
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
if options.key?(:execution_profiles)
|
56
|
+
[:graph_name, :graph_source, :graph_language, :graph_read_consistency, :graph_write_consistency].each do |opt|
|
57
|
+
raise ::ArgumentError, "#{opt} is not allowed when execution profiles are used" if options.key?(opt)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
63
61
|
username = options[:username]
|
64
62
|
password = options[:password]
|
65
63
|
options[:custom_types] ||= []
|
66
64
|
options[:custom_types] << Dse::Geometry::Point << Dse::Geometry::LineString << Dse::Geometry::Polygon
|
65
|
+
|
66
|
+
# validate_and_massage will return a new options hash, with non-C* options removed. Hold onto the original hash
|
67
|
+
# for attributes we still need later.
|
68
|
+
full_options = options
|
67
69
|
options, hosts = Cassandra.validate_and_massage_options(options)
|
68
70
|
|
69
71
|
# Use the DSE plain text authenticator if we have a username and password. The above validation already
|
@@ -75,18 +77,45 @@ module Dse
|
|
75
77
|
else
|
76
78
|
options[:cluster_klass] = Dse::Cluster
|
77
79
|
driver = ::Cassandra::Driver.new(options)
|
80
|
+
system_defaults = ::Cassandra::Driver.new
|
81
|
+
profile_manager = driver.profile_manager
|
82
|
+
unless profile_manager.profiles.key?(:default_graph)
|
83
|
+
# full_options has the graph options. But we don't want to use other attributes like load_balancing_policy, etc.
|
84
|
+
# in defining our default graph profile. So make a new hash that explicitly sets core profile attributes to
|
85
|
+
# system defaults.
|
86
|
+
graph_profile = Dse::Graph::ExecutionProfile.new(
|
87
|
+
full_options.merge(timeout: 30,
|
88
|
+
load_balancing_policy: system_defaults.load_balancing_policy,
|
89
|
+
retry_policy: system_defaults.retry_policy,
|
90
|
+
consistency: system_defaults.consistency
|
91
|
+
))
|
92
|
+
profile_manager.add_profile(:default_graph, graph_profile)
|
93
|
+
end
|
94
|
+
unless profile_manager.profiles.key?(:default_graph_system)
|
95
|
+
graph_profile = Dse::Graph::ExecutionProfile.new(graph_read_consistency: full_options[:graph_read_consistency],
|
96
|
+
graph_write_consistency: full_options[:graph_write_consistency],
|
97
|
+
timeout: 180)
|
98
|
+
profile_manager.add_profile(:default_graph_system, graph_profile)
|
99
|
+
end
|
100
|
+
unless profile_manager.profiles.key?(:default_graph_analytics)
|
101
|
+
# Wrap the system default load-balancing policy that we'd otherwise run, with a host-targeting policy, for the
|
102
|
+
# analytics profile.
|
78
103
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
104
|
+
# We do this before driver.connect because driver.connect saves off the policy in the cluster
|
105
|
+
# registry and does a few other things.
|
106
|
+
graph_profile = Dse::Graph::ExecutionProfile.new(
|
107
|
+
graph_source: 'a',
|
108
|
+
graph_name: full_options[:graph_name],
|
109
|
+
graph_read_consistency: full_options[:graph_read_consistency],
|
110
|
+
graph_write_consistency: full_options[:graph_write_consistency],
|
111
|
+
load_balancing_policy: Dse::LoadBalancing::Policies::HostTargeting.new(
|
112
|
+
system_defaults.load_balancing_policy
|
113
|
+
),
|
114
|
+
timeout: (3600 * 24 * 7)
|
115
|
+
)
|
116
|
+
profile_manager.add_profile(:default_graph_analytics, graph_profile)
|
89
117
|
end
|
118
|
+
driver.connect(hosts)
|
90
119
|
end
|
91
120
|
end
|
92
121
|
|
data/lib/dse/cluster.rb
CHANGED
@@ -11,9 +11,6 @@ module Dse
|
|
11
11
|
# Cluster represents a DSE cluster. It serves as a {Dse::Session session factory} and a collection of metadata.
|
12
12
|
# It wraps a {http://dsdocs30/api/cassandra/cluster Cassandra::Cluster} and exposes all of its functionality.
|
13
13
|
class Cluster
|
14
|
-
# @return [Dse::Graph::Options] default graph options used by queries on this cluster.
|
15
|
-
attr_reader :graph_options
|
16
|
-
|
17
14
|
# @private
|
18
15
|
def initialize(logger,
|
19
16
|
io_reactor,
|
@@ -24,9 +21,8 @@ module Dse
|
|
24
21
|
cluster_metadata,
|
25
22
|
execution_options,
|
26
23
|
connection_options,
|
27
|
-
|
24
|
+
profile_manager,
|
28
25
|
reconnection_policy,
|
29
|
-
retry_policy,
|
30
26
|
address_resolution_policy,
|
31
27
|
connector,
|
32
28
|
futures_factory,
|
@@ -40,21 +36,21 @@ module Dse
|
|
40
36
|
cluster_metadata,
|
41
37
|
execution_options,
|
42
38
|
connection_options,
|
43
|
-
|
39
|
+
profile_manager,
|
44
40
|
reconnection_policy,
|
45
|
-
retry_policy,
|
46
41
|
address_resolution_policy,
|
47
42
|
connector,
|
48
43
|
futures_factory,
|
49
44
|
timestamp_generator)
|
50
|
-
@graph_options = Dse::Graph::Options.new
|
51
|
-
|
52
45
|
# We need the futures factory ourselves for async error reporting and potentially for our
|
53
46
|
# own async processing independent of the C* driver.
|
54
47
|
@futures = futures_factory
|
48
|
+
|
49
|
+
# Similarly for profile-manager
|
50
|
+
@profile_manager = profile_manager
|
55
51
|
end
|
56
52
|
|
57
|
-
# Delegates to {http://
|
53
|
+
# Delegates to {http://dsdocs30/api/cassandra/cluster/?local=true&nav=toc#connect_async-instance_method
|
58
54
|
# Cassandra::Cluster#connect_async}
|
59
55
|
# to connect asynchronously to a cluster, but returns a future that will resolve to a DSE session rather than
|
60
56
|
# Cassandra session.
|
@@ -66,7 +62,7 @@ module Dse
|
|
66
62
|
future = @delegate_cluster.connect_async(keyspace)
|
67
63
|
# We want to actually return a DSE session upon successful connection.
|
68
64
|
future.then do |cassandra_session|
|
69
|
-
Dse::Session.new(cassandra_session, @
|
65
|
+
Dse::Session.new(cassandra_session, @profile_manager, @futures)
|
70
66
|
end
|
71
67
|
end
|
72
68
|
|
@@ -79,6 +75,12 @@ module Dse
|
|
79
75
|
connect_async(keyspace).get
|
80
76
|
end
|
81
77
|
|
78
|
+
# @private
|
79
|
+
def inspect
|
80
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
81
|
+
"@delegate_cluster=#{@delegate_cluster.inspect}>"
|
82
|
+
end
|
83
|
+
|
82
84
|
#### The following methods handle arbitrary delegation to the underlying cluster object. ####
|
83
85
|
protected
|
84
86
|
|
data/lib/dse/graph.rb
CHANGED
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2016 DataStax Inc.
|
5
|
+
#
|
6
|
+
# This software can be used solely with DataStax Enterprise. Please consult the license at
|
7
|
+
# http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
8
|
+
#++
|
9
|
+
|
10
|
+
module Dse
|
11
|
+
module Graph
|
12
|
+
# @!parse
|
13
|
+
# # Execution profile class that adds graph option support
|
14
|
+
# class ExecutionProfile < ::Cassandra::Execution::Profile
|
15
|
+
# # @return [String] name of the targeted graph; required unless the statement is a system query.
|
16
|
+
# attr_accessor :graph_name
|
17
|
+
# # @return [String] graph traversal source (default "g")
|
18
|
+
# attr_accessor :graph_source
|
19
|
+
# # @return [String] language used in the graph statement (default "gremlin-groovy")
|
20
|
+
# attr_accessor :graph_language
|
21
|
+
# # @return [Cassandra::CONSISTENCIES] read consistency level for graph statement.
|
22
|
+
# # Overrides the standard statement consistency level. Defaults to ONE in the server,
|
23
|
+
# # but the default may be configured differently.
|
24
|
+
# attr_accessor :graph_read_consistency
|
25
|
+
# # @return [Cassandra::CONSISTENCIES] write consistency level for graph statement.
|
26
|
+
# # Overrides the standard statement consistency level. Defaults to QUORUM in the server,
|
27
|
+
# # but the default may be configured differently.
|
28
|
+
# attr_accessor :graph_write_consistency
|
29
|
+
# end
|
30
|
+
|
31
|
+
|
32
|
+
class ExecutionProfile < ::Cassandra::Execution::Profile
|
33
|
+
extend Forwardable
|
34
|
+
|
35
|
+
# @private
|
36
|
+
attr_reader :graph_options
|
37
|
+
|
38
|
+
def_delegators :@graph_options, :graph_name, :graph_source, :graph_language, :graph_read_consistency,
|
39
|
+
:graph_write_consistency
|
40
|
+
|
41
|
+
# Creates a {ExecutionProfile} instance, which extends
|
42
|
+
# {http://dsdocs/api/cassandra/execution/profile Cassandra::Execution::Profile}.
|
43
|
+
# It takes all of the same options as the Cassandra::Execution::Profile constructor and
|
44
|
+
# the following extra options.
|
45
|
+
#
|
46
|
+
# @option options [String] :graph_name name of graph to use in graph statements
|
47
|
+
# @option options [String] :graph_source graph traversal source
|
48
|
+
# @option options [String] :graph_language language used in graph queries
|
49
|
+
# @option options [Cassandra::CONSISTENCIES] :graph_read_consistency read consistency level for graph statements.
|
50
|
+
# Overrides the standard statement consistency level
|
51
|
+
# @option options [Cassandra::CONSISTENCIES] :graph_write_consistency write consistency level for
|
52
|
+
# graph statements. Overrides the standard statement consistency level
|
53
|
+
def initialize(options = {})
|
54
|
+
options[:timeout] = 30 unless options[:timeout]
|
55
|
+
super(options)
|
56
|
+
@graph_options = Dse::Graph::Options.new(options)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @private
|
60
|
+
def eql?(other)
|
61
|
+
other.is_a?(ExecutionProfile) && \
|
62
|
+
super(other) && \
|
63
|
+
@graph_options == other.graph_options
|
64
|
+
end
|
65
|
+
alias == eql?
|
66
|
+
|
67
|
+
# @private
|
68
|
+
def hash
|
69
|
+
@hash ||= begin
|
70
|
+
h = super.hash
|
71
|
+
h = 31 * h + @graph_options.hash
|
72
|
+
h
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# @private
|
77
|
+
def inspect
|
78
|
+
"#<Dse::Graph::ExecutionProfile:0x#{object_id.to_s(16)} " \
|
79
|
+
"super=#{super.inspect}, " \
|
80
|
+
"@graph_name=#{@graph_options.graph_name.inspect}, " \
|
81
|
+
"@graph_source=#{@graph_options.graph_source.inspect}, " \
|
82
|
+
"@graph_language=#{@graph_options.graph_language.inspect}, " \
|
83
|
+
"@graph_read_consistency=#{@graph_options.graph_read_consistency.inspect}, " \
|
84
|
+
"@graph_write_consistency=#{@graph_options.graph_write_consistency.inspect}>"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/dse/graph/options.rb
CHANGED
@@ -9,29 +9,8 @@
|
|
9
9
|
|
10
10
|
module Dse
|
11
11
|
module Graph
|
12
|
-
#
|
13
|
-
# class Options
|
14
|
-
# # @return [String] name of the targeted graph; required unless the statement is a system query.
|
15
|
-
# attr_accessor :graph_name
|
16
|
-
# # @return [String] graph traversal source (default "g")
|
17
|
-
# attr_accessor :graph_source
|
18
|
-
# # @return [String] language used in the graph statement (default "gremlin-groovy")
|
19
|
-
# attr_accessor :graph_language
|
20
|
-
# # @return [Cassandra::CONSISTENCIES] read consistency level for graph statement.
|
21
|
-
# # Overrides the standard statement consistency level. Defaults to ONE in the server,
|
22
|
-
# # but the default may be configured differently.
|
23
|
-
# attr_accessor :graph_read_consistency
|
24
|
-
# # @return [Cassandra::CONSISTENCIES] write consistency level for graph statement.
|
25
|
-
# # Overrides the standard statement consistency level. Defaults to QUORUM in the server,
|
26
|
-
# # but the default may be configured differently.
|
27
|
-
# attr_accessor :graph_write_consistency
|
28
|
-
# end
|
29
|
-
|
30
|
-
# Options for DSE Graph queries
|
12
|
+
# @private Options for DSE Graph queries
|
31
13
|
class Options
|
32
|
-
# @return [Numeric] the timeout for graph requests
|
33
|
-
attr_reader :timeout
|
34
|
-
|
35
14
|
# @private
|
36
15
|
DEFAULT_GRAPH_OPTIONS = {
|
37
16
|
'graph-source' => 'g',
|
@@ -59,64 +38,40 @@ module Dse
|
|
59
38
|
set(k, v) if OPTION_NAMES.include?(k)
|
60
39
|
end
|
61
40
|
|
62
|
-
|
41
|
+
# Set expert options, if available.
|
42
|
+
if options.key?(:expert_options)
|
43
|
+
options[:expert_options].each do |k, v|
|
44
|
+
set(k, v)
|
45
|
+
end
|
46
|
+
end
|
63
47
|
end
|
64
48
|
|
65
49
|
OPTION_NAMES.each do |attr|
|
66
50
|
define_method(attr.to_s) do
|
67
51
|
@real_options[stringify(attr)]
|
68
52
|
end
|
69
|
-
|
70
|
-
define_method("#{attr}=") do |value|
|
71
|
-
@real_options[stringify(attr)] = value
|
72
|
-
end
|
73
53
|
end
|
74
54
|
|
75
55
|
# @private
|
76
|
-
def
|
77
|
-
|
78
|
-
|
56
|
+
def eql?(other)
|
57
|
+
other.is_a?(Options) && \
|
58
|
+
@real_options == other.instance_variable_get(:@real_options)
|
79
59
|
end
|
60
|
+
alias == eql?
|
80
61
|
|
81
62
|
# @private
|
82
|
-
|
83
|
-
|
84
|
-
@timeout = new_timeout
|
85
|
-
if @timeout
|
86
|
-
@real_options['request-timeout'] = [@timeout * 1000].pack('Q>')
|
87
|
-
else
|
88
|
-
@real_options.delete('request-timeout')
|
89
|
-
end
|
90
|
-
nil
|
91
|
-
end
|
92
|
-
|
93
|
-
# Set an option in this {Options} object. This is primarily used to set "expert" options that
|
94
|
-
# are not part of the public api and thus may change over time.
|
95
|
-
# @param key [String, Symbol] option to set.
|
96
|
-
# @param value [String] value to set for the option.
|
97
|
-
# @return [Options] self, thus allowing method chaining.
|
98
|
-
def set(key, value)
|
99
|
-
string_key = stringify(key)
|
100
|
-
if string_key == 'timeout'
|
101
|
-
set_timeout(value)
|
102
|
-
elsif value
|
103
|
-
@real_options[stringify(key)] = value
|
104
|
-
end
|
105
|
-
self
|
63
|
+
def hash
|
64
|
+
@hash ||= 31 * 17 + @real_options.hash
|
106
65
|
end
|
107
66
|
|
108
|
-
#
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
else
|
117
|
-
@real_options.delete(string_key)
|
118
|
-
end
|
119
|
-
nil
|
67
|
+
# @private
|
68
|
+
def inspect
|
69
|
+
"#<Dse::Graph::Options:0x#{object_id.to_s(16)} " \
|
70
|
+
"@graph_name=#{@real_options['graph-name'].inspect}, " \
|
71
|
+
"@graph_source=#{@real_options['graph-source'].inspect}, " \
|
72
|
+
"@graph_language=#{@real_options['graph-language'].inspect}, " \
|
73
|
+
"@graph_read_consistency=#{@real_options['graph-read-consistency'].inspect}, " \
|
74
|
+
"@graph_write_consistency=#{@real_options['graph-write-consistency'].inspect}>"
|
120
75
|
end
|
121
76
|
|
122
77
|
# Merge another {Options} object with this one to produce a new merged {Options} object.
|
@@ -131,63 +86,38 @@ module Dse
|
|
131
86
|
result = Options.new
|
132
87
|
result.instance_variable_set(:@real_options,
|
133
88
|
@real_options.merge(other.instance_variable_get(:@real_options)))
|
134
|
-
other_timeout = other.instance_variable_get(:@timeout)
|
135
|
-
result.instance_variable_set(:@timeout,
|
136
|
-
other_timeout ? other_timeout : @timeout)
|
137
89
|
result
|
138
90
|
end
|
139
91
|
|
140
|
-
# Clear the options within this {Options} object.
|
141
|
-
def clear
|
142
|
-
@real_options.clear
|
143
|
-
@timeout = nil
|
144
|
-
end
|
145
|
-
|
146
92
|
# @private
|
147
93
|
def stringify(attr)
|
148
94
|
attr.to_s.tr('_', '-')
|
149
95
|
end
|
150
96
|
|
151
|
-
# @private
|
152
|
-
def merge!(other)
|
153
|
-
result = merge(other)
|
154
|
-
@real_options = result.instance_variable_get(:@real_options)
|
155
|
-
@timeout = result.instance_variable_get(:@timeout)
|
156
|
-
self
|
157
|
-
end
|
158
|
-
|
159
97
|
# @return whether or not this options object is configured for the analytics graph source.
|
160
98
|
def analytics?
|
161
99
|
@real_options['graph-source'] == 'a'
|
162
100
|
end
|
163
101
|
|
164
102
|
# @private
|
165
|
-
def as_payload
|
103
|
+
def as_payload(timeout = nil)
|
166
104
|
# Merge in real options with defaults to get a final payload
|
167
|
-
DEFAULT_GRAPH_OPTIONS.merge(@real_options)
|
168
|
-
|
169
|
-
|
170
|
-
# @private
|
171
|
-
def eql?(other)
|
172
|
-
other.is_a?(Options) && \
|
173
|
-
@real_options == other.instance_variable_get(:@real_options)
|
105
|
+
result = DEFAULT_GRAPH_OPTIONS.merge(@real_options)
|
106
|
+
result['request-timeout'] = [timeout * 1000].pack('Q>') unless timeout.nil?
|
107
|
+
result
|
174
108
|
end
|
175
|
-
alias == eql?
|
176
109
|
|
177
|
-
|
178
|
-
def hash
|
179
|
-
@hash ||= 31 * 17 + @real_options.hash
|
180
|
-
end
|
110
|
+
private
|
181
111
|
|
182
|
-
#
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
"
|
189
|
-
|
190
|
-
|
112
|
+
# Set an option in this {Options} object. This is primarily used to set "expert" options that
|
113
|
+
# are not part of the public api and thus may change over time.
|
114
|
+
# @param key [String, Symbol] option to set.
|
115
|
+
# @param value [String] value to set for the option.
|
116
|
+
# @return [Options] self, thus allowing method chaining.
|
117
|
+
def set(key, value)
|
118
|
+
raise "can't modify frozen Dse::Graph::Options" if frozen?
|
119
|
+
@real_options[stringify(key)] = value if value
|
120
|
+
self
|
191
121
|
end
|
192
122
|
end
|
193
123
|
end
|
data/lib/dse/graph/statement.rb
CHANGED
@@ -13,19 +13,40 @@ module Dse
|
|
13
13
|
# re-issuing the same statement multiple times the same way.
|
14
14
|
class Statement
|
15
15
|
include Cassandra::Statement
|
16
|
+
extend Forwardable
|
17
|
+
|
18
|
+
# @!method graph_name
|
19
|
+
# @return [String] name of the targeted graph; required unless the statement is a system query.
|
20
|
+
#
|
21
|
+
# @!method graph_source
|
22
|
+
# @return [String] graph traversal source (default "g")
|
23
|
+
#
|
24
|
+
# @!method graph_language
|
25
|
+
# @return [String] language used in the graph statement (default "gremlin-groovy")
|
26
|
+
#
|
27
|
+
# @!method graph_read_consistency
|
28
|
+
# @return [Cassandra::CONSISTENCIES] read consistency level for graph statement.
|
29
|
+
# Overrides the standard statement consistency level. Defaults to ONE in the server,
|
30
|
+
# but the default may be configured differently.
|
31
|
+
# @!method graph_write_consistency
|
32
|
+
# @return [Cassandra::CONSISTENCIES] write consistency level for graph statement.
|
33
|
+
# Overrides the standard statement consistency level. Defaults to QUORUM in the server,
|
34
|
+
# but the default may be configured differently.
|
35
|
+
def_delegators :@options, :graph_name, :graph_source, :graph_language, :graph_read_consistency,
|
36
|
+
:graph_write_consistency
|
16
37
|
|
17
38
|
# @return [String] graph statement string
|
18
39
|
attr_reader :statement
|
19
40
|
# @return [Hash<String, String>] parameters to the statement
|
20
41
|
attr_reader :parameters
|
21
|
-
# @
|
42
|
+
# @private
|
22
43
|
attr_reader :options
|
23
44
|
# @private
|
24
45
|
attr_reader :simple_statement
|
25
46
|
|
26
47
|
# @param statement [String] graph statement
|
27
48
|
# @param parameters [Hash<String, String>] (nil) parameters to the statement
|
28
|
-
# @param options [Hash
|
49
|
+
# @param options [Hash] (nil) graph options
|
29
50
|
# @param idempotent [Boolean] (false) whether or not the statement is idempotent
|
30
51
|
def initialize(statement, parameters = nil, options = nil, idempotent = false)
|
31
52
|
# Save off statement and idempotent; easy stuff.
|
@@ -46,22 +67,10 @@ module Dse
|
|
46
67
|
parameters = [tweaked_params.to_json]
|
47
68
|
end
|
48
69
|
|
49
|
-
# Graph
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
# 3. options is an Options object; then just assign to @options.
|
54
|
-
|
55
|
-
unless options.nil?
|
56
|
-
Cassandra::Util.assert_instance_of_one_of([Dse::Graph::Options, ::Hash], options)
|
57
|
-
@options = if options.is_a?(Options)
|
58
|
-
options
|
59
|
-
elsif !options[:graph_options].nil?
|
60
|
-
Cassandra::Util.assert_instance_of(Dse::Graph::Options, options[:graph_options])
|
61
|
-
options[:graph_options]
|
62
|
-
else
|
63
|
-
Dse::Graph::Options.new(options)
|
64
|
-
end
|
70
|
+
# Create a Graph::Options object only if we have non-nil options.
|
71
|
+
unless options.nil? || options.empty?
|
72
|
+
Cassandra::Util.assert_instance_of(::Hash, options)
|
73
|
+
@options = Dse::Graph::Options.new(options)
|
65
74
|
end
|
66
75
|
|
67
76
|
@simple_statement = Cassandra::Statements::Simple.new(@statement,
|
data/lib/dse/session.rb
CHANGED
@@ -16,9 +16,9 @@ module Dse
|
|
16
16
|
# @see http://dsdocs30/api/cassandra/session Cassandra::Session
|
17
17
|
class Session
|
18
18
|
# @private
|
19
|
-
def initialize(cassandra_session,
|
19
|
+
def initialize(cassandra_session, profile_manager, futures_factory)
|
20
20
|
@cassandra_session = cassandra_session
|
21
|
-
@
|
21
|
+
@profile_manager = profile_manager
|
22
22
|
@futures = futures_factory
|
23
23
|
end
|
24
24
|
|
@@ -28,8 +28,6 @@ module Dse
|
|
28
28
|
# {Cassandra::Session#execute_async} are valid here. However, there are some extras, noted below.
|
29
29
|
# @option options [Hash] :arguments Parameters for the graph statement.
|
30
30
|
# NOTE: Unlike {#execute} and {#execute_async}, this must be a hash of <parameter-name,value>.
|
31
|
-
# @option options [Dse::Graph::Options] :graph_options options for the DSE graph statement handler. Takes
|
32
|
-
# priority over other `:graph_*` options specified below.
|
33
31
|
# @option options [String] :graph_name name of graph to use in graph statements
|
34
32
|
# @option options [String] :graph_source graph traversal source
|
35
33
|
# @option options [String] :graph_language language used in graph queries
|
@@ -37,6 +35,8 @@ module Dse
|
|
37
35
|
# Overrides the standard statement consistency level
|
38
36
|
# @option options [Cassandra::CONSISTENCIES] :graph_write_consistency write consistency level for graph statements.
|
39
37
|
# Overrides the standard statement consistency level
|
38
|
+
# @option options [String, Symbol] :execution_profile (:default_graph) name of {Dse::Graph::ExecutionProfile}
|
39
|
+
# from which to obtain certain query options.
|
40
40
|
# @return [Cassandra::Future<Cassandra::Result>]
|
41
41
|
# @see http://dsdocs30/api/cassandra/session#execute_async-instance_method
|
42
42
|
# Cassandra::Session::execute_async for all of the core options.
|
@@ -45,15 +45,28 @@ module Dse
|
|
45
45
|
# about to do some destructive mutations.
|
46
46
|
|
47
47
|
options = options.dup
|
48
|
+
|
48
49
|
Cassandra::Util.assert_instance_of_one_of([String, Dse::Graph::Statement], graph_statement)
|
50
|
+
arguments = nil
|
51
|
+
if options
|
52
|
+
Cassandra::Util.assert_instance_of(::Hash, options)
|
53
|
+
arguments = options.delete(:arguments)
|
54
|
+
end
|
49
55
|
|
50
56
|
if graph_statement.is_a?(String)
|
51
|
-
graph_statement = Dse::Graph::Statement.new(graph_statement,
|
57
|
+
graph_statement = Dse::Graph::Statement.new(graph_statement, arguments, options, options[:idempotent])
|
52
58
|
end
|
53
59
|
|
54
|
-
|
55
|
-
options[:
|
56
|
-
options[:
|
60
|
+
options[:execution_profile] ||= :default_graph
|
61
|
+
profile = @profile_manager.profiles[options[:execution_profile]]
|
62
|
+
Cassandra::Util.assert(!profile.nil?, "Profile '#{options[:execution_profile]}' does not exist")
|
63
|
+
Cassandra::Util.assert_instance_of(Dse::Graph::ExecutionProfile, profile)
|
64
|
+
|
65
|
+
graph_options = profile.graph_options.merge(graph_statement.options)
|
66
|
+
|
67
|
+
# The custom payload should have a 'request-timeout' that is the value of the :timeout option, if specified.
|
68
|
+
# Otherwise, fall back to the timeout in the execution profile.
|
69
|
+
options[:payload] = graph_options.as_payload(options[:timeout] || profile.timeout)
|
57
70
|
|
58
71
|
if graph_options.analytics?
|
59
72
|
@cassandra_session.execute_async('CALL DseClientTool.getAnalyticsGraphServer()').then do |rows|
|
data/lib/dse/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dse-driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sandeep Tamhankar
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cassandra-driver
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.0
|
19
|
+
version: 3.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.0
|
26
|
+
version: 3.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- lib/dse/graph.rb
|
78
78
|
- lib/dse/graph/duration.rb
|
79
79
|
- lib/dse/graph/edge.rb
|
80
|
+
- lib/dse/graph/execution_profile.rb
|
80
81
|
- lib/dse/graph/options.rb
|
81
82
|
- lib/dse/graph/path.rb
|
82
83
|
- lib/dse/graph/result.rb
|