X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=elmo%2Fmodb.el;h=6574e63f1efb0cd41b23e069a3f414bdadd91aa4;hb=13ea09ab66b44b1a3b0971e1a24ce0da47a6ca0a;hp=d8e564fb861a8fc1bdc69a9f51f6edfff14ebb61;hpb=aeafc826de87afdfb39a5b9181c147a7ddf3bbeb;p=elisp%2Fwanderlust.git diff --git a/elmo/modb.el b/elmo/modb.el index d8e564f..6574e63 100644 --- a/elmo/modb.el +++ b/elmo/modb.el @@ -33,11 +33,13 @@ (eval-when-compile (require 'cl)) (require 'luna) +(require 'modb-entity) (eval-and-compile - (luna-define-class modb-generic () (location ; location for save. + (luna-define-class modb-generic () (location ; location for save. message-modified ; message is modified. flag-modified ; flag is modified. + mime-charset ; for encode & decode. )) (luna-define-internal-accessors 'modb-generic)) @@ -66,6 +68,9 @@ Return a list of messages which have duplicated message-id.") (luna-define-generic elmo-msgdb-length (msgdb) "Return number of messages in the MSGDB") +(luna-define-generic elmo-msgdb-flag-available-p (msgdb flag) + "Return non-nil when FLAG is available.") + (luna-define-generic elmo-msgdb-flags (msgdb number) "Return a list of flag which corresponds to the message with NUMBER.") @@ -74,22 +79,33 @@ Return a list of messages which have duplicated message-id.") MSGDB is the ELMO msgdb. NUMBER is a message number to set flag. FLAG is a symbol which is one of the following: -`new' ... Message which is new. -`read' ... Message which is already read. -`important' ... Message which is important. -`answered' ... Message which is answered. -`cached' ... Message which is cached.") + `new' ... Message which is new. + `unread' ... Message which is not read. + `important' ... Message which is important. + `answered' ... Message which is answered. + `cached' ... Message which is cached. +'sugar' flag: + `read' ... Message which is already read. + `uncached' ... Message which is not cached.") (luna-define-generic elmo-msgdb-unset-flag (msgdb number flag) "Unset message flag. MSGDB is the ELMO msgdb. NUMBER is a message number to set flag. FLAG is a symbol which is one of the following: -`new' ... Message which is new. -`read' ... Message which is already read. -`important' ... Message which is important. -`answered' ... Message which is answered. -`cached' ... Message which is cached.") + `new' ... Message which is new. + `unread' ... Message which is not read. + `important' ... Message which is important. + `answered' ... Message which is answered. + `cached' ... Message which is cached. +'sugar' flag: + `read' ... Message which is already read. + `uncached' ... Message which is not cached. + `all' ... Remove all flags.") + +(luna-define-generic elmo-msgdb-flag-count (msgdb) + "Return a list of cons cell as (flag . count). +The count is number of message which is set flag in the MSGDB.") (luna-define-generic elmo-msgdb-list-messages (msgdb) "Return a list of message numbers in the MSGDB.") @@ -97,19 +113,35 @@ FLAG is a symbol which is one of the following: (luna-define-generic elmo-msgdb-list-flagged (msgdb flag) "Return a list of message numbers which is set FLAG in the MSGDB.") -;;; (luna-define-generic elmo-msgdb-search (msgdb condition &optional numbers) -;;; "Search and return list of message numbers. -;;; MSGDB is the ELMO msgdb structure. -;;; CONDITION is a condition structure for searching. -;;; If optional argument NUMBERS is specified and is a list of message numbers, -;;; messages are searched from the list.") +(luna-define-generic elmo-msgdb-search (msgdb condition &optional numbers) + "Search and return list of message numbers. +MSGDB is the ELMO msgdb structure. +CONDITION is a condition structure for searching. +If optional argument NUMBERS is specified and is a list of message numbers, +messages are searched from the list. +Return t if the condition is unsupported.") + +(luna-define-generic elmo-msgdb-match-condition (msgdb condition number + &optional numbers) + "Check whether the condition of the message is satisfied or not. +MSGDB is the msgdb to search from. +CONDITION is the search condition. +NUMBER is the message number to check. +If optional argument NUMBERS is specified and is a list of message numbers, +messages are searched from the list. +Return CONDITION itself if no entity exists in msgdb.") (luna-define-generic elmo-msgdb-append-entity (msgdb entity &optional flags) "Append a ENTITY with FLAGS into the MSGDB. Return non-nil if message-id of entity is duplicated.") +(luna-define-generic elmo-msgdb-update-entity (msgdb entity values) + "Update a ENTITY with VALUES into the MSGDB. +VALUES is an alist of field-name and field-value.") + (luna-define-generic elmo-msgdb-delete-messages (msgdb numbers) - "Delete messages which are contained NUMBERS from MSGDB.") + "Delete messages which are contained NUMBERS from MSGDB. +Return non-nil if messages is deleted successfully.") (luna-define-generic elmo-msgdb-sort-entities (msgdb predicate &optional app-data) @@ -117,80 +149,34 @@ Return non-nil if message-id of entity is duplicated.") PREDICATE is called with two entities and APP-DATA. Should return non-nil if the first entity is \"less\" than the second.") +(luna-define-generic elmo-msgdb-message-number (msgdb message-id) + "Get message number from MSGDB which corresponds to MESSAGE-ID.") + +(luna-define-method elmo-msgdb-message-number ((msgdb modb-generic) + message-id) + (elmo-message-entity-number + (elmo-msgdb-message-entity msgdb message-id))) + (luna-define-generic elmo-msgdb-message-entity (msgdb key) "Return the message-entity structure which matches to the KEY. KEY is a number or a string. A number is for message number in the MSGDB. A string is for message-id of the message.") -;; Message entity handling. -(defvar modb-cache-internal nil) -(defun elmo-message-entity-db (entity) - "Get modb instance which corresponds to the ENTITY." - (if (or (null (car entity)) - (stringp (car entity))) - ;; Transitional implementation for modb-legacy. - (or modb-cache-internal - (progn - (require 'modb-legacy) - (setq modb-cache-internal (luna-make-entity 'modb-legacy)))) - ;; XXX Next generation entity structure...not decided yet. - (car entity))) - -(luna-define-generic elmo-msgdb-make-message-entity (msgdb - &rest args) - "Make a message entity for MSGDB.") - -(luna-define-generic elmo-msgdb-message-entity-number (msgdb entity) - "Number of the ENTITY.") - -(luna-define-generic elmo-msgdb-message-entity-set-number (msgdb entity number) - "Set number of the ENTITY.") - -(luna-define-generic elmo-msgdb-message-entity-field (msgdb - entity field - &optional decode) - "Retrieve field value of the message entity. -MSGDB is the msgdb structure. -ENTITY is the message entity structure. +(luna-define-generic elmo-msgdb-message-field (msgdb number field + &optional type) + "Get message field value in the MSGDB. +NUMBER is a number of the message. FIELD is a symbol of the field. -If optional DECODE is no-nil, the field value is decoded.") +If optional argument TYPE is specified, return converted value.") -(luna-define-generic elmo-msgdb-message-entity-set-field (msgdb - entity field value) - "Set the field value of the message entity. -MSGDB is the msgdb structure. -ENTITY is the message entity structure. -FIELD is a symbol of the field. -VALUE is the field value to set.") - -(luna-define-generic elmo-msgdb-copy-message-entity (msgdb entity) - "Copy message entity. -MSGDB is the msgdb structure. -ENTITY is the message entity structure.") - -(luna-define-generic elmo-msgdb-create-message-entity-from-file (msgdb number - file) - "Create message entity from file. -MSGDB is the msgdb structure. -NUMBER is the number of the newly created message entity. -FILE is the message file.") - -(luna-define-generic elmo-msgdb-create-message-entity-from-buffer (msgdb - number - &rest args) - "Create message entity from current buffer. -NUMBER is the number of the newly created message entity. -Rest of the ARGS is a plist of message entity field for initial value. -Header region is supposed to be narrowed.") - -;; Transitional interface. -(luna-define-generic elmo-msgdb-match-condition-internal (msgdb - condition - entity - flags - numbers) - "Return non-nil when the entity matches the condition.") +(luna-define-method elmo-msgdb-message-field ((msgdb modb-generic) + number field &optional type) + (elmo-message-entity-field (elmo-msgdb-message-entity msgdb number) + field type)) + +(luna-define-generic elmo-msgdb-message-entity-handler (msgdb) + "Get modb entity handler instance which corresponds to the MSGDB.") ;;; generic implement ;; @@ -223,46 +209,65 @@ Header region is supposed to be narrowed.") (luna-define-method elmo-msgdb-length ((msgdb modb-generic)) 0) -;; Generic method. -(luna-define-method elmo-msgdb-create-message-entity-from-file - ((msgdb modb-generic) number file) - (let (insert-file-contents-pre-hook ; To avoid autoconv-xmas... - insert-file-contents-post-hook header-end - (attrib (file-attributes file)) - ret-val size mtime) - (with-temp-buffer - (if (not (file-exists-p file)) - () - (setq size (nth 7 attrib)) - (setq mtime (timezone-make-date-arpa-standard - (current-time-string (nth 5 attrib)) (current-time-zone))) - ;; insert header from file. - (catch 'done - (condition-case nil - (elmo-msgdb-insert-file-header file) - (error (throw 'done nil))) - (goto-char (point-min)) - (setq header-end - (if (re-search-forward "\\(^--.*$\\)\\|\\(\n\n\\)" nil t) - (point) - (point-max))) - (narrow-to-region (point-min) header-end) - (elmo-msgdb-create-message-entity-from-buffer - msgdb number :size size :date mtime)))))) - -;; Dummy message-entity methods. -(luna-define-method elmo-msgdb-make-message-entity ((msgdb modb-generic) - args) - (cons msgdb args)) - -(luna-define-method elmo-msgdb-message-entity-field ((msgdb modb-generic) - entity field - &optional decode) - (plist-get (cdr entity) (intern (concat ":" (symbol-name field))))) - -(luna-define-method elmo-msgdb-message-entity-number ((msgdb modb-generic) - entity) - (plist-get (cdr entity) :number)) +(luna-define-method elmo-msgdb-search ((msgdb modb-generic) + condition &optional numbers) + t) + +(luna-define-method elmo-msgdb-match-condition ((msgdb modb-generic) + condition + number + &optional numbers) + (let ((entity (elmo-msgdb-message-entity msgdb number))) + (if entity + (elmo-condition-match + condition + #'elmo-msgdb-match-condition-primitive + (list msgdb number entity + (or numbers (elmo-msgdb-list-messages msgdb)))) + condition))) + +(defun elmo-msgdb-match-condition-primitive (condition msgdb number entity + population) + (let ((key (elmo-filter-key condition)) + (case-fold-search t)) + (cond + ((string= key "last") + (<= (length (memq number population)) + (string-to-number (elmo-filter-value condition)))) + ((string= key "first") + (< (- (length population) + (length (memq number population))) + (string-to-number (elmo-filter-value condition)))) + ((string= key "flag") + (let ((flags (elmo-msgdb-flags msgdb number))) + (cond ((string= (elmo-filter-value condition) "any") + (and flags (not (equal flags '(cached))))) + ((string= (elmo-filter-value condition) "digest") + (catch 'found + (dolist (flag flags) + (when (or (memq flag elmo-digest-flags) + (elmo-global-flag-p flag)) + (throw 'found t))))) + ((string= (elmo-filter-value condition) "read") + (not (memq 'read flags))) + (t + (memq (intern (elmo-filter-value condition)) flags))))) + (t + (elmo-msgdb-message-match-condition (elmo-message-entity-handler entity) + condition entity))))) + +(luna-define-method elmo-msgdb-update-entity ((msgdb modb-generic) + entity values) + (when (elmo-msgdb-message-entity-update-fields + (elmo-message-entity-handler entity) + entity values) + (modb-generic-set-message-modified-internal msgdb t) + t)) + +(luna-define-method elmo-msgdb-message-entity-handler ((msgdb modb-generic)) + (or modb-entity-default-cache-internal + (setq modb-entity-default-cache-internal + (luna-make-entity modb-entity-default-handler)))) ;; for on demand loading (provide 'modb-generic)