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,21 @@
1
+ module Neo4j
2
+ class Railtie < ::Rails::Railtie
3
+ config.neo4j = ActiveSupport::OrderedOptions.new
4
+
5
+ initializer "neo4j.tx" do |app|
6
+ app.config.middleware.use Neo4j::Rails::LuceneConnectionCloser
7
+ end
8
+
9
+ # Add ActiveModel translations to the I18n load_path
10
+ initializer "i18n" do |app|
11
+ config.i18n.load_path += Dir[File.join(File.dirname(__FILE__), '..', '..', '..', 'config', 'locales', '*.{rb,yml}')]
12
+ end
13
+
14
+ # Starting Neo after :load_config_initializers allows apps to
15
+ # register migrations in config/initializers
16
+ initializer "neo4j.start", :after => :load_config_initializers do |app|
17
+ Neo4j::Config.setup.merge!(app.config.neo4j.to_hash)
18
+ Neo4j.start
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,96 @@
1
+ module Neo4j
2
+ module Rails
3
+ module Relationships
4
+
5
+ class Mapper
6
+ def initialize(rel_type, dsl=nil)
7
+ @rel_type = rel_type
8
+ @relationships = []
9
+ @dsl = dsl
10
+ end
11
+
12
+ def rel_type
13
+ (@dsl && @dsl.rel_type) || @rel_type
14
+ end
15
+
16
+ def direction
17
+ (@dsl && @dsl.direction) || :outgoing
18
+ end
19
+
20
+ def to_s
21
+ "#{self.class} #{object_id} dir: #{direction} rel_type: #{@rel_type} wrapped #{@dsl}"
22
+ end
23
+
24
+ def single_relationship(*)
25
+ @relationships.first
26
+ end
27
+
28
+ def each(&block)
29
+ # TODO direction
30
+ # TODO DRY
31
+ @relationships.each do |rel|
32
+ block.call rel.end_node
33
+ end
34
+ @dsl.each(&block) if @dsl
35
+ end
36
+
37
+ def each_node(node, direction, &block) #:nodoc:
38
+ # TODO direction
39
+ @relationships.each do |rel|
40
+ block.call rel.end_node
41
+ end
42
+ @dsl.each_node(node, direction, &block) if @dsl && node.persisted?
43
+ end
44
+
45
+ def del_rel(rel)
46
+ # TODO, we need to delete this when it is saved
47
+ @relationships.delete(rel)
48
+ end
49
+
50
+ def create_relationship_to(from, to)
51
+ #rel_type = (@dsl && @dsl.rel_type) || @rel_type
52
+ #from, to = (@dsl && @dsl.incoming?) ? [to, from] : [from, to]
53
+ @relationships << Relationship.new(@rel_type, from, to, self)
54
+ end
55
+
56
+ def single_node(from)
57
+ if !@relationships.empty?
58
+ @relationships.first.end_node
59
+ else
60
+ @dsl.single_node(from) if @dsl && from.persisted?
61
+ end
62
+ end
63
+
64
+ def valid?
65
+ all_valid = true
66
+ !@relationships.each do |rel|
67
+ start_node = rel.start_node
68
+ end_node = rel.end_node
69
+
70
+ if !end_node.valid?
71
+ all_valid = false
72
+ start_node.errors[@rel_type.to_sym] ||= []
73
+ start_node.errors[@rel_type.to_sym] << end_node.errors
74
+ end
75
+ end
76
+ all_valid
77
+ end
78
+
79
+ def persist
80
+ @relationships.each do |rel|
81
+ if @dsl
82
+ start_node = rel.start_node
83
+ end_node = rel.end_node
84
+
85
+ end_node.save!
86
+ @dsl.create_relationship_to(start_node, end_node)
87
+ else
88
+ rel.end_node.save!
89
+ rel.start_node.outgoing(@rel_type) << rel.end_node
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,30 @@
1
+ module Neo4j
2
+ module Rails
3
+ module Relationships
4
+
5
+ class Relationship
6
+ attr_reader :rel_type, :start_node, :end_node
7
+
8
+
9
+ def initialize(rel_type, start_node, end_node, decl)
10
+ @rel_type = rel_type
11
+ @start_node = start_node
12
+ @end_node = end_node
13
+ @decl = decl
14
+ end
15
+
16
+ def del
17
+ @decl.del_rel(self)
18
+ end
19
+
20
+ def persist
21
+ @start_node._java
22
+ end
23
+
24
+ def to_s
25
+ "Rel [#{rel_type} start #{start_node} end #{end_node}]"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,60 @@
1
+ module Neo4j
2
+ module Rails
3
+ module Relationships
4
+
5
+ # TODO, reuse for incoming relationships ?
6
+ class OutgoingRelationship
7
+ include Enumerable
8
+
9
+ def initialize(from_node, mapper)
10
+ @from_node = from_node
11
+ @mapper = mapper
12
+ end
13
+
14
+ def <<(other)
15
+ @mapper.create_relationship_to(@from_node, other)
16
+ end
17
+
18
+ def each(&block)
19
+ # TODO Direction
20
+ @mapper.each &block
21
+ end
22
+ end
23
+
24
+
25
+ def write_changed_relationships
26
+ @relationships.each_value do |mapper|
27
+ mapper.persist
28
+ end
29
+ end
30
+
31
+ def valid_relationships?
32
+ !@relationships.values.find {|mapper| !mapper.valid?}
33
+ end
34
+
35
+ def _decl_rels_for(type)
36
+ dsl = super
37
+ if false && persisted?
38
+ dsl
39
+ else
40
+ @relationships[type] ||= Mapper.new(type, dsl)
41
+ end
42
+ end
43
+
44
+
45
+ def clear_relationships
46
+ @relationships = {}
47
+ end
48
+
49
+
50
+ def outgoing(rel_type)
51
+ if persisted?
52
+ super
53
+ else
54
+ @relationships[rel_type] ||= Mapper.new(rel_type)
55
+ OutgoingRelationship.new(self, @relationships[rel_type])
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,25 @@
1
+ module Neo4j
2
+ module Rails
3
+ module Serialization
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include ActiveModel::Serializers::Xml
8
+
9
+ # Patch for ActiveModel's XML serializer. There is a bug in the original where
10
+ # raw_value is used in the initializer and so demands always that the object being
11
+ # serialized is sent the attribute's name as a method call. This causes a problem
12
+ # for Neo4j properties that aren't declared and so don't have methods to call. Besides
13
+ # which it's not necessary to re-call to get the value again if it has already
14
+ # been passed.
15
+ class ActiveModel::Serializers::Xml::Serializer::Attribute
16
+ def initialize(name, serializable, raw_value=nil)
17
+ @name, @serializable = name, serializable
18
+ @value = raw_value || @serializable.send(name)
19
+ @type = compute_type
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,65 @@
1
+ # Handle all the created_at, updated_at, created_on, updated_on type stuff.
2
+ module Neo4j
3
+ module Rails
4
+ module Timestamps
5
+ extend ActiveSupport::Concern
6
+
7
+ TIMESTAMP_PROPERTIES = [ :created_at, :created_on, :updated_at, :updated_on ]
8
+
9
+ def write_changed_attributes
10
+ update_timestamp
11
+ super
12
+ end
13
+
14
+ def init_on_create(*args)
15
+ create_timestamp
16
+ super
17
+ end
18
+
19
+ # Set the timestamps for this model if timestamps is set to true in the config
20
+ # and the model is set up with the correct property name, e.g.:
21
+ #
22
+ # class Trackable < Neo4j::Rails::Model
23
+ # property :updated_at, :type => DateTime
24
+ # end
25
+ def update_timestamp
26
+ write_date_or_timestamp(:updated_at) if Neo4j::Config[:timestamps] && respond_to?(:updated_at)
27
+ end
28
+
29
+ # Set the timestamps for this model if timestamps is set to true in the config
30
+ # and the model is set up with the correct property name, e.g.:
31
+ #
32
+ # class Trackable < Neo4j::Rails::Model
33
+ # property :created_at, :type => DateTime
34
+ # end
35
+ def create_timestamp
36
+ write_date_or_timestamp(:created_at) if Neo4j::Config[:timestamps] && respond_to?(:created_at)
37
+ end
38
+
39
+ # Write the timestamp as a Date, DateTime or Time depending on the property type
40
+ def write_date_or_timestamp(attribute)
41
+ value = case self.class._decl_props[attribute][:type].to_s
42
+ when "DateTime"
43
+ DateTime.now
44
+ when "Date"
45
+ Date.today
46
+ when "Time"
47
+ Time.now
48
+ end
49
+
50
+ send("#{attribute}=", value)
51
+ end
52
+
53
+ module ClassMethods
54
+ def property_setup(property, options)
55
+ super
56
+
57
+ # ensure there's always a type on the timestamp properties
58
+ if Neo4j::Config[:timestamps] && TIMESTAMP_PROPERTIES.include?(property)
59
+ _decl_props[property][:type] = Time
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,67 @@
1
+ module Neo4j
2
+ module Rails
3
+
4
+ # This method is typically used in an Rails ActionController as a filter method.
5
+ # It will guarantee that an transaction is create before your action is called,
6
+ # and that the transaction is finished after your action is called.
7
+ #
8
+ # Example:
9
+ # class MyController < ActionController::Base
10
+ # around_filter Neo4j::Rails::Transaction, :only => [:edit, :delete]
11
+ # ...
12
+ # end
13
+ class Transaction
14
+ class << self
15
+ def new
16
+ finish if Thread.current[:neo4j_transaction]
17
+ Thread.current[:neo4j_transaction] = Neo4j::Transaction.new
18
+ end
19
+
20
+ def current
21
+ Thread.current[:neo4j_transaction]
22
+ end
23
+
24
+ def running?
25
+ Thread.current[:neo4j_transaction] != nil
26
+ end
27
+
28
+ def fail?
29
+ Thread.current[:neo4j_transaction_fail] != nil
30
+ end
31
+
32
+ def fail
33
+ Thread.current[:neo4j_transaction_fail] = true
34
+ end
35
+
36
+ def success
37
+ Thread.current[:neo4j_transaction_fail] = nil
38
+ end
39
+
40
+ def finish
41
+ tx = Thread.current[:neo4j_transaction]
42
+ tx.success unless fail?
43
+ tx.finish
44
+ Thread.current[:neo4j_transaction] = nil
45
+ Thread.current[:neo4j_transaction_fail] = nil
46
+ end
47
+
48
+ def filter(*, &block)
49
+ run &block
50
+ end
51
+
52
+ def run
53
+ begin
54
+ new
55
+ ret = yield self
56
+ rescue
57
+ fail
58
+ raise
59
+ ensure
60
+ finish
61
+ end
62
+ ret
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,15 @@
1
+ module Neo4j
2
+ module Rails
3
+ module TxMethods
4
+ def tx_methods(*methods)
5
+ methods.each do |method|
6
+ tx_method = "#{method}_in_tx"
7
+ send(:alias_method, tx_method, method)
8
+ send(:define_method, method) do |*args|
9
+ Neo4j::Rails::Transaction.running? ? send(tx_method, *args) : Neo4j::Rails::Transaction.run { send(tx_method, *args) }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ module Neo4j
2
+ module Rails
3
+ module Validations
4
+ include ActiveModel::Validations
5
+
6
+ def read_attribute_for_validation(key)
7
+ respond_to?(key) ? send(key) : self[key]
8
+ end
9
+
10
+ # The validation process on save can be skipped by passing false. The regular Model#save method is
11
+ # replaced with this when the validations module is mixed in, which it is by default.
12
+ def save(options={})
13
+ perform_validations(options) ? super : false
14
+ end
15
+
16
+ def valid?(context = nil)
17
+ context ||= (new_record? ? :create : :update)
18
+ output = super(context)
19
+ output_rels = valid_relationships?
20
+ errors.empty? && output && output_rels
21
+ end
22
+
23
+ private
24
+ def perform_validations(options={})
25
+ perform_validation = case options
26
+ when Hash
27
+ options[:validate] != false
28
+ end
29
+
30
+ if perform_validation
31
+ valid?(options.is_a?(Hash) ? options[:context] : nil)
32
+ else
33
+ true
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ module Neo4j
2
+ module Rails
3
+ module Validations
4
+ class NonNilValidator < ActiveModel::EachValidator
5
+ def validate_each(record, attribute, value)
6
+ record.errors.add(attribute, :nil, options.merge(:value => value)) if value.nil?
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,37 @@
1
+ module Neo4j
2
+ module Rails
3
+ module Validations
4
+ extend ActiveSupport::Concern
5
+
6
+ class UniquenessValidator < ActiveModel::EachValidator
7
+ def initialize(options)
8
+ super(options.reverse_merge(:case_sensitive => true))
9
+ end
10
+
11
+ def setup(klass)
12
+ @attributes.each do |attribute|
13
+ if klass.index_type_for(attribute) != :exact
14
+ raise "Can't validate property #{attribute.inspect} on class #{klass} since there is no :exact lucene index on that property or the index declaration #{attribute} comes after the validation declaration in #{klass} (try to move it before the validation rules)"
15
+ end
16
+ end
17
+ end
18
+
19
+ def validate_each(record, attribute, value)
20
+ return if options[:allow_blank] && value.blank?
21
+ record.class.all("#{attribute}: \"#{value}\"").each do |rec|
22
+ if rec.id != record.id # it doesn't count if we find ourself!
23
+ record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
24
+ break
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ module ClassMethods
31
+ def validates_uniqueness_of(*attr_names)
32
+ validates_with UniquenessValidator, _merge_attributes(attr_names)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end