Re: DBI::DBD: err/errstr/state - and how it has helped DBD::Informix

2004-12-15 Thread Tim Bunce
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

2004-12-15 Thread Jonathan Leffler
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

2004-12-15 Thread Tim Bunce
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

2004-12-14 Thread Tim Bunce
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

2004-12-14 Thread Jonathan Leffler
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

2004-12-13 Thread Steffen Goeldner
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

2004-12-13 Thread Tim Bunce
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

2004-12-13 Thread Jonathan Leffler
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.