neo4j 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/CHANGELOG +141 -0
  2. data/CONTRIBUTORS +15 -0
  3. data/Gemfile +3 -0
  4. data/README.rdoc +2015 -0
  5. data/lib/neo4j.old/batch_inserter.rb +144 -0
  6. data/lib/neo4j.old/config.rb +138 -0
  7. data/lib/neo4j.old/event_handler.rb +73 -0
  8. data/lib/neo4j.old/extensions/activemodel.rb +158 -0
  9. data/lib/neo4j.old/extensions/aggregate.rb +12 -0
  10. data/lib/neo4j.old/extensions/aggregate/aggregate_enum.rb +40 -0
  11. data/lib/neo4j.old/extensions/aggregate/ext/node_mixin.rb +69 -0
  12. data/lib/neo4j.old/extensions/aggregate/node_aggregate.rb +8 -0
  13. data/lib/neo4j.old/extensions/aggregate/node_aggregate_mixin.rb +331 -0
  14. data/lib/neo4j.old/extensions/aggregate/node_aggregator.rb +216 -0
  15. data/lib/neo4j.old/extensions/aggregate/node_group.rb +43 -0
  16. data/lib/neo4j.old/extensions/aggregate/prop_group.rb +30 -0
  17. data/lib/neo4j.old/extensions/aggregate/property_enum.rb +24 -0
  18. data/lib/neo4j.old/extensions/aggregate/props_aggregate.rb +8 -0
  19. data/lib/neo4j.old/extensions/aggregate/props_aggregate_mixin.rb +31 -0
  20. data/lib/neo4j.old/extensions/aggregate/props_aggregator.rb +80 -0
  21. data/lib/neo4j.old/extensions/find_path.rb +117 -0
  22. data/lib/neo4j.old/extensions/graph_algo.rb +1 -0
  23. data/lib/neo4j.old/extensions/graph_algo/all_simple_paths.rb +133 -0
  24. data/lib/neo4j.old/extensions/graph_algo/neo4j-graph-algo-0.3.jar +0 -0
  25. data/lib/neo4j.old/extensions/reindexer.rb +104 -0
  26. data/lib/neo4j.old/extensions/rest.rb +21 -0
  27. data/lib/neo4j.old/extensions/rest/rest.rb +336 -0
  28. data/lib/neo4j.old/extensions/rest/rest_mixin.rb +193 -0
  29. data/lib/neo4j.old/extensions/rest/server.rb +50 -0
  30. data/lib/neo4j.old/extensions/rest/stubs.rb +141 -0
  31. data/lib/neo4j.old/extensions/rest_master.rb +34 -0
  32. data/lib/neo4j.old/extensions/rest_slave.rb +31 -0
  33. data/lib/neo4j.old/extensions/tx_tracker.rb +392 -0
  34. data/lib/neo4j.old/indexer.rb +187 -0
  35. data/lib/neo4j.old/jars.rb +6 -0
  36. data/lib/neo4j.old/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  37. data/lib/neo4j.old/jars/neo4j-kernel-1.0.jar +0 -0
  38. data/lib/neo4j.old/mixins/java_list_mixin.rb +139 -0
  39. data/lib/neo4j.old/mixins/java_node_mixin.rb +205 -0
  40. data/lib/neo4j.old/mixins/java_property_mixin.rb +169 -0
  41. data/lib/neo4j.old/mixins/java_relationship_mixin.rb +60 -0
  42. data/lib/neo4j.old/mixins/migration_mixin.rb +157 -0
  43. data/lib/neo4j.old/mixins/node_mixin.rb +249 -0
  44. data/lib/neo4j.old/mixins/property_class_methods.rb +265 -0
  45. data/lib/neo4j.old/mixins/rel_class_methods.rb +167 -0
  46. data/lib/neo4j.old/mixins/relationship_mixin.rb +103 -0
  47. data/lib/neo4j.old/neo.rb +247 -0
  48. data/lib/neo4j.old/node.rb +49 -0
  49. data/lib/neo4j.old/reference_node.rb +15 -0
  50. data/lib/neo4j.old/relationship.rb +85 -0
  51. data/lib/neo4j.old/relationships/decl_relationship_dsl.rb +164 -0
  52. data/lib/neo4j.old/relationships/has_list.rb +101 -0
  53. data/lib/neo4j.old/relationships/has_n.rb +129 -0
  54. data/lib/neo4j.old/relationships/node_traverser.rb +138 -0
  55. data/lib/neo4j.old/relationships/relationship_dsl.rb +149 -0
  56. data/lib/neo4j.old/relationships/traversal_position.rb +50 -0
  57. data/lib/neo4j.old/relationships/wrappers.rb +51 -0
  58. data/lib/neo4j.old/search_result.rb +72 -0
  59. data/lib/neo4j.old/transaction.rb +254 -0
  60. data/lib/neo4j.old/version.rb +3 -0
  61. data/lib/neo4j.rb +50 -0
  62. data/lib/neo4j/config.rb +137 -0
  63. data/lib/neo4j/database.rb +43 -0
  64. data/lib/neo4j/equal.rb +22 -0
  65. data/lib/neo4j/event_handler.rb +91 -0
  66. data/lib/neo4j/index.rb +157 -0
  67. data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  68. data/lib/neo4j/jars/lucene-core-2.9.2.jar +0 -0
  69. data/lib/neo4j/jars/lucene-core-3.0.1.jar +0 -0
  70. data/lib/neo4j/jars/neo4j-index-1.1.jar +0 -0
  71. data/lib/neo4j/jars/neo4j-kernel-1.1.1.jar +0 -0
  72. data/lib/neo4j/jars/neo4j-kernel-1.1.jar +0 -0
  73. data/lib/neo4j/jars/neo4j-lucene-index-0.1-20100916.085626-67.jar +0 -0
  74. data/lib/neo4j/mapping/class_methods/index.rb +21 -0
  75. data/lib/neo4j/mapping/class_methods/property.rb +139 -0
  76. data/lib/neo4j/mapping/class_methods/relationship.rb +96 -0
  77. data/lib/neo4j/mapping/class_methods/rule.rb +135 -0
  78. data/lib/neo4j/mapping/decl_relationship_dsl.rb +151 -0
  79. data/lib/neo4j/mapping/has_n.rb +117 -0
  80. data/lib/neo4j/mapping/node_mixin.rb +70 -0
  81. data/lib/neo4j/neo4j.rb +65 -0
  82. data/lib/neo4j/node.rb +82 -0
  83. data/lib/neo4j/node_mixin.rb +4 -0
  84. data/lib/neo4j/node_relationship.rb +60 -0
  85. data/lib/neo4j/node_traverser.rb +141 -0
  86. data/lib/neo4j/property.rb +72 -0
  87. data/lib/neo4j/rails/lucene_connection_closer.rb +19 -0
  88. data/lib/neo4j/rails/model.rb +210 -0
  89. data/lib/neo4j/rails/railtie.rb +16 -0
  90. data/lib/neo4j/rails/transaction.rb +29 -0
  91. data/lib/neo4j/rails/value.rb +43 -0
  92. data/lib/neo4j/relationship.rb +88 -0
  93. data/lib/neo4j/relationship_traverser.rb +57 -0
  94. data/lib/neo4j/to_java.rb +17 -0
  95. data/lib/neo4j/transaction.rb +69 -0
  96. data/lib/neo4j/version.rb +3 -0
  97. data/neo4j.gemspec +30 -0
  98. metadata +243 -0
