neo4j-core 0.0.15-java → 2.0.0.alpha.1-java

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 (38) hide show
  1. data/Gemfile +2 -2
  2. data/README.rdoc +12 -192
  3. data/lib/neo4j-core.rb +3 -19
  4. data/lib/neo4j-core/database.rb +5 -4
  5. data/lib/neo4j-core/event_handler.rb +1 -1
  6. data/lib/neo4j-core/index/class_methods.rb +41 -27
  7. data/lib/neo4j-core/index/index.rb +4 -3
  8. data/lib/neo4j-core/index/index_config.rb +23 -30
  9. data/lib/neo4j-core/index/indexer.rb +53 -65
  10. data/lib/neo4j-core/index/indexer_registry.rb +2 -2
  11. data/lib/neo4j-core/index/lucene_query.rb +42 -53
  12. data/lib/neo4j-core/node/class_methods.rb +4 -4
  13. data/lib/neo4j-core/node/node.rb +8 -1
  14. data/lib/neo4j-core/property/property.rb +3 -1
  15. data/lib/neo4j-core/relationship/relationship.rb +10 -8
  16. data/lib/neo4j-core/rels/rels.rb +4 -9
  17. data/lib/neo4j-core/rels/traverser.rb +27 -13
  18. data/lib/neo4j-core/traversal/prune_evaluator.rb +2 -2
  19. data/lib/neo4j-core/traversal/traverser.rb +27 -122
  20. data/lib/neo4j-core/type_converters/type_converters.rb +287 -0
  21. data/lib/neo4j-core/version.rb +1 -1
  22. data/lib/neo4j-core/version.rb~ +3 -0
  23. data/lib/neo4j/config.rb +6 -3
  24. data/lib/neo4j/neo4j.rb +22 -51
  25. data/lib/neo4j/node.rb +0 -27
  26. data/lib/neo4j/relationship.rb +0 -25
  27. data/lib/test.rb +27 -0
  28. data/neo4j-core.gemspec +2 -2
  29. metadata +11 -17
  30. data/lib/neo4j-core/cypher/cypher.rb +0 -969
  31. data/lib/neo4j-core/cypher/result_wrapper.rb +0 -48
  32. data/lib/neo4j-core/hash_with_indifferent_access.rb +0 -165
  33. data/lib/neo4j-core/index/unique_factory.rb +0 -54
  34. data/lib/neo4j-core/property/java.rb +0 -59
  35. data/lib/neo4j-core/wrapper/class_methods.rb +0 -22
  36. data/lib/neo4j-core/wrapper/wrapper.rb +0 -20
  37. data/lib/neo4j/algo.rb +0 -300
  38. data/lib/neo4j/cypher.rb +0 -180
@@ -1,5 +1,5 @@
1
1
  module Neo4j
2
2
  module Core
3
- VERSION = "0.0.15"
3
+ VERSION = "2.0.0.alpha.1"
4
4
  end
5
5
  end
@@ -0,0 +1,3 @@
1
+ module Neo4jCore
2
+
3
+ end
data/lib/neo4j/config.rb CHANGED
@@ -37,7 +37,7 @@ module Neo4j
37
37
  # @return [Hash] the default file loaded by yaml
38
38
  def defaults
39
39
  require 'yaml'
40
- @defaults ||= Neo4j::Core::HashWithIndifferentAccess.new(YAML.load_file(default_file))
40
+ @defaults ||= YAML.load_file(default_file)
41
41
  end
42
42
 
43
43
  # @return [String] the expanded path of the Config[:storage_path] property
@@ -56,7 +56,7 @@ module Neo4j
56
56
  # @yield config
57
57
  # @yieldparam [Neo4j::Config] config - this configuration class
58
58
  def use
59
- @configuration ||= Neo4j::Core::HashWithIndifferentAccess.new
59
+ @configuration ||= {}
60
60
  yield @configuration
61
61
  nil
62
62
  end
@@ -123,13 +123,16 @@ module Neo4j
123
123
  map
124
124
  end
125
125
 
126
+ private
127
+
126
128
  # @return The a new configuration using default values as a hash.
127
129
  def setup()
128
- @configuration = Neo4j::Core::HashWithIndifferentAccess.new
130
+ @configuration = {}
129
131
  @configuration.merge!(defaults)
130
132
  @configuration
131
133
  end
132
134
 
135
+
133
136
  end
134
137
  end
135
138
 
data/lib/neo4j/neo4j.rb CHANGED
@@ -5,17 +5,10 @@
5
5
  # The Neo4j modules is used to interact with an Neo4j Database instance.
6
6
  # You can for example start and stop an instance and list all the nodes that exist in the database.
7
7
  #
8
- # @example
9
- # require 'neo4j'
10
- # Neo4j::Transaction.run { Neo4j.ref_node.outgoing(:friends) << Neo4j::Node.new(:name => 'andreas')}
11
- # Neo4j.ref_node.node(:outgoing, :friends)[:name] #=> 'andreas'
12
- # Neo4j.query(Neo4j.ref_node){|ref| ref > ':friends' > :x; :x}
13
- #
14
- # ==== Notice - Starting and Stopping Neo4j
8
+ # === Starting and Stopping Neo4j
15
9
  # You don't normally need to start the Neo4j database since it will be automatically started when needed.
16
10
  # Before the database is started you should configure where the database is stored, see {Neo4j::Config]}.
17
11
  #
18
- #
19
12
  module Neo4j
20
13
 
21
14
  # @return [String] The version of the Neo4j jar files
@@ -58,10 +51,9 @@ module Neo4j
58
51
  end
59
52
 
60
53
  # Checks read only mode of the database. Only one process can have write access to the database.
61
- # It will always return false if the database is not started yet.
62
54
  # @return [true, false] if the database has started up in read only mode
63
55
  def read_only?
64
- !!(@db && @db.graph && @db.read_only?)
56
+ (@db && @db.graph && @db.read_only?)
65
57
  end
66
58
 
67
59
  # Returns a started db instance. Starts it's not running.
@@ -72,10 +64,14 @@ module Neo4j
72
64
  db
73
65
  end
74
66
 
75
- # If the database is not running it returns Neo4j::Config.storage_path otherwise it asks the database
76
- # @return [String] the current storage path of the database
67
+ # Runs all user defined migrations.
68
+ def migrate!
69
+
70
+ end
71
+
72
+ # @return [String, nil] the current storage path of a running neo4j database. If the database is not running it returns nil.
77
73
  def storage_path
