neography 0.0.31 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/.gitignore +3 -0
  2. data/.travis.yml +1 -1
  3. data/CONTRIBUTORS +2 -1
  4. data/README.md +247 -0
  5. data/Rakefile +1 -2
  6. data/lib/neography/config.rb +48 -16
  7. data/lib/neography/connection.rb +151 -0
  8. data/lib/neography/errors.rb +42 -0
  9. data/lib/neography/node.rb +17 -14
  10. data/lib/neography/node_relationship.rb +3 -1
  11. data/lib/neography/node_traverser.rb +24 -20
  12. data/lib/neography/property.rb +31 -28
  13. data/lib/neography/property_container.rb +1 -1
  14. data/lib/neography/relationship.rb +16 -19
  15. data/lib/neography/rest/auto_indexes.rb +64 -0
  16. data/lib/neography/rest/batch.rb +262 -0
  17. data/lib/neography/rest/clean.rb +19 -0
  18. data/lib/neography/rest/cypher.rb +24 -0
  19. data/lib/neography/rest/gremlin.rb +24 -0
  20. data/lib/neography/rest/helpers.rb +26 -0
  21. data/lib/neography/rest/indexes.rb +97 -0
  22. data/lib/neography/rest/node_auto_indexes.rb +14 -0
  23. data/lib/neography/rest/node_indexes.rb +35 -0
  24. data/lib/neography/rest/node_paths.rb +57 -0
  25. data/lib/neography/rest/node_properties.rb +11 -0
  26. data/lib/neography/rest/node_relationships.rb +53 -0
  27. data/lib/neography/rest/node_traversal.rb +81 -0
  28. data/lib/neography/rest/nodes.rb +102 -0
  29. data/lib/neography/rest/paths.rb +36 -0
  30. data/lib/neography/rest/properties.rb +56 -0
  31. data/lib/neography/rest/relationship_auto_indexes.rb +14 -0
  32. data/lib/neography/rest/relationship_indexes.rb +35 -0
  33. data/lib/neography/rest/relationship_properties.rb +11 -0
  34. data/lib/neography/rest/relationships.rb +23 -0
  35. data/lib/neography/rest.rb +285 -615
  36. data/lib/neography/tasks.rb +1 -1
  37. data/lib/neography/version.rb +1 -1
  38. data/lib/neography.rb +13 -2
  39. data/neography.gemspec +8 -8
  40. data/spec/integration/authorization_spec.rb +2 -2
  41. data/spec/integration/index_spec.rb +4 -4
  42. data/spec/integration/neography_spec.rb +2 -2
  43. data/spec/integration/node_path_spec.rb +2 -2
  44. data/spec/integration/node_relationship_spec.rb +5 -3
  45. data/spec/integration/node_spec.rb +20 -19
  46. data/spec/integration/parsing_spec.rb +2 -2
  47. data/spec/integration/relationship_spec.rb +2 -2
  48. data/spec/integration/rest_batch_spec.rb +28 -28
  49. data/spec/integration/rest_bulk_spec.rb +2 -2
  50. data/spec/integration/rest_experimental_spec.rb +2 -2
  51. data/spec/integration/rest_gremlin_fail_spec.rb +2 -2
  52. data/spec/integration/rest_header_spec.rb +4 -9
  53. data/spec/integration/rest_index_spec.rb +21 -1
  54. data/spec/integration/rest_node_spec.rb +58 -44
  55. data/spec/integration/rest_path_spec.rb +5 -5
  56. data/spec/integration/rest_plugin_spec.rb +8 -2
  57. data/spec/integration/rest_relationship_spec.rb +35 -30
  58. data/spec/integration/rest_traverse_spec.rb +2 -2
  59. data/spec/matchers.rb +33 -0
  60. data/spec/neography_spec.rb +23 -0
  61. data/spec/spec_helper.rb +19 -1
  62. data/spec/unit/config_spec.rb +46 -0
  63. data/spec/unit/connection_spec.rb +205 -0
  64. data/spec/unit/node_spec.rb +100 -0
  65. data/spec/unit/properties_spec.rb +136 -0
  66. data/spec/unit/relationship_spec.rb +118 -0
  67. data/spec/unit/rest/batch_spec.rb +243 -0
  68. data/spec/unit/rest/clean_spec.rb +17 -0
  69. data/spec/unit/rest/cypher_spec.rb +21 -0
  70. data/spec/unit/rest/gremlin_spec.rb +26 -0
  71. data/spec/unit/rest/node_auto_indexes_spec.rb +67 -0
  72. data/spec/unit/rest/node_indexes_spec.rb +126 -0
  73. data/spec/unit/rest/node_paths_spec.rb +80 -0
  74. data/spec/unit/rest/node_properties_spec.rb +80 -0
  75. data/spec/unit/rest/node_relationships_spec.rb +78 -0
  76. data/spec/unit/rest/node_traversal_spec.rb +128 -0
  77. data/spec/unit/rest/nodes_spec.rb +188 -0
  78. data/spec/unit/rest/paths_spec.rb +69 -0
  79. data/spec/unit/rest/relationship_auto_indexes_spec.rb +67 -0
  80. data/spec/unit/rest/relationship_indexes_spec.rb +128 -0
  81. data/spec/unit/rest/relationship_properties_spec.rb +80 -0
  82. data/spec/unit/rest/relationships_spec.rb +22 -0
  83. metadata +86 -19
  84. data/Gemfile.lock +0 -44
  85. data/README.rdoc +0 -420
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ Gemfile.lock
1
2
  .idea
