]> git.cworth.org Git - sup/blob - lib/sup/index.rb
Merge branch 'locking-refactor'
[sup] / lib / sup / index.rb
1 ## Index interface, subclassed by Ferret indexer.
2
3 require 'fileutils'
4
5 begin
6   require 'chronic'
7   $have_chronic = true
8 rescue LoadError => e
9   debug "optional 'chronic' library not found; date-time query restrictions disabled"
10   $have_chronic = false
11 end
12
13 module Redwood
14
15 class BaseIndex
16   include InteractiveLock
17
18   class LockError < StandardError
19     def initialize h
20       @h = h
21     end
22
23     def method_missing m; @h[m.to_s] end
24   end
25
26   include Singleton
27
28   def initialize dir=BASE_DIR
29     @dir = dir
30     @lock = Lockfile.new lockfile, :retries => 0, :max_age => nil
31   end
32
33   def lockfile; File.join @dir, "lock" end
34
35   def lock
36     debug "locking #{lockfile}..."
37     begin
38       @lock.lock
39     rescue Lockfile::MaxTriesLockError
40       raise LockError, @lock.lockinfo_on_disk
41     end
42   end
43
44   def start_lock_update_thread
45     @lock_update_thread = Redwood::reporting_thread("lock update") do
46       while true
47         sleep 30
48         @lock.touch_yourself
49       end
50     end
51   end
52
53   def stop_lock_update_thread
54     @lock_update_thread.kill if @lock_update_thread
55     @lock_update_thread = nil
56   end
57
58   def unlock
59     if @lock && @lock.locked?
60       debug "unlocking #{lockfile}..."
61       @lock.unlock
62     end
63   end
64
65   def load
66     SourceManager.load_sources
67     load_index
68   end
69
70   def save
71     debug "saving index and sources..."
72     FileUtils.mkdir_p @dir unless File.exists? @dir
73     SourceManager.save_sources
74     save_index
75   end
76
77   def load_index
78     unimplemented
79   end
80
81   def add_message m; unimplemented end
82   def update_message m; unimplemented end
83   def update_message_state m; unimplemented end
84
85   def save_index fn
86     unimplemented
87   end
88
89   def contains_id? id
90     unimplemented
91   end
92
93   def contains? m; contains_id? m.id end
94
95   def size
96     unimplemented
97   end
98
99   def empty?; size == 0 end
100
101   ## Yields a message-id and message-building lambda for each
102   ## message that matches the given query, in descending date order.
103   ## You should probably not call this on a block that doesn't break
104   ## rather quickly because the results can be very large.
105   def each_id_by_date query={}
106     unimplemented
107   end
108
109   ## Return the number of matches for query in the index
110   def num_results_for query={}
111     unimplemented
112   end
113
114   ## yield all messages in the thread containing 'm' by repeatedly
115   ## querying the index. yields pairs of message ids and
116   ## message-building lambdas, so that building an unwanted message
117   ## can be skipped in the block if desired.
118   ##
119   ## only two options, :limit and :skip_killed. if :skip_killed is
120   ## true, stops loading any thread if a message with a :killed flag
121   ## is found.
122   def each_message_in_thread_for m, opts={}
123     unimplemented
124   end
125
126   ## Load message with the given message-id from the index
127   def build_message id
128     unimplemented
129   end
130
131   ## Delete message with the given message-id from the index
132   def delete id
133     unimplemented
134   end
135
136   ## Given an array of email addresses, return an array of Person objects that
137   ## have sent mail to or received mail from any of the given addresses.
138   def load_contacts email_addresses, h={}
139     unimplemented
140   end
141
142   ## Yield each message-id matching query
143   def each_id query={}
144     unimplemented
145   end
146
147   ## Yield each message matching query
148   def each_message query={}, &b
149     each_id query do |id|
150       yield build_message(id)
151     end
152   end
153
154   ## Implementation-specific optimization step
155   def optimize
156     unimplemented
157   end
158
159   ## Return the id source of the source the message with the given message-id
160   ## was synced from
161   def source_for_id id
162     unimplemented
163   end
164
165   class ParseError < StandardError; end
166
167   ## parse a query string from the user. returns a query object
168   ## that can be passed to any index method with a 'query'
169   ## argument.
170   ##
171   ## raises a ParseError if something went wrong.
172   def parse_query s
173     unimplemented
174   end
175 end
176
177 index_name = ENV['SUP_INDEX'] || $config[:index] || DEFAULT_INDEX
178 case index_name
179   when "xapian"; require "sup/xapian_index"
180   when "ferret"; require "sup/ferret_index"
181   else fail "unknown index type #{index_name.inspect}"
182 end
183 Index = Redwood.const_get "#{index_name.capitalize}Index"
184 debug "using index #{Index.name}"
185
186 end