78
- return Neo4j::Config.storage_path unless db.running?
74
+ return nil unless db.running?
79
75
  db.storage_path
80
76
  end
81
77
 
@@ -89,42 +85,18 @@ module Neo4j
89
85
  # Check the neo4j
90
86
  # Returns an enumerable of hash values.
91
87
  #
92
- # @example Using the Cypher DSL
93
- # q = Neo4j.query{ match node(3) <=> node(:x); ret :x}
94
- # q.first[:n] #=> the @node
95
- # q.columns.first => :n
96
- #
97
- # @example Using the Cypher DSL and one parameter (n=Neo4j.ref_node)
98
- # q = Neo4j.query(Neo4j.ref_node){|n| n <=> node(:x); :x}
99
- # q.first[:n] #=> the @node
100
- # q.columns.first => :n
101
- #
102
- # @example Using an array of nodes
103
- # # same as - two_nodes=node(Neo4j.ref_node.neo_id, node_b.neo_id), b = node(b.neo_id)
104
- # q = Neo4j.query([Neo4j.ref_node, node_b], node_c){|two_nodes, b| two_nodes <=> b; b}
88
+ # @example
105
89
  #
106
- # @example With an string
107
- # q = Neo4j._query("START n=node(42) RETURN n")
108
- # q.first(:n) #=> the @node
109
- # q.columns.first => :n
90
+ # q = Neo4j.query("START n=node({node}) RETURN n", 'node' => @node.neo_id)
91
+ # q.first['n'] #=> the @node
92
+ # q.columns.first => 'n'
110
93
  #
111
- # @see Cypher
112
- # @see http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html The Cypher Query Language Documentation
94
+ # @see {http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html The Cypher Query Language Documentation}
113
95
  # @note Returns a read-once only forward iterable.
114
- # @param params parameter for the query_dsl block
115
- # @return [Neo4j::Core::Cypher::ResultWrapper] a forward read once only Enumerable, containing hash values.
116
- def query(*params, &query_dsl)
117
- q = Cypher.new(*params, &query_dsl).to_s
118
- _query(q)
119
- end
120
-
121
- # Performs a cypher query with given string
122
- # @param [String] q the cypher query as a String
123
- # @return (see #query)
124
- def _query(q)
125
- engine = Java::OrgNeo4jCypherJavacompat::ExecutionEngine.new(db)
126
- result = engine.execute(q)
127
- Neo4j::Core::Cypher::ResultWrapper.new(result)
96
+ # @return [Enumerable] a forward read once only Enumerable, containing hash values.
97
+ def query(query, params = {})
98
+ engine = org.neo4j.cypher.javacompat.ExecutionEngine.new(db)
99
+ engine.execute(query, params)
128
100
  end
129
101
 
130
102
 
@@ -193,7 +165,7 @@ module Neo4j
193
165
 
194
166
  # Usually, a client attaches relationships to this node that leads into various parts of the node space.
195
167
  # ®return the reference node, which is a "starting point" in the node space.
196
- # @note In case the ref_node has been assigned via the threadlocal_ref_node method,
168
+ # @note In case the ref_node has been assigned via the threadlocal_ref_node method,
197
169
  # then that node will be returned instead.
198
170
  # @see the design guide at http://wiki.neo4j.org/content/Design_Guide
199
171
  def ref_node(this_db = self.started_db)
@@ -227,16 +199,15 @@ module Neo4j
227
199
  # Neo4j.management(org.neo4j.management.HighAvailability).isMaster
228
200
  #
229
201
  # @param jmx_clazz the JMX class http://api.neo4j.org/current/org/neo4j/management/package-summary.html
230
- # @param this_db default currently running instance or a newly started neo4j db instance
202
+ # @param this_db default currently runnig instance or a newly started neo4j db instance
231
203
  # @see for the jmx_clazz p
232
- # @node this
233
- def management(jmx_clazz = Java::OrgNeo4jJmx::Primitives, this_db = self.started_db)
204
+ def management(jmx_clazz = org.neo4j.jmx.Primitives, this_db = self.started_db)
234
205
  this_db.management(jmx_clazz)
235
206
  end
236
207
 
237
208
  # @return [Enumerable] all nodes in the database
238
209
  def all_nodes(this_db = self.started_db)
239
- Enumerator.new(this_db, :each_node)
210
+ Enumerable::Enumerator.new(this_db, :each_node)
240
211
  end
241
212
 
242
213
  # @return [Enumerable] all nodes in the database but not wrapped in ruby classes.
data/lib/neo4j/node.rb CHANGED
@@ -9,39 +9,14 @@ module Neo4j
9
9
  # *org.neo4j.kernel.impl.core.NodeProxy* object. This java object includes the same mixin as this class. The #class method on the java object
10
10
  # returns Neo4j::Node in order to make it feel like an ordinary Ruby object.
11
11
  #
12
- # @example Create a node with one property (see {Neo4j::Core::Node::ClassMethods})
13
- # Neo4j::Node.new(:name => 'andreas')
14
- #
15
- # @example Create a relationship (see {Neo4j::Core::Traversal})
16
- # Neo4j::Node.new.outgoing(:friends) << Neo4j::Node.new
17
- #
18
- # @example Finding relationships (see {Neo4j::Core::Rels})
19
- # node.rels(:outgoing, :friends)
20
- #
21
- # @example Lucene index (see {Neo4j::Core::Index})
22
- # Neo4j::Node.trigger_on(:typex => 'MyTypeX')
23
- # Neo4j::Node.index(:name)
24
- # a = Neo4j::Node.new(:name => 'andreas', :typex => 'MyTypeX')
25
- # # finish_tx
26
- # Neo4j::Node.find(:name => 'andreas').first.should == a
27
- #
28
12
  class Node
29
13
  extend Neo4j::Core::Node::ClassMethods
30
- extend Neo4j::Core::Wrapper::ClassMethods
31
- extend Neo4j::Core::Index::ClassMethods
32
14
 
33
15
  include Neo4j::Core::Property
34
16
  include Neo4j::Core::Rels
35
17
  include Neo4j::Core::Traversal
36
18
  include Neo4j::Core::Equal
