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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4d902cb2867667c62e30b5a4c0ca2aa5341b06cc
4
- data.tar.gz: 95ce7ebf16a229a510ab76aeb1e40b69275e1dc3
3
+ metadata.gz: bf2546cbe829d338babc703fcecdeff5650e8fd5
4
+ data.tar.gz: 094b2019bb62cb8e9f5e510eb54cf00f51c6131f
5
5
  SHA512:
6
- metadata.gz: 265e6724e37c3a89d7af59dcc2484915cd0d39b60e1cf642bd22ed1f0a6d997aa09163186148e78803f7cec552be2c07f0ce9eb503f572208c116313da6db764
7
- data.tar.gz: c84429373e502d634d4b29c6a0ab864af15e4def869260693bfba8789c4a610c2406f2dd611d6d84317ca2a55199c267d642342f1610966d5a210a351ae873eb
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' if ENV["TRAVIS"]
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
- validate_conf(conf)
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
- else conf.empty?
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 = target.nil? ? identity : 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
- Neo4j::Session.query.match(n1: from_class.mapped_label_name, n2: to_class.mapped_label_name)
90
- .where("n1.#{from_class.primary_key} = {from_node_id}")
91
- .where("n2.#{to_class.primary_key} = {to_node_id}")
92
- .params(from_node_id: from_node.id, to_node_id: to_node.id)
93
- .create("(n1)-[r:`#{type}`]->(n2)")
94
- .with('r').set(r: props).return(:r).first.r
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
@@ -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
@@ -22,7 +22,7 @@ module Neo4j
22
22
  end
23
23
 
24
24
  included do
25
- self.include_root_in_json = true
25
+ self.include_root_in_json = Neo4j::Config.include_root_in_json
26
26
 
27
27
  def self.i18n_scope
28
28
  :neo4j
data/lib/neo4j/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Neo4j
2
- VERSION = "3.0.3"
2
+ VERSION = "3.0.4"
3
3
  end
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, intended as a complete replacement for ActiveRecord.
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.5")
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.3
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-03 00:00:00.000000000 Z
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.5
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.5
96
+ version: 3.0.8
97
97
  description: |
98
- A Neo4j OGM (Object-Graph-Mapper) for use in Ruby on Rails and Rack frameworks, intended as a complete replacement for ActiveRecord.
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