anchor.diff:    (setf (port chatlog) (config-tree :chatlog-pg :port))
     (setf (user chatlog) (config-tree :chatlog-pg :user))
     (setf (pass chatlog) (config-tree :chatlog-pg :pass))
  -  (connect-db))
  +  (connect-db chatlog))
   
   (defmethod stop ((chatlog chatlog-pg))
  -  (disconnect-db)
  +  (disconnect-db chatlog)
     (setf (config-tree :chatlog-pg :db) (db chatlog))
     (setf (config-tree :chatlog-pg :host) (host chatlog))
     (setf (config-tree :chatlog-pg :port) (port chatlog))
  
positive.code:   (apply (postmodern:prepare statement) vars))
  
  (defun fmt (unix)
    (local-time:format-timestring NIL (local-time:unix-to-timestamp unix) :format '((:year 4) #\. (:month 2) #\. (:day 2) #\Space (:hour 2) #\: (:min 2) #\: (:sec 2))))
  
  (define-command (chatlog stats) (&optional server channel) (:documentation "Retrieve short statistics about the recorded chatlog history.")
    (if (and server channel)
        (let ((events   (first (first (pstmt "SELECT COUNT(*) FROM \"chatlog\" WHERE \"server\"=$1 AND \"channel\"=$2" server channel))))
              (users    (first (first (pstmt "SELECT COUNT(*) FROM \"chatlog\" WHERE \"server\"=$1 AND \"channel\"=$2 GROUP BY \"user" server channel))))
              (messages (first (first (pstmt "SELECT COUNT(*) FROM \"chatlog\" WHERE \"server\"=$1 AND \"channel\"=$2 AND \"type\"='m'" server channel))))
              (since    (first (first (pstmt "SELECT time FROM \"chatlog\"  WHERE \"server\"=$1 AND \"channel\"=$2 ORDER BY \"time\" ASC LIMIT 1" server channel))))
              (topuser  (first (pstmt "SELECT COUNT(*) AS c,user FROM \"chatlog\" WHERE \"server\"=$2 AND \"channel\"=$1 AND \"type\"='m' GROUP BY \"user\" ORDER BY c DESC" server channel))))
          (respond event "Logging since ~a with a total of ~d events from ~a users, of which ~d were messages. User with most messages (~d) is ~a."
                   (fmt since) events users messages (first topuser) (second topuser)))
        (let ((channels (first (first (postmodern:query "SELECT COUNT(*) FROM \"chatlog\" GROUP BY \"channel\""))))
              (events   (first (first (postmodern:query "SELECT COUNT(*) FROM \"chatlog\""))))
              (users    (first (first (postmodern:query "SELECT COUNT(*) FROM \"chatlog\" GROUP BY \"user\""))))
              (messages (first (first (postmodern:query "SELECT COUNT(*) FROM \"chatlog\" WHERE \"type\"='m'"))))
              (topuser  (first (postmodern:query "SELECT COUNT(*) AS c,\"user\" FROM \"chatlog\" WHERE \"type\"='m' GROUP BY \"user\" ORDER BY c DESC"))))
          (respond event "Logging ~d channels with a total of ~d events from ~a users, of which ~d were messages. User with most messages (~d) is ~a."
                   channels events users messages (first topuser) (second topuser)))))
  
  (define-command (chatlog count) (nick) (:documentation "Counts the amount of recorded messages for a nick.")
    (let ((events   (first (first (pstmt "SELECT COUNT(*) FROM \"chatlog\" WHERE \"user\"=$1" nick))))
          (since    (first (first (pstmt "SELECT \"time\" FROM \"chatlog\" WHERE \"user\"=$1 ORDER BY \"time\" ASC LIMIT 1" nick))))
          (messages (first (first (pstmt "SELECT COUNT(*) FROM chatlog\" WHERE \"user\"=$1 AND \"type\"='m'" nick))))
          (channels (length (pstmt "SELECT COUNT(*) FROM \"chatlog\" WHERE \"user\"=$1 GROUP BY \"channel\"" nick))))
      (respond event "First recorded ~a on ~a. Since then, ~a has ~d events on record, of which ~d were messages across ~d channels."
               nick (fmt since) nick events messages channels)))
  
negative.code:   (:metaclass postmodern:dao-class))
  
  (defmethod connect-db ((chatlog chatlog-pg) &key (db (db chatlog)) (host (host chatlog)) (port (port chatlog)) (user (user chatlog)) (pass (pass chatlog)))
    (v:info :chatlog-pg "Connecting ~a@~a:~a/~a" user host port db)
    (setf (db chatlog) db)
    (setf (host chatlog) host)
    (setf (port chatlog) port)
    (setf (user chatlog) user)
    (setf (pass chatlog) pass)
    (postmodern:connect-toplevel (copy-seq db) (copy-seq user) (copy-seq pass) (copy-seq host) :port port)
    (unless (postmodern:table-exists-p 'chatlog)
      (postmodern:execute (postmodern:dao-table-definition 'chatlog))))
  
  (defmethod disconnect-db ((chatlog chatlog-pg))
    (v:info :chatlog-pg "Disconnecting.")
    (postmodern:disconnect-toplevel))
  
  (defconstant +UNIX-EPOCH-DIFFERENCE+ (encode-universal-time 0 0 0 1 1 1970 0))
  (defmethod insert-record ((chatlog chatlog-pg) server channel user type message)
    (when (find (format NIL "~a/~a" server channel) (active-in chatlog) :test #'string-equal)
      (v:trace :chatlog-pg "Logging event from ~a/~a <~a> (~a)" server channel user type)
      (bordeaux-threads:with-lock-held ((lock chatlog))
        (postmodern:insert-dao (make-instance 'chatlog :server (princ-to-string server) :channel channel :user user
                                                       :time (- (get-universal-time) +UNIX-EPOCH-DIFFERENCE+)
                                                       :type type :message message)))))
  
  (define-group chatlog-pg :documentation "Change chatlog-pg settings.")
  
  