ashikawa-core 0.6.0 → 0.7.0
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.
- data/.rspec +0 -1
- data/.travis.yml +2 -0
- data/CONTRIBUTING.md +14 -29
- data/Gemfile.devtools +9 -10
- data/README.md +30 -9
- data/Rakefile +1 -1
- data/ashikawa-core.gemspec +9 -8
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/roodi.yml +4 -5
- data/config/site.reek +40 -16
- data/config/yardstick.yml +1 -1
- data/lib/ashikawa-core/collection.rb +109 -22
- data/lib/ashikawa-core/connection.rb +42 -110
- data/lib/ashikawa-core/cursor.rb +13 -6
- data/lib/ashikawa-core/database.rb +67 -17
- data/lib/ashikawa-core/document.rb +41 -10
- data/lib/ashikawa-core/edge.rb +50 -0
- data/lib/ashikawa-core/exceptions/client_error/bad_syntax.rb +24 -0
- data/lib/ashikawa-core/exceptions/{collection_not_found.rb → client_error/resource_not_found/collection_not_found.rb} +3 -1
- data/lib/ashikawa-core/exceptions/{document_not_found.rb → client_error/resource_not_found/document_not_found.rb} +3 -1
- data/lib/ashikawa-core/exceptions/{index_not_found.rb → client_error/resource_not_found/index_not_found.rb} +3 -1
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found.rb +25 -0
- data/lib/ashikawa-core/exceptions/client_error.rb +23 -0
- data/lib/ashikawa-core/exceptions/server_error/json_error.rb +25 -0
- data/lib/ashikawa-core/exceptions/server_error.rb +23 -0
- data/lib/ashikawa-core/figure.rb +59 -2
- data/lib/ashikawa-core/index.rb +23 -7
- data/lib/ashikawa-core/query.rb +10 -10
- data/lib/ashikawa-core/request_preprocessor.rb +49 -0
- data/lib/ashikawa-core/response_preprocessor.rb +111 -0
- data/lib/ashikawa-core/version.rb +1 -1
- data/lib/ashikawa-core.rb +0 -1
- data/spec/acceptance/basic_spec.rb +61 -22
- data/spec/acceptance/index_spec.rb +11 -4
- data/spec/acceptance/query_spec.rb +4 -1
- data/spec/acceptance/spec_helper.rb +0 -2
- data/spec/acceptance_auth/spec_helper.rb +0 -2
- data/spec/fixtures/collections/60768679-count.json +13 -0
- data/spec/fixtures/collections/60768679-figures.json +35 -0
- data/spec/fixtures/collections/60768679-properties-volatile.json +12 -0
- data/spec/fixtures/collections/60768679-properties.json +12 -0
- data/spec/fixtures/collections/{4588.json → 60768679.json} +2 -2
- data/spec/fixtures/collections/all.json +5 -5
- data/spec/fixtures/cursor/26011191-2.json +1 -1
- data/spec/fixtures/cursor/26011191.json +1 -1
- data/spec/fixtures/documents/example_1-137249191.json +6 -0
- data/spec/fixtures/documents/new-example_1-137249191.json +6 -0
- data/spec/setup/arangodb.sh +1 -1
- data/spec/unit/collection_spec.rb +117 -42
- data/spec/unit/connection_spec.rb +161 -61
- data/spec/unit/cursor_spec.rb +39 -12
- data/spec/unit/database_spec.rb +119 -19
- data/spec/unit/document_spec.rb +4 -2
- data/spec/unit/edge_spec.rb +54 -0
- data/spec/unit/exception_spec.rb +36 -8
- data/spec/unit/figure_spec.rb +37 -11
- data/spec/unit/index_spec.rb +1 -1
- data/spec/unit/query_spec.rb +18 -18
- data/spec/unit/spec_helper.rb +4 -13
- data/tasks/adjustments.rake +3 -2
- metadata +59 -32
- data/lib/ashikawa-core/exceptions/unknown_path.rb +0 -15
- data/spec/fixtures/collections/4590-properties.json +0 -9
- data/spec/fixtures/collections/4590.json +0 -8
- data/spec/fixtures/collections/73482-figures.json +0 -23
- data/spec/fixtures/documents/4590-333.json +0 -5
- data/spec/fixtures/documents/new-4590-333.json +0 -5
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'ashikawa-core/document'
|
2
|
+
|
3
|
+
module Ashikawa
|
4
|
+
module Core
|
5
|
+
# A certain Edge within a certain Collection
|
6
|
+
class Edge < Document
|
7
|
+
# The ID of the 'from' document
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
# @api public
|
11
|
+
# @example Get the ID for the 'from' Document
|
12
|
+
# document = Ashikawa::Core::Edge.new(database, raw_document)
|
13
|
+
# document.from_id # => "my_fancy_collection/2345678"
|
14
|
+
attr_reader :from_id
|
15
|
+
|
16
|
+
# The ID of the 'to' document
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
# @api public
|
20
|
+
# @example Get the ID for the 'to' Document
|
21
|
+
# document = Ashikawa::Core::Edge.new(database, raw_document)
|
22
|
+
# document.to_id # => "my_fancy_collection/2345678"
|
23
|
+
attr_reader :to_id
|
24
|
+
|
25
|
+
# Initialize an Edge with the database and raw data
|
26
|
+
#
|
27
|
+
# @param [Database] database
|
28
|
+
# @param [Hash] raw_edge
|
29
|
+
# @api public
|
30
|
+
# @example Create an Edge
|
31
|
+
# document = Ashikawa::Core::Edge.new(database, raw_edge)
|
32
|
+
def initialize(database, raw_edge)
|
33
|
+
@from_id = raw_edge["_from"]
|
34
|
+
@to_id = raw_edge["_to"]
|
35
|
+
super(database, raw_edge)
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
# Send a request for this edge with the given opts
|
41
|
+
#
|
42
|
+
# @param [Hash] opts Options for this request
|
43
|
+
# @return [Hash] The parsed response from the server
|
44
|
+
# @api private
|
45
|
+
def send_request_for_document(opts = {})
|
46
|
+
@database.send_request("edge/#{@id}", opts)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "ashikawa-core/exceptions/client_error.rb"
|
2
|
+
|
3
|
+
module Ashikawa
|
4
|
+
module Core
|
5
|
+
# This exception is thrown when the client used bad syntax in a request
|
6
|
+
class BadSyntax < ClientError
|
7
|
+
# Create a new instance
|
8
|
+
#
|
9
|
+
# @return RuntimeError
|
10
|
+
# @api private
|
11
|
+
def initialize
|
12
|
+
super(400)
|
13
|
+
end
|
14
|
+
|
15
|
+
# String representation of the exception
|
16
|
+
#
|
17
|
+
# @return String
|
18
|
+
# @api private
|
19
|
+
def to_s
|
20
|
+
"Status 400: The syntax of the request was bad"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
require "ashikawa-core/exceptions/client_error/resource_not_found"
|
2
|
+
|
1
3
|
module Ashikawa
|
2
4
|
module Core
|
3
5
|
# This Exception is thrown when a document was requested from
|
4
6
|
# the server that does not exist.
|
5
|
-
class CollectionNotFoundException <
|
7
|
+
class CollectionNotFoundException < ResourceNotFound
|
6
8
|
# String representation of the exception
|
7
9
|
#
|
8
10
|
# @return String
|
@@ -1,8 +1,10 @@
|
|
1
|
+
require "ashikawa-core/exceptions/client_error/resource_not_found"
|
2
|
+
|
1
3
|
module Ashikawa
|
2
4
|
module Core
|
3
5
|
# This Exception is thrown when a document was requested from
|
4
6
|
# the server that does not exist.
|
5
|
-
class DocumentNotFoundException <
|
7
|
+
class DocumentNotFoundException < ResourceNotFound
|
6
8
|
# String representation of the exception
|
7
9
|
#
|
8
10
|
# @return String
|
@@ -1,8 +1,10 @@
|
|
1
|
+
require "ashikawa-core/exceptions/client_error/resource_not_found"
|
2
|
+
|
1
3
|
module Ashikawa
|
2
4
|
module Core
|
3
5
|
# This Exception is thrown when an index was requested from
|
4
6
|
# the server that does not exist.
|
5
|
-
class IndexNotFoundException <
|
7
|
+
class IndexNotFoundException < ResourceNotFound
|
6
8
|
# String representation of the exception
|
7
9
|
#
|
8
10
|
# @return String
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "ashikawa-core/exceptions/client_error.rb"
|
2
|
+
|
3
|
+
module Ashikawa
|
4
|
+
module Core
|
5
|
+
# This Exception is thrown when you request
|
6
|
+
# a resource that does not exist on the server
|
7
|
+
class ResourceNotFound < ClientError
|
8
|
+
# Create a new instance
|
9
|
+
#
|
10
|
+
# @return RuntimeError
|
11
|
+
# @api private
|
12
|
+
def initialize
|
13
|
+
super(404)
|
14
|
+
end
|
15
|
+
|
16
|
+
# String representation of the exception
|
17
|
+
#
|
18
|
+
# @return String
|
19
|
+
# @api private
|
20
|
+
def to_s
|
21
|
+
"Status 404: The Resource you requested was not found on the server"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ashikawa
|
2
|
+
module Core
|
3
|
+
# The client had an error in the request
|
4
|
+
class ClientError < RuntimeError
|
5
|
+
# Create a new instance
|
6
|
+
#
|
7
|
+
# @param [Integer] status
|
8
|
+
# @return RuntimeError
|
9
|
+
# @api private
|
10
|
+
def initialize(status)
|
11
|
+
@status = status
|
12
|
+
end
|
13
|
+
|
14
|
+
# String representation of the exception
|
15
|
+
#
|
16
|
+
# @return String
|
17
|
+
# @api private
|
18
|
+
def to_s
|
19
|
+
"Status #{@status}: An Error occured in the client"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "ashikawa-core/exceptions/server_error"
|
2
|
+
|
3
|
+
module Ashikawa
|
4
|
+
module Core
|
5
|
+
# This Exception is thrown when the Json
|
6
|
+
# from the server was malformed
|
7
|
+
class JsonError < ServerError
|
8
|
+
# Create a new instance
|
9
|
+
#
|
10
|
+
# @return RuntimeError
|
11
|
+
# @api private
|
12
|
+
def initialize
|
13
|
+
super(nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
# String representation of the exception
|
17
|
+
#
|
18
|
+
# @return String
|
19
|
+
# @api private
|
20
|
+
def to_s
|
21
|
+
"Either the JSON from the server was malformed or the content type incorrect"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ashikawa
|
2
|
+
module Core
|
3
|
+
# The server had an error during the request
|
4
|
+
class ServerError < RuntimeError
|
5
|
+
# Create a new instance
|
6
|
+
#
|
7
|
+
# @param [Integer] status
|
8
|
+
# @return RuntimeError
|
9
|
+
# @api private
|
10
|
+
def initialize(status)
|
11
|
+
@status = status
|
12
|
+
end
|
13
|
+
|
14
|
+
# String representation of the exception
|
15
|
+
#
|
16
|
+
# @return String
|
17
|
+
# @api private
|
18
|
+
def to_s
|
19
|
+
"Status #{@status}: An Error occured on the server"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/ashikawa-core/figure.rb
CHANGED
@@ -10,8 +10,10 @@ module Ashikawa
|
|
10
10
|
# figure = Ashikawa::Core::Figure.new(raw_figure)
|
11
11
|
def initialize(raw_figure)
|
12
12
|
@datafiles = raw_figure["datafiles"]
|
13
|
-
@alive
|
14
|
-
@dead
|
13
|
+
@alive = raw_figure["alive"]
|
14
|
+
@dead = raw_figure["dead"]
|
15
|
+
@shapes = raw_figure["shapes"]
|
16
|
+
@journals = raw_figure["journals"]
|
15
17
|
end
|
16
18
|
|
17
19
|
# The number of active datafiles
|
@@ -25,6 +27,17 @@ module Ashikawa
|
|
25
27
|
@datafiles["count"]
|
26
28
|
end
|
27
29
|
|
30
|
+
# The file size of datafiles
|
31
|
+
#
|
32
|
+
# @return Fixnum
|
33
|
+
# @api public
|
34
|
+
# @example Get the file size of datafiles
|
35
|
+
# figure = Ashikawa::Core::Figure.new(raw_figure)
|
36
|
+
# figure.datafile_size #=> 1337
|
37
|
+
def datafiles_file_size
|
38
|
+
@datafiles["fileSize"]
|
39
|
+
end
|
40
|
+
|
28
41
|
# The total size in bytes used by all living documents
|
29
42
|
#
|
30
43
|
# @return Fixnum
|
@@ -68,6 +81,50 @@ module Ashikawa
|
|
68
81
|
def dead_count
|
69
82
|
@dead["count"]
|
70
83
|
end
|
84
|
+
|
85
|
+
# The total number of shapes used in the collection
|
86
|
+
#
|
87
|
+
# @return Fixnum
|
88
|
+
# @api public
|
89
|
+
# @example Get the number of shapes
|
90
|
+
# figure = Ashikawa::Core::Figure.new(raw_figure)
|
91
|
+
# figure.shapes_count #=> 1337
|
92
|
+
def shapes_count
|
93
|
+
@shapes["count"]
|
94
|
+
end
|
95
|
+
|
96
|
+
# The number of deletion markers
|
97
|
+
#
|
98
|
+
# @return Fixnum
|
99
|
+
# @api public
|
100
|
+
# @example Get the number of deletion markers
|
101
|
+
# figure = Ashikawa::Core::Figure.new(raw_figure)
|
102
|
+
# figure.dead_deletion #=> 1337
|
103
|
+
def dead_deletion
|
104
|
+
@dead["deletion"]
|
105
|
+
end
|
106
|
+
|
107
|
+
# The number of journals
|
108
|
+
#
|
109
|
+
# @return Fixnum
|
110
|
+
# @api public
|
111
|
+
# @example Get the number of journals
|
112
|
+
# figure = Ashikawa::Core::Figure.new(raw_figure)
|
113
|
+
# figure.journal_count #=> 1337
|
114
|
+
def journals_count
|
115
|
+
@journals["count"]
|
116
|
+
end
|
117
|
+
|
118
|
+
# The file size of journals
|
119
|
+
#
|
120
|
+
# @return Fixnum
|
121
|
+
# @api public
|
122
|
+
# @example Get the file size of journals
|
123
|
+
# figure = Ashikawa::Core::Figure.new(raw_figure)
|
124
|
+
# figure.journal_size #=> 1337
|
125
|
+
def journals_file_size
|
126
|
+
@journals["fileSize"]
|
127
|
+
end
|
71
128
|
end
|
72
129
|
end
|
73
130
|
end
|
data/lib/ashikawa-core/index.rb
CHANGED
@@ -3,6 +3,7 @@ module Ashikawa
|
|
3
3
|
# An index on a certain collection
|
4
4
|
class Index
|
5
5
|
# The fields the index is defined on as symbols
|
6
|
+
#
|
6
7
|
# @return [Array<Symbol>]
|
7
8
|
# @api public
|
8
9
|
# @example Get the fields the index is set on
|
@@ -11,6 +12,7 @@ module Ashikawa
|
|
11
12
|
attr_reader :on
|
12
13
|
|
13
14
|
# The type of index as a symbol
|
15
|
+
#
|
14
16
|
# @return [Symbol]
|
15
17
|
# @api public
|
16
18
|
# @example Get the type of the index
|
@@ -19,6 +21,7 @@ module Ashikawa
|
|
19
21
|
attr_reader :type
|
20
22
|
|
21
23
|
# Is the unique constraint set?
|
24
|
+
#
|
22
25
|
# @return [Boolean]
|
23
26
|
# @api public
|
24
27
|
# @example Get the fields the index is set on
|
@@ -26,8 +29,9 @@ module Ashikawa
|
|
26
29
|
# index.unique #=> false
|
27
30
|
attr_reader :unique
|
28
31
|
|
29
|
-
# The
|
30
|
-
#
|
32
|
+
# The ID of the index (includes a Collection prefix)
|
33
|
+
#
|
34
|
+
# @return [String]
|
31
35
|
# @api public
|
32
36
|
# @example Get the id of this index
|
33
37
|
# index = Ashikawa::Core::Index.new(collection, raw_index)
|
@@ -44,10 +48,7 @@ module Ashikawa
|
|
44
48
|
# index = Ashikawa::Core::Index.new(collection, raw_index)
|
45
49
|
def initialize(collection, raw_index)
|
46
50
|
@collection = collection
|
47
|
-
|
48
|
-
@on = raw_index["fields"].map { |field| field.to_sym } if raw_index.has_key?("fields")
|
49
|
-
@type = raw_index["type"].to_sym if raw_index.has_key?("type")
|
50
|
-
@unique = raw_index["unique"] if raw_index.has_key?("unique")
|
51
|
+
parse_raw_index(raw_index)
|
51
52
|
end
|
52
53
|
|
53
54
|
# Remove the index from the collection
|
@@ -58,7 +59,22 @@ module Ashikawa
|
|
58
59
|
# index = Ashikawa::Core::Index.new(collection, raw_index)
|
59
60
|
# index.delete
|
60
61
|
def delete
|
61
|
-
@collection.send_request("index/#{@
|
62
|
+
@collection.send_request("index/#{@id}", :delete => {})
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Parse information returned from the server
|
68
|
+
#
|
69
|
+
# @param [Hash] raw_index
|
70
|
+
# @return self
|
71
|
+
# @api private
|
72
|
+
def parse_raw_index(raw_index)
|
73
|
+
@id = raw_index["id"]
|
74
|
+
@on = raw_index["fields"].map { |field| field.to_sym } if raw_index.has_key?("fields")
|
75
|
+
@type = raw_index["type"].to_sym if raw_index.has_key?("type")
|
76
|
+
@unique = raw_index["unique"]
|
77
|
+
self
|
62
78
|
end
|
63
79
|
end
|
64
80
|
end
|
data/lib/ashikawa-core/query.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'ashikawa-core/cursor'
|
2
2
|
require 'ashikawa-core/document'
|
3
3
|
require 'ashikawa-core/exceptions/no_collection_provided'
|
4
|
+
require 'ashikawa-core/exceptions/client_error/bad_syntax'
|
4
5
|
require 'forwardable'
|
5
6
|
require 'backports'
|
6
|
-
require 'rest-client'
|
7
7
|
|
8
8
|
module Ashikawa
|
9
9
|
module Core
|
@@ -38,7 +38,7 @@ module Ashikawa
|
|
38
38
|
# query = Ashikawa::Core::Query.new(collection)
|
39
39
|
# query.all # => #<Cursor id=33>
|
40
40
|
def all(options={})
|
41
|
-
simple_query_request("
|
41
|
+
simple_query_request("simple/all",
|
42
42
|
options,
|
43
43
|
[:limit, :skip])
|
44
44
|
end
|
@@ -56,7 +56,7 @@ module Ashikawa
|
|
56
56
|
# query = Ashikawa::Core::Query.new(collection)
|
57
57
|
# query.by_example({ "color" => "red" }, :options => { :limit => 1 }) #=> #<Cursor id=2444>
|
58
58
|
def by_example(example={}, options={})
|
59
|
-
simple_query_request("
|
59
|
+
simple_query_request("simple/by-example",
|
60
60
|
{ :example => example }.merge(options),
|
61
61
|
[:limit, :skip, :example])
|
62
62
|
end
|
@@ -71,7 +71,7 @@ module Ashikawa
|
|
71
71
|
# query = Ashikawa::Core::Query.new(collection)
|
72
72
|
# query.first_example({ "color" => "red"}) # => #<Document id=2444 color="red">
|
73
73
|
def first_example(example = {})
|
74
|
-
response = simple_query_request("
|
74
|
+
response = simple_query_request("simple/first-example",
|
75
75
|
{ :example => example },
|
76
76
|
[:example])
|
77
77
|
response.first
|
@@ -92,7 +92,7 @@ module Ashikawa
|
|
92
92
|
# query = Ashikawa::Core::Query.new(collection)
|
93
93
|
# query.near(:latitude => 37.331693, :longitude => -122.030468)
|
94
94
|
def near(options={})
|
95
|
-
simple_query_request("
|
95
|
+
simple_query_request("simple/near",
|
96
96
|
options,
|
97
97
|
[:latitude, :longitude, :distance, :skip, :limit, :geo])
|
98
98
|
end
|
@@ -113,7 +113,7 @@ module Ashikawa
|
|
113
113
|
# query = Ashikawa::Core::Query.new(collection)
|
114
114
|
# query.within(:latitude => 37.331693, :longitude => -122.030468, :radius => 100)
|
115
115
|
def within(options={})
|
116
|
-
simple_query_request("
|
116
|
+
simple_query_request("simple/within",
|
117
117
|
options,
|
118
118
|
[:latitude, :longitude, :radius, :distance, :skip, :limit, :geo])
|
119
119
|
end
|
@@ -133,7 +133,7 @@ module Ashikawa
|
|
133
133
|
# query = Ashikawa::Core::Query.new(collection)
|
134
134
|
# query.within(:latitude => 37.331693, :longitude => -122.030468, :radius => 100)
|
135
135
|
def in_range(options={})
|
136
|
-
simple_query_request("
|
136
|
+
simple_query_request("simple/range",
|
137
137
|
options,
|
138
138
|
[:attribute, :left, :right, :closed, :limit, :skip])
|
139
139
|
end
|
@@ -149,7 +149,7 @@ module Ashikawa
|
|
149
149
|
# query = Ashikawa::Core::Query.new(collection)
|
150
150
|
# query.execute("FOR u IN users LIMIT 2") # => #<Cursor id=33>
|
151
151
|
def execute(query, options = {})
|
152
|
-
post_request("
|
152
|
+
post_request("cursor",
|
153
153
|
options.merge({ :query => query }),
|
154
154
|
[:query, :count, :batch_size])
|
155
155
|
end
|
@@ -163,8 +163,8 @@ module Ashikawa
|
|
163
163
|
# query = Ashikawa::Core::Query.new(collection)
|
164
164
|
# query.valid?("FOR u IN users LIMIT 2") # => true
|
165
165
|
def valid?(query)
|
166
|
-
|
167
|
-
rescue
|
166
|
+
!!post_request("query", { :query => query })
|
167
|
+
rescue Ashikawa::Core::BadSyntax
|
168
168
|
false
|
169
169
|
end
|
170
170
|
|