ashikawa-core 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|