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.
Files changed (68) hide show
  1. data/.rspec +0 -1
  2. data/.travis.yml +2 -0
  3. data/CONTRIBUTING.md +14 -29
  4. data/Gemfile.devtools +9 -10
  5. data/README.md +30 -9
  6. data/Rakefile +1 -1
  7. data/ashikawa-core.gemspec +9 -8
  8. data/config/flay.yml +2 -2
  9. data/config/flog.yml +1 -1
  10. data/config/roodi.yml +4 -5
  11. data/config/site.reek +40 -16
  12. data/config/yardstick.yml +1 -1
  13. data/lib/ashikawa-core/collection.rb +109 -22
  14. data/lib/ashikawa-core/connection.rb +42 -110
  15. data/lib/ashikawa-core/cursor.rb +13 -6
  16. data/lib/ashikawa-core/database.rb +67 -17
  17. data/lib/ashikawa-core/document.rb +41 -10
  18. data/lib/ashikawa-core/edge.rb +50 -0
  19. data/lib/ashikawa-core/exceptions/client_error/bad_syntax.rb +24 -0
  20. data/lib/ashikawa-core/exceptions/{collection_not_found.rb → client_error/resource_not_found/collection_not_found.rb} +3 -1
  21. data/lib/ashikawa-core/exceptions/{document_not_found.rb → client_error/resource_not_found/document_not_found.rb} +3 -1
  22. data/lib/ashikawa-core/exceptions/{index_not_found.rb → client_error/resource_not_found/index_not_found.rb} +3 -1
  23. data/lib/ashikawa-core/exceptions/client_error/resource_not_found.rb +25 -0
  24. data/lib/ashikawa-core/exceptions/client_error.rb +23 -0
  25. data/lib/ashikawa-core/exceptions/server_error/json_error.rb +25 -0
  26. data/lib/ashikawa-core/exceptions/server_error.rb +23 -0
  27. data/lib/ashikawa-core/figure.rb +59 -2
  28. data/lib/ashikawa-core/index.rb +23 -7
  29. data/lib/ashikawa-core/query.rb +10 -10
  30. data/lib/ashikawa-core/request_preprocessor.rb +49 -0
  31. data/lib/ashikawa-core/response_preprocessor.rb +111 -0
  32. data/lib/ashikawa-core/version.rb +1 -1
  33. data/lib/ashikawa-core.rb +0 -1
  34. data/spec/acceptance/basic_spec.rb +61 -22
  35. data/spec/acceptance/index_spec.rb +11 -4
  36. data/spec/acceptance/query_spec.rb +4 -1
  37. data/spec/acceptance/spec_helper.rb +0 -2
  38. data/spec/acceptance_auth/spec_helper.rb +0 -2
  39. data/spec/fixtures/collections/60768679-count.json +13 -0
  40. data/spec/fixtures/collections/60768679-figures.json +35 -0
  41. data/spec/fixtures/collections/60768679-properties-volatile.json +12 -0
  42. data/spec/fixtures/collections/60768679-properties.json +12 -0
  43. data/spec/fixtures/collections/{4588.json → 60768679.json} +2 -2
  44. data/spec/fixtures/collections/all.json +5 -5
  45. data/spec/fixtures/cursor/26011191-2.json +1 -1
  46. data/spec/fixtures/cursor/26011191.json +1 -1
  47. data/spec/fixtures/documents/example_1-137249191.json +6 -0
  48. data/spec/fixtures/documents/new-example_1-137249191.json +6 -0
  49. data/spec/setup/arangodb.sh +1 -1
  50. data/spec/unit/collection_spec.rb +117 -42
  51. data/spec/unit/connection_spec.rb +161 -61
  52. data/spec/unit/cursor_spec.rb +39 -12
  53. data/spec/unit/database_spec.rb +119 -19
  54. data/spec/unit/document_spec.rb +4 -2
  55. data/spec/unit/edge_spec.rb +54 -0
  56. data/spec/unit/exception_spec.rb +36 -8
  57. data/spec/unit/figure_spec.rb +37 -11
  58. data/spec/unit/index_spec.rb +1 -1
  59. data/spec/unit/query_spec.rb +18 -18
  60. data/spec/unit/spec_helper.rb +4 -13
  61. data/tasks/adjustments.rake +3 -2
  62. metadata +59 -32
  63. data/lib/ashikawa-core/exceptions/unknown_path.rb +0 -15
  64. data/spec/fixtures/collections/4590-properties.json +0 -9
  65. data/spec/fixtures/collections/4590.json +0 -8
  66. data/spec/fixtures/collections/73482-figures.json +0 -23
  67. data/spec/fixtures/documents/4590-333.json +0 -5
  68. data/spec/fixtures/documents/new-4590-333.json +0 -5
