ashikawa-core 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0188e3f9d7f519dd6219ecf2cf7f54d57e2318b6
4
- data.tar.gz: a8b0deb872c8771186b23861d7aacf264b16facf
3
+ metadata.gz: 1415f79ce912907851e91f4f1810668fb0a83024
4
+ data.tar.gz: 4076c3f55aecd6f194057cfbc6a7f0e0c671b774
5
5
  SHA512:
6
- metadata.gz: dd134061b8cfad2f9aee15e9f9fed43b77c8f2bbebf9c19e4932ad53786e66b9a8ce1e42a7c1b593aee4be1086b4a7b90c412cc7ec310869891ee26892c24a58
7
- data.tar.gz: 094089ba8bcfdc3776722d3c8aff6a4e21f7c8fe72b353cdfa97a03baf0c79f4742c30740092efa67e1db5f698cb4ac5697a7b8f7609bb2b12fb7907236d6a16
6
+ metadata.gz: cbca0fdac8f1f59c2597d684b58bd1c3f6cfdf28fa5df3cf7aecda655cb9430e1117ab72bd56b7bcaa88751fa23915ac48e86157e5f06f1adfebb71f6f8325f9
7
+ data.tar.gz: 98687992409d83cb2c894156019e0c4ebb539ad2eb94e2d036815c5d935b07320abf6ce24d69829726d3244e45ec0d4c9d66a5a6b25eabf9dafb1f9dd58baa65
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  .DS_Store
2
+ tags
2
3
  /.yardoc
3
4
  /doc
