arango-driver 3.5.0.alpha0

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.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +1073 -0
  4. data/arango_opal.js +15 -0
  5. data/lib/arango-driver.rb +61 -0
  6. data/lib/arango.rb +96 -0
  7. data/lib/arango/aql.rb +188 -0
  8. data/lib/arango/collection.rb +575 -0
  9. data/lib/arango/collection/documents.rb +122 -0
  10. data/lib/arango/collection/edges.rb +149 -0
  11. data/lib/arango/collection/importing.rb +57 -0
  12. data/lib/arango/collection/indexes.rb +53 -0
  13. data/lib/arango/collection/replication.rb +24 -0
  14. data/lib/arango/collection/user.rb +28 -0
  15. data/lib/arango/cursor.rb +67 -0
  16. data/lib/arango/database.rb +188 -0
  17. data/lib/arango/database/analyzer.rb +21 -0
  18. data/lib/arango/database/aql_functions.rb +54 -0
  19. data/lib/arango/database/aql_queries.rb +114 -0
  20. data/lib/arango/database/aql_query_cache.rb +27 -0
  21. data/lib/arango/database/collections.rb +100 -0
  22. data/lib/arango/database/foxx_services.rb +103 -0
  23. data/lib/arango/database/graph_access.rb +27 -0
  24. data/lib/arango/database/http_route.rb +9 -0
  25. data/lib/arango/database/replication.rb +96 -0
  26. data/lib/arango/database/stream_transactions.rb +25 -0
  27. data/lib/arango/database/tasks.rb +67 -0
  28. data/lib/arango/database/transactions.rb +15 -0
  29. data/lib/arango/database/user.rb +26 -0
  30. data/lib/arango/database/view_access.rb +37 -0
  31. data/lib/arango/document.rb +443 -0
  32. data/lib/arango/edge.rb +164 -0
  33. data/lib/arango/error.rb +97 -0
  34. data/lib/arango/error_db.rb +27 -0
  35. data/lib/arango/foxx.rb +255 -0
  36. data/lib/arango/graph.rb +202 -0
  37. data/lib/arango/graph/basics.rb +39 -0
  38. data/lib/arango/graph/edge_access.rb +56 -0
  39. data/lib/arango/graph/vertex_access.rb +33 -0
  40. data/lib/arango/helper/collection_assignment.rb +13 -0
  41. data/lib/arango/helper/database_assignment.rb +14 -0
  42. data/lib/arango/helper/request_method.rb +45 -0
  43. data/lib/arango/helper/return.rb +21 -0
  44. data/lib/arango/helper/satisfaction.rb +28 -0
  45. data/lib/arango/helper/server_assignment.rb +13 -0
  46. data/lib/arango/helper/traversal.rb +12 -0
  47. data/lib/arango/index.rb +103 -0
  48. data/lib/arango/replication.rb +231 -0
  49. data/lib/arango/request.rb +92 -0
  50. data/lib/arango/request_batch.rb +174 -0
  51. data/lib/arango/result.rb +130 -0
  52. data/lib/arango/search_view.rb +23 -0
  53. data/lib/arango/server.rb +68 -0
  54. data/lib/arango/server/administration.rb +296 -0
  55. data/lib/arango/server/agency.rb +23 -0
  56. data/lib/arango/server/async.rb +51 -0
  57. data/lib/arango/server/batch.rb +35 -0
  58. data/lib/arango/server/config.rb +76 -0
  59. data/lib/arango/server/databases.rb +71 -0
  60. data/lib/arango/server/monitoring.rb +17 -0
  61. data/lib/arango/server/opal_support.rb +95 -0
  62. data/lib/arango/server/tasks.rb +69 -0
  63. data/lib/arango/server/user.rb +22 -0
  64. data/lib/arango/task.rb +223 -0
  65. data/lib/arango/transaction.rb +113 -0
  66. data/lib/arango/traversal.rb +212 -0
  67. data/lib/arango/user.rb +174 -0
  68. data/lib/arango/version.rb +3 -0
  69. data/lib/arango/vertex.rb +112 -0
  70. data/lib/arango/view.rb +124 -0
  71. data/lib/arango/view/basics.rb +25 -0
  72. metadata +296 -0
@@ -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,14 @@
1
+ module Arango
2
+ module Helper
3
+ module DatabaseAssignment
4
+
5
+ protected
6
+
7
+ def assign_database(database)
8
+ satisfy_class?(database, [Arango::Database])
9
+ @database = database
10
+ @server = @database.arango_server
11
+ end
12
+ end
13
+ end
14
+ 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