arangorb 1.4.1 → 2.0.0

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/ArangoRB.gemspec +20 -18
  3. data/Gemfile +3 -0
  4. data/README.md +1079 -908
  5. data/lib/AQL.rb +155 -0
  6. data/lib/Batch.rb +97 -0
  7. data/lib/Cache.rb +71 -0
  8. data/lib/Collection.rb +852 -0
  9. data/lib/Database.rb +417 -0
  10. data/lib/Document.rb +346 -0
  11. data/lib/Edge.rb +104 -0
  12. data/lib/Error.rb +125 -0
  13. data/lib/Foxx.rb +277 -0
  14. data/lib/Graph.rb +325 -0
  15. data/lib/Index.rb +126 -0
  16. data/lib/Replication.rb +235 -0
  17. data/lib/Request.rb +143 -0
  18. data/lib/Server.rb +466 -0
  19. data/lib/Task.rb +120 -0
  20. data/lib/Transaction.rb +115 -0
  21. data/lib/Traversal.rb +224 -0
  22. data/lib/User.rb +197 -0
  23. data/lib/Vertex.rb +127 -0
  24. data/lib/View.rb +151 -0
  25. data/lib/arangorb.rb +23 -15
  26. data/lib/helpers/Error.rb +28 -0
  27. data/lib/helpers/Return.rb +53 -0
  28. metadata +64 -45
  29. data/lib/ArangoRB_AQL.rb +0 -181
  30. data/lib/ArangoRB_Cache.rb +0 -174
  31. data/lib/ArangoRB_Col.rb +0 -526
  32. data/lib/ArangoRB_DB.rb +0 -363
  33. data/lib/ArangoRB_Doc.rb +0 -319
  34. data/lib/ArangoRB_Edg.rb +0 -184
  35. data/lib/ArangoRB_Gra.rb +0 -201
  36. data/lib/ArangoRB_Index.rb +0 -135
  37. data/lib/ArangoRB_Replication.rb +0 -261
  38. data/lib/ArangoRB_Ser.rb +0 -446
  39. data/lib/ArangoRB_Task.rb +0 -129
  40. data/lib/ArangoRB_Tra.rb +0 -169
  41. data/lib/ArangoRB_Tran.rb +0 -68
  42. data/lib/ArangoRB_User.rb +0 -157
  43. data/lib/ArangoRB_Ver.rb +0 -162
  44. data/spec/arangoRB_helper.rb +0 -4
  45. data/spec/arangoRestart_helper.rb +0 -14
  46. data/spec/arangorb-1.3.0.gem +0 -0
  47. data/spec/lib/0.1.0/arangoAQL_helper.rb +0 -64
  48. data/spec/lib/0.1.0/arangoC_helper.rb +0 -170
  49. data/spec/lib/0.1.0/arangoDB_helper.rb +0 -119
  50. data/spec/lib/0.1.0/arangoDoc_helper.rb +0 -79
  51. data/spec/lib/0.1.0/arangoE_helper.rb +0 -50
  52. data/spec/lib/0.1.0/arangoG_helper.rb +0 -78
  53. data/spec/lib/0.1.0/arangoS_helper.rb +0 -37
  54. data/spec/lib/0.1.0/arangoT_helper.rb +0 -48
  55. data/spec/lib/0.1.0/arangoV_helper.rb +0 -65
  56. data/spec/lib/1.0.0/arangoC_helper.rb +0 -73
  57. data/spec/lib/1.0.0/arangoDB_helper.rb +0 -48
  58. data/spec/lib/1.0.0/arangoI_helper.rb +0 -43
  59. data/spec/lib/1.0.0/arangoS_helper.rb +0 -192
  60. data/spec/lib/1.0.0/arangoTa_helper.rb +0 -49
  61. data/spec/lib/1.0.0/arangoTr_helper.rb +0 -15
  62. data/spec/lib/1.0.0/arangoU_helper.rb +0 -72
  63. data/spec/lib/1.1.0/arangoRB_helper.rb +0 -144
  64. data/spec/lib/1.1.0/arangoRB_walks_helper.rb +0 -19
  65. data/spec/lib/1.2.0/arangoCache_helper.rb +0 -66
  66. data/spec/lib/1.3.0/arangoHash_helper.rb +0 -30
  67. data/spec/lib/arangoRB_0.1.0_helper.rb +0 -9
  68. data/spec/lib/arangoRB_1.0.0_helper.rb +0 -6
  69. data/spec/lib/arangoRB_1.1.0_helper.rb +0 -2
  70. data/spec/lib/arangoRB_1.2.0_helper.rb +0 -2
  71. data/spec/spec_helper.rb +0 -42
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
data/lib/Index.rb ADDED
@@ -0,0 +1,126 @@
1
+ # === INDEXES ===
2
+
3
+ module Arango
4
+ class Index
5
+ include Arango::Helper_Error
6
+ include Arango::Helper_Return
7
+ include Arango::Collection_Return
8
+
9
+ def self.new(*args)
10
+ hash = args[0]
11
+ super unless hash.is_a?(Hash)
12
+ collection = hash[:collection]
13
+ if collection.is_a?(Arango::Collection) && collection.database.server.active_cache && !hash[:id].nil?
14
+ cache_name = "#{collection.database.name}/#{collection.name}/#{hash[:id]}"
15
+ cached = collection.database.server.cache.cache.dig(:index, cache_name)
16
+ if cached.nil?
17
+ hash[:cache_name] = cache_name
18
+ return super
19
+ else
20
+ body = hash[:body] || {}
21
+ [:type, :sparse, :unique, :fields, :deduplicate, :geoJson,
22
+ :minLength].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(collection:, body: {}, id: nil, type: "hash", unique: nil,
31
+ fields:, sparse: nil, geoJson: nil, minLength: nil, deduplicate: nil,
32
+ cache_name: nil)
33
+ assign_collection(collection)
34
+ unless cache_name.nil?
35
+ @cache_name = cache_name
36
+ @server.cache.save(:index, cache_name, self)
37
+ end
38
+ body[:type] ||= type
39
+ body[:id] ||= id
40
+ body[:sparse] ||= sparse
41
+ body[:unique] ||= unique
42
+ body[:fields] ||= fields.is_a?(String) ? [fields] : fields
43
+ body[:deduplicate] ||= deduplicate
44
+ body[:geoJson] ||= geoJson
45
+ body[:minLength] ||= minLength
46
+
47
+ assign_attributes(body)
48
+ end
49
+
50
+ # === DEFINE ===
51
+
52
+ attr_accessor :id, :unique, :fields, :key, :sparse, :geoJson, :minLenght,
53
+ :deduplicate, :cache_name
54
+ attr_reader :type, :database, :collection, :server
55
+
56
+ def type=(type)
57
+ satisfy_category?(type, ["hash", "skiplist", "persistent", "geo", "fulltext", "primary"])
58
+ @type = type
59
+ end
60
+ alias assign_type type=
61
+
62
+ def body=(result)
63
+ @body = result
64
+ @id = result[:id] || @id
65
+ @key = @id&.split("/")&.dig(1)
66
+ @type = assign_type(result[:type] || @type)
67
+ @unique = result[:unique] || @unique
68
+ @fields = result[:fields] || @fields
69
+ @sparse = result[:sparse] || @sparse
70
+ @geoJson = result[:geoJson] || @geoJson
71
+ @minLength = result[:minLength] || @minLength
72
+ @deduplicate = result[:deduplicate] || @deduplicate
73
+ if @server.active_cache && @cache_name.nil?
74
+ @cache_name = "#{@database.name}/#{@collection.name}/#{@id}"
75
+ @server.cache.save(:index, @cache_name, self)
76
+ end
77
+ end
78
+ alias assign_attributes body=
79
+
80
+ # === DEFINE ===
81
+
82
+ def to_h
83
+ {
84
+ "key": @key,
85
+ "id": @id,
86
+ "body": @body,
87
+ "type": @type,
88
+ "sparse": @sparse,
89
+ "unique": @unique,
90
+ "fields": @fields,
91
+ "idCache": @idCache,
92
+ "geoJson": @geoJson,
93
+ "minLength": @minLength,
94
+ "deduplicate": @deduplicate,
95
+ "collection": @collection.name
96
+ }.delete_if{|k,v| v.nil?}
97
+ end
98
+
99
+ # === COMMANDS ===
100
+
101
+ def retrieve
102
+ result = @database.request("GET", "_api/index/#{@id}")
103
+ return_element(result)
104
+ end
105
+
106
+ def create
107
+ body = {
108
+ "fields": @fields,
109
+ "unique": @unique,
110
+ "type": @type,
111
+ "id": @id,
112
+ "geoJson": @geoJson,
113
+ "minLength": @minLength,
114
+ "deduplicate": @deduplicate
115
+ }
116
+ query = { "collection": @collection.name }
117
+ result = @database.request("POST", "_api/index", body: body, query: query)
118
+ return_element(result)
119
+ end
120
+
121
+ def destroy
122
+ result = @database.request("DELETE", "_api/index/#{@id}")
123
+ return_delete(result)
124
+ end
125
+ end
126
+ end