4
5
  /*.gem
data/.hound.yml CHANGED
@@ -28,7 +28,7 @@ HashSyntax:
28
28
  Enabled: true
29
29
 
30
30
  StringLiterals:
31
- Enabled: true
31
+ EnforcedStyle: single_quotes
32
32
 
33
33
  Void:
34
34
  Enabled: true
data/.travis.yml CHANGED
@@ -6,12 +6,8 @@ rvm:
6
6
  - 2.0.0
7
7
  - 2.1.2
8
8
  - jruby-1.7.12
9
- - rbx-2.2.6
10
9
  env:
11
- - ARANGODB_DISABLE_AUTHENTIFICATION=false VERSION=2.1
12
- matrix:
13
- allow_failures:
14
- - rvm: 2.1.0
10
+ - ARANGODB_DISABLE_AUTHENTIFICATION=false VERSION=2.2
15
11
  script: "bundle exec rake ci"
16
12
  addons:
17
13
  code_climate:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # Version 0.13.0
2
+
3
+ **Codename: Galadriel**
4
+
5
+ * Support for the [new Graph module](http://docs.arangodb.org/HttpGharial/README.html) in Arango 2.2 (#55)
6
+ * Fixed badge URL for Inch (#130)
7
+ * **Deprecated** `Collection#create_edge` in favor of `EdgeCollection#add`
8
+ * Sending the `X-Arango-Version` HTTP header with each request (#82)
9
+ * Development only:
10
+ * Removed Rubinius from Travis
11
+ * You will need ArangoDB 2.2 for development
12
+ * Automatically removed auto-generated databases for acceptance specs
13
+
1
14
  # Version 0.12.0
2
15
 
3
16
  **Codename: V for Verifying**
data/README.md CHANGED
@@ -6,16 +6,15 @@
6
6
  | Documentation | [RubyDoc](http://www.rubydoc.info/gems/ashikawa-core)
7
7
  | CI | [![Build Status](http://img.shields.io/travis/triAGENS/ashikawa-core.svg)](http://travis-ci.org/triAGENS/ashikawa-core)
8
8
  | Code Metrics | [![Code Climate](http://img.shields.io/codeclimate/github/triAGENS/ashikawa-core.svg)](https://codeclimate.com/github/triAGENS/ashikawa-core) [![Code Climate Coverage](http://img.shields.io/codeclimate/coverage/github/triAGENS/ashikawa-core.svg)](https://codeclimate.com/github/triAGENS/ashikawa-core)
9
- | Inline docs | [![Inline docs](http://inch-pages.github.io/github/triAGENS/ashikawa-core.svg)](http://inch-pages.github.io/github/triAGENS/ashikawa-core)
9
+ | Inline docs | [![Inline docs](http://inch-ci.org/github/triAGENS/ashikawa-core.svg)](http://inch-ci.org/github/triAGENS/ashikawa-core)
10
10
  | Gem Version | [![Gem Version](http://img.shields.io/gem/v/ashikawa-core.svg)](http://rubygems.org/gems/ashikawa-core)
11
11
  | Dependencies | [![Dependency Status](http://img.shields.io/gemnasium/triAGENS/ashikawa-core.svg)](https://gemnasium.com/triAGENS/ashikawa-core)
12
12
 
13
- Ashikawa Core is a Wrapper around the ArangoDB Rest API. It provides low level access and is intended to be used in ArangoDB ODMs and other projects related to the database. It is always working with the stable version of ArangoDB, this is currently version **2.1**.
13
+ Ashikawa Core is a Wrapper around the ArangoDB Rest API. It provides low level access and is intended to be used in ArangoDB ODMs and other projects related to the database. It is always working with the stable version of ArangoDB, this is currently version **2.2**.
14
14
 
15
15
  All tests run on Travis CI for the following versions of Ruby:
16
16
 
17
17
  * MRI 1.9.3, 2.0.0 and 2.1.2
18
- * Rubinius 2.2.6
19
18
  * JRuby 1.7.12
20
19
 
21
20
  ## How to install it?
data/config/reek.yml CHANGED
@@ -63,6 +63,7 @@ TooManyMethods:
63
63
  TooManyStatements:
64
64
  enabled: true
65
65
  exclude:
66
+ - Ashikawa::Core::Database#translate_params
66
67
  - Ashikawa::Core::FaradayFactory#self.create_connection
67
68
  - Ashikawa::Core::FaradayFactory#faraday_for
68
69
  - Ashikawa::Core::ErrorResponse#on_complete
@@ -354,7 +354,7 @@ module Ashikawa
354
354
  # document = collection.fetch(12345)
355
355
  def fetch(document_key)
356
356
  response = send_request_for_content_key(document_key)
357
- @content_class.new(@database, response)
357
+ build_content_class(response)
358
358
  end
359
359
 
360
360
  # Fetch a certain document by its key, return nil if the document does not exist
@@ -397,6 +397,9 @@ module Ashikawa
397
397
 
398
398
  # Create a new edge between two documents with certain attributes
399
399
  #
400
+ # @deprecated Since we introduced the dedicated Graph module ('gharial') all operations regarding edges
401
+ # and vertices should be done through that module. Due to this please use EdgeCollection#add
402
+ # instead.
400
403
  # @param [Document] from
401
404
  # @param [Document] to
402
405
  # @param [Hash] attributes
@@ -405,6 +408,7 @@ module Ashikawa
405
408
  # @example Create a new document from raw data
406
409
  # collection.create_edge(node_a, node_b, {'name' => 'incredible edge'})
407
410
  def create_edge(from, to, attributes)
411
+ warn '[DEPRECATION] `create_edge` is deprecated. Please use `EdgeCollection#add` instead.'
408
412
  raise "Can't create an edge in a document collection" if @content_type == :document
409
413
  response = send_request("edge?collection=#{@id}&from=#{from.id}&to=#{to.id}", post: attributes)
410
414
  Edge.new(@database, response, attributes)
@@ -485,6 +489,15 @@ module Ashikawa
485
489
  get_information_from_server(:properties, :isVolatile)
486
490
  end
487
491
 
492
+ # Builds an instance for the content class
493
+ #
494
+ # @param [Hash] data The raw data to be used to instatiate the class
495
+ # @return [Document] The instatiated document
496
+ # @api private
497
+ def build_content_class(data)
498
+ @content_class.new(@database, data)
499
+ end
500
+
488
501
  private
489
502
 
490
503
  # Send a put request with a given key and value to the server
@@ -3,6 +3,7 @@ require 'forwardable'
3
3
  require 'faraday'
4
4
  require 'equalizer'
5
5
  require 'ashikawa-core/error_response'
6
+ require 'ashikawa-core/x_arango_version'
6
7
  require 'ashikawa-core/faraday_factory'
7
8
 
8
9
  module Ashikawa
@@ -1,6 +1,8 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'ashikawa-core/exceptions/client_error/resource_not_found/collection_not_found'
3
+ require 'ashikawa-core/exceptions/client_error/resource_not_found/graph_not_found'
3
4
  require 'ashikawa-core/collection'
5
+ require 'ashikawa-core/graph'
4
6
  require 'ashikawa-core/connection'
5
7
  require 'ashikawa-core/cursor'
6
8
  require 'ashikawa-core/configuration'
@@ -205,6 +207,45 @@ module Ashikawa
205
207
  Transaction.new(self, action, collections)
206
208
  end
207
209
 
210
+ # Fetch a single graph from this database or creates it if does not exist yet.
211
+ #
212
+ # @param [String] graph_name The name of the Graph
213
+ # @return [Graph] The requested graph
214
+ # @api public
215
+ def graph(graph_name)
216
+ response = send_request("gharial/#{graph_name}")
217
+ Graph.new(self, response['graph'])
218
+ rescue Ashikawa::Core::GraphNotFoundException
219
+ return create_graph(graph_name)
220
+ end
221
+
222
+ # Create a new Graph for this database.
223
+ #
224
+ # @param [String] graph_name The name of the Graph
225
+ # @option options [Array<Hash>] :edge_definitions A list of edge definitions
226
+ # @option options [Array<String>] :orphan_collections A list of orphan collections
227
+ # @return [Graph] The graph that was created
228
+ # @api public
229
+ # @example Create a graph without additional options
230
+ # database = Ashikawa::Core::Database.new('http://localhost:8529')
231
+ # database.create_graph('a') # => #<Graph name="a">
232
+ # @example Create a graph with edge definitions and orphan collections
233
+ # database = Ashikawa::Core::Database.new('http://localhost:8529')
234
+ # database.create_graph('g', {
235
+ # edge_definitions: [{ collection: 'c', from: 'a', to: 'b'}],
236
+ # orphan_collections: ['d']
237
+ # })
238
+ def create_graph(graph_name, options = {})
239
+ response = send_request('gharial', post: translate_params(graph_name, options))
240
+ Graph.new(self, response['graph'])
241
+ end
242
+
243
+ # Fetch all graphs for this database
244
+ def graphs
245
+ response = send_request('gharial')
246
+ response['graphs'].map { |raw_graph| Graph.new(self, raw_graph) }
247
+ end
248
+
208
249
  private
209
250
 
210
251
  # Parse a raw collection
@@ -232,12 +273,14 @@ module Ashikawa
232
273
 
233
274
  # Translate the params into the required format
234
275
  #
235
- # @param [String] collection_identifier
276
+ # @param [String] identifier
236
277
  # @param [Hash] opts
237
278
  # @return [Hash]
238
279
  # @api private
239
- def translate_params(collection_identifier, opts)
240
- params = { name: collection_identifier }
280
+ def translate_params(identifier, opts)
281
+ params = { name: identifier }
282
+ params[:edgeDefinitions] = opts[:edge_definitions] if opts.key?(:edge_definitions)
283
+ params[:orphanCollections] = opts[:orphan_collections] if opts.key?(:orphan_collections)
241
284
  params[:isVolatile] = true if opts[:is_volatile]
242
285
  params[:type] = COLLECTION_TYPES[opts[:content_type]] if opts.key?(:content_type)
243
286
  params[:keyOptions] = translate_key_options(opts[:key_options]) if opts.key?(:key_options)
@@ -35,16 +35,25 @@ module Ashikawa
35
35
  # document.revision # => 3456789
36
36
  attr_reader :revision
37
37
 
38
+ # The optional graph this document belongs to
39
+ #
40
+ # @return [Graph] The Graph instance the document was fetched from
41
+ # @api public
42
+ attr_reader :graph
43
+
38
44
  # Initialize a Document with the database and raw data
39
45
  #
40
46
  # @param [Database] database
41
47
  # @param [Hash] raw_document
42
48
  # @param [Hash] additional_data
49
+ # @option _additional_data [Graph] graph The graph this document is associated with
43
50
  # @api public
44
51
  # @example Create a document
45
52
  # document = Ashikawa::Core::Document.new(database, raw_document)
46
53
  def initialize(database, raw_document, additional_data = {})
47
54
  @database = database
55
+ @graph = additional_data.delete(:graph)
56
+
48
57
  raw_document.merge!(clean_up_additional_data(additional_data))
49
58
  parse_raw_document(raw_document)
50
59
  end
@@ -154,7 +163,11 @@ module Ashikawa
154
163
  # @return [Hash] The parsed response from the server
155
164
  # @api private
156
165
  def send_request_for_document(opts = {})
157
- @database.send_request("document/#{@id}", opts)
166
+ if graph
167
+ @database.send_request("gharial/#{graph.name}/vertex/#{@id}", opts)
168
+ else
169
+ @database.send_request("document/#{@id}", opts)
170
+ end
158
171
  end
159
172
 
160
173
  # Clean up the raw data hash to have string keys
@@ -31,6 +31,7 @@ module Ashikawa
31
31
  # @param [Database] _database
32
32
  # @param [Hash] raw_edge
33
33
  # @param [Hash] _additional_data
34
+ # @option _additional_data [Graph] graph The graph this edge is associated with
34
35
  # @api public
35
36
  # @example Create an Edge
36
37
  # document = Ashikawa::Core::Edge.new(database, raw_edge)
@@ -48,7 +49,11 @@ module Ashikawa
48
49
  # @return [Hash] The parsed response from the server
49
50
  # @api private
50
51
  def send_request_for_document(opts)
51
- @database.send_request("edge/#{@id}", opts)
52
+ if graph
53
+ @database.send_request("gharial/#{graph.name}/edge/#{@id}", opts)
54
+ else
55
+ @database.send_request("edge/#{@id}", opts)
56
+ end
52
57
  end
53
58
  end
54
59
  end
@@ -0,0 +1,92 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'ashikawa-core/collection'
3
+ require 'ashikawa-core/edge'
4
+
5
+ module Ashikawa
6
+ module Core
7
+ # An edge collection as it is returned from a graph
8
+ #
9
+ # @note This is basically just a regular collection with some additional attributes and methods to ease
10
+ # working with collections in the graph module.
11
+ class EdgeCollection < Collection
12
+ # The prepared AQL statement to remove edges
13
+ REMOVE_EDGES_AQL_STATEMENT = <<-AQL.gsub(/^[ \t]*/, '')
14
+ FOR e IN @@edge_collection
15
+ FILTER e._from == @from && e._to == @to
16
+ REMOVE e._key IN @@edge_collection
17
+ AQL
18
+
19
+ # The Graph instance this EdgeCollection was originally fetched from
20
+ #
21
+ # @return [Graph] The Graph instance the collection was fetched from
22
+ # @api public
23
+ attr_reader :graph
24
+
25
+ # Create a new EdgeCollection object
26
+ #
27
+ # @param [Database] database The database the connection belongs to
28
+ # @param [Hash] raw_collection The raw collection returned from the server
29
+ # @param [Graph] graph The graph from which this collection was fetched
30
+ # @note You should not create instance manually but rather use Graph#add_edge_definition
31
+ # @api public
32
+ def initialize(database, raw_collection, graph)
33
+ super(database, raw_collection)
34
+ @graph = graph
35
+ end
36
+
37
+ # Create one or more edges between documents with certain attributes
38
+ #
39
+ # @param [Document] from The outbound vertex
40
+ # @param [Document] to The inbound vertex
41
+ # @param [Hash] attributes Additional attributes to add to all created edges
42
+ # @return [Edge] The created Edge
43
+ # @api public
44
+ # @example Create an edge between two vertices
45
+ # edges = edge_collection.add(from: vertex_a, to: vertex_b)
46
+ def add(directions)
47
+ from_vertex, to_vertex = directions.values_at(:from, :to)
48
+ response = send_request_for_this_collection('', post: { _from: from_vertex.id, _to: to_vertex.id })
49
+ fetch(response['edge']['_key'])
50
+ end
51
+
52
+ # Remove edges by example
53
+ #
54
+ # @note This will remove ALL edges between the given vertices. For more fine grained control delete
55
+ # the desired edges through Edge#remove.
56
+ # @param [Hash] from_to Specifies the edge by its vertices to be removed
57
+ # @option from_to [Document] from The from part of the edge
58
+ # @option from_to [Document] to The to part of the edge
59
+ # @api public
60
+ def remove(from_to)
61
+ bind_vars = {
62
+ :@edge_collection => name,
63
+ :from => from_to[:from].id,
64
+ :to => from_to[:to].id
65
+ }
66
+
67
+ database.query.execute(REMOVE_EDGES_AQL_STATEMENT, bind_vars: bind_vars)
68
+ end
69
+
70
+ # Builds a new edge object and passes the current graph to it
71
+ #
72
+ # @param [Hash] data The raw data to be used to instatiate the class
73
+ # @return [Edge] The instatiated edge
74
+ # @api private
75
+ def build_content_class(data)
76
+ Edge.new(@database, data, graph: graph)
77
+ end
78
+
79
+ private
80
+
81
+ # Send a request to the server through the Graph module
82
+ #
83
+ # @param [String] path The requested path
84
+ # @param [Hash] method The desired HTTP Verb (defaults to GET) and its parameters
85
+ # @return [Hash] Response from the server
86
+ # @api private
87
+ def send_request_for_this_collection(path, method = {})
88
+ send_request("gharial/#{graph.name}/edge/#@name/#{path}", method)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -4,6 +4,7 @@ require 'ashikawa-core/exceptions/client_error/resource_not_found'
4
4
  require 'ashikawa-core/exceptions/client_error/resource_not_found/index_not_found'
