dse-driver 1.0.1
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 +15 -0
- data/.yardopts +13 -0
- data/README.md +72 -0
- data/ext/gss_api_context/extconf.rb +27 -0
- data/ext/gss_api_context/gss_api_context.c +129 -0
- data/ext/gss_api_context/kerberosgss.c +407 -0
- data/ext/gss_api_context/kerberosgss.h +71 -0
- data/lib/dse.rb +104 -0
- data/lib/dse/auth/providers/gss_api.rb +160 -0
- data/lib/dse/auth/providers/password.rb +56 -0
- data/lib/dse/cluster.rb +99 -0
- data/lib/dse/geometry/line_string.rb +181 -0
- data/lib/dse/geometry/point.rb +179 -0
- data/lib/dse/geometry/polygon.rb +196 -0
- data/lib/dse/graph.rb +18 -0
- data/lib/dse/graph/duration.rb +131 -0
- data/lib/dse/graph/edge.rb +74 -0
- data/lib/dse/graph/options.rb +194 -0
- data/lib/dse/graph/path.rb +54 -0
- data/lib/dse/graph/result.rb +85 -0
- data/lib/dse/graph/result_set.rb +77 -0
- data/lib/dse/graph/statement.rb +118 -0
- data/lib/dse/graph/vertex.rb +107 -0
- data/lib/dse/graph/vertex_property.rb +66 -0
- data/lib/dse/load_balancing/policies/host_targeting.rb +102 -0
- data/lib/dse/session.rb +106 -0
- data/lib/dse/statements.rb +15 -0
- data/lib/dse/statements/host_targeting.rb +50 -0
- data/lib/dse/util.rb +12 -0
- data/lib/dse/util/endian_buffer.rb +37 -0
- data/lib/dse/version.rb +12 -0
- metadata +123 -0
@@ -0,0 +1,102 @@
|
|
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 LoadBalancing
|
12
|
+
module Policies
|
13
|
+
# A load balancing policy that targets a particular host, and delegates to a lower-level policy if the
|
14
|
+
# host is not available.
|
15
|
+
# @private
|
16
|
+
class HostTargeting < Cassandra::LoadBalancing::Policy
|
17
|
+
# @private
|
18
|
+
class Plan
|
19
|
+
def initialize(targeted_host, policy, keyspace, statement, options)
|
20
|
+
@targeted_host = targeted_host
|
21
|
+
@policy = policy
|
22
|
+
@keyspace = keyspace
|
23
|
+
@statement = statement
|
24
|
+
@options = options
|
25
|
+
@first = true
|
26
|
+
end
|
27
|
+
|
28
|
+
def has_next?
|
29
|
+
@next = @targeted_host if @first && !@targeted_host.nil? && @targeted_host.up?
|
30
|
+
@first = false
|
31
|
+
return true if @next
|
32
|
+
|
33
|
+
@plan ||= @policy.plan(@keyspace, @statement, @options)
|
34
|
+
|
35
|
+
while @plan.has_next?
|
36
|
+
host = @plan.next
|
37
|
+
|
38
|
+
unless host == @targeted_host
|
39
|
+
@next = host
|
40
|
+
return true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
def next
|
48
|
+
host = @next
|
49
|
+
@next = nil
|
50
|
+
host
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
extend Forwardable
|
55
|
+
|
56
|
+
# @!method distance(host)
|
57
|
+
# Delegates to wrapped policy
|
58
|
+
# @see Cassandra::LoadBalancing::Policy#distance
|
59
|
+
#
|
60
|
+
# @!method host_found(host)
|
61
|
+
# Delegates to wrapped policy
|
62
|
+
# @see Cassandra::LoadBalancing::Policy#host_found
|
63
|
+
#
|
64
|
+
# @!method host_up(host)
|
65
|
+
# Delegates to wrapped policy
|
66
|
+
# @see Cassandra::LoadBalancing::Policy#host_up
|
67
|
+
#
|
68
|
+
# @!method host_down(host)
|
69
|
+
# Delegates to wrapped policy
|
70
|
+
# @see Cassandra::LoadBalancing::Policy#host_down
|
71
|
+
#
|
72
|
+
# @!method host_lost(host)
|
73
|
+
# Delegates to wrapped policy
|
74
|
+
# @see Cassandra::LoadBalancing::Policy#host_lost
|
75
|
+
def_delegators :@base_policy, :distance, :host_found, :host_up, :host_down, :host_lost
|
76
|
+
|
77
|
+
# @param base_policy [Cassandra::LoadBalancing::Policy] policy to delegate to if host is not available.
|
78
|
+
def initialize(base_policy)
|
79
|
+
@base_policy = base_policy
|
80
|
+
end
|
81
|
+
|
82
|
+
def setup(cluster)
|
83
|
+
@cluster = cluster
|
84
|
+
@base_policy.setup(cluster)
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
|
88
|
+
def teardown(cluster)
|
89
|
+
@cluster = nil
|
90
|
+
@base_policy.teardown(cluster)
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def plan(keyspace, statement, options)
|
95
|
+
# Fall back to creating a plan from the base policy if the statement is not host-targeting.
|
96
|
+
return @base_policy.plan(keyspace, statement, options) unless statement.is_a?(Dse::Statements::HostTargeting)
|
97
|
+
Plan.new(@cluster.host(statement.target_ip), @base_policy, keyspace, statement, options)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/dse/session.rb
ADDED
@@ -0,0 +1,106 @@
|
|
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
|
+
# A session is used to execute queries. In addition to executing standard CQL queries via the
|
12
|
+
# {http://dsdocs30/api/cassandra/session#execute-instance_method #execute} and
|
13
|
+
# {http://dsdocs30/api/cassandra/session#execute_async-instance_method #execute_async}
|
14
|
+
# methods, it executes graph queries via the {#execute_graph_async} and {#execute_graph} methods.
|
15
|
+
#
|
16
|
+
# @see http://dsdocs30/api/cassandra/session Cassandra::Session
|
17
|
+
class Session
|
18
|
+
# @private
|
19
|
+
def initialize(cassandra_session, graph_options, futures_factory)
|
20
|
+
@cassandra_session = cassandra_session
|
21
|
+
@graph_options = graph_options
|
22
|
+
@futures = futures_factory
|
23
|
+
end
|
24
|
+
|
25
|
+
# Execute a graph statement asynchronously.
|
26
|
+
# @param graph_statement [String, Dse::Graph::Statement] a graph statement
|
27
|
+
# @param options [Hash] a customizable set of options. All of the options supported by
|
28
|
+
# {Cassandra::Session#execute_async} are valid here. However, there are some extras, noted below.
|
29
|
+
# @option options [Hash] :arguments Parameters for the graph statement.
|
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
|
+
# @option options [String] :graph_name name of graph to use in graph statements
|
34
|
+
# @option options [String] :graph_source graph traversal source
|
35
|
+
# @option options [String] :graph_language language used in graph queries
|
36
|
+
# @option options [Cassandra::CONSISTENCIES] :graph_read_consistency read consistency level for graph statements.
|
37
|
+
# Overrides the standard statement consistency level
|
38
|
+
# @option options [Cassandra::CONSISTENCIES] :graph_write_consistency write consistency level for graph statements.
|
39
|
+
# Overrides the standard statement consistency level
|
40
|
+
# @return [Cassandra::Future<Cassandra::Result>]
|
41
|
+
# @see http://dsdocs30/api/cassandra/session#execute_async-instance_method
|
42
|
+
# Cassandra::Session::execute_async for all of the core options.
|
43
|
+
def execute_graph_async(graph_statement, options = {})
|
44
|
+
# Make our own copy of the options. The caller might want to re-use the options they provided, and we're
|
45
|
+
# about to do some destructive mutations.
|
46
|
+
|
47
|
+
options = options.dup
|
48
|
+
Cassandra::Util.assert_instance_of_one_of([String, Dse::Graph::Statement], graph_statement)
|
49
|
+
|
50
|
+
if graph_statement.is_a?(String)
|
51
|
+
graph_statement = Dse::Graph::Statement.new(graph_statement, options[:arguments], options, options[:idempotent])
|
52
|
+
end
|
53
|
+
|
54
|
+
graph_options = @graph_options.merge(graph_statement.options)
|
55
|
+
options[:payload] = graph_options.as_payload
|
56
|
+
options[:timeout] = graph_options.timeout
|
57
|
+
|
58
|
+
if graph_options.analytics?
|
59
|
+
@cassandra_session.execute_async('CALL DseClientTool.getAnalyticsGraphServer()').then do |rows|
|
60
|
+
row = rows.first
|
61
|
+
if row.nil? || row['result'].nil?
|
62
|
+
@cassandra_session.execute_async(graph_statement, options).then do |raw_result|
|
63
|
+
Dse::Graph::ResultSet.new(raw_result)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
ip = row['result']['ip']
|
67
|
+
targeted_statement = Dse::Statements::HostTargeting.new(graph_statement, ip)
|
68
|
+
@cassandra_session.execute_async(targeted_statement, options).then do |raw_result|
|
69
|
+
Dse::Graph::ResultSet.new(raw_result)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
else
|
74
|
+
@cassandra_session.execute_async(graph_statement, options).then do |raw_result|
|
75
|
+
Dse::Graph::ResultSet.new(raw_result)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
rescue => e
|
79
|
+
@futures.error(e)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Execute a graph statement synchronously.
|
83
|
+
# @see #execute_graph_async
|
84
|
+
# @return [Cassandra::Result] a Cassandra result containing individual JSON results.
|
85
|
+
def execute_graph(statement, options = {})
|
86
|
+
execute_graph_async(statement, options).get
|
87
|
+
end
|
88
|
+
|
89
|
+
#### The following methods handle arbitrary delegation to the underlying session object. ####
|
90
|
+
protected
|
91
|
+
|
92
|
+
# @private
|
93
|
+
def method_missing(method_name, *args, &block)
|
94
|
+
# If we get here, we don't have a method of our own. Forward the request to @cassandra_session.
|
95
|
+
# If it returns itself, we will coerce the result to return our *self* instead.
|
96
|
+
|
97
|
+
result = @cassandra_session.send(method_name, *args, &block)
|
98
|
+
(result == @cassandra_session) ? self : result
|
99
|
+
end
|
100
|
+
|
101
|
+
# @private
|
102
|
+
def respond_to?(method, include_private = false)
|
103
|
+
super || @cassandra_session.respond_to?(method, include_private)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
# @private
|
12
|
+
module Statements
|
13
|
+
end
|
14
|
+
end
|
15
|
+
require 'dse/statements/host_targeting'
|
@@ -0,0 +1,50 @@
|
|
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 Statements
|
12
|
+
# Wraps any query statement and attaches a target host, making it usable in a targeted load-balancing policy
|
13
|
+
# without modifying the user's statement.
|
14
|
+
# @private
|
15
|
+
class HostTargeting
|
16
|
+
include Cassandra::Util
|
17
|
+
include Cassandra::Statement
|
18
|
+
|
19
|
+
# @return the base statement to execute.
|
20
|
+
attr_reader :base_statement
|
21
|
+
# @return [String] the ip address of the host on which the statement should run if possible.
|
22
|
+
attr_reader :target_ip
|
23
|
+
|
24
|
+
def initialize(base_statement, target_ip)
|
25
|
+
@base_statement = base_statement
|
26
|
+
@target_ip = target_ip
|
27
|
+
end
|
28
|
+
|
29
|
+
# @private
|
30
|
+
def accept(client, options)
|
31
|
+
client.query(self, options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def idempotent?
|
35
|
+
@base_statement.idempotent?
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def method_missing(method_name, *args, &block)
|
41
|
+
# Delegate all method calls to the real statement that we're wrapping.
|
42
|
+
@base_statement.send(method_name, *args, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_to?(method, include_private = false)
|
46
|
+
super || @base_statement.respond_to?(method, include_private)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/dse/util.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2016 DataStax Inc.
|
3
|
+
#
|
4
|
+
# This software can be used solely with DataStax Enterprise. Please consult the license at
|
5
|
+
# http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
6
|
+
#++
|
7
|
+
|
8
|
+
module Dse
|
9
|
+
# @private
|
10
|
+
module Util
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,37 @@
|
|
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 Util
|
12
|
+
# Wrapper class around a Cassandra::Protocol::CqlByteBuffer that delegates reads of some
|
13
|
+
# numeric values to the appropriate underlying method, depending on endian-ness.
|
14
|
+
# @private
|
15
|
+
class EndianBuffer
|
16
|
+
def initialize(buffer, little_endian)
|
17
|
+
@buffer = buffer
|
18
|
+
# Depending on the endian-ness of the data, we want to invoke different read methods on the buffer.
|
19
|
+
if little_endian
|
20
|
+
@read_unsigned = buffer.method(:read_unsigned_int_le)
|
21
|
+
@read_double = buffer.method(:read_double_le)
|
22
|
+
else
|
23
|
+
@read_unsigned = buffer.method(:read_int)
|
24
|
+
@read_double = buffer.method(:read_double)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_unsigned
|
29
|
+
@read_unsigned.call
|
30
|
+
end
|
31
|
+
|
32
|
+
def read_double
|
33
|
+
@read_double.call
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/dse/version.rb
ADDED
@@ -0,0 +1,12 @@
|
|
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
|
+
VERSION = '1.0.1'.freeze
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dse-driver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sandeep Tamhankar
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: cassandra-driver
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
description: A pure Ruby driver for DataStax Enterprise
|
56
|
+
email:
|
57
|
+
- sandeep.tamhankar@datastax.com
|
58
|
+
executables: []
|
59
|
+
extensions:
|
60
|
+
- ext/gss_api_context/extconf.rb
|
61
|
+
extra_rdoc_files:
|
62
|
+
- README.md
|
63
|
+
files:
|
64
|
+
- .yardopts
|
65
|
+
- README.md
|
66
|
+
- ext/gss_api_context/extconf.rb
|
67
|
+
- ext/gss_api_context/gss_api_context.c
|
68
|
+
- ext/gss_api_context/kerberosgss.c
|
69
|
+
- ext/gss_api_context/kerberosgss.h
|
70
|
+
- lib/dse.rb
|
71
|
+
- lib/dse/auth/providers/gss_api.rb
|
72
|
+
- lib/dse/auth/providers/password.rb
|
73
|
+
- lib/dse/cluster.rb
|
74
|
+
- lib/dse/geometry/line_string.rb
|
75
|
+
- lib/dse/geometry/point.rb
|
76
|
+
- lib/dse/geometry/polygon.rb
|
77
|
+
- lib/dse/graph.rb
|
78
|
+
- lib/dse/graph/duration.rb
|
79
|
+
- lib/dse/graph/edge.rb
|
80
|
+
- lib/dse/graph/options.rb
|
81
|
+
- lib/dse/graph/path.rb
|
82
|
+
- lib/dse/graph/result.rb
|
83
|
+
- lib/dse/graph/result_set.rb
|
84
|
+
- lib/dse/graph/statement.rb
|
85
|
+
- lib/dse/graph/vertex.rb
|
86
|
+
- lib/dse/graph/vertex_property.rb
|
87
|
+
- lib/dse/load_balancing/policies/host_targeting.rb
|
88
|
+
- lib/dse/session.rb
|
89
|
+
- lib/dse/statements.rb
|
90
|
+
- lib/dse/statements/host_targeting.rb
|
91
|
+
- lib/dse/util.rb
|
92
|
+
- lib/dse/util/endian_buffer.rb
|
93
|
+
- lib/dse/version.rb
|
94
|
+
homepage: http://docs.datastax.com/en/developer/ruby-driver-dse/1.0
|
95
|
+
licenses: []
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options:
|
99
|
+
- --title
|
100
|
+
- Ruby Driver for DSE
|
101
|
+
- --main
|
102
|
+
- README.md
|
103
|
+
- --line-numbers
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.9.3
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.5.0
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Ruby Driver for DataStax Enterprise
|
122
|
+
test_files: []
|
123
|
+
has_rdoc:
|