On Mon, Apr 23, 2007 at 08:56:45PM -0400, Patrick Galbraith wrote:
> Hi all,
> 
> Soon, I'll be releasing DBD::mysql 4.005 and was wondering if there any 
> last minute thoughts, requests?

A few general 'DBI best practice' items (that other drivers authors
should check their code for)...

---

Don't use DBIS or dbis when you can use DBIc_STATE(imp_xxh).
DBIS is much slower, especially on perls built with threads enabled.
It's a macro that expands to a function call, whereas
DBIc_STATE(imp_xxh) is just accessing a field in the handle structure.

---

In the specific case of dbis->debug or DBIS->debug, use 
DBIc_TRACE_LEVEL(imp_xxh)
instead. That correctly masks out the higher bits that DBI now reserves
for trace flags.  See TRACING in the DBI docs.

---

DBIc_ERR and DBIc_ERRSTR, and DBIc_STATE should not be set directly.
So change do_error() from the existing 28 lines to something like this:

void do_error(SV* h, int rc, const char* what, const char* sqlstate)
{
  D_imp_xxh(h);
  DBIh_SET_ERR_CHAR(h, imp_xxh, Nullch, rc, what, sqlstate, Nullch);
}

That will call set_err() to correctly merge info, warning and error states
and trigger the $h->{HandleSetErr} hook. See set_err() in the DBI docs.

---

The do_warn code is confused. It sets DBIc_ERR to a true value which
means it's really acting like do_error (it'll trigger RaiseError etc).
It should probably look like this:

void do_warn(SV* h, int rc, char* what)
{
  D_imp_xxh(h);
  DBIh_SET_ERR_CHAR(h, imp_xxh, "0", 0, what); /* "0" = warning */
}

---

doquietwarn doesn't seem to be used, but if it was then
DBIc_WARN(imp_xxh) could be used as the control. That defaults to true
but can be turned off via $h->{Warn}=0. It's inherited by child handles.

---

Hope that helps.

Tim.

Reply via email to