neo4j 1.0.0.beta.27-java → 1.0.0.beta.28-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.
- data/CONTRIBUTORS +1 -0
- data/lib/neo4j.rb +38 -72
- data/lib/neo4j/{algo.rb → algo/algo.rb} +5 -1
- data/lib/neo4j/batch/batch.rb +2 -0
- data/lib/neo4j/batch/indexer.rb +108 -0
- data/lib/neo4j/batch/inserter.rb +168 -0
- data/lib/neo4j/database.rb +13 -8
- data/lib/neo4j/{mapping/class_methods/list.rb → has_list/class_methods.rb} +2 -4
- data/lib/neo4j/has_list/has_list.rb +3 -0
- data/lib/neo4j/{mapping/has_list.rb → has_list/mapping.rb} +2 -2
- data/lib/neo4j/{mapping/class_methods/relationship.rb → has_n/class_methods.rb} +42 -12
- data/lib/neo4j/has_n/decl_relationship_dsl.rb +216 -0
- data/lib/neo4j/has_n/has_n.rb +3 -0
- data/lib/neo4j/{mapping/has_n.rb → has_n/mapping.rb} +16 -7
- data/lib/neo4j/index/index.rb +5 -0
- data/lib/neo4j/index/indexer.rb +27 -22
- data/lib/neo4j/index/lucene_query.rb +3 -1
- data/lib/neo4j/jars/core/neo4j-graph-algo-0.8-1.3.M01.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-index-1.3-1.3.M01.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-kernel-1.3-1.3.M01.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-lucene-index-0.5-1.3.M01.jar +0 -0
- data/lib/neo4j/jars/ha/{neo4j-ha-0.6-SNAPSHOT.jar → neo4j-ha-0.6-1.3.M01.jar} +0 -0
- data/lib/neo4j/jars/ha/neo4j-management-1.3-1.3.M01.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-shell-1.3-1.3.M01.jar +0 -0
- data/lib/neo4j/migrations/class_methods.rb +102 -0
- data/lib/neo4j/migrations/extensions.rb +10 -9
- data/lib/neo4j/migrations/lazy_node_mixin.rb +50 -0
- data/lib/neo4j/migrations/migration.rb +84 -81
- data/lib/neo4j/migrations/migrations.rb +6 -100
- data/lib/neo4j/migrations/node_mixin.rb +80 -0
- data/lib/neo4j/migrations/ref_node_wrapper.rb +32 -0
- data/lib/neo4j/neo4j.rb +11 -0
- data/lib/neo4j/node.rb +55 -25
- data/lib/neo4j/{mapping/class_methods/init_node.rb → node_mixin/class_methods.rb} +3 -3
- data/lib/neo4j/{mapping → node_mixin}/node_mixin.rb +35 -18
- data/lib/neo4j/{mapping/class_methods/property.rb → property/class_methods.rb} +5 -4
- data/lib/neo4j/{property.rb → property/property.rb} +2 -0
- data/lib/neo4j/rails/finders.rb +21 -7
- data/lib/neo4j/rails/rails.rb +19 -0
- data/lib/neo4j/rails/timestamps.rb +1 -1
- data/lib/neo4j/relationship.rb +7 -0
- data/lib/neo4j/{mapping/class_methods/init_rel.rb → relationship_mixin/class_methods.rb} +4 -4
- data/lib/neo4j/{mapping → relationship_mixin}/relationship_mixin.rb +23 -5
- data/lib/neo4j/rels/rels.rb +85 -0
- data/lib/neo4j/rels/traverser.rb +102 -0
- data/lib/neo4j/{mapping/class_methods/rule.rb → rule/class_methods.rb} +11 -11
- data/lib/neo4j/rule/functions/count.rb +37 -0
- data/lib/neo4j/rule/functions/function.rb +74 -0
- data/lib/neo4j/rule/functions/functions.rb +3 -0
- data/lib/neo4j/rule/functions/sum.rb +29 -0
- data/lib/neo4j/rule/rule.rb +5 -0
- data/lib/neo4j/rule/rule_event_listener.rb +162 -0
- data/lib/neo4j/rule/rule_node.rb +182 -0
- data/lib/neo4j/to_java.rb +0 -14
- data/lib/neo4j/traversal/filter_predicate.rb +25 -0
- data/lib/neo4j/traversal/prune_evaluator.rb +14 -0
- data/lib/neo4j/traversal/rel_expander.rb +31 -0
- data/lib/neo4j/traversal/traversal.rb +90 -0
- data/lib/neo4j/traversal/traverser.rb +173 -0
- data/lib/neo4j/{type_converters.rb → type_converters/type_converters.rb} +0 -0
- data/lib/neo4j/version.rb +1 -1
- data/lib/test.rb~ +2 -0
- data/neo4j.gemspec +11 -10
- metadata +48 -37
- data/lib/neo4j/functions/count.rb +0 -33
- data/lib/neo4j/functions/function.rb +0 -72
- data/lib/neo4j/functions/sum.rb +0 -27
- data/lib/neo4j/jars/core/neo4j-graph-algo-0.8-SNAPSHOT.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-index-1.3-SNAPSHOT.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-kernel-1.3-SNAPSHOT.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-lucene-index-0.5-SNAPSHOT.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-management-1.3-SNAPSHOT.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-shell-1.3-SNAPSHOT.jar +0 -0
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +0 -214
- data/lib/neo4j/mapping/rule.rb +0 -158
- data/lib/neo4j/mapping/rule_node.rb +0 -176
- data/lib/neo4j/migrations.rb +0 -12
- data/lib/neo4j/migrations/global_migration.rb +0 -29
- data/lib/neo4j/migrations/lazy_migration_mixin.rb +0 -47
- data/lib/neo4j/migrations/migration_mixin.rb +0 -78
- data/lib/neo4j/node_mixin.rb +0 -4
- data/lib/neo4j/node_relationship.rb +0 -161
- data/lib/neo4j/node_traverser.rb +0 -224
- data/lib/neo4j/relationship_mixin.rb +0 -4
- data/lib/neo4j/relationship_traverser.rb +0 -92
data/lib/neo4j/database.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'neo4j/config'
|
2
|
+
require 'neo4j/event_handler'
|
3
|
+
require 'neo4j/transaction'
|
4
|
+
|
1
5
|
module Neo4j
|
2
6
|
# Wraps both Java Neo4j GraphDatabaseService and Lucene.
|
3
7
|
# You can access the raw java neo4j and lucene db's with the <tt>graph</tt> and <tt>lucene</tt>
|
@@ -7,7 +11,7 @@ module Neo4j
|
|
7
11
|
# If one tries to start an already started database then a read only instance to neo4j will be used.
|
8
12
|
#
|
9
13
|
class Database
|
10
|
-
attr_reader :graph, :lucene, :event_handler
|
14
|
+
attr_reader :graph, :lucene, :event_handler, :storage_path
|
11
15
|
|
12
16
|
def initialize()
|
13
17
|
@event_handler = EventHandler.new
|
@@ -16,6 +20,7 @@ module Neo4j
|
|
16
20
|
def start #:nodoc:
|
17
21
|
return if running?
|
18
22
|
@running = true
|
23
|
+
@storage_path = Config.storage_path
|
19
24
|
|
20
25
|
begin
|
21
26
|
if self.class.locked?
|
@@ -36,24 +41,24 @@ module Neo4j
|
|
36
41
|
end
|
37
42
|
|
38
43
|
def start_readonly_graph_db #:nodoc:
|
39
|
-
Neo4j.logger.info "Starting Neo4j in readonly mode since the #{
|
44
|
+
Neo4j.logger.info "Starting Neo4j in readonly mode since the #{@storage_path} is locked"
|
40
45
|
Neo4j.load_local_jars
|
41
|
-
@graph = org.neo4j.kernel.EmbeddedReadOnlyGraphDatabase.new(
|
46
|
+
@graph = org.neo4j.kernel.EmbeddedReadOnlyGraphDatabase.new(@storage_path, Config.to_java_map)
|
42
47
|
end
|
43
48
|
|
44
49
|
def start_local_graph_db #:nodoc:
|
45
|
-
Neo4j.logger.info "Starting local Neo4j using db #{
|
50
|
+
Neo4j.logger.info "Starting local Neo4j using db #{@storage_path}"
|
46
51
|
Neo4j.load_local_jars
|
47
|
-
@graph = org.neo4j.kernel.EmbeddedGraphDatabase.new(
|
52
|
+
@graph = org.neo4j.kernel.EmbeddedGraphDatabase.new(@storage_path, Config.to_java_map)
|
48
53
|
@graph.register_transaction_event_handler(@event_handler)
|
49
54
|
@lucene = @graph.index
|
50
55
|
@event_handler.neo4j_started(self)
|
51
56
|
end
|
52
57
|
|
53
58
|
def start_ha_graph_db
|
54
|
-
Neo4j.logger.info "starting Neo4j in HA mode, machine id: #{Neo4j.config['ha.machine_id']} at #{Neo4j.config['ha.server']} db #{
|
59
|
+
Neo4j.logger.info "starting Neo4j in HA mode, machine id: #{Neo4j.config['ha.machine_id']} at #{Neo4j.config['ha.server']} db #{@storage_path}"
|
55
60
|
Neo4j.load_ha_jars # those jars are only needed for the HighlyAvailableGraphDatabase
|
56
|
-
@graph = org.neo4j.kernel.HighlyAvailableGraphDatabase.new(
|
61
|
+
@graph = org.neo4j.kernel.HighlyAvailableGraphDatabase.new(@storage_path, Neo4j.config.to_java_map)
|
57
62
|
@graph.register_transaction_event_handler(@event_handler)
|
58
63
|
@lucene = @graph.index #org.neo4j.index.impl.lucene.LuceneIndexProvider.new
|
59
64
|
@event_handler.neo4j_started(self)
|
@@ -69,7 +74,7 @@ module Neo4j
|
|
69
74
|
@graph.isReadOnly
|
70
75
|
end
|
71
76
|
|
72
|
-
# check if the database is locked. A neo4j database is locked when
|
77
|
+
# check if the database is locked. A neo4j database is locked when the database is running.
|
73
78
|
def self.locked?
|
74
79
|
lock_file = File.join(Neo4j.config.storage_path, 'neostore')
|
75
80
|
return false unless File.exist?(lock_file)
|
@@ -1,13 +1,11 @@
|
|
1
|
-
module Neo4j::
|
1
|
+
module Neo4j::HasList
|
2
2
|
module ClassMethods
|
3
|
-
module List
|
4
3
|
def has_list(name, params = {})
|
5
4
|
module_eval(%Q{
|
6
5
|
def #{name}
|
7
|
-
Neo4j::Mapping
|
6
|
+
Neo4j::HasList::Mapping.new(self, '#{name}')
|
8
7
|
end}, __FILE__, __LINE__)
|
9
8
|
end
|
10
|
-
end
|
11
9
|
end
|
12
10
|
end
|
13
11
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Neo4j
|
2
|
-
module
|
2
|
+
module HasList
|
3
3
|
|
4
4
|
# Enables creating and traversal of nodes in a list.
|
5
5
|
#
|
@@ -31,7 +31,7 @@ module Neo4j
|
|
31
31
|
#
|
32
32
|
# person.feeds[42] # => a
|
33
33
|
#
|
34
|
-
class
|
34
|
+
class Mapping
|
35
35
|
include Enumerable
|
36
36
|
include ToJava
|
37
37
|
include WillPaginate::Finders::Base
|
@@ -1,12 +1,11 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module
|
3
|
-
|
4
|
-
module Relationship
|
1
|
+
module Neo4j
|
2
|
+
module HasN
|
3
|
+
module ClassMethods
|
5
4
|
include Neo4j::ToJava
|
6
5
|
|
7
6
|
# Specifies a relationship between two node classes.
|
8
7
|
# Generates assignment and accessor methods for the given relationship.
|
9
|
-
# Both incoming and outgoing relationships can be declared, see Neo4j::
|
8
|
+
# Both incoming and outgoing relationships can be declared, see Neo4j::HasN::DeclRelationshipDsl
|
10
9
|
#
|
11
10
|
# ==== Example
|
12
11
|
#
|
@@ -19,32 +18,63 @@ module Neo4j::Mapping
|
|
19
18
|
# folder.files << Neo4j::Node.new << Neo4j::Node.new
|
20
19
|
# folder.files.inject {...}
|
21
20
|
#
|
21
|
+
# FolderNode.files #=> 'files' the name of the relationship
|
22
|
+
#
|
23
|
+
# ==== Example has_n(x).to(...)
|
24
|
+
#
|
25
|
+
# You can declare which class it has relationship to.
|
26
|
+
# The generated relationships will be prefixed with the name of that class.
|
27
|
+
#
|
28
|
+
# class FolderNode
|
29
|
+
# include Ne4j::NodeMixin
|
30
|
+
# has_n(:files).to(File)
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# FolderNode.files #=> 'File#files' the name of the relationship
|
34
|
+
#
|
35
|
+
# ==== Example has_n(x).from(class, has_n_name)
|
36
|
+
#
|
37
|
+
# Neo4j.rb can also generate accessor method for traversing and adding relationship on incoming nodes.
|
38
|
+
#
|
39
|
+
# class FileNode
|
40
|
+
# include Ne4j::NodeMixin
|
41
|
+
# has_one(:folder).from(FolderNode, :files)
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
#
|
22
45
|
# ==== Returns
|
23
46
|
#
|
24
|
-
# Neo4j::
|
47
|
+
# * This method returns Neo4j::HasN::DeclRelationshipDsl
|
48
|
+
# * The generated has_n method returns a Neo4j::HasN::Mapping object
|
25
49
|
#
|
26
50
|
def has_n(rel_type, params = {})
|
27
51
|
clazz = self
|
28
52
|
module_eval(%Q{
|
29
53
|
def #{rel_type}
|
30
54
|
dsl = _decl_rels_for('#{rel_type}'.to_sym)
|
31
|
-
Neo4j::Mapping
|
55
|
+
Neo4j::HasN::Mapping.new(self, dsl)
|
32
56
|
end}, __FILE__, __LINE__)
|
33
57
|
|
58
|
+
|
34
59
|
module_eval(%Q{
|
35
60
|
def #{rel_type}_rels
|
36
61
|
dsl = _decl_rels_for('#{rel_type}'.to_sym)
|
37
62
|
dsl.all_relationships(self)
|
38
63
|
end}, __FILE__, __LINE__)
|
39
64
|
|
40
|
-
|
65
|
+
instance_eval(%Q{
|
66
|
+
def #{rel_type}
|
67
|
+
_decl_rels[:#{rel_type}].rel_type.to_s
|
68
|
+
end}, __FILE__, __LINE__)
|
69
|
+
|
70
|
+
_decl_rels[rel_type.to_sym] = DeclRelationshipDsl.new(rel_type, false, clazz, params)
|
41
71
|
end
|
42
72
|
|
43
73
|
|
44
74
|
# Specifies a relationship between two node classes.
|
45
75
|
# Generates assignment and accessor methods for the given relationship
|
46
76
|
# Old relationship is deleted when a new relationship is assigned.
|
47
|
-
# Both incoming and outgoing relationships can be declared, see Neo4j::
|
77
|
+
# Both incoming and outgoing relationships can be declared, see Neo4j::HasN::DeclRelationshipDsl
|
48
78
|
#
|
49
79
|
# ==== Example
|
50
80
|
#
|
@@ -60,7 +90,7 @@ module Neo4j::Mapping
|
|
60
90
|
#
|
61
91
|
# ==== Returns
|
62
92
|
#
|
63
|
-
# Neo4j::
|
93
|
+
# Neo4j::HasN::DeclRelationshipDsl
|
64
94
|
#
|
65
95
|
def has_one(rel_type, params = {})
|
66
96
|
clazz = self
|
@@ -82,9 +112,9 @@ module Neo4j::Mapping
|
|
82
112
|
dsl.single_relationship(self)
|
83
113
|
end}, __FILE__, __LINE__)
|
84
114
|
|
85
|
-
_decl_rels[rel_type.to_sym] =
|
115
|
+
_decl_rels[rel_type.to_sym] = DeclRelationshipDsl.new(rel_type, true, clazz, params)
|
86
116
|
end
|
87
117
|
|
88
118
|
end
|
89
119
|
end
|
90
|
-
end
|
120
|
+
end
|
@@ -0,0 +1,216 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module HasN
|
3
|
+
|
4
|
+
|
5
|
+
# A DSL for declared relationships has_n and has_one
|
6
|
+
# This DSL will be used to create accessor methods for relationships.
|
7
|
+
# Instead of using the 'raw' Neo4j::NodeMixin#rels method where one needs to know
|
8
|
+
# the name of relationship and direction one can use the generated accessor methods.
|
9
|
+
#
|
10
|
+
# The DSL can also be used to specify a mapping to a Ruby class for a relationship, see Neo4j::HasN::DeclRelationshipDsl#relationship
|
11
|
+
#
|
12
|
+
# ==== Example
|
13
|
+
#
|
14
|
+
# class Folder
|
15
|
+
# include Neo4j::NodeMixin
|
16
|
+
# property :name
|
17
|
+
# # Declaring a Many relationship to any other node
|
18
|
+
# has_n(:files)
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# class File
|
22
|
+
# include Neo4j::NodeMixin
|
23
|
+
# # declaring a incoming relationship from Folder's relationship files
|
24
|
+
# has_one(:folder).from(Folder, :files)
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# The following methods will be generated:
|
28
|
+
# <b>Folder#files</b> :: returns an Enumerable of outgoing nodes for relationship 'files'
|
29
|
+
# <b>Folder#files_rels</b> :: returns an Enumerable of outgoing relationships for relationship 'files'
|
30
|
+
# <b>File#folder</b> :: for adding one node for the relationship 'files' from the outgoing Folder node
|
31
|
+
# <b>File#folder_rel</b> :: for accessing relationship 'files' from the outgoing Folder node
|
32
|
+
# <b>File#folder</b> :: for accessing nodes from relationship 'files' from the outgoing Folder node
|
33
|
+
#
|
34
|
+
class DeclRelationshipDsl
|
35
|
+
include Neo4j::ToJava
|
36
|
+
|
37
|
+
attr_reader :target_class, :direction, :rel_type
|
38
|
+
|
39
|
+
def initialize(method_id, has_one, target_class, params)
|
40
|
+
@direction = :outgoing
|
41
|
+
@method_id = method_id
|
42
|
+
@has_one = has_one
|
43
|
+
@rel_type = method_id
|
44
|
+
@target_class = target_class
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
"DeclRelationshipDsl #{object_id} dir: #{@direction} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_class} rel_class:#{@relationship}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_one?
|
52
|
+
@has_one
|
53
|
+
end
|
54
|
+
|
55
|
+
def each_node(node, direction, raw = false, &block) #:nodoc:
|
56
|
+
type = type_to_java(rel_type)
|
57
|
+
dir = dir_to_java(direction)
|
58
|
+
node._java_node.getRelationships(type, dir).each do |rel|
|
59
|
+
other = raw ? rel.getOtherNode(node) : rel.getOtherNode(node).wrapper
|
60
|
+
block.call other
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def incoming? #:nodoc:
|
65
|
+
@direction == :incoming
|
66
|
+
end
|
67
|
+
|
68
|
+
def single_node(node) #:nodoc:
|
69
|
+
rel = single_relationship(node)
|
70
|
+
rel && rel.other_node(node).wrapper
|
71
|
+
end
|
72
|
+
|
73
|
+
def single_relationship(node) #:nodoc:
|
74
|
+
node._java_node.rel(direction, rel_type)
|
75
|
+
end
|
76
|
+
|
77
|
+
def _all_relationships(node) #:nodoc:
|
78
|
+
type = type_to_java(rel_type)
|
79
|
+
dir = dir_to_java(direction)
|
80
|
+
node._java_node.getRelationships(type, dir)
|
81
|
+
end
|
82
|
+
|
83
|
+
def all_relationships(node) #:nodoc:
|
84
|
+
Neo4j::Rels::Traverser.new(node._java_node, [rel_type], direction)
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_relationship_to(node, other) # :nodoc:
|
88
|
+
from, to = incoming? ? [other, node] : [node, other]
|
89
|
+
java_type = type_to_java(rel_type)
|
90
|
+
|
91
|
+
rel = from._java_node.create_relationship_to(to._java_node, java_type)
|
92
|
+
rel[:_classname] = relationship_class.to_s if relationship_class
|
93
|
+
rel.wrapper
|
94
|
+
end
|
95
|
+
|
96
|
+
# Specifies an outgoing relationship.
|
97
|
+
# The name of the outgoing class will be used as a prefix for the relationship used.
|
98
|
+
#
|
99
|
+
# ==== Arguments
|
100
|
+
# clazz:: to which class this relationship goes
|
101
|
+
# relationship:: optional, the relationship to use
|
102
|
+
#
|
103
|
+
# ==== Example
|
104
|
+
# class FolderNode
|
105
|
+
# include Neo4j::NodeMixin
|
106
|
+
# has_n(:files).to(FileNode)
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# folder = FolderNode.new
|
110
|
+
# # generate a relationship between folder and file of type 'FileNode#files'
|
111
|
+
# folder.files << FileNode.new
|
112
|
+
#
|
113
|
+
def to(*args)
|
114
|
+
@direction = :outgoing
|
115
|
+
|
116
|
+
if (args.size > 1)
|
117
|
+
raise "only one argument expected - the class of the node this relationship points to, got #{args.inspect}"
|
118
|
+
elsif (Class === args[0])
|
119
|
+
# handle e.g. has_n(:friends).to(class)
|
120
|
+
@target_class = args[0]
|
121
|
+
@rel_type = "#{@target_class}##{@method_id}"
|
122
|
+
else
|
123
|
+
raise "Expected a class for, got #{args[0]}/#{args[0].class}"
|
124
|
+
end
|
125
|
+
self
|
126
|
+
end
|
127
|
+
|
128
|
+
# Specifies an incoming relationship.
|
129
|
+
# Will use the outgoing relationship given by the from class.
|
130
|
+
#
|
131
|
+
# ==== Example, with prefix FileNode
|
132
|
+
# class FolderNode
|
133
|
+
# include Neo4j::NodeMixin
|
134
|
+
# has_n(:files).to(FileNode)
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# class FileNode
|
138
|
+
# include Neo4j::NodeMixin
|
139
|
+
# # will only traverse any incoming relationship of type files from node FileNode
|
140
|
+
# has_one(:folder).from(FileNode, :files)
|
141
|
+
# end
|
142
|
+
#
|
143
|
+
# file = FileNode.new
|
144
|
+
# # create an outgoing relationship of type 'FileNode#files' from folder node to file (FileNode is the prefix).
|
145
|
+
# file.folder = FolderNode.new
|
146
|
+
#
|
147
|
+
# ==== Example, without prefix
|
148
|
+
#
|
149
|
+
# class FolderNode
|
150
|
+
# include Neo4j::NodeMixin
|
151
|
+
# has_n(:files)
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
# class FileNode
|
155
|
+
# include Neo4j::NodeMixin
|
156
|
+
# has_one(:folder).from(:files) # will traverse any incoming relationship of type files
|
157
|
+
# end
|
158
|
+
#
|
159
|
+
# file = FileNode.new
|
160
|
+
# # create an outgoing relationship of type 'FileNode#files' from folder node to file
|
161
|
+
# file.folder = FolderNode.new
|
162
|
+
#
|
163
|
+
#
|
164
|
+
def from(*args)
|
165
|
+
@direction = :incoming
|
166
|
+
|
167
|
+
if (args.size > 1)
|
168
|
+
# handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
|
169
|
+
@rel_type = "#{@target_class}##{args[1]}"
|
170
|
+
@target_class = args[0]
|
171
|
+
other_class_dsl = @target_class._decl_rels[args[1]]
|
172
|
+
if other_class_dsl
|
173
|
+
@relationship = other_class_dsl.relationship_class
|
174
|
+
else
|
175
|
+
Neo4j.logger.warn "Unknown outgoing relationship #{args[1]} on #{@target_class}"
|
176
|
+
end
|
177
|
+
elsif (Symbol === args[0])
|
178
|
+
# handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
|
179
|
+
@rel_type = args[0]
|
180
|
+
else
|
181
|
+
raise "Expected a symbol for, got #{args[0]}"
|
182
|
+
end
|
183
|
+
self
|
184
|
+
end
|
185
|
+
|
186
|
+
# Specifies which relationship ruby class to use for the relationship
|
187
|
+
#
|
188
|
+
# ==== Example
|
189
|
+
#
|
190
|
+
# class OrderLine
|
191
|
+
# include Neo4j::RelationshipMixin
|
192
|
+
# property :units
|
193
|
+
# property :unit_price
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
# class Order
|
197
|
+
# property :total_cost
|
198
|
+
# property :dispatched
|
199
|
+
# has_n(:products).to(Product).relationship(OrderLine)
|
200
|
+
# end
|
201
|
+
#
|
202
|
+
# order = Order.new
|
203
|
+
# order.products << Product.new
|
204
|
+
# order.products_rels.first # => OrderLine
|
205
|
+
#
|
206
|
+
def relationship(rel_class)
|
207
|
+
@relationship = rel_class
|
208
|
+
self
|
209
|
+
end
|
210
|
+
|
211
|
+
def relationship_class # :nodoc:
|
212
|
+
@relationship
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -1,16 +1,20 @@
|
|
1
|
+
require 'neo4j/has_n/class_methods'
|
2
|
+
require 'neo4j/has_n/decl_relationship_dsl'
|
3
|
+
require 'neo4j/has_n/mapping'
|
4
|
+
|
1
5
|
module Neo4j
|
2
|
-
module
|
6
|
+
module HasN
|
3
7
|
|
4
|
-
#
|
8
|
+
# The object created by a has_n or has_one Neo4j::NodeMixin class method which enables creating and traversal of nodes.
|
5
9
|
#
|
6
|
-
# Includes the Enumerable
|
10
|
+
# Includes the Enumerable and WillPaginate mixins.
|
7
11
|
# The Neo4j::Mapping::ClassMethods::Relationship#has_n and Neo4j::Mapping::ClassMethods::Relationship#one
|
8
12
|
# methods returns an object of this type.
|
9
13
|
#
|
10
14
|
# ==== See Also
|
11
|
-
# Neo4j::
|
15
|
+
# Neo4j::HasN::ClassMethods
|
12
16
|
#
|
13
|
-
class
|
17
|
+
class Mapping
|
14
18
|
include Enumerable
|
15
19
|
include WillPaginate::Finders::Base
|
16
20
|
|
@@ -23,11 +27,11 @@ module Neo4j
|
|
23
27
|
end
|
24
28
|
|
25
29
|
def to_s
|
26
|
-
"HasN [#@direction, id: #{@node.neo_id} type: #{@dsl && @dsl.rel_type} dsl:#{@dsl}]"
|
30
|
+
"HasN::Mapping [#@direction, id: #{@node.neo_id} type: #{@dsl && @dsl.rel_type} dsl:#{@dsl}]"
|
27
31
|
end
|
28
32
|
|
29
33
|
def size
|
30
|
-
|
34
|
+
self.to_a.size
|
31
35
|
end
|
32
36
|
|
33
37
|
alias_method :length, :size
|
@@ -56,6 +60,11 @@ module Neo4j
|
|
56
60
|
@dsl.each_node(@node, @direction, true, &block)
|
57
61
|
end
|
58
62
|
|
63
|
+
# Returns an real ruby array.
|
64
|
+
def to_ary
|
65
|
+
self.to_a
|
66
|
+
end
|
67
|
+
|
59
68
|
def wp_query(options, pager, args, &block) #:nodoc:
|
60
69
|
page = pager.current_page || 1
|
61
70
|
to = pager.per_page * page
|