5
5
  require 'ashikawa-core/exceptions/client_error/resource_not_found/document_not_found'
6
6
  require 'ashikawa-core/exceptions/client_error/resource_not_found/collection_not_found'
7
+ require 'ashikawa-core/exceptions/client_error/resource_not_found/graph_not_found'
7
8
  require 'ashikawa-core/exceptions/client_error/bad_syntax'
8
9
  require 'ashikawa-core/exceptions/client_error/authentication_failed'
9
10
  require 'ashikawa-core/exceptions/server_error'
@@ -100,10 +101,25 @@ module Ashikawa
100
101
  when %r{\A(/_db/[^/]+)?/_api/document} then DocumentNotFoundException
101
102
  when %r{\A(/_db/[^/]+)?/_api/collection} then CollectionNotFoundException
102
103
  when %r{\A(/_db/[^/]+)?/_api/index} then IndexNotFoundException
104
+ when %r{\A(/_db/[^/]+)?/_api/gharial} then resource_not_found_in_graph_scope
103
105
  else ResourceNotFound
104
106
  end
105
107
  end
106
108
 
109
+ # Raise fitting ResourceNotFoundException within the Graph module
110
+ #
111
+ # @raise [DocumentNotFoundException, CollectionNotFoundException, GraphNotFoundException, ResourceNotFound]
112
+ # @return nil
113
+ # @api private
114
+ def resource_not_found_in_graph_scope
115
+ raise case @body['errorMessage']
116
+ when 'graph not found' then GraphNotFoundException
117
+ when 'collection not found' then CollectionNotFoundException
118
+ when 'document not found' then DocumentNotFoundException
119
+ else ResourceNotFound
120
+ end
121
+ end
122
+
107
123
  # Read the error message for the request
