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,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