-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update for Neo4J 3.x, neo4jrb 8.x, and neojrb-core 7.0.x #18
Changes from 8 commits
f36c43c
8e4632c
47b77bd
b8af182
1d8e0c3
a3dab0d
e1e38e1
726eb05
2fc2f5d
1df8d25
b31d935
cec87d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,13 @@ | |
.idea | ||
bin/ | ||
/db | ||
|
||
# shapfile stuff | ||
*.CPG | ||
*.dbf | ||
*.prj | ||
*.sbn | ||
*.sbx | ||
*.shp | ||
*.shp.xml | ||
*.shx |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,21 +8,21 @@ install: | |
- "bundle exec rake neo4j_spatial:install" | ||
- "bundle exec rake neo4j:start --trace" | ||
- "sleep 20" | ||
- "bundle exec rake neo4j:generate_schema_migration[constraint,Restaurant,uuid]" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can certainly do this, but the specs won't work on other peoples' machines unless they know to run this line. I generally try to do something like this inside the specs themselves: Neo4j::ActiveBase.label_object(: Restaurant).create_constraint(:uuid, type: :unique) You might also rescue from |
||
sudo: false | ||
cache: bundler | ||
script: | ||
- "travis_retry bundle exec rake default --trace" | ||
language: ruby | ||
jdk: oraclejdk8 | ||
rvm: | ||
- 2.0.0 | ||
- 2.2.4 | ||
- 2.3.1 | ||
- jruby-9.0.5.0 | ||
env: | ||
global: | ||
- JRUBY_OPTS="-J-Xmx1280m -Xcompile.invokedynamic=false -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -J-noverify -Xcompile.mode=OFF" | ||
- NEO4J_VERSION=3.0.1 | ||
- NEO4J_VERSION=3.1.0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 3.2 just came out, BTW ;) |
||
matrix: | ||
- NEO4J_URL="http://localhost:7474" | ||
matrix: | ||
|
@@ -32,11 +32,3 @@ matrix: | |
install: | ||
script: "bundle exec rubocop" | ||
env: "RUBOCOP=true" | ||
|
||
# Older versions of Neo4j with latest version of Ruby | ||
- rvm: 2.3.1 | ||
env: NEO4J_VERSION=2.3.3 | ||
- rvm: 2.3.1 | ||
env: NEO4J_VERSION=2.2.2 | ||
- rvm: 2.3.1 | ||
env: NEO4J_VERSION=2.1.8 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -126,6 +126,12 @@ It then drops you back into a QueryProxy in the context of the class. If you had | |
|
||
If you did no define `spatial_index` on your model or what to query against something other than the model's default, you can feed a third argument: the index to use for the query. | ||
|
||
## Rake tasks: | ||
#### `neo4j_spatial:install` | ||
|
||
usage: `NEO4J_VERSION='3.0.4' rake neo4j_spatial:install[<env>]` | ||
If no `env` argument is provided, this defaults to 'development' | ||
|
||
## Additional Resources | ||
|
||
Check out the specs and the code for help, it's rather straightforward. | ||
|
@@ -136,3 +142,29 @@ mostly works for an idea of the basics, just replace Neography-specific commands | |
## Contributions | ||
|
||
Pull requests and maintanence help would be swell. In addition to being fully tested, please ensure rubocop passes by running `rubocop` from the CLI. | ||
|
||
### Running Tests: | ||
|
||
Upon first running `bundle exec rake spec` or `bundle exec rspec spec`, you may run into an issue like this: | ||
|
||
``` | ||
Failure/Error: Restaurant.delete_all | ||
|
||
Neo4j::DeprecatedSchemaDefinitionError: | ||
Some schema elements were defined by the model (which is no longer supported), but they do not exist in the database. Run the following to create them: | ||
|
||
rake neo4j:generate_schema_migration[constraint,Restaurant,uuid] | ||
|
||
|
||
And then run `rake neo4j:migrate` | ||
... | ||
``` | ||
|
||
To resolve, simply run the commands as it says (but maybe prefix `bundle exec` depending on your setup): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see that you have this in the docs (which is great!). It would be nicer, though, if people didn't need to think about it |
||
|
||
``` | ||
bundle exec rake neo4j:generate_schema_migration[constraint,Restaurant,uuid] | ||
bundle exec rake neo4j:migrate | ||
``` | ||
|
||
NOTE that if your NEO4J_URL is not the default, you will have to prefix while running migrate: `NEO4J_URL='http://localhost:7123' be rake neo4j:migrate` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,11 @@ | ||
require 'bundler/gem_tasks' | ||
require 'neo4j' | ||
require 'neo4j/rake_tasks' | ||
require 'net/http' | ||
|
||
def system_or_fail(command) | ||
system(command) || exit(1) | ||
end | ||
require 'neo4jrb_spatial/rake_tasks' | ||
load 'neo4j/tasks/migration.rake' | ||
|
||
task 'spec' do | ||
system_or_fail('rspec spec') | ||
end | ||
|
||
namespace :neo4j_spatial do | ||
def match_version?(version, max_version) | ||
min_version = max_version.split('.')[0..-1].join('.') | ||
Gem::Version.new(version) <= Gem::Version.new(max_version) && | ||
Gem::Version.new(version) >= Gem::Version.new(min_version) | ||
end | ||
|
||
def matching_version(version) | ||
uri = 'https://raw.githubusercontent.com/neo4j-contrib/m2/master/releases/org/neo4j/neo4j-spatial/maven-metadata.xml' | ||
versions = Net::HTTP.get_response(URI.parse(uri)).body | ||
versions = versions.scan(/<version>([a-z\-0-9\.]+)<\/version>/) | ||
versions.map! { |e| e.first.split('-neo4j-') } | ||
versions.select { |e| match_version?(version, e.last) }.last | ||
end | ||
|
||
task 'install' do | ||
url = 'https://github.com/neo4j-contrib/m2/blob/master/releases/org/neo4j/neo4j-spatial' | ||
input_version = ENV['NEO4J_VERSION'] | ||
fail ArgumentError, 'Missing NEO4J_VERSION' unless input_version | ||
spatial_version, neo4j_version = *matching_version(input_version) | ||
if neo4j_version[0].to_i < 3 | ||
file_name = "neo4j-spatial-#{spatial_version}-neo4j-#{neo4j_version}-server-plugin.zip" | ||
system_or_fail("wget -O #{file_name} #{url}/#{spatial_version}-neo4j-#{neo4j_version}/#{file_name}?raw=true") | ||
system_or_fail("unzip #{file_name} -d ./db/neo4j/development/plugins") | ||
else | ||
file_name = "neo4j-spatial-#{spatial_version}-neo4j-#{neo4j_version}-server-plugin.jar" | ||
system_or_fail("wget -O #{file_name} #{url}/#{spatial_version}-neo4j-#{neo4j_version}/#{file_name}?raw=true") | ||
system_or_fail("mv #{file_name} ./db/neo4j/development/plugins") | ||
end | ||
end | ||
end | ||
|
||
task default: ['spec'] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,38 +5,75 @@ def self.included(other) | |
other.extend(ClassMethods) | ||
end | ||
|
||
def add_to_spatial_index(index_name = nil) | ||
index = index_name || self.class.spatial_index_name | ||
fail 'index name not found' unless index | ||
Neo4j::Session.current.add_node_to_spatial_index(index, self) | ||
def add_to_spatial_layer(layer_name = nil) | ||
layer = layer_name || self.class.spatial_layer_name | ||
fail 'layer name not found' unless layer | ||
Neo4j::ActiveBase.current_session.add_node_to_layer(layer, self) | ||
end | ||
|
||
module ClassMethods | ||
attr_reader :spatial_index_name | ||
def spatial_index(index_name = nil) | ||
return spatial_index_name unless index_name | ||
# create_index_callback(index_name) | ||
@spatial_index_name = index_name | ||
attr_reader :spatial_layer_name | ||
attr_reader :spatial_layer_type | ||
attr_reader :spatial_layer_config | ||
|
||
def spatial_layer(layer_name = nil, options = {}) | ||
return spatial_layer_name unless layer_name | ||
|
||
@spatial_layer_name = layer_name | ||
@spatial_layer_type = options.fetch(:type, 'SimplePoint') | ||
@spatial_layer_config = options.fetch(:config, 'lon:lat') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about having a attr_reader :spatial_layer
SpatialLayer = Struct.new(:name, :type, :config)
def spatial_layer(layer_name = nil, options = {})
return spatial_layer_name unless layer_name
@spatial_layer = SpatialLayer.new(layer_name, options.fetch(:type, 'SimplePoint'), options.fetch(:config, 'lon:lat'))
end |
||
|
||
spatial_layer_name | ||
end | ||
|
||
# This will not work for now. Neo4j Spatial's REST API doesn't seem to work within transactions. | ||
# def create_index_callback(index_name) | ||
# after_create(proc { |node| Neo4j::Session.current.add_node_to_spatial_index(index_name, node) }) | ||
# end | ||
def create_layer | ||
fail 'layer name not found' unless spatial_layer_name | ||
|
||
# private :create_index_callback | ||
lon_name, lat_name = spatial_layer_config.split(':') | ||
|
||
Neo4j::ActiveBase.current_session.add_layer(spatial_layer_name, spatial_layer_type, lat_name, lon_name) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might just be part of the original API, but it feels strange to extend the session objects with |
||
end | ||
|
||
def remove_layer | ||
fail 'layer name not found' unless spatial_layer_name | ||
|
||
Neo4j::ActiveBase.current_session.remove_layer(spatial_layer_name) | ||
end | ||
end | ||
end | ||
|
||
module Query | ||
class QueryProxy | ||
def spatial_match(var, params_string, spatial_index = nil) | ||
index = model.spatial_index_name || spatial_index | ||
fail 'Cannot query without index. Set index in model or as third argument.' unless index | ||
Neo4j::Session.current.query | ||
.start("#{var} = node:#{index}({spatial_params})") | ||
.proxy_as(model, var) | ||
.params(spatial_params: params_string) | ||
def within_distance(coordinate, distance, layer_name = nil) | ||
layer = model.spatial_layer_name || layer_name | ||
|
||
Neo4j::ActiveBase.current_session | ||
.within_distance(layer, coordinate, distance, execute: false) | ||
.proxy_as(model, :node) | ||
end | ||
|
||
def bbox(min, max, layer_name = nil) | ||
layer = model.spatial_layer_name || layer_name | ||
|
||
Neo4j::ActiveBase.current_session | ||
.bbox(layer, min, max, execute: false) | ||
.proxy_as(model, :node) | ||
end | ||
|
||
def closest(coordinate, distance = 100, layer_name = nil) | ||
layer = model.spatial_layer_name || layer_name | ||
|
||
Neo4j::ActiveBase.current_session | ||
.closest(layer, coordinate, distance, execute: false) | ||
.proxy_as(model, :node) | ||
end | ||
|
||
def intersects(geometry, layer_name = nil) | ||
layer = model.spatial_layer_name || layer_name | ||
|
||
Neo4j::ActiveBase.current_session | ||
.intersects(layer, geometry, execute: false) | ||
.proxy_as(model, :node) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, I'm not familiar with this gem, but using |
||
end | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always really, really try to avoid allowing the code to get more complex on a global level. Rarely I'll make a
rubocop:disable
comment around the method itself if I absolutely need to, but most of the time I can find a way to refactor and most of the time my code is better for it (not always ;) )There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I'd suggest running
rubocop -aD
. That will fix any issues that it can, and then you can resolve the rest. TheD
will output the cop's name so that you can look it up in case you don't know what it's talking about ;)