anchor.diff:                      :titles (if titles (ensure-vector titles) :null)
                       :first-name (or first-name :null)
                       :suffix (or suffix :null)
  -                    :suffix-titles (if suffix-titles (ensure-vector suffix-titles) :null))))))
  +                    :suffix-titles (if suffix-titles (ensure-vector suffix-titles) :null)
  +                    :full-name (calculate-full-name
  +                                base-name use-article-p adjectives titles
  +                                first-name suffix suffix-titles))))))
   
   (defun base-name (entity)
     (db-query (:select 'base-name :from 'nameable :where (:= 'entity-id entity))
               :single))
   
  -;; Thank you, PCL
  -(defparameter *english-list*
  -  "~{~#[~;~a~;~a and ~a~:;~@{~a~#[~;, and ~:;, ~]~}~]~}")
  +(defun full-name (entity)
  +  (db-query (:select 'full-name :from 'nameable :where (:= 'entity-id entity))
  +            :single))
   
  -(defun full-name (entity)
  -  (macrolet ((unless-null (maybe-null &body body)
  -               `(unless (eq :null ,maybe-null)
  -                  ,@body)))
  -    (when-let (row (db-query (:select :* :from 'nameable :where (:= 'entity-id entity))
  -                             :row))
  -      (destructuring-bind (id entity-id base-name use-article-p adjectives
  -                              titles first-name suffix suffix-titles)
  -          row
  -        (declare (ignore id entity-id))
  -        (with-output-to-string (s)
  -          (when use-article-p (princ "a " s))
  -          (unless-null adjectives (format s *english-list* (coerce adjectives 'list)) (princ " " s))
  -          (unless-null titles (map nil (curry #'format s "~A ") titles))
  -          (unless-null first-name (format s "~A " first-name))
  -          (princ base-name s)
  -          (unless-null suffix (format s " ~A" suffix))
  -          (unless-null suffix-titles (format s "~{, ~A~}" (coerce suffix-titles 'list))))))))
  +(defun recalculate-full-name (entity)
  +  (with-transaction ()
  +    (let ((full-name-args (db-query (:for-update
  +                                     (:select 'base-name 'use-article-p 'adjectives 'titles
  +                                              'first-name 'suffix 'suffix-titles
  +                                              :from 'nameable
  +                                              :where (:= 'entity-id entity)))
  +                                    :row)))
  +      (db-query (:update 'nameable :set
  +                         'full-name (apply #'calculate-full-name
  +                                           (substitute nil :null full-name-args)))))))
  +
  +(defun refresh-all-full-names ()
  +  (with-transaction ()
  +    (doquery (:select 'entity-id :from 'nameable) (entity)
  +      (with-db (:reusep nil)
  +        (recalculate-full-name entity)))))
   
   (defun test-names ()
     (flet ((test-case (expected nameable-alist)
  
positive.code:         :sykosomatic.util
          :sykosomatic.db
          :sykosomatic.entity)
    (:export :add-name :base-name :full-name))
  (cl:in-package #:sykosomatic.game-objects.nameable)
  
  (defdao nameable ()
    ((entity-id bigint)
  
negative.code:    (titles (or db-null text[]))
     (first-name (or db-null text))
     (suffix (or db-null text))
     (suffix-titles (or db-null text[]))
     (full-name text)))
  
  (defun add-name (entity base-name &key
                   use-article-p adjectives titles
  