* wl/wl-summary.el (wl-summary-mode): Check with fboundp before calling `make-local...
[elisp/wanderlust.git] / elmo / modb.el
1 ;;; modb.el --- Message Orchestration DataBase.
2
3 ;; Copyright (C) 2003 Yuuichi Teranishi <teranisi@gohome.org>
4
5 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
6 ;;      Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
7 ;; Keywords: mail, net news
8
9 ;; This file is part of ELMO (Elisp Library for Message Orchestration).
10
11 ;; This program is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15 ;;
16 ;; This program is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20 ;;
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25 ;;
26
27 ;;; Commentary:
28 ;;
29
30 ;;; Code:
31 ;;
32
33 (eval-when-compile (require 'cl))
34
35 (require 'luna)
36 (require 'modb-entity)
37
38 (eval-and-compile
39   (luna-define-class modb-generic () (location         ; location for save.
40                                       message-modified ; message is modified.
41                                       flag-modified    ; flag is modified.
42                                       mime-charset     ; for encode & decode.
43                                       ))
44   (luna-define-internal-accessors 'modb-generic))
45
46 (luna-define-generic elmo-msgdb-load (msgdb)
47   "Load the MSGDB.")
48
49 (luna-define-generic elmo-msgdb-save (msgdb)
50   "Save the MSGDB.")
51
52 (luna-define-generic elmo-msgdb-location (msgdb)
53   "Return the location of MSGDB.")
54
55 (luna-define-generic elmo-msgdb-message-modified-p (msgdb)
56   "Return non-nil if message is modified.")
57
58 (luna-define-generic elmo-msgdb-flag-modified-p (msgdb)
59   "Return non-nil if flag is modified.")
60
61 (luna-define-generic elmo-msgdb-append (msgdb msgdb-append)
62   "Append the MSGDB-APPEND to the MSGDB.
63 Return a list of messages which have duplicated message-id.")
64
65 (luna-define-generic elmo-msgdb-clear (msgdb)
66   "Clear the MSGDB structure.")
67
68 (luna-define-generic elmo-msgdb-length (msgdb)
69   "Return number of messages in the MSGDB")
70
71 (luna-define-generic elmo-msgdb-flag-available-p (msgdb flag)
72   "Return non-nil when FLAG is available.")
73
74 (luna-define-generic elmo-msgdb-flags (msgdb number)
75   "Return a list of flag which corresponds to the message with NUMBER.")
76
77 (luna-define-generic elmo-msgdb-set-flag (msgdb number flag)
78   "Set message flag.
79 MSGDB is the ELMO msgdb.
80 NUMBER is a message number to set flag.
81 FLAG is a symbol which is one of the following:
82   `new'       ... Message which is new.
83   `unread'    ... Message which is not read.
84   `important' ... Message which is important.
85   `answered'  ... Message which is answered.
86   `cached'    ... Message which is cached.
87 'sugar' flag:
88   `read'      ... Message which is already read.
89   `uncached'  ... Message which is not cached.")
90
91 (luna-define-generic elmo-msgdb-unset-flag (msgdb number flag)
92   "Unset message flag.
93 MSGDB is the ELMO msgdb.
94 NUMBER is a message number to set flag.
95 FLAG is a symbol which is one of the following:
96   `new'       ... Message which is new.
97   `unread'    ... Message which is not read.
98   `important' ... Message which is important.
99   `answered'  ... Message which is answered.
100   `cached'    ... Message which is cached.
101 'sugar' flag:
102   `read'      ... Message which is already read.
103   `uncached'  ... Message which is not cached.
104   `all'       ... Remove all flags.")
105
106 (luna-define-generic elmo-msgdb-flag-count (msgdb)
107   "Return a list of cons cell as (flag . count).
108 The count is number of message which is set flag in the MSGDB.")
109
110 (luna-define-generic elmo-msgdb-list-messages (msgdb)
111   "Return a list of message numbers in the MSGDB.")
112
113 (luna-define-generic elmo-msgdb-list-flagged (msgdb flag)
114   "Return a list of message numbers which is set FLAG in the MSGDB.")
115
116 (luna-define-generic elmo-msgdb-search (msgdb condition &optional numbers)
117   "Search and return list of message numbers.
118 MSGDB is the ELMO msgdb structure.
119 CONDITION is a condition structure for searching.
120 If optional argument NUMBERS is specified and is a list of message numbers,
121 messages are searched from the list.
122 Return t if the condition is unsupported.")
123
124 (luna-define-generic elmo-msgdb-match-condition (msgdb condition number
125                                                        &optional numbers)
126   "Check whether the condition of the message is satisfied or not.
127 MSGDB is the msgdb to search from.
128 CONDITION is the search condition.
129 NUMBER is the message number to check.
130 If optional argument NUMBERS is specified and is a list of message numbers,
131 messages are searched from the list.
132 Return CONDITION itself if no entity exists in msgdb.")
133
134 (luna-define-generic elmo-msgdb-append-entity (msgdb entity &optional flags)
135   "Append a ENTITY with FLAGS into the MSGDB.
136 Return non-nil if message-id of entity is duplicated.")
137
138 (luna-define-generic elmo-msgdb-update-entity (msgdb entity values)
139   "Update a ENTITY with VALUES into the MSGDB.
140 VALUES is an alist of field-name and field-value.")
141
142 (luna-define-generic elmo-msgdb-delete-messages (msgdb numbers)
143   "Delete messages which are contained NUMBERS from MSGDB.
144 Return non-nil if messages is deleted successfully.")
145
146 (luna-define-generic elmo-msgdb-sort-entities (msgdb predicate
147                                                      &optional app-data)
148   "Sort entities of MSGDB, comparing with PREDICATE.
149 PREDICATE is called with two entities and APP-DATA.
150 Should return non-nil if the first entity is \"less\" than the second.")
151
152 (luna-define-generic elmo-msgdb-message-number (msgdb message-id)
153   "Get message number from MSGDB which corresponds to MESSAGE-ID.")
154
155 (luna-define-method elmo-msgdb-message-number ((msgdb modb-generic)
156                                                message-id)
157   (elmo-message-entity-number
158    (elmo-msgdb-message-entity msgdb message-id)))
159
160 (luna-define-generic elmo-msgdb-message-entity (msgdb key)
161   "Return the message-entity structure which matches to the KEY.
162 KEY is a number or a string.
163 A number is for message number in the MSGDB.
164 A string is for message-id of the message.")
165
166 (luna-define-generic elmo-msgdb-message-field (msgdb number field
167                                                      &optional type)
168   "Get message field value in the MSGDB.
169 NUMBER is a number of the message.
170 FIELD is a symbol of the field.
171 If optional argument TYPE is specified, return converted value.")
172
173 (luna-define-method elmo-msgdb-message-field ((msgdb modb-generic)
174                                               number field &optional type)
175   (elmo-message-entity-field (elmo-msgdb-message-entity msgdb number)
176                              field type))
177
178 (luna-define-generic elmo-msgdb-message-entity-handler (msgdb)
179   "Get modb entity handler instance which corresponds to the MSGDB.")
180
181 ;;; generic implement
182 ;;
183 (luna-define-method elmo-msgdb-load ((msgdb modb-generic))
184   t)
185
186 (luna-define-method elmo-msgdb-location ((msgdb modb-generic))
187   (modb-generic-location-internal msgdb))
188
189 (luna-define-method elmo-msgdb-message-modified-p ((msgdb modb-generic))
190   (modb-generic-message-modified-internal msgdb))
191
192 (luna-define-method elmo-msgdb-flag-modified-p ((msgdb modb-generic))
193   (modb-generic-flag-modified-internal msgdb))
194
195 (luna-define-method elmo-msgdb-append ((msgdb modb-generic) msgdb-append)
196   (let (duplicates)
197     (dolist (number (elmo-msgdb-list-messages msgdb-append))
198       (when (elmo-msgdb-append-entity
199              msgdb
200              (elmo-msgdb-message-entity msgdb-append number)
201              (elmo-msgdb-flags msgdb-append number))
202         (setq duplicates (cons number duplicates))))
203     duplicates))
204
205 (luna-define-method elmo-msgdb-clear ((msgdb modb-generic))
206   (modb-generic-set-message-modified-internal msgdb nil)
207   (modb-generic-set-flag-modified-internal msgdb nil))
208
209 (luna-define-method elmo-msgdb-length ((msgdb modb-generic))
210   0)
211
212 (luna-define-method elmo-msgdb-search ((msgdb modb-generic)
213                                        condition &optional numbers)
214   t)
215
216 (luna-define-method elmo-msgdb-match-condition ((msgdb modb-generic)
217                                                 condition
218                                                 number
219                                                 &optional numbers)
220   (let ((entity (elmo-msgdb-message-entity msgdb number)))
221     (if entity
222         (elmo-condition-match
223          condition
224          #'elmo-msgdb-match-condition-primitive
225          (list msgdb number entity
226                (or numbers (elmo-msgdb-list-messages msgdb))))
227       condition)))
228
229 (defun elmo-msgdb-match-condition-primitive (condition msgdb number entity
230                                                        population)
231   (let ((key (elmo-filter-key condition))
232         (case-fold-search t))
233     (cond
234      ((string= key "last")
235       (<= (length (memq number population))
236           (string-to-number (elmo-filter-value condition))))
237      ((string= key "first")
238       (< (- (length population)
239             (length (memq number population)))
240          (string-to-number (elmo-filter-value condition))))
241      ((string= key "flag")
242       (let ((flags (elmo-msgdb-flags msgdb number)))
243         (cond ((string= (elmo-filter-value condition) "any")
244                (and flags (not (equal flags '(cached)))))
245               ((string= (elmo-filter-value condition) "digest")
246                (catch 'found
247                  (dolist (flag flags)
248                    (when (or (memq flag elmo-digest-flags)
249                              (elmo-global-flag-p flag))
250                      (throw 'found t)))))
251               ((string= (elmo-filter-value condition) "read")
252                (not (memq 'read flags)))
253               (t
254                (memq (intern (elmo-filter-value condition)) flags)))))
255      (t
256       (elmo-msgdb-message-match-condition (elmo-message-entity-handler entity)
257                                           condition entity)))))
258
259 (luna-define-method elmo-msgdb-update-entity ((msgdb modb-generic)
260                                               entity values)
261   (when (elmo-msgdb-message-entity-update-fields
262          (elmo-message-entity-handler entity)
263          entity values)
264     (modb-generic-set-message-modified-internal msgdb t)
265     t))
266
267 (luna-define-method elmo-msgdb-message-entity-handler ((msgdb modb-generic))
268   (or modb-entity-default-cache-internal
269       (setq modb-entity-default-cache-internal
270             (luna-make-entity modb-entity-default-handler))))
271
272 ;; for on demand loading
273 (provide 'modb-generic)
274
275 (require 'product)
276 (product-provide (provide 'modb) (require 'elmo-version))
277
278 ;;; modb.el ends here