@@ -0,0 +1,117 @@
1
+ module Neo4j
2
+ module Mapping
3
+
4
+ # Enables creating and traversal of nodes.
5
+ # Includes the Enumerable Mixin.
6
+ #
7
+ class HasN
8
+ include Enumerable
9
+
10
+ def initialize(node, dsl) # :nodoc:
11
+ @node = node
12
+ @direction = dsl.direction
13
+ # returns the other DSL if it exists otherwise use this DSL for specifing incoming relationships
14
+ if @direction == :outgoing
15
+ @dsl = dsl
16
+ else
17
+ # which class specifies the incoming DSL ?
18
+ clazz = dsl.to_class || node.class
19
+ @dsl = clazz.decl_relationships[dsl.to_type]
20
+ raise "Unspecified outgoing relationship '#{dsl.to_type}' for incoming relationship '#{dsl.rel_id}' on class #{clazz}" if @dsl.nil?
21
+ end
22
+
23
+ @traverser = Neo4j::NodeTraverser.new(node._java_node, @dsl.namespace_type, @direction)
24
+ end
25
+
26
+
27
+ # Returns the relationships instead of the nodes.
28
+ #
29
+ # ==== Example
30
+ # # return the relationship objects between the folder and file nodes:
31
+ # folder.files.rels.each {|x| ...}
32
+ #
33
+ def rels
34
+ Neo4j::RelationshipTraverser.new(@node._java_node, [@dsl.namespace_type], @direction)
35
+ end
36
+
37
+ # Sets the depth of the traversal.
38
+ # Default is 1 if not specified.
39
+ #
40
+ # ==== Example
41
+ # morpheus.friends.depth(:all).each { ... }
42
+ # morpheus.friends.depth(3).each { ... }
43
+ #
44
+ # ==== Arguments
45
+ # d<Fixnum,Symbol>:: the depth or :all if traversing to the end of the network.
46
+ # ==== Return
47
+ # self
48
+ #
49
+ def depth(d)
50
+ @traverser.depth(d)
51
+ self
52
+ end
53
+
54
+ # Required by the Enumerable mixin.
55
+ def each(&block)
56
+ @traverser.each(&block)
57
+ end
58
+
59
+
60
+ # Returns true if there are no node in this type of relationship
61
+ def empty?
62
+ @traverser.empty?
63
+ end
64
+
65
+
66
+ # Creates a relationship instance between this and the other node.
67
+ def new(other)
68
+ create_rel(@node, other)
69
+ end
70
+
71
+
72
+ # Creates a relationship between this and the other node.
73
+ #
74
+ # ==== Example
75
+ #
76
+ # n1 = Node.new # Node has declared having a friend type of relationship
77
+ # n2 = Node.new
78
+ # n3 = Node.new
79
+ #
80
+ # n1 << n2 << n3
81
+ #
82
+ # This is the same as:
83
+ #
84
+ # n1.add_rel(:friends, n2)
85
+ # n1.add_rel(:friends, n3)
86
+ #
87
+ # ==== Returns
88
+ # self
89
+ #
90
+ def <<(other)
91
+ create_rel(@node, other)
92
+ self
93
+ end
94
+
95
+
96
+ def create_rel(node, other) # :nodoc:
97
+ # If the are creating an incoming relationship we need to swap incoming and outgoing nodes
98
+ if @direction == :outgoing
99
+ from, to = node, other
100
+ else
101
+ from, to = other, node
102
+ end
103
+
104
+ rel = from.outgoing(@dsl.namespace_type) << to
105
+ # rel[_classname] = @dsl.relationship_class # TODO
106
+
107
+ # the from.neo_id is only used for cascade_delete_incoming since that node will be deleted when all the list items has been deleted.
108
+ # if cascade_delete_outgoing all nodes will be deleted when the root node is deleted
109
+ # if cascade_delete_incoming then the root node will be deleted when all root nodes' outgoing nodes are deleted
110
+ rel[@dsl.cascade_delete_prop_name] = node.neo_id if @dsl.cascade_delete?
111
+ rel
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,70 @@
1
+ module Neo4j::Mapping
2
+
3
+ module NodeMixin
4
+ extend Forwardable
5
+ include Neo4j::Index
6
+
7
+ def_delegators :@_java_node, :[]=, :[], :property?, :props, :attributes, :update, :neo_id, :id, :rels, :rel?, :to_param, :getId,
8
+ :rel, :del, :list?, :print, :print_sub, :outgoing, :incoming, :both,
9
+ :equal?, :eql?, :==, :exist?
10
+
11
+
12
+ # --------------------------------------------------------------------------
13
+ # Initialization methods
14
+ #
15
+
16
+
17
+ # Init this node with the specified java neo node
18
+ #
19
+ def init_on_load(java_node) # :nodoc:
20
+ @_java_node = java_node
21
+ end
22
+
23
+
24
+ # Creates a new node and initialize with given properties.
25
+ #
26
+ def init_on_create(*args) # :nodoc:
27
+ self[:_classname] = self.class.to_s
28
+ if args[0].respond_to?(:each_pair)
29
+ args[0].each_pair { |k, v| @_java_node.set_property(k.to_s, v) }
30
+ end
31
+ end
32
+
33
+ # Returns the org.neo4j.graphdb.Node wrapped object
34
+ def _java_node
35
+ @_java_node
36
+ end
37
+
38
+ def id
39
+ @_java_node.id
40
+ end
41
+
42
+ def self.included(c) # :nodoc:
43
+ c.instance_eval do
44
+ # these constants are used in the Neo4j::RelClassMethods and Neo4j::PropertyClassMethods
45
+ # they are defined here since they should only be defined once -
46
+ # all subclasses share the same index, declared properties and index_updaters
47
+ unless c.const_defined?(:DECL_RELATIONSHIPS)
48
+ const_set(:ROOT_CLASS, self)
49
+ const_set(:DECL_RELATIONSHIPS, {})
50
+ const_set(:PROPERTIES_INFO, {})
51
+ end
52
+ class << self
53
+ alias_method :orig_new, :new
54
+ end
55
+ end
56
+ c.extend ClassMethods::Property
57
+ c.extend ClassMethods::Relationship
58
+ c.extend ClassMethods::Aggregate
59
+ c.extend Neo4j::Index::ClassMethods
60
+ def c.inherited(subclass)
61
+ subclass.indexer subclass
62
+ super
63
+ end
64
+ c.indexer c
65
+
66
+ end
67
+
68
+
69
+ end
70
+ end
@@ -0,0 +1,65 @@
1
+ module Neo4j
2
+
3
+ class << self
4
+
5
+
6
+ # Start Neo4j using the default database.
7
+ # This is not required since the database will be started automatically when it is used.
8
+ #
9
+ def start
10
+ default_db
11
+ end
12
+
13
+
14
+ # sets the default database to use
15
+ def default_db=(my_db)
16
+ @db = my_db
17
+ end
18
+
19
+ # Returns default database. Creates a new one if it does not exist, but does not start it.
20
+ def default_db
21
+ @db ||= Database.new
22
+ end
23
+
24
+ # Returns a started db instance
25
+ def started_db
26
+ db = default_db
27
+ db.start unless db.running?
28
+ db
29
+ end
30
+
31
+
32
+ # Returns an unstarted db instance
33
+ # this is typically used for configuring the database, which must sometimes
34
+ # be done before the database is started
35
+ # if the database was already started an excetion will be raised
36
+ def unstarted_db
37
+ @db ||= Database.new
38
+ raise "database was already started" if @db.running?
39
+ @db
40
+ end
41
+
42
+ # returns true if the database is running
43
+ def running?
44
+ @db && @db.running?
45
+ end
46
+
47
+
48
+ def shutdown(this_db = @db)
49
+ this_db.shutdown if this_db
50
+ end
51
+
52
+ def ref_node(this_db = self.started_db)
53
+ this_db.graph.reference_node
54
+ end
55
+
56
+ # Returns an Enumerable object for all nodes in the database
57
+ def all_nodes(this_db = self.started_db)
58
+ Enumerator.new(this_db, :each_node)
59
+ end
60
+
61
+ def event_handler(this_db = default_db)
62
+ this_db.event_handler
63
+ end
64
+ end
65
+ end
data/lib/neo4j/node.rb ADDED
@@ -0,0 +1,82 @@
1
+ module Neo4j
2
+
3
+
4
+
5
+ org.neo4j.kernel.impl.core.NodeProxy.class_eval do
6
+ include Neo4j::Property
7
+ include Neo4j::NodeRelationship
8
+ include Neo4j::Equal
9
+ include Neo4j::Index
10
+
11
+ # Delete the node and all its relationship
12
+ def del
13
+ rels.each {|r| r.del}
14
+ delete
15
+ end
16
+
17
+ # returns true if the node exists in the database
18
+ def exist?
19
+ Neo4j::Node.exist?(self)
20
+ end
21
+
22
+ # provide a hook for ruby class mapping
23
+ def wrapped_entity
24
+ self
25
+ end
26
+
27
+ def class
28
+ Neo4j::Node
29
+ end
30
+ end
31
+
32
+
33
+ class Node
34
+ extend Neo4j::Index::ClassMethods
35
+
36
+ self.indexer self
37
+
38
+ class << self
39
+
40
+
41
+ # Creates a new node using the default db instance when given no args
42
+ # Same as Neo4j::Node#create
43
+ def new(*args)
44
+ # the first argument can be an hash of properties to set
45
+ props = args[0].respond_to?(:each_pair) && args[0]
46
+
47
+ # a db instance can be given, is the first argument if that was not a hash, or otherwise the second
48
+ db = (!props && args[0]) || args[1] || Neo4j.started_db
49
+
50
+ node = db.graph.create_node
51
+ props.each_pair { |k, v| node.set_property(k.to_s, v) } if props
52
+ node
53
+ end
54
+
55
+ # create is the same as new
56
+ alias_method :create, :new
57
+
58
+ def load(node_id, db = Neo4j.started_db)
59
+ load_wrapper(db.graph.get_node_by_id(node_id.to_i))
60
+ rescue java.lang.IllegalStateException
61
+ nil # the node has been deleted
62
+ rescue org.neo4j.graphdb.NotFoundException
63
+ nil
64
+ end
65
+
66
+ def load_wrapper(node)
67
+ return node unless node.property?(:_classname)
68
+ to_class(node[:_classname]).load_wrapper(node)
69
+ end
70
+
71
+ def to_class(class_name)
72
+ class_name.split("::").inject(Kernel) {|container, name| container.const_get(name.to_s) }
73
+ end
74
+
75
+ def exist?(node_or_node_id, db = Neo4j.started_db)
76
+ id = node_or_node_id.kind_of?(Fixnum) ? node_or_node_id : node_or_node_id.id
77
+ load(id, db) != nil
78
+ end
79
+
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,4 @@
1
+ module Neo4j
2
+ # make an alias so that we don't have to write the long name Neo4j::Mapping::NodeMixin
3
+ NodeMixin = Neo4j::Mapping::NodeMixin
4
+ end
@@ -0,0 +1,60 @@
1
+ module Neo4j
2
+
3
+
4
+ module NodeRelationship
5
+ include ToJava
6
+
7
+ def outgoing(type=nil)
8
+ if type
9
+ NodeTraverser.new(self).outgoing(type)
10
+ else
11
+ raise "not implemented yet"
12
+ NodeTraverser.new(self)
13
+ end
14
+ end
15
+
16
+ def incoming(type=nil)
17
+ if type
18
+ NodeTraverser.new(self).incoming(type)
19
+ else
20
+ raise "not implemented yet"
21
+ NodeTraverser.new(self)
22
+ end
23
+ end
24
+
25
+ def both(type=nil)
26
+ if type
27
+ NodeTraverser.new(self).both(type)
28
+ else
29
+ NodeTraverser.new(self) # default is both
30
+ end
31
+ end
32
+
33
+ def rels(*type)
34
+ RelationshipTraverser.new(self, type, :both)
35
+ end
36
+
37
+
38
+ # Check if the given relationship exists
39
+ # Returns true if there are one or more relationships from this node to other nodes
40
+ # with the given relationship.
41
+ #
42
+ # ==== Parameters
43
+ # type:: the key and value to be set, default any type
44
+ # dir:: optional default :both (either, :outgoing, :incoming, :both)
45
+ #
46
+ # ==== Returns
47
+ # true if one or more relationships exists for the given type and dir
48
+ # otherwise false
49
+ #
50
+ def rel? (type=nil, dir=:both)
51
+ if type
52
+ hasRelationship(type_to_java(type), dir_to_java(dir))
53
+ else
54
+ hasRelationship
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,141 @@
1
+ module Neo4j
2
+
3
+ class PruneEvaluator # :nodoc:
4
+ include org.neo4j.graphdb.traversal.PruneEvaluator
5
+ def initialize(proc)
6
+ @proc = proc
7
+ end
8
+
9
+ def prune_after(path)
10
+ @proc.call(path)
11
+ end
12
+ end
13
+
14
+ class FilterPredicate # :nodoc:
15
+ include org.neo4j.helpers.Predicate
16
+ def initialize
17
+ @procs = []
18
+ end
19
+
20
+ def add(proc)
21
+ @procs << proc
22
+ end
23
+
24
+ def include_start_node
25
+ @include_start_node = true
26
+ end
27
+
28
+ def accept(path)
29
+ return false if @include_start_node && path.length == 0
30
+ # find the first filter which returns false
31
+ # if not found then we will accept this path
32
+ @procs.find {|p| !p.call(path)}.nil?
33
+ end
34
+ end
35
+
36
+
37
+ class NodeTraverser
38
+ include Enumerable
39
+ include ToJava
40
+
41
+ def initialize(from, type = nil, dir=nil)
42
+ @from = from
43
+ @depth = 1
44
+ if type.nil? || dir.nil?
45
+ @td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first()
46
+ else
47
+ @type = type_to_java(type)
48
+ @dir = dir_to_java(dir)
49
+ @td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first().relationships(@type, @dir)
50
+ end
51
+ end
52
+
53
+
54
+
55
+ def <<(other_node)
56
+ new(other_node)
57
+ self
58
+ end
59
+
60
+ def new(other_node)
61
+ raise "Only allowed to create outgoing relationships, please add it on the other node if you want to create an incoming relationship" unless @dir == org.neo4j.graphdb.Direction::OUTGOING
62
+ @from.create_relationship_to(other_node, @type)
63
+ end
64
+
65
+ def both(type)
66
+ @type = type_to_java(type) if type
67
+ @dir = dir_to_java(:both)
68
+ @td = @td.relationships(type_to_java(type), @dir)
69
+ self
70
+ end
71
+
72
+ def outgoing(type)
73
+ @type = type_to_java(type) if type
74
+ @dir = dir_to_java(:outgoing)
75
+ @td = @td.relationships(type_to_java(type), @dir)
76
+ self
77
+ end
78
+
79
+ def incoming(type)
80
+ @type = type_to_java(type) if type
81
+ @dir = dir_to_java(:incoming)
82
+ @td = @td.relationships(type_to_java(type), @dir)
83
+ self
84
+ end
85
+
86
+ def filter_method(name, &proc)
87
+ # add method name
88
+ singelton = class << self; self; end
89
+ singelton.send(:define_method, name) {filter &proc}
90
+ self
91
+ end
92
+
93
+ def prune(&block)
94
+ @td = @td.prune(PruneEvaluator.new(block))
95
+ self
96
+ end
97
+
98
+ def filter(&block)
99
+ # we keep a reference to filter predicate since only one filter is allowed and we might want to modify it
100
+ @filter_predicate ||= FilterPredicate.new
101
+ @filter_predicate.add(block)
102
+ @td = @td.filter(@filter_predicate)
103
+ self
104
+ end
105
+
106
+ # Sets depth, if :all then it will traverse any depth
107
+ def depth(d)
108
+ @depth = d
109
+ self
110
+ end
111
+
112
+ def include_start_node
113
+ @include_start_node = true
114
+ self
115
+ end
116
+
117
+ def size
118
+ [*self].size
119
+ end
120
+
121
+ def each
122
+ iter = iterator
123
+ while (iter.hasNext) do
124
+ yield Neo4j::Node.load_wrapper(iter.next)
125
+ end
126
+ end
127
+
128
+ def iterator
129
+ unless @include_start_node
130
+ if @filter_predicate
131
+ @filter_predicate.include_start_node
132
+ else
133
+ @td = @td.filter(org.neo4j.kernel.Traversal.return_all_but_start_node)
134
+ end
135
+ end
136
+ @td = @td.prune(org.neo4j.kernel.Traversal.pruneAfterDepth( @depth ) ) unless @depth == :all
137
+ @td.traverse(@from).nodes.iterator
138
+ end
139
+ end
140
+
141
+ end