37
19
  include Neo4j::Core::Node
38
- include Neo4j::Core::Wrapper
39
- include Neo4j::Core::Property::Java # for documentation purpose only
40
- include Neo4j::Core::Index
41
-
42
- node_indexer do
43
- index_names :exact => 'default_node_index_exact', :fulltext => 'default_node_index_fulltext'
44
- end
45
20
 
46
21
  class << self
47
22
 
@@ -54,8 +29,6 @@ module Neo4j
54
29
  include Neo4j::Core::Traversal
55
30
  include Neo4j::Core::Equal
56
31
  include Neo4j::Core::Node
57
- include Neo4j::Core::Wrapper
58
- include Neo4j::Core::Index
59
32
  end
60
33
  end
61
34
  end
@@ -29,36 +29,13 @@ module Neo4j
29
29
  #
30
30
  # node.outgoing(:friends) << other_node << yet_another_node
31
31
  #
32
- # @example lucene index
33
- # Neo4j::Relationship.trigger_on(:typey => 123)
34
- # Neo4j::Relationship.index(:name)
35
- # a = Neo4j::Relationship.new(:friends, Neo4j::Node.new, Neo4j::Node.new, :typey => 123, :name => 'kalle')
36
- # # Finish tx
37
- # Neo4j::Relationship.find(:name => 'kalle').first.should be_nil
38
- #
39
32
  # @see http://api.neo4j.org/current/org/neo4j/graphdb/Relationship.html
40
33
  #
41
34
  class Relationship
42
35
  extend Neo4j::Core::Relationship::ClassMethods
43
- extend Neo4j::Core::Wrapper::ClassMethods
44
- extend Neo4j::Core::Index::ClassMethods
45
-
46
36
  include Neo4j::Core::Property
47
37
  include Neo4j::Core::Equal
48
38
  include Neo4j::Core::Relationship
49
- include Neo4j::Core::Wrapper
50
- include Neo4j::Core::Property::Java # for documentation purpose only
51
- include Neo4j::Core::Index
52
-
53
-
54
- # (see Neo4j::Core::Relationship::ClassMethods#new)
55
- def initialize(rel_type, start_node, end_node, props={})
56
- end
57
-
58
-
59
- rel_indexer do
60
- index_names :exact => 'default_rel_index_exact', :fulltext => 'default_rel_index_fulltext'
61
- end
62
39
 
63
40
  class << self
64
41
  def extend_java_class(java_clazz) #:nodoc:
@@ -66,8 +43,6 @@ module Neo4j
66
43
  include Neo4j::Core::Property
67
44
  include Neo4j::Core::Equal
68
45
  include Neo4j::Core::Relationship
69
- include Neo4j::Core::Wrapper
70
- include Neo4j::Core::Index
71
46
  end
72
47
  end
73
48
 
data/lib/test.rb ADDED
@@ -0,0 +1,27 @@
1
+ puts "TEST"
2
+
3
+ class LazyMap
4
+ include Enumerable
5
+
6
+ def initialize(stuff, &map_block)
7
+ @stuff = stuff
8
+ @map_block = map_block
9
+ end
10
+
11
+ def each
12
+ @stuff.each{|x| yield @map_block.call(x)}
13
+ end
14
+
15
+ end
16
+
17
+ class Foo
18
+ include Enumerable
19
+
20
+ def each
21
+ (1..5).to_a.each do |x|
22
+ yield x
23
+ end
24
+ end
25
+ end
26
+ e = LazyMap.new(Foo.new, &:to_s)
27
+ puts "Max #{e.find{|x| x == "2"}}"
data/neo4j-core.gemspec CHANGED
@@ -25,7 +25,7 @@ It comes included with the Apache Lucene document database.
25
25
  s.files = Dir.glob("{bin,lib,config}/**/*") + %w(README.rdoc Gemfile neo4j-core.gemspec)
26
26
  s.has_rdoc = true
27
27
  s.extra_rdoc_files = %w( README.rdoc )
