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,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