arango-driver 3.5.0.alpha0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +1073 -0
- data/arango_opal.js +15 -0
- data/lib/arango-driver.rb +61 -0
- data/lib/arango.rb +96 -0
- data/lib/arango/aql.rb +188 -0
- data/lib/arango/collection.rb +575 -0
- data/lib/arango/collection/documents.rb +122 -0
- data/lib/arango/collection/edges.rb +149 -0
- data/lib/arango/collection/importing.rb +57 -0
- data/lib/arango/collection/indexes.rb +53 -0
- data/lib/arango/collection/replication.rb +24 -0
- data/lib/arango/collection/user.rb +28 -0
- data/lib/arango/cursor.rb +67 -0
- data/lib/arango/database.rb +188 -0
- data/lib/arango/database/analyzer.rb +21 -0
- data/lib/arango/database/aql_functions.rb +54 -0
- data/lib/arango/database/aql_queries.rb +114 -0
- data/lib/arango/database/aql_query_cache.rb +27 -0
- data/lib/arango/database/collections.rb +100 -0
- data/lib/arango/database/foxx_services.rb +103 -0
- data/lib/arango/database/graph_access.rb +27 -0
- data/lib/arango/database/http_route.rb +9 -0
- data/lib/arango/database/replication.rb +96 -0
- data/lib/arango/database/stream_transactions.rb +25 -0
- data/lib/arango/database/tasks.rb +67 -0
- data/lib/arango/database/transactions.rb +15 -0
- data/lib/arango/database/user.rb +26 -0
- data/lib/arango/database/view_access.rb +37 -0
- data/lib/arango/document.rb +443 -0
- data/lib/arango/edge.rb +164 -0
- data/lib/arango/error.rb +97 -0
- data/lib/arango/error_db.rb +27 -0
- data/lib/arango/foxx.rb +255 -0
- data/lib/arango/graph.rb +202 -0
- data/lib/arango/graph/basics.rb +39 -0
- data/lib/arango/graph/edge_access.rb +56 -0
- data/lib/arango/graph/vertex_access.rb +33 -0
- data/lib/arango/helper/collection_assignment.rb +13 -0
- data/lib/arango/helper/database_assignment.rb +14 -0
- data/lib/arango/helper/request_method.rb +45 -0
- data/lib/arango/helper/return.rb +21 -0
- data/lib/arango/helper/satisfaction.rb +28 -0
- data/lib/arango/helper/server_assignment.rb +13 -0
- data/lib/arango/helper/traversal.rb +12 -0
- data/lib/arango/index.rb +103 -0
- data/lib/arango/replication.rb +231 -0
- data/lib/arango/request.rb +92 -0
- data/lib/arango/request_batch.rb +174 -0
- data/lib/arango/result.rb +130 -0
- data/lib/arango/search_view.rb +23 -0
- data/lib/arango/server.rb +68 -0
- data/lib/arango/server/administration.rb +296 -0
- data/lib/arango/server/agency.rb +23 -0
- data/lib/arango/server/async.rb +51 -0
- data/lib/arango/server/batch.rb +35 -0
- data/lib/arango/server/config.rb +76 -0
- data/lib/arango/server/databases.rb +71 -0
- data/lib/arango/server/monitoring.rb +17 -0
- data/lib/arango/server/opal_support.rb +95 -0
- data/lib/arango/server/tasks.rb +69 -0
- data/lib/arango/server/user.rb +22 -0
- data/lib/arango/task.rb +223 -0
- data/lib/arango/transaction.rb +113 -0
- data/lib/arango/traversal.rb +212 -0
- data/lib/arango/user.rb +174 -0
- data/lib/arango/version.rb +3 -0
- data/lib/arango/vertex.rb +112 -0
- data/lib/arango/view.rb +124 -0
- data/lib/arango/view/basics.rb +25 -0
- metadata +296 -0
data/lib/arango/graph.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
# === GRAPH ===
|
2
|
+
|
3
|
+
module Arango
|
4
|
+
class Graph
|
5
|
+
include Arango::Helper::Satisfaction
|
6
|
+
include Arango::Helper::Return
|
7
|
+
include Arango::Helper::DatabaseAssignment
|
8
|
+
|
9
|
+
def initialize(name:, database:, body: {}, cache_name: nil, edge_definitions: [], is_smart: nil, number_of_shards: nil, orphan_collections: [],
|
10
|
+
replication_factor: nil, smart_graph_attribute: nil)
|
11
|
+
assign_database(database)
|
12
|
+
unless cache_name.nil?
|
13
|
+
@cache_name = cache_name
|
14
|
+
@server.cache.save(:graph, cache_name, self)
|
15
|
+
end
|
16
|
+
body[:_key] ||= name
|
17
|
+
body[:_id] ||= "_graphs/#{name}"
|
18
|
+
body[:edgeDefinitions] ||= edge_definitions
|
19
|
+
body[:isSmart] ||= is_smart
|
20
|
+
body[:numberOfShards] ||= number_of_shards
|
21
|
+
body[:orphanCollections] ||= orphan_collections
|
22
|
+
body[:replicationFactor] ||= replication_factor
|
23
|
+
body[:smartGraphAttribute] ||= smart_graph_attribute
|
24
|
+
assign_attributes(body)
|
25
|
+
end
|
26
|
+
|
27
|
+
# === DEFINE ===
|
28
|
+
|
29
|
+
attr_reader :body, :cache_name, :database, :id, :is_smart, :name, :rev, :server
|
30
|
+
attr_accessor :number_of_shards, :replication_factor, :smart_graph_attribute
|
31
|
+
alias key name
|
32
|
+
|
33
|
+
def body=(result)
|
34
|
+
@body = result
|
35
|
+
assign_edge_definitions(result[:edgeDefinitions] || @edge_definitions)
|
36
|
+
assign_orphan_collections(result[:orphanCollections] || @orphan_collections)
|
37
|
+
@name = result[:_key] || @name
|
38
|
+
@id = result[:_id] || @id
|
39
|
+
@id = "_graphs/#{@name}" if @id.nil? && !@name.nil?
|
40
|
+
@rev = result[:_rev] || @rev
|
41
|
+
@is_smart = result[:isSmart] || @is_smart
|
42
|
+
@number_of_shards = result[:numberOfShards] || @number_of_shards
|
43
|
+
@replication_factor = result[:replicationFactor] || @replication_factor
|
44
|
+
@smart_graph_attribute = result[:smartGraphAttribute] || @smart_graph_attribute
|
45
|
+
if @server.active_cache && @cache_name.nil?
|
46
|
+
@cache_name = "#{@database.name}/#{@name}"
|
47
|
+
@server.cache.save(:graph, @cache_name, self)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
alias assign_attributes body=
|
51
|
+
|
52
|
+
def name=(name)
|
53
|
+
@name = name
|
54
|
+
@id = "_graphs/#{@name}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def return_collection(collection, type=nil)
|
58
|
+
satisfy_class?(collection, [Arango::Collection, String])
|
59
|
+
case collection
|
60
|
+
when Arango::Collection
|
61
|
+
return collection
|
62
|
+
when String
|
63
|
+
return Arango::Collection.new(name: collection,
|
64
|
+
database: @database, type: type, graph: self)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def edge_definitions_raw
|
69
|
+
@edge_definitions ||= []
|
70
|
+
@edge_definitions.map do |edgedef|
|
71
|
+
{
|
72
|
+
collection: edgedef[:collection].name,
|
73
|
+
from: edgedef[:from].map{|t| t.name},
|
74
|
+
to: edgedef[:to].map{|t| t.name}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
private :edge_definitions_raw
|
79
|
+
|
80
|
+
def edge_definitions(raw=false)
|
81
|
+
return edge_definitions_raw if raw
|
82
|
+
return @edge_definitions
|
83
|
+
end
|
84
|
+
|
85
|
+
def edge_definitions=(edge_definitions)
|
86
|
+
@edge_definitions = []
|
87
|
+
edge_definitions ||= []
|
88
|
+
edge_definitions = [edge_definitions] unless edge_definitions.is_a?(Array)
|
89
|
+
edge_definitions.each do |edge_definition|
|
90
|
+
hash = {}
|
91
|
+
hash[:collection] = return_collection(edge_definition[:collection], :edge)
|
92
|
+
edge_definition[:from] ||= []
|
93
|
+
edge_definition[:to] ||= []
|
94
|
+
hash[:from] = edge_definition[:from].map{|t| return_collection(t)}
|
95
|
+
hash[:to] = edge_definition[:to].map{|t| return_collection(t)}
|
96
|
+
setup_orphan_collection_after_adding_edge_definitions(hash)
|
97
|
+
@edge_definitions << hash
|
98
|
+
end
|
99
|
+
end
|
100
|
+
alias assign_edge_definitions edge_definitions=
|
101
|
+
|
102
|
+
def orphan_collections=(orphan_collections)
|
103
|
+
orphan_collections ||= []
|
104
|
+
orphan_collections = [orphan_collections] unless orphan_collections.is_a?(Array)
|
105
|
+
@orphan_collections = orphan_collections.map{|oc| add_orphan_collection(oc)}
|
106
|
+
end
|
107
|
+
alias assign_orphan_collections orphan_collections=
|
108
|
+
|
109
|
+
def orphan_collections_raw
|
110
|
+
@orphan_collections ||= []
|
111
|
+
@orphan_collections.map{|oc| oc.name}
|
112
|
+
end
|
113
|
+
private :orphan_collections_raw
|
114
|
+
|
115
|
+
def orphan_collections(raw=false)
|
116
|
+
return orphan_collections_raw if raw
|
117
|
+
return @orphan_collections
|
118
|
+
end
|
119
|
+
|
120
|
+
# === HANDLE ORPHAN COLLECTION ===
|
121
|
+
|
122
|
+
def add_orphan_collection(orphanCollection)
|
123
|
+
orphanCollection = return_collection(orphanCollection)
|
124
|
+
if @edge_definitions.any? do |ed|
|
125
|
+
names = []
|
126
|
+
names |= ed[:from].map{|f| f&.name}
|
127
|
+
names |= ed[:to].map{|t| t&.name}
|
128
|
+
names.include?(orphanCollection.name)
|
129
|
+
end
|
130
|
+
raise Arango::Error.new err: :orphan_collection_used_by_edge_definition, data: {collection: orphanCollection.name}
|
131
|
+
end
|
132
|
+
return orphanCollection
|
133
|
+
end
|
134
|
+
private :add_orphan_collection
|
135
|
+
|
136
|
+
def setup_orphan_collection_after_adding_edge_definitions(edge_definition)
|
137
|
+
collection = []
|
138
|
+
collection |= edge_definition[:from]
|
139
|
+
collection |= edge_definition[:to]
|
140
|
+
@orphan_collections.delete_if{|c| collection.include?(c.name)}
|
141
|
+
end
|
142
|
+
private :setup_orphan_collection_after_adding_edge_definitions
|
143
|
+
|
144
|
+
def setup_orphan_collection_after_removing_edge_definitions(edge_definition)
|
145
|
+
edgeCollection = edge_definition[:collection].name
|
146
|
+
collections |= []
|
147
|
+
collections |= edge_definition[:from]
|
148
|
+
collections |= edge_definition[:to]
|
149
|
+
collections.each do |collection|
|
150
|
+
unless @edge_definitions.any? do |ed|
|
151
|
+
if ed[:collection].name != edgeCollection
|
152
|
+
names = []
|
153
|
+
names |= ed[:from].map{|f| f&.name}
|
154
|
+
names |= ed[:to].map{|t| t&.name}
|
155
|
+
names.include?(collection.name)
|
156
|
+
else
|
157
|
+
false
|
158
|
+
end
|
159
|
+
end
|
160
|
+
unless @orphan_collections.map{|oc| oc.name}.include?(collection.name)
|
161
|
+
@orphan_collections << collection
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
private :setup_orphan_collection_after_removing_edge_definitions
|
167
|
+
|
168
|
+
# === REQUEST ===
|
169
|
+
|
170
|
+
def request(action, url, body: {}, headers: {}, query: {}, key: nil, return_direct_result: false)
|
171
|
+
url = "_api/gharial/#{@name}/#{url}"
|
172
|
+
@database.request(action, url, body: body, headers: headers,
|
173
|
+
query: query, key: key, return_direct_result: return_direct_result)
|
174
|
+
end
|
175
|
+
|
176
|
+
# === TO HASH ===
|
177
|
+
|
178
|
+
def to_h
|
179
|
+
{
|
180
|
+
name: @name,
|
181
|
+
id: @id,
|
182
|
+
rev: @rev,
|
183
|
+
isSmart: @is_smart,
|
184
|
+
numberOfShards: @number_of_shards,
|
185
|
+
replicationFactor: @replication_factor,
|
186
|
+
smartGraphAttribute: @smart_graph_attribute,
|
187
|
+
edgeDefinitions: edge_definitions_raw,
|
188
|
+
orphanCollections: orphan_collections_raw,
|
189
|
+
cache_name: @cache_name,
|
190
|
+
database: @database.name
|
191
|
+
}.delete_if{|k,v| v.nil?}
|
192
|
+
end
|
193
|
+
|
194
|
+
# === GET ===
|
195
|
+
|
196
|
+
def retrieve
|
197
|
+
result = @database.request("GET", "_api/gharial/#{@name}", key: :graph)
|
198
|
+
return_element(result)
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Arango
|
2
|
+
module Graph
|
3
|
+
module Basics
|
4
|
+
def create(is_smart: @is_smart, smart_graph_attribute: @smart_graph_attribute,
|
5
|
+
number_of_shards: @number_of_shards)
|
6
|
+
body = {
|
7
|
+
name: @name,
|
8
|
+
edgeDefinitions: edge_definitions_raw,
|
9
|
+
orphanCollections: orphan_collections_raw,
|
10
|
+
isSmart: is_smart,
|
11
|
+
options: {
|
12
|
+
smartGraphAttribute: smart_graph_attribute,
|
13
|
+
numberOfShards: number_of_shards
|
14
|
+
}
|
15
|
+
}
|
16
|
+
body[:options].delete_if{|k,v| v.nil?}
|
17
|
+
body.delete(:options) if body[:options].empty?
|
18
|
+
result = @database.request("POST", "_api/gharial", body: body, key: :graph)
|
19
|
+
return_element(result)
|
20
|
+
end
|
21
|
+
|
22
|
+
def exist?
|
23
|
+
|
24
|
+
end
|
25
|
+
alias exists? exist?
|
26
|
+
|
27
|
+
def info
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def drop(dropCollections: nil)
|
32
|
+
query = { dropCollections: dropCollections }
|
33
|
+
result = @database.request("DELETE", "_api/gharial/#{@name}", query: query,
|
34
|
+
key: :removed)
|
35
|
+
return_delete(result)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Arango
|
2
|
+
module Graph
|
3
|
+
module EdgeAccess
|
4
|
+
def edge_collection
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
def edge_collections
|
9
|
+
result = request("GET", "edge", key: :collections)
|
10
|
+
return result if @database.server.async != false
|
11
|
+
return result if return_directly?(result)
|
12
|
+
result.map{|r| Arango::Collection.new(database: @database, name: r, type: :edge)}
|
13
|
+
end
|
14
|
+
|
15
|
+
def edge_definitions
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_edge_definition(collection:, from:, to:)
|
20
|
+
satisfy_class?(collection, [String, Arango::Collection])
|
21
|
+
satisfy_class?(from, [String, Arango::Collection], true)
|
22
|
+
satisfy_class?(to, [String, Arango::Collection], true)
|
23
|
+
from = [from] unless from.is_a?(Array)
|
24
|
+
to = [to] unless to.is_a?(Array)
|
25
|
+
body = {}
|
26
|
+
body[:collection] = collection.is_a?(String) ? collection : collection.name
|
27
|
+
body[:from] = from.map{|f| f.is_a?(String) ? f : f.name }
|
28
|
+
body[:to] = to.map{|t| t.is_a?(String) ? t : t.name }
|
29
|
+
result = request("POST", "edge", body: body, key: :graph)
|
30
|
+
return_element(result)
|
31
|
+
end
|
32
|
+
|
33
|
+
def replace_edge_definition(collection:, from:, to:)
|
34
|
+
satisfy_class?(collection, [String, Arango::Collection])
|
35
|
+
satisfy_class?(from, [String, Arango::Collection], true)
|
36
|
+
satisfy_class?(to, [String, Arango::Collection], true)
|
37
|
+
from = [from] unless from.is_a?(Array)
|
38
|
+
to = [to] unless to.is_a?(Array)
|
39
|
+
body = {}
|
40
|
+
body[:collection] = collection.is_a?(String) ? collection : collection.name
|
41
|
+
body[:from] = from.map{|f| f.is_a?(String) ? f : f.name }
|
42
|
+
body[:to] = to.map{|t| t.is_a?(String) ? t : t.name }
|
43
|
+
result = request("PUT", "edge/#{body[:collection]}", body: body, key: :graph)
|
44
|
+
return_element(result)
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_edge_definition(collection:, dropCollection: nil)
|
48
|
+
satisfy_class?(collection, [String, Arango::Collection])
|
49
|
+
query = {dropCollection: dropCollection}
|
50
|
+
collection = collection.is_a?(String) ? collection : collection.name
|
51
|
+
result = request("DELETE", "edge/#{collection}", query: query, key: :graph)
|
52
|
+
return_element(result)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Arango
|
2
|
+
module Graph
|
3
|
+
module VertexAccess
|
4
|
+
def vertex_collection
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
def vertex_collections
|
9
|
+
result = request("GET", "vertex", key: :collections)
|
10
|
+
return result if return_directly?(result)
|
11
|
+
result.map do |x|
|
12
|
+
Arango::Collection.new(name: x, database: @database, graph: self)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_vertex_collection(collection:)
|
17
|
+
satisfy_class?(collection, [String, Arango::Collection])
|
18
|
+
collection = collection.is_a?(String) ? collection : collection.name
|
19
|
+
body = { collection: collection }
|
20
|
+
result = request("POST", "vertex", body: body, key: :graph)
|
21
|
+
return_element(result)
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove_vertex_collection(collection:, dropCollection: nil)
|
25
|
+
query = {dropCollection: dropCollection}
|
26
|
+
satisfy_class?(collection, [String, Arango::Collection])
|
27
|
+
collection = collection.is_a?(String) ? collection : collection.name
|
28
|
+
result = request("DELETE", "vertex/#{collection}", query: query, key: :graph)
|
29
|
+
return_element(result)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Arango
|
2
|
+
module Helper
|
3
|
+
module CollectionAssignment
|
4
|
+
def assign_collection(collection)
|
5
|
+
satisfy_class?(collection, [Arango::Collection])
|
6
|
+
@collection = collection
|
7
|
+
@graph = @collection.graph
|
8
|
+
@database = @collection.database
|
9
|
+
@arango_server = @database.arango_server
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Arango
|
2
|
+
module Helper
|
3
|
+
module RequestMethod
|
4
|
+
def request_method(method_name, &block)
|
5
|
+
promise_method_name = "batch_#{method_name}".to_sym
|
6
|
+
define_method(method_name) do |*args|
|
7
|
+
request_hash = instance_exec(*args, &block)
|
8
|
+
@database.execute_request(request_hash)
|
9
|
+
end
|
10
|
+
define_method(promise_method_name) do |*args|
|
11
|
+
request_hash = instance_exec(*args, &block)
|
12
|
+
@database.batch_request(request_hash)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def multi_request_method(method_name, &block)
|
17
|
+
promise_method_name = "batch_#{method_name}".to_sym
|
18
|
+
define_method(method_name) do |*args|
|
19
|
+
requests = instance_exec(*args, &block)
|
20
|
+
@database.execute_requests(requests)
|
21
|
+
end
|
22
|
+
define_method(promise_method_name) do |*args|
|
23
|
+
requests= instance_exec(*args, &block)
|
24
|
+
promises = []
|
25
|
+
requests.each do |request_hash|
|
26
|
+
promises << @database.batch_request(request_hash)
|
27
|
+
end
|
28
|
+
Promise.when(*promises).then { |values| values.last }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def aql_request_method(method_name, &block)
|
33
|
+
promise_method_name = "batch_#{method_name}".to_sym
|
34
|
+
define_method(method_name) do |*args|
|
35
|
+
request_hash = instance_exec(*args, &block)
|
36
|
+
@database.execute_aql(request_hash)
|
37
|
+
end
|
38
|
+
define_method(promise_method_name) do |*args|
|
39
|
+
request_hash = instance_exec(*args, &block)
|
40
|
+
@database.batch_execute_aql(request_hash)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Arango
|
2
|
+
module Helper
|
3
|
+
module Return
|
4
|
+
def return_directly?(result)
|
5
|
+
return result if @server.async || @server.return_output
|
6
|
+
result == true
|
7
|
+
end
|
8
|
+
|
9
|
+
def return_element(result)
|
10
|
+
return result unless @server.async
|
11
|
+
assign_attributes(result)
|
12
|
+
return_directly?(result) ? result : self
|
13
|
+
end
|
14
|
+
|
15
|
+
def return_delete(result)
|
16
|
+
return result unless @server.async
|
17
|
+
return_directly?(result) ? result : true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Arango
|
2
|
+
module Helper
|
3
|
+
module Satisfaction
|
4
|
+
def satisfy_class?(object, classes=[String], array=false)
|
5
|
+
if array
|
6
|
+
object = [object] unless object.is_a?(Array)
|
7
|
+
object.each do |obj|
|
8
|
+
satisfy_class?(obj, classes, false)
|
9
|
+
end
|
10
|
+
else
|
11
|
+
return if classes.include?(object.class)
|
12
|
+
name ||= object.object_id.to_s
|
13
|
+
raise Arango::Error.new err: :wrong_class, data: { wrong_value: name, wrong_class: object.class.to_s, expected_class: classes.to_s }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def satisfy_category?(object, list)
|
18
|
+
return if list.include?(object)
|
19
|
+
name = object.object_id.to_s
|
20
|
+
raise Arango::Error.new err: :wrong_element, data: { wrong_attribute: name, wrong_value: object, list: list }
|
21
|
+
end
|
22
|
+
|
23
|
+
def warning_deprecated(warning, name)
|
24
|
+
puts "ARANGORB WARNING: #{name} function is deprecated" if warning
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|