Re: DBI::DBD: err/errstr/state - and how it has helped DBD::Informix
On Tue, Dec 14, 2004 at 06:24:40PM -0800, Jonathan Leffler wrote: On Tue, 14 Dec 2004 16:47:39 +, Tim Bunce [EMAIL PROTECTED] wrote: On Tue, Dec 14, 2004 at 07:08:08AM -0800, Jonathan Leffler wrote: I had certainly managed to miss this change - which could easily account for some of the weirdnesses I'd been seeing in DBD::Informix. (I haven't had a chance to do a thing for a week and more.) This sort of backwards incompatible change (in the use of set_err()) stuff needs to be firmly highlighted. I hope it was and I simply missed it. I would have put in place a comment about legacy drivers no longer being good exemplars. I don't think the change is backwards incompatible. It's a change in 'best practice' that ensures that errors on one db handle don't also appear on other children of the same handle. OK - well, I've removed the Err, Errstr, State parameters from the calls to _new_drh and _new_dbh and things seem to be working better for me in DBD::Informix.. I'm now trying to work out how the DBIh_SET_ERR_SV() and - more particularly - DBIh_SET_ERR_CHAR() functions can be used. I've spotted the section of DBI::DBD that discusses these - and I note that it deprecates the use 'dbis' and 'DBIS' shortly afterwards. DBIS is slow for threaded perl and probably broken for multiplicity perls (perl configured with -DMULTPLICITY). Any code that has a handle can change DBIS-foo to DBIc_DBISTATE(imp_xxh)-foo and will run faster in threaded perl. I have a pair of central error reporting functions - for $drh and $dbh as it happens - but they get passed only the imp_drh_t or imp_dbh_t pointers and not an associated SV. Is there a way to get back to the SV from the imp_d?h_t pointer? You can use h = newRV((SV*)DBIc_MY_H(imp_xxh)); or h = sv_2mortal(newRV((SV*)DBIc_MY_H(imp_xxh))); The newRV is needed because DBIc_MY_H returns a pointer to an HV struct, not an RV reference to an HV. You'd probably need the sv_2mortal to free the reference returned by newRV else you'd leak. There are two problems I'm having. One: what is the significance of the SV *h and the imp_xxh_t * arguments? The SV *h is the handle (the same as $h in the perl code, only typically it's the inner handle) - it's an RV to a HV. The imp_xxh_t *imp_xxh is the implementors data structure. Direct fast access to your own data structure. Why are both needed; The SV handle is what perl gives you when it calls your function, but the implementors data structure is typically what you want. Getting from the SV to the imp_xxh_t is relatively expensive so best to do it as little as possible. But to do some things you need the SV, so that's why both get passed around a lot. The DBIc_MY_H() way to get back the handle from the imp_xxh_t is relatively new. There may be some potential issues with it though I think you can use it here. But note that the sv_2mortal(newRV(...)) means it's more expensive. I'd recommend just passing both values around. what should those values be. I'm not sure what you're asking there. The other problem may be indirectly related. DBD::Informix has some (debugging) functions which I want to invoke from code that is unrelated to Perl - and therefore should not be contaminated with Perl nasties like SV pointers. At the moment, that code is using DBIS to find the debug level. The code does not have 'h' or 'imp_xxh' values available to it -- so it uses the DBIS to obtain the information it needs. If you don't want code contaminated then I'd recommend passing in the debug level as a parameter. DBIS will work, but it's slow for threaded perls and broken for multiplicity perls. Am I seeking to do the impossible (and if so, why does it have to be impossible)? ISTR that when I was first working with DBD::Informix (1996 or so) I got fed up with all the SV/imp_??h_t pointer pairs in the function calls when they weren't really both necessary. It may be that was more misguided than I knew, though it's worked fine for a long time. Yes, I know I'm trying to do too much with too little real knowledge of what's going on. We all are :) Tim. Having said that, there is certainly a possibility that changes in this area could be related to the 'weirdnesses' you're seeing. But that wouldn't be by design. Tim. On Tue, 14 Dec 2004 10:12:54 +0100, Steffen Goeldner [EMAIL PROTECTED] wrote: DBI 1.31 suggests that lexically scoped variables should be passed to _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.31,_29th_November_2002 DBI 1.33 suggests that drivers should no longer pass these variables to _new_drh() or _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.33,_27th_February_2003 This leaves set_err() as the sole interface to set error codes. But The Perl DBI Database Driver Writer's Guide still
Re: DBI::DBD: err/errstr/state - and how it has helped DBD::Informix
Sorry for this flurry of half-researched questions... :-( I'll probably be able to submit another patch to DBI::DBD.pm out of this. On Wed, 15 Dec 2004 10:11:57 +, Tim Bunce [EMAIL PROTECTED] wrote: On Tue, Dec 14, 2004 at 06:24:40PM -0800, Jonathan Leffler wrote: On Tue, 14 Dec 2004 16:47:39 +, Tim Bunce [EMAIL PROTECTED] wrote: [...] OK - well, I've removed the Err, Errstr, State parameters from the calls to _new_drh and _new_dbh and things seem to be working better for me in DBD::Informix.. I'm now trying to work out how the DBIh_SET_ERR_SV() and - more particularly - DBIh_SET_ERR_CHAR() functions can be used. I've spotted the section of DBI::DBD that discusses these - and I note that it deprecates the use 'dbis' and 'DBIS' shortly afterwards. DBIS is slow for threaded perl and probably broken for multiplicity perls (perl configured with -DMULTPLICITY). Any code that has a handle can change DBIS-foo to DBIc_DBISTATE(imp_xxh)-foo and will run faster in threaded perl. That assumes you have an imp_xxh around to work with. In some of the contexts, I don't, which is why the code is still messing with DBIS. I faintly remember trying to do something about it back in (early) 2003 -- unless it was 2001 -- and not coming to any useful conclusion. I'll end up doing somewhat more major surgery than I originally expected. It's what happens when you neglect software for 4 years. I have a pair of central error reporting functions - for $drh and $dbh as it happens - but they get passed only the imp_drh_t or imp_dbh_t pointers and not an associated SV. Is there a way to get back to the SV from the imp_d?h_t pointer? You can use h = newRV((SV*)DBIc_MY_H(imp_xxh)); or h = sv_2mortal(newRV((SV*)DBIc_MY_H(imp_xxh))); The newRV is needed because DBIc_MY_H returns a pointer to an HV struct, not an RV reference to an HV. You'd probably need the sv_2mortal to free the reference returned by newRV else you'd leak. There are two problems I'm having. One: what is the significance of the SV *h and the imp_xxh_t * arguments? The SV *h is the handle (the same as $h in the perl code, only typically it's the inner handle) - it's an RV to a HV. The imp_xxh_t *imp_xxh is the implementors data structure. Direct fast access to your own data structure. Why are both needed; The SV handle is what perl gives you when it calls your function, but the implementors data structure is typically what you want. Getting from the SV to the imp_xxh_t is relatively expensive so best to do it as little as possible. But to do some things you need the SV, so that's why both get passed around a lot. The DBIc_MY_H() way to get back the handle from the imp_xxh_t is relatively new. There may be some potential issues with it though I think you can use it here. But note that the sv_2mortal(newRV(...)) means it's more expensive. I'd recommend just passing both values around. Thanks; that's helpful. what should those values be. I'm not sure what you're asking there. Nor me - sorry. The other problem may be indirectly related. DBD::Informix has some (debugging) functions which I want to invoke from code that is unrelated to Perl - and therefore should not be contaminated with Perl nasties like SV pointers. At the moment, that code is using DBIS to find the debug level. The code does not have 'h' or 'imp_xxh' values available to it -- so it uses the DBIS to obtain the information it needs. If you don't want code contaminated then I'd recommend passing in the debug level as a parameter. DBIS will work, but it's slow for threaded perls and broken for multiplicity perls. OK - I'll do something about it. -- Jonathan Leffler [EMAIL PROTECTED] #include disclaimer.h Guardian of DBD::Informix - v2003.04 - http://dbi.perl.org I don't suffer from insanity - I enjoy every minute of it.
Re: DBI::DBD: err/errstr/state - and how it has helped DBD::Informix
On Wed, Dec 15, 2004 at 07:27:59AM -0800, Jonathan Leffler wrote: Sorry for this flurry of half-researched questions... :-( I'll probably be able to submit another patch to DBI::DBD.pm out of this. Great! Thanks. Tim. p.s. Patch against subversion if possible. If not grab the latest from http://svn.perl.org/modules/dbi/trunk/lib/DBI/DBD.pm before patching.
Re: DBI::DBD: err/errstr/state
On Tue, Dec 14, 2004 at 07:08:08AM -0800, Jonathan Leffler wrote: I had certainly managed to miss this change - which could easily account for some of the weirdnesses I'd been seeing in DBD::Informix. (I haven't had a chance to do a thing for a week and more.) This sort of backwards incompatible change (in the use of set_err()) stuff needs to be firmly highlighted. I hope it was and I simply missed it. I would have put in place a comment about legacy drivers no longer being good exemplars. I don't think the change is backwards incompatible. It's a change in 'best practice' that ensures that errors on one db handle don't also appear on other children of the same handle. Having said that, there is certainly a possibility that changes in this area could be related to the 'weirdnesses' you're seeing. But that wouldn't be by design. Tim. On Tue, 14 Dec 2004 10:12:54 +0100, Steffen Goeldner [EMAIL PROTECTED] wrote: DBI 1.31 suggests that lexically scoped variables should be passed to _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.31,_29th_November_2002 DBI 1.33 suggests that drivers should no longer pass these variables to _new_drh() or _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.33,_27th_February_2003 This leaves set_err() as the sole interface to set error codes. But The Perl DBI Database Driver Writer's Guide still suggests that global $err/$errstr/$state variables are needed for DBI: http://search.cpan.org/~timb/DBI-1.46/lib/DBI/DBD.pm#The_header IMO, we can discard the paragraph without substitution. Steffen Index: lib/DBI/DBD.pm === --- lib/DBI/DBD.pm (revision 623) +++ lib/DBI/DBD.pm (working copy) @@ -569,21 +569,8 @@ package DBD::File; use strict; - use vars qw($err $errstr $state $drh); + use vars qw($VERSION $drh); - $err = 0; # holds error code for DBI::err - $errstr = ; # holds error string for DBI::errstr - $sqlstate = S1000; # holds SQL statefor DBI::state - -These variables are used for storing error states and messages. -Note that most pure Perl drivers do not support the SQL standard error -indicator SQLSTATE, and for such drivers, the value S1000 is -appropriate. -If your database does support SQLSTATE, then initialize $sqlstate to an -empty string. -However, it is crucial to understand that you must not modify them -directly; see below. - $VERSION = 1.23.00 # Version number of DBD::File This is where the version number of your driver is specified. -- Jonathan Leffler [EMAIL PROTECTED] #include disclaimer.h Guardian of DBD::Informix - v2003.04 - http://dbi.perl.org I don't suffer from insanity - I enjoy every minute of it.
Re: DBI::DBD: err/errstr/state - and how it has helped DBD::Informix
On Tue, 14 Dec 2004 16:47:39 +, Tim Bunce [EMAIL PROTECTED] wrote: On Tue, Dec 14, 2004 at 07:08:08AM -0800, Jonathan Leffler wrote: I had certainly managed to miss this change - which could easily account for some of the weirdnesses I'd been seeing in DBD::Informix. (I haven't had a chance to do a thing for a week and more.) This sort of backwards incompatible change (in the use of set_err()) stuff needs to be firmly highlighted. I hope it was and I simply missed it. I would have put in place a comment about legacy drivers no longer being good exemplars. I don't think the change is backwards incompatible. It's a change in 'best practice' that ensures that errors on one db handle don't also appear on other children of the same handle. OK - well, I've removed the Err, Errstr, State parameters from the calls to _new_drh and _new_dbh and things seem to be working better for me in DBD::Informix.. I'm now trying to work out how the DBIh_SET_ERR_SV() and - more particularly - DBIh_SET_ERR_CHAR() functions can be used. I've spotted the section of DBI::DBD that discusses these - and I note that it deprecates the use 'dbis' and 'DBIS' shortly afterwards. I have a pair of central error reporting functions - for $drh and $dbh as it happens - but they get passed only the imp_drh_t or imp_dbh_t pointers and not an associated SV. Is there a way to get back to the SV from the imp_d?h_t pointer? There are two problems I'm having. One: what is the significance of the SV *h and the imp_xxh_t * arguments? Why are both needed; what should those values be. The other problem may be indirectly related. DBD::Informix has some (debugging) functions which I want to invoke from code that is unrelated to Perl - and therefore should not be contaminated with Perl nasties like SV pointers. At the moment, that code is using DBIS to find the debug level. The code does not have 'h' or 'imp_xxh' values available to it -- so it uses the DBIS to obtain the information it needs. Am I seeking to do the impossible (and if so, why does it have to be impossible)? ISTR that when I was first working with DBD::Informix (1996 or so) I got fed up with all the SV/imp_??h_t pointer pairs in the function calls when they weren't really both necessary. It may be that was more misguided than I knew, though it's worked fine for a long time. Yes, I know I'm trying to do too much with too little real knowledge of what's going on. Having said that, there is certainly a possibility that changes in this area could be related to the 'weirdnesses' you're seeing. But that wouldn't be by design. Tim. On Tue, 14 Dec 2004 10:12:54 +0100, Steffen Goeldner [EMAIL PROTECTED] wrote: DBI 1.31 suggests that lexically scoped variables should be passed to _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.31,_29th_November_2002 DBI 1.33 suggests that drivers should no longer pass these variables to _new_drh() or _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.33,_27th_February_2003 This leaves set_err() as the sole interface to set error codes. But The Perl DBI Database Driver Writer's Guide still suggests that global $err/$errstr/$state variables are needed for DBI: http://search.cpan.org/~timb/DBI-1.46/lib/DBI/DBD.pm#The_header IMO, we can discard the paragraph without substitution. -- Jonathan Leffler [EMAIL PROTECTED] #include disclaimer.h Guardian of DBD::Informix - v2 003.04 - http://dbi.perl.org I don't suffer from insanity - I enjoy every minute of it.
DBI::DBD: err/errstr/state
DBI 1.31 suggests that lexically scoped variables should be passed to _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.31,_29th_November_2002 DBI 1.33 suggests that drivers should no longer pass these variables to _new_drh() or _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.33,_27th_February_2003 This leaves set_err() as the sole interface to set error codes. But The Perl DBI Database Driver Writer's Guide still suggests that global $err/$errstr/$state variables are needed for DBI: http://search.cpan.org/~timb/DBI-1.46/lib/DBI/DBD.pm#The_header IMO, we can discard the paragraph without substitution. Steffen Index: lib/DBI/DBD.pm === --- lib/DBI/DBD.pm (revision 623) +++ lib/DBI/DBD.pm (working copy) @@ -569,21 +569,8 @@ package DBD::File; use strict; - use vars qw($err $errstr $state $drh); + use vars qw($VERSION $drh); - $err = 0; # holds error code for DBI::err - $errstr = ; # holds error string for DBI::errstr - $sqlstate = S1000; # holds SQL statefor DBI::state - -These variables are used for storing error states and messages. -Note that most pure Perl drivers do not support the SQL standard error -indicator SQLSTATE, and for such drivers, the value S1000 is -appropriate. -If your database does support SQLSTATE, then initialize $sqlstate to an -empty string. -However, it is crucial to understand that you must not modify them -directly; see below. - $VERSION = 1.23.00 # Version number of DBD::File This is where the version number of your driver is specified.
Re: DBI::DBD: err/errstr/state
Thanks, applied. Tim. On Tue, Dec 14, 2004 at 10:12:54AM +0100, Steffen Goeldner wrote: DBI 1.31 suggests that lexically scoped variables should be passed to _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.31,_29th_November_2002 DBI 1.33 suggests that drivers should no longer pass these variables to _new_drh() or _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.33,_27th_February_2003 This leaves set_err() as the sole interface to set error codes. But The Perl DBI Database Driver Writer's Guide still suggests that global $err/$errstr/$state variables are needed for DBI: http://search.cpan.org/~timb/DBI-1.46/lib/DBI/DBD.pm#The_header IMO, we can discard the paragraph without substitution. Steffen Index: lib/DBI/DBD.pm === --- lib/DBI/DBD.pm(revision 623) +++ lib/DBI/DBD.pm(working copy) @@ -569,21 +569,8 @@ package DBD::File; use strict; - use vars qw($err $errstr $state $drh); + use vars qw($VERSION $drh); - $err = 0; # holds error code for DBI::err - $errstr = ; # holds error string for DBI::errstr - $sqlstate = S1000; # holds SQL statefor DBI::state - -These variables are used for storing error states and messages. -Note that most pure Perl drivers do not support the SQL standard error -indicator SQLSTATE, and for such drivers, the value S1000 is -appropriate. -If your database does support SQLSTATE, then initialize $sqlstate to an -empty string. -However, it is crucial to understand that you must not modify them -directly; see below. - $VERSION = 1.23.00 # Version number of DBD::File This is where the version number of your driver is specified.
Re: DBI::DBD: err/errstr/state
I had certainly managed to miss this change - which could easily account for some of the weirdnesses I'd been seeing in DBD::Informix. (I haven't had a chance to do a thing for a week and more.) This sort of backwards incompatible change (in the use of set_err()) stuff needs to be firmly highlighted. I hope it was and I simply missed it. I would have put in place a comment about legacy drivers no longer being good exemplars. On Tue, 14 Dec 2004 10:12:54 +0100, Steffen Goeldner [EMAIL PROTECTED] wrote: DBI 1.31 suggests that lexically scoped variables should be passed to _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.31,_29th_November_2002 DBI 1.33 suggests that drivers should no longer pass these variables to _new_drh() or _new_dbh(): http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.33,_27th_February_2003 This leaves set_err() as the sole interface to set error codes. But The Perl DBI Database Driver Writer's Guide still suggests that global $err/$errstr/$state variables are needed for DBI: http://search.cpan.org/~timb/DBI-1.46/lib/DBI/DBD.pm#The_header IMO, we can discard the paragraph without substitution. Steffen Index: lib/DBI/DBD.pm === --- lib/DBI/DBD.pm (revision 623) +++ lib/DBI/DBD.pm (working copy) @@ -569,21 +569,8 @@ package DBD::File; use strict; - use vars qw($err $errstr $state $drh); + use vars qw($VERSION $drh); - $err = 0; # holds error code for DBI::err - $errstr = ; # holds error string for DBI::errstr - $sqlstate = S1000; # holds SQL statefor DBI::state - -These variables are used for storing error states and messages. -Note that most pure Perl drivers do not support the SQL standard error -indicator SQLSTATE, and for such drivers, the value S1000 is -appropriate. -If your database does support SQLSTATE, then initialize $sqlstate to an -empty string. -However, it is crucial to understand that you must not modify them -directly; see below. - $VERSION = 1.23.00 # Version number of DBD::File This is where the version number of your driver is specified. -- Jonathan Leffler [EMAIL PROTECTED] #include disclaimer.h Guardian of DBD::Informix - v2003.04 - http://dbi.perl.org I don't suffer from insanity - I enjoy every minute of it.