neo4j 1.0.0.beta.21-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 (99) hide show
  1. data/CHANGELOG +141 -0
  2. data/CONTRIBUTORS +17 -0
  3. data/Gemfile +16 -0
  4. data/README.rdoc +135 -0
  5. data/lib/generators/neo4j.rb +65 -0
  6. data/lib/generators/neo4j/model/model_generator.rb +39 -0
  7. data/lib/generators/neo4j/model/templates/model.erb +7 -0
  8. data/lib/neo4j.rb +77 -0
  9. data/lib/neo4j/config.rb +153 -0
  10. data/lib/neo4j/database.rb +56 -0
  11. data/lib/neo4j/equal.rb +21 -0
  12. data/lib/neo4j/event_handler.rb +116 -0
  13. data/lib/neo4j/index/class_methods.rb +62 -0
  14. data/lib/neo4j/index/index.rb +33 -0
  15. data/lib/neo4j/index/indexer.rb +312 -0
  16. data/lib/neo4j/index/indexer_registry.rb +68 -0
  17. data/lib/neo4j/index/lucene_query.rb +191 -0
  18. data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  19. data/lib/neo4j/jars/lucene-core-3.0.2.jar +0 -0
  20. data/lib/neo4j/jars/neo4j-index-1.2-1.2.M03.jar +0 -0
  21. data/lib/neo4j/jars/neo4j-kernel-1.2-1.2.M03.jar +0 -0
  22. data/lib/neo4j/jars/neo4j-lucene-index-0.2-1.2.M03.jar +0 -0
  23. data/lib/neo4j/load.rb +21 -0
  24. data/lib/neo4j/mapping/class_methods/init_node.rb +50 -0
  25. data/lib/neo4j/mapping/class_methods/init_rel.rb +35 -0
  26. data/lib/neo4j/mapping/class_methods/list.rb +13 -0
  27. data/lib/neo4j/mapping/class_methods/property.rb +82 -0
  28. data/lib/neo4j/mapping/class_methods/relationship.rb +91 -0
  29. data/lib/neo4j/mapping/class_methods/rule.rb +295 -0
  30. data/lib/neo4j/mapping/decl_relationship_dsl.rb +214 -0
  31. data/lib/neo4j/mapping/has_list.rb +134 -0
  32. data/lib/neo4j/mapping/has_n.rb +83 -0
  33. data/lib/neo4j/mapping/node_mixin.rb +112 -0
  34. data/lib/neo4j/mapping/relationship_mixin.rb +120 -0
  35. data/lib/neo4j/model.rb +4 -0
  36. data/lib/neo4j/neo4j.rb +95 -0
  37. data/lib/neo4j/node.rb +131 -0
  38. data/lib/neo4j/node_mixin.rb +4 -0
  39. data/lib/neo4j/node_relationship.rb +149 -0
  40. data/lib/neo4j/node_traverser.rb +157 -0
  41. data/lib/neo4j/property.rb +111 -0
  42. data/lib/neo4j/rails/attributes.rb +155 -0
  43. data/lib/neo4j/rails/callbacks.rb +34 -0
  44. data/lib/neo4j/rails/finders.rb +134 -0
  45. data/lib/neo4j/rails/lucene_connection_closer.rb +19 -0
  46. data/lib/neo4j/rails/mapping/property.rb +60 -0
  47. data/lib/neo4j/rails/model.rb +105 -0
  48. data/lib/neo4j/rails/persistence.rb +260 -0
  49. data/lib/neo4j/rails/railtie.rb +21 -0
  50. data/lib/neo4j/rails/relationships/mapper.rb +96 -0
  51. data/lib/neo4j/rails/relationships/relationship.rb +30 -0
  52. data/lib/neo4j/rails/relationships/relationships.rb +60 -0
  53. data/lib/neo4j/rails/serialization.rb +25 -0
  54. data/lib/neo4j/rails/timestamps.rb +65 -0
  55. data/lib/neo4j/rails/transaction.rb +67 -0
  56. data/lib/neo4j/rails/tx_methods.rb +15 -0
  57. data/lib/neo4j/rails/validations.rb +38 -0
  58. data/lib/neo4j/rails/validations/non_nil.rb +11 -0
  59. data/lib/neo4j/rails/validations/uniqueness.rb +37 -0
  60. data/lib/neo4j/relationship.rb +169 -0
  61. data/lib/neo4j/relationship_mixin.rb +4 -0
  62. data/lib/neo4j/relationship_traverser.rb +92 -0
  63. data/lib/neo4j/to_java.rb +31 -0
  64. data/lib/neo4j/transaction.rb +68 -0
  65. data/lib/neo4j/type_converters.rb +117 -0
  66. data/lib/neo4j/version.rb +3 -0
  67. data/lib/orm_adapter/adapters/neo4j.rb +55 -0
  68. data/lib/tmp/neo4j/active_tx_log +1 -0
  69. data/lib/tmp/neo4j/index/lucene-store.db +0 -0
  70. data/lib/tmp/neo4j/index/lucene.log.active +0 -0
  71. data/lib/tmp/neo4j/lucene-fulltext/lucene-store.db +0 -0
  72. data/lib/tmp/neo4j/lucene-fulltext/lucene.log.active +0 -0
  73. data/lib/tmp/neo4j/lucene/lucene-store.db +0 -0
  74. data/lib/tmp/neo4j/lucene/lucene.log.active +0 -0
  75. data/lib/tmp/neo4j/messages.log +85 -0
  76. data/lib/tmp/neo4j/neostore +0 -0
  77. data/lib/tmp/neo4j/neostore.id +0 -0
  78. data/lib/tmp/neo4j/neostore.nodestore.db +0 -0
  79. data/lib/tmp/neo4j/neostore.nodestore.db.id +0 -0
  80. data/lib/tmp/neo4j/neostore.propertystore.db +0 -0
  81. data/lib/tmp/neo4j/neostore.propertystore.db.arrays +0 -0
  82. data/lib/tmp/neo4j/neostore.propertystore.db.arrays.id +0 -0
  83. data/lib/tmp/neo4j/neostore.propertystore.db.id +0 -0
  84. data/lib/tmp/neo4j/neostore.propertystore.db.index +0 -0
  85. data/lib/tmp/neo4j/neostore.propertystore.db.index.id +0 -0
  86. data/lib/tmp/neo4j/neostore.propertystore.db.index.keys +0 -0
  87. data/lib/tmp/neo4j/neostore.propertystore.db.index.keys.id +0 -0
  88. data/lib/tmp/neo4j/neostore.propertystore.db.strings +0 -0
  89. data/lib/tmp/neo4j/neostore.propertystore.db.strings.id +0 -0
  90. data/lib/tmp/neo4j/neostore.relationshipstore.db +0 -0
  91. data/lib/tmp/neo4j/neostore.relationshipstore.db.id +0 -0
  92. data/lib/tmp/neo4j/neostore.relationshiptypestore.db +0 -0
  93. data/lib/tmp/neo4j/neostore.relationshiptypestore.db.id +0 -0
  94. data/lib/tmp/neo4j/neostore.relationshiptypestore.db.names +0 -0
  95. data/lib/tmp/neo4j/neostore.relationshiptypestore.db.names.id +0 -0
  96. data/lib/tmp/neo4j/nioneo_logical.log.active +0 -0
  97. data/lib/tmp/neo4j/tm_tx_log.1 +0 -0
  98. data/neo4j.gemspec +31 -0
  99. metadata +216 -0