28
- s.rdoc_options = ["--quiet", "--title", "Neo4j::Core", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
28
+ s.rdoc_options = ["--quiet", "--title", "Neo4j.rb", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
29
29
 
30
- s.add_dependency("neo4j-community", ">= 1.7.0")
30
+ s.add_dependency("neo4j-community", "1.6.1.alpha.1")
31
31
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neo4j-core
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.15
4
+ prerelease: 6
5
+ version: 2.0.0.alpha.1
6
6
  platform: java
7
7
  authors:
8
8
  - Andreas Ronge
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-04-27 00:00:00 Z
13
+ date: 2012-03-11 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: neo4j-community
@@ -18,9 +18,9 @@ dependencies:
18
18
  requirement: &id001 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
- - - ">="
21
+ - - "="
22
22
  - !ruby/object:Gem::Version
23
- version: 1.7.0
23
+ version: 1.6.1.alpha.1
24
24
  type: :runtime
25
25
  version_requirements: *id001
26
26
  description: |
@@ -37,10 +37,9 @@ extensions: []
37
37
  extra_rdoc_files:
38
38
  - README.rdoc
39
39
  files:
40
+ - lib/test.rb
40
41
  - lib/neo4j-core.rb
41
42
  - lib/neo4j/config.rb
42
- - lib/neo4j/algo.rb
43
- - lib/neo4j/cypher.rb
44
43
  - lib/neo4j/transaction.rb
45
44
  - lib/neo4j/neo4j.rb
46
45
  - lib/neo4j/neo4j.rb~
@@ -48,14 +47,13 @@ files:
48
47
  - lib/neo4j/relationship.rb
49
48
  - lib/neo4j-core/event_handler.rb
50
49
  - lib/neo4j-core/lazy_map.rb
51
- - lib/neo4j-core/hash_with_indifferent_access.rb
50
+ - lib/neo4j-core/version.rb~
52
51
  - lib/neo4j-core/database.rb
53
52
  - lib/neo4j-core/relationship_set.rb
54
53
  - lib/neo4j-core/version.rb
55
54
  - lib/neo4j-core/to_java.rb
56
55
  - lib/neo4j-core/node/node.rb
57
56
  - lib/neo4j-core/node/class_methods.rb
58
- - lib/neo4j-core/property/java.rb
59
57
  - lib/neo4j-core/property/property.rb
60
58
  - lib/neo4j-core/equal/equal.rb
61
59
  - lib/neo4j-core/traversal/rel_expander.rb
@@ -64,21 +62,17 @@ files:
64
62
  - lib/neo4j-core/traversal/traversal.rb
65
63
  - lib/neo4j-core/traversal/traverser.rb
66
64
  - lib/neo4j-core/traversal/evaluator.rb
65
+ - lib/neo4j-core/type_converters/type_converters.rb
67
66
  - lib/neo4j-core/rels/traverser.rb
68
67
  - lib/neo4j-core/rels/rels.rb
69
- - lib/neo4j-core/wrapper/wrapper.rb
70
- - lib/neo4j-core/wrapper/class_methods.rb
71
68
  - lib/neo4j-core/index/index_config.rb
72
69
  - lib/neo4j-core/index/indexer.rb
73
70
  - lib/neo4j-core/index/lucene_query.rb
74
71
  - lib/neo4j-core/index/indexer_registry.rb
75
- - lib/neo4j-core/index/unique_factory.rb
76
72
  - lib/neo4j-core/index/class_methods.rb
77
73
  - lib/neo4j-core/index/index.rb
78
74
  - lib/neo4j-core/relationship/class_methods.rb
79
75
  - lib/neo4j-core/relationship/relationship.rb
80
- - lib/neo4j-core/cypher/cypher.rb
81
- - lib/neo4j-core/cypher/result_wrapper.rb
82
76
  - config/neo4j/config.yml
83
77
  - README.rdoc
84
78
  - Gemfile
@@ -90,7 +84,7 @@ post_install_message:
90
84
  rdoc_options:
91
85
  - --quiet
92
86
  - --title
93
- - Neo4j::Core
87
+ - Neo4j.rb
94
88
  - --line-numbers
95
89
  - --main
96
90
  - README.rdoc
@@ -106,9 +100,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
100
  required_rubygems_version: !ruby/object:Gem::Requirement
107
101
  none: false
108
102
  requirements:
109
- - - ">="
103
+ - - ">"
110
104
  - !ruby/object:Gem::Version
111
- version: "0"
105
+ version: 1.3.1
112
106
  requirements: []
113
107
 
114
108
  rubyforge_project: neo4j-core
@@ -1,969 +0,0 @@
1
- module Neo4j
2
- module Core
3
-
4
- # This module contains a number of mixins and classes used by the neo4j.rb cypher DSL.
5
- # The Cypher DSL is evaluated in the context of {Neo4j::Cypher} which contains a number of methods (e.g. {Neo4j::Cypher#node})
6
- # which returns classes from this module.
7
- module Cypher
8
-
9
- module MathFunctions
10
- def abs(value=nil)
11
- _add_math_func(:abs, value)
12
- end
13
-
14
- def sqrt(value=nil)
15
- _add_math_func(:sqrt, value)
16
- end
17
-
18
- def round(value=nil)
19
- _add_math_func(:round, value)
20
- end
21
-
22
- def sign(value=nil)
23
- _add_math_func(:sign, value)
24
- end
25
-
26
- # @private
27
- def _add_math_func(name, value=nil)
28
- value ||= self.respond_to?(:var_name) ? self.var_name : to_s
29
- expressions.delete(self)
30
- Property.new(expressions, nil, name).to_function!(value)
31
- end
32
- end
33
-
34
- module MathOperator
35
- def -(other)
36
- ExprOp.new(self, other, '-')
37
- end
38
-
39
- def +(other)
40
- ExprOp.new(self, other, '+')
41
- end
42
- end
43
-
44
- module Comparable
45
- def <(other)
46
- ExprOp.new(self, other, '<')
47
- end
48
-
49
- def <=(other)
50
- ExprOp.new(self, other, '<=')
51
- end
52
-
53
- def =~(other)
54
- ExprOp.new(self, other, '=~')
55
- end
56
-
57
- def >(other)
58
- ExprOp.new(self, other, '>')
59
- end
60
-
61
- def >=(other)
62
- ExprOp.new(self, other, '>=')
63
- end
64
-
65
- ## Only in 1.9
66
- if RUBY_VERSION > "1.9.0"
67
- eval %{
68
- def !=(other)
69
- other.is_a?(String) ? ExprOp.new(self, other, "!=") : super
70
- end }
71
- end
72
-
73
- def ==(other)
74
- if other.is_a?(Fixnum) || other.is_a?(String) || other.is_a?(Regexp)
75
- ExprOp.new(self, other, "=")
76
- else
77
- super
78
- end
79
- end
80
- end
81
-
82
- module PredicateMethods
83
- def all?(&block)
84
- self.respond_to?(:iterable)
85
- Predicate.new(expressions, :op => 'all', :clause => :where, :input => input, :iterable => iterable, :predicate_block => block)
86
- end
87
-
88
- def extract(&block)
89
- Predicate.new(expressions, :op => 'extract', :clause => :return, :input => input, :iterable => iterable, :predicate_block => block)
90
- end
91
-
92
- def filter(&block)
93
- Predicate.new(expressions, :op => 'filter', :clause => :return, :input => input, :iterable => iterable, :predicate_block => block)
94
- end
95
-
96
- def any?(&block)
97
- Predicate.new(@expressions, :op => 'any', :clause => :where, :input => input, :iterable => iterable, :predicate_block => block)
98
- end
99
-
100
- def none?(&block)
101
- Predicate.new(@expressions, :op => 'none', :clause => :where, :input => input, :iterable => iterable, :predicate_block => block)
102
- end
103
-
104
- def single?(&block)
105
- Predicate.new(@expressions, :op => 'single', :clause => :where, :input => input, :iterable => iterable, :predicate_block => block)
106
- end
107
-
108
- end
109
-
110
- module Variable
111
- attr_accessor :return_method
112
-
113
- def distinct
114
- self.return_method = {:name => 'distinct', :bracket => false}
115
- self
116
- end
117
-
118
- def [](prop_name)
119
- Property.new(expressions, self, prop_name)
120
- end
121
-
122
- def as(v)
123
- @var_name = v
124
- self
125
- end
126
-
127
- # generates a <tt>ID</tt> cypher fragment.
128
- def neo_id
129
- Property.new(@expressions, self, 'ID').to_function!
130
- end
131
-
132
- # generates a <tt>has</tt> cypher fragment.
133
- def property?(p)
134
- p = Property.new(expressions, self, p)
135
- p.binary_operator("has")
136
- end
137
-
138
- # generates a <tt>is null</tt> cypher fragment.
139
- def exist?
140
- p = Property.new(expressions, self, p)
141
- p.binary_operator("", " is null")
142
- end
143
-
144
- # Can be used instead of [_classname] == klass
145
- def is_a?(klass)
146
- return super if klass.class != Class || !klass.respond_to?(:_load_wrapper)
147
- self[:_classname] == klass.to_s
148
- end
149
- end
150
-
151
- module Matchable
152
- # This operator means related to, without regard to type or direction.
153
- # @param [Symbol, #var_name] other either a node (Symbol, #var_name)
154
- # @return [MatchRelLeft, MatchNode]
155
- def <=>(other)
156
- MatchNode.new(self, other, expressions, :both)
157
- end
158
-
159
- # This operator means outgoing related to
160
- # @param [Symbol, #var_name, String] other the relationship
161
- # @return [MatchRelLeft, MatchNode]
162
- def >(other)
163
- MatchRelLeft.new(self, other, expressions, :outgoing)
164
- end
165
-
166
- # This operator means any direction related to
167
- # @param (see #>)
168
- # @return [MatchRelLeft, MatchNode]
169
- def -(other)
170
- MatchRelLeft.new(self, other, expressions, :both)
171
- end
172
-
173
- # This operator means incoming related to
174
- # @param (see #>)
175
- # @return [MatchRelLeft, MatchNode]
176
- def <(other)
177
- MatchRelLeft.new(self, other, expressions, :incoming)
178
- end
179
-
180
- # Outgoing relationship to other node
181
- # @param [Symbol, #var_name] other either a node (Symbol, #var_name)
182
- # @return [MatchRelLeft, MatchNode]
183
- def >>(other)
184
- MatchNode.new(self, other, expressions, :outgoing)
185
- end
186
-
187
- def outgoing(rel_type)
188
- node = NodeVar.new(@expressions, @variables)
189
- MatchRelLeft.new(self, ":`#{rel_type}`", expressions, :outgoing) > node
190
- node
191
- end
192
-
193
- def incoming(rel_type)
194
- node = NodeVar.new(@expressions, @variables)
195
- MatchRelLeft.new(self, ":`#{rel_type}`", expressions, :incoming) < node
196
- node
197
- end
198
-
199
- def both(rel_type)
200
- node = NodeVar.new(@expressions, @variables)
201
- MatchRelLeft.new(self, ":`#{rel_type}`", expressions, :both) < node
202
- node
203
- end
204
-
205
- # Incoming relationship to other node
206
- # @param [Symbol, #var_name] other either a node (Symbol, #var_name)
207
- # @return [MatchRelLeft, MatchNode]
208
- def <<(other)
209
- MatchNode.new(self, other, expressions, :incoming)
210
- end
211
- end
212
-
213
- class Expression
214
- attr_reader :expressions
215
- attr_accessor :separator, :clause
216
-
217
- def initialize(expressions, clause)
218
- @clause = clause
219
- @expressions = expressions
220
- insert_last(clause)
221
- @separator = ","
222
- end
223
-
224
- def insert_last(clause)
225
- i = @expressions.reverse.index { |e| e.clause == clause }
226
- if i.nil?
227
- @expressions << self
228
- else
229
- pos = @expressions.size - i
230
- @expressions.insert(pos, self)
231
- end
232
- end
233
-
234
- def prefixes
235
- {:start => "START", :where => " WHERE", :match => " MATCH", :return => " RETURN", :order_by => " ORDER BY", :skip => " SKIP", :limit => " LIMIT"}
236
- end
237
-
238
- def prefix
239
- prefixes[clause]
240
- end
241
-
242
- def valid?
243
- true
244
- end
245
-
246
- end
247
-
248
- # A property is returned from a Variable by using the [] operator.
249
- #
250
- # It has a number of useful method like
251
- # <tt>count</tt>, <tt>sum</tt>, <tt>avg</tt>, <tt>min</tt>, <tt>max</tt>, <tt>collect</tt>, <tt>head</tt>, <tt>last</tt>, <tt>tail</tt>,
252
- #
253
- # @example
254
- # n=node(2, 3, 4); n[:name].collect
255
- # # same as START n0=node(2,3,4) RETURN collect(n0.property)
256
- class Property
257
- # @private
258
- attr_reader :expressions, :var_name
259
- include Comparable
260
- include MathOperator
261
- include MathFunctions
262
- include PredicateMethods
263
-
264
- def initialize(expressions, var, prop_name)
265
- @var = var.respond_to?(:var_name) ? var.var_name : var
266
- @expressions = expressions
267
- @prop_name = prop_name
268
- @var_name = @prop_name ? "#{@var.to_s}.#{@prop_name}" : @var.to_s
269
- end
270
-
271
- # @private
272
- def to_function!(var = @var.to_s)
273
- @var_name = "#{@prop_name}(#{var})"
274
- self
275
- end
276
-
277
- # Make it possible to rename a property with a different name (AS)
278
- def as(new_name)
279
- @var_name = "#{@var_name} AS #{new_name}"
280
- end
281
-
282
- # required by the Predicate Methods Module
283
- # @see PredicateMethods
284
- # @private
285
- def iterable
286
- var_name
287
- end
288
-
289
- def input
290
- self
291
- end
292
-
293
- # @private
294
- def in?(values)
295
- binary_operator("", " IN [#{values.map { |x| %Q["#{x}"] }.join(',')}]")
296
- end
297
-
298
- # Only return distinct values/nodes/rels/paths
299
- def distinct
300
- @var_name = "distinct #{@var_name}"
301
- self
302
- end
303
-
304
- def length
305
- @prop_name = "length"
306
- to_function!
307
- self
308
- end
309
-
310
- %w[count sum avg min max collect head last tail].each do |meth_name|
311
- define_method(meth_name) do
312
- function(meth_name.to_s)
313
- end
314
- end
315
-
316
- # @private
317
- def function(func_name_pre, func_name_post = "")
318
- ExprOp.new(self, nil, func_name_pre, func_name_post)
319
- end
320
-
321
- # @private
322
- def binary_operator(op, post_fix = "")
323
- ExprOp.new(self, nil, op, post_fix).binary!
324
- end
325
- end
326
-
327
- class Start < Expression
328
- # @private
329
- attr_reader :var_name
330
- include Variable
331
- include Matchable
332
-
333
- def initialize(var_name, expressions)
334
- @var_name = "#{var_name}#{expressions.size}"
335
- super(expressions, :start)
336
- end
337
-
338
- end
339
-
340
- # Can be created from a <tt>node</tt> dsl method.
341
- class StartNode < Start
342
- # @private
343
- attr_reader :nodes
344
-
345
- def initialize(nodes, expressions)
346
- super("n", expressions)
347
-
348
- @nodes = nodes.map { |n| n.respond_to?(:neo_id) ? n.neo_id : n }
349
- end
350
-
351
- def to_s
352
- "#{var_name}=node(#{nodes.join(',')})"
353
- end
354
- end
355
-
356
-
357
- # Can be created from a <tt>rel</tt> dsl method.
358
- class StartRel < Start
359
- # @private
360
- attr_reader :rels
361
-
362
- def initialize(rels, expressions)
363
- super("r", expressions)
364
- @rels = rels.map { |n| n.respond_to?(:neo_id) ? n.neo_id : n }
365
- end
366
-
367
- def to_s
368
- "#{var_name}=relationship(#{rels.join(',')})"
369
- end
370
- end
371
-
372
- class NodeQuery < Start
373
- attr_reader :index_name, :query
374
-
375
- def initialize(index_class, query, index_type, expressions)
376
- super("n", expressions)
377
- @index_name = index_class.index_name_for_type(index_type)
378
- @query = query
379
- end
380
-
381
- def to_s
382
- "#{var_name}=node:#{index_name}(#{query})"
383
- end
384
- end
385
-
386
- class NodeLookup < Start
387
- attr_reader :index_name, :query
388
-
389
- def initialize(index_class, key, value, expressions)
390
- super("n", expressions)
391
- index_type = index_class.index_type(key.to_s)
392
- raise "No index on #{index_class} property #{key}" unless index_type
393
- @index_name = index_class.index_name_for_type(index_type)
394
- @query = %Q[#{key}="#{value}"]
395
- end
396
-
397
- def to_s
398
- %Q[#{var_name}=node:#{index_name}(#{query})]
399
- end
400
-
401
- end
402
-
403
- # The return statement in the cypher query
404
- class Return < Expression
405
- attr_reader :var_name
406
-
407
- def initialize(name_or_ref, expressions, opts = {})
408
- super(expressions, :return)
409
- @name_or_ref = name_or_ref
410
- @name_or_ref.referenced! if @name_or_ref.respond_to?(:referenced!)
411
- @var_name = @name_or_ref.respond_to?(:var_name) ? @name_or_ref.var_name : @name_or_ref.to_s
412
- opts.each_pair { |k, v| self.send(k, v) }
413
- end
414
-
415
- # @private
416
- def return_method
417
- @name_or_ref.respond_to?(:return_method) && @name_or_ref.return_method
418
- end
419
-
420
- # @private
421
- def as_return_method
422
- if return_method[:bracket]
423
- "#{return_method[:name]}(#@var_name)"
424
- else
425
- "#{return_method[:name]} #@var_name"
426
- end
427
- end
428
-
429
- # Specifies an <tt>ORDER BY</tt> cypher query
430
- # @param [Property] props the properties which should be sorted
431
- # @return self
432
- def asc(*props)
433
- @order_by ||= OrderBy.new(expressions)
434
- @order_by.asc(props)
435
- self
436
- end
437
-
438
- # Specifies an <tt>ORDER BY</tt> cypher query
439
- # @param [Property] props the properties which should be sorted
440
- # @return self
441
- def desc(*props)
442
- @order_by ||= OrderBy.new(expressions)
443
- @order_by.desc(props)
444
- self
445
- end
446
-
447
- # Creates a <tt>SKIP</tt> cypher clause
448
- # @param [Fixnum] val the number of entries to skip
449
- # @return self
450
- def skip(val)
451
- Skip.new(expressions, val)
452
- self
453
- end
454
-
455
- # Creates a <tt>LIMIT</tt> cypher clause
456
- # @param [Fixnum] val the number of entries to limit
457
- # @return self
458
- def limit(val)
459
- Limit.new(expressions, val)
460
- self
461
- end
462
-
463
- def to_s
464
- return_method ? as_return_method : var_name.to_s
465
- end
466
- end
467
-
468
- # Can be used to skip result from a return clause
469
- class Skip < Expression
470
- def initialize(expressions, value)
471
- super(expressions, :skip)
472
- @value = value
473
- end
474
-
475
- def to_s
476
- @value
477
- end
478
- end
479
-
480
- # Can be used to limit result from a return clause
481
- class Limit < Expression
482
- def initialize(expressions, value)
483
- super(expressions, :limit)
484
- @value = value
485
- end
486
-
487
- def to_s
488
- @value
489
- end
490
- end
491
-
492
- class OrderBy < Expression
493
- def initialize(expressions)
494
- super(expressions, :order_by)
495
- @orders = []
496
- end
497
-
498
- def asc(props)
499
- @orders << [:asc, props]
500
- end
501
-
502
- def desc(props)
503
- @orders << [:desc, props]
504
- end
505
-
506
- def to_s
507
- @orders.map do |pair|
508
- if pair[0] == :asc
509
- pair[1].map(&:var_name).join(', ')
510
- else
511
- pair[1].map(&:var_name).join(', ') + " DESC"
512
- end
513
- end.join(', ')
514
- end
515
- end
516
-
517
- # Created from a node's match operator like >> or <.
518
- class Match < Expression
519
- # @private
520
- attr_reader :dir, :expressions, :left, :right, :var_name, :dir_op
521
- # @private
522
- attr_accessor :algorithm, :next, :prev
523
- include Variable
524
-
525
- def initialize(left, right, expressions, dir, dir_op)
526
- super(expressions, :match)
527
- @var_name = "m#{expressions.size}"
528
- @dir = dir
529
- @dir_op = dir_op
530
- @prev = left if left.is_a?(Match)
531
- @left = left
532
- @right = right
533
- end
534
-
535
-
536
- # Generates a <tt>x in nodes(m3)</tt> cypher expression.
537
- #
538
- # @example
539
- # p.nodes.all? { |x| x[:age] > 30 }
540
- def nodes
541
- Entities.new(@expressions, "nodes", self)
542
- end
543
-
544
- # Generates a <tt>x in relationships(m3)</tt> cypher expression.
545
- #
546
- # @example
547
- # p.relationships.all? { |x| x[:age] > 30 }
548
- def rels
549
- Entities.new(@expressions, "relationships", self)
550
- end
551
-
552
- # returns the length of the path
553
- def length
554
- self.return_method = {:name => 'length', :bracket => true}
555
- self
556
- end
557
-
558
- # @private
559
- def find_match_start
560
- c = self
561
- while (c.prev) do
562
- c = c.prev
563
- end
564
- c
565
- end
566
-
567
- # @private
568
- def left_var_name
569
- @left.respond_to?(:var_name) ? @left.var_name : @left.to_s
570
- end
571
-
572
- # @private
573
- def right_var_name
574
- @right.respond_to?(:var_name) ? @right.var_name : @right.to_s
575
- end
576
-
577
- # @private
578
- def right_expr
579
- @right.respond_to?(:expr) ? @right.expr : right_var_name
580
- end
581
-
582
- # @private
583
- def referenced!
584
- @referenced = true
585
- end
586
-
587
- # @private
588
- def referenced?
589
- !!@referenced
590
- end
591
-
592
- # @private
593
- def to_s
594
- curr = find_match_start
595
- result = (referenced? || curr.referenced?) ? "#{var_name} = " : ""
596
- result << (algorithm ? "#{algorithm}(" : "")
597
- begin
598
- result << curr.expr
599
- end while (curr = curr.next)
600
- result << ")" if algorithm
601
- result
602
- end
603
- end
604
-
605
- # The left part of a match clause, e.g. node < rel(':friends')
606
- # Can return {MatchRelRight} using a match operator method.
607
- class MatchRelLeft < Match
608
- def initialize(left, right, expressions, dir)
609
- super(left, right, expressions, dir, dir == :incoming ? '<-' : '-')
610
- end
611
-
612
- # @param [Symbol,NodeVar,String] other part of the match cypher statement.
613
- # @return [MatchRelRight] the right part of an relationship cypher query.
614
- def >(other)
615
- expressions.delete(self)
616
- self.next = MatchRelRight.new(self, other, expressions, :outgoing)
617
- end
618
-
619
- # @see #>
620
- # @return (see #>)
621
- def <(other)
622
- expressions.delete(self)
623
- self.next = MatchRelRight.new(self, other, expressions, :incoming)
624
- end
625
-
626
- # @see #>
627
- # @return (see #>)
628
- def -(other)
629
- expressions.delete(self)
630
- self.next = MatchRelRight.new(self, other, expressions, :both)
631
- end
632
-
633
- # @return [String] a cypher string for this match.
634
- def expr
635
- if prev
636
- # we have chained more then one relationships in a match expression
637
- "#{dir_op}[#{right_expr}]"
638
- else
639
- # the right is an relationship and could be an expressions, e.g "r?"
640
- "(#{left_var_name})#{dir_op}[#{right_expr}]"
641
- end
642
- end
643
- end
644
-
645
- class MatchRelRight < Match
646
- # @param left the left part of the query
647
- # @param [Symbol,NodeVar,String] right part of the match cypher statement.
648
- def initialize(left, right, expressions, dir)
649
- super(left, right, expressions, dir, dir == :outgoing ? '->' : '-')
650
- end
651
-
652
- # @param [Symbol,NodeVar,String] other part of the match cypher statement.
653
- # @return [MatchRelLeft] the right part of an relationship cypher query.
654
- def >(other)
655
- expressions.delete(self)
656
- self.next = MatchRelLeft.new(self, other, expressions, :outgoing)
657
- end
658
-
659
- # @see #>
660
- # @return (see #>)
661
- def <(other)
662
- expressions.delete(self)
663
- self.next = MatchRelLeft.new(self, other, expressions, :incoming)
664
- end
665
-
666
- # @see #>
667
- # @return (see #>)
668
- def -(other)
669
- expressions.delete(self)
670
- self.next = MatchRelLeft.new(self, other, expressions, :both)
671
- end
672
-
673
- # @return [String] a cypher string for this match.
674
- def expr
675
- "#{dir_op}(#{right_var_name})"
676
- end
677
-
678
- # negate this match
679
- def not
680
- expressions.delete(self)
681
- ExprOp.new(left, nil, "not").binary!
682
- end
683
-
684
- if RUBY_VERSION > "1.9.0"
685
- eval %{
686
- def !
687
- expressions.delete(self)
688
- ExprOp.new(left, nil, "not").binary!
689
- end
690
- }
691
- end
692
-
693
- end
694
-
695
- # The right part of a match clause (node_b), e.g. node_a > rel(':friends') > node_b
696
- #
697
- class MatchNode < Match
698
- attr_reader :dir_op
699
-
700
- def initialize(left, right, expressions, dir)
701
- dir_op = case dir
702
- when :outgoing then
703
- "-->"
704
- when :incoming then
705
- "<--"
706
- when :both then
707
- "--"
708
- end
709
- super(left, right, expressions, dir, dir_op)
710
- end
711
-
712
- # @return [String] a cypher string for this match.
713
- def expr
714
- if prev
715
- # we have chained more then one relationships in a match expression
716
- "#{dir_op}(#{right_expr})"
717
- else
718
- # the right is an relationship and could be an expressions, e.g "r?"
719
- "(#{left_var_name})#{dir_op}(#{right_expr})"
720
- end
721
- end
722
-
723
- def <<(other)
724
- expressions.delete(self)
725
- self.next = MatchNode.new(self, other, expressions, :incoming)
726
- end
727
-
728
- def >>(other)
729
- expressions.delete(self)
730
- self.next = MatchNode.new(self, other, expressions, :outgoing)
731
- end
732
-
733
- # @param [Symbol,NodeVar,String] other part of the match cypher statement.
734
- # @return [MatchRelRight] the right part of an relationship cypher query.
735
- def >(other)
736
- expressions.delete(self)
737
- self.next = MatchRelLeft.new(self, other, expressions, :outgoing)
738
- end
739
-
740
- # @see #>
741
- # @return (see #>)
742
- def <(other)
743
- expressions.delete(self)
744
- self.next = MatchRelLeft.new(self, other, expressions, :incoming)
745
- end
746
-
747
- # @see #>
748
- # @return (see #>)
749
- def -(other)
750
- expressions.delete(self)
751
- self.next = MatchRelLeft.new(self, other, expressions, :both)
752
- end
753
-
754
- end
755
-
756
- # Represents an unbound node variable used in match statements
757
- class NodeVar
758
- include Variable
759
- include Matchable
760
-
761
- # @return the name of the variable
762
- attr_reader :var_name
763
- attr_reader :expressions
764
-
765
- def initialize(expressions, variables)
766
- variables ||= []
767
- @var_name = "v#{variables.size}"
768
- variables << self
769
- @variables = variables
770
- @expressions = expressions
771
- end
772
-
773
- # @return [String] a cypher string for this node variable
774
- def to_s
775
- var_name
776
- end
777
-
778
- end
779
-
780
- # represent an unbound relationship variable used in match,where,return statement
781
- class RelVar
782
- include Variable
783
-
784
- attr_reader :var_name, :expr, :expressions
785
-
786
- def initialize(expressions, variables, expr)
787
- variables << self
788
- @expr = expr
789
- @expressions = expressions
790
- guess = expr ? /([[:alpha:]]*)/.match(expr)[1] : ""
791
- @var_name = guess.empty? ? "v#{variables.size}" : guess
792
- end
793
-
794
- def rel_type
795
- Property.new(@expressions, self, 'type').to_function!
796
- end
797
-
798
- # @return [String] a cypher string for this relationship variable
799
- def to_s
800
- var_name
801
- end
802
-
803
- end
804
-
805
- class ExprOp < Expression
806
- attr_reader :left, :right, :op, :neg, :post_fix
807
- include MathFunctions
808
-
809
- def initialize(left, right, op, post_fix = "")
810
- super(left.expressions, :where)
811
- @op = op
812
- @post_fix = post_fix
813
- self.expressions.delete(left)
814
- self.expressions.delete(right)
815
- @left = quote(left)
816
- if regexp?(right)
817
- @op = "=~"
818
- @right = to_regexp(right)
819
- else
820
- @right = right && quote(right)
821
- end
822
- @neg = nil
823
- end
824
-
825
- def separator
826
- " "
827
- end
828
-
829
- def quote(val)
830
- if val.respond_to?(:var_name) && !val.kind_of?(Match)
831
- val.var_name
832
- else
833
- val.is_a?(String) ? %Q["#{val}"] : val
834
- end
835
- end
836
-
837
- def regexp?(right)
838
- @op == "=~" || right.is_a?(Regexp)
839
- end
840
-
841
- def to_regexp(val)
842
- %Q[/#{val.respond_to?(:source) ? val.source : val.to_s}/]
843
- end
844
-
845
- def count
846
- ExprOp.new(self, nil, 'count')
847
- end
848
-
849
- def &(other)
850
- ExprOp.new(self, other, "and")
851
- end
852
-
853
- def |(other)
854
- ExprOp.new(self, other, "or")
855
- end
856
-
857
- def -@
858
- @neg = "not"
859
- self
860
- end
861
-
862
- def not
863
- @neg = "not"
864
- self
865
- end
866
-
867
- # Only in 1.9
868
- if RUBY_VERSION > "1.9.0"
869
- eval %{
870
- def !
871
- @neg = "not"
872
- self
873
- end
874
- }
875
- end
876
-
877
- def left_to_s
878
- left.is_a?(ExprOp) ? "(#{left})" : left
879
- end
880
-
881
- def right_to_s
882
- right.is_a?(ExprOp) ? "(#{right})" : right
883
- end
884
-
885
- def binary!
886
- @binary = true
887
- self
888
- end
889
-
890
- def valid?
891
- # puts "valid? @binary=#{@binary} (#@left #@op #@right) in clause #{clause} ret #{@binary ? !!@left : !!@left && !!@right}"
892
- # it is only valid in a where clause if it's either binary or it has right and left values
893
- @binary ? @left : @left && @right
894
- end
895
-
896
- def to_s
897
- if @right
898
- neg ? "#{neg}(#{left_to_s} #{op} #{right_to_s})" : "#{left_to_s} #{op} #{right_to_s}"
899
- else
900
- # binary operator
901
- neg ? "#{neg}#{op}(#{left_to_s}#{post_fix})" : "#{op}(#{left_to_s}#{post_fix})"
902
- end
903
- end
904
- end
905
-
906
- class Where < Expression
907
- def initialize(expressions, where_statement = nil)
908
- super(expressions, :where)
909
- @where_statement = where_statement
910
- end
911
-
912
- def to_s
913
- @where_statement.to_s
914
- end
915
- end
916
-
917
- class Predicate < Expression
918
- attr_accessor :params
919
-
920
- def initialize(expressions, params)
921
- @params = params
922
- @identifier = :x
923
- params[:input].referenced! if params[:input].respond_to?(:referenced!)
924
- super(expressions, params[:clause])
925
- end
926
-
927
- def identifier(i)
928
- @identifier = i
929
- self
930
- end
931
-
932
- def to_s
933
- input = params[:input]
934
- if input.kind_of?(Property)
935
- yield_param = Property.new([], @identifier, nil)
936
- args = ""
937
- else
938
- yield_param = NodeVar.new([], []).as(@identifier.to_sym)
939
- args = "(#{input.var_name})"
940
- end
941
- context = Neo4j::Cypher.new(yield_param, &params[:predicate_block])
942
- context.expressions.each { |e| e.clause = nil }
943
- if params[:clause] == :return
944
- where_or_colon = ':'
945
- else
946
- where_or_colon = 'WHERE'
947
- end
948
- predicate_value = context.to_s[1..-1] # skip separator ,
949
- "#{params[:op]}(#@identifier in #{params[:iterable]}#{args} #{where_or_colon} #{predicate_value})"
950
- end
951
- end
952
-
953
- class Entities
954
- include PredicateMethods
955
- attr_reader :input, :expressions, :iterable
956
-
957
- def initialize(expressions, iterable, input)
958
- @iterable = iterable
959
- @input = input
960
- @expressions = expressions
961
- end
962
-
963
- end
964
-
965
- end
966
-
967
- end
968
-
969
- end