arangorb 1.4.1 → 2.0.0

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