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,23 @@
1
+ module Arango
2
+ class Server
3
+ module Agency
4
+ def agency_config
5
+ request("GET", "_api/agency/config")
6
+ end
7
+
8
+ def agency_write(body:, agency_mode: nil)
9
+ satisfy_category?(agency_mode, ["waitForCommmitted", "waitForSequenced", "noWait", nil])
10
+ headers = {"X-ArangoDB-Agency-Mode": agency_mode}
11
+ request("POST", "_api/agency/write", headers: headers,
12
+ body: body)
13
+ end
14
+
15
+ def agency_read(body:, agency_mode: nil)
16
+ satisfy_category?(agency_mode, ["waitForCommmitted", "waitForSequenced", "noWait", nil])
17
+ headers = {"X-ArangoDB-Agency-Mode": agency_mode}
18
+ request("POST", "_api/agency/read", headers: headers,
19
+ body: body)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,51 @@
1
+ module Arango
2
+ class Server
3
+ module Async
4
+ # === ASYNC ===
5
+
6
+ def fetch_async(id:)
7
+ request("PUT", "_api/job/#{id}")
8
+ end
9
+
10
+ def cancel_async(id:)
11
+ request("PUT", "_api/job/#{id}/cancel", key: :result)
12
+ end
13
+
14
+ def destroy_async(id:, stamp: nil)
15
+ query = {stamp: stamp}
16
+ request("DELETE", "_api/job/#{id}", query: query, key: :result)
17
+ end
18
+
19
+ def destroy_async_by_type(type:, stamp: nil)
20
+ satisfy_category?(type, %w[all expired])
21
+ query = {stamp: stamp}
22
+ request("DELETE", "_api/job/#{type}", query: query)
23
+ end
24
+
25
+ def destroy_all_async
26
+ destroy_async_by_type(type: "all")
27
+ end
28
+
29
+ def destroy_expired_async
30
+ destroy_async_by_type(type: "expired")
31
+ end
32
+
33
+ def retrieve_async(id:)
34
+ request("GET", "_api/job/#{id}")
35
+ end
36
+
37
+ def retrieve_async_by_type(type:, count: nil)
38
+ satisfy_category?(type, %w[done pending])
39
+ request("GET", "_api/job/#{type}", query: {count: count})
40
+ end
41
+
42
+ def retrieve_done_async(count: nil)
43
+ retrieve_async_by_type(type: "done", count: count)
44
+ end
45
+
46
+ def retrieve_pending_async(count: nil)
47
+ retrieve_async_by_type(type: "pending", count: count)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,35 @@
1
+ module Arango
2
+ class Server
3
+ module Batch
4
+ # === BATCH ===
5
+
6
+ def batch(requests: [])
7
+ Arango::RequestBatch.new(server: self, requests: requests)
8
+ end
9
+
10
+ def create_dump_batch(ttl:, dbserver: nil)
11
+ query = { DBserver: dbserver }
12
+ body = { ttl: ttl }
13
+ result = request("POST", "_api/replication/batch",
14
+ body: body, query: query)
15
+ return result if return_directly?(result)
16
+ return result[:id]
17
+ end
18
+
19
+ def destroy_dump_batch(id:, dbserver: nil)
20
+ query = {DBserver: dbserver}
21
+ result = request("DELETE", "_api/replication/batch/#{id}", query: query)
22
+ return_delete(result)
23
+ end
24
+
25
+ def prolong_dump_batch(id:, ttl:, dbserver: nil)
26
+ query = { DBserver: dbserver }
27
+ body = { ttl: ttl }
28
+ result = request("PUT", "_api/replication/batch/#{id}",
29
+ body: body, query: query)
30
+ return result if return_directly?(result)
31
+ return true
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,76 @@
1
+ module Arango
2
+ class Server
3
+ module Config
4
+ attr_reader :active_cache, :async, :base_uri, :cache, :host, :password, :port, :return_output, :tls, :username
5
+ attr_accessor :size, :timeout, :verbose, :warning
6
+
7
+ def username=(username)
8
+ @username = username
9
+ @options[:basic_auth][:username] = @username
10
+ @request.options = options
11
+ end
12
+
13
+ def password=(password)
14
+ @password = password
15
+ @options[:basic_auth][:password] = @password
16
+ @request.options = options
17
+ end
18
+
19
+ def host=(host)
20
+ @host = host
21
+ update_base_uri
22
+ end
23
+
24
+ def port=(port)
25
+ @port = port
26
+ update_base_uri
27
+ end
28
+
29
+ def tls=(tls)
30
+ satisfy_category?(tls, [false, true])
31
+ @tls = tls
32
+ update_base_uri
33
+ end
34
+
35
+ def active_cache=(active)
36
+ satisfy_category?(active, [true, false])
37
+ @active_cache = active
38
+ if @active_cache
39
+ @cache ||= Arango::Cache.new
40
+ elsif !@cache.nil?
41
+ @cache.clear
42
+ end
43
+ end
44
+
45
+ def return_output=(return_output)
46
+ satisfy_category?(return_output, [true, false])
47
+ @return_output = return_output
48
+ @request.return_output = return_output
49
+ end
50
+
51
+ def verbose=(verbose)
52
+ satisfy_category?(verbose, [true, false])
53
+ @verbose = verbose
54
+ @request.verbose = verbose
55
+ end
56
+
57
+ def async=(async)
58
+ satisfy_category?(async, ["true", "false", false, true, "store", :store])
59
+ case async
60
+ when true, "true"
61
+ @options[:headers]["x-arango-async"] = "true"
62
+ @async = true
63
+ when :store, "store"
64
+ @options[:headers]["x-arango-async"] = "store"
65
+ @async = :store
66
+ when false, "false"
67
+ @options[:headers].delete("x-arango-async")
68
+ @async = false
69
+ end
70
+ @request.async = @async
71
+ @request.options = @options
72
+ end
73
+ alias assign_async async=
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,71 @@
1
+ module Arango
2
+ class Server
3
+ module Databases
4
+ # Retrieves all databases.
5
+ # @return [Array<Arango::Database>]
6
+ def all_databases
7
+ Arango::Database.all(server: self)
8
+ end
9
+
10
+ # Retrieves all databases the current user can access.
11
+ # @return [Array<Arango::Database>]
12
+ def all_user_databases
13
+ Arango::Database.all_user_databases(server: self)
14
+ end
15
+
16
+ # Retrieves a list of all databases.
17
+ # @return [Array<String>] List of database names.
18
+ def list_databases
19
+ Arango::Database.list(server: self)
20
+ end
21
+
22
+ # Retrieves a list of all databases the current user can access.
23
+ # @return [Array<String>] List of database names.
24
+ def list_user_databases
25
+ Arango::Database.list_user_databases(server: self)
26
+ end
27
+
28
+ # Creates a new database.
29
+ # @param name [String] The name of the database
30
+ # @return [Arango::Database] The instance of the database created.
31
+ def create_database(name)
32
+ Arango::Database.new(name, server: self).create
33
+ end
34
+
35
+ # Instantiates a new database, but does not store it on th server.
36
+ # @param name [String] The name of the database
37
+ # @return [Arango::Database] The instance of the database.
38
+ def new_database(name)
39
+ Arango::Database.new(name, server: self)
40
+ end
41
+
42
+ # Removes a database.
43
+ # @param name [String] The name of the database
44
+ # @return nil
45
+ def drop_database(name)
46
+ Arango::Database.drop(name, server: self)
47
+ end
48
+ alias delete_database drop_database
49
+ alias destroy_database drop_database
50
+
51
+ # Get database from server.
52
+ # @param name [String] The name of the database
53
+ # @return [Arango::Database] The instance of the database.
54
+ def get_database(name)
55
+ db = Arango::Database.get(name, server: self)
56
+ Arango.current_database = db if Arango.current_server == self
57
+ db
58
+ end
59
+ alias fetch_database get_database
60
+ alias retrieve_database get_database
61
+
62
+ # Check if database exists.
63
+ # @param name [String] Name of the database.
64
+ # @return [Boolean]
65
+ def exist_database?(name)
66
+ Arango::Database.exist?(name, server: self)
67
+ end
68
+ alias database_exist? exist_database?
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,17 @@
1
+ module Arango
2
+ class Server
3
+ module Monitoring
4
+ # === MONITORING ===
5
+
6
+ def cluster_health
7
+ request("GET", "_admin/health")
8
+ end
9
+
10
+ def cluster_statistics dbserver:
11
+ query = {DBserver: dbserver}
12
+ request("GET", "_admin/clusterStatistics", query: query)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,95 @@
1
+ module Arango
2
+ class Server
3
+ module OpalSupport
4
+ # From the Arango 2.8 documentation:
5
+ #
6
+ # Modules Path versus Modules Collection
7
+ #
8
+ # ArangoDB comes with predefined modules defined in the file-system under the path specified by
9
+ # startup.startup-directory. In a standard installation this point to the system share directory.
10
+ # Even if you are an administrator of ArangoDB you might not have write permissions to this location.
11
+ # On the other hand, in order to deploy some extension for ArangoDB, you might need to install additional
12
+ # JavaScript modules. This would require you to become root and copy the files into the share directory.
13
+ # In order to ease the deployment of extensions, ArangoDB uses a second mechanism to look up JavaScript modules.
14
+ #
15
+ # JavaScript modules can either be stored in the filesystem as regular file or
16
+ # in the database collection _modules.
17
+ #
18
+ # If you execute
19
+ #
20
+ # require("com/example/extension")
21
+ #
22
+ # then ArangoDB will try to locate the corresponding JavaScript as file as follows
23
+ #
24
+ # There is a cache for the results of previous require calls. First of all ArangoDB checks if
25
+ # com/example/extension is already in the modules cache. If it is, the export object for this module
26
+ # is returned. No further JavaScript is executed.
27
+ #
28
+ # ArangoDB will then check, if there is a file called com/example/extension.js in the system search path.
29
+ # If such a file exists, it is executed in a new module context and the value of exports object is returned.
30
+ # This value is also stored in the module cache.
31
+ #
32
+ # If no file can be found, ArangoDB will check if the collection _modules contains a document of the form
33
+ #
34
+ # {
35
+ # path: "/com/example/extension",
36
+ # content: "...."
37
+ # }
38
+ #
39
+ # Note: The leading / is important - even if you call require without a leading /. If such a document exists,
40
+ # then the value of the content attribute must contain the JavaScript code of the module. This string is
41
+ # executed in a new module context and the value of exports object is returned. This value is also stored
42
+ # in the module cache.
43
+ #
44
+ #
45
+ # Taken from the Changelog for 3.5.0.rc.1,
46
+ # https://github.com/arangodb/arangodb/blob/43fa37e35935e095dae31f250456f030da3c451f/CHANGELOG#L826:
47
+ #
48
+ # * Do not create `_modules` collection for new databases/installations.
49
+ #
50
+ # `_modules` is only needed for custom modules, and in case a custom
51
+ # module is defined via `defineModule`, the _modules collection will
52
+ # be created lazily automatically.
53
+ #
54
+ # Existing modules in existing `_modules` collections will remain
55
+ # functional even after this change
56
+ #
57
+ #
58
+ # So this is what we use for storing the opal module in arango and making it available.
59
+
60
+ def install_opal_module(database = '_system', force: false)
61
+ database = database.name unless database.class == String
62
+ dirname = File.dirname(__FILE__)
63
+ filename = File.expand_path(File.join(dirname, '..', '..', '..', 'arango_opal.js'))
64
+ content = File.read(filename)
65
+ system_db = get_database(database)
66
+ system_db.create_collection('_modules', is_system: true) unless system_db.collection_exist?('_modules', exclude_system: false)
67
+ modules_collection = system_db.get_collection('_modules')
68
+ opal_module_doc = modules_collection.get_document(path: '/opal')
69
+ if opal_module_doc
70
+ opal_module_doc.content = content
71
+ opal_module_doc.update
72
+ else
73
+ modules_collection.create_document({ path: '/opal', content: content })
74
+ end
75
+ end
76
+
77
+ # def install_opal_parser_module(database = '_system', force: false)
78
+ # database = database.name unless database.class == String
79
+ # dirname = File.dirname(__FILE__)
80
+ # filename = File.expand_path(File.join(dirname, '..', '..', '..', 'arango_opal_parser.js'))
81
+ # content = File.read(filename)
82
+ # system_db = get_database(database)
83
+ # system_db.create_collection('_modules', is_system: true) unless system_db.collection_exist?('_modules', exclude_system: false)
84
+ # modules_collection = system_db.get_collection('_modules')
85
+ # opal_module_doc = modules_collection.get_document(path: '/opal-parser')
86
+ # if opal_module_doc
87
+ # opal_module_doc.content = content
88
+ # opal_module_doc.update
89
+ # else
90
+ # modules_collection.create_document({ path: '/opal-parser', content: content })
91
+ # end
92
+ # end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,69 @@
1
+ module Arango
2
+ class Server
3
+ module Tasks
4
+
5
+ # Get all tasks.
6
+ #
7
+ # @return [Array<Arango::Task>]
8
+ def all_tasks
9
+ Arango::Task.all(server: self)
10
+ end
11
+
12
+ # Create a new task with given id, task is saved to the database.
13
+ # @param id [String]
14
+ # @param command [String] The javascript code to execute.
15
+ # @param name [String] The task name, optional.
16
+ # @param offset [Integer] The number of seconds initial delay, optional.
17
+ # @param params [Hash] Hash of params to pass to the command, optional.
18
+ # @param period [Integer] Number of seconds between executions, optional.
19
+ # @return [Arango::Task]
20
+ def create_task(id, command:, name: nil, offset: nil, params: nil, period: nil)
21
+ Arango::Task.new(id, command: command, name: name, offset: offset, params: params, period: period, server: self).create
22
+ end
23
+
24
+ # Get a task from the server.
25
+ # @param id [String]
26
+ # @return [Arango::Task]
27
+ def get_task(id)
28
+ Arango::Task.get(id, server: self)
29
+ end
30
+ alias fetch_task get_task
31
+ alias retrieve_task get_task
32
+
33
+ # Instantiate a new task with given id, task is not saved to the database.
34
+ # @param id [String]
35
+ # @param command [String] The javascript code to execute, optional.
36
+ # @param name [String] The task name, optional.
37
+ # @param offset [Integer] The number of seconds initial delay, optional.
38
+ # @param params [Hash] Hash of params to pass to the command, optional.
39
+ # @param period [Integer] Number of seconds between executions, optional.
40
+ # @return [Arango::Task]
41
+ def new_task(id, command: nil, name: nil, offset: nil, params: nil, period: nil)
42
+ Arango::Task.new(id, command: command, name: name, offset: offset, params: params, period: period, server: self)
43
+ end
44
+
45
+ # Get a list of all task ids.
46
+ # @return [Array<String>]
47
+ def list_tasks
48
+ Arango::Task.list(server: self)
49
+ end
50
+
51
+ # Delete task with given id.
52
+ # @param id [String]
53
+ # @return [Boolean] Returns true if task has been deleted.
54
+ def drop_task(id)
55
+ Arango::Task.delete(id, server: self)
56
+ end
57
+ alias delete_task drop_task
58
+ alias destroy_task drop_task
59
+
60
+ # Checks existence of a task.
61
+ # @param id [String]
62
+ # @return [Boolean] Returns true if the task exists, otherwise false.
63
+ def exist_task?(id)
64
+ Arango::Task.exist?(id, server: self)
65
+ end
66
+ alias task_exist? exist_task?
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,22 @@
1
+ module Arango
2
+ class Server
3
+ module User
4
+ # === USER ===
5
+
6
+ def user(password: "", name:, extra: {}, active: nil)
7
+ Arango::User.new(host: self, password: password, name: name, extra: extra,
8
+ active: active)
9
+ end
10
+
11
+ def users
12
+ result = request("GET", "_api/user", key: :result)
13
+ return result if return_directly?(result)
14
+ result.map do |user|
15
+ Arango::User.new(name: user[:user], active: user[:active],
16
+ extra: user[:extra], host: self)
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end