|
From: Eric B. <eb...@ya...> - 2003-08-22 18:13:06
|
I'm using the error handler feature to catch bad db queries. Calling dbi_result_next_row() in a while loop causes _error_handler() to get called. I think it would be better to ignore this condition rather than report it as an error. This isn't an error in the context of a while loop. Ignoring this error in my error handler doesn't work because I need to trap when someone requests a bad fields name which is the same error code. Can the call to _error_handler() be taken out of the baseline for this function? __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com |
|
From: Markus H. <mar...@mh...> - 2003-08-25 13:23:56
|
Hi Eric, could you please provide a code example? It is not obvious to me why _error_handler() is called unless the loop goes too far. If it really does, this is probably a bug somewhere else that needs to be fixed. regards, Markus Eric Bixby writes: > I'm using the error handler feature to catch bad db > queries. > > Calling dbi_result_next_row() in a while loop causes > _error_handler() to get called. I think it would be > better to ignore this condition rather than report it > as an error. This isn't an error in the context of a > while loop. Ignoring this error in my error handler > doesn't work because I need to trap when someone > requests a bad fields name which is the same error > code. > > Can the call to _error_handler() be taken out of the > baseline for this function? > -- Markus Hoenicka mar...@ca... (Spam-protected email: replace the quadrupeds with "mhoenicka") http://www.mhoenicka.de |
|
From: Christian M. S. <chr...@st...> - 2003-08-25 19:23:33
Attachments:
dbiex.c
|
=2D----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, Took me some time to understand what you where talking about. (I don't use= =20 error handlers anywhere) Not sure what my thought are about removing it, There are other ways then=20 while loops to call dbi_result_next_row() and in some of them the error fee= ls=20 kosher. There are ways to ignore the problem.=20 You could just look at the error_flag ignoring BAD_IDX errors in your error= =20 handler or change the behavior of your while loops. In attaching some example code. Cheers,=20 Christian Ps. While looking into the problem I found that dbi_result_seek_row() don't=20 return -1 when retval is -1 from dbd_goto_row() it continues along trying t= o=20 fetch the row (This is a bug and should be changed even though we don't=20 remove the error handler, guess it hasn't been found yet becouse all driver= s=20 always return 1 from dbd_goto_row()). On Friday 22 August 2003 20.13, Eric Bixby wrote: : I'm using the error handler feature to catch bad db : queries. : : Calling dbi_result_next_row() in a while loop causes : _error_handler() to get called. I think it would be : better to ignore this condition rather than report it : as an error. This isn't an error in the context of a : while loop. Ignoring this error in my error handler : doesn't work because I need to trap when someone : requests a bad fields name which is the same error : code. : : Can the call to _error_handler() be taken out of the : baseline for this function? : : : __________________________________ : Do you Yahoo!? : Yahoo! SiteBuilder - Free, easy-to-use web site design software : http://sitebuilder.yahoo.com : : : ------------------------------------------------------- : This SF.net email is sponsored by: VM Ware : With VMware you can run multiple operating systems on a single machine. : WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines : at the same time. Free trial click : here:http://www.vmware.com/wl/offer/358/0 : _______________________________________________ : libdbi-devel mailing list : lib...@li... : https://lists.sourceforge.net/lists/listinfo/libdbi-devel =2D----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (GNU/Linux) iD8DBQE/Si2jj1ZSAMHYBOkRAnOjAKD0R6Zf4Y3VT0T3zw2n5Mb7F+G8tACguo/b fYj6XfBIvHyij9eyuC1U4Ss=3D =3DBUm3 =2D----END PGP SIGNATURE----- |
|
From: Eric B. <eb...@ya...> - 2003-08-25 18:39:53
|
Christian,
I should've included some example code to help explain
what I was talking about. However, I'm glad you where
able to understand what I was saying.
Error handling is great because it helps find sloppy
mistakes that the compiler will not find. For
example, I was able to find mistakes where someone
did a query like "SELECT x FROM y", then did a
dbi_result_get_long("x_nm").
My error handler does an assert() so that it forces
the developers to fix the problem rather than ignoring
it or not realizing that it occurred.
The problem with ignoring BAD_IDX is that it's the
same error code that occurs in a while loop and the
same error code that occurs in the example I just
gave.
Usually, we used a for loop, like this:
rows = dbi_result_get_numrows(result);
for (row = 0; row < rows; row++) {
dbi_result_next_row(result);
column = dbi_result_get_string(result, "A");
printf("%s\n", column);
}
However, we switched to using a while loop to use
fewer lines of code, like this:
while (dbi_result_next_row(result)) {
column = dbi_result_get_string(result, "A");
printf("%s\n", column);
}
The quick fix I came up with, to avoid rewriting the
while loops back to for loops, was to create a wrapper
function:
int DbiResultNextRow(dbi_result Result)
{
dbi_result_t *result = Result;
if ((result != NULL) && (result->currowidx <
dbi_result_get_numrows(Result)))
{
return dbi_result_next_row(result);
}
else
{
return 0;
}
}
Thanks for your help.
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com
|
|
From: Christian M. S. <chr...@st...> - 2003-08-25 19:04:11
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday 25 August 2003 20.39, Eric Bixby wrote: [..] : The problem with ignoring BAD_IDX is that it's the : same error code that occurs in a while loop and the : same error code that occurs in the example I just : gave. I'm talking about the error flags, they are diffrent for BADIDX and BADNAME use dbi_conn_error_flag(conn) to fetch the error flag. errno is from the db error_flag is from libdbi. Cheers, Christian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (GNU/Linux) iD8DBQE/Sl21j1ZSAMHYBOkRAp0JAJ4xn7n5WOuVF2nH1ChTt4JSGwxxVACg9kc5 hw3lj8LFGKVLtJ0se53T0rs= =wuXt -----END PGP SIGNATURE----- |
|
From: Eric B. <eb...@ya...> - 2003-08-26 14:18:59
|
Yes, your right. For some reason, I thought dbi_result_get_XXX() was flagging BAD_IDX when it calls dbi_result_get_XXX_idx() with a bad field. __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com |
|
From: Markus H. <mar...@mh...> - 2003-08-26 05:05:41
|
Hi,
I didn't get round to debug the problem, but if the loop below doesn't
work as expected, it's a libdbi bug. dbi_result_next_row() checks
whether currowidx is within the bounds of the result set and throws an
error if it is too high. There is probably a hidden off-by-one
error in the comparisons that we need to fix.
regards,
Markus
Eric Bixby writes:
> However, we switched to using a while loop to use
> fewer lines of code, like this:
>
> while (dbi_result_next_row(result)) {
> column = dbi_result_get_string(result, "A");
> printf("%s\n", column);
> }
>
--
Markus Hoenicka
mar...@ca...
(Spam-protected email: replace the quadrupeds with "mhoenicka")
http://www.mhoenicka.de
|
|
From: Eric B. <eb...@ya...> - 2003-08-26 20:42:10
|
Markus,
The loop shown works if you don't have an error
handler. It won't work if you create your own error
handler and do an assert() on any errors.
It works like feof(), when reading from a file. The
loop continues as long as there is data to retrieve.
dbi_result_next_row() produces an error when the code
tries to access a row greater than or equal to the
number of rows.
For example, if a SELECT returned zero rows, then you
do a while(dbi_result_next_row()){}, you are trying to
access a row, zero, that is equal to the number of
rows, zero. An error will be triggered.
Therefore, you must either:
1) ignore this particular error
2) use a for() or while() based on the number of rows
I don't think it's a bug in libdbi. I now think, you
should probably keep it the way it is because it might
be an error someone is interested in finding.
It's just something libdbi developers will need to
keep in mind if creating their own error handler.
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com
|
|
From: David P. <da...@ne...> - 2003-12-25 00:14:14
|
On Tue, 26 Aug 2003 12:19:01 -0700 (PDT), Eric Bixby wrote:
> dbi_result_next_row() produces an error when the code
> tries to access a row greater than or equal to the
> number of rows.
Right, the problem is because we're currently implementing the iterator
concept within the dbi_result_*_row() functions, not as a seperate object. I
think this simplification is a good one, but we could always add a dbi_cursor
type if someone can think of a good reason to have it.
> I don't think it's a bug in libdbi. I now think, you
> should probably keep it the way it is because it might
> be an error someone is interested in finding.
>
> It's just something libdbi developers will need to
> keep in mind if creating their own error handler.
I agree, it probably should stay the way it is, since the illustrated usage of
dbi_result_next_row() technically is generating an error. But what if we had
another function that does boundary checking, so that code using while loops
could check that too? Something like:
while (dbi_result_has_next_row(result) && dbi_result_next_row(result)) {
...
}
Now the while loop would bail out when it should without triggering an error.
For loops and other constructs would work the same as they always have.
I'm going to add something like this to CVS.
David
-------
David Parker <da...@ne...>
Neon Goat Productions
http://www.neongoat.com
0xF90FFFE5 / F362 51F7 6D51 85EB AF68 75B9 D29B 1AFC F90F FFE5
-------
|
|
From: Christian M. S. <chr...@st...> - 2003-08-26 07:03:42
|
=2D----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
On Tuesday 26 August 2003 06.13, Markus Hoenicka wrote:
: Hi,
:
: I didn't get round to debug the problem, but if the loop below doesn't
: work as expected, it's a libdbi bug. dbi_result_next_row() checks
: whether currowidx is within the bounds of the result set and throws an
: error if it is too high. There is probably a hidden off-by-one
: error in the comparisons that we need to fix.
No It's not a bug. It's a feature ;)=20
Everytime the while loop checks the condition if it should loop one more ti=
me=20
the function dbi_conn_next_row() gets executed.=20
: while (dbi_result_next_row(result))
So say that there are 8 rows, when the 8 row are fetched the while loop=20
executes dbi_conn_next_row() one more time to check if it should go a 9:th=
=20
time, libdbi throws a DABIDX becouse you are trying to fetch row number 9 a=
nd=20
there are only 8 rows, returns 0 so the while loop stops.
So the question here is. Should this error check for BADIDX be taken out of=
=20
dbi_result_next_row() so that you can use it whitout errors thrown in a pla=
in=20
while loop.=20
While looking in to the problem I found something that is a bug.=20
dbi_result_seek_row() doesn't return -1 when dbd_seek_row() returns -1=20
indicating failure. It tryies to fetch the row anyway which is in my eyes a=
n=20
error (if the row can't be seeked we are fetching the wrong row).
=2D --- dbi_result.c.orig 2003-08-26 08:55:37.000000000 +0200
+++ dbi_result.c 2003-08-26 08:56:33.000000000 +0200
@@ -86,6 +86,7 @@
retval =3D result->conn->driver->functions->goto_row(result, row-1);
if (retval =3D=3D -1) {
_error_handler(result->conn, DBI_ERROR_DBD);
+ return -1;
}
retval =3D result->conn->driver->functions->fetch_row(result, row-1=
);
if (retval =3D=3D 0) {
Take it easy,
Christian
=2D----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE/SwZYj1ZSAMHYBOkRAp3AAKCpKstob/rPu80wPnkQ6AvV2myC9wCg79XC
OM7WGOh7CtjP/1cKpWOIlsE=3D
=3Dg9dh
=2D----END PGP SIGNATURE-----
|
|
From: Markus H. <mar...@mh...> - 2003-08-26 19:47:12
|
Christian M. Stamgren writes:
> No It's not a bug. It's a feature ;)
>
Can we settle on "misfeature" if it's not a bug then? I don't have a
clean solution, but we can try to use the lesser evil. E.g. consider
the following (untested) code:
int dbi_result_next_row(dbi_result Result) {
dbi_result_t *result = Result;
if (!result) return 0;
if (result->currowidx == dbi_result_get_numrows(Result)) {
return 0;
}
else if (result->currowidx > dbi_result_get_numrows(Result)) {
_error_handler(result->conn, DBI_ERROR_BADIDX);
return 0;
}
return dbi_result_seek_row(Result, result->currowidx+1);
}
This would allow to run a while loop without triggering the error
handler. The price we'd have to pay is that the first call in a for
loop that accidentally goes beyond the bounds will return 0
(correctly) but not trigger the error handler.
regards,
Markus
--
Markus Hoenicka
mar...@ca...
(Spam-protected email: replace the quadrupeds with "mhoenicka")
http://www.mhoenicka.de
|