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
data/lib/dse/graph.rb
ADDED
@@ -0,0 +1,18 @@
|
|
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
|
+
require 'dse/graph/edge'
|
11
|
+
require 'dse/graph/options'
|
12
|
+
require 'dse/graph/path'
|
13
|
+
require 'dse/graph/result'
|
14
|
+
require 'dse/graph/result_set'
|
15
|
+
require 'dse/graph/statement'
|
16
|
+
require 'dse/graph/vertex'
|
17
|
+
require 'dse/graph/vertex_property'
|
18
|
+
require 'dse/graph/duration'
|
@@ -0,0 +1,131 @@
|
|
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
|
+
# Represents a duration of time, corresponding to the Duration datatype in DSE Graph. In DSE Graph,
|
13
|
+
# this type is represented by the
|
14
|
+
# {https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html Java 8 Duration} type.
|
15
|
+
class Duration
|
16
|
+
# Days in duration of time. May be negative. Is internally coerced to an integer,
|
17
|
+
# so a value being assigned need not be an `Integer` itself.
|
18
|
+
# @return [Integer] days in duration of time.
|
19
|
+
attr_reader :days
|
20
|
+
|
21
|
+
# Hours in duration of time. May be negative. Is internally coerced to an integer,
|
22
|
+
# so a value being assigned need not be an `Integer` itself.
|
23
|
+
# @return [Integer] hours in duration of time.
|
24
|
+
attr_reader :hours
|
25
|
+
|
26
|
+
# Minutes in duration of time. May be negative. Is internally coerced to an integer,
|
27
|
+
# so a value being assigned need not be an `Integer` itself.
|
28
|
+
# @return [Integer] minutes in duration of time.
|
29
|
+
attr_reader :minutes
|
30
|
+
|
31
|
+
# Seconds in duration of time. May be negative. Is internally coerced to an float,
|
32
|
+
# so a value being assigned need not be an `Float` itself.
|
33
|
+
# @return [Float] seconds in duration of time.
|
34
|
+
attr_reader :seconds
|
35
|
+
|
36
|
+
# @private
|
37
|
+
# We expect a string of the form PnDTnHnMn.nS, where n's are positive or negative integers, and where
|
38
|
+
# components may be missing (e.g. PT7.8S is valid)
|
39
|
+
PAT = /^P((?<days>-?\d+)D)?T((?<hours>-?\d+)H)?((?<minutes>-?\d+)M)?((?<seconds>-?[0-9.]+)S)?$/
|
40
|
+
|
41
|
+
# Create a {Duration} object. All arguments are internally coerced to desired types.
|
42
|
+
# @param days [Integer] number of days in the time-frame. May be negative.
|
43
|
+
# @param hours [Integer] number of hours in the time-frame. May be negative.
|
44
|
+
# @param minutes [Integer] number of minutes in the time-frame. May be negative.
|
45
|
+
# @param seconds [Float] number of seconds in the time-frame. May be negative.
|
46
|
+
def initialize(days, hours, minutes, seconds)
|
47
|
+
@days = days.to_i
|
48
|
+
@hours = hours.to_i
|
49
|
+
@minutes = minutes.to_i
|
50
|
+
@seconds = seconds.to_f
|
51
|
+
end
|
52
|
+
|
53
|
+
def days=(days)
|
54
|
+
@days = days.to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
def hours=(hours)
|
58
|
+
@hours = hours.to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
def minutes=(minutes)
|
62
|
+
@minutes = minutes.to_i
|
63
|
+
end
|
64
|
+
|
65
|
+
def seconds=(seconds)
|
66
|
+
@seconds = seconds.to_f
|
67
|
+
end
|
68
|
+
|
69
|
+
# Parse a duration string from DSE Graph and construct a {Duration} object
|
70
|
+
# @param duration [String] duration string from DSE Graph.
|
71
|
+
# @raise [ArgumentError] if the duration string fails to parse.
|
72
|
+
def self.parse(duration)
|
73
|
+
parse_result = PAT.match(duration.to_s)
|
74
|
+
raise(ArgumentError,
|
75
|
+
"Failed to parse '#{duration}': expected format PnDTnHnMn.nS with integer n" \
|
76
|
+
' and optionally missing duration components') unless parse_result
|
77
|
+
Duration.new(parse_result[:days], parse_result[:hours], parse_result[:minutes], parse_result[:seconds])
|
78
|
+
end
|
79
|
+
|
80
|
+
# A string formatted as `PnDTnHnMn.nS`, where `n` is a number that goes with the character code following it.
|
81
|
+
#
|
82
|
+
# D - days<br>
|
83
|
+
# H - hours<br>
|
84
|
+
# M - minutes<br>
|
85
|
+
# S - seconds<br>
|
86
|
+
#
|
87
|
+
# @example a duration of 1 day, 2 hours, 3 minutes, 4.5 seconds
|
88
|
+
# P1DT2H3M4.5S
|
89
|
+
# @return [String] this {Duration} as a string formatted `PnDTnHnMn.nS`.
|
90
|
+
#
|
91
|
+
# @see https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-
|
92
|
+
# Java 8 Duration#parse
|
93
|
+
def to_s
|
94
|
+
# Construct a string of the form PnDTnHnMn.nS
|
95
|
+
"P#{@days}DT#{@hours}H#{@minutes}M#{@seconds}S"
|
96
|
+
end
|
97
|
+
|
98
|
+
# @private
|
99
|
+
def eql?(other)
|
100
|
+
other.is_a?(Duration) && as_seconds == other.as_seconds
|
101
|
+
end
|
102
|
+
alias == eql?
|
103
|
+
|
104
|
+
# @return [Float] this {Duration} object converted to seconds
|
105
|
+
def as_seconds
|
106
|
+
@seconds + @minutes * 60 + @hours * 3600 + @days * 86400
|
107
|
+
end
|
108
|
+
|
109
|
+
# @private
|
110
|
+
def hash
|
111
|
+
@hash ||= begin
|
112
|
+
h = 17
|
113
|
+
h = 31 * h + @days.hash
|
114
|
+
h = 31 * h + @hours.hash
|
115
|
+
h = 31 * h + @minutes.hash
|
116
|
+
h = 31 * h + @seconds.hash
|
117
|
+
h
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @private
|
122
|
+
def inspect
|
123
|
+
"#<Duration:0x#{object_id.to_s(16)} " \
|
124
|
+
"@days=#{@days.inspect}, " \
|
125
|
+
"@hours=#{@hours.inspect}, " \
|
126
|
+
"@minutes=#{@minutes.inspect}, " \
|
127
|
+
"@seconds=#{@seconds.inspect}>"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,74 @@
|
|
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
|
+
# Edge represents an edge in DSE graph. An edge connects two vertices.
|
13
|
+
class Edge
|
14
|
+
include Cassandra::Util
|
15
|
+
|
16
|
+
# @return [Hash] id of this edge
|
17
|
+
attr_reader :id
|
18
|
+
# @return [String] label of this edge
|
19
|
+
attr_reader :label
|
20
|
+
# @return [Hash<String, String>] properties of this edge
|
21
|
+
attr_reader :properties
|
22
|
+
# @return [String] id of the "to" vertex of the edge
|
23
|
+
attr_reader :in_v
|
24
|
+
# @return [String] label of the "to" vertex of the edge
|
25
|
+
attr_reader :in_v_label
|
26
|
+
# @return [String] id of the "from" vertex of the edge
|
27
|
+
attr_reader :out_v
|
28
|
+
# @return [String] label of the "from" vertex of the edge
|
29
|
+
attr_reader :out_v_label
|
30
|
+
|
31
|
+
# @private
|
32
|
+
def initialize(id, label, properties, in_v, in_v_label, out_v, out_v_label)
|
33
|
+
@id = id
|
34
|
+
@label = label
|
35
|
+
@properties = properties
|
36
|
+
@in_v = in_v
|
37
|
+
@in_v_label = in_v_label
|
38
|
+
@out_v = out_v
|
39
|
+
@out_v_label = out_v_label
|
40
|
+
end
|
41
|
+
|
42
|
+
# @private
|
43
|
+
def [](key)
|
44
|
+
@properties[key]
|
45
|
+
end
|
46
|
+
|
47
|
+
# @private
|
48
|
+
def eql?(other)
|
49
|
+
# id's are unique among graph objects, so we only need to compare id's to test for equality.
|
50
|
+
other.is_a?(Edge) && \
|
51
|
+
@id == other.id
|
52
|
+
end
|
53
|
+
alias == eql?
|
54
|
+
|
55
|
+
# @private
|
56
|
+
def hash
|
57
|
+
# id's are unique among graph objects, so we only need to hash on the id for safely adding to a hash/set.
|
58
|
+
@hash ||= 31 * 17 + @id.hash
|
59
|
+
end
|
60
|
+
|
61
|
+
# @private
|
62
|
+
def inspect
|
63
|
+
"#<Dse::Graph::Edge:0x#{object_id.to_s(16)} " \
|
64
|
+
"@id=#{@id.inspect}, " \
|
65
|
+
"@label=#{@label.inspect}, " \
|
66
|
+
"@properties=#{@properties.inspect}, " \
|
67
|
+
"@in_v=#{@in_v.inspect}, " \
|
68
|
+
"@in_v_label=#{@in_v_label.inspect}, " \
|
69
|
+
"@out_v=#{@out_v.inspect}, " \
|
70
|
+
"@out_v_label=#{@out_v_label.inspect}>"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,194 @@
|
|
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
|
+
# 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
|
31
|
+
class Options
|
32
|
+
# @return [Numeric] the timeout for graph requests
|
33
|
+
attr_reader :timeout
|
34
|
+
|
35
|
+
# @private
|
36
|
+
DEFAULT_GRAPH_OPTIONS = {
|
37
|
+
'graph-source' => 'g',
|
38
|
+
'graph-language' => 'gremlin-groovy'
|
39
|
+
}.freeze
|
40
|
+
|
41
|
+
# @private
|
42
|
+
OPTION_NAMES = [
|
43
|
+
:graph_name,
|
44
|
+
:graph_source,
|
45
|
+
:graph_language,
|
46
|
+
:graph_read_consistency,
|
47
|
+
:graph_write_consistency
|
48
|
+
].freeze
|
49
|
+
|
50
|
+
# Create an Options object.
|
51
|
+
# @param options [Hash] optional hash containing graph options. Keys are option name symbols
|
52
|
+
# (e.g. `:graph_name`). Unset options will inherit from the defaults.
|
53
|
+
def initialize(options = {})
|
54
|
+
# Filter the given options to only those we care about.
|
55
|
+
@real_options = {}
|
56
|
+
return unless options
|
57
|
+
|
58
|
+
options.each do |k, v|
|
59
|
+
set(k, v) if OPTION_NAMES.include?(k)
|
60
|
+
end
|
61
|
+
|
62
|
+
set_timeout(options[:timeout])
|
63
|
+
end
|
64
|
+
|
65
|
+
OPTION_NAMES.each do |attr|
|
66
|
+
define_method(attr.to_s) do
|
67
|
+
@real_options[stringify(attr)]
|
68
|
+
end
|
69
|
+
|
70
|
+
define_method("#{attr}=") do |value|
|
71
|
+
@real_options[stringify(attr)] = value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# @private
|
76
|
+
def timeout=(val)
|
77
|
+
set_timeout(val)
|
78
|
+
val
|
79
|
+
end
|
80
|
+
|
81
|
+
# @private
|
82
|
+
# rubocop:disable Style/AccessorMethodName
|
83
|
+
def set_timeout(new_timeout)
|
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
|
106
|
+
end
|
107
|
+
|
108
|
+
# Delete an option from this {Options} object.
|
109
|
+
# @param key [String, Symbol] option to delete.
|
110
|
+
# @return nil
|
111
|
+
def delete(key)
|
112
|
+
string_key = stringify(key)
|
113
|
+
if string_key == 'timeout'
|
114
|
+
@timeout = nil
|
115
|
+
@real_options.delete('request-timeout')
|
116
|
+
else
|
117
|
+
@real_options.delete(string_key)
|
118
|
+
end
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
|
122
|
+
# Merge another {Options} object with this one to produce a new merged {Options} object.
|
123
|
+
# The "other" object's values take precedence over this one.
|
124
|
+
# @param other [Options] Options object to merge with this one.
|
125
|
+
# @return [Options] new Options object with the merged options.
|
126
|
+
def merge(other)
|
127
|
+
# Just return our-self (no need to copy) if we're merging in nothing.
|
128
|
+
return self if other.nil?
|
129
|
+
|
130
|
+
# This is fairly efficient, but manipulates the guts of an Options object.
|
131
|
+
result = Options.new
|
132
|
+
result.instance_variable_set(:@real_options,
|
133
|
+
@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
|
+
result
|
138
|
+
end
|
139
|
+
|
140
|
+
# Clear the options within this {Options} object.
|
141
|
+
def clear
|
142
|
+
@real_options.clear
|
143
|
+
@timeout = nil
|
144
|
+
end
|
145
|
+
|
146
|
+
# @private
|
147
|
+
def stringify(attr)
|
148
|
+
attr.to_s.tr('_', '-')
|
149
|
+
end
|
150
|
+
|
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
|
+
# @return whether or not this options object is configured for the analytics graph source.
|
160
|
+
def analytics?
|
161
|
+
@real_options['graph-source'] == 'a'
|
162
|
+
end
|
163
|
+
|
164
|
+
# @private
|
165
|
+
def as_payload
|
166
|
+
# Merge in real options with defaults to get a final payload
|
167
|
+
DEFAULT_GRAPH_OPTIONS.merge(@real_options)
|
168
|
+
end
|
169
|
+
|
170
|
+
# @private
|
171
|
+
def eql?(other)
|
172
|
+
other.is_a?(Options) && \
|
173
|
+
@real_options == other.instance_variable_get(:@real_options)
|
174
|
+
end
|
175
|
+
alias == eql?
|
176
|
+
|
177
|
+
# @private
|
178
|
+
def hash
|
179
|
+
@hash ||= 31 * 17 + @real_options.hash
|
180
|
+
end
|
181
|
+
|
182
|
+
# @private
|
183
|
+
def inspect
|
184
|
+
"#<Dse::Graph::Options:0x#{object_id.to_s(16)} " \
|
185
|
+
"@graph_name=#{@real_options['graph-name'].inspect}, " \
|
186
|
+
"@graph_source=#{@real_options['graph-source'].inspect}, " \
|
187
|
+
"@graph_language=#{@real_options['graph-language'].inspect}, " \
|
188
|
+
"@graph_read_consistency=#{@real_options['graph-read-consistency'].inspect}, " \
|
189
|
+
"@graph_write_consistency=#{@real_options['graph-write-consistency'].inspect}, " \
|
190
|
+
"@timeout=#{@timeout.inspect}>"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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
|
+
# Path represents a path connecting a set of vertices.
|
13
|
+
class Path
|
14
|
+
# @return [Array<Array>] labels in the path
|
15
|
+
attr_reader :labels
|
16
|
+
# @return [Array<Vertex, Edge, Result>] objects in the path, coerced to domain objects that
|
17
|
+
# we recognize, or a {Result} otherwise
|
18
|
+
attr_reader :objects
|
19
|
+
|
20
|
+
# @private
|
21
|
+
def initialize(labels, objects)
|
22
|
+
@labels = labels
|
23
|
+
@objects = objects.map do |o|
|
24
|
+
Result.new(o).cast
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @private
|
29
|
+
def eql?(other)
|
30
|
+
other.is_a?(Path) && \
|
31
|
+
@labels == other.labels && \
|
32
|
+
@objects == other.objects
|
33
|
+
end
|
34
|
+
alias == eql?
|
35
|
+
|
36
|
+
# @private
|
37
|
+
def hash
|
38
|
+
@hash ||= begin
|
39
|
+
h = 17
|
40
|
+
h = 31 * h + @labels.hash
|
41
|
+
h = 31 * h + @objects.hash
|
42
|
+
h
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# @private
|
47
|
+
def inspect
|
48
|
+
"#<Dse::Graph::Path:0x#{object_id.to_s(16)} " \
|
49
|
+
"@labels=#{@labels.inspect}, " \
|
50
|
+
"@objects=#{@objects.inspect}>"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|