PERL DBI documentatio -- how to check for errors

PERL DBI documentatio -- how to check for errors

am 17.11.2005 07:42:00 von Nitzan Shaked

(A bit long)
(Bottom line: is it, or is it not, enough to always check DBI::err)

Hello

The documentation for how to check the success of various DBI calls, and in
particular do(), selectrow_foo() and selectall_foo() is unclear and not
precise, at least for me. Actually I am not sure, after scrutinizing, how
exactly to check for errors.

Specific problems:

Looking at the doc for "err", we see: "The DBI resets $h->err to undef
before most DBI method calls", note the "most". Since the documentation for
specific methods does not say which do *not* reset err, I have no way of
knowing which do and which don't.

Also: looking at (for example) the doc for selectall_hashref(), we can find:
"If any method except fetchrow_hashref fails, and "RaiseError" is not set,
selectall_hashref will return undef. If fetchrow_hashref fails and
"RaiseError" is not set, then it will return with whatever data it has
fetched thus far. $DBI::err should be checked to catch that".
selectall_arrayref() and selectcol_arrayref() have similar documentation.

To me this looks like the correct way to check selectall_hashref() is then:
my $hr = $dbh->selectall_hashref( ... );
(!defined $hr || defined $DBI::err) && die( ... );

Justification: error returns undef, so we need to see whether the result is
defined at all. Checking DBI::err is to test "that" -- only some rows were
returned. It does *not* say explicitly that err is reset before hand, so I
can't be sure that testing err alone is enough!

Looking at selectrow_hashref() says that error is indicated by undef. It
does *not* say err will be set. So I can only assume I need to:

my $hr = $dbh->selectrow_hashref( ... );
!defined $hr && die( "..." );

Again it does not say err is reset before, so I cannot assume I can trust
err for telling me about errors. The docs only explicitly mention the return
value.

To summarize:

My understand of the docs as written is that errors for selectall_ and
selectcol_ methods should be checked as:

(!defined $return_value || defined $DBI::err) && die( ... );

.... that errors for selectrow_ methods should be checked as:

(defined $return_value) || die( ... );

.... and that errors for do() should be checked as:

($return_value) || die( ... );

Is that correct? Is it really not possible to only check for (defined
DBI::err) always?

Can someone verify, or clarify the docs?

Much obligied,
Nitzan



--
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe: http://lists.mysql.com/perl?unsub=gcdmp-msql-mysql-modules@m .gmane.org

Re: PERL DBI documentatio -- how to check for errors

am 17.11.2005 11:12:15 von Stefan Hinz

Nitzan,

> (A bit long)
> (Bottom line: is it, or is it not, enough to always check DBI::err)

I'd correct the documentation, if I only knew what documentation you're
referring to. :-) In the MySQL Reference Manual, we have this:

http://dev.mysql.com/doc/refman/5.0/en/perl.html

But that's nothing but a very short overview.

At the moment, the Perl DBI documentation isn't maintained by us,
although there are plans to do that.

/Stefan


> The documentation for how to check the success of various DBI calls, and in
> particular do(), selectrow_foo() and selectall_foo() is unclear and not
> precise, at least for me. Actually I am not sure, after scrutinizing, how
> exactly to check for errors.
>
> Specific problems:
>
> Looking at the doc for "err", we see: "The DBI resets $h->err to undef
> before most DBI method calls", note the "most". Since the documentation for
> specific methods does not say which do *not* reset err, I have no way of
> knowing which do and which don't.
>
> Also: looking at (for example) the doc for selectall_hashref(), we can find:
> "If any method except fetchrow_hashref fails, and "RaiseError" is not set,
> selectall_hashref will return undef. If fetchrow_hashref fails and
> "RaiseError" is not set, then it will return with whatever data it has
> fetched thus far. $DBI::err should be checked to catch that".
> selectall_arrayref() and selectcol_arrayref() have similar documentation.
>
> To me this looks like the correct way to check selectall_hashref() is then:
> my $hr = $dbh->selectall_hashref( ... );
> (!defined $hr || defined $DBI::err) && die( ... );
>
> Justification: error returns undef, so we need to see whether the result is
> defined at all. Checking DBI::err is to test "that" -- only some rows were
> returned. It does *not* say explicitly that err is reset before hand, so I
> can't be sure that testing err alone is enough!
>
> Looking at selectrow_hashref() says that error is indicated by undef. It
> does *not* say err will be set. So I can only assume I need to:
>
> my $hr = $dbh->selectrow_hashref( ... );
> !defined $hr && die( "..." );
>
> Again it does not say err is reset before, so I cannot assume I can trust
> err for telling me about errors. The docs only explicitly mention the return
> value.
>
> To summarize:
>
> My understand of the docs as written is that errors for selectall_ and
> selectcol_ methods should be checked as:
>
> (!defined $return_value || defined $DBI::err) && die( ... );
>
> ... that errors for selectrow_ methods should be checked as:
>
> (defined $return_value) || die( ... );
>
> ... and that errors for do() should be checked as:
>
> ($return_value) || die( ... );
>
> Is that correct? Is it really not possible to only check for (defined
> DBI::err) always?
>
> Can someone verify, or clarify the docs?
>
> Much obligied,
> Nitzan
>
>
>


Regards,

Stefan
--
Stefan Hinz
MySQL AB Documentation Team Lead
Skype: stefanhinz SIP: 4429
Desk: +49308270294-0 Fax: -1
TZ: Berlin Mobile: +491777841069

--
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe: http://lists.mysql.com/perl?unsub=gcdmp-msql-mysql-modules@m .gmane.org