@@ -0,0 +1,169 @@
1
+ module Neo4j
2
+
3
+ org.neo4j.kernel.impl.core.RelationshipProxy.class_eval do
4
+ include Neo4j::Property
5
+ include Neo4j::Equal
6
+
7
+ alias_method :_end_node, :getEndNode
8
+ alias_method :_start_node, :getStartNode
9
+ alias_method :_other_node, :getOtherNode
10
+
11
+
12
+ def del
13
+ delete
14
+ end
15
+
16
+ def end_node # :nodoc:
17
+ getEndNode.wrapper
18
+ end
19
+
20
+ def start_node # :nodoc:
21
+ getStartNode.wrapper
22
+ end
23
+
24
+ def other_node(node) # :nodoc:
25
+ getOtherNode(node._java_node).wrapper
26
+ end
27
+
28
+
29
+ # same as _java_rel
30
+ # Used so that we have same method for both relationship and nodes
31
+ def wrapped_entity
32
+ self
33
+ end
34
+
35
+ def _java_rel
36
+ self
37
+ end
38
+
39
+
40
+ # Returns true if the relationship exists
41
+ def exist?
42
+ Neo4j::Relationship.exist?(self)
43
+ end
44
+
45
+ # Loads the Ruby wrapper for this node
46
+ # If there is no _classname property for this node then it will simply return itself.
47
+ # Same as Neo4j::Node.load_wrapper(node)
48
+ def wrapper
49
+ self.class.wrapper(self)
50
+ end
51
+
52
+
53
+ # Returns the relationship name
54
+ #
55
+ # ====Example
56
+ # a = Neo4j::Node.new
57
+ # a.outgoing(:friends) << Neo4j::Node.new
58
+ # a.rels.first.rel_type # => 'friends'
59
+ #
60
+ def rel_type
61
+ getType().name()
62
+ end
63
+
64
+ def class
65
+ Neo4j::Relationship
66
+ end
67
+
68
+ end
69
+
70
+ #
71
+ # A relationship between two nodes in the graph. A relationship has a start node, an end node and a type.
72
+ # You can attach properties to relationships with the API specified in Neo4j::JavaPropertyMixin.
73
+ #
74
+ # Relationship are created by invoking the << operator on the rels method on the node as follow:
75
+ # node.outgoing(:friends) << other_node << yet_another_node
76
+ #
77
+ # or using the Neo4j::Relationship#new method (which does the same thing):
78
+ # rel = Neo4j::Relationship.new(:friends, node, other_node)
79
+ #
80
+ # The fact that the relationship API gives meaning to start and end nodes implicitly means that all relationships have a direction.
81
+ # In the example above, rel would be directed from node to otherNode.
82
+ # A relationship's start node and end node and their relation to outgoing and incoming are defined so that the assertions in the following code are true:
83
+ #
84
+ # a = Neo4j::Node.new
85
+ # b = Neo4j::Node.new
86
+ # rel = Neo4j::Relationship.new(:some_type, a, b)
87
+ # # Now we have: (a) --- REL_TYPE ---> (b)
88
+ #
89
+ # rel.start_node # => a
90
+ # rel.end_node # => b
91
+ #
92
+ # Furthermore, Neo4j guarantees that a relationship is never "hanging freely,"
93
+ # i.e. start_node, end_node and other_node are guaranteed to always return valid, non-null nodes.
94
+ #
95
+ # See also the Neo4j::RelationshipMixin if you want to wrap a relationship with your own Ruby class.
96
+ #
97
+ # === Included Mixins
98
+ # * Neo4j::Property
99
+ # * Neo4j::Equal
100
+ #
101
+ # (Those mixin are actually not included in the Neo4j::Relationship but instead directly included in the java class org.neo4j.kernel.impl.core.RelationshipProxy)
102
+ #
103
+ class Relationship
104
+ extend Neo4j::Index::ClassMethods
105
+
106
+ self.rel_indexer self
107
+
108
+ class << self
109
+ include Neo4j::Load
110
+ include Neo4j::ToJava
111
+
112
+
113
+ # Returns a org.neo4j.graphdb.Relationship java object (!)
114
+ # Will trigger a event that the relationship was created.
115
+ #
116
+ # === Parameters
117
+ # type :: the type of relationship
118
+ # from_node :: the start node of this relationship
119
+ # end_node :: the end node of this relationship
120
+ # props :: optional properties for the created relationship
121
+ #
122
+ # === Returns
123
+ # org.neo4j.graphdb.Relationship java object
124
+ #
125
+ # === Examples
126
+ #
127
+ # Neo4j::Relationship.new :friend, node1, node2, :since => '2001-01-02', :status => 'okey'
128
+ #
129
+ def new(type, from_node, to_node, props=nil)
130
+ java_type = type_to_java(type)
131
+ rel = from_node._java_node.create_relationship_to(to_node._java_node, java_type)
132
+ props.each_pair {|k,v| rel[k] = v} if props
133
+ rel
134
+ end
135
+
136
+ # create is the same as new
137
+ alias_method :create, :new
138
+
139
+ # Loads a relationship or wrapped relationship given a native java relationship or an id.
140
+ # If there is a Ruby wrapper for the node then it will create a Ruby object that will
141
+ # wrap the java node (see Neo4j::RelationshipMixin).
142
+ #
143
+ # If the relationship does not exist it will return nil
144
+ #
145
+ def load(rel_id, db = Neo4j.started_db)
146
+ rel = _load(rel_id, db)
147
+ return nil if rel.nil?
148
+ rel.wrapper
149
+ end
150
+
151
+ # Same as load but does not return the node as a wrapped Ruby object.
152
+ #
153
+ def _load(rel_id, db)
154
+ rel = db.graph.get_relationship_by_id(rel_id.to_i)
155
+ rel.hasProperty('_classname') # since we want a IllegalStateException which is otherwise not triggered
156
+ rel
157
+ rescue java.lang.IllegalStateException
158
+ nil # the node has been deleted
159
+ rescue org.neo4j.graphdb.NotFoundException
160
+ nil
161
+ end
162
+
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+
169
+
@@ -0,0 +1,4 @@
1
+ module Neo4j
2
+ # make an alias so that we don't have to write the long name Neo4j::Mapping::Relationship
3
+ RelationshipMixin = Neo4j::Mapping::RelationshipMixin
4
+ end
@@ -0,0 +1,92 @@
1
+ module Neo4j
2
+
3
+ class RelationshipTraverser
4
+ include Enumerable
5
+ include ToJava
6
+
7
+ def initialize(node, types, direction)
8
+ @node = node
9
+ if types.size > 1
10
+ @types = types.inject([]) { |result, type| result << type_to_java(type) }.to_java(:'org.neo4j.graphdb.RelationshipType')
11
+ elsif types.size == 1
12
+ @type = type_to_java(types[0])
13
+ end
14
+ @direction = direction
15
+ end
16
+
17
+ def to_s
18
+ if @type
19
+ "#{self.class} [type: #{@type} dir:#{@direction}]"
20
+ elsif @types
21
+ "#{self.class} [types: #{@types.join(',')} dir:#{@direction}]"
22
+ else
23
+ "#{self.class} [types: ANY dir:#{@direction}]"
24
+ end
25
+ end
26
+
27
+ def each
28
+ iter = iterator
29
+ while (iter.hasNext())
30
+ rel = iter.next
31
+ yield rel.wrapper if match_to_other?(rel)
32
+ end
33
+ end
34
+
35
+ def empty?
36
+ first == nil
37
+ end
38
+
39
+ def iterator
40
+ if @types
41
+ @node.get_relationships(@types).iterator
42
+ elsif @type
43
+ @node.get_relationships(@type, dir_to_java(@direction))
44
+ else
45
+ @node.get_relationships(dir_to_java(@direction))
46
+ end
47
+ end
48
+
49
+ def match_to_other?(rel)
50
+ if @to_other.nil?
51
+ true
52
+ elsif @direction == :outgoing
53
+ rel._end_node == @to_other
54
+ elsif @direction == :incoming
55
+ rel._start_node == @to_other
56
+ else
57
+ rel._start_node == @to_other || rel._end_node == @to_other
58
+ end
59
+ end
60
+
61
+ def to_other(to_other)
62
+ @to_other = to_other
63
+ self
64
+ end
65
+
66
+ def del
67
+ each { |rel| rel.del }
68
+ end
69
+
70
+ def size
71
+ [*self].size
72
+ end
73
+
74
+ def both
75
+ @direction = :both
76
+ self
77
+ end
78
+
79
+ def incoming
80
+ raise "Not allowed calling incoming when finding several relationships types" if @types
81
+ @direction = :incoming
82
+ self
83
+ end
84
+
85
+ def outgoing
86
+ raise "Not allowed calling outgoing when finding several relationships types" if @types
87
+ @direction = :outgoing
88
+ self
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,31 @@
1
+ module Neo4j
2
+ module ToJava
3
+
4
+ def type_to_java(type)
5
+ org.neo4j.graphdb.DynamicRelationshipType.withName(type.to_s)
6
+ end
7
+
8
+ def dir_to_java(dir)
9
+ case dir
10
+ when :outgoing then org.neo4j.graphdb.Direction::OUTGOING
11
+ when :both then org.neo4j.graphdb.Direction::BOTH
12
+ when :incoming then org.neo4j.graphdb.Direction::INCOMING
13
+ else raise "unknown direction '#{dir}', expects :outgoing, :incoming or :both"
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+
20
+ org.neo4j.kernel.impl.core.IntArrayIterator.class_eval do
21
+ def each_wrapped
22
+ while(hasNext())
23
+ yield self.next().wrapper
24
+ end
25
+ end
26
+
27
+ def wrapped
28
+ Enumerator.new(self, :each_wrapped)
29
+ end
30
+
31
+ end
@@ -0,0 +1,68 @@
1
+ module Neo4j
2
+ #
3
+ # All modifying operations that work with the node space must be wrapped in a transaction. Transactions are thread confined.
4
+ # Neo4j does not implement true nested transaction, instead it uses flat nested transactions
5
+ # see http://wiki.neo4j.org/content/Flat_nested_transactions
6
+ #
7
+ class Transaction
8
+
9
+ # Starts a new Neo4j Transaction
10
+ # Returns a Java Neo4j Transaction object
11
+ # See http://api.neo4j.org/current/org/neo4j/graphdb/Transaction.html
12
+ #
13
+ # Example:
14
+ # tx = Neo4j::Transaction.new
15
+ # # modify something
16
+ # tx.success
17
+ # tx.finish
18
+ def self.new(instance = Neo4j.started_db)
19
+ instance.begin_tx
20
+ end
21
+
22
+ # Runs a block in a Neo4j transaction
23
+ #
24
+ # Many operations on neo requires an transaction. You will get much better performance if
25
+ # one transaction is wrapped around several neo operation instead of running one transaction per
26
+ # neo operation.
27
+ # If one transaction is already running then a 'placebo' transaction will be created.
28
+ # Performing a finish on a placebo transaction will not finish the 'real' transaction.
29
+ #
30
+ # ==== Params
31
+ # ::yield:: the block to be performed in one transaction
32
+ #
33
+ # ==== Examples
34
+ # include 'neo4j'
35
+ #
36
+ # Neo4j::Transaction.run {
37
+ # node = PersonNode.new
38
+ # }
39
+ #
40
+ # You have also access to transaction object
41
+ #
42
+ # Neo4j::Transaction.run { |t|
43
+ # # something failed
44
+ # t.failure # will cause a rollback
45
+ # }
46
+
47
+ # If an exception occurs inside the block the transaction will rollback automatically
48
+ #
49
+ # ==== Returns
50
+ # The value of the evaluated provided block
51
+ #
52
+ def self.run # :yield: block that will be executed in a transaction
53
+ raise ArgumentError.new("Expected a block to run in Transaction.run") unless block_given?
54
+
55
+ begin
56
+ tx = Neo4j::Transaction.new
57
+ ret = yield tx
58
+ tx.success
59
+ rescue Exception
60
+ tx.failure unless tx.nil?
61
+ raise
62
+ ensure
63
+ tx.finish unless tx.nil?
64
+ end
65
+ ret
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,117 @@
1
+ module Neo4j
2
+
3
+ # Responsible for converting values from and to Java Neo4j and Lucene.
4
+ # You can implement your own converter by implementing the method <tt>to_java</tt> and <tt>to_ruby</tt>
5
+ # and add it to the Neo4j::Config with the key <tt>:converters</tt>
6
+ #
7
+ # There are currently two default converters that are triggered when a Date or a DateTime is read or written.
8
+ #
9
+ module TypeConverters
10
+
11
+ # The default converter to use if there isn't a specific converter for the type
12
+ class DefaultConverter
13
+ class << self
14
+ def to_java(value)
15
+ value
16
+ end
17
+
18
+ def to_ruby(value)
19
+ value
20
+ end
21
+ end
22
+ end
23
+
24
+ # Converts Date objects to Java long types. Must be timezone UTC.
25
+ class DateConverter
26
+ class << self
27
+ def to_java(value)
28
+ return nil if value.nil?
29
+ Time.utc(value.year, value.month, value.day).to_i
30
+ end
31
+
32
+ def to_ruby(value)
33
+ return nil if value.nil?
34
+ Time.at(value).utc
35
+ end
36
+ end
37
+ end
38
+
39
+ # Converts DateTime objects to and from Java long types. Must be timezone UTC.
40
+ class DateTimeConverter
41
+ class << self
42
+ # Converts the given DateTime (UTC) value to an Fixnum.
43
+ # Only utc times are supported !
44
+ def to_java(value)
45
+ return nil if value.nil?
46
+ Time.utc(value.year, value.month, value.day, value.hour, value.min, value.sec).to_i
47
+ end
48
+
49
+ def to_ruby(value)
50
+ return nil if value.nil?
51
+ t = Time.at(value).utc
52
+ DateTime.civil(t.year, t.month, t.day, t.hour, t.min, t.sec)
53
+ end
54
+ end
55
+ end
56
+
57
+ class TimeConverter
58
+ class << self
59
+ # Converts the given DateTime (UTC) value to an Fixnum.
60
+ # Only utc times are supported !
61
+ def to_java(value)
62
+ return nil if value.nil?
63
+ value.utc.to_i
64
+ end
65
+
66
+ def to_ruby(value)
67
+ return nil if value.nil?
68
+ Time.at(value).utc
69
+ end
70
+ end
71
+ end
72
+
73
+ class << self
74
+ # Always returns a converter that handles to_ruby or to_java
75
+ def converter(type = nil)
76
+ Neo4j.converters[type] || DefaultConverter
77
+ end
78
+
79
+ # Converts the given value to a Java type by using the registered converters.
80
+ # It just looks at the class of the given value unless an attribute name is given.
81
+ # It will convert it if there is a converter registered (in Neo4j::Config) for this value.
82
+ def convert(value, attribute = nil, klass = nil)
83
+ converter(attribute_type(value, attribute, klass)).to_java(value)
84
+ end
85
+
86
+ # Converts the given property (key, value) to Java by using configuration from the given class.
87
+ # If no Converter is defined for this value then it simply returns the given value.
88
+ def to_java(clazz, key, value)
89
+ type = clazz._decl_props[key.to_sym] && clazz._decl_props[key.to_sym][:type]
90
+ converter(type).to_java(value)
91
+ end
92
+
93
+ # Converts the given property (key, value) to Ruby by using configuration from the given class.
94
+ # If no Converter is defined for this value then it simply returns the given value.
95
+ def to_ruby(clazz, key, value)
96
+ type = clazz._decl_props[key.to_sym] && clazz._decl_props[key.to_sym][:type]
97
+ converter(type).to_ruby(value)
98
+ end
99
+
100
+ private
101
+ def attribute_type(value, attribute = nil, klass = nil)
102
+ type = (attribute && klass) ? attribute_type_from_attribute_and_klass(value, attribute, klass) : nil
103
+ type || attribute_type_from_value(value)
104
+ end
105
+
106
+ def attribute_type_from_attribute_and_klass(value, attribute, klass)
107
+ if klass.respond_to?(:_decl_props)
108
+ (klass._decl_props.has_key?(attribute) && klass._decl_props[attribute][:type]) ? klass._decl_props[attribute][:type] : nil
109
+ end
110
+ end
111
+
112
+ def attribute_type_from_value(value)
113
+ value.class
114
+ end
115
+ end
116
+ end
117
+ end