2
3
  *.iml
3
4
  neo4j
@@ -5,3 +6,5 @@ pkg/*
5
6
  *.gem
6
7
  .bundle
7
8
  log/*
9
+ .rvmrc
10
+ Gemfile.lock
data/.travis.yml CHANGED
@@ -1,4 +1,4 @@
1
- script: "bundle exec rake neo4j:install['enterprise','1.8.M06'] neo4j:start spec --trace"
1
+ script: "bundle exec rake neo4j:install['enterprise','1.8'] neo4j:start spec --trace"
2
2
  language: ruby
3
3
  rvm:
4
4
  - 1.9.3
data/CONTRIBUTORS CHANGED
@@ -14,4 +14,5 @@ Contributors:
14
14
  * Nick Reavill
15
15
  * Marcel Sherf
16
16
  * David Pitman
17
- * Garrett Heaver
17
+ * Garrett Heaver
18
+ * Roel van Dijk
data/README.md ADDED
@@ -0,0 +1,247 @@
1
+ [![Build Status](https://secure.travis-ci.org/maxdemarzi/neography.png?branch=master)](http://travis-ci.org/maxdemarzi/neography)
2
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/maxdemarzi/neography)
3
+
4
+ ## Welcome to Neography
5
+
6
+ Neography is a thin Ruby wrapper to the Neo4j Rest API, for more information:
7
+
8
+ * [Getting Started with Neo4j Server](http://neo4j.org/community/)
9
+ * [Neo4j Rest API Reference](http://docs.neo4j.org/chunked/milestone/rest-api.html)
10
+
11
+ If you want to the full power of Neo4j, you will want to use JRuby and the excellent Neo4j.rb gem at https://github.com/andreasronge/neo4j by Andreas Ronge
12
+
13
+
14
+ ## Installation
15
+
16
+ ### Gemfile
17
+
18
+ Add `neography` to your Gemfile:
19
+
20
+ ```ruby
21
+ gem 'neography'
22
+ ```
23
+
24
+ And run Bundler:
25
+
26
+ ```sh
27
+ $ bundle
28
+ ```
29
+
30
+ ### Manually:
31
+
32
+ Or install `neography` manually:
33
+
34
+ ```sh
35
+ $ gem install 'neography'
36
+ ```
37
+
38
+ And require the gem in your Ruby code:
39
+
40
+ ```ruby
41
+ require 'rubygems'
42
+ require 'neography'
43
+ ```
44
+
45
+ Read the wiki for information about [dependencies](https://github.com/maxdemarzi/neography/wiki/Dependencies).
46
+
47
+ [Rake tasks](https://github.com/maxdemarzi/neography/wiki/Rake-tasks) are available for downloading, installing and running Neo4j.
48
+
49
+
50
+ ## Usage
51
+
52
+ ### Configuration and initialization
53
+
54
+ Configure Neography as follows:
55
+
56
+ ```ruby
57
+ # these are the default values:
58
+ Neography.configure do |config|
59
+ config.protocol = "http://"
60
+ config.server = "localhost"
61
+ config.port = 7474
62
+ config.directory = "" # prefix this path with '/'
63
+ config.cypher_path = "/cypher"
64
+ config.gremlin_path = "/ext/GremlinPlugin/graphdb/execute_script"
65
+ config.log_file = "neography.log"
66
+ config.log_enabled = false
67
+ config.max_threads = 20
68
+ config.authentication = nil # 'basic' or 'digest'
69
+ config.username = nil
70
+ config.password = nil
71
+ config.parser = {:parser => MultiJsonParser}
72
+ end
73
+ ```
74
+
75
+ Then initialize a `Rest` instance:
76
+
77
+ ```ruby
78
+ @neo = Neography::Rest.new
79
+ ```
80
+
81
+ For overriding these default and other initialization methods, see the
82
+ [configuration and initialization](https://github.com/maxdemarzi/neography/wiki/Configuration-and-initialization) page in the Wiki.
83
+
84
+
85
+ ### REST API
86
+
87
+ Neography supports the creation and retrieval of nodes and relationships through the Neo4j REST interface.
88
+ It supports indexes, Gremlin scripts, Cypher queries and batch operations.
89
+
90
+ Some of this functionality is shown here, but all of it is explained in the following Wiki pages:
91
+
92
+ * [Nodes](https://github.com/maxdemarzi/neography/wiki/Nodes) - Create, get and delete nodes.
93
+ * [Node properties](https://github.com/maxdemarzi/neography/wiki/Node-properties) - Set, get and remove node properties.
94
+ * [Node relationships](https://github.com/maxdemarzi/neography/wiki/Node-relationships) - Create and get relationships between nodes.
95
+ * [Relationship](https://github.com/maxdemarzi/neography/wiki/Relationships) - Get and delete relationships.
96
+ * [Relationship properties](https://github.com/maxdemarzi/neography/wiki/Relationship-properties) - Create, get and delete relationship properties.
97
+ * [Node indexes](https://github.com/maxdemarzi/neography/wiki/Node-indexes) - List and create node indexes. Add, remove, get and search nodes in indexes.
98
+ * [Relationship indexes](https://github.com/maxdemarzi/neography/wiki/Relationship-indexes) - List and create relationships indexes. Add, remove, get and search relationships in indexes.
99
+ * [Auto indexes](https://github.com/maxdemarzi/neography/wiki/Auto-indexes) - Get, set and remove auto indexes.
100
+ * [Scripts and queries](https://github.com/maxdemarzi/neography/wiki/Scripts-and-queries) - Run Gremlin scripts and Cypher queries.
101
+ * [Paths and traversal](https://github.com/maxdemarzi/neography/wiki/Paths-and-traversal) - Paths between nodes and path traversal.
102
+ * [Batch](https://github.com/maxdemarzi/neography/wiki/Batch) - Execute multiple calls at once.
103
+ * [Errors](https://github.com/maxdemarzi/neography/wiki/Errors) - Errors raised if REST API calls fail.
104
+
105
+
106
+ Some example usage:
107
+
108
+ ```ruby
109
+ # Node creation:
110
+ node1 = @neo.create_node("age" => 31, "name" => "Max")
111
+ node2 = @neo.create_node("age" => 33, "name" => "Roel")
112
+
113
+ # Node properties:
114
+ @neo.set_node_properties(node1, {"weight" => 200})
115
+
116
+ # Relationships between nodes:
117
+ @neo.create_relationship("coding_buddies", node1, node2)
118
+
119
+ # Get node relationships:
120
+ @neo.get_node_relationships(node2, "in", "coding_buddies")
121
+
122
+ # Use indexes:
123
+ @neo.add_node_to_index("people", "name", "max", node1)
124
+ @neo.get_node_index("people", "name", "max")
125
+
126
+ # Cypher queries:
127
+ @neo.execute_query("start n=node(0) return n")
128
+
129
+ # Batches:
130
+ @neo.batch [:create_node, {"name" => "Max"}],
131
+ [:create_node, {"name" => "Marc"}]
132
+ ```
133
+
134
+ This is just a small sample of the full API, see the [Wiki documentation](https://github.com/maxdemarzi/neography/wiki) for the full API.
135
+
136
+ Neography raises REST API errors as Ruby errors, see the wiki page about [errors](https://github.com/maxdemarzi/neography/wiki/Errors).
137
+ (**Note**: older versions of Neography did not raise any errors!)
138
+
139
+
140
+ ## *Phase 2*
141
+
142
+ Trying to mimic the [Neo4j.rb API](https://github.com/andreasronge/neo4j/wiki/Neo4j%3A%3ACore-Nodes-Properties-Relationships).
143
+
144
+ Now we are returning full objects. The properties of the node or relationship can be accessed directly (`node.name`).
145
+ The Neo4j ID is available by using `node.neo_id`.
146
+
147
+ Some of this functionality is shown here, but all of it is explained in the following Wiki pages:
148
+
149
+ * [Nodes](https://github.com/maxdemarzi/neography/wiki/Phase-2-Nodes) - Create, load and delete nodes.
150
+ * [Node properties](https://github.com/maxdemarzi/neography/wiki/Phase-2-Node-properties) - Add, get and remove node properties.
151
+ * [Node relationships](https://github.com/maxdemarzi/neography/wiki/Phase-2-Node-relationships) - Create and retrieve node relationships.
152
+ * [Node paths](https://github.com/maxdemarzi/neography/wiki/Phase-2-Node-paths) - Gets paths between nodes.
153
+
154
+
155
+ ```ruby
156
+ # create two nodes:
157
+ n1 = Neography::Node.create("age" => 31, "name" => "Max")
158
+ n2 = Neography::Node.create("age" => 33, "name" => "Roel")
159
+
160
+ n1.exist? # => true
161
+
162
+ # get and change some properties:
163
+ n1[:age] # => 31
164
+ n1.name # => "Max"
165
+ n1[:age] = 32 # change property
166
+ n1.weight = 190 # new property
167
+ n1.age = nil # remove property
168
+
169
+ # add a relationship between nodes:
170
+ new_rel = Neography::Relationship.create(:coding_buddies, n1, n2)
171
+
172
+ # remove a relationship:
173
+ new_rel.del
174
+
175
+ # add a relationship on nodes:
176
+ n1.outgoing(:coding_buddies) << n2
177
+
178
+ # more advanced relationship traversal:
179
+ n1.outgoing(:friends) # Get nodes related by outgoing friends relationship
180
+ n1.outgoing(:friends).depth(2).include_start_node # Get n1 and nodes related by friends and friends of friends
181
+
182
+ n1.rel?(:outgoing, :friends) # Has outgoing friends relationship
183
+ n1.rels(:friends,:work).outgoing # Get outgoing friends and work relationships
184
+
185
+ n1.all_paths_to(n2).incoming(:friends).depth(4) # Gets all paths of a specified type
186
+ n1.shortest_path_to(n2).incoming(:friends).depth(4).nodes # Gets just nodes in path
187
+ ```
188
+
189
+ This is just a small sample of the full API, see the [Wiki documentation](https://github.com/maxdemarzi/neography/wiki) for the full API.
190
+
191
+ ## More
192
+
193
+ ### Examples
194
+
195
+ Some [example code](https://github.com/maxdemarzi/neography/wiki/Examples).
196
+
197
+
198
+ ### Testing
199
+
200
+ Some [tips about testing](https://github.com/maxdemarzi/neography/wiki/Testing).
201
+
202
+
203
+ ### Related Neo4j projects
204
+
205
+ Complement to Neography are the:
206
+
207
+ * [Neo4j Active Record Adapter](https://github.com/yournextleap/activerecord-neo4j-adapter) by Nikhil Lanjewar
208
+ * [Neology](https://github.com/lordkada/neology) by Carlo Alberto Degli Atti
209
+ * [Neoid](https://github.com/elado/neoid) by Elad Ossadon
210
+
211
+ An alternative to Neography is [Architect4r](https://github.com/namxam/architect4r) by Maximilian Schulz
212
+
213
+
214
+ ### Neography in the Wild
215
+
216
+ * [Vouched](http://getvouched.com)
217
+ * [Neovigator](http://neovigator.herokuapp.com) fork it at https://github.com/maxdemarzi/neovigator
218
+ * [Neoflix](http://neoflix.herokuapp.com) fork it at https://github.com/maxdemarzi/neoflix
219
+
220
+
221
+ ### Getting started with Neography
222
+
223
+ * [Getting Started with Ruby and Neo4j](http://maxdemarzi.com/2012/01/04/getting-started-with-ruby-and-neo4j/)
224
+ * [Graph visualization with Neo4j](http://maxdemarzi.com/2012/01/11/graph-visualization-and-neo4j/)
225
+ * [Neo4j on Heroku](http://maxdemarzi.com/2012/01/13/neo4j-on-heroku-part-one/)
226
+
227
+
228
+ ## Contributing
229
+
230
+ Please create a [new issue](https://github.com/maxdemarzi/neography/issues) if you run into any bugs.
231
+
232
+ Contribute patches via [pull requests](https://github.com/maxdemarzi/neography/pulls).
233
+
234
+
235
+ ## Help
236
+
237
+ If you are just starting out, or need help send me an e-mail at maxdemarzi@gmail.com.
238
+
239
+ Check you my blog at http://maxdemarzi.com where I have more Neography examples.
240
+
241
+
242
+ ## Licenses
243
+
244
+ * Neography - MIT, see the LICENSE file http://github.com/maxdemarzi/neography/tree/master/LICENSE.
245
+ * Lucene - Apache, see http://lucene.apache.org/java/docs/features.html
246
+ * Neo4j - Dual free software/commercial license, see http://neo4j.org
247
+
data/Rakefile CHANGED
@@ -6,10 +6,9 @@ require 'neography/tasks'
6
6
 
7
7
  RSpec::Core::RakeTask.new(:spec) do |t|
8
8
  t.rspec_opts = "--color"
9
- t.pattern = "spec/integration/*_spec.rb"
9
+ t.pattern = "spec/**/*_spec.rb"
10
10
  end