Re: PERL DBI documentatio -- how to check for errors

am 17.11.2005 13:18:20 von Jochen Wiedmann

Nitzan Shaked wrote:

> The documentation for how to check the success of various DBI calls, and in
> particular do(), selectrow_foo() and selectall_foo() is unclear and not
> precise, at least for me. Actually I am not sure, after scrutinizing, how
> exactly to check for errors.

It is quite easy: If it is not for reasons of upwards compatibility,
there is absolutely *no* excuse for not setting the "RaiseError" flag
and using exception handlers for catching errors. That works guaranteed
and always, allows you to ignore the return codes and stuff like that
and, sooner or later, will make your code drastically simpler and better
to read. (Unless, of course, you ignore error messages completely, which
is even more simple to read, but obiusly not better.)

"RaiseError" rules.

Jochen

--
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe: http://lists.mysql.com/perl?unsub=gcdmp-msql-mysql-modules@m .gmane.org

RE: PERL DBI documentatio -- how to check for errors

am 18.11.2005 12:57:03 von Nitzan Shaked

I actually read "programming the PERL DBI", and it seems that everyone
agrees "RaiseError" rules.

However, I do have on my hands a system of 30K+ PERL lines. The DBI error
checking is "in place" and so is the code to handle the errors. It's just
that I am not so sure the checking itself is done properly.

Now, *everybody* knows you don't go around changing the structure of a large
existing system. I *am* willing to change "$rv or die..." to "defined $rv or
die...". Or similar changes.

So -- thank you the response (I mean it), but can anyone please give a
precise definition as how to check for errors in selectall_foo(),
selectrow_foo(), and do() ?

Much obligied.

-----Original Message-----
From: Jochen Wiedmann [mailto:jochen.wiedmann@gmail.com]
Sent: Thursday, November 17, 2005 14:18 PM
To: Nitzan Shaked
Cc: mysqldoc@lists.mysql.com; perl@lists.mysql.com
Subject: Re: PERL DBI documentatio -- how to check for errors

Nitzan Shaked wrote:

> The documentation for how to check the success of various DBI calls, and
in
> particular do(), selectrow_foo() and selectall_foo() is unclear and not
> precise, at least for me. Actually I am not sure, after scrutinizing, how
> exactly to check for errors.

It is quite easy: If it is not for reasons of upwards compatibility,
there is absolutely *no* excuse for not setting the "RaiseError" flag
and using exception handlers for catching errors. That works guaranteed
and always, allows you to ignore the return codes and stuff like that
and, sooner or later, will make your code drastically simpler and better
to read. (Unless, of course, you ignore error messages completely, which
is even more simple to read, but obiusly not better.)

"RaiseError" rules.

Jochen

--
MySQL Documentation Mailing List
For list archives: http://lists.mysql.com/mysqldoc
To unsubscribe:
http://lists.mysql.com/mysqldoc?unsub=calius@netvision.net.i l


--
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe: http://lists.mysql.com/perl?unsub=gcdmp-msql-mysql-modules@m .gmane.org

Re: PERL DBI documentatio -- how to check for errors

am 18.11.2005 13:41:02 von Jochen Wiedmann

On 11/18/05, Nitzan Shaked wrote:

> Now, *everybody* knows you don't go around changing the structure of a la=
rge
> existing system. I *am* willing to change "$rv or die..." to "defined $rv=
or
> die...". Or similar changes.

No problem. Set the "RaiseError" flag locally, as in:

my $dbh;
# Performs a database operation, using the database handle $dbh
# We don't know the state of $dbh, but presumably it has "RaiseErro=
r"
# turned off. But we may turn it on within the following block:
{
local $dbh->{"RaiseError"} =3D 1;
eval {
# Do one or more database operations here ...
};
if ($@) { ... }
}

Note, that you might even encapsulate this in a separate method.


Jochen


--
Often it does seem a pity that Noah and his party did not miss the
boat. (Mark Twain)

--
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe: http://lists.mysql.com/perl?unsub=3Dgcdmp-msql-mysql-modules @m.gmane.org

RE: PERL DBI documentatio -- how to check for errors

am 18.11.2005 13:44:35 von Nitzan Shaked

Thanks again.

That's correct, and is one of the alternatives we've considered. However, at
the very least for the intellectual curiosity: what IS the answer to my
original question?

BR,
Nitzan

-----Original Message-----
From: Jochen Wiedmann [mailto:jochen.wiedmann@gmail.com]
Sent: Friday, November 18, 2005 14:41 PM
To: Nitzan Shaked
Cc: perl@lists.mysql.com
Subject: Re: PERL DBI documentatio -- how to check for errors

On 11/18/05, Nitzan Shaked wrote:

> Now, *everybody* knows you don't go around changing the structure of a
large
> existing system. I *am* willing to change "$rv or die..." to "defined $rv
or
> die...". Or similar changes.

No problem. Set the "RaiseError" flag locally, as in:

my $dbh;
# Performs a database operation, using the database handle $dbh
# We don't know the state of $dbh, but presumably it has
"RaiseError"
# turned off. But we may turn it on within the following block:
{
local $dbh->{"RaiseError"} = 1;
eval {
# Do one or more database operations here ...
};
if ($@) { ... }
}

Note, that you might even encapsulate this in a separate method.


Jochen


--
Often it does seem a pity that Noah and his party did not miss the
boat. (Mark Twain)

--
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe: http://lists.mysql.com/perl?unsub=calius@netvision.net.il


--
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe: http://lists.mysql.com/perl?unsub=gcdmp-msql-mysql-modules@m .gmane.org