Internals¶
This document describes how auditing works in the code, internal to the application.
There are four primary actions which zf-doctrine-audit implements. The first is building an audit database based on the configuration listing entities and joinEntities.
Audit Entity Autoloader¶
In order to map configured entities to a database we must have a class for each audited entity. The naming of these classes
follows this pattern (found in ZF\Doctrine\Audit\Repository\AuditEntityRepository
):
return "ZF\\Doctrine\\Audit\\RevisionEntity\\" . str_replace('\\', '_', $entityName);
So an entity in the target object manager named Db\Entity\User
will be audited by an entity in the audit object manager named
ZF\\Doctrine\\Audit\\RevisionEntity\\Db_Entity_User
. Access to this entity through the audit object manager works as you
would expect in a doctrine object manager:
$auditObjectManger->getRepository('ZF\\Doctrine\\Audit\\RevisionEntity\\Db_Entity_User')
->findBy([
'id' => 2,
]);
This code will fetch the complete audit history for the Db\Entity\User
entity with id = 2.
This is possible because audit entity classes are dynamically created via an Autoloader.
Audit Object Manager Metadata¶
Mapping drivers for configured entities
and joinEntities
dynamically create metadata based on target entity metadata.
By introspecting the existing target entity metadata a new metadata definition can be assigned to an Autoloader created class.
The dynamically created classes assigned to dynamically created metadata combined with static auditing entities creates a complete audit object manager in the application. This object manager can be used by the schema tool and that is how the audit database is created.
Trigger Tool¶
Currently zf-doctrine-audit only supports MySQL. However the code is written such that new databases may be supported. The SQL for the target database is generated by the Trigger Tool. This tool implements two functions:
get_revision_entity_audit
close_revision_audit
get_revision_entity_audit function¶
get_revision_entity_audit
will create a new record in the RevisionEntity_Audit table and possibly the Revision_Audit table.
When get_revision_entity_audit
is called a check is done if a Revision_Audit record exists with the current connectionId
. If found the id
for that record is used. This allows multiple sql calls to be grouped into a single Revision.
Grouping of multiple sql calls into a single Revision only happens when running through the Object Manager. When changes are made to the target database through another means each Revision has only one RevisionEntity.
get_revision_entity_audit
returns an id for a newly created RevisionEntity_Audit record. This id is assigned to the auditing table audit row.
close_revision_audit function¶
When running through an ORM this function is called postFlush
. The Revision Comment comment is passed to the function along with the authenticated user. This changes the connectionId back to null. While the connectionId is not null it is used to group RevisionEntity together.
When running from a command line or attaching to the database is any other way than through the ORM this function is called at the end of each table create, update, and delete trigger.
create, update, delete triggers¶
Every table which is audited is assinged three triggers, one each for create, update, and delete. These triggers copy the audited row data into the audit database, assign a RevisionEntity, and either call close_revision_audit
or not.
The create trigger populates the audit table with the new data. The update trigger populates the audit table with the new, updated, data. The delete trigger populates the audit table with the last data for the row. In other words, the last update audit data will match the delete audit data.
Epoch Tool¶
This tool creates temporary stored procedures, runs them, then deletes them. This method is the fastest way to copy data from the target database into the audit database. The stored procedures output status information while they work.
RevisionAudit Tool¶
This tool is responsible for closing the Revision_Audit table after changes have been made. This tool can be called on its own. This tool is called in postFlush().