11
11
 
12
12
  desc "Run Tests"
13
13
  task :default => :spec
14
14
 
15
-
@@ -1,20 +1,52 @@
1
1
  module Neography
2
- class Config
3
- class << self; attr_accessor :protocol, :server, :port, :directory, :cypher_path, :gremlin_path, :log_file, :log_enabled, :logger, :max_threads, :authentication, :username, :password, :parser end
2
+ class Config
3
+
4
+ attr_accessor :protocol, :server, :port, :directory,
5
+ :cypher_path, :gremlin_path,
6
+ :log_file, :log_enabled,
7
+ :max_threads,
8
+ :authentication, :username, :password,
9
+ :parser
10
+
11
+ def initialize
12
+ set_defaults
13
+ end
14
+
15
+ def to_hash
16
+ {
17
+ :protocol => @protocol,
18
+ :server => @server,
19
+ :port => @port,
20
+ :directory => @directory,
21
+ :cypher_path => @cypher_path,
22
+ :gremlin_path => @gremlin_path,
23
+ :log_file => @log_file,
24
+ :log_enabled => @log_enabled,
25
+ :max_threads => @max_threads,
26
+ :authentication => @authentication,
27
+ :username => @username,
28
+ :password => @password,
29
+ :parser => @parser
30
+ }
31
+ end
32
+
33
+ private
34
+
35
+ def set_defaults
36
+ @protocol = "http://"
37
+ @server = "localhost"
38
+ @port = 7474
39
+ @directory = ""
40
+ @cypher_path = "/cypher"
41
+ @gremlin_path = "/ext/GremlinPlugin/graphdb/execute_script"
42
+ @log_file = "neography.log"
43
+ @log_enabled = false
44
+ @max_threads = 20
45
+ @authentication = nil
46
+ @username = nil
47
+ @password = nil
48
+ @parser = {:parser => MultiJsonParser}
49
+ end
4
50
 
