(eval-when-compile (require 'cl))
(require 'elmo-util)
-(require 'mime)
(require 'modb)
(defcustom modb-standard-divide-number 500
(number-list ; sorted list of message numbers.
entity-map ; number, msg-id -> entity mapping.
flag-map ; number -> flag-list mapping
+ flag-count ; list of (FLAG . COUNT)
))
(luna-define-internal-accessors 'modb-standard))
(if (eq 'autoload (car-safe entity))
(cddr entity)
(elmo-msgdb-message-entity-field
- (elmo-message-entity-db entity)
+ (elmo-message-entity-handler entity)
entity 'message-id)))
(defsubst modb-standard-entity-map (modb)
(throw 'done t))
(setq check-flags (cdr check-flags)))))
+(defsubst modb-standard-countup-flags (modb flags &optional delta)
+ (let ((flag-count (modb-standard-flag-count-internal modb))
+ (delta (or delta 1))
+ elem)
+ (dolist (flag flags)
+ (if (setq elem (assq flag flag-count))
+ (setcdr elem (+ (cdr elem) delta))
+ (setq flag-count (cons (cons flag delta) flag-count))))
+ (modb-standard-set-flag-count-internal modb flag-count)))
;; save and load functions
(defun modb-standard-load-msgid (modb path)
(elmo-make-hash (elmo-msgdb-length modb)))))
(dolist (info (elmo-object-load
(expand-file-name modb-standard-flag-filename path)))
+ (modb-standard-countup-flags modb (cdr info))
(elmo-set-hash-val (modb-standard-key (car info)) info table))
(modb-standard-set-flag-map-internal modb table)))
path)))
(elmo-set-hash-val (modb-standard-key
(elmo-msgdb-message-entity-number
- (elmo-message-entity-db entity)
+ (elmo-message-entity-handler entity)
entity))
entity
table)
(elmo-set-hash-val (elmo-msgdb-message-entity-field
- (elmo-message-entity-db entity)
+ (elmo-message-entity-handler entity)
entity 'message-id)
entity
table))
(symbol-value atom)
table))
(modb-standard-flag-map msgdb-append)))
+ ;; flag-count
+ (dolist (pair (modb-standard-flag-count-internal msgdb-append))
+ (modb-standard-countup-flags msgdb (list (car pair)) (cdr pair)))
;; modification flags
(dolist (number (modb-standard-number-list-internal msgdb-append))
(modb-standard-set-message-modified msgdb number)
(luna-define-method elmo-msgdb-clear :after ((msgdb modb-standard))
(modb-standard-set-number-list-internal msgdb nil)
(modb-standard-set-entity-map-internal msgdb nil)
- (modb-standard-set-flag-map-internal msgdb nil))
+ (modb-standard-set-flag-map-internal msgdb nil)
+ (modb-standard-set-flag-count-internal msgdb nil))
(luna-define-method elmo-msgdb-length ((msgdb modb-standard))
(length (modb-standard-number-list-internal msgdb)))
(uncached
(elmo-msgdb-unset-flag msgdb number 'cached))
(t
- (let* ((cur-flags (modb-standard-message-flags msgdb number))
- (new-flags (copy-sequence cur-flags)))
- (and (memq 'new new-flags)
- (setq new-flags (delq 'new new-flags)))
- (or (memq flag new-flags)
- (setq new-flags (cons flag new-flags)))
- (when (and (eq flag 'unread)
- (memq 'answered new-flags))
- (setq new-flags (delq 'answered new-flags)))
- (unless (equal new-flags cur-flags)
+ (let ((cur-flags (modb-standard-message-flags msgdb number))
+ new-flags diff)
+ (unless (memq flag cur-flags)
+ (setq new-flags (cons flag cur-flags))
+ (setq diff (elmo-list-diff new-flags cur-flags))
+ (modb-standard-countup-flags msgdb (car diff))
+ (modb-standard-countup-flags msgdb (cadr diff) -1)
(elmo-set-hash-val (modb-standard-key number)
(cons number new-flags)
(modb-standard-flag-map msgdb))
(elmo-msgdb-set-flag msgdb number 'unread))
(uncached
(elmo-msgdb-set-flag msgdb number 'cached))
+ (all
+ (modb-standard-countup-flags msgdb
+ (modb-standard-message-flags msgdb number)
+ -1)
+ (elmo-clear-hash-val (modb-standard-key number)
+ (modb-standard-flag-map msgdb)))
(t
- (let* ((cur-flags (modb-standard-message-flags msgdb number))
- (new-flags (copy-sequence cur-flags)))
- (and (memq 'new new-flags)
- (setq new-flags (delq 'new new-flags)))
- (and (memq flag new-flags)
- (setq new-flags (delq flag new-flags)))
- (when (and (eq flag 'unread)
- (memq 'answered new-flags))
- (setq new-flags (delq 'answered new-flags)))
- (unless (equal new-flags cur-flags)
+ (let ((cur-flags (modb-standard-message-flags msgdb number))
+ new-flags diff)
+ (when (memq flag cur-flags)
+ (setq new-flags (delq flag (copy-sequence cur-flags)))
+ (setq diff (elmo-list-diff new-flags cur-flags))
+ (modb-standard-countup-flags msgdb (car diff))
+ (modb-standard-countup-flags msgdb (cadr diff) -1)
(elmo-set-hash-val (modb-standard-key number)
(cons number new-flags)
(modb-standard-flag-map msgdb))
- (modb-standard-set-flag-modified msgdb number))))))
+ (modb-standard-set-flag-modified msgdb number))
+ (when (eq flag 'unread)
+ (elmo-msgdb-unset-flag msgdb number 'new))))))
+
+(luna-define-method elmo-msgdb-flag-count ((msgdb modb-standard))
+ (modb-standard-flag-count-internal msgdb))
(luna-define-method elmo-msgdb-list-messages ((msgdb modb-standard))
(copy-sequence
(modb-standard-number-list-internal msgdb)))
(luna-define-method elmo-msgdb-list-flagged ((msgdb modb-standard) flag)
- (let (entry matched)
+ (let ((flags (case flag
+ (digest
+ (nconc '(unread)(elmo-get-global-flags t t)))
+ (any
+ (nconc '(unread answered)(elmo-get-global-flags t t)))))
+ entry matched)
(case flag
(read
(dolist (number (modb-standard-number-list-internal msgdb))
(unless (memq 'unread (modb-standard-message-flags msgdb number))
(setq matched (cons number matched)))))
- (digest
- (mapatoms
- (lambda (atom)
- (setq entry (symbol-value atom))
- (when (modb-standard-match-flags '(unread important)
- (cdr entry))
- (setq matched (cons (car entry) matched))))
- (modb-standard-flag-map msgdb)))
- (any
+ ((digest any)
(mapatoms
(lambda (atom)
(setq entry (symbol-value atom))
- (when (modb-standard-match-flags '(unread important answered)
- (cdr entry))
+ (when (modb-standard-match-flags flags (cdr entry))
(setq matched (cons (car entry) matched))))
(modb-standard-flag-map msgdb)))
(t
(modb-standard-flag-map msgdb))))
matched))
+(luna-define-method elmo-msgdb-search ((msgdb modb-standard)
+ condition &optional numbers)
+ (if (vectorp condition)
+ (let ((key (elmo-filter-key condition))
+ results)
+ (cond
+ ((and (string= key "flag")
+ (eq (elmo-filter-type condition) 'match))
+ (setq results (elmo-msgdb-list-flagged
+ msgdb
+ (intern (elmo-filter-value condition))))
+ (if numbers
+ (elmo-list-filter numbers results)
+ results))
+ ((member key '("first" "last"))
+ (let* ((numbers (or numbers
+ (modb-standard-number-list-internal msgdb)))
+ (len (length numbers))
+ (lastp (string= key "last"))
+ (value (string-to-number (elmo-filter-value condition))))
+ (when (eq (elmo-filter-type condition) 'unmatch)
+ (setq lastp (not lastp)
+ value (- len value)))
+ (if lastp
+ (nthcdr (max (- len value) 0) numbers)
+ (when (> value 0)
+ (let* ((numbers (copy-sequence numbers))
+ (last (nthcdr (1- value) numbers)))
+ (when last
+ (setcdr last nil))
+ numbers)))))
+ (t
+ t)))
+ t))
+
(luna-define-method elmo-msgdb-append-entity ((msgdb modb-standard)
entity &optional flags)
- (let ((number (elmo-msgdb-message-entity-number
- (elmo-message-entity-db entity) entity))
- (msg-id (elmo-msgdb-message-entity-field
- (elmo-message-entity-db entity) entity 'message-id))
- duplicate)
- ;; number-list
- (modb-standard-set-number-list-internal
- msgdb
- (nconc (modb-standard-number-list-internal msgdb)
- (list number)))
- ;; entity-map
- (let ((table (modb-standard-entity-map msgdb)))
- (setq duplicate (elmo-get-hash-val msg-id table))
- (elmo-set-hash-val (modb-standard-key number) entity table)
- (elmo-set-hash-val msg-id entity table))
- ;; modification flags
- (modb-standard-set-message-modified msgdb number)
- ;; flag-map
- (when flags
- (elmo-set-hash-val
- (modb-standard-key number)
- (cons number flags)
- (modb-standard-flag-map msgdb))
- (modb-standard-set-flag-modified msgdb number))
- duplicate))
+ (when entity
+ (let ((number (elmo-msgdb-message-entity-number
+ (elmo-message-entity-handler entity) entity))
+ (msg-id (elmo-msgdb-message-entity-field
+ (elmo-message-entity-handler entity) entity 'message-id))
+ duplicate)
+ (when msg-id
+ ;; number-list
+ (modb-standard-set-number-list-internal
+ msgdb
+ (nconc (modb-standard-number-list-internal msgdb)
+ (list number)))
+ ;; entity-map
+ (let ((table (modb-standard-entity-map msgdb)))
+ (setq duplicate (elmo-get-hash-val msg-id table))
+ (elmo-set-hash-val (modb-standard-key number) entity table)
+ (elmo-set-hash-val msg-id entity table))
+ ;; modification flags
+ (modb-standard-set-message-modified msgdb number)
+ ;; flag-map
+ (when flags
+ (elmo-set-hash-val
+ (modb-standard-key number)
+ (cons number flags)
+ (modb-standard-flag-map msgdb))
+ (modb-standard-countup-flags msgdb flags)
+ (modb-standard-set-flag-modified msgdb number))
+ duplicate))))
(luna-define-method elmo-msgdb-delete-messages ((msgdb modb-standard)
numbers)
(dolist (number numbers)
(setq key (modb-standard-key number)
entity (elmo-get-hash-val key entity-map))
- ;; number-list
- (setq number-list (delq number number-list))
- ;; entity-map
- (elmo-clear-hash-val key entity-map)
- (elmo-clear-hash-val (modb-standard-entity-id entity) entity-map)
- ;; flag-map
- (elmo-clear-hash-val key flag-map)
- (modb-standard-set-message-modified msgdb number)
- (modb-standard-set-flag-modified msgdb number))
+ (when entity
+ ;; number-list
+ (setq number-list (delq number number-list))
+ ;; entity-map
+ (elmo-clear-hash-val key entity-map)
+ (elmo-clear-hash-val (modb-standard-entity-id entity) entity-map)
+ ;; flag-count (must be BEFORE flag-map)
+ (modb-standard-countup-flags
+ msgdb
+ (modb-standard-message-flags msgdb number)
+ -1)
+ ;; flag-map
+ (elmo-clear-hash-val key flag-map)
+ (modb-standard-set-message-modified msgdb number)
+ (modb-standard-set-flag-modified msgdb number)))
(modb-standard-set-number-list-internal msgdb number-list)
(modb-standard-set-entity-map-internal msgdb entity-map)
- (modb-standard-set-flag-map-internal msgdb flag-map)))
+ (modb-standard-set-flag-map-internal msgdb flag-map)
+ t))
(luna-define-method elmo-msgdb-sort-entities ((msgdb modb-standard)
predicate &optional app-data)
(message "Sorting...done")
msgdb))
-(luna-define-method elmo-msgdb-message-entity ((msgdb modb-standard) key)
+(defun modb-standard-message-entity (msgdb key load)
(let ((ret (elmo-get-hash-val
- (cond ((stringp key) key)
- ((numberp key) (modb-standard-key key)))
+ key
(modb-standard-entity-map-internal msgdb))))
- (if (eq 'autoload (car-safe ret))
+ (if (and (eq 'autoload (car-safe ret)) load)
(when modb-standard-divide-number
(modb-standard-load-entity
msgdb
(elmo-msgdb-location msgdb)
(/ (nth 1 ret) modb-standard-divide-number))
- (elmo-get-hash-val
- (cond ((stringp key) key)
- ((numberp key) (modb-standard-key key)))
- (modb-standard-entity-map-internal msgdb)))
+ (modb-standard-message-entity msgdb key nil))
ret)))
-;;; Message entity handling.
-(defsubst modb-standard-make-message-entity (args)
- "Make an message entity."
- (cons (plist-get args :message-id)
- (vector (plist-get args :number)
- (plist-get args :references)
- (plist-get args :from)
- (plist-get args :subject)
- (plist-get args :date)
- (plist-get args :to)
- (plist-get args :cc)
- (plist-get args :size)
- (plist-get args :extra))))
-
-(luna-define-method elmo-msgdb-make-message-entity ((msgdb modb-standard)
- args)
- (modb-standard-make-message-entity args))
-
-(luna-define-method elmo-msgdb-create-message-entity-from-buffer
- ((msgdb modb-standard) number args)
- (let ((extras elmo-msgdb-extra-fields)
- (default-mime-charset default-mime-charset)
- entity message-id references from subject to cc date
- extra field-body charset size)
- (save-excursion
- (setq entity (modb-standard-make-message-entity args)
- ;; For compatibility.
- msgdb (elmo-message-entity-db entity))
- (elmo-set-buffer-multibyte default-enable-multibyte-characters)
- (setq message-id (elmo-msgdb-get-message-id-from-buffer))
- (and (setq charset (cdr (assoc "charset" (mime-read-Content-Type))))
- (setq charset (intern-soft charset))
- (setq default-mime-charset charset))
- (setq references
- (or (elmo-msgdb-get-last-message-id
- (elmo-field-body "in-reply-to"))
- (elmo-msgdb-get-last-message-id
- (elmo-field-body "references")))
- from (elmo-replace-in-string
- (elmo-mime-string (or (elmo-field-body "from")
- elmo-no-from))
- "\t" " ")
- subject (elmo-replace-in-string
- (elmo-mime-string (or (elmo-field-body "subject")
- elmo-no-subject))
- "\t" " ")
- date (elmo-field-body "date")
- to (mapconcat 'identity (elmo-multiple-field-body "to") ",")
- cc (mapconcat 'identity (elmo-multiple-field-body "cc") ","))
- (unless (elmo-msgdb-message-entity-field msgdb entity 'size)
- (if (setq size (elmo-field-body "content-length"))
- (setq size (string-to-int size))
- (setq size 0)))
- (while extras
- (if (setq field-body (elmo-field-body (car extras)))
- (elmo-msgdb-message-entity-set-field
- msgdb entity (intern (downcase (car extras))) field-body))
- (setq extras (cdr extras)))
- (dolist (field '(number message-id references from subject
- date to cc size))
- (when (symbol-value field)
- (elmo-msgdb-message-entity-set-field
- msgdb entity field (symbol-value field))))
- entity)))
-
-;;; Message entity interface
-;;
-(luna-define-method elmo-msgdb-message-entity-number ((msgdb modb-standard)
- entity)
- ;; To be implemented.
- )
-
-(luna-define-method elmo-msgdb-message-entity-set-number ((msgdb modb-standard)
- entity
- number)
- ;; To be implemented.
- )
-
-(luna-define-method elmo-msgdb-message-entity-field ((msgdb modb-standard)
- entity field
- &optional decode)
- ;; To be implemented.
- )
-
-(luna-define-method elmo-msgdb-message-entity-set-field ((msgdb modb-standard)
- entity field value)
- ;; To be implemented.
- )
-
-(luna-define-method elmo-msgdb-copy-message-entity ((msgdb modb-standard)
- entity)
- ;; To be implemented.
- )
-
-(luna-define-method elmo-msgdb-match-condition-internal ((msgdb modb-standard)
- condition
- entity flags numbers)
- ;; To be implemented.
- )
+(luna-define-method elmo-msgdb-message-entity ((msgdb modb-standard) key)
+ (when key
+ (modb-standard-message-entity
+ msgdb
+ (cond ((stringp key) key)
+ ((numberp key) (modb-standard-key key)))
+ 'autoload)))
(require 'product)
(product-provide (provide 'modb-standard) (require 'elmo-version))