108
124
  #
109
125
  # @param [String] The raw body of the request
@@ -0,0 +1,18 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'ashikawa-core/exceptions/client_error/resource_not_found'
3
+
4
+ module Ashikawa
5
+ module Core
6
+ # This Exception is thrown when the collection was found in the database but was not
7
+ # yet associated to the Graph.
8
+ class CollectionNotInGraphException < ResourceNotFound
9
+ # String representation of the exception
10
+ #
11
+ # @return String
12
+ # @api private
13
+ def to_s
14
+ 'The requested collection has not been added to the graph yet.'
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'ashikawa-core/exceptions/client_error/resource_not_found'
3
+
4
+ module Ashikawa
5
+ module Core
6
+ # This Exception is thrown when a graph was requested from
7
+ # the server that does not exist.
8
+ class GraphNotFoundException < ResourceNotFound
9
+ # String representation of the exception
10
+ #
11
+ # @return String
12
+ # @api private
13
+ def to_s
14
+ 'You requested a graph from the server that does not exist'
15
+ end
16
+ end
17
+ end
18
+ end
@@ -15,7 +15,7 @@ module Ashikawa
15
15
  }
16
16
 
17
17
  # Request middlewares that will be prepended
18
- DEFAULT_REQUEST_MIDDLEWARES = [:json]
18
+ DEFAULT_REQUEST_MIDDLEWARES = [:json, :x_arango_version]
19
19
 
20
20
  # Response middlewares that will be prepended
21
21
  DEFAULT_RESPONSE_MIDDLEWARES = [:error_response, :json]