5
- @protocol = 'http://'
6
- @server = 'localhost'
7
- @port = 7474
8
- @directory = ''
9
- @cypher_path = '/cypher'
10
- @gremlin_path = '/ext/GremlinPlugin/graphdb/execute_script'
11
- @log_file = 'neography.log'
12
- @log_enabled = false
13
- @logger = Logger.new(@log_file) if @log_enabled
14
- @max_threads = 20
15
- @authentication = {}
16
- @username = nil
17
- @password = nil
18
- @parser = {:parser => MultiJsonParser}
19
51
  end
20
52
  end
@@ -0,0 +1,151 @@
1
+ module Neography
2
+ class Connection
3
+
4
+ USER_AGENT = "Neography/#{Neography::VERSION}"
5
+
6
+ attr_accessor :protocol, :server, :port, :directory,
7
+ :cypher_path, :gremlin_path,
8
+ :log_file, :log_enabled, :logger,
9
+ :max_threads,
10
+ :authentication, :username, :password,
11
+ :parser
12
+
13
+ def initialize(options = ENV['NEO4J_URL'] || {})
14
+ config = merge_configuration(options)
15
+ save_local_configuration(config)
16
+ end
17
+
18
+ def configure(protocol, server, port, directory)
19
+ @protocol = protocol
20
+ @server = server
21
+ @port = port
22
+ @directory = directory
23
+ end
24
+
25
+ def configuration
26
+ "#{@protocol}#{@server}:#{@port}#{@directory}/db/data"
27
+ end
28
+
29
+ def merge_options(options)
30
+ merged_options = options.merge!(@authentication).merge!(@parser)
31
+ merged_options[:headers].merge!(@user_agent) if merged_options[:headers]
32
+ merged_options
33
+ end
34
+
35
+ def get(path, options={})
36
+ evaluate_response(HTTParty.get(configuration + path, merge_options(options)))
37
+ end
38
+
39
+ def post(path, options={})
40
+ evaluate_response(HTTParty.post(configuration + path, merge_options(options)))
41
+ end
42
+
43
+ def put(path, options={})
44
+ evaluate_response(HTTParty.put(configuration + path, merge_options(options)))
45
+ end
46
+
47
+ def delete(path, options={})
48
+ evaluate_response(HTTParty.delete(configuration + path, merge_options(options)))
49
+ end
50
+
51
+ private
52
+
53
+ def merge_configuration(options)
54
+ options = parse_string_options(options) unless options.is_a? Hash
55
+ config = Neography.configuration.to_hash
56
+ config.merge(options)
57
+ end
58
+
59
+ def save_local_configuration(config)
60
+ @protocol = config[:protocol]
61
+ @server = config[:server]
62
+ @port = config[:port]
63
+ @directory = config[:directory]
64
+ @cypher_path = config[:cypher_path]
65
+ @gremlin_path = config[:gremlin_path]
66
+ @log_file = config[:log_file]
67
+ @log_enabled = config[:log_enabled]
68
+ @max_threads = config[:max_threads]
69
+ @parser = config[:parser]
70
+
71
+ @user_agent = { "User-Agent" => USER_AGENT }
72
+
73
+ @authentication = {}
74
+ if config[:authentication]
75
+ @authentication = {
76
+ "#{config[:authentication]}_auth".to_sym => {
77
+ :username => config[:username],
78
+ :password => config[:password]
79
+ }
80
+ }
81
+ end
82
+
83
+ if @log_enabled
84
+ @logger = Logger.new(@log_file)
85
+ end
86
+ end
87
+
88
+ def evaluate_response(response)
89
+ code = response.code
90
+ body = response.body
91
+ case code
92
+ when 200
93
+ @logger.debug "OK" if @log_enabled
94
+ response.parsed_response
95
+ when 201
96
+ @logger.debug "OK, created #{body}" if @log_enabled
97
+ response.parsed_response
98
+ when 204
99
+ @logger.debug "OK, no content returned" if @log_enabled
100
+ nil
101
+ when 400...500
102
+ handle_4xx_response(code, body)
103
+ nil
104
+ end
105
+ end
106
+
107
+ def handle_4xx_response(code, body)
108
+ parsed_body = JSON.parse(body)
109
+ message = parsed_body["message"]
110
+ stacktrace = parsed_body["stacktrace"]
111
+
112
+ @logger.error "#{code} error: #{body}" if @log_enabled
113
+
114
+ case code
115
+ when 400, 404
116
+ case parsed_body["exception"]
117
+ when "SyntaxException" ; raise SyntaxException.new(message, code, stacktrace)
118
+ when "PropertyValueException" ; raise PropertyValueException.new(message, code, stacktrace)
119
+ when "BadInputException" ; raise BadInputException.new(message, code, stacktrace)
120
+ when "NodeNotFoundException" ; raise NodeNotFoundException.new(message, code, stacktrace)
121
+ when "NoSuchPropertyException" ; raise NoSuchPropertyException.new(message, code, stacktrace)
122
+ when "RelationshipNotFoundException" ; raise RelationshipNotFoundException.new(message, code, stacktrace)
123
+ when "NotFoundException" ; raise NotFoundException.new(message, code, stacktrace)
124
+ else
125
+ raise NeographyError.new(message, code, stacktrace)
126
+ end
127
+ when 401
128
+ raise UnauthorizedError.new(message, code, stacktrace)
129
+ when 409
130
+ raise OperationFailureException.new(message, code, stacktrace)
131
+ else
132
+ raise NeographyError.new(message, code, stacktrace)
133
+ end
134
+ end
135
+
136
+ def parse_string_options(options)
137
+ url = URI.parse(options)
138
+ options = {
139
+ :protocol => url.scheme + "://",
140
+ :server => url.host,
141
+ :port => url.port,
142
+ :directory => url.path,
143
+ :username => url.user,
144
+ :password => url.password
145
+ }
146
+ options[:authentication] = 'basic' unless url.user.nil?
147
+ options
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,42 @@
1
+ module Neography
2
+
3
+ class NeographyError < StandardError
4
+ attr_reader :message, :code, :stacktrace
5
+
6
+ def initialize(message = nil, code = nil, stacktrace = nil)
7
+ @message = message
8
+ @code = code
9
+ @stacktrace = stacktrace
10
+ end
11
+ end
12
+
13
+ # HTTP Authentication error
14
+ class UnauthorizedError < NeographyError; end
15
+
16
+ # the Neo4j server Exceptions returned by the REST API:
17
+
18
+ # A node could not be found
19
+ class NodeNotFoundException < NeographyError; end
20
+
21
+ # A node cannot be deleted because it has relationships
22
+ class OperationFailureException < NeographyError; end
23
+
24
+ # Properties can not be null
25
+ class PropertyValueException < NeographyError; end
26
+
27
+ # Trying to a delete a property that does not exist
28
+ class NoSuchPropertyException < NeographyError; end
29
+
30
+ # A relationship could not be found
31
+ class RelationshipNotFoundException < NeographyError; end
32
+
33
+ # Error during valid Cypher query
34
+ class BadInputException < NeographyError; end
35
+
36
+ # Invalid Cypher query syntax
37
+ class SyntaxException < NeographyError; end
38
+
39
+ # A path could not be found by node traversal
40
+ class NotFoundException < NeographyError; end
41
+
42
+ end
@@ -9,24 +9,22 @@ module Neography
9
9
  attr_accessor :neo_server
