Skip to content
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

Neo4j 8.x and Core 7.x support #14

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ script:
language: ruby
jdk: oraclejdk8
rvm:
- 2.0.0
- 2.1.9
- 2.2.4
- 2.3.1
- jruby-9.0.5.0
Expand Down
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ source 'https://rubygems.org'
gemspec

gem 'activesupport', '~> 4.2' if RUBY_VERSION.to_f < 2.2

gem 'neo4j', '~> 8.0.0.alpha.2'
4 changes: 2 additions & 2 deletions lib/neo4j/active_node/spatial.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def self.included(other)
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)
ActiveBase.current_session.add_node_to_spatial_index(index, self)
end

module ClassMethods
Expand All @@ -33,7 +33,7 @@ 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
Neo4j::ActiveBase.new_query
.start("#{var} = node:#{index}({spatial_params})")
.proxy_as(model, var)
.params(spatial_params: params_string)
Expand Down
28 changes: 28 additions & 0 deletions lib/neo4j/cypher_session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Neo4j
module Core
module Spatial
module CypherSession
%w(
spatial?
spatial_plugin
add_point_layer
add_editable_layer
get_layer
add_geometry_to_layer
edit_geometry_from_layer
add_node_to_layer
find_geometries_in_bbox
find_geometries_within_distance
create_spatial_index
add_node_to_spatial_index
).each do |method, &_block|
define_method(method) do |*args, &block|
@adaptor.send(method, *args, &block)
end
end
end
end
end
end

Neo4j::Core::CypherSession.__send__(:include, Neo4j::Core::Spatial::CypherSession)
138 changes: 138 additions & 0 deletions lib/neo4j/http_adaptor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
require 'neo4j/core/cypher_session/adaptors/http'

module Neo4j
module Core
module Spatial
module HTTPAdaptor
def spatial?
connection.get('/db/data/ext/SpatialPlugin').status == 200
end

def spatial_plugin
connection.get('/db/data/ext/SpatialPlugin').body
end

def add_point_layer(layer, lat = nil, lon = nil)
options = {
layer: layer,
lat: lat || 'lat',
lon: lon || 'lon'
}

spatial_post('/ext/SpatialPlugin/graphdb/addSimplePointLayer', options)
end

def add_editable_layer(layer, format = 'WKT', node_property_name = 'wkt')
options = {
layer: layer,
format: format,
nodePropertyName: node_property_name
}

spatial_post('/ext/SpatialPlugin/graphdb/addEditableLayer', options)
end

def get_layer(layer)
options = {
layer: layer
}
spatial_post('/ext/SpatialPlugin/graphdb/getLayer', options)
end

def add_geometry_to_layer(layer, geometry)
options = {
layer: layer,
geometry: geometry
}
spatial_post('/ext/SpatialPlugin/graphdb/addGeometryWKTToLayer', options)
end

def edit_geometry_from_layer(layer, geometry, node)
options = {
layer: layer,
geometry: geometry,
geometryNodeId: get_id(node)
}
spatial_post('/ext/SpatialPlugin/graphdb/updateGeometryFromWKT', options)
end

def add_node_to_layer(layer, node)
options = {
layer: layer,
node: "/db/data/node/#{node.neo_id}"
}
spatial_post('/ext/SpatialPlugin/graphdb/addNodeToLayer', options)
end

def find_geometries_in_bbox(layer, minx, maxx, miny, maxy)
options = {
layer: layer,
minx: minx,
maxx: maxx,
miny: miny,
maxy: maxy
}
spatial_post('/ext/SpatialPlugin/graphdb/findGeometriesInBBox', options)
end

def find_geometries_within_distance(layer, pointx, pointy, distance)
options = {
layer: layer,
pointX: pointx,
pointY: pointy,
distanceInKm: distance
}
spatial_post('/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance', options)
end

def create_spatial_index(name, type = nil, lat = nil, lon = nil)
options = {
name: name,
config: {
provider: 'spatial',
geometry_type: type || 'point',
lat: lat || 'lat',
lon: lon || 'lon'
}
}
spatial_post('/index/node', options)
end

def add_node_to_spatial_index(index, node)
options = {
uri: "/#{get_id(node)}",
key: 'k',
value: 'v'
}
spatial_post("/index/node/#{index}", options)
end

private

def spatial_post(path, options)
connection.post("/db/data/#{path}", options).body
end

def connection
@requestor.instance_variable_get(:@faraday)
end

def get_id(id)
return id.neo_id if id.respond_to?(:neo_id)
case id
when Array
get_id(id.first)
when Hash
id[:self].split('/').last
when String
id.split('/').last
else
id
end
end
end
end
end
end

Neo4j::Core::CypherSession::Adaptors::HTTP.include Neo4j::Core::Spatial::HTTPAdaptor
5 changes: 5 additions & 0 deletions lib/neo4jrb_spatial.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
require 'neo4jrb_spatial/version'
require 'neo4jrb_spatial/errors'
# New Cypher API
require 'neo4j/http_adaptor'
require 'neo4j/cypher_session'
# Old cypher API
require 'neo4j/spatial'
# Neo4jrb OGM
require 'neo4j/active_node/spatial'
4 changes: 2 additions & 2 deletions neo4jrb_spatial.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rspec'
spec.add_development_dependency 'pry'

spec.add_dependency 'neo4j', '>= 5.0.1', '< 8'
spec.add_dependency 'neo4j-core', '>= 5.0.1', '< 7'
spec.add_dependency 'neo4j', '>= 5.0.1'
spec.add_dependency 'neo4j-core', '>= 5.0.1'
spec.add_dependency 'neo4j-rake_tasks', '~> 0.3'
end
31 changes: 31 additions & 0 deletions spec/active_node_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
describe 'ActiveNode integration', type: :active_model do
let(:node) { Restaurant.create(name: "Chris's Restaurant", lat: 60.1, lon: 15.2) }
let(:outside_node) { Restaurant.create(name: 'Lily Thai', lat: 59.0, lon: 14.9) }
before do
Neo4j::ActiveBase.current_session.create_spatial_index('restaurants')
stub_active_node_class('Restaurant') do
include Neo4j::ActiveNode::Spatial
spatial_index 'restaurants'
property :name
property :lat
property :lon
end

Restaurant.delete_all
[node, outside_node].each(&:add_to_spatial_index)
end

let(:match) { Restaurant.all.spatial_match(:r, 'withinDistance:[60.0,15.0,100.0]') }

it 'is a QueryProxy' do
expect(match).to respond_to(:to_cypher)
end

it 'matches to the node in the spatial index' do
expect(match.first).to eq node
end

it 'only returns expected nodes' do
expect(match.to_a).not_to include(outside_node)
end
end
Loading