neo4j 3.0.3 → 3.0.4
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/lib/neo4j/active_node/id_property.rb +4 -8
- data/lib/neo4j/active_node/node_wrapper.rb +2 -0
- data/lib/neo4j/active_node/query/query_proxy.rb +50 -2
- data/lib/neo4j/active_node/query/query_proxy_methods.rb +27 -2
- data/lib/neo4j/active_node/query_methods.rb +0 -5
- data/lib/neo4j/active_node/reflection.rb +1 -1
- data/lib/neo4j/active_rel/persistence.rb +11 -7
- data/lib/neo4j/config.rb +5 -2
- data/lib/neo4j/paginated.rb +1 -2
- data/lib/neo4j/shared.rb +1 -1
- data/lib/neo4j/version.rb +1 -1
- data/neo4j.gemspec +2 -2
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf2546cbe829d338babc703fcecdeff5650e8fd5
|
4
|
+
data.tar.gz: 094b2019bb62cb8e9f5e510eb54cf00f51c6131f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7552de25d876bd2b98038637c517ae77c47c04ae5d3fbd0a14852710998a3549d1ce981a9c35eea94e84cf1dcc04f469497ae7c7eb9be45a76b77f813900bd8
|
7
|
+
data.tar.gz: ba45f543a6cbce758ccfba472789cfb41ba78ce8ee6fe70db8e187371a1a638e83c86a6dae316a4ff786046a61b2ab3a984001993d4150b30e9eee57c4b89fcd
|
data/Gemfile
CHANGED
@@ -2,7 +2,7 @@ source 'http://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem 'neo4j-core', github: 'neo4jrb/neo4j-core'
|
5
|
+
#gem 'neo4j-core', github: 'neo4jrb/neo4j-core', branch: 'master'
|
6
6
|
#gem 'neo4j-core', git: 'https://github.com/neo4jrb/neo4j-core'
|
7
7
|
#gem 'orm_adapter', :path => '../orm_adapter'
|
8
8
|
|
@@ -27,25 +27,21 @@ module Neo4j::ActiveNode
|
|
27
27
|
|
28
28
|
module TypeMethods
|
29
29
|
def define_id_methods(clazz, name, conf)
|
30
|
-
|
30
|
+
raise "Expected a Hash, got #{conf.class} (#{conf.to_s}) for id_property" unless conf.is_a?(Hash)
|
31
31
|
if conf[:on]
|
32
32
|
define_custom_method(clazz, name, conf[:on])
|
33
33
|
elsif conf[:auto]
|
34
34
|
raise "only :uuid auto id_property allowed, got #{conf[:auto]}" unless conf[:auto] == :uuid
|
35
35
|
define_uuid_method(clazz, name)
|
36
|
-
|
36
|
+
elsif conf.empty?
|
37
37
|
define_property_method(clazz, name)
|
38
|
+
else
|
39
|
+
raise "Illegal value #{conf.inspect} for id_property, expected :on or :auto"
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
43
|
private
|
42
44
|
|
43
|
-
def validate_conf(conf)
|
44
|
-
return if conf.empty?
|
45
|
-
raise "Expected a Hash, got #{conf.class} (#{conf.to_s}) for id_property" unless conf.is_a?(Hash)
|
46
|
-
raise "Illegal value #{conf.inspect} for id_property, expected :on or :auto" unless conf.include?(:auto) || conf.include?(:on)
|
47
|
-
end
|
48
|
-
|
49
45
|
def define_property_method(clazz, name)
|
50
46
|
clear_methods(clazz, name)
|
51
47
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
class Neo4j::Node
|
2
|
+
# The wrapping process is what transforms a raw CypherNode or EmbeddedNode from Neo4j::Core into a healthy ActiveNode (or ActiveRel) object.
|
2
3
|
module Wrapper
|
3
4
|
|
4
5
|
# this is a plugin in the neo4j-core so that the Ruby wrapper will be wrapped around the Neo4j::Node objects
|
@@ -23,6 +24,7 @@ class Neo4j::Node
|
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
27
|
+
# Makes the determination of whether to use <tt>_classname</tt> (or whatever is defined by config) or the node's labels.
|
26
28
|
def sorted_wrapper_classes
|
27
29
|
if self.props.is_a?(Hash) && self.props.has_key?(Neo4j::Config.class_name_property)
|
28
30
|
self.props[Neo4j::Config.class_name_property].constantize
|
@@ -11,6 +11,27 @@ module Neo4j
|
|
11
11
|
# Will be nil when using QueryProxy chains on class methods.
|
12
12
|
attr_reader :caller
|
13
13
|
|
14
|
+
# QueryProxy is ActiveNode's Cypher DSL. While the name might imply that it creates queries in a general sense,
|
15
|
+
# it is actually referring to <tt>Neo4j::Core::Query</tt>, which is a pure Ruby Cypher DSL provided by the <tt>neo4j-core</tt> gem.
|
16
|
+
# QueryProxy provides ActiveRecord-like methods for common patterns. When it's not handling CRUD for relationships and queries, it
|
17
|
+
# provides ActiveNode's association chaining (`student.lessons.teachers.where(age: 30).hobbies`) and enjoys long walks on the
|
18
|
+
# beach.
|
19
|
+
#
|
20
|
+
# It should not ever be necessary to instantiate a new QueryProxy object directly, it always happens as a result of
|
21
|
+
# calling a method that makes use of it.
|
22
|
+
#
|
23
|
+
# @param [Constant] model The class which included ActiveNode (typically a model, hence the name) from which the query
|
24
|
+
# originated.
|
25
|
+
# @param [Neo4j::ActiveNode::HasN::Association] association The ActiveNode association (an object created by a <tt>has_one</tt> or
|
26
|
+
# <tt>has_many</tt>) that created this object.
|
27
|
+
# @param [Hash] options Additional options pertaining to the QueryProxy object. These may include:
|
28
|
+
# * node_var: A string or symbol to be used by Cypher within its query string as an identifier
|
29
|
+
# * rel_var: Same as above but pertaining to a relationship identifier
|
30
|
+
# * session: The session to be used for this query
|
31
|
+
# * caller: The node instance at the start of the QueryProxy chain
|
32
|
+
# * query_proxy: An existing QueryProxy chain upon which this new object should be built
|
33
|
+
#
|
34
|
+
# QueryProxy objects are evaluated lazily.
|
14
35
|
def initialize(model, association = nil, options = {})
|
15
36
|
@model = model
|
16
37
|
@association = association
|
@@ -24,10 +45,21 @@ module Neo4j
|
|
24
45
|
@params = options[:query_proxy] ? options[:query_proxy].instance_variable_get('@params') : {}
|
25
46
|
end
|
26
47
|
|
48
|
+
# The current node identifier on deck, so to speak. It is the object that will be returned by calling `each` and the last node link
|
49
|
+
# in the QueryProxy chain.
|
27
50
|
def identity
|
28
51
|
@node_var || :result
|
29
52
|
end
|
30
53
|
|
54
|
+
# The relationship identifier most recently used by the QueryProxy chain.
|
55
|
+
def rel_identity
|
56
|
+
@rel_var
|
57
|
+
end
|
58
|
+
|
59
|
+
# Executes the query against the database if the results are not already present in a node's association cache. This method is
|
60
|
+
# shared by <tt>each</tt>, <tt>each_rel</tt>, and <tt>each_with_rel</tt>.
|
61
|
+
# @param [String,Symbol] node The string or symbol of the node to return from the database.
|
62
|
+
# @param [String,Symbol] rel The string or symbol of a relationship to return from the database.
|
31
63
|
def enumerable_query(node, rel = nil)
|
32
64
|
pluck_this = rel.nil? ? [node] : [node, rel]
|
33
65
|
return self.pluck(*pluck_this) if @association.nil? || caller.nil?
|
@@ -40,6 +72,10 @@ module Neo4j
|
|
40
72
|
association_collection
|
41
73
|
end
|
42
74
|
|
75
|
+
# Just like every other <tt>each</tt> but it allows for optional params to support the versions that also return relationships.
|
76
|
+
# The <tt>node</tt> and <tt>rel</tt> params are typically used by those other methods but there's nothing stopping you from
|
77
|
+
# using `your_node.each(true, true)` instead of `your_node.each_with_rel`.
|
78
|
+
# @return [Enumerable] An enumerable containing some combination of nodes and rels.
|
43
79
|
def each(node = true, rel = nil, &block)
|
44
80
|
if node && rel
|
45
81
|
enumerable_query(identity, @rel_var).each { |obj, rel| yield obj, rel }
|
@@ -49,14 +85,23 @@ module Neo4j
|
|
49
85
|
end
|
50
86
|
end
|
51
87
|
|
88
|
+
# When called at the end of a QueryProxy chain, it will return the resultant relationship objects intead of nodes.
|
89
|
+
# For example, to return the relationship between a given student and their lessons:
|
90
|
+
# student.lessons.each_rel do |rel|
|
91
|
+
# @return [Enumerable] An enumerable containing any number of applicable relationship objects.
|
52
92
|
def each_rel(&block)
|
53
93
|
block_given? ? each(false, true, &block) : to_enum(:each, false, true)
|
54
94
|
end
|
55
95
|
|
96
|
+
# When called at the end of a QueryProxy chain, it will return the nodes and relationships of the last link.
|
97
|
+
# For example, to return a lesson and each relationship to a given student:
|
98
|
+
# student.lessons.each_with_rel do |lesson, rel|
|
56
99
|
def each_with_rel(&block)
|
57
100
|
block_given? ? each(true, true, &block) : to_enum(:each, true, true)
|
58
101
|
end
|
59
102
|
|
103
|
+
# Does exactly what you would hope. Without it, comparing `bobby.lessons == sandy.lessons` would evaluate to false because it
|
104
|
+
# would be comparing the QueryProxy objects, not the lessons themselves.
|
60
105
|
def ==(value)
|
61
106
|
self.to_a == value
|
62
107
|
end
|
@@ -89,7 +134,10 @@ module Neo4j
|
|
89
134
|
query_as(identity)
|
90
135
|
end
|
91
136
|
|
92
|
-
# Build a Neo4j::Core::Query object for the QueryProxy
|
137
|
+
# Build a Neo4j::Core::Query object for the QueryProxy. This is necessary when you want to take an existing QueryProxy chain
|
138
|
+
# and work with it from the more powerful (but less friendly) Neo4j::Core::Query.
|
139
|
+
# @param [String,Symbol] var The identifier to use for node at this link of the QueryProxy chain.
|
140
|
+
# student.lessons.query_as(:l).with('your cypher here...')
|
93
141
|
def query_as(var)
|
94
142
|
var = @node_var if @node_var
|
95
143
|
query = if @association
|
@@ -106,7 +154,7 @@ module Neo4j
|
|
106
154
|
end
|
107
155
|
end
|
108
156
|
|
109
|
-
# Cypher string for the QueryProxy's query
|
157
|
+
# Cypher string for the QueryProxy's query. This will not include params. For the full output, see <tt>to_cypher_with_params</tt>.
|
110
158
|
def to_cypher
|
111
159
|
query.to_cypher
|
112
160
|
end
|
@@ -49,11 +49,36 @@ module Neo4j
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
# Deletes a group of nodes and relationships within a QP chain. When identifier is omitted, it will remove the last link in the chain.
|
53
|
+
# The optional argument must be a node identifier. A relationship identifier will result in a Cypher Error
|
54
|
+
# @param [String,Symbol] the optional identifier of the link in the chain to delete.
|
55
|
+
def delete_all(identifier = nil)
|
56
|
+
query_with_target(identifier) do |target|
|
57
|
+
begin
|
58
|
+
self.query.with(target).match("(#{target})-[#{target}_rel]-()").delete("#{target}, #{target}_rel").exec
|
59
|
+
rescue Neo4j::Session::CypherError
|
60
|
+
self.query.delete(target).exec
|
61
|
+
end
|
62
|
+
self.caller.clear_association_cache if self.caller.respond_to?(:clear_association_cache)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Shorthand for `MATCH (start)-[r]-(other_node) WHERE ID(other_node) = #{other_node.neo_id}`
|
67
|
+
# @return [Neo4j::ActiveNode::Query::QueryProxy] A QueryProxy object upon which you can build.
|
68
|
+
def match_to(node)
|
69
|
+
self.where(neo_id: node.neo_id)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Gives you the first relationship between the last link of a QueryProxy chain and a given node
|
73
|
+
# Shorthand for `MATCH (start)-[r]-(other_node) WHERE ID(other_node) = #{other_node.neo_id} RETURN r`
|
74
|
+
def first_rel_to(node)
|
75
|
+
self.where(neo_id: node.neo_id).limit(1).pluck(rel_identity).first
|
76
|
+
end
|
77
|
+
|
52
78
|
private
|
53
79
|
|
54
80
|
def query_with_target(target, &block)
|
55
|
-
target
|
56
|
-
block.yield(target)
|
81
|
+
block.yield(target || identity)
|
57
82
|
end
|
58
83
|
|
59
84
|
def exists_query_start(origin, condition, target)
|
@@ -36,11 +36,6 @@ module Neo4j
|
|
36
36
|
|
37
37
|
alias_method :blank?, :empty?
|
38
38
|
|
39
|
-
def include?(other)
|
40
|
-
raise(InvalidParameterError, ':include? only accepts nodes') unless other.respond_to?(:neo_id)
|
41
|
-
self.query_as(:n).where(n: {primary_key => other.id}).return("count(n) AS count").first.count > 0
|
42
|
-
end
|
43
|
-
|
44
39
|
def find_in_batches(options = {})
|
45
40
|
self.query_as(:n).return(:n).find_in_batches(:n, primary_key, options) do |batch|
|
46
41
|
yield batch.map(&:n)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Neo4j::ActiveNode
|
2
|
-
# A reflection contains information about an association.
|
2
|
+
# A reflection contains information about an association.
|
3
3
|
# They are often used in connection with form builders to determine associated classes.
|
4
4
|
# This module contains methods related to the creation and retrieval of reflections.
|
5
5
|
module Reflection
|
@@ -4,8 +4,8 @@ module Neo4j::ActiveRel
|
|
4
4
|
include Neo4j::Shared::Persistence
|
5
5
|
|
6
6
|
class RelInvalidError < RuntimeError; end
|
7
|
-
|
8
7
|
class ModelClassInvalidError < RuntimeError; end
|
8
|
+
class RelCreateFailedError < RuntimeError; end
|
9
9
|
|
10
10
|
def clear_association_cache; end
|
11
11
|
|
@@ -86,12 +86,16 @@ module Neo4j::ActiveRel
|
|
86
86
|
def _rel_creation_query(from_node, to_node, props)
|
87
87
|
from_class = from_node.class
|
88
88
|
to_class = to_node.class
|
89
|
-
|
90
|
-
.
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
begin
|
90
|
+
Neo4j::Session.query.match(n1: from_class.mapped_label_name, n2: to_class.mapped_label_name)
|
91
|
+
.where("n1.#{from_class.primary_key} = {from_node_id}")
|
92
|
+
.where("n2.#{to_class.primary_key} = {to_node_id}")
|
93
|
+
.params(from_node_id: from_node.id, to_node_id: to_node.id)
|
94
|
+
.create("(n1)-[r:`#{type}`]->(n2)")
|
95
|
+
.with('r').set(r: props).return(:r).first.r
|
96
|
+
rescue NoMethodError
|
97
|
+
raise RelCreateFailedError, "Unable to create relationship. from_node: #{from_node}, to_node: #{to_node}"
|
98
|
+
end
|
95
99
|
end
|
96
100
|
|
97
101
|
end
|
data/lib/neo4j/config.rb
CHANGED
@@ -113,7 +113,10 @@ module Neo4j
|
|
113
113
|
Neo4j::Config[:class_name_property] || :_classname
|
114
114
|
end
|
115
115
|
|
116
|
+
def include_root_in_json
|
117
|
+
# we use ternary because a simple || will always evaluate true
|
118
|
+
Neo4j::Config[:include_root_in_json].nil? ? true : Neo4j::Config[:include_root_in_json]
|
119
|
+
end
|
116
120
|
end
|
117
121
|
end
|
118
|
-
|
119
|
-
end
|
122
|
+
end
|
data/lib/neo4j/paginated.rb
CHANGED
@@ -8,9 +8,8 @@ module Neo4j
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.create_from(source, page, per_page, order = nil)
|
11
|
-
#partial = source.drop((page-1) * per_page).first(per_page)
|
12
11
|
target = source.node_var
|
13
|
-
partial = source.skip(page-1).limit(per_page)
|
12
|
+
partial = source.skip((page - 1) * per_page).limit(per_page)
|
14
13
|
ordered_partial, ordered_source = if order
|
15
14
|
[partial.order_by(order), source.query.with("#{target} as #{target}").pluck("COUNT(#{target})").first]
|
16
15
|
else
|
data/lib/neo4j/shared.rb
CHANGED
data/lib/neo4j/version.rb
CHANGED
data/neo4j.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.summary = "A graph database for Ruby"
|
17
17
|
s.license = 'MIT'
|
18
18
|
s.description = <<-EOF
|
19
|
-
A Neo4j OGM (Object-Graph-Mapper) for use in Ruby on Rails and Rack frameworks
|
19
|
+
A Neo4j OGM (Object-Graph-Mapper) for use in Ruby on Rails and Rack frameworks heavily inspired by ActiveRecord.
|
20
20
|
EOF
|
21
21
|
|
22
22
|
s.require_path = 'lib'
|
@@ -31,7 +31,7 @@ A Neo4j OGM (Object-Graph-Mapper) for use in Ruby on Rails and Rack frameworks,
|
|
31
31
|
s.add_dependency("activesupport", "~> 4")
|
32
32
|
s.add_dependency("railties", "~> 4")
|
33
33
|
s.add_dependency('active_attr', "~> 0.8")
|
34
|
-
s.add_dependency("neo4j-core", "~> 3.0.
|
34
|
+
s.add_dependency("neo4j-core", "~> 3.0.8")
|
35
35
|
|
36
36
|
if RUBY_PLATFORM =~ /java/
|
37
37
|
s.add_dependency("neo4j-community", '~> 2.0')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neo4j
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Ronge
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: orm_adapter
|
@@ -86,16 +86,16 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 3.0.
|
89
|
+
version: 3.0.8
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 3.0.
|
96
|
+
version: 3.0.8
|
97
97
|
description: |
|
98
|
-
A Neo4j OGM (Object-Graph-Mapper) for use in Ruby on Rails and Rack frameworks
|
98
|
+
A Neo4j OGM (Object-Graph-Mapper) for use in Ruby on Rails and Rack frameworks heavily inspired by ActiveRecord.
|
99
99
|
email: andreas.ronge@gmail.com
|
100
100
|
executables:
|
101
101
|
- neo4j-jars
|