arango-driver 3.5.0.alpha0

Sign up to get free protection for your applications and to get access to all the features.
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