NAME
Punk::DBI::db - the observed database handle
DESCRIPTION
The database-handle half of Punk::DBI. Wraps the statement-running methods DBI implements in its own dispatch - do and the select* family - so a pk_abi query observer sees them.
These are the ones that matter. $sth->execute is covered by Punk::DBI::st, and a hand-written statement is far more likely to be a selectall_arrayref than a prepared handle the caller drives itself.
Why a subclass and not Callbacks
DBI's Callbacks cannot do this, for two independent reasons. The select* methods are DBI's own dispatch and reach the inner execute without firing an execute callback at all, so exactly the hand-written statements this exists for are the ones a callback misses. And callbacks run before the method, so there is no way to report that a statement finished or whether it worked - and the observer contract is a start and a done.
One report per statement, at the altitude the caller asked for
Whether DBI answers one of these itself or falls back to prepare and execute is a per-driver, per-call detail. DBD::SQLite runs a bind-free do natively and takes the prepare/execute path the moment there is a placeholder - so the same statement reaches Punk::DBI::st on one branch and not the other.
Left alone that would report a statement once or twice depending on whether it had bind values, and double count the duration of every one that did. A re-entrancy guard means the outermost wrapper is the only one that reports: the caller asked for selectall_arrayref, so that is the statement.
The generated methods in Punk::Model::DBI use prepare_cached and execute directly, which is the st path, and are reported once there.
What the observer is told
The statement text and the number of bind values. Never the values: they are the literal data, and the SQL carries placeholders exactly where they would have been.
A statement is reported as having succeeded when it ran. These methods return data rather than a status, and a query that matched no rows has not failed; one that went wrong raised, because RaiseError is this framework's default, and the wrapper reports that before rethrowing.
SEE ALSO
AUTHOR
LNATION <email@lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION <email@lnation.org>.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)