10
10
 
11
11
  class << self
12
- def create(*args)
13
- # the arguments can be an hash of properties to set or a rest instance
14
- props = (args[0].respond_to?(:each_pair) && args[0]) || args[1]
15
- db = (args[0].is_a?(Neography::Rest) && args[0]) || args[1] || Neography::Rest.new
12
+ def create(props = nil, db = Neography::Rest.new)
13
+ raise ArgumentError.new("syntax deprecated") if props.is_a?(Neography::Rest)
14
+
16
15
  node = self.new(db.create_node(props))
17
16
  node.neo_server = db
18
17
  node
19
18
  end
20
19
 
21
- def load(*args)
22
- # the first argument can be an hash of properties to set
23
- node = !args[0].is_a?(Neography::Rest) && args[0] || args[1]
20
+ def load(node, db = Neography::Rest.new)
21
+ raise ArgumentError.new("syntax deprecated") if node.is_a?(Neography::Rest)
24
22
 
25
- # a db instance can be given, it is the first argument or the second
26
- db = (args[0].is_a?(Neography::Rest) && args[0]) || args[1] || Neography::Rest.new
27
23
  node = db.get_node(node)
28
- node = self.new(node) unless node.nil?
29
- node.neo_server = db unless node.nil?
24
+ if node
25
+ node = self.new(node)
26
+ node.neo_server = db
27
+ end
30
28
  node
31
29
  end
32
30
 
@@ -34,12 +32,17 @@ module Neography
34
32
  end
35
33
 
36
34
  def del
37
- self.neo_server.delete_node!(self.neo_id)
35
+ neo_server.delete_node!(self.neo_id)
38
36
  end
39
37
 
40
38
  def exist?
41
- !self.neo_server.get_node(self.neo_id).nil?
39
+ begin
40
+ neo_server.get_node(self.neo_id)
41
+ true
42
+ rescue NodeNotFoundException
43
+ false
44
+ end
42
45
  end
43
46
 
44
47
  end
45
- end
48
+ end
@@ -1,6 +1,8 @@
1
1
  module Neography
2
2
  module NodeRelationship
3
3
 
4
+ DIRECTIONS = ["incoming", "in", "outgoing", "out", "all", "both"]
5
+
4
6
  def outgoing(types=nil)
5
7
  NodeTraverser.new(self).outgoing(types)
6
8
  end
@@ -32,4 +34,4 @@ module Neography
32
34
  end
33
35
 
34
36
  end
35
- end
37
+ end