neo4j 1.0.0.beta.21-java

Sign up to get free protection for your applications and to get access to all the features.
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