error handling
[acts_as_ferret.git] / lib / multi_index.rb
blob227c48c5bcfa2e4cd0f85f534393165281b8969f
1 module ActsAsFerret #:nodoc:
2   
3       # this class is not threadsafe
4       class MultiIndex
5         
6         def initialize(model_classes, options = {})
7           @model_classes = model_classes
8           # ensure all models indexes exist
9           @model_classes.each { |m| m.aaf_index.ensure_index_exists }
10           default_fields = @model_classes.inject([]) do |fields, c| 
11             fields + c.aaf_configuration[:ferret][:default_field] 
12           end
13           @options = { 
14             :default_field => default_fields
15           }.update(options)
16         end
17         
18         def search(query, options={})
19           #puts "querystring: #{query.to_s}"
20           query = process_query(query)
21           #puts "parsed query: #{query.to_s}"
22           searcher.search(query, options)
23         end
25         def search_each(query, options = {}, &block)
26           query = process_query(query)
27           searcher.search_each(query, options, &block)
28         end
30         # checks if all our sub-searchers still are up to date
31         def latest?
32           return false unless @reader
33           # segfaults with 0.10.4 --> TODO report as bug @reader.latest?
34           @sub_readers.each do |r| 
35             return false unless r.latest? 
36           end
37           true
38         end
39          
40         def searcher
41           ensure_searcher
42           @searcher
43         end
44         
45         def doc(i)
46           searcher[i]
47         end
48         alias :[] :doc
49         
50         def query_parser
51           @query_parser ||= Ferret::QueryParser.new(@options)
52         end
53         
54         def process_query(query)
55           query = query_parser.parse(query) if query.is_a?(String)
56           return query
57         end
59         def close
60           @searcher.close if @searcher
61           @reader.close if @reader
62         end
64         protected
66           def ensure_searcher
67             unless latest?
68               @sub_readers = @model_classes.map { |clazz| 
69                 begin
70                   reader = Ferret::Index::IndexReader.new(clazz.aaf_configuration[:index_dir])
71                 rescue Exception
72                   raise "error opening #{clazz.aaf_configuration[:index_dir]}: #{$!}"
73                 end
74               }
75               close
76               @reader = Ferret::Index::IndexReader.new(@sub_readers)
77               @searcher = Ferret::Search::Searcher.new(@reader)
78             end
79           end
81       end # of class MultiIndex
83 end