To edit pages or tickets please login with username/password: aaf/aaf

Changeset 317

Show
Ignore:
Timestamp:
02/18/08 20:36:03 (8 months ago)
Author:
jk
Message:

zwischenstand globale config

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/demo/app/models/content_base.rb

    r308 r317  
    1111  # 'more like this' queries to find other content instances with similar 
    1212  # descriptions 
    13   acts_as_ferret( :fields => { :comment_count => {}, 
     13  acts_as_ferret( :fields => { :comment_count => { :index => :untokenized }, 
    1414                               :title         => { :boost => :title_boost },  
    1515                               :description   => { :boost => 1, :store => :yes }, 
  • trunk/demo/test/unit/shared_index1_test.rb

    r169 r317  
    55 
    66  def setup 
    7     SharedIndex1.rebuild_index(SharedIndex2) 
     7    SharedIndex1.rebuild_index 
    88  end 
    99 
     
    7474 
    7575  def test_ferret_destroy 
    76     SharedIndex1.rebuild_index(SharedIndex2) 
     76    SharedIndex1.rebuild_index 
    7777    result = SharedIndex1.find_id_by_contents("first OR another", :models => :all) 
    7878    assert_equal 4, result.first 
     
    8383 
    8484  def test_ferret_destroy_ticket_88 
    85     SharedIndex1.rebuild_index(SharedIndex2) 
     85    SharedIndex1.rebuild_index 
    8686    result = SharedIndex1.find_id_by_contents("first OR another", :models => :all) 
    8787    assert_equal 4, result.first 
  • trunk/demo/test/unit/shared_index2_test.rb

    r147 r317  
    55 
    66  def setup 
    7     SharedIndex1.rebuild_index(SharedIndex2) 
     7    SharedIndex1.rebuild_index 
    88  end 
    99 
  • trunk/plugin/acts_as_ferret/init.rb

    r123 r317  
    2121require 'acts_as_ferret' 
    2222 
     23ActsAsFerret::logger = RAILS_DEFAULT_LOGGER 
  • trunk/plugin/acts_as_ferret/lib/act_methods.rb

    r308 r317  
    11module ActsAsFerret #:nodoc: 
    2          
     2 
    33  # This module defines the acts_as_ferret method and is included into  
    44  # ActiveRecord::Base 
     
    7373    # For downwards compatibility reasons you can also specify the Ferret options in the  
    7474    # last Hash argument. 
    75     def acts_as_ferret(options={}, ferret_options={}
     75    def acts_as_ferret(options={}
    7676      # default to DRb mode 
    7777      options[:remote] = true if options[:remote].nil? 
     
    100100      end 
    101101 
    102  
    103102      extend ClassMethods 
    104103      extend SharedIndexClassMethods if options[:single_index] 
     
    107106      include MoreLikeThis::InstanceMethods 
    108107 
    109       # AR hooks 
    110       after_create  :ferret_create 
    111       after_update  :ferret_update 
    112       after_destroy :ferret_destroy       
     108      if options[:rdig] 
     109        require 'rdig_adapter' 
     110        include ActsAsFerret::RdigAdapter 
     111      end 
     112 
     113      unless included_modules.include?(ActsAsFerret::WithoutAR) 
     114        # set up AR hooks 
     115        after_create  :ferret_create 
     116        after_update  :ferret_update 
     117        after_destroy :ferret_destroy       
     118      end 
    113119 
    114120      cattr_accessor :aaf_configuration 
    115121 
    116       # default config 
    117       self.aaf_configuration = {  
    118         :index_dir => "#{ActsAsFerret::index_dir}/#{self.name.underscore}", 
    119         :store_class_name => false, 
    120         :name => self.table_name, 
    121         :class_name => self.name, 
    122         :single_index => false, 
    123         :reindex_batch_size => 1000, 
    124         :ferret => {},                    # Ferret config Hash 
    125         :ferret_fields => {},             # list of indexed fields that will be filled later 
    126         :enabled => true,                 # used for class-wide disabling of Ferret 
    127         :mysql_fast_batches => true,      # turn off to disable the faster, id based batching mechanism for MySQL 
    128         :raise_drb_errors => false        # handle DRb connection errors by default 
    129       } 
    130  
    131       # merge aaf options with args 
    132       aaf_configuration.update(options) if options.is_a?(Hash) 
    133       # apply appropriate settings for shared index 
    134       if aaf_configuration[:single_index]  
    135         aaf_configuration[:index_dir] = "#{ActsAsFerret::index_dir}/shared"  
    136         aaf_configuration[:store_class_name] = true  
     122      # shared index defaults 
     123      if options.delete(:single_index) 
     124        options[:store_class_name] = true  
     125        options[:index] = 'shared' 
    137126      end 
    138127 
    139       # set ferret default options 
    140       aaf_configuration[:ferret].reverse_merge!( :or_default => false,  
    141                                                  :handle_parse_errors => true, 
    142                                                  :default_field => nil # will be set later on 
    143                                                  #:max_clauses => 512, 
    144                                                  #:analyzer => Ferret::Analysis::StandardAnalyzer.new, 
    145                                                  # :wild_card_downcase => true 
    146                                                ) 
    147  
    148       # merge ferret options with those from second parameter hash 
    149       aaf_configuration[:ferret].update(ferret_options) if ferret_options.is_a?(Hash) 
    150  
    151       unless options[:remote] 
    152         ActsAsFerret::ensure_directory aaf_configuration[:index_dir]  
    153         aaf_configuration[:index_base_dir] = aaf_configuration[:index_dir] 
    154         aaf_configuration[:index_dir] = find_last_index_version(aaf_configuration[:index_dir]) 
    155         logger.debug "using index in #{aaf_configuration[:index_dir]}" 
     128      # apply default config for rdig based models 
     129      if options[:rdig] 
     130        options[:fields] ||= { :title   => { :boost => 3, :store => :yes }, 
     131                               :content => { :store => :yes } } 
    156132      end 
    157133 
    158       # these properties are somewhat vital to the plugin and shouldn't 
    159       # be overwritten by the user: 
    160       aaf_configuration[:ferret].update( 
    161         :key               => (aaf_configuration[:single_index] ? [:id, :class_name] : :id), 
    162         :path              => aaf_configuration[:index_dir], 
    163         :auto_flush        => true, # slower but more secure in terms of locking problems TODO disable when running in drb mode? 
    164         :create_if_missing => true 
    165       ) 
    166        
    167       if aaf_configuration[:fields] 
    168         add_fields(aaf_configuration[:fields]) 
    169       else 
    170         add_fields(self.new.attributes.keys.map { |k| k.to_sym }) 
    171         add_fields(aaf_configuration[:additional_fields]) 
    172       end 
     134      # name of this index 
     135      index_name = options.delete(:index) || self.name.underscore 
    173136 
    174       # now that all fields have been added, we can initialize the default 
    175       # field list to be used by the query parser. 
    176       # It will include all content fields *not* marked as :untokenized. 
    177       # This fixes the otherwise failing CommentTest#test_stopwords. Basically 
    178       # this means that by default only tokenized fields (which all fields are 
    179       # by default) will be searched. If you want to search inside the contents  
    180       # of an untokenized field, you'll have to explicitly specify it in your  
    181       # query. 
    182       # 
    183       # Unfortunately this is not very useful with a shared index (see 
    184       # http://projects.jkraemer.net/acts_as_ferret/ticket/85) 
    185       # You should consider specifying the default field list to search for as 
    186       # part of the ferret_options hash in your call to acts_as_ferret. 
    187       aaf_configuration[:ferret][:default_field] ||= if aaf_configuration[:single_index] 
    188         logger.warn "You really should set the acts_as_ferret :default_field option when using a shared index!" 
    189         '*' 
    190       else 
    191         aaf_configuration[:ferret_fields].keys.select do |f|  
    192           aaf_configuration[:ferret_fields][f][:index] != :untokenized 
    193         end 
    194       end 
    195       logger.info "default field list: #{aaf_configuration[:ferret][:default_field].inspect}" 
     137      self.aaf_configuration = ActsAsFerret::register_class_with_index(self, index_name, options) 
     138      logger.debug "configured index for class #{self.name}:\n#{aaf_configuration.inspect}" 
    196139 
    197       if options[:remote] 
    198         aaf_index.ensure_index_exists 
    199       end 
     140      # update our copy of the global index config with options local to this class 
     141      aaf_configuration[:class_name] ||= self.name 
     142 
     143      # add methods for retrieving field values 
     144      add_fields options[:fields] 
     145      add_fields options[:additional_fields] 
     146      add_fields aaf_configuration[:fields] 
     147      add_fields aaf_configuration[:additional_fields] 
     148 
     149      # not good at class level, index might get initialized too early 
     150      #if options[:remote] 
     151      #  aaf_index.ensure_index_exists 
     152      #end 
    200153    end 
    201154 
     
    203156    protected 
    204157     
    205     # find the most recent version of an index 
    206     def find_last_index_version(basedir) 
    207       # check for versioned index 
    208       versions = Dir.entries(basedir).select do |f|  
    209         dir = File.join(basedir, f) 
    210         File.directory?(dir) && File.file?(File.join(dir, 'segments')) && f =~ /^\d+(_\d+)?$/ 
    211       end 
    212       if versions.any? 
    213         # select latest version 
    214         versions.sort! 
    215         File.join basedir, versions.last 
    216       else 
    217         basedir 
    218       end 
    219     end 
    220158 
    221  
    222     # helper that defines a method that adds the given field to a ferret  
     159    # helper to defines a method which adds the given field to a ferret  
    223160    # document instance 
    224161    def define_to_field_method(field, options = {}) 
    225       if options[:boost].is_a?(Symbol) 
    226         dynamic_boost = options[:boost] 
    227         options.delete :boost 
    228       end 
    229       options.reverse_merge!( :store       => :no,  
    230                               :highlight   => :yes,  
    231                               :index       => :yes,  
    232                               :term_vector => :with_positions_offsets, 
    233                               :via         => field, 
    234                               :boost       => 1.0 ) 
    235       options[:term_vector] = :no if options[:index] == :no 
    236       aaf_configuration[:ferret_fields][field] = options 
    237  
    238       define_method("#{field}_to_ferret".to_sym) do 
    239         begin 
    240           val = content_for_field_name(field, dynamic_boost) 
     162      method_name = "#{field}_to_ferret" 
     163      return if instance_methods.include?(method_name) # already defined 
     164      dynamic_boost = options[:boost] if options[:boost].is_a?(Symbol) 
     165      via = options[:via] || field 
     166      define_method(method_name.to_sym) do 
     167        val = begin 
     168          content_for_field_name(field, via, dynamic_boost) 
    241169        rescue 
    242170          logger.warn("Error retrieving value for field #{field}: #{$!}") 
    243           val = '' 
     171          '' 
    244172        end 
    245173        logger.debug("Adding field #{field} with value '#{val}' to index") 
     
    249177 
    250178    def add_fields(field_config) 
     179      # TODO 
     180        #field_config.each do |*args|  
     181        #  define_to_field_method *args 
     182        #end                 
    251183      if field_config.is_a? Hash 
    252         field_config.each_pair do |key,val
    253           define_to_field_method(key,val)                   
     184        field_config.each_pair do |field, options
     185          define_to_field_method field, options 
    254186        end 
    255187      elsif field_config.respond_to?(:each) 
    256188        field_config.each do |field|  
    257           define_to_field_method(field) 
     189          define_to_field_method field 
    258190        end                 
    259191      end 
  • trunk/plugin/acts_as_ferret/lib/acts_as_ferret.rb

    r312 r317  
    3434require 'ferret_result' 
    3535require 'instance_methods' 
     36require 'without_ar' 
    3637 
    3738require 'multi_index' 
     
    4546require 'ferret_server' 
    4647 
     48require 'rdig_adapter' 
    4749 
    4850# The Rails ActiveRecord Ferret Mixin. 
     
    7072# 
    7173module ActsAsFerret 
     74 
     75  class ActsAsFerretError < StandardError; end 
     76  class IndexNotDefined < ActsAsFerretError; end 
     77  class IndexAlreadyDefined < ActsAsFerretError; end 
     78 
     79  # default field list for use with a shared index. Set it globally to 
     80  # avoid having to specify the same :default_field value in every class using 
     81  # the shared index. 
     82  @@shared_index_default_fields = nil 
     83  mattr_accessor :shared_index_default_fields 
     84 
     85  @@logger = nil 
     86  mattr_accessor :logger 
    7287 
    7388  # global Hash containing all multi indexes created by all classes using the plugin 
     
    8297  def self.ferret_indexes; @@ferret_indexes end 
    8398 
     99  # holds per-index configuration, key is the index name 
     100  @@index_definitions = {} 
     101  # mapping from class name to index name 
     102  @@index_using_classes = {} 
     103  def self.index_definitions; @@index_definitions end 
     104 
     105  DEFAULT_FIELD_OPTIONS = { 
     106    :store       => :no,  
     107    :highlight   => :yes,  
     108    :index       => :yes,  
     109    :term_vector => :with_positions_offsets, 
     110    :boost       => 1.0 
     111  } 
     112 
     113  def self.field_config_for(fieldname, options = {}) 
     114    config = DEFAULT_FIELD_OPTIONS.merge options 
     115    config[:term_vector] = :no if config[:index] == :no 
     116    config.delete :via 
     117    config.delete :boost if config[:boost].is_a?(Symbol) # dynamic boosts aren't handled here 
     118    return config 
     119  end 
     120 
     121  def self.build_field_config(fields) 
     122    field_config = {} 
     123    case fields 
     124    when Array 
     125      fields.each { |name| field_config[name] = field_config_for name } 
     126    when Hash 
     127      fields.each { |name, options| field_config[name] = field_config_for name, options } 
     128    else raise InvalidArgumentError.new(":fields option must be Hash or Array") 
     129    end if fields 
     130    return field_config 
     131  end 
     132 
     133  # Globally declares an index. 
     134  # 
     135  # Use the index in your model classes with 
     136  #    acts_as_ferret :index => :index_name 
     137  # 
     138  # This method is also used to implicitly declare an index when you use the 
     139  # acts_as_ferret call without the :index option as usual. 
     140  def self.define_index(name, options = {}) 
     141    name = name.to_sym 
     142    raise IndexAlreadyDefined.new(name) if index_definitions.has_key?(name) 
     143    index_definition = { 
     144      :index_dir => "#{ActsAsFerret::index_dir}/#{name}", 
     145      :store_class_name => false, 
     146      :name => name, 
     147      :single_index => false, 
     148      :reindex_batch_size => 1000, 
     149      :ferret => {}, 
     150      :ferret_fields => {},             # list of indexed fields that will be filled later 
     151      :enabled => true,                 # used for class-wide disabling of Ferret 
     152      :mysql_fast_batches => true,      # turn off to disable the faster, id based batching mechanism for MySQL 
     153      :raise_drb_errors => false        # handle DRb connection errors by default 
     154    }.update( options ) 
     155 
     156    index_definition[:registered_models] = [] 
     157     
     158    # build ferret configuration 
     159    index_definition[:ferret] = { 
     160      :or_default          => false,  
     161      :handle_parse_errors => true, 
     162      :default_field       => nil,              # will be set later on 
     163      #:max_clauses => 512, 
     164      #:analyzer => Ferret::Analysis::StandardAnalyzer.new, 
     165      # :wild_card_downcase => true 
     166    }.update( options[:ferret] || {} ) 
     167 
     168    index_definition[:user_default_field] = index_definition[:ferret][:default_field] 
     169 
     170    # these properties are somewhat vital to the plugin and shouldn't 
     171    # be overwritten by the user: 
     172    index_definition[:ferret].update( 
     173      :key               => (index_definition[:store_class_name] ? [:id, :class_name] : :id), 
     174      :path              => index_definition[:index_dir], 
     175      :auto_flush        => true, # slower but more secure in terms of locking problems TODO disable when running in drb mode? 
     176      :create_if_missing => true 
     177    ) 
     178 
     179 
     180    unless index_definition[:remote] 
     181      ActsAsFerret::ensure_directory index_definition[:index_dir]  
     182      index_definition[:index_base_dir] = index_definition[:index_dir] 
     183      index_definition[:index_dir] = find_last_index_version(index_definition[:index_dir]) 
     184      logger.debug "using index in #{index_definition[:index_dir]}" 
     185    end 
     186 
     187    # field config 
     188    index_definition[:ferret_fields] = build_field_config( options[:fields] ) 
     189    index_definition[:ferret_fields].update build_field_config( options[:additional_fields] ) 
     190 
     191    index_definitions[name] = index_definition 
     192    return index_definition 
     193  end 
    84194  
    85    
     195  # called internally by the acts_as_ferret method 
     196  # 
     197  # TODO part of the given options which might influence the indexing of 
     198  # records of a special class (such as analyzer, field configuration(i.e. 
     199  # dynamic boosts) need to be copied to the returned per-class config so they 
     200  # are taken into account properly even when multiple classes use conflicting 
     201  # settings) 
     202  def self.register_class_with_index(clazz, index_name, options = {}) 
     203    index_name = index_name.to_sym 
     204    @@index_using_classes[clazz.name] = index_name 
     205    if definition = index_definitions[index_name] 
     206      definition[:shared_index] = true 
     207      # TODO: add class-declared options to the index definition? which? 
     208      # merge fields from this acts_as_ferret call with predefined fields 
     209      already_defined_fields = definition[:ferret_fields] 
     210      field_config = build_field_config options[:fields] 
     211      field_config.update build_field_config( options[:additional_fields] ) 
     212      field_config.each do |field, config| 
     213        if already_defined_fields.has_key?(field) 
     214          logger.info "ignoring redefinition of ferret field #{field}" 
     215        else 
     216          already_defined_fields[field] = config 
     217          logger.info "adding new field #{field} from class #{clazz.name} to index #{index_name}" 
     218        end 
     219      end 
     220    else 
     221      # index definition on the fly 
     222      # default to all attributes of this class 
     223      options[:fields] ||= clazz.new.attributes.keys.map { |k| k.to_sym } 
     224      define_index index_name, options 
     225    end 
     226 
     227    # update default field list to be used by the query parser, unless it  
     228    # was explicitly given by user. 
     229    # 
     230    # It will include all content fields *not* marked as :untokenized. 
     231    # This fixes the otherwise failing CommentTest#test_stopwords. Basically 
     232    # this means that by default only tokenized fields (which all fields are 
     233    # by default) will be searched. If you want to search inside the contents  
     234    # of an untokenized field, you'll have to explicitly specify it in your  
     235    # query. 
     236    definition = index_definitions[index_name] 
     237    unless definition[:user_default_field] 
     238      # grab all tokenized fields 
     239      definition[:ferret][:default_field] = definition[:ferret_fields].keys.select do |field| 
     240        definition[:ferret_fields][field][:index] != :untokenized 
     241      end 
     242      logger.info "default field list for index #{index_name}: #{definition[:ferret][:default_field].inspect}" 
     243    end 
     244 
     245    # TODO: duped definition more or less worthless... 
     246    definition[:registered_models] << clazz 
     247    return definition.dup 
     248  end 
     249 
     250  # returns the index with the given name. 
     251  def self.get_index(name) 
     252    definition = index_definitions[name] 
     253    path = definition[:index_dir] 
     254    ferret_indexes[path] ||= create_index_instance(definition) 
     255  end 
     256 
     257  # creates a new Index instance. 
     258  def self.create_index_instance(definition) 
     259    if definition[:remote] 
     260      RemoteIndex 
     261    elsif definition[:shared_index] 
     262      SharedIndex 
     263    else 
     264      LocalIndex 
     265    end.new(definition) 
     266  end 
     267 
     268  def self.rebuild_index(name) 
     269    idx = get_index(name) 
     270    idx.rebuild_index 
     271  end 
     272 
     273  # Switches the named index to a new index directory. 
     274  # Used by the DRb server when switching to a new index version. 
     275  def self.change_index_dir(name, new_dir) 
     276    logger.debug "[#{name}] changing index dir to #{new_dir}" 
     277    definition = @@index_definitions[name] 
     278    idx = get_index(name) 
     279 
     280    # store index with the new dir as key. This prevents the aaf_index method 
     281    # from opening another index instance later on. 
     282    ferret_indexes[new_dir] = idx 
     283 
     284    old_dir = definition[:index_dir] 
     285    definition[:index_dir] = definition[:ferret][:path] = new_dir 
     286 
     287    # clean old reference to index 
     288    ActsAsFerret::ferret_indexes.delete old_dir 
     289    idx.reopen! 
     290    logger.debug "[#{name}] index dir is now #{new_dir}" 
     291  end 
     292 
     293  # returns the index definition for the index used by the given class or 
     294  # index_name 
     295  def self.index_definition(clazz_or_index_name) 
     296    logger.debug "index_definition for #{clazz_or_index_name}" 
     297    # TODO: inheritance hochhangeln (Content, ContentBase) 
     298    index_name = clazz_or_index_name.is_a?(Class) ?  
     299      @@index_using_classes[clazz_or_index_name.name] : clazz_or_index_name 
     300    logger.debug "index_definition for #{index_name}" 
     301    index_definitions[index_name] 
     302  end 
     303 
     304  # find the most recent version of an index 
     305  def self.find_last_index_version(basedir) 
     306    # check for versioned index 
     307    versions = Dir.entries(basedir).select do |f|  
     308      dir = File.join(basedir, f) 
     309      File.directory?(dir) && File.file?(File.join(dir, 'segments')) && f =~ /^\d+(_\d+)?$/ 
     310    end 
     311    if versions.any? 
     312      # select latest version 
     313      versions.sort! 
     314      File.join basedir, versions.last 
     315    else 
     316      basedir 
     317    end 
     318  end 
     319 
    86320  def self.ensure_directory(dir) 
    87321    FileUtils.mkdir_p dir unless (File.directory?(dir) || File.symlink?(dir)) 
    88322  end 
     323 
     324 
    89325   
    90326  # make sure the default index base dir exists. by default, all indexes are created 
  • trunk/plugin/acts_as_ferret/lib/blank_slate.rb

    r312 r317  
    11if defined?(BlankSlate) 
    2   # Rails 2.x has  
     2  # Rails 2.x has it already 
    33  module ActsAsFerret 
    44    class BlankSlate < ::BlankSlate 
  • trunk/plugin/acts_as_ferret/lib/class_methods.rb

    r310 r317  
    2121    end 
    2222 
    23     # rebuild the index from all data stored for this model. 
     23    # rebuild the index from all data stored for this model, and any other 
     24    # model classes associated with the same index. 
    2425    # This is called automatically when no index exists yet. 
    2526    # 
    26     # When calling this method manually, you can give any additional  
    27     # model classes that should also go into this index as parameters.  
    28     # Useful when using the :single_index option. 
    29     # Note that attributes named the same in different models will share 
    30     # the same field options in the shared index. 
    31     def rebuild_index(*models) 
    32       models << self unless models.include?(self) 
    33       aaf_index.rebuild_index models.map(&:to_s) 
    34       self.index_dir = find_last_index_version(aaf_configuration[:index_base_dir]) unless aaf_configuration[:remote] 
     27    # TODO: move into index class and add a method taking an index name to 
     28    # ActsAsFerret module. 
     29    def rebuild_index 
     30      ActsAsFerret::rebuild_index(aaf_configuration[:name]) 
    3531    end 
    3632 
     
    4440      options = Hash === ids.last ? ids.pop : {} 
    4541      ids = ids.first if ids.size == 1 && ids.first.is_a?(Enumerable) 
    46       aaf_index.bulk_index(ids, options) 
     42      aaf_index.bulk_index(self.name, ids, options) 
    4743    end 
    4844 
     
    10096        offset = 0 
    10197        ids.each_slice(batch_size) do |id_slice| 
    102           logger.debug "########## slice: #{id_slice.join(',')}" 
    10398          records = find( :all, :conditions => ["id in (?)", id_slice] ) 
    104           logger.debug "########## slice records: #{records.inspect}" 
    10599          #yield records, offset 
    106100          yield find( :all, :conditions => ["id in (?)", id_slice] ), offset 
     
    110104    end 
    111105 
    112     # Switches this class to a new index located in dir. 
    113     # Used by the DRb server when switching to a new index version. 
     106    # TODO change any references to this method to use 
     107    # ActsAsFerret::change_index_dir 
    114108    def index_dir=(dir) 
    115       logger.debug "changing index dir to #{dir}" 
    116        
    117       # store index with the new dir as key. This prevents the aaf_index method 
    118       # from opening another index instance later on. 
    119       ActsAsFerret::ferret_indexes[dir] = aaf_index 
    120       old_dir = aaf_configuration[:index_dir] 
    121       aaf_configuration[:index_dir] = aaf_configuration[:ferret][:path] = dir 
    122       # clean old reference to index 
    123       ActsAsFerret::ferret_indexes.delete old_dir 
    124       aaf_index.reopen! 
    125       logger.debug "index dir is now #{dir}" 
     109      logger.warn "DEPRECATED, use ActsAsFerret::change_index_dir instead if index_dir=" 
     110      ActsAsFerret::change_index_dir(aaf_configuration[:name], dir) 
    126111    end 
    127112     
     
    133118    # Index object, too. 
    134119    def aaf_index 
    135       ActsAsFerret::ferret_indexes[aaf_configuration[:index_dir]] ||= create_index_instance 
     120      ActsAsFerret::get_index(aaf_configuration[:name]) 
    136121    end  
    137122     
     
    352337 
    353338    def lazy_find_by_contents(q, options = {}) 
     339      logger.debug "lazy_find_by_contents: #{q}" 
    354340      result = [] 
    355341      rank   = 0 
    356342      total_hits = find_id_by_contents(q, options) do |model, id, score, data| 
     343        logger.debug "model: #{model}, id: #{id}, data: #{data}" 
    357344        result << FerretResult.new(model, id, score, rank += 1, data) 
    358345      end 
     
    467454    end 
    468455 
    469     # creates a new Index instance. 
    470     def create_index_instance 
    471       if aaf_configuration[:remote] 
    472        RemoteIndex 
    473       elsif aaf_configuration[:single_index] 
    474         SharedIndex 
    475       else 
    476         LocalIndex 
    477       end.new(aaf_configuration) 
    478     end 
    479  
    480456    # combine our conditions with those given by user, if any 
    481457    def combine_conditions(conditions, additional_conditions = []) 
  • trunk/plugin/acts_as_ferret/lib/ferret_result.rb

    r312 r317  
    2121      @ferret_rank  = rank 
    2222      @data = data 
     23      @use_record = false 
    2324    end 
    24      
     25 
     26    def inspect 
     27      "#<FerretResult wrapper for #{@model} with id #{@id}" 
     28    end 
     29 
    2530    def method_missing(method, *args, &block) 
    26       if @ar_record || !@data.has_key?(method) 
     31      # don't try to fetch attributes from RDig based records 
     32      if (@ar_record && @use_record) || !@data.has_key?(method) 
     33        RAILS_DEFAULT_LOGGER.debug "miss for key: #{method.inspect} in #{@data.keys.inspect}" 
    2734        to_record.send method, *args, &block 
    2835      else 
     
    4047        @ar_record.ferret_rank  = ferret_rank 
    4148        @ar_record.ferret_score = ferret_score 
     49        @use_record = !@ar_record.class.included_modules.include?(ActsAsFerret::RdigAdapter) 
    4250      end 
    4351      @ar_record 
  • trunk/plugin/acts_as_ferret/lib/ferret_server.rb

    r296 r317  
    145145 
    146146      # hides LocalIndex#rebuild_index to implement index versioning 
    147       def rebuild_index(clazz, *models) 
     147      def rebuild_index(clazz) 
     148        definition = ActsAsFerret::index_definition_for_class(clazz) 
     149        models = definition[:registered_models] 
    148150        with_class clazz do |clazz| 
    149           models = models.flatten.uniq.map(&:constantize) 
    150           models << clazz unless models.include?(clazz) 
    151151          index = new_index_for(clazz, models) 
    152152          reconnect_when_needed(clazz) do 
     
    154154            index.index_models models 
    155155          end 
    156           new_version = File.join clazz.aaf_configuration[:index_base_dir], Time.now.utc.strftime('%Y%m%d%H%M%S') 
     156          new_version = File.join definition[:index_base_dir], Time.now.utc.strftime('%Y%m%d%H%M%S') 
    157157          # create a unique directory name (needed for unit tests where  
    158158          # multiple rebuilds per second may occur) 
     
    164164           
    165165          File.rename index.options[:path], new_version 
    166           clazz.index_dir = new_version  
     166          ActsAsFerret::change_index_dir definition[:name], new_version  
    167167        end 
    168168      end 
  • trunk/plugin/acts_as_ferret/lib/index.rb

    r308 r317  
    1010      @logger = Logger.new("#{RAILS_ROOT}/log/ferret_index.log") 
    1111      @logger.level = ActiveRecord::Base.logger.level 
     12      @index_name = aaf_configuration[:name] 
    1213    end 
    1314     
  • trunk/plugin/acts_as_ferret/lib/instance_methods.rb

    r307 r317  
    152152    end 
    153153 
    154     def content_for_field_name(field, dynamic_boost = nil) 
    155       ar_field = aaf_configuration[:ferret_fields][field][:via] 
    156       field_data = self.send(ar_field) || self.instance_variable_get("@#{ar_field}") 
     154    def content_for_field_name(field, via = field, dynamic_boost = nil) 
     155      field_data = self.send(via) || self.instance_variable_get("@#{via}") 
    157156      if (dynamic_boost && boost_value = self.send(dynamic_boost)) 
    158157        field_data = Ferret::Field.new(field_data) 
  • trunk/plugin/acts_as_ferret/lib/local_index.rb

    r307 r317  
    4646    end 
    4747 
    48     # rebuilds the index from all records of the model class this index belongs 
    49     # to. Arguments can be given in shared index scenarios to name multiple 
    50     # model classes to include in the index 
    51     def rebuild_index(*models) 
    52       models << aaf_configuration[:class_name] unless models.include?(aaf_configuration[:class_name]) 
    53       models = models.flatten.uniq.map(&:constantize) 
     48    # rebuilds the index from all records of the model classes associated with this index 
     49    def rebuild_index 
     50      definition = ActsAsFerret::index_definition(@index_name) 
     51      models = definition[:registered_models] 
    5452      logger.debug "rebuild index: #{models.inspect}" 
    55       index = Ferret::Index::Index.new(aaf_configuration[:ferret].dup.update(:auto_flush  => false,  
    56                                                                              :field_infos => ActsAsFerret::field_infos(models), 
    57                                                                              :create      => true)) 
    58       index.batch_size = aaf_configuration[:reindex_batch_size] 
     53      self.close 
     54      index = Ferret::Index::Index.new(definition[:ferret].dup.update(:auto_flush  => false,  
     55                                                                      # TODO fieldinfos sollten jetzt 
     56                                                                      # auch aus neuer config kommen! 
     57                                                                      :field_infos => ActsAsFerret::field_infos(models), 
     58                                                                      :create      => true)) 
     59      index.batch_size = definition[:reindex_batch_size] 
    5960      index.logger = logger 
    6061      index.index_models models 
    61     end 
    62  
    63     def bulk_index(ids, options) 
    64       ferret_index.bulk_index(aaf_configuration[:class_name].constantize, ids, options) 
     62      ActsAsFerret::change_index_dir @index_name, definition[:ferret][:path] 
     63    end 
     64 
     65    def bulk_index(class_name, ids, options) 
     66      ferret_index.bulk_index(class_name.constantize, ids, options) 
    6567    end 
    6668 
     
    109111      logger.debug "query: #{ferret_index.process_query query}" if logger.debug? 
    110112      lazy_fields = determine_lazy_fields options 
     113      logger.debug "lazy_fields: #{lazy_fields}" 
    111114 
    112115      total_hits = index.search_each(query, options) do |hit, score| 
  • trunk/plugin/acts_as_ferret/lib/multi_index.rb

    r198 r317  
    6868              @sub_readers = @model_classes.map { |clazz|  
    6969                begin 
    70                   reader = Ferret::Index::IndexReader.new(clazz.aaf_configuration[:index_dir]) 
     70                  reader = Ferret::Index::IndexReader.new(ActsAsFerret::index_definition(clazz)[:index_dir]) 
    7171                rescue Exception 
    72                   raise "error opening #{clazz.aaf_configuration[:index_dir]}: #{$!}" 
     72                  raise "error opening reader on index for class #{clazz.inspect}: #{$!}" 
    7373                end 
    7474              } 

To edit pages or tickets please login with username/password: aaf/aaf