arangorb3 0.0.10

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.
data/lib/Foxx.rb ADDED
@@ -0,0 +1,277 @@
1
+ # === FOXX ===
2
+
3
+ module Arango
4
+ class Foxx
5
+ include Arango::Helper_Error
6
+ include Arango::Helper_Return
7
+ include Arango::Database_Return
8
+
9
+ def self.new(*args)
10
+ hash = args[0]
11
+ super unless hash.is_a?(Hash)
12
+ database = hash[:database]
13
+ if database.is_a?(Arango::Database) && database.server.active_cache && !hash[:mount].nil?
14
+ cache_name = "#{database.name}/#{hash[:mount]}"
15
+ cached = database.server.cache.cache.dig(:foxx, cache_name)
16
+ if cached.nil?
17
+ hash[:cache_name] = cache_name
18
+ return super
19
+ else
20
+ body = hash[:body] || {}
21
+ [:mount, :development, :legacy, :provides, :name, :version,
22
+ :type, :setup, :teardown].each{|k| body[k] ||= hash[k]}
23
+ cached.assign_attributes(body)
24
+ return cached
25
+ end
26
+ end
27
+ super
28
+ end
29
+
30
+ def initialize(database:, body: {}, mount:, development: nil, legacy: nil,
31
+ provides: nil, name: nil, version: nil, type: "application/json",
32
+ setup: nil, teardown: nil, cache_name: nil)
33
+ assign_database(database)
34
+ unless cache_name.nil?
35
+ @cache_name = cache_name
36
+ @server.cache.save(:foxx, cache_name, self)
37
+ end
38
+ assign_attributes(body)
39
+ assign_type(type)
40
+ @mount ||= mount
41
+ @development ||= development
42
+ @setup ||= setup
43
+ @legacy ||= legacy
44
+ @provides ||= provides
45
+ @name ||= name
46
+ @version ||= version
47
+ @teardown ||= teardown
48
+ end
49
+
50
+ # === DEFINE ===
51
+
52
+ attr_reader :database, :server, :type, :body, :cache_name
53
+ attr_accessor :name, :development, :legacy, :provides,
54
+ :version, :mount, :setup, :teardown
55
+
56
+ def body=(result)
57
+ if result.is_a?(Hash)
58
+ @body = result
59
+ @name = result[:name] || @name
60
+ @version = result[:version] || @version
61
+ @mount = result[:mount] || @mount
62
+ @development = result[:development] || @development
63
+ @legacy = result[:legacy] || @legacy
64
+ @provides = result[:provides] || @provides
65
+ if @server.active_cache && @cache_name.nil?
66
+ @cache_name = "#{@database.name}/#{@mount}"
67
+ @server.cache.save(:task, @cache_name, self)
68
+ end
69
+ end
70
+ end
71
+ alias assign_attributes body=
72
+
73
+ def type=(type)
74
+ satisfy_category?(type, ["application/zip", "zip", "application/javascript", "javascript", "application/json", "json", "multipart/form-data", "data"], "type")
75
+ type = "application/#{type}" if ["zip", "javascript", "json"].include?(type)
76
+ type = "multipart/form-data" if type == "data"
77
+ @type = type
78
+ end
79
+ alias assign_type type=
80
+
81
+ # === TO HASH ===
82
+
83
+ def to_h
84
+ {
85
+ "name": @name,
86
+ "version": @version,
87
+ "mount": @mount,
88
+ "development": @development,
89
+ "legacy": @legacy,
90
+ "provides": @provides,
91
+ "type": @type,
92
+ "teardown": @teardown,
93
+ "cache_name": @cache_name,
94
+ "database": @database.name
95
+ }.delete_if{|k,v| v.nil?}
96
+ end
97
+
98
+ def return_foxx(result, val=nil)
99
+ return result if @server.async != false
100
+ case val
101
+ when :configuration
102
+ @configuration = result
103
+ when :dependencies
104
+ @dependencies = result
105
+ else
106
+ assign_attributes(result)
107
+ end
108
+ return return_directly?(result) ? result : self
109
+ end
110
+ private :return_foxx
111
+
112
+ # === ACTIONS ===
113
+
114
+ def retrieve
115
+ query = {"mount": @mount}
116
+ result = @database.request("GET", url: "_api/foxx/service")
117
+ return_foxx(result)
118
+ end
119
+
120
+ def create(body: @body, type: @type, development: @development,
121
+ setup: @setup, legacy: @legacy)
122
+ headers = {"Accept": type}
123
+ skip_to_json = type != "application/json"
124
+ query = {
125
+ "mount": @mount,
126
+ "setup": setup,
127
+ "development ": development ,
128
+ "legacy": legacy
129
+ }
130
+ result = @database.request("POST",
131
+ url: "_api/foxx", body: body, headers: headers,
132
+ skip_to_json: skip_to_json, query: query)
133
+ return_foxx(result)
134
+ end
135
+
136
+ def destroy(teardown: @teardown)
137
+ query = {
138
+ "mount": @mount,
139
+ "teardown": teardown
140
+ }
141
+ result = @database.request("DELETE", "_api/foxx/service", query: query)
142
+ return_foxx(result)
143
+ end
144
+
145
+ def replace(body: @body, type: @type, teardown: @teardown, setup: @setup,
146
+ legacy: @legacy)
147
+ headers = {"Accept": type}
148
+ skip_to_json = type != "application/json"
149
+ query = {
150
+ "mount": @mount,
151
+ "setup": setup,
152
+ "development ": development,
153
+ "legacy": legacy
154
+ }
155
+ result = @database.request("PUT", "_api/foxx/service", body: body,
156
+ headers: headers, skip_to_json: skip_to_json, query: query)
157
+ return_foxx(result)
158
+ end
159
+
160
+ def update(body: @body, type: @type, teardown: @teardown,
161
+ setup: @setup, legacy: @legacy)
162
+ assign_type(type)
163
+ headers = {"Accept": type}
164
+ skip_to_json = @type != "application/json"
165
+ query = {
166
+ "mount": @mount,
167
+ "setup": setup,
168
+ "development ": development,
169
+ "legacy": legacy
170
+ }
171
+ result = @database.request("PATCH", "_api/foxx/service", body: body,
172
+ headers: headers, skip_to_json: skip_to_json, query: query)
173
+ return_foxx(result)
174
+ end
175
+
176
+ # === CONFIGURATION ===
177
+
178
+ def retrieveConfiguration
179
+ query = {"mount": @mount}
180
+ result = @database.request("GET", "_api/foxx/configuration", query: query)
181
+ return_foxx(result, :configuration)
182
+ end
183
+
184
+ def updateConfiguration(body:)
185
+ query = {"mount": @mount}
186
+ result = @database.request("PATCH", "_api/foxx/configuration", query: query, body: body)
187
+ return_foxx(result, :configuration)
188
+ end
189
+
190
+ def replaceConfiguration(body:)
191
+ query = {"mount": @mount}
192
+ result = @database.request("PUT", "_api/foxx/configuration", query: query, body: body)
193
+ return_foxx(result, :configuration)
194
+ end
195
+
196
+ # === DEPENDENCY ===
197
+
198
+ def retrieveDependencies
199
+ query = {"mount": @mount}
200
+ result = @database.request("GET", "_api/foxx/dependencies", query: query)
201
+ return_foxx(result, :dependencies)
202
+ end
203
+
204
+ def updateDependencies(body:)
205
+ query = {"mount": @mount}
206
+ result = @database.request("PATCH", "_api/foxx/dependencies", query: query, body: body)
207
+ return_foxx(result, :dependencies)
208
+ end
209
+
210
+ def replaceDependencies(body:)
211
+ query = {"mount": @mount}
212
+ result = @database.request("PUT", "_api/foxx/dependencies", query: query, body: body)
213
+ return_foxx(result, :dependencies)
214
+ end
215
+
216
+ # === MISCELLANEOUS
217
+
218
+ def scripts
219
+ query = {"mount": @mount}
220
+ @database.request("GET", "_api/foxx/scripts", query: query)
221
+ end
222
+
223
+ def run_script(name:, body: {})
224
+ query = {"mount": @mount}
225
+ @database.request("POST", "_api/foxx/scripts/#{name}", query: query, body: body)
226
+ end
227
+
228
+ def tests(reporter: nil, idiomatic: nil)
229
+ satisfy_category?(reporter, [nil, "default", "suite", "stream", "xunit", "tap"])
230
+ headers = {}
231
+ headers[:"Content-Type"] = case reporter
232
+ when "stream"
233
+ "application/x-ldjson"
234
+ when "tap"
235
+ "text/plain, text/*"
236
+ when "xunit"
237
+ "application/xml, text/xml"
238
+ else
239
+ nil
240
+ end
241
+ query = {"mount": @mount}
242
+ @database.request("GET", "_api/foxx/scripts", query: query, headers: headers)
243
+ end
244
+
245
+ def enableDevelopment
246
+ query = {"mount": @mount}
247
+ @database.request("POST", "_api/foxx/development", query: query)
248
+ end
249
+
250
+ def disableDevelopment
251
+ query = {"mount": @mount}
252
+ @database.request("DELETE", "_api/foxx/development", query: query)
253
+ end
254
+
255
+ def readme
256
+ query = {"mount": @mount}
257
+ @database.request("GET", "_api/foxx/readme", query: query)
258
+ end
259
+
260
+ def swagger
261
+ query = {"mount": @mount}
262
+ @database.request("GET", "_api/foxx/swagger", query: query)
263
+ end
264
+
265
+ def download(path:, warning: @server.warning)
266
+ query = {"mount": @mount}
267
+ @server.download("POST", "_db/#{@database.name}/_api/foxx/download",
268
+ path: path, query: query)
269
+ puts "File saved in #{path}" if warning
270
+ end
271
+
272
+ def commit(body:, replace: nil)
273
+ query = {"replace": replace}
274
+ @database.request("POST", "_api/foxx/commit", body: body, query: query)
275
+ end
276
+ end
277
+ end
data/lib/Graph.rb ADDED
@@ -0,0 +1,325 @@
1
+ # === GRAPH ===
2
+
3
+ module Arango
4
+ class Graph
5
+ include Arango::Helper_Error
6
+ include Arango::Helper_Return
7
+ include Arango::Database_Return
8
+
9
+ def self.new(*args)
10
+ hash = args[0]
11
+ super unless hash.is_a?(Hash)
12
+ database = hash[:database]
13
+ if database.is_a?(Arango::Database) && database.server.active_cache
14
+ cache_name = "#{database.name}/#{hash[:name]}"
15
+ cached = database.server.cache.cache.dig(:graph, cache_name)
16
+ if cached.nil?
17
+ hash[:cache_name] = cache_name
18
+ return super
19
+ else
20
+ body = hash[:body] || {}
21
+ [:isSmart, :edgeDefinitions, :orphanCollections, :numberOfShards,
22
+ :replicationFactor, :smartGraphAttribute].each{|k| body[k] ||= hash[k]}
23
+ cached.assign_attributes(body)
24
+ return cached
25
+ end
26
+ end
27
+ super
28
+ end
29
+
30
+ def initialize(name:, database:, edgeDefinitions: [],
31
+ orphanCollections: [], body: {}, numberOfShards: nil, isSmart: nil,
32
+ smartGraphAtttribute: nil, replicationFactor: nil, cache_name: nil)
33
+ assign_database(database)
34
+ unless cache_name.nil?
35
+ @cache_name = cache_name
36
+ @server.cache.save(:graph, cache_name, self)
37
+ end
38
+ body[:_key] ||= name
39
+ body[:_id] ||= "_graphs/#{name}"
40
+ body[:isSmart] ||= isSmart
41
+ body[:edgeDefinitions] ||= edgeDefinitions
42
+ body[:orphanCollections] ||= orphanCollections
43
+ body[:numberOfShards] ||= numberOfShards
44
+ body[:replicationFactor] ||= replicationFactor
45
+ body[:smartGraphAttribute] ||= smartGraphAttribute
46
+ assign_attributes(body)
47
+ end
48
+
49
+ # === DEFINE ===
50
+
51
+ attr_reader :name, :database, :server, :id, :body, :rev, :isSmart, :cache_name
52
+ attr_accessor :numberOfShards, :replicationFactor, :smartGraphAttribute
53
+ alias key name
54
+
55
+ def body=(result)
56
+ @body = result
57
+ assign_edgeDefinitions(result[:edgeDefinitions] || @edgeDefinitions)
58
+ assign_orphanCollections(result[:orphanCollections] || @orphanCollections)
59
+ @name = result[:_key] || @name
60
+ @id = result[:_id] || @id
61
+ @id = "_graphs/#{@name}" if @id.nil? && !@name.nil?
62
+ @rev = result[:_rev] || @rev
63
+ @isSmart = result[:isSmart] || @isSmart
64
+ @numberOfShards = result[:numberOfShards] || @numberOfShards
65
+ @replicationFactor = result[:replicationFactor] || @replicationFactor
66
+ @smartGraphAttribute = result[:smartGraphAttribute] || @smartGraphAttribute
67
+ if @server.active_cache && @cache_name.nil?
68
+ @cache_name = "#{@database.name}/#{@name}"
69
+ @server.cache.save(:graph, @cache_name, self)
70
+ end
71
+ end
72
+ alias assign_attributes body=
73
+
74
+ def name=(name)
75
+ @name = name
76
+ @id = "_graphs/#{@name}"
77
+ end
78
+
79
+ def return_collection(collection, type=nil)
80
+ satisfy_class?(collection, [Arango::Collection, String])
81
+ case collection
82
+ when Arango::Collection
83
+ return collection
84
+ when String
85
+ return Arango::Collection.new(name: collection,
86
+ database: @database, type: type, graph: self)
87
+ end
88
+ end
89
+
90
+ def edgeDefinitionsRaw
91
+ @edgeDefinitions ||= []
92
+ @edgeDefinitions.map do |edgedef|
93
+ {
94
+ "collection": edgedef[:collection].name,
95
+ "from": edgedef[:from].map{|t| t.name},
96
+ "to": edgedef[:to].map{|t| t.name}
97
+ }
98
+ end
99
+ end
100
+ private :edgeDefinitionsRaw
101
+
102
+ def edgeDefinitions(raw=false)
103
+ return edgeDefinitionsRaw if raw
104
+ return @edgeDefinitions
105
+ end
106
+
107
+ def edgeDefinitions=(edgeDefinitions)
108
+ @edgeDefinitions = []
109
+ edgeDefinitions ||= []
110
+ edgeDefinitions = [edgeDefinitions] unless edgeDefinitions.is_a?(Array)
111
+ edgeDefinitions.each do |edgeDefinition|
112
+ hash = {}
113
+ hash[:collection] = return_collection(edgeDefinition[:collection], :edge)
114
+ edgeDefinition[:from] ||= []
115
+ edgeDefinition[:to] ||= []
116
+ hash[:from] = edgeDefinition[:from].map{|t| return_collection(t)}
117
+ hash[:to] = edgeDefinition[:to].map{|t| return_collection(t)}
118
+ setup_orphaCollection_after_adding_edge_definitions(hash)
119
+ @edgeDefinitions << hash
120
+ end
121
+ end
122
+ alias assign_edgeDefinitions edgeDefinitions=
123
+
124
+ def orphanCollections=(orphanCollections)
125
+ orphanCollections ||= []
126
+ orphanCollections = [orphanCollections] unless orphanCollections.is_a?(Array)
127
+ @orphanCollections = orphanCollections.map{|oc| add_orphan_collection(oc)}
128
+ end
129
+ alias assign_orphanCollections orphanCollections=
130
+
131
+ def orphanCollectionsRaw
132
+ @orphanCollections ||= []
133
+ @orphanCollections.map{|oc| oc.name}
134
+ end
135
+ private :orphanCollectionsRaw
136
+
137
+ def orphanCollections(raw=false)
138
+ return orphanCollectionsRaw if raw
139
+ return @orphanCollections
140
+ end
141
+
142
+ # === HANDLE ORPHAN COLLECTION ===
143
+
144
+ def add_orphan_collection(orphanCollection)
145
+ orphanCollection = return_collection(orphanCollection)
146
+ if @edgeDefinitions.any? do |ed|
147
+ names = []
148
+ names |= ed[:from].map{|f| f&.name}
149
+ names |= ed[:to].map{|t| t&.name}
150
+ names.include?(orphanCollection.name)
151
+ end
152
+ raise Arango::Error.new err: :orphan_collection_used_by_edge_definition, data: {"collection": orphanCollection.name}
153
+ end
154
+ return orphanCollection
155
+ end
156
+ private :add_orphan_collection
157
+
158
+ def setup_orphaCollection_after_adding_edge_definitions(edgeDefinition)
159
+ collection = []
160
+ collection |= edgeDefinition[:from]
161
+ collection |= edgeDefinition[:to]
162
+ @orphanCollections.delete_if{|c| collection.include?(c.name)}
163
+ end
164
+ private :setup_orphaCollection_after_adding_edge_definitions
165
+
166
+ def setup_orphaCollection_after_removing_edge_definitions(edgeDefinition)
167
+ edgeCollection = edgeDefinition[:collection].name
168
+ collections |= []
169
+ collections |= edgeDefinition[:from]
170
+ collections |= edgeDefinition[:to]
171
+ collections.each do |collection|
172
+ unless @edgeDefinitions.any? do |ed|
173
+ if ed[:collection].name != edgeCollection
174
+ names = []
175
+ names |= ed[:from].map{|f| f&.name}
176
+ names |= ed[:to].map{|t| t&.name}
177
+ names.include?(collection.name)
178
+ else
179
+ false
180
+ end
181
+ end
182
+ unless @orphanCollections.map{|oc| oc.name}.include?(collection.name)
183
+ @orphanCollections << collection
184
+ end
185
+ end
186
+ end
187
+ end
188
+ private :setup_orphaCollection_after_removing_edge_definitions
189
+
190
+ # === REQUEST ===
191
+
192
+ def request(action, url, body: {}, headers: {}, query: {}, key: nil, return_direct_result: false, skip_to_json: false)
193
+ url = "_api/gharial/#{@name}/#{url}"
194
+ @database.request(action, url, body: body, headers: headers,
195
+ query: query, key: key, return_direct_result: return_direct_result,
196
+ skip_to_json: skip_to_json)
197
+ end
198
+
199
+ # === TO HASH ===
200
+
201
+ def to_h
202
+ {
203
+ "name": @name,
204
+ "id": @id,
205
+ "rev": @rev,
206
+ "isSmart": @isSmart,
207
+ "numberOfShards": @numberOfShards,
208
+ "replicationFactor": @replicationFactor,
209
+ "smartGraphAttribute": @smartGraphAttribute,
210
+ "edgeDefinitions": edgeDefinitionsRaw,
211
+ "orphanCollections": orphanCollectionsRaw,
212
+ "cache_name": @cache_name,
213
+ "database": @database.name
214
+ }.delete_if{|k,v| v.nil?}
215
+ end
216
+
217
+ # === GET ===
218
+
219
+ def retrieve
220
+ result = @database.request("GET", "_api/gharial/#{@name}", key: :graph)
221
+ return_element(result)
222
+ end
223
+
224
+ # === POST ===
225
+
226
+ def create(isSmart: @isSmart, smartGraphAttribute: @smartGraphAttribute,
227
+ numberOfShards: @numberOfShards)
228
+ body = {
229
+ "name": @name,
230
+ "edgeDefinitions": edgeDefinitionsRaw,
231
+ "orphanCollections": orphanCollectionsRaw,
232
+ "isSmart": isSmart,
233
+ "options": {
234
+ "smartGraphAttribute": smartGraphAttribute,
235
+ "numberOfShards": numberOfShards
236
+ }
237
+ }
238
+ body[:options].delete_if{|k,v| v.nil?}
239
+ body.delete(:options) if body[:options].empty?
240
+ result = @database.request("POST", "_api/gharial", body: body, key: :graph)
241
+ return_element(result)
242
+ end
243
+
244
+ # === DELETE ===
245
+
246
+ def destroy(dropCollections: nil)
247
+ query = { "dropCollections": dropCollections }
248
+ result = @database.request("DELETE", "_api/gharial/#{@name}", query: query,
249
+ key: :removed)
250
+ return_delete(result)
251
+ end
252
+
253
+ # === VERTEX COLLECTION ===
254
+
255
+ def getVertexCollections
256
+ result = request("GET", "vertex", key: :collections)
257
+ return result if return_directly?(result)
258
+ result.map do |x|
259
+ Arango::Collection.new(name: x, database: @database, graph: self)
260
+ end
261
+ end
262
+ alias vertexCollections getVertexCollections
263
+
264
+ def addVertexCollection(collection:)
265
+ satisfy_class?(collection, [String, Arango::Collection])
266
+ collection = collection.is_a?(String) ? collection : collection.name
267
+ body = { "collection": collection }
268
+ result = request("POST", "vertex", body: body, key: :graph)
269
+ return_element(result)
270
+ end
271
+
272
+ def removeVertexCollection(collection:, dropCollection: nil)
273
+ query = {"dropCollection": dropCollection}
274
+ satisfy_class?(collection, [String, Arango::Collection])
275
+ collection = collection.is_a?(String) ? collection : collection.name
276
+ result = request("DELETE", "vertex/#{collection}", query: query, key: :graph)
277
+ return_element(result)
278
+ end
279
+
280
+ # === EDGE COLLECTION ===
281
+
282
+ def getEdgeCollections
283
+ result = request("GET", "edge", key: :collections)
284
+ return result if @database.server.async != false
285
+ return result if return_directly?(result)
286
+ result.map{|r| Arango::Collection.new(database: @database, name: r, type: :edge)}
287
+ end
288
+
289
+ def addEdgeDefinition(collection:, from:, to:)
290
+ satisfy_class?(collection, [String, Arango::Collection])
291
+ satisfy_class?(from, [String, Arango::Collection], true)
292
+ satisfy_class?(to, [String, Arango::Collection], true)
293
+ from = [from] unless from.is_a?(Array)
294
+ to = [to] unless to.is_a?(Array)
295
+ body = {}
296
+ body[:collection] = collection.is_a?(String) ? collection : collection.name
297
+ body[:from] = from.map{|f| f.is_a?(String) ? f : f.name }
298
+ body[:to] = to.map{|t| t.is_a?(String) ? t : t.name }
299
+ result = request("POST", "edge", body: body, key: :graph)
300
+ return_element(result)
301
+ end
302
+
303
+ def replaceEdgeDefinition(collection:, from:, to:)
304
+ satisfy_class?(collection, [String, Arango::Collection])
305
+ satisfy_class?(from, [String, Arango::Collection], true)
306
+ satisfy_class?(to, [String, Arango::Collection], true)
307
+ from = [from] unless from.is_a?(Array)
308
+ to = [to] unless to.is_a?(Array)
309
+ body = {}
310
+ body[:collection] = collection.is_a?(String) ? collection : collection.name
311
+ body[:from] = from.map{|f| f.is_a?(String) ? f : f.name }
312
+ body[:to] = to.map{|t| t.is_a?(String) ? t : t.name }
313
+ result = request("PUT", "edge/#{body[:collection]}", body: body, key: :graph)
314
+ return_element(result)
315
+ end
316
+
317
+ def removeEdgeDefinition(collection:, dropCollection: nil)
318
+ satisfy_class?(collection, [String, Arango::Collection])
319
+ query = {"dropCollection": dropCollection}
320
+ collection = collection.is_a?(String) ? collection : collection.name
321
+ result = request("DELETE", "edge/#{collection}", query: query, key: :graph)
322
+ return_element(result)
323
+ end
324
+ end
325
+ end