data/.rspec CHANGED
@@ -1,4 +1,3 @@
1
1
  --color
2
2
  --format progress
3
- --profile
4
3
  --order random
data/.travis.yml CHANGED
@@ -18,3 +18,5 @@ matrix:
18
18
  - rvm: ruby-head
19
19
  - rvm: jruby-head
20
20
  script: "bundle exec rake ci"
21
+ notifications:
22
+ webhooks: https://www.buildheroes.com/api/projects/0f136ecd2207606cfacf9a968fe9fd0819398b63/builds
data/CONTRIBUTING.md CHANGED
@@ -2,40 +2,25 @@
2
2
 
3
3
  When you want to write code for the project, please follow these guidelines:
4
4
 
5
- 1. Claim the ticket: Tell us that you want to work on a certain ticket, we will assign it to you (We don't want two people to work on the same thing ;) )
6
- 2. Fork your feature branch from the `development` branch (not the `master` branch)
7
- 3. Write an acceptance test: Describe what you want to do (our integration tests touch the database)
8
- 4. Implement it: Write a unit test, check that it fails, make the test pass – repeat (our unit tests don't touch the database)
9
- 5. Write documentation for it.
10
- 6. Check with `bundle exec rake` that everything is fine and send the pull request to the `development` branch :)
5
+ 1. **Claim** the ticket: Tell us that you want to work on a certain ticket, we will assign it to you (We don't want two people to work on the same thing ;) )
6
+ 2. **Fork** your feature branch from the `development` branch (not the `master` branch)
7
+ 3. Write an **acceptance test**: Describe what you want to do (our acceptance tests touch the database)
8
+ 4. **Implement** it: Write a unit test, check that it fails, make the test pass – repeat (our unit tests don't touch the database)
9
+ 5. Write **documentation** for it.
10
+ 6. Check with `bundle exec rake ci` (you need to have ArangoDB running for that) that everything is fine and send the pull request to the `development` branch :)
11
11
 
12
- ## How to get started developing
12
+ ## Setup
13
13
 
14
- Getting started is easy, just follow these steps.
14
+ Nothing special:
15
15
 
16
- ### In a nutshell
17
-
18
- * Clone the project.
16
+ * Clone the project
19
17
  * `cd` into the folder and run `bundle`
20
- * `bundle exec rake` and see all tests passing (you need to have ArangoDB installed for that)
21
- * Happy coding!
22
-
23
- ### Detailed description
24
-
25
- Make sure you are running Ruby 1.9.x (or JRuby/Rubinius in 1.9 mode) and clone the latest snapshot into a directory of your choice. Also make sure ArangoDB is installed and accessible via `arangod` (for example by installing it via `brew install arangodb`).
26
-
27
- We encourage you to use [rvm](https://rvm.io/). If you do so, a gemset for the project is created upon changing into the directory. If you do not use `rvm` nothing special will happen in this case. Don't worry about it.
28
-
29
- Change into the project directory. Run `bundle` to get all dependencies (do a `gem install bundler` before if you don't have bundler installed).
30
-
31
- Now you can run `bundle exec rake` to see all tests passing (hopefully). Happy coding!
32
-
33
- You can also start up yard for documentation: `bundle exec rake yard:server`
18
+ * `bundle exec rake ci` and see all tests passing (you need to have ArangoDB running for that)
19
+ * Happy hacking!
34
20
 
35
- ### Guard
21
+ ## Guard
36
22
 
37
- Guard is a tool for comfortable development. If you want to use it for development, you have to first start an instance of ArangoDB and then start guard with `bundle exec guard`. This will:
23
+ Guard is a tool for comfortable development. If you want to use it, you have to first start an instance of ArangoDB and then start guard with `bundle exec guard`. This will:
38
24
 
39
- * Run a documentation server on `http://localhost:8808`
40
25
  * Run `bundle` whenever you change the dependencies
41
- * Run the integration and unit tests whenever you change a file in the lib or spec directory
26
+ * Run the **unit tests** whenever you change a file in the lib or spec directory
data/Gemfile.devtools CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  group :development do
4
4
  gem 'rake', '~> 10.0.3'
5
- gem 'rspec', '~> 2.12.0'
5
+ gem 'rspec', '~> 2.13.0'
6
6
  gem 'yard', '~> 0.8.4.1'
7
7
  end
8
8
 
@@ -13,15 +13,14 @@ end
13
13
  group :guard do
14
14
  gem 'guard', '~> 1.6.2'
15
15
  gem 'guard-bundler', '~> 1.0.0'
16
- gem 'guard-rspec', '~> 2.3.3'
16
+ gem 'guard-rspec', '~> 2.4.1'
17
17
 
18
18
  # file system change event handling
19
19
  gem 'rb-fchange', '~> 0.0.6', :require => false
20
20
  gem 'rb-fsevent', '~> 0.9.3', :require => false
21
21
  gem 'rb-inotify', '~> 0.9.0', :require => false
22
22
 
23
- # Remove this one https://github.com/guard/listen/pull/78 is released
24
- gem 'listen', '~> 0.7.2', :git => 'https://github.com/guard/listen.git'
23
+ gem 'listen', '~> 0.7.3'
25
24
 
26
25
  # notification handling
27
26
  gem 'libnotify', '~> 0.8.0', :require => false
@@ -30,11 +29,11 @@ group :guard do
30
29
  end
31
30
 
32
31
  group :metrics do
33
- gem 'flay', '~> 1.4.3'
34
- gem 'flog', '~> 2.5.3'
35
- gem 'reek', '~> 1.2.13', :git => 'https://github.com/troessner/reek.git', :ref => 'ef77fcecaa21c9ebcbe4d9a79d41b0e70196bf18'
36
- gem 'roodi', '~> 2.2.0'
37
- gem 'yardstick', '~> 0.9.2'
32
+ gem 'flay', '~> 2.1.0'
33
+ gem 'flog', '~> 3.2.2'
34
+ gem 'reek', '~> 1.3.1'
35
+ gem 'metric_fu-roodi', '~> 2.2.1'
36
+ gem 'yardstick', '~> 0.9.2'
38
37
 
39
38
  platforms :ruby_18, :ruby_19 do
40
39
  # this indirectly depends on ffi which does not build on ruby-head
@@ -42,7 +41,7 @@ group :metrics do
42
41
  end
43
42
 
44
43
  platforms :mri_19, :rbx do
45
- # gem 'mutant', '~> 0.2.16'
44
+ gem 'mutant', '~> 0.2.17'
46
45
  end
47
46
 
48
47
  platforms :mri_19 do
data/README.md CHANGED
@@ -5,26 +5,47 @@
5
5
  [![Dependency Status](https://gemnasium.com/triAGENS/ashikawa-core.png)](https://gemnasium.com/triAGENS/ashikawa-core)
6
6
  [![Code Climate](https://codeclimate.com/github/triAGENS/ashikawa-core.png)](https://codeclimate.com/github/triAGENS/ashikawa-core)
7
7
 
8
- Ashikawa Core is a Wrapper around the ArangoDB Rest API. It provides low level access and will be used in different ArangoDB ODMs and other projects related to the database. It is always working with the stable version of ArangoDB, this is currently version **1.1.2**.
8
+ Ashikawa Core is a Wrapper around the ArangoDB Rest API. It provides low level access and will be used in different ArangoDB ODMs and other projects related to the database. It is always working with the stable version of ArangoDB, this is currently version **1.2**. If you want to access an ArangoDB instance running version **1.1.2** refer to version [0.6](https://github.com/triAGENS/ashikawa-core/tree/0.6.0) of this gem (or just update ;) ).
9
9
 
10
10
  All tests run on Travis CI for the following versions of Ruby:
11
11
 
12
- * MRI 1.8.7, 1.9.2 and 1.9.3
12
+ * MRI 1.8.7, 1.9.2, 1.9.3 and 2.0.0
13
13
  * Rubinius 1.8 and 1.9 mode
14
14
  * JRuby 1.8 and 1.9 mode
15
15
  * REE
16
16
 
17
17
  We also run on JRuby and MRI Head, but they are allowed failures (Please see [Travis](http://travis-ci.org/triAGENS/ashikawa-core) for their build status).
18
18
 
19
- Please note that the `master` branch is always the stable version released on Ruby Gems and documented on RDoc. If you want the most recent version, please refer to the `development` branch.
19
+ Please note that the [`master`](https://github.com/triAGENS/ashikawa-core) branch is always the stable version released on Ruby Gems and documented on RDoc. If you want the most recent version, please refer to the [`development`](https://github.com/triAGENS/ashikawa-core/tree/development) branch.
20
20
 
21
- ## How to use it
21
+ ## How to Setup a Connection
22
22
 
23
- For a detailed description of Ashikawa::Core please refer to the [documentation](http://rdoc.info/github/triAGENS/ashikawa-core/master/frames). An example:
23
+ We want to provide you with as much flexibility as possible. So you can choose which adapter to use for HTTP (choose from the adapters available for [Faraday](https://github.com/lostisland/faraday)) and what you want to use for logging (basically anything that has an `info` method that takes a String). It defaults to Net::HTTP and no logging:
24
24
 
25
25
  ```ruby
26
- database = Ashikawa::Core::Database.new "http://localhost:8529"
26
+ database = Ashikawa::Core::Database.new do |config|
27
+ config.url = "http://localhost:8529"
28
+ end
29
+ ```
30
+
31
+ But you could for example use Typhoeus for HTTP and yell for logging:
32
+
33
+ ```ruby
34
+ require "typhoeus"
35
+ require "yell"
36
+
37
+ logger = Yell.new(STDOUT)
27
38
 
39
+ database = Ashikawa::Core::Database.new do |config|
40
+ config.url = "http://localhost:8529"
41
+ config.adapter = :typhoeus
42
+ config.logger = logger
43
+ end
44
+ ```
45
+
46
+ For a detailed description on how to use Ashikawa::Core please refer to the [documentation](http://rdoc.info/github/triAGENS/ashikawa-core/master/frames). An example:
47
+
48
+ ```ruby
28
49
  database["my_collection"] # => Returns the collection my_collection – creates it, if it doesn't exist
29
50
  database["my_collection"].name = "new_name"
30
51
  database["new_name"].delete
@@ -38,6 +59,6 @@ If you find a bug in this gem, please report it on [our tracker](https://github.
38
59
 
39
60
  If you want to contribute to the project, see CONTRIBUTING.md for details. It contains information on our process and how to set up everything. The following people have contributed to this project:
40
61
 
41
- * Lucas Dohmen (@moonglum): Developer
42
- * Tobias Eilert (@EinLama): Contributor
43
- * Markus Schirp (@mbj): Contributor
62
+ * Lucas Dohmen ([@moonglum](https://github.com/moonglum)): Developer
63
+ * Tobias Eilert ([@EinLama](https://github.com/EinLama)): Contributor
64
+ * Markus Schirp ([@mbj](https://github.com/mbj)): Contributor
data/Rakefile CHANGED
@@ -3,6 +3,6 @@ require 'devtools'
3
3
  require 'bundler/gem_tasks'
4
4
  require 'rspec/core/rake_task'
5
5
 
6
- Devtools.init
6
+ Devtools.init_rake_tasks
7
7
 
8
8
  import("./tasks/adjustments.rake")
@@ -9,10 +9,10 @@ Gem::Specification.new do |gem|
9
9
  gem.email = ["me@moonglum.net", "tobias.eilert@me.com"]
10
10
  gem.homepage = "http://triagens.github.com/ashikawa-core"
11
11
  gem.summary = "Ashikawa Core is a wrapper around the ArangoDB REST API"
12
- gem.description = "Ashikawa Core is a wrapper around the ArangoDB REST API. It provides low level access and will be used in different ArangoDB ODMs."
12
+ gem.description = "Ashikawa Core is a wrapper around the ArangoDB REST API. It provides low level access and will be used in different ArangoDB ODMs and other tools."
13
13
 
14
- gem.required_ruby_version = '>= 1.9.2'
15
- gem.requirements << "ArangoDB, v1.1.2"
14
+ gem.required_ruby_version = '>= 1.8.7'
15
+ gem.requirements << "ArangoDB, v1.2"
16
16
 
17
17
  gem.rubyforge_project = "ashikawa-core"
18
18
 
@@ -21,10 +21,11 @@ Gem::Specification.new do |gem|
21
21
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
22
  gem.require_paths = ["lib"]
23
23
 
24
- # Runtime Dependencies
25
- gem.add_dependency "rest-client", "~> 1.6.7"
26
- gem.add_dependency "json", "~> 1.7.7"
24
+ gem.add_dependency "faraday", "~> 0.8.6"
25
+ gem.add_dependency "multi_json", "~> 1.6.1"
26
+ gem.add_dependency "null_logger", "~> 0.0.1"
27
27
 
28
- # Development Dependencies
29
- gem.add_development_dependency "webmock", "~> 1.9.3"
28
+ # Set to 2.8.2 because of Devtools
29
+ # Needs an upgrade, because of an error in this version
30
+ gem.add_dependency "backports", "~> 2.8.2"
30
31
  end
data/config/flay.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  ---
2
- threshold: 18
3
- total_score: 250
2
+ threshold: 14
3
+ total_score: 265
data/config/flog.yml CHANGED
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 23.0
2
+ threshold: 11.3
data/config/roodi.yml CHANGED
@@ -1,15 +1,14 @@
1
- AbcMetricMethodCheck: { score: 15.0 }
1
+ AbcMetricMethodCheck: { score: 10.0 }
2
2
  AssignmentInConditionalCheck: { }
3
- CaseMissingElseCheck: { }
4
- ClassLineCountCheck: { line_count: 500 }
3
+ ClassLineCountCheck: { line_count: 1000 }
5
4
  ClassNameCheck:
6
5
  pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
7
6
  ClassVariableCheck: { }
8
7
  CyclomaticComplexityBlockCheck: { complexity: 1 }
9
- CyclomaticComplexityMethodCheck: { complexity: 5 }
8
+ CyclomaticComplexityMethodCheck: { complexity: 6 }
10
9
  EmptyRescueBodyCheck: { }
11
10
  ForLoopCheck: { }
12
- MethodLineCountCheck: { line_count: 10 }
11
+ MethodLineCountCheck: { line_count: 9 }
13
12
  MethodNameCheck:
14
13
  pattern: !ruby/regexp /^[_a-z<>=\[\]|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/
15
14
  ModuleLineCountCheck: { line_count: 500 }
data/config/site.reek CHANGED
@@ -2,7 +2,7 @@
2
2
  UncommunicativeParameterName:
3
3
  accept: []
4
4
  exclude: []
5
- enabled: false
5
+ enabled: true
6
6
  reject:
7
7
  - !ruby/regexp /^.$/
8
8
  - !ruby/regexp /[0-9]$/
@@ -10,6 +10,7 @@ UncommunicativeParameterName:
10
10
  LargeClass:
11
11
  max_methods: 10
12
12
  exclude:
13
+ - Ashikawa::Core::Figure
13
14
  - Ashikawa::Core::Query
14
15
  - Ashikawa::Core::Collection
15
16
  enabled: true
@@ -29,8 +30,17 @@ LongParameterList:
29
30
  enabled: true
30
31
  overrides: {}
31
32
  FeatureEnvy:
32
- exclude: []
33
- enabled: false
33
+ exclude:
34
+ - Ashikawa::Core::RequestPreprocessor
35
+ - Ashikawa::Core::ResponsePreprocessor
36
+ - Ashikawa::Core::Database#initialize
37
+ - Ashikawa::Core::Database#create_collection
38
+ - Ashikawa::Core::Connection#http_verb
39
+ - Ashikawa::Core::Connection#initialize
40
+ - Ashikawa::Core::Index#parse_raw_index
41
+ - Ashikawa::Core::Query#allowed_options
42
+ - Ashikawa::Core::Query#prepare_request_data
43
+ enabled: true
34
44
  ClassVariable:
35
45
  exclude: []
36
46
  enabled: true
@@ -47,26 +57,26 @@ UncommunicativeModuleName:
47
57
  reject: []
48
58
  NestedIterators:
49
59
  ignore_iterators: []
50
- exclude: []
60
+ exclude:
61
+ - Ashikawa::Core::Query#prepare_request_data
51
62
  enabled: true
52
- max_allowed_nesting: 2
63
+ max_allowed_nesting: 1
53
64
  LongMethod:
54
- max_statements: 8
55
- exclude: []
65
+ max_statements: 4
66
+ exclude:
67
+ - Ashikawa::Core::ResponsePreprocessor#handle_status
68
+ - Ashikawa::Core::Database#create_collection
69
+ - Ashikawa::Core::Cursor#parse_raw_cursor
70
+ - Ashikawa::Core::Document#parse_raw_document
71
+ - Ashikawa::Core::Index#parse_raw_index
72
+ - Ashikawa::Core::Collection#parse_raw_collection
73
+ - Ashikawa::Core::Connection#authenticate_with
56
74
  enabled: true
57
75
  Duplication:
58
76
  allow_calls: []
59
- exclude:
60
- - Ashikawa::Core::Document#initialize
77
+ exclude: []
61
78
  enabled: true
62
79
  max_calls: 1
63
- UtilityFunction:
64
- max_helper_calls: 0
65
- exclude: []
66
- enabled: false
67
- Attribute:
68
- exclude: []
69
- enabled: false
70
80
  UncommunicativeVariableName:
71
81
  accept: []
72
82
  exclude: []
@@ -93,3 +103,17 @@ LongYieldList:
93
103
  max_params: 1
94
104
  exclude: []
95
105
  enabled: true
106
+ UtilityFunction:
107
+ max_helper_calls: 0
108
+ exclude: []
109
+ enabled: false
110
+ NilCheck:
111
+ enabled: true
112
+ exclude:
113
+ - Ashikawa::Core::Database#setup_new_connection
114
+ - Ashikawa::Core::Document#check_if_persisted!
115
+ - Ashikawa::Core::Query#prepare_request_data
116
+ - Ashikawa::Core::Query#wrapped_request
117
+ Attribute:
118
+ exclude: []
119
+ enabled: false
data/config/yardstick.yml CHANGED
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 100
2
+ threshold: 98.1
@@ -1,4 +1,5 @@
1
1
  require "ashikawa-core/document"
2
+ require "ashikawa-core/edge"
2
3
  require "ashikawa-core/index"
3
4
  require "ashikawa-core/cursor"
4
5
  require "ashikawa-core/query"
@@ -12,6 +13,16 @@ module Ashikawa
12
13
  class Collection
13
14
  extend Forwardable
14
15
 
16
+ CONTENT_TYPES = {
17
+ 2 => :document,
18
+ 3 => :edge
19
+ }
20
+
21
+ CONTENT_CLASS = {
22
+ :document => Document,
23
+ :edge => Edge
24
+ }
25
+
15
26
  # The name of the collection, must be unique
16
27
  #
17
28
  # @return [String]
@@ -87,6 +98,24 @@ module Ashikawa
87
98
  # collection.database #=> #<Database: ...>
88
99
  attr_reader :database
89
100
 
101
+ # The kind of content in the collection: Documents or Edges
102
+ #
103
+ # @return [:document, :edge]
104
+ # @api public
105
+ # @example
106
+ # database = Ashikawa::Core::Database.new("http://localhost:8529")
107
+ # raw_collection = {
108
+ # "name" => "example_1",
109
+ # "waitForSync" => true,
110
+ # "id" => 4588,
111
+ # "status" => 3,
112
+ # "error" => false,
113
+ # "code" => 200
114
+ # }
115
+ # collection = Ashikawa::Core::Collection.new(database, raw_collection)
116
+ # collection.content_type #=> :document
117
+ attr_reader :content_type
118
+
90
119
  # Sending requests is delegated to the database
91
120
  def_delegator :@database, :send_request
92
121
 
@@ -108,9 +137,8 @@ module Ashikawa
108
137
  # collection = Ashikawa::Core::Collection.new(database, raw_collection)
109
138
  def initialize(database, raw_collection)
110
139
  @database = database
111
- @name = raw_collection['name'] if raw_collection.has_key?('name')
112
- @id = raw_collection['id'].to_i if raw_collection.has_key?('id')
113
- @status = Status.new raw_collection['status'].to_i if raw_collection.has_key?('status')
140
+ parse_raw_collection(raw_collection)
141
+ @content_class = CONTENT_CLASS[@content_type]
114
142
  end
115
143
 
116
144
  # Change the name of the collection
@@ -307,8 +335,8 @@ module Ashikawa
307
335
  # @example Fetch the document with the ID 12345
308
336
  # document = collection[12345]
309
337
  def [](document_id)
310
- server_response = send_request("/document/#{@id}/#{document_id}")
311
- Document.new(@database, server_response)
338
+ response = send_request_for_content_id(document_id)
339
+ @content_class.new(@database, response)
312
340
  end
313
341
 
314
342
  # Replace a document by its ID
@@ -320,22 +348,38 @@ module Ashikawa
320
348
  # @example Replace the document with the ID 12345
321
349
  # collection[12345] = document
322
350
  def []=(document_id, raw_document)
323
- send_request("/document/#{@id}/#{document_id}", :put => raw_document)
351
+ send_request_for_content_id(document_id, :put => raw_document)
324
352
  end
325
353
 
326
- # Create a new document from raw data
354
+ # Create a new document with given attributes
327
355
  #
328
- # @param [Hash] raw_document
356
+ # @param [Hash] attributes
329
357
  # @return [Document] The created document
330
358
  # @api public
331
359
  # @example Create a new document from raw data
332
- # collection.create(raw_document)
333
- def create(raw_document)
334
- server_response = send_request("/document?collection=#{@id}", :post => raw_document)
335
- Document.new(@database, server_response)
360
+ # collection.create_document(attributes)
361
+ def create_document(attributes)
362
+ raise "Can't create a document in an edge collection" if @content_type == :edge
363
+ response = send_request_for_content(:post => attributes)
364
+ Document.new(@database, response)
336
365
  end
337
366
 
338
- alias :<< :create
367
+ alias :<< :create_document
368
+
369
+ # Create a new edge between two documents with certain attributes
370
+ #
371
+ # @param [Document] from
372
+ # @param [Document] to
373
+ # @param [Hash] attributes
374
+ # @return [Edge] The created edge
375
+ # @api public
376
+ # @example Create a new document from raw data
377
+ # collection.create_edge(node_a, node_b, {"name" => "incredible edge"})
378
+ def create_edge(from, to, attributes)
379
+ raise "Can't create an edge in a document collection" if @content_type == :document
380
+ response = send_request("edge?collection=#{@id}&from=#{from.id}&to=#{to.id}", :post => attributes)
381
+ Edge.new(@database, response)
382
+ end
339
383
 
340
384
  # Add an index to the collection
341
385
  #
@@ -347,7 +391,7 @@ module Ashikawa
347
391
  # people = database['people']
348
392
  # people.add_index(:hash, :on => [:name, :profession])
349
393
  def add_index(type, opts)
350
- response = send_request("/index?collection=#{@id}", :post => {
394
+ response = send_request("index?collection=#{@id}", :post => {
351
395
  "type" => type.to_s,
352
396
  "fields" => opts[:on].map { |field| field.to_s }
353
397
  })
@@ -364,7 +408,7 @@ module Ashikawa
364
408
  # people = database['people']
365
409
  # people.index(1244) #=> #<Index: id=1244...>
366
410
  def index(id)
367
- server_response = send_request("/index/#{@id}/#{id}")
411
+ server_response = send_request("index/#{@name}/#{id}")
368
412
  Index.new(self, server_response)
369
413
  end
370
414
 
@@ -376,9 +420,9 @@ module Ashikawa
376
420
  # people = database['people']
377
421
  # people.indices #=> [#<Index: id=1244...>, ...]
378
422
  def indices
379
- server_response = send_request("/index?collection=#{@id}")
423
+ response = send_request("index?collection=#{@id}")
380
424
 
381
- server_response["indexes"].map do |raw_index|
425
+ response["indexes"].map do |raw_index|
382
426
  Index.new(self, raw_index)
383
427
  end
384
428
  end
@@ -394,6 +438,17 @@ module Ashikawa
394
438
  Query.new(self)
395
439
  end
396
440
 
441
+ # Check if the collection is volatile
442
+ #
443
+ # @return [Boolean]
444
+ # @api public
445
+ # @example Is the people collection volatile?
446
+ # people = database['people']
447
+ # people.volatile? #=> false
448
+ def volatile?
449
+ get_information_from_server(:properties, :isVolatile)
450
+ end
451
+
397
452
  private
398
453
 
399
454
  # Send a put request with a given key and value to the server
@@ -404,7 +459,7 @@ module Ashikawa
404
459
  # @return [Object] The result
405
460
  # @api private
406
461
  def send_information_to_server(path, key, value)
407
- send_request_for_this_collection("/#{path}", :put => { key.to_s => value })
462
+ send_request_for_this_collection("#{path}", :put => { key.to_s => value })
408
463
  end
409
464
 
410
465
  # Send a put request with the given command
@@ -413,7 +468,7 @@ module Ashikawa
413
468
  # @return [Object] The result
414
469
  # @api private
415
470
  def send_command_to_server(command)
416
- send_request_for_this_collection("/#{command}", :put => {})
471
+ send_request_for_this_collection("#{command}", :put => {})
417
472
  end
418
473
 
419
474
  # Send a get request to the server and return a certain attribute
@@ -423,8 +478,8 @@ module Ashikawa
423
478
  # @return [Object] The result
424
479
  # @api private
425
480
  def get_information_from_server(path, attribute)
426
- server_response = send_request_for_this_collection("/#{path}")
427
- server_response[attribute.to_s]
481
+ response = send_request_for_this_collection("#{path}")
482
+ response[attribute.to_s]
428
483
  end
429
484
 
430
485
  # Send a request to the server with the name of the collection prepended
@@ -432,7 +487,39 @@ module Ashikawa
432
487
  # @return [String] Response from the server
433
488
  # @api private
434
489
  def send_request_for_this_collection(path, method={})
435
- send_request("/collection/#{id}#{path}", method)
490
+ send_request("collection/#{id}/#{path}", method)
491
+ end
492
+
493
+ # Parse information returned from the server
494
+ #
495
+ # @param [Hash] raw_collection
496
+ # @return self
497
+ # @api private
498
+ def parse_raw_collection(raw_collection)
499
+ @name = raw_collection['name']
500
+ @id = raw_collection['id']
501
+ @content_type = CONTENT_TYPES[raw_collection['type']] || :document
502
+ @status = Status.new(raw_collection['status'].to_i) if raw_collection.has_key?('status')
503
+ self
504
+ end
505
+
506
+ # Send a request for the content with the given id
507
+ #
508
+ # @param [Integer] document_id The id of the document
509
+ # @param [Hash] opts The options for the request
510
+ # @return [Hash] parsed JSON response from the server
511
+ # @api private
512
+ def send_request_for_content_id(document_id, opts = {})
513
+ send_request("#{@content_type}/#{@id}/#{document_id}", opts)
514
+ end
515
+
516
+ # Send a request for the content of this collection
517
+ #
518
+ # @param [Hash] opts The options for the request
519
+ # @return [Hash] parsed JSON response from the server
520
+ # @api private
521
+ def send_request_for_content(opts = {})
522
+ send_request("#{@content_type}?collection=#{@id}", opts)
436
523
  end
437
524
  end
438
525
  end