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,223 @@
1
+ # === TASK ===
2
+
3
+ module Arango
4
+ class Task
5
+ include Arango::Helper::Satisfaction
6
+ include Arango::Helper::DatabaseAssignment
7
+ include Arango::Helper::ServerAssignment
8
+
9
+ class << self
10
+ # Takes a hash and instantiates a Arango::Task object from it.
11
+ #
12
+ # @param task_hash [Hash]
13
+ # @return [Arango::Task]
14
+ def from_h(task_hash, server: nil)
15
+ raise Arango::Error.new(err: :no_task_id) unless task_hash.key?(:id)
16
+ task_hash = task_hash.transform_keys { |k| k.to_s.underscore.to_sym }
17
+ task_hash.merge!(server: server) if server
18
+ if task_hash[:database].class == String
19
+ task_hash[:database] = Arango::Database.new(task_hash[:database], server: server)
20
+ end
21
+ created = task_hash.delete(:created)
22
+ offset = task_hash.delete(:offset)
23
+ type = task_hash.delete(:type)
24
+ task = Arango::Task.new(task_hash.delete(:id), **task_hash)
25
+ task.instance_variable_set(:@created, created)
26
+ task.instance_variable_set(:@offset, offset)
27
+ task.instance_variable_set(:@type, type)
28
+ task
29
+ end
30
+
31
+ # Takes a Arango::Result and instantiates a Arango::Task object from it.
32
+ #
33
+ # @param arango_result [Arango::Result]
34
+ # @return [Arango::Task]
35
+ def from_result(arango_result, server: nil)
36
+ from_h(arango_result.to_h, server: server)
37
+ end
38
+
39
+ # Delete a task from the server or from a database.
40
+ #
41
+ # @param id [String] The id of the Task
42
+ # @param database [Arango::Database] A database, optional if server is given.
43
+ # @param server [Arango::Server] Server, optional if database is given.
44
+ # @return [Arango::Task]
45
+ def drop(id, database: nil, server: Arango.current_server)
46
+ if database
47
+ database.request(delete: "_api/tasks/#{id}")
48
+ elsif server
49
+ server.request(delete: "_api/tasks/#{id}")
50
+ end
51
+ nil
52
+ end
53
+ alias delete drop
54
+ alias destroy drop
55
+
56
+ # Gets a task from the server or from a database.
57
+ #
58
+ # @param id [String] The id of the Task
59
+ # @param database [Arango::Database] A database, optional if server is given.
60
+ # @param server [Arango::Server] Server, optional if database is given.
61
+ # @return [Arango::Task]
62
+ def get(id, database: nil, server: Arango.current_server)
63
+ if database
64
+ result = database.request(get: "_api/tasks/#{id}")
65
+ server = database.arango_server
66
+ elsif server
67
+ result = server.request(get: "_api/tasks/#{id}")
68
+ end
69
+ Arango::Task.from_result(result, server: server)
70
+ end
71
+ alias fetch get
72
+ alias retrieve get
73
+
74
+ # Get all tasks from a server or from a database
75
+ #
76
+ # @param database [Arango::Database] A database, optional if server is given.
77
+ # @param server [Arango::Server] Server, optional if database is given.
78
+ # @return [Array<Arango::Task>]
79
+ def all(database: nil, server: Arango.current_server)
80
+ if database
81
+ result = database.request(get: "_api/tasks")
82
+ server = database.arango_server
83
+ elsif server
84
+ result = server.request(get: "_api/tasks")
85
+ end
86
+ result.map { |task| Arango::Task.from_h(task, server: server) }
87
+ end
88
+
89
+ # List all tasks ids from a server or from a database
90
+ #
91
+ # @param database [Arango::Database] A database, optional if server is given.
92
+ # @param server [Arango::Server] Server, optional if database is given.
93
+ # @return [Array<String>]
94
+ def list(database: nil, server: Arango.current_server)
95
+ if database
96
+ result = database.request(get: '_api/tasks')
97
+ elsif server
98
+ result = server.request(get: '_api/tasks')
99
+ end
100
+ result.map { |task| task[:id] }
101
+ end
102
+
103
+ def exist?(id, database: nil, server: Arango.current_server)
104
+ result = list(database: database, server: server)
105
+ result.include?(id)
106
+ end
107
+ end
108
+
109
+ # Access the javascript code of the task.
110
+ # @return [String] The javascript code as string.
111
+ attr_accessor :command
112
+ alias javascript_command command
113
+ alias javascript_command= command=
114
+
115
+ # The Task id.
116
+ # @return [String]
117
+ attr_accessor :id
118
+
119
+ # The Task name.
120
+ # @return [String] or nil
121
+ attr_accessor :name
122
+
123
+ # The number of seconds initial delay.
124
+ # @return [Integer] or nil
125
+ attr_accessor :offset
126
+
127
+ # Hash of params to pass to the command
128
+ # # @return [Hash] or nil
129
+ attr_accessor :params
130
+
131
+ # Number of seconds between executions.
132
+ # @return [Integer] or nil
133
+ attr_accessor :period
134
+
135
+ # Time this task has been created at, timestamp.
136
+ # return [BigDecimal]
137
+ attr_reader :created
138
+
139
+ # Database the task belongs to
140
+ # return [Arango::Database] or nil
141
+ attr_reader :database
142
+
143
+ # Server the Task belongs to.
144
+ # return [Arango::Server]
145
+ attr_reader :server
146
+
147
+ # Task type.
148
+ # return [Symbol] Either :periodic or :timed.
149
+ attr_reader :type
150
+
151
+ # Instantiate a new task.
152
+ #
153
+ # @param command [String] The javascript code to execute, optional.
154
+ # @param name [String] The task name, optional.
155
+ # @param offset [Integer] The number of seconds initial delay, optional.
156
+ # @param params [Hash] Hash of params to pass to the command, optional.
157
+ # @param period [Integer] Number of seconds between executions, optional.
158
+ # @return [Arango::Task]
159
+ def initialize(id = nil, command: nil, name: nil, offset: nil, params: nil, period: nil, database: nil, server: Arango.current_server)
160
+ if database
161
+ assign_database(database)
162
+ @requester = @database
163
+ elsif server
164
+ assign_server(server)
165
+ @requester = @server
166
+ end
167
+ @id = id
168
+ @command = command
169
+ @name = name
170
+ @offset = offset
171
+ @params = params
172
+ @period = period
173
+ end
174
+
175
+ # Convert the Task to a Hash
176
+ # @return [Hash]
177
+ def to_h
178
+ {
179
+ id: @id,
180
+ name: @name,
181
+ type: @type,
182
+ period: @period,
183
+ command: @command,
184
+ params: @params,
185
+ created: @created,
186
+ cache_name: @cache_name,
187
+ database: @database ? @database.name : nil
188
+ }.delete_if{|_,v| v.nil?}
189
+ end
190
+
191
+ # Create the task in the database.
192
+ # return [Arango::Task] Returns the task.
193
+ def create
194
+ body = {
195
+ name: @name,
196
+ command: @command,
197
+ period: @period,
198
+ offset: @offset,
199
+ params: @params,
200
+ database: @database ? @database.name : nil
201
+ }
202
+ if @id
203
+ result = @requester.request(put: "_api/tasks/#{@id}", body: body)
204
+ else
205
+ result = @requester.request(post: "_api/tasks", body: body)
206
+ @id = result.id
207
+ end
208
+ @type = result.type.to_sym
209
+ @created = result.created
210
+ @name = result.name
211
+ self
212
+ end
213
+
214
+ # Remove the task from the database.
215
+ # return nil.
216
+ def drop
217
+ @requester.request(delete: "_api/tasks/#{@id}")
218
+ nil
219
+ end
220
+ alias delete drop
221
+ alias destroy drop
222
+ end
223
+ end
@@ -0,0 +1,113 @@
1
+ # === TRANSACTION ===
2
+
3
+ module Arango
4
+ class Transaction
5
+ include Arango::Helper::Satisfaction
6
+ include Arango::Helper::Return
7
+ include Arango::Helper::DatabaseAssignment
8
+
9
+ def initialize(action:, database:, intermediate_commit_size: nil, intermediate_commit_count: nil, lock_timeout: nil, max_transaction_size: nil,
10
+ params: nil, read: [], wait_for_sync: nil, write: [])
11
+ assign_database(database)
12
+ @action = action
13
+ @intermediate_commit_count = intermediate_commit_count
14
+ @intermediate_commit_size = intermediate_commit_size
15
+ @lock_timeout = lock_timeout
16
+ @max_transaction_size = max_transaction_size
17
+ @params = params
18
+ @read = return_write_or_read(read)
19
+ @result = nil
20
+ @wait_for_sync = wait_for_sync
21
+ @write = return_write_or_read(write)
22
+ end
23
+
24
+ # === DEFINE ===
25
+
26
+ attr_reader :database, :read, :result, :server, :write
27
+ attr_accessor :action, :intermediate_commit_count, :intermediate_commit_size, :lock_timeout, :max_transaction_size, :params, :wait_for_sync
28
+
29
+ def write=(write)
30
+ @write = return_write_or_read(write)
31
+ end
32
+
33
+ def add_write(write)
34
+ write = return_write_or_read(write)
35
+ @write ||= []
36
+ @write << write
37
+ end
38
+
39
+ def read=(read)
40
+ @read = return_write_or_read(read)
41
+ end
42
+
43
+ def add_read(read)
44
+ read = return_write_or_read(read)
45
+ @read ||= []
46
+ @read << read
47
+ end
48
+
49
+ def return_write_or_read(value)
50
+ case value
51
+ when Array
52
+ return value.map{|x| return_collection(x)}
53
+ when String, Arango::Collection
54
+ return [return_collection(value)]
55
+ when NilClass
56
+ return []
57
+ else
58
+ raise Arango::Error.new err: :read_or_write_should_be_string_or_collections, data: {wrong_value: value, wrong_class: value.class}
59
+ end
60
+ end
61
+ private :return_write_or_read
62
+
63
+ def return_collection(collection, type=nil)
64
+ satisfy_class?(collection, [Arango::Collection, String])
65
+ case collection
66
+ when Arango::Collection
67
+ return collection
68
+ when String
69
+ return Arango::Collection.new(name: collection, database: @database)
70
+ end
71
+ end
72
+ private :return_collection
73
+
74
+ # === TO HASH ===
75
+
76
+ def to_h
77
+ {
78
+ action: @action,
79
+ database: @database.name,
80
+ params: @params,
81
+ read: @read.map{|x| x.name},
82
+ result: @result,
83
+ write: @write.map{|x| x.name}
84
+ }.delete_if{|k,v| v.nil?}
85
+ end
86
+
87
+ # === EXECUTE ===
88
+
89
+ def execute(action: @action, params: @params,
90
+ max_transaction_size: @max_transaction_size,
91
+ lock_timeout: @lock_timeout, wait_for_sync: @wait_for_sync,
92
+ intermediate_commit_count: @intermediate_commit_count,
93
+ intermediate_commit_size: @intermediate_commit_size)
94
+ body = {
95
+ collections: {
96
+ read: @read.map{|x| x.name},
97
+ write: @write.map{|x| x.name}
98
+ },
99
+ action: action,
100
+ intermediate_commit_size: intermediate_commit_size,
101
+ intermediateCommitCount: intermediate_commit_count,
102
+ lockTimeout: lock_timeout,
103
+ maxTransactionSize: max_transaction_size,
104
+ params: params,
105
+ waitForSync: wait_for_sync
106
+ }
107
+ result = @database.request("POST", "_api/transaction", body: body)
108
+ return result if @server.async != false
109
+ @result = result[:result]
110
+ return return_directly?(result) ? result : result[:result]
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,212 @@
1
+ # === TRAVERSAL ===
2
+
3
+ module Arango
4
+ class Traversal
5
+ include Arango::Helper::Satisfaction
6
+ include Arango::Helper::Return
7
+ include Arango::Helper::DatabaseAssignment
8
+
9
+ def initialize(body: {}, direction: nil, edge_collection: nil, expander: nil, filter: nil, init: nil, item_order: nil, max_depth: nil,
10
+ max_iterations: nil, min_depth: nil, order: nil, sort: nil, strategy: nil, uniqueness: nil, vertex:, visitor: nil)
11
+ satisfy_category?(direction, ["outbound", "inbound", "any", nil])
12
+ satisfy_category?(item_order, ["forward", "backward", nil])
13
+ satisfy_category?(order, ["preorder", "postorder", "preorder-expander", nil])
14
+ satisfy_category?(strategy, ["depthfirst", "breadthfirst", nil])
15
+ body[:direction] ||= direction
16
+ body[:edge_collection] ||= edge_collection
17
+ body[:expander] ||= expander
18
+ body[:filter] ||= filter
19
+ body[:init] ||= init
20
+ body[:item_order] ||= item_order
21
+ body[:max_depth] ||= max_depth
22
+ body[:max_iterations] ||= max_iterations
23
+ body[:min_depth] ||= min_depth
24
+ body[:order] ||= order
25
+ body[:sort] ||= sort
26
+ body[:startVertex] ||= vertex
27
+ body[:strategy] ||= strategy
28
+ body[:uniqueness] ||= uniqueness
29
+ body[:visitor] ||= visitor
30
+ assign_body(body)
31
+ @vertices = nil
32
+ @paths = nil
33
+ end
34
+
35
+ # === DEFINE ===
36
+
37
+ attr_accessor :expander, :filter, :init, :max_depth, :max_iterations, :min_depth, :sort, :uniqueness, :visitor
38
+ attr_reader :body, :collection, :database, :direction, :edge_collection, :graph, :item_order, :order, :paths, :server, :strategy,
39
+ :vertex, :vertices
40
+ alias start_vertex vertex
41
+
42
+ def body=(body)
43
+ @body = body
44
+ @direction = body[:direction] || @direction
45
+ @expander = body[:expander] || @expander
46
+ @filter = body[:filter] || @filter
47
+ @init = body[:init] || @init
48
+ @item_order = body[:item_order] || @item_order
49
+ @max_depth = body[:maxDepth] || @max_depth
50
+ @max_iterations = body[:max_iterations] || @max_iterations
51
+ @min_depth = body[:min_depth] || @min_depth
52
+ @order = body[:order] || @order
53
+ @sort = body[:sort] || @sort
54
+ @strategy = body[:strategy] || @strategy
55
+ @uniqueness = body[:uniqueness] || @uniqueness
56
+ @visitor = body[:visitor] || @visitor
57
+ send(:edge_collection=, body[:edge_collection] || @edge_collection)
58
+ send(:start_vertex=, body[:startVertex] || @vertex)
59
+ end
60
+ alias assign_body body=
61
+
62
+ def direction=(direction)
63
+ satisfy_category?(direction, ["outbound", "inbound", "any", nil])
64
+ @direction = direction
65
+ end
66
+
67
+ def item_order=(itemOrder)
68
+ satisfy_category?(itemOrder, ["forward", "backward", nil])
69
+ @item_order = itemOrder
70
+ end
71
+
72
+ def strategy=(strategy)
73
+ satisfy_category?(strategy, ["depthfirst", "breadthfirst", nil])
74
+ @strategy = strategy
75
+ end
76
+
77
+ def order=(order)
78
+ satisfy_category?(order, ["preorder", "postorder", "preorder-expander", nil])
79
+ @order = order
80
+ end
81
+
82
+ def start_vertex=(vertex)
83
+ case vertex
84
+ when Arango::Edge
85
+ when Arango::Document, Arango::Vertex
86
+ @vertex = vertex
87
+ @collection = @vertex.collection
88
+ @database = @collection.database
89
+ @graph = @collection.graph
90
+ @server = @database.server
91
+ return
92
+ when String
93
+ if @database.nil?
94
+ raise Arango::Error.new err: :database_undefined_for_traversal
95
+ elsif vertex.include? "/"
96
+ val = vertex.split("/")
97
+ @collection = Arango::Collection.new(database: @database, name: val[0])
98
+ @vertex = Arango::Document.new(collection: @collection, name: val[1])
99
+ return
100
+ end
101
+ end
102
+ raise Arango::Error.new err: :wrong_start_vertex_type
103
+ end
104
+ alias vertex= start_vertex=
105
+
106
+ def edge_collection=(collection)
107
+ return nil if collection.nil?
108
+ satisfy_class?(collection, [Arango::Collection, String])
109
+ case collection
110
+ when Arango::Collection
111
+ if collection.type != :edge
112
+ raise Arango::Error.new err: :edge_collection_should_be_of_type_edge
113
+ end
114
+ @edge_collection = collection
115
+ when String
116
+ collection_instance = Arango::Collection.new(name: collection,
117
+ database: @database, type: :edge, graph: @graph)
118
+ @edge_collection = collection_instance
119
+ end
120
+ end
121
+
122
+ def in
123
+ @direction = "inbound"
124
+ end
125
+
126
+ def out
127
+ @direction = "outbound"
128
+ end
129
+
130
+ def any
131
+ @direction = "any"
132
+ end
133
+
134
+ # === TO HASH ===
135
+
136
+ def to_h
137
+ {
138
+ database: @database.name,
139
+ direction: @direction,
140
+ edgeCollection: @edge_collection&.name,
141
+ expander: @expander,
142
+ filter: @filter,
143
+ graph: @graph&.name,
144
+ idCache: @id_cache,
145
+ init: @init,
146
+ itemOrder: @item_order,
147
+ maxDepth: @max_depth,
148
+ maxiterations: @max_iterations,
149
+ minDepth: @min_depth,
150
+ order: @order,
151
+ paths: @paths&.map do |x|
152
+ {
153
+ edges: x[:edges]&.map{|e| e.id},
154
+ vertices: x[:vertices]&.map{|v| v.id}
155
+ }
156
+ end,
157
+ sort: @sort,
158
+ startVertex: @vertex&.id,
159
+ strategy: @strategy,
160
+ uniqueness: @uniqueness,
161
+ vertices: @vertices&.map{|x| x.id},
162
+ visitor: @visitor
163
+ }.delete_if{|k,v| v.nil?}
164
+ end
165
+
166
+ # === EXECUTE ===
167
+
168
+ def execute
169
+ body = {
170
+ direction: @direction,
171
+ edgeCollection: @edge_collection&.name,
172
+ expander: @expander,
173
+ filter: @filter,
174
+ graphName: @graph&.name,
175
+ init: @init,
176
+ itemOrder: @item_order,
177
+ maxDepth: @max_depth,
178
+ maxiterations: @max_iterations,
179
+ minDepth: @min_depth,
180
+ order: @order,
181
+ sort: @sort,
182
+ startVertex: @vertex&.id,
183
+ strategy: @strategy,
184
+ uniqueness: @uniqueness,
185
+ visitor: @visitor
186
+ }
187
+ result = @database.request("POST", "_api/traversal", body: body)
188
+ return result if @server.async != false
189
+ @vertices = result[:result][:visited][:vertices].map do |x|
190
+ collection = Arango::Collection.new(name: x[:_id].split("/")[0],
191
+ database: @database)
192
+ Arango::Document.new(name: x[:_key], collection: collection, body: x)
193
+ end
194
+ @paths = result[:result][:visited][:paths].map do |x|
195
+ {
196
+ edges: x[:edges].map do |e|
197
+ collection_edge = Arango::Collection.new(name: e[:_id].split("/")[0],
198
+ database: @database, type: :edge)
199
+ Arango::Document.new(name: e[:_key], collection: collection_edge,
200
+ body: e, from: e[:_from], to: e[:_to])
201
+ end,
202
+ vertices: x[:vertices].map do |v|
203
+ collection_vertex = Arango::Collection.new(name: v[:_id].split("/")[0],
204
+ database: @database)
205
+ Arango::Document.new(name: v[:_key], collection: collection_vertex, body: v)
206
+ end
207
+ }
208
+ end
209
+ return return_directly?(result) ? result : self
210
+ end
211
+ end
212
+ end