Oh yeah, there is something interesting going on in the wrapper, We keep track of the ongoing transactions by mapping the
user-id to a list of transaction contexts (every nested transaction by a user "pushes" a new txn-context).  Anyway, it's the
repository-persistent-information that has the interesting stuff:(defclass repository-persistent-information ()
  (
   (type  :initarg :type
          :initform (error "Required initarg :type omitted.")
          :reader repository-persistent-information/type
          :type repository-type)
   ;; Database parent is the root extent for an extent database, or the master database for a satellite.
   ;; Root extents or master repositories won't have a parent
   (parent-repository :initarg :parent-repository
                      :initform nil
                      :reader repository-persistent-information/parent
                      :type (optional relative-pathname))
   ;; Satellite repositories is non-nil only for master repositories.
   (satellite-repositories :initform nil
                           :initarg :satellite-repositories
                           :accessor repository-persistent-information/satellite-repositories)
   (canonical-class-dictionary :initform (make-instance 'canonical-class-dictionary)
                               :reader repository-persistent-information/canonical-class-dictionary)
   (cid-master-table :initform (make-instance 'cid-master-table)
                     :reader repository-persistent-information/cid-master-table)
   (root-mapper  :initarg :root-mapper
                 :initform (error "Required initarg :root-mapper omitted.")
                 :reader repository-persistent-information/root-mapper)
   (cid-mapper   :initarg :cid-mapper
                 :initform (error "Required initarg :cid-mapper omitted.")
                 :reader repository-persistent-information/cid-mapper)
   (local-mapper :initarg :local-mapper
                 :initform (error "Required initarg :local-mapper omitted.")
                 :reader repository-persistent-information/local-mapper)
   (locally-named-roots :initarg :locally-named-roots
                        :initform (error "Required initarg :locally-named-roots omitted.")
                        :reader repository-persistent-information/locally-named-roots)
   (anonymous-user :initarg :anonymous-user
                   :initform nil
                   :reader repository-persistent-information/anonymous-user))
  (:default-initargs :node-id +object-id-of-root+)  ;; force this to always be the root object.
  (:documentation "Persistent information describing a repositiory, and stored in the repository")
  (:metaclass persistent-standard-class)
  (:schema-version 0))The
repository-type is just a keyword:(defconstant *repository-types* '(:basic :master :satellite :transport :extent :workspace) "Type of repositories. Note that all but :EXTENT types of repositories serve as root extents for databases which have multiple extents, and therefore imply extent.")The
parent-repository and thesatellite-repositories are for juggling multiple "satellite" repositories for holding particular subsets of changes (for, say, geographically distributing the servers for different product groups).The
canonical-class-dictionary is an intern table for objects.The
cid-master-table is (logically) the collection of audit-records.  A CID (after change id) is represented as an integer index  into the master table.The
root-mapper is a mapping table from distributed identifiers to objects. The
cid-mapper is a mapping table from the distributed identifier that represents the CID to the integer index of that CID in the master table.  It is a subtable of the local mapper.The
local-mapper is submapping of the root-mapping, but a supermapping of the cid-mapper.The
locally-named-rootsis a hash table for storing the root objects of the repository.Finally, there is the
anonymous-user slot, which is the user id assigned for bootstrapping.And all this crap is in support of this procedure:
(defun call-with-repository-transaction (&key repository 
                                              transaction-type
                                              user-id-specifier
                                              reason
                                              ;; generally, you only want to specify these two
                                              meta-cid-set-specifier
                                              cid-set-specifier 
                                              ;; but if you are doing a comparison,
                                              ;; specify these as well
                                              aux-meta-cid-set-specifier
                                              aux-cid-set-specifier 
                                              receiver)
  (check-type user-id-specifier (or keyword distributed-identifier))
  (check-type transaction-type repository-transaction-type)
  (check-type reason string)
  ;; implementation omitted for brevity, ha ha
  )Naturally we need to specify the
:repository, the :transaction-type is one of (defconstant *repository-transaction-types* '(:read-only
                                              :read-write
                                              :read-cons
                                              :read-only-compare
                                              :read-cons-nonversioned
                                              :read-only-nonversioned
                                              :read-write-nonversioned))The :user-id-specifier should be a distributed-identifier of a core-user instance.The
:reason is a human readable string describing the transaction.  The
:meta-cid-set-specifier is mumble, mumble... just a sec...The
:cid-set-specifier is how you specify which CIDs will form the basis view for the transaction.  We allow this to be a procedure that returns a cid-set object, and we will call this procedure as we are setting up the transaction and use the :meta-cid-set-specifier to specify the CIDs to form the versioned view the procedure will see.  The
:meta-cid-set-specifier can be the symbol :latest-metaversion, a timestamp, or a cid-set. :latest-metaversion means to use all CIDS while resolving the :cid-set-specifier, a timestamp is useful for rewinding the world, and the main use for using an explicit cid-set is for synchronizing views between master and satellite repositories.The
:receiver is invoked within the dynamic extent of a transaction.  It is passed a core-txn object that contains the metadata associated with the transaction.The ChangeSafe core components are the repository that holds changes and associated meta-information, and simple versioned CLOS objects. It is only useful as a foundation layer, though.
Next up, another level of abstraction...