Re: sth->prepare() setting Active?

2016-10-03 Thread David Nicol
this isn't tested -- i'm writing it here in e-mail -- but it or something
very close to it might work. supporting prepare_cached or other forms of
sth reuse could require a way to clear the flag.


package DBIx::WrapActive;
our $AUTOLOAD;

### invoke like $sth = DBIx::WrapActive::wrap($sth);
sub wrap{ bless [$_[0], 0 ] };
sub active { $_[0]->[1] and $_[0]->active }
sub execute {
my $obj = shift;
$obj->[1] = 1;
$obj->[0]->execute(@_);
}
sub AUTOLOAD{
 my ($method) = $AUTOLOAD =~ m/::([^:]+)$/;
 *{$AUTOLOAD} = sub {
 my $obj = shift;
 $obj->[0]->$method(@_);
 };
 goto &$AUTOLOAD;
};


Re: sth->prepare() setting Active?

2016-10-01 Thread Tim Bunce
Looks good. Thanks David!

Tim.

On Fri, Sep 30, 2016 at 04:03:35PM -0500, David Nicol wrote:
> sorry, this one is better
> 
>"Active"
> 
>Type: boolean, read-only
> 
>The "Active" attribute is true if the handle object is "active". This
>is rarely used in applications. The exact meaning of active depends on
>the database driver, but some aspects of the semantics are defined for
>interoperability. These include:
> 
>o   For a database handle, active typically means that the handle is
>connected to a database ("$dbh->disconnect" sets "Active" off).
> 
>o   For a statement handle it typically means that the handle is a
>"SELECT" that may have more data to fetch. (Fetching all the data
>or calling "$sth->finish" sets "Active" off.)
> 
>o   Prepared statement handles that must have "execute" called on them
>before they will return data should not be active until that
>happens.

> --- DBI.pm_orig   2016-09-30 15:28:20.0 -0500
> +++ DBI.pm2016-09-30 15:59:26.0 -0500
> @@ -3595,13 +3595,29 @@
>  Type: boolean, read-only
>  
>  The C attribute is true if the handle object is "active". This is 
> rarely used in
> -applications. The exact meaning of active is somewhat vague at the
> -moment. For a database handle it typically means that the handle is
> -connected to a database (C<$dbh-Edisconnect> sets C off).  For
> -a statement handle it typically means that the handle is a C
> +applications. The exact meaning of active depends on the database driver, 
> but some aspects
> +of the semantics are defined for interoperability. These include:
> +
> +=over
> +
> +=item
> +
> +For a database handle, active typically means that the handle is
> +connected to a database (C<$dbh-Edisconnect> sets C off).
> +
> +=item
> +
> +For a statement handle it typically means that the handle is a C
>  that may have more data to fetch. (Fetching all the data or calling 
> C<$sth-Efinish>
>  sets C off.)
>  
> +=item
> +
> +Prepared statement handles that must have C called on them before 
> they will return data
> +should not be active until that happens.
> +
> +=back
> +
>  =head3 C
>  
>  Type: boolean



Re: sth->prepare() setting Active?

2016-09-30 Thread David Nicol
sorry, this one is better

   "Active"

   Type: boolean, read-only

   The "Active" attribute is true if the handle object is "active". This
   is rarely used in applications. The exact meaning of active depends on
   the database driver, but some aspects of the semantics are defined for
   interoperability. These include:

   o   For a database handle, active typically means that the handle is
   connected to a database ("$dbh->disconnect" sets "Active" off).

   o   For a statement handle it typically means that the handle is a
   "SELECT" that may have more data to fetch. (Fetching all the data
   or calling "$sth->finish" sets "Active" off.)

   o   Prepared statement handles that must have "execute" called on them
   before they will return data should not be active until that
   happens.
--- DBI.pm_orig 2016-09-30 15:28:20.0 -0500
+++ DBI.pm  2016-09-30 15:59:26.0 -0500
@@ -3595,13 +3595,29 @@
 Type: boolean, read-only
 
 The C attribute is true if the handle object is "active". This is 
rarely used in
-applications. The exact meaning of active is somewhat vague at the
-moment. For a database handle it typically means that the handle is
-connected to a database (C<$dbh-Edisconnect> sets C off).  For
-a statement handle it typically means that the handle is a C
+applications. The exact meaning of active depends on the database driver, but 
some aspects
+of the semantics are defined for interoperability. These include:
+
+=over
+
+=item
+
+For a database handle, active typically means that the handle is
+connected to a database (C<$dbh-Edisconnect> sets C off).
+
+=item
+
+For a statement handle it typically means that the handle is a C
 that may have more data to fetch. (Fetching all the data or calling 
C<$sth-Efinish>
 sets C off.)
 
+=item
+
+Prepared statement handles that must have C called on them before 
they will return data
+should not be active until that happens.
+
+=back
+
 =head3 C
 
 Type: boolean


Re: sth->prepare() setting Active?

2016-09-30 Thread David Nicol
On Fri, Sep 30, 2016 at 4:57 AM, Tim Bunce  wrote:
>> > > Should a call to prepare() return an Active statement? (i.e. 
>> > > $sth->{Active} == 1)
>> > >
>> > > This appears to be the behaviour of DBD::Sybase, but not DBD::Pg
>> >


>> That's unfortunate, because Class::DBI does.
>>
>> $ grep -r Active .
>> ./lib/Class/DBI.pm:   $sth->execute(@$args) unless $sth->{Active};
>>
>> (from sth_to_objects)
>>
>> As far as I can see, this is to work out whether the sth that's been
>> passed in has already had execute called on it (e.g. part of a multiple
>> result loop). Removing the $sth->{Active} check (and ensuring Ima::DBI
>> always calls prepare and not prepare_cached (I haven't figured out what's
>> going on there yet) gets Class::DBI working with DBD::Sybase.

> I'd take the view that $sth->{Active} shouldn't be true until after a
> successful execute().
>
> I'd happily take a doc patch that tightens up the docs in that direction.

Attached is a patch against current CPAN version that modifies the
documentation to the following:

   "Active"

   Type: boolean, read-only

   The "Active" attribute is true if the handle object is "active". This
   is rarely used in applications. The exact meaning of active depends on
   the database driver, but some aspects of the semantics are defined for
   interoperability. These include:

   For a database handle, active typically means that the handle is
   connected to a database ("$dbh->disconnect" sets "Active" off).

   For a statement handle it typically means that the handle is a "SELECT"
   that may have more data to fetch. (Fetching all the data or calling
   "$sth->finish" sets "Active" off.)

   Prepared statement handles that must have "execute" called on them
   before they will return data should not be active until that happens.



-- 
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra
--- DBI.pm_orig 2016-09-30 15:28:20.0 -0500
+++ DBI.pm  2016-09-30 15:51:54.0 -0500
@@ -3595,13 +3595,19 @@
 Type: boolean, read-only
 
 The C attribute is true if the handle object is "active". This is 
rarely used in
-applications. The exact meaning of active is somewhat vague at the
-moment. For a database handle it typically means that the handle is
-connected to a database (C<$dbh-Edisconnect> sets C off).  For
-a statement handle it typically means that the handle is a C
+applications. The exact meaning of active depends on the database driver, but 
some aspects
+of the semantics are defined for interoperability. These include:
+
+For a database handle, active typically means that the handle is
+connected to a database (C<$dbh-Edisconnect> sets C off).
+
+For a statement handle it typically means that the handle is a C
 that may have more data to fetch. (Fetching all the data or calling 
C<$sth-Efinish>
 sets C off.)
 
+Prepared statement handles that must have C called on them before 
they will return data
+should not be active until that happens.
+
 =head3 C
 
 Type: boolean
@@ -6774,7 +6780,7 @@
 
 The C<\%attr> parameter may also contain the following attributes:
 
-=over
+=over 4
 
 =item C
 


Re: sth->prepare() setting Active?

2016-09-30 Thread Tim Bunce
On Fri, Sep 30, 2016 at 12:40:02AM +0100, Russell Howe via dbi-users wrote:
> On Thu, Sep 29, 2016 at 11:30:08PM -, Greg Sabino Mullane wrote:
> > 
> > > Should a call to prepare() return an Active statement? (i.e. 
> > > $sth->{Active} == 1)
> > >
> > > This appears to be the behaviour of DBD::Sybase, but not DBD::Pg
> > 
> > I don't think there is a canonical answer to that, but I can say that 
> > DBD::Pg in most cases will not even talk to the server until the first 
> > execute() after the prepare(), so it not being Active seems a sane 
> > interpretation.

> > The docs for DBD::Pg:
> > 
> >Indicates if a handle is active or not. For database handles, this 
> >indicates if the database has been disconnected or not. For statement 
> >handles, it indicates if all the data has been fetched yet or not. 
> >Use of this attribute is not encouraged.
> > 
> > As far as I can tell, DBD::Sybase makes not effort to do anything special 
> > regarding that attribute.
> 
> DBD::Sybase has this
> 
> /* Re-enable the active flag here (in 1.05_03) to fix bug with
>finish not getting called correctly */
> DBIc_ACTIVE_on(imp_sth);
> 
> at the end of syb_st_prepare() in dbdimp.c
> 
> So, it explictly sets Active to deal with some issue that I haven't
> fully delved into.
> 
> > In short, I would not rely upon it, especially across DBDs.
> 
> That's unfortunate, because Class::DBI does.
> 
> $ grep -r Active .
> ./lib/Class/DBI.pm:   $sth->execute(@$args) unless $sth->{Active};
> 
> (from sth_to_objects)
> 
> As far as I can see, this is to work out whether the sth that's been
> passed in has already had execute called on it (e.g. part of a multiple
> result loop). Removing the $sth->{Active} check (and ensuring Ima::DBI
> always calls prepare and not prepare_cached (I haven't figured out what's
> going on there yet) gets Class::DBI working with DBD::Sybase.
> 
> Our current code overrides db_Main which seems like an unnecessary hack
> to me, and confuses Class::DBI somewhat, triggering warnings.
> 
> I'm halfway down this rabbit hole and not really sure which turning to
> take now!

I'd take the view that $sth->{Active} shouldn't be true until after a
successful execute().

I'd happily take a doc patch that tightens up the docs in that direction.

Tim.