neo4j 1.0.0.beta.17 → 1.0.0.beta.18
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.
- data/Gemfile +2 -2
- data/README.rdoc +2 -2
- data/lib/generators/neo4j.rb +65 -0
- data/lib/generators/neo4j/model/model_generator.rb +39 -0
- data/lib/generators/neo4j/model/templates/model.rb +7 -0
- data/lib/neo4j.rb +2 -2
- data/lib/neo4j/config.rb +14 -12
- data/lib/neo4j/database.rb +1 -1
- data/lib/neo4j/equal.rb +3 -0
- data/lib/neo4j/event_handler.rb +25 -14
- data/lib/neo4j/index/class_methods.rb +3 -2
- data/lib/neo4j/index/indexer.rb +121 -21
- data/lib/neo4j/index/lucene_query.rb +156 -0
- data/lib/neo4j/load.rb +3 -2
- data/lib/neo4j/mapping/class_methods/property.rb +16 -0
- data/lib/neo4j/mapping/class_methods/relationship.rb +3 -1
- data/lib/neo4j/mapping/class_methods/root.rb +3 -0
- data/lib/neo4j/mapping/class_methods/rule.rb +141 -66
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +8 -8
- data/lib/neo4j/mapping/has_n.rb +11 -1
- data/lib/neo4j/mapping/node_mixin.rb +20 -0
- data/lib/neo4j/neo4j.rb +24 -5
- data/lib/neo4j/node.rb +1 -1
- data/lib/neo4j/property.rb +1 -1
- data/lib/neo4j/rails/model.rb +40 -36
- data/lib/neo4j/rails/properties.rb +29 -0
- data/lib/neo4j/rails/value.rb +8 -29
- data/lib/neo4j/transaction.rb +0 -1
- data/lib/neo4j/version.rb +1 -1
- metadata +8 -5
- data/lib/neo4j/index/wrapped_query.rb +0 -59
- data/lib/neo4j/mapping/class_methods/index.rb +0 -17
    
        data/Gemfile
    CHANGED
    
    | @@ -6,11 +6,11 @@ group 'test' do | |
| 6 6 | 
             
              gem "rake", ">= 0.8.7"
         | 
| 7 7 | 
             
              gem "rdoc", ">= 2.5.10"
         | 
| 8 8 | 
             
              gem "horo", ">= 1.0.2"
         | 
| 9 | 
            -
              gem "rspec-apigen", ">= 0.0.4"
         | 
| 10 9 | 
             
              gem "rspec", ">= 2.0.0"
         | 
| 11 10 | 
             
              gem "rspec-rails-matchers", ">= 0.2.1"
         | 
| 11 | 
            +
              gem "test-unit"
         | 
| 12 12 | 
             
            end
         | 
| 13 13 |  | 
| 14 14 | 
             
            gem 'ruby-debug-base19' if RUBY_VERSION.include? "1.9"
         | 
| 15 15 | 
             
            gem 'ruby-debug-base' if RUBY_VERSION.include? "1.8"
         | 
| 16 | 
            -
            gem "ruby-debug-ide"
         | 
| 16 | 
            +
            gem "ruby-debug-ide"
         | 
    
        data/README.rdoc
    CHANGED
    
    | @@ -15,13 +15,13 @@ Here are some of the major benefits of Neo4j.rb | |
| 15 15 |  | 
| 16 16 | 
             
            * Domain Modeling - use the language of a graph (nodes/relationship/properties) to express your domain !
         | 
| 17 17 | 
             
              * Schema Less and Efficient storage of Semi Structured Information
         | 
| 18 | 
            -
              * No {O/R mismatch}[http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch] - very natural to map a graph to an Object Oriented language like Ruby.
         | 
| 18 | 
            +
              * No {O/R mismatch}[http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch] - very natural to map a graph to an \Object Oriented language like Ruby.
         | 
| 19 19 | 
             
            * {Performance}[http://www.oscon.com/oscon2009/public/schedule/detail/8364]
         | 
| 20 20 | 
             
            * Embedded Database - no database tier, easier to install, test, deploy and configure. It is run in the same process as your application.
         | 
| 21 21 | 
             
            * Express Queries as Traversals
         | 
| 22 22 | 
             
              * Fast deep traversal instead of slow SQL queries that span many table joins.
         | 
| 23 23 | 
             
              * Very natural to express graph related problem with traversals (recommendation engine, find shortest parth etc..)
         | 
| 24 | 
            -
            * Seamless integration with Ruby on Rails.
         | 
| 24 | 
            +
            * Seamless integration with Ruby on \Rails.
         | 
| 25 25 | 
             
            * ACID Transaction with rollbacks support.
         | 
| 26 26 |  | 
| 27 27 | 
             
            === Documentation
         | 
| @@ -0,0 +1,65 @@ | |
| 1 | 
            +
            require 'rails/generators/named_base'
         | 
| 2 | 
            +
            require 'rails/generators/active_model'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Neo4j
         | 
| 5 | 
            +
            	module Generators
         | 
| 6 | 
            +
            	end
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            class Neo4j::Generators::Base < Rails::Generators::NamedBase #:nodoc:
         | 
| 10 | 
            +
            	def self.source_root
         | 
| 11 | 
            +
            		@_neo4j_source_root ||= File.expand_path(File.join(File.dirname(__FILE__),
         | 
| 12 | 
            +
            			'neo4j', generator_name, 'templates'))
         | 
| 13 | 
            +
            	end
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            class Neo4j::Generators::ActiveModel < Rails::Generators::ActiveModel #:nodoc:
         | 
| 17 | 
            +
            	def self.all(klass)
         | 
| 18 | 
            +
            		"#{klass}.all"
         | 
| 19 | 
            +
            	end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            	def self.find(klass, params=nil)
         | 
| 22 | 
            +
            		"#{klass}.find(#{params})"
         | 
| 23 | 
            +
            	end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            	def self.build(klass, params=nil)
         | 
| 26 | 
            +
            		if params
         | 
| 27 | 
            +
            			"#{klass}.new(#{params})"
         | 
| 28 | 
            +
            		else
         | 
| 29 | 
            +
            			"#{klass}.new"
         | 
| 30 | 
            +
            		end
         | 
| 31 | 
            +
            	end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            	def save
         | 
| 34 | 
            +
            		"#{name}.save"
         | 
| 35 | 
            +
            	end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            	def update_attributes(params=nil)
         | 
| 38 | 
            +
            		"#{name}.update_attributes(#{params})"
         | 
| 39 | 
            +
            	end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            	def errors
         | 
| 42 | 
            +
            		"#{name}.errors"
         | 
| 43 | 
            +
            	end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            	def destroy
         | 
| 46 | 
            +
            		"#{name}.destroy"
         | 
| 47 | 
            +
            	end
         | 
| 48 | 
            +
            end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            module Rails
         | 
| 51 | 
            +
              module Generators
         | 
| 52 | 
            +
                class GeneratedAttribute #:nodoc:
         | 
| 53 | 
            +
                  def type_class
         | 
| 54 | 
            +
                  	case type.to_s.downcase
         | 
| 55 | 
            +
            					when 'datetime' 										then 'DateTime'
         | 
| 56 | 
            +
            					when 'date' 												then 'Date'
         | 
| 57 | 
            +
            					when 'text' 												then 'String'
         | 
| 58 | 
            +
            					when 'integer', 'number', 'fixnum' 	then 'Fixnum'
         | 
| 59 | 
            +
            					when 'float' 												then 'Float'
         | 
| 60 | 
            +
            					else 'String'
         | 
| 61 | 
            +
                  	end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            require File.join(File.dirname(__FILE__), '..', '..', 'neo4j.rb')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class Neo4j::Generators::ModelGenerator < Neo4j::Generators::Base
         | 
| 4 | 
            +
            	argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
         | 
| 5 | 
            +
            	
         | 
| 6 | 
            +
            	check_class_collision
         | 
| 7 | 
            +
            	
         | 
| 8 | 
            +
            	class_option :timestamps, :type => :boolean
         | 
| 9 | 
            +
            	class_option :parent,     :type => :string, :desc => "The parent class for the generated model"
         | 
| 10 | 
            +
            	
         | 
| 11 | 
            +
            	def create_model_file
         | 
| 12 | 
            +
            		template "model.rb", File.join('app/models', "#{singular_name}.rb")
         | 
| 13 | 
            +
            	end
         | 
| 14 | 
            +
            	
         | 
| 15 | 
            +
            	protected
         | 
| 16 | 
            +
            	def migration?
         | 
| 17 | 
            +
            		false
         | 
| 18 | 
            +
            	end
         | 
| 19 | 
            +
            	
         | 
| 20 | 
            +
            	def timestamps?
         | 
| 21 | 
            +
            		options[:timestamps]
         | 
| 22 | 
            +
            	end
         | 
| 23 | 
            +
            	
         | 
| 24 | 
            +
            	def parent?
         | 
| 25 | 
            +
            		options[:parent]
         | 
| 26 | 
            +
            	end
         | 
| 27 | 
            +
            	
         | 
| 28 | 
            +
            	def timestamp_statements
         | 
| 29 | 
            +
            		%q{
         | 
| 30 | 
            +
            property :created_at, DateTime
         | 
| 31 | 
            +
            # property :created_on, Date
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            property :updated_at, DateTime
         | 
| 34 | 
            +
            # property :updated_on, Date
         | 
| 35 | 
            +
            }            
         | 
| 36 | 
            +
            	end
         | 
| 37 | 
            +
            	
         | 
| 38 | 
            +
            	hook_for :test_framework
         | 
| 39 | 
            +
            end
         | 
| @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            class <%= class_name %> < <%= parent? ? options[:parent].classify : "Neo4j::Rails::Model" %>
         | 
| 2 | 
            +
            <% attributes.each do |attribute| -%>
         | 
| 3 | 
            +
            	property :<%= attribute.name %><%= ", :type => #{attribute.type_class}" unless attribute.type_class == "String" %>
         | 
| 4 | 
            +
            <% end -%>
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            <%= timestamp_statements if timestamps? -%>
         | 
| 7 | 
            +
            end
         | 
    
        data/lib/neo4j.rb
    CHANGED
    
    | @@ -22,7 +22,7 @@ require 'neo4j/index/index' | |
| 22 22 | 
             
            require 'neo4j/index/class_methods'
         | 
| 23 23 | 
             
            require 'neo4j/index/index_registry'
         | 
| 24 24 | 
             
            require 'neo4j/index/indexer'
         | 
| 25 | 
            -
            require 'neo4j/index/ | 
| 25 | 
            +
            require 'neo4j/index/lucene_query'
         | 
| 26 26 | 
             
            require 'neo4j/relationship_traverser'
         | 
| 27 27 | 
             
            require 'neo4j/node_traverser'
         | 
| 28 28 | 
             
            require 'neo4j/property'
         | 
| @@ -36,7 +36,6 @@ require 'neo4j/mapping/class_methods/init_node' | |
| 36 36 | 
             
            require 'neo4j/mapping/class_methods/init_rel'
         | 
| 37 37 | 
             
            require 'neo4j/mapping/class_methods/root'
         | 
| 38 38 | 
             
            require 'neo4j/mapping/class_methods/property'
         | 
| 39 | 
            -
            require 'neo4j/mapping/class_methods/index'
         | 
| 40 39 | 
             
            require 'neo4j/mapping/class_methods/relationship'
         | 
| 41 40 | 
             
            require 'neo4j/mapping/decl_relationship_dsl'
         | 
| 42 41 | 
             
            require 'neo4j/mapping/has_n'
         | 
| @@ -54,6 +53,7 @@ require 'neo4j/rails/transaction' | |
| 54 53 | 
             
            require 'neo4j/rails/railtie'
         | 
| 55 54 | 
             
            require 'neo4j/rails/validations/uniqueness'
         | 
| 56 55 | 
             
            require 'neo4j/rails/model'
         | 
| 56 | 
            +
            require 'neo4j/rails/properties'
         | 
| 57 57 | 
             
            require 'neo4j/rails/value'
         | 
| 58 58 | 
             
            require 'neo4j/rails/lucene_connection_closer'
         | 
| 59 59 |  | 
    
        data/lib/neo4j/config.rb
    CHANGED
    
    | @@ -2,9 +2,12 @@ | |
| 2 2 | 
             
            module Neo4j
         | 
| 3 3 |  | 
| 4 4 |  | 
| 5 | 
            -
              # Keeps configuration for neo4j.
         | 
| 5 | 
            +
              # == Keeps configuration for neo4j.
         | 
| 6 6 | 
             
              #
         | 
| 7 | 
            -
              # Neo4j::Config[:storage_path] | 
| 7 | 
            +
              # The most important configuration is <tt>Neo4j::Config[:storage_path]</tt> which is used to
         | 
| 8 | 
            +
              # locate where the neo4j database is stored on the filesystem.
         | 
| 9 | 
            +
              # If this directory is empty then a new database will be created, otherwise it will use the
         | 
| 10 | 
            +
              # database from that directory.
         | 
| 8 11 | 
             
              #
         | 
| 9 12 | 
             
              class Config
         | 
| 10 13 | 
             
                # This code is copied from merb-core/config.rb.
         | 
| @@ -45,8 +48,8 @@ module Neo4j | |
| 45 48 | 
             
                  # Set the value of a config entry.
         | 
| 46 49 | 
             
                  #
         | 
| 47 50 | 
             
                  # ==== Parameters
         | 
| 48 | 
            -
                  # key | 
| 49 | 
            -
                  # val | 
| 51 | 
            +
                  # key:: The key to set the parameter for.
         | 
| 52 | 
            +
                  # val:: The value of the parameter.
         | 
| 50 53 | 
             
                  #
         | 
| 51 54 | 
             
                  def []=(key, val)
         | 
| 52 55 | 
             
                    (@configuration ||= setup)[key] = val
         | 
| @@ -56,7 +59,7 @@ module Neo4j | |
| 56 59 | 
             
                  # Gets the the value of a config entry
         | 
| 57 60 | 
             
                  #
         | 
| 58 61 | 
             
                  # ==== Parameters
         | 
| 59 | 
            -
                  # key | 
| 62 | 
            +
                  # key:: The key of the config entry value we want
         | 
| 60 63 | 
             
                  #
         | 
| 61 64 | 
             
                  def [](key)
         | 
| 62 65 | 
             
                    (@configuration ||= setup)[key]
         | 
| @@ -69,7 +72,7 @@ module Neo4j | |
| 69 72 | 
             
                  # key<Object>:: The key of the parameter to delete.
         | 
| 70 73 | 
             
                  #
         | 
| 71 74 | 
             
                  # ==== Returns
         | 
| 72 | 
            -
                  #  | 
| 75 | 
            +
                  # The value of the removed entry.
         | 
| 73 76 | 
             
                  #
         | 
| 74 77 | 
             
                  def delete(key)
         | 
| 75 78 | 
             
                    @configuration.delete(key)
         | 
| @@ -90,12 +93,11 @@ module Neo4j | |
| 90 93 | 
             
                  # Retrieve the value of a config entry, returning the provided default if the key is not present
         | 
| 91 94 | 
             
                  #
         | 
| 92 95 | 
             
                  # ==== Parameters
         | 
| 93 | 
            -
                  # key | 
| 94 | 
            -
                  # default | 
| 95 | 
            -
                  # The default value to return if the parameter is not set.
         | 
| 96 | 
            +
                  # key:: The key to retrieve the parameter for.
         | 
| 97 | 
            +
                  # default::The default value to return if the parameter is not set.
         | 
| 96 98 | 
             
                  #
         | 
| 97 99 | 
             
                  # ==== Returns
         | 
| 98 | 
            -
                  #  | 
| 100 | 
            +
                  # The value of the configuration parameter or the default.
         | 
| 99 101 | 
             
                  #
         | 
| 100 102 | 
             
                  def fetch(key, default)
         | 
| 101 103 | 
             
                    @configuration.fetch(key, default)
         | 
| @@ -116,7 +118,7 @@ module Neo4j | |
| 116 118 | 
             
                  # Returns the configuration as a hash.
         | 
| 117 119 | 
             
                  #
         | 
| 118 120 | 
             
                  # ==== Returns
         | 
| 119 | 
            -
                  #  | 
| 121 | 
            +
                  # The config as a hash.
         | 
| 120 122 | 
             
                  #
         | 
| 121 123 | 
             
                  def to_hash
         | 
| 122 124 | 
             
                    @configuration
         | 
| @@ -125,7 +127,7 @@ module Neo4j | |
| 125 127 | 
             
                  # Returns the config as YAML.
         | 
| 126 128 | 
             
                  #
         | 
| 127 129 | 
             
                  # ==== Returns
         | 
| 128 | 
            -
                  #  | 
| 130 | 
            +
                  # The config as YAML.
         | 
| 129 131 | 
             
                  #
         | 
| 130 132 | 
             
                  def to_yaml
         | 
| 131 133 | 
             
                    require "yaml"
         | 
    
        data/lib/neo4j/database.rb
    CHANGED
    
    
    
        data/lib/neo4j/equal.rb
    CHANGED
    
    
    
        data/lib/neo4j/event_handler.rb
    CHANGED
    
    | @@ -1,6 +1,30 @@ | |
| 1 1 | 
             
            module Neo4j
         | 
| 2 2 |  | 
| 3 | 
            -
              # Handles  | 
| 3 | 
            +
              # == Handles Transactional Events
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              # You can use this to receive event before the transaction commits.
         | 
| 6 | 
            +
              # The following events are supported:
         | 
| 7 | 
            +
              # * <tt>on_neo4j_started</tt>
         | 
| 8 | 
            +
              # * <tt>on_neo4j_shutdown</tt>
         | 
| 9 | 
            +
              # * <tt>on_node_created</tt>
         | 
| 10 | 
            +
              # * <tt>on_node_deleted</tt>
         | 
| 11 | 
            +
              # * <tt>on_relationship_created</tt>
         | 
| 12 | 
            +
              # * <tt>on_relationship_deleted</tt>
         | 
| 13 | 
            +
              # * <tt>on_property_changed</tt>
         | 
| 14 | 
            +
              # * <tt>on_rel_property_changed</tt>
         | 
| 15 | 
            +
              #
         | 
| 16 | 
            +
              # === Usage
         | 
| 17 | 
            +
              #
         | 
| 18 | 
            +
              #   class MyListener
         | 
| 19 | 
            +
              #     def on_node_deleted(node, old_props, tx_data)
         | 
| 20 | 
            +
              #     end
         | 
| 21 | 
            +
              #   end
         | 
| 22 | 
            +
              #
         | 
| 23 | 
            +
              #   # to add an listener without starting neo4j:
         | 
| 24 | 
            +
              #   Neo4j.unstarted_db.event_handler.add(MyListener.new)
         | 
| 25 | 
            +
              #
         | 
| 26 | 
            +
              # You only need to implement the methods that you need.
         | 
| 27 | 
            +
              #
         | 
| 4 28 | 
             
              class EventHandler
         | 
| 5 29 | 
             
                include org.neo4j.graphdb.event.TransactionEventHandler
         | 
| 6 30 |  | 
| @@ -88,18 +112,5 @@ module Neo4j | |
| 88 112 | 
             
                def rel_property_changed(rel, key, old_value, new_value)
         | 
| 89 113 | 
             
                  @listeners.each {|li| li.on_rel_property_changed(rel, key, old_value, new_value) if li.respond_to?(:on_rel_property_changed)}
         | 
| 90 114 | 
             
                end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                # TODO ?
         | 
| 93 | 
            -
                def tx_finished(tx)
         | 
| 94 | 
            -
                  @listeners.each {|li| li.on_tx_finished(tx) if li.respond_to?(:on_tx_finished)}
         | 
| 95 | 
            -
                end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                def neo_started(neo_instance)
         | 
| 98 | 
            -
                  @listeners.each {|li|  li.on_neo_started(neo_instance)  if li.respond_to?(:on_neo_started)}
         | 
| 99 | 
            -
                end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                def neo_stopped(neo_instance)
         | 
| 102 | 
            -
                  @listeners.each {|li| li.on_neo_stopped(neo_instance) if li.respond_to?(:on_neo_stopped)}
         | 
| 103 | 
            -
                end
         | 
| 104 115 | 
             
              end
         | 
| 105 116 | 
             
            end
         | 
| @@ -34,11 +34,12 @@ module Neo4j | |
| 34 34 | 
             
                  #   class Phone
         | 
| 35 35 | 
             
                  #      include Neo4j::NodeMixin
         | 
| 36 36 | 
             
                  #      property :phone
         | 
| 37 | 
            -
                  #       | 
| 37 | 
            +
                  #      node_indexer Contact  # put index on the Contact class instead
         | 
| 38 | 
            +
                  #      index :phone
         | 
| 38 39 | 
             
                  #   end
         | 
| 39 40 | 
             
                  #
         | 
| 40 41 | 
             
                  #   # Find an contact with a phone number, this works since they share the same index
         | 
| 41 | 
            -
                  #   Contact.find('phone: 12345  | 
| 42 | 
            +
                  #   Contact.find('phone: 12345').first #=> a phone object !
         | 
| 42 43 | 
             
                  #
         | 
| 43 44 | 
             
                  # ==== Returns
         | 
| 44 45 | 
             
                  # The indexer that should be used to index the given class
         | 
    
        data/lib/neo4j/index/indexer.rb
    CHANGED
    
    | @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            module Neo4j
         | 
| 2 2 | 
             
              module Index
         | 
| 3 | 
            -
                class Indexer  | 
| 3 | 
            +
                class Indexer 
         | 
| 4 4 | 
             
                  attr_reader :indexer_for, :field_types, :via_relationships
         | 
| 5 5 |  | 
| 6 | 
            -
                  def initialize(clazz, type)
         | 
| 6 | 
            +
                  def initialize(clazz, type) #:nodoc:
         | 
| 7 7 | 
             
                    # part of the unique name of the index
         | 
| 8 8 | 
             
                    @indexer_for       = clazz
         | 
| 9 9 |  | 
| @@ -19,7 +19,7 @@ module Neo4j | |
| 19 19 | 
             
                    @parent_indexers   = []
         | 
| 20 20 | 
             
                  end
         | 
| 21 21 |  | 
| 22 | 
            -
                  def inherit_fields_from(parent_index)
         | 
| 22 | 
            +
                  def inherit_fields_from(parent_index) #:nodoc:
         | 
| 23 23 | 
             
                    return unless parent_index
         | 
| 24 24 | 
             
                    @field_types.reverse_merge!(parent_index.field_types) if parent_index.respond_to?(:field_types)
         | 
| 25 25 | 
             
                    @via_relationships.reverse_merge!(parent_index.via_relationships) if parent_index.respond_to?(:via_relationships)
         | 
| @@ -30,7 +30,53 @@ module Neo4j | |
| 30 30 | 
             
                    "Indexer @#{object_id} [index_for:#{@indexer_for}, field_types=#{@field_types.keys.join(', ')}, via=#{@via_relationships.inspect}]"
         | 
| 31 31 | 
             
                  end
         | 
| 32 32 |  | 
| 33 | 
            -
                  # | 
| 33 | 
            +
                  # Add an index on a field so that it will be automatically updated by neo4j transactional events.
         | 
| 34 | 
            +
                  #
         | 
| 35 | 
            +
                  # The index method takes an optional configuration hash which allows you to:
         | 
| 36 | 
            +
                  #
         | 
| 37 | 
            +
                  # === Add an index on an a property
         | 
| 38 | 
            +
                  #
         | 
| 39 | 
            +
                  # Example:
         | 
| 40 | 
            +
                  #   class Person
         | 
| 41 | 
            +
                  #     include Neo4j::NodeMixin
         | 
| 42 | 
            +
                  #     index :name
         | 
| 43 | 
            +
                  #   end
         | 
| 44 | 
            +
                  #
         | 
| 45 | 
            +
                  # When the property name is changed/deleted or the node created it will keep the lucene index in sync.
         | 
| 46 | 
            +
                  # You can then perform a lucene query like this: Person.find('name: andreas')
         | 
| 47 | 
            +
                  #'
         | 
| 48 | 
            +
                  # === Add index on other nodes.
         | 
| 49 | 
            +
                  #
         | 
| 50 | 
            +
                  # Example:
         | 
| 51 | 
            +
                  #
         | 
| 52 | 
            +
                  #   class Person
         | 
| 53 | 
            +
                  #     include Neo4j::NodeMixin
         | 
| 54 | 
            +
                  #     has_n(:friends).to(Contact)
         | 
| 55 | 
            +
                  #     has_n(:known_by).from(:friends)
         | 
| 56 | 
            +
                  #     index :user_id, :via => :known_by
         | 
| 57 | 
            +
                  #   end
         | 
| 58 | 
            +
                  #
         | 
| 59 | 
            +
                  # Notice that you *must* specify an incoming relationship with the via key, as shown above.
         | 
| 60 | 
            +
                  # In the example above an index <tt>user_id</tt> will be added to all Person nodes which has a <tt>friends</tt> relationship
         | 
| 61 | 
            +
                  # that person with that user_id. This allows you to do lucene queries on your friends properties.
         | 
| 62 | 
            +
                  #
         | 
| 63 | 
            +
                  # === Set the type value to index
         | 
| 64 | 
            +
                  # By default all values will be indexed as Strings.
         | 
| 65 | 
            +
                  # If you want for example to do a numerical range query you must tell Neo4j.rb to index it as a numeric value.
         | 
| 66 | 
            +
                  # You do that with the key <tt>type</tt>
         | 
| 67 | 
            +
                  #
         | 
| 68 | 
            +
                  # Example:
         | 
| 69 | 
            +
                  #   class Person
         | 
| 70 | 
            +
                  #     include Neo4j::NodeMixin
         | 
| 71 | 
            +
                  #     index :weight, :type => Float
         | 
| 72 | 
            +
                  #   end
         | 
| 73 | 
            +
                  #
         | 
| 74 | 
            +
                  # Supported values for <tt>:type</tt> is <tt>String</tt>, <tt>Float</tt> and <tt>Fixnum</tt>
         | 
| 75 | 
            +
                  #
         | 
| 76 | 
            +
                  # === For more information
         | 
| 77 | 
            +
                  # * See Neo4j::Index::LuceneQuery
         | 
| 78 | 
            +
                  # * See #find
         | 
| 79 | 
            +
                  #
         | 
| 34 80 | 
             
                  def index(field, conf = {})
         | 
| 35 81 | 
             
                    if conf[:via]
         | 
| 36 82 | 
             
                      rel_dsl = @indexer_for._decl_rels[conf[:via]]
         | 
| @@ -48,7 +94,7 @@ module Neo4j | |
| 48 94 | 
             
                    end
         | 
| 49 95 | 
             
                  end
         | 
| 50 96 |  | 
| 51 | 
            -
                  def remove_index_on_fields(node, props, tx_data)
         | 
| 97 | 
            +
                  def remove_index_on_fields(node, props, tx_data) #:nodoc:
         | 
| 52 98 | 
             
                    @field_types.keys.each { |field| rm_index(node, field, props[field]) if props[field] }
         | 
| 53 99 | 
             
                    # remove all via indexed fields
         | 
| 54 100 | 
             
                    @via_relationships.each_value do |dsl|
         | 
| @@ -61,15 +107,15 @@ module Neo4j | |
| 61 107 | 
             
                    end
         | 
| 62 108 | 
             
                  end
         | 
| 63 109 |  | 
| 64 | 
            -
                  def update_on_deleted_relationship(relationship)
         | 
| 110 | 
            +
                  def update_on_deleted_relationship(relationship) #:nodoc:
         | 
| 65 111 | 
             
                    update_on_relationship(relationship, false)
         | 
| 66 112 | 
             
                  end
         | 
| 67 113 |  | 
| 68 | 
            -
                  def update_on_new_relationship(relationship)
         | 
| 114 | 
            +
                  def update_on_new_relationship(relationship) #:nodoc:
         | 
| 69 115 | 
             
                    update_on_relationship(relationship, true)
         | 
| 70 116 | 
             
                  end
         | 
| 71 117 |  | 
| 72 | 
            -
                  def update_on_relationship(relationship, is_created)
         | 
| 118 | 
            +
                  def update_on_relationship(relationship, is_created) #:nodoc:
         | 
| 73 119 | 
             
                    rel_type = relationship.rel_type
         | 
| 74 120 | 
             
                    end_node = relationship._end_node
         | 
| 75 121 | 
             
                    # find which via relationship match rel_type
         | 
| @@ -93,7 +139,7 @@ module Neo4j | |
| 93 139 | 
             
                    end
         | 
| 94 140 | 
             
                  end
         | 
| 95 141 |  | 
| 96 | 
            -
                  def update_index_on(node, field, old_val, new_val)
         | 
| 142 | 
            +
                  def update_index_on(node, field, old_val, new_val) #:nodoc:
         | 
| 97 143 | 
             
                    if @via_relationships.include?(field)
         | 
| 98 144 | 
             
                      dsl = @via_relationships[field]
         | 
| 99 145 | 
             
                      to_class = dsl.to_class
         | 
| @@ -106,42 +152,94 @@ module Neo4j | |
| 106 152 | 
             
                    update_single_index_on(node, field, old_val, new_val)
         | 
| 107 153 | 
             
                  end
         | 
| 108 154 |  | 
| 109 | 
            -
                  def update_single_index_on(node, field, old_val, new_val)
         | 
| 155 | 
            +
                  def update_single_index_on(node, field, old_val, new_val) #:nodoc:
         | 
| 110 156 | 
             
                    if @field_types.include?(field)
         | 
| 111 157 | 
             
                      rm_index(node, field, old_val) if old_val
         | 
| 112 158 | 
             
                      add_index(node, field, new_val) if new_val
         | 
| 113 159 | 
             
                    end
         | 
| 114 160 | 
             
                  end
         | 
| 115 161 |  | 
| 162 | 
            +
                  # Returns true if there is an index on the given field.
         | 
| 163 | 
            +
                  #
         | 
| 116 164 | 
             
                  def index?(field)
         | 
| 117 165 | 
             
                    @field_types.include?(field.to_s)
         | 
| 118 166 | 
             
                  end
         | 
| 119 167 |  | 
| 120 | 
            -
                   | 
| 168 | 
            +
                  # Returns the type of index for the given field (e.g. :exact or :fulltext)
         | 
| 169 | 
            +
                  #
         | 
| 170 | 
            +
                  def index_type_for(field) #:nodoc:
         | 
| 121 171 | 
             
                    return nil unless index?(field)
         | 
| 122 172 | 
             
                    @field_types[field.to_s]
         | 
| 123 173 | 
             
                  end
         | 
| 124 174 |  | 
| 175 | 
            +
                  # Returns true if there is an index of the given type defined.
         | 
| 125 176 | 
             
                  def index_type?(type)
         | 
| 126 177 | 
             
                    @field_types.values.include?(type)
         | 
| 127 178 | 
             
                  end
         | 
| 128 179 |  | 
| 180 | 
            +
                  # Adds an index on the given entity
         | 
| 181 | 
            +
                  # This is normally not needed since you can instead declare an index which will automatically keep
         | 
| 182 | 
            +
                  # the lucene index in sync. See #index
         | 
| 183 | 
            +
                  #
         | 
| 129 184 | 
             
                  def add_index(entity, field, value)
         | 
| 130 185 | 
             
                   	return false unless @field_types.has_key?(field)
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                    # we might need to know what type the properties are when indexing and querying
         | 
| 188 | 
            +
                    @decl_props ||= @indexer_for.respond_to?(:_decl_props) && @indexer_for._decl_props
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                    type = @decl_props && @decl_props[field.to_sym] && @decl_props[field.to_sym][:type]
         | 
| 191 | 
            +
                    if type
         | 
| 192 | 
            +
                      raise "Can't index #{type} with value #{value} since it is not a #{type}" unless type === value
         | 
| 193 | 
            +
                      value = if String != type
         | 
| 194 | 
            +
                                org.neo4j.index.impl.lucene.ValueContext.new(value).indexNumeric
         | 
| 195 | 
            +
                              else
         | 
| 196 | 
            +
                                org.neo4j.index.impl.lucene.ValueContext.new(value)
         | 
| 197 | 
            +
                              end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                    end
         | 
| 200 | 
            +
             | 
| 131 201 | 
             
                    index_for_field(field.to_s).add(entity, field, value)
         | 
| 132 202 | 
             
                  	@parent_indexers.each { |i| i.add_index(entity, field, value) }
         | 
| 133 203 | 
             
                  end
         | 
| 134 204 |  | 
| 205 | 
            +
                  # Removes an index on the given entity
         | 
| 206 | 
            +
                  # This is normally not needed since you can instead declare an index which will automatically keep
         | 
| 207 | 
            +
                  # the lucene index in sync. See #index
         | 
| 208 | 
            +
                  #
         | 
| 135 209 | 
             
                  def rm_index(entity, field, value)
         | 
| 136 210 | 
             
                    return false unless @field_types.has_key?(field)
         | 
| 137 211 | 
             
                    index_for_field(field).remove(entity, field, value)
         | 
| 138 212 | 
             
                    @parent_indexers.each { |i| i.rm_index(entity, field, value) }
         | 
| 139 213 | 
             
                  end
         | 
| 140 214 |  | 
| 215 | 
            +
                  # Performs a Lucene Query.
         | 
| 216 | 
            +
                  #
         | 
| 217 | 
            +
                  # In order to use this you have to declare an index on the fields first, see #index.
         | 
| 218 | 
            +
                  # Notice that you should close the lucene query after the query has been executed.
         | 
| 219 | 
            +
                  # You can do that either by provide an block or calling the Neo4j::Index::LuceneQuery#close
         | 
| 220 | 
            +
                  # method. When performing queries from Ruby on Rails you do not need this since it will be automatically closed
         | 
| 221 | 
            +
                  # (by Rack).
         | 
| 222 | 
            +
                  #
         | 
| 223 | 
            +
                  # === Example, with a block
         | 
| 224 | 
            +
                  #   
         | 
| 225 | 
            +
                  #   Person.find('name: kalle') {|query| puts "#{[*query].join(', )"}
         | 
| 226 | 
            +
                  #
         | 
| 227 | 
            +
                  # ==== Example
         | 
| 228 | 
            +
                  #
         | 
| 229 | 
            +
                  #   query = Person.find('name: kalle')
         | 
| 230 | 
            +
                  #   puts "First item #{query.first}"
         | 
| 231 | 
            +
                  #   query.close
         | 
| 232 | 
            +
                  #
         | 
| 233 | 
            +
                  # === Return Value
         | 
| 234 | 
            +
                  # It will return a Neo4j::Index::LuceneQuery object
         | 
| 235 | 
            +
                  #
         | 
| 236 | 
            +
                  #
         | 
| 141 237 | 
             
                  def find(query, params = {})
         | 
| 142 | 
            -
                     | 
| 143 | 
            -
                     | 
| 144 | 
            -
             | 
| 238 | 
            +
                    # we might need to know what type the properties are when indexing and querying
         | 
| 239 | 
            +
                    @decl_props ||= @indexer_for.respond_to?(:_decl_props) && @indexer_for._decl_props
         | 
| 240 | 
            +
             | 
| 241 | 
            +
                    index = index_for_type(params[:type] || :exact)
         | 
| 242 | 
            +
                    query = (params[:wrapped].nil? || params[:wrapped]) ? LuceneQuery.new(index, @decl_props, query) : index.query(query)
         | 
| 145 243 |  | 
| 146 244 | 
             
                    if block_given?
         | 
| 147 245 | 
             
                      begin
         | 
| @@ -155,7 +253,7 @@ module Neo4j | |
| 155 253 | 
             
                    end
         | 
| 156 254 | 
             
                  end
         | 
| 157 255 |  | 
| 158 | 
            -
                  #  | 
| 256 | 
            +
                  # delete the index, if no type is provided clear all types of indexes
         | 
| 159 257 | 
             
                  def delete_index_type(type=nil)
         | 
| 160 258 | 
             
                    if type
         | 
| 161 259 | 
             
                      #raise "can't clear index of type '#{type}' since it does not exist ([#{@field_types.values.join(',')}] exists)" unless index_type?(type)
         | 
| @@ -167,12 +265,14 @@ module Neo4j | |
| 167 265 | 
             
                    end
         | 
| 168 266 | 
             
                  end
         | 
| 169 267 |  | 
| 170 | 
            -
                  def on_neo4j_shutdown
         | 
| 268 | 
            +
                  def on_neo4j_shutdown #:nodoc:
         | 
| 171 269 | 
             
                    # Since we might start the database again we must make sure that we don't keep any references to
         | 
| 172 | 
            -
                    # an old lucene index  | 
| 270 | 
            +
                    # an old lucene index in memory.
         | 
| 173 271 | 
             
                    @indexes.clear
         | 
| 174 272 | 
             
                  end
         | 
| 175 273 |  | 
| 274 | 
            +
                  # Removes the cached lucene index, can be useful for some RSpecs which needs to restart the Neo4j.
         | 
| 275 | 
            +
                  #
         | 
| 176 276 | 
             
                  def rm_field_type(type=nil)
         | 
| 177 277 | 
             
                    if type
         | 
| 178 278 | 
             
                      @field_types.delete_if { |k, v| v == type }
         | 
| @@ -181,22 +281,22 @@ module Neo4j | |
| 181 281 | 
             
                    end
         | 
| 182 282 | 
             
                  end
         | 
| 183 283 |  | 
| 184 | 
            -
                  def index_for_field(field)
         | 
| 284 | 
            +
                  def index_for_field(field) #:nodoc:
         | 
| 185 285 | 
             
                    type = @field_types[field]
         | 
| 186 286 | 
             
                    @indexes[type] ||= create_index_with(type)
         | 
| 187 287 | 
             
                  end
         | 
| 188 288 |  | 
| 189 | 
            -
                  def index_for_type(type)
         | 
| 289 | 
            +
                  def index_for_type(type) #:nodoc:
         | 
| 190 290 | 
             
                    @indexes[type] ||= create_index_with(type)
         | 
| 191 291 | 
             
                  end
         | 
| 192 292 |  | 
| 193 | 
            -
                  def lucene_config(type)
         | 
| 293 | 
            +
                  def lucene_config(type) #:nodoc:
         | 
| 194 294 | 
             
                    conf = Neo4j::Config[:lucene][type.to_sym]
         | 
| 195 295 | 
             
                    raise "unknown lucene type #{type}" unless conf
         | 
| 196 296 | 
             
                    conf
         | 
| 197 297 | 
             
                  end
         | 
| 198 298 |  | 
| 199 | 
            -
                  def create_index_with(type)
         | 
| 299 | 
            +
                  def create_index_with(type) #:nodoc:
         | 
| 200 300 | 
             
                    db=Neo4j.started_db
         | 
| 201 301 | 
             
                    index_config = lucene_config(type)
         | 
| 202 302 | 
             
                    if @type == :node
         |