neography 0.0.31 → 1.0.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.
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