Re: using callbacks with connect_cached

2013-09-04 Thread Tim Bunce
Both merged. Thanks!

Tim.

On Tue, Sep 03, 2013 at 11:07:15AM -0700, David E. Wheeler wrote:
> On Aug 25, 2013, at 12:10 PM, Tim Bunce  wrote:
> 
> > p.s. I'd be delighted to get a doc patch that notes the need to use a
> > lexical for the callbacks hashref on connect_cached.
> 
> Submitted: https://github.com/perl5-dbi/dbi/pull/2
> 
> > p.p.s. I'd also consider a patch to add a 'connect_cached.connected'
> > callback for new connections.
> 
> Good idea! How’s this? https://github.com/perl5-dbi/dbi/pull/3
> 
> David
> 


Re: using callbacks with connect_cached

2013-09-03 Thread David E. Wheeler
On Aug 25, 2013, at 12:10 PM, Tim Bunce  wrote:

> p.s. I'd be delighted to get a doc patch that notes the need to use a
> lexical for the callbacks hashref on connect_cached.

Submitted: https://github.com/perl5-dbi/dbi/pull/2

> p.p.s. I'd also consider a patch to add a 'connect_cached.connected'
> callback for new connections.

Good idea! How’s this? https://github.com/perl5-dbi/dbi/pull/3

David



Re: using callbacks with connect_cached

2013-08-25 Thread Tim Bunce
On Sun, Aug 25, 2013 at 01:38:57PM +0200, David E. Wheeler wrote:
> On Aug 24, 2013, at 9:40 PM, Vincent Veyron  wrote:
> 
> You can also use a private attribute in connect_cached.new to tell the 
> connected callback to do its thing:
> 
> my $cb = {
> 'connect_cached.new' => sub {
> $_[4]->{private_is_new} = 1;
> return;
> },
> connected => sub {
> my $dbh = shift;
> warn "connected\n" if delete $dbh->{private_is_new};
> return;
> }
> };
> 
> for (1..3) {
> DBI->connect_cached('dbi:SQLite:', '', '', {
> PrintError => 0,
> RaiseError => 1,
> AutoCommit => 1,
> Callbacks  => $cb,
> });
> }
> 
> This emits "connected" only once.

If you're going to use a callback on connected and an attribute then
there's no need to also use connect_cached.new. Just this should do:

  connected => sub {
  my $dbh = shift;
  if (++$dbh->{private_connected_count} == 1) {
  ... # is new connection
  }
  return;
  }

Tim.

p.s. I'd be delighted to get a doc patch that notes the need to use a
lexical for the callbacks hashref on connect_cached.

p.p.s. I'd also consider a patch to add a 'connect_cached.connected'
callback for new connections.


Re: using callbacks with connect_cached

2013-08-25 Thread David E. Wheeler
On Aug 24, 2013, at 9:40 PM, Vincent Veyron  wrote:

> Not quite : I thought connected_cache.new would enable me to set the
> correct datestyle once for a cached connection, and then be cached with
> it, but we've seen that won't work.
> 
> Using the connected callback would do a 'set datestyle to xyz' for each
> connection, even if cached. I realize it's no big deal (.5ms on my lowly
> Atom processor), but every little bit helps, as I'm sure you know. 
> 
> So I now set the datestyle when the user logs in (hence once, with
> $dbh->do('SET datestyle TO xyz'), and the database handle is cached and
> reused as is.

You can also use a private attribute in connect_cached.new to tell the 
connected callback to do its thing:


my $cb = {
'connect_cached.new' => sub {
$_[4]->{private_is_new} = 1;
return;
},
connected => sub {
my $dbh = shift;
warn "connected\n" if delete $dbh->{private_is_new};
return;
}
};

for (1..3) {
DBI->connect_cached('dbi:SQLite:', '', '', {
PrintError => 0,
RaiseError => 1,
AutoCommit => 1,
Callbacks  => $cb,
});
}

This emits "connected" only once.

Best,

David

Re: using callbacks with connect_cached

2013-08-24 Thread Vincent Veyron
Le samedi 24 août 2013 à 21:01 +0200, David E. Wheeler a écrit :
> On Aug 24, 2013, at 1:32 AM, Vincent Veyron  wrote:
> 
> >> Pretty sure the connected callback will work, too.
> > 
> > It certainly does, I've checked, but this callback would add a query to
> > each connection. 
> 
> Is that not what you want?

Hi David,

Not quite : I thought connected_cache.new would enable me to set the
correct datestyle once for a cached connection, and then be cached with
it, but we've seen that won't work.

Using the connected callback would do a 'set datestyle to xyz' for each
connection, even if cached. I realize it's no big deal (.5ms on my lowly
Atom processor), but every little bit helps, as I'm sure you know. 

So I now set the datestyle when the user logs in (hence once, with
$dbh->do('SET datestyle TO xyz'), and the database handle is cached and
reused as is.

-- 
Salutations, Vincent Veyron 
http://marica.fr/ 
Gestion des contrats, des contentieux juridiques et des sinistres
d'assurance



Re: using callbacks with connect_cached

2013-08-24 Thread David E. Wheeler
On Aug 24, 2013, at 1:32 AM, Vincent Veyron  wrote:

>> Pretty sure the connected callback will work, too.
> 
> It certainly does, I've checked, but this callback would add a query to
> each connection. 

Is that not what you want?

David



Re: using callbacks with connect_cached

2013-08-23 Thread Vincent Veyron
Le vendredi 23 août 2013 à 20:33 +0200, David E. Wheeler a écrit :


> Pretty sure the connected callback will work, too.
> 

It certainly does, I've checked, but this callback would add a query to
each connection. 

If you care to see the code in action, it's visible here :

http://as-pro.biz/clients/login?nom_utilisateur=demo-gmc&mot_de_passe=demo-gmc

(it's a demo, you can click away)

-- 
Salutations, Vincent Veyron
http://vincentveyron.com
Logiciels de gestion des sinistres assurance et des contentieux pour le service 
juridique



Re: using callbacks with connect_cached

2013-08-23 Thread David E. Wheeler
On Aug 23, 2013, at 7:13 PM, Vincent Veyron  wrote:

> Can't call method "do" on an undefined value
> at /home/lib/Aspro/db_handle.pm
> 
> which seems logical, since DBI.pm's documentation says :
> 
> "connect_cached.*" callbacks are invoked before connect_cached() has
> applied the connect attributes 
> 
> But I found a middle ground (setting the datestyle once at login time,
> it is then kept by the cached connection)

Pretty sure the connected callback will work, too.

David



Re: using callbacks with connect_cached

2013-08-23 Thread Vincent Veyron
Le vendredi 23 août 2013 à 16:25 +0200, David E. Wheeler a écrit :

> Oh, you know what? I think this is why the example in the docs and my blog 
> post puts the callback into a lexical variable, then just passes that 
> lexical. This is because the params passed to connect_cached(), if they vary 
> at all, create different connections. You call connect_cached() three times, 
> and construct the Callbacks hash reference anew each time. So it is different 
> each time.
> 
> Try this:
> 
> my $cb = {
> 'connect_cached.reused' => sub { print "reused!!!"; return; },
> };
> for my $test (1..3) {
> my $cached_dbh = MyApp::SQLite->connect_cached(
> "dbi:SQLite:dbname=$dbfile", '', '',
> {
> RaiseError  => 1,
> PrintError  => 0,
> Callbacks => $cb,
> }
> );
> ...
> }
> 

That did the trick! Congratulations for finding it.

I still can't use connect_cached.new for my original purpose, which was
to send an SQL query setting the correct datestyle for a new connection;
the error returned is :

 Can't call method "do" on an undefined value
at /home/lib/Aspro/db_handle.pm

which seems logical, since DBI.pm's documentation says :

"connect_cached.*" callbacks are invoked before connect_cached() has
applied the connect attributes 

But I found a middle ground (setting the datestyle once at login time,
it is then kept by the cached connection)

Thank you for your help.

-- 
Salutations, Vincent Veyron 
http://marica.fr/ 
Gestion des contrats, des contentieux juridiques et des sinistres
d'assurance



Re: using callbacks with connect_cached

2013-08-23 Thread David E. Wheeler
On Aug 23, 2013, at 12:22 PM, Vincent Veyron  wrote:

> As you can see, no caching happens when any callback is present in the
> connect method (connected, connect_cached.new, or
> connect_cached.reused).

Oh, you know what? I think this is why the example in the docs and my blog post 
puts the callback into a lexical variable, then just passes that lexical. This 
is because the params passed to connect_cached(), if they vary at all, create 
different connections. You call connect_cached() three times, and construct the 
Callbacks hash reference anew each time. So it is different each time.

Try this:

my $cb = {
'connect_cached.reused' => sub { print "reused!!!"; return; },
};
for my $test (1..3) {
my $cached_dbh = MyApp::SQLite->connect_cached(
"dbi:SQLite:dbname=$dbfile", '', '',
{
RaiseError  => 1,
PrintError  => 0,
Callbacks => $cb,
}
);
...
}

Best,

David

Re: using callbacks with connect_cached

2013-08-23 Thread Vincent Veyron
Hi David,

To make sure my problem was not tied to mod_perl, I modified sligthly
the SQLite app that you published on this page :

http://www.justatheory.com/computers/databases/sqlite/

so that it uses connect_cached, connecting 3 times for a simple select
on the 'try' table.

Here is a paste of the modified code, followed by its output :

http://pastebin.com/aR8YH1zR

As you can see, no caching happens when any callback is present in the
connect method (connected, connect_cached.new, or
connect_cached.reused).

-- 
Salutations, Vincent Veyron 
http://marica.fr/ 
Gestion des contrats, des contentieux juridiques et des sinistres
d'assurance



Re: using callbacks with connect_cached

2013-08-22 Thread Vincent Veyron
Le jeudi 22 août 2013 à 23:32 +0200, David E. Wheeler a écrit :

> What if you change the callback to return a true value?
> 


Do you mean like this (return 1 instead of simply return)? 

my $dbh = DBI->connect_cached( "DBI:Pg:dbname=aspro", 'www-data',
undef, {
PrintError =>1,
RaiseError => 1,
AutoCommit => 1,
pg_bool_tf => 't',
private_preferred_datestyle => $preferred_datestyle,

Callbacks => {
 "connect_cached.new" => sub {
 warn "new handle";
 return 1;
 },

 }
   } )  


No change, a new handle is created on every request.



-- 
Salutations, Vincent Veyron 
http://marica.fr/ 
Gestion des contrats, des contentieux juridiques et des sinistres
d'assurance



Re: using callbacks with connect_cached

2013-08-22 Thread David E. Wheeler
On Aug 22, 2013, at 10:53 PM, Vincent Veyron  wrote:

>> Note that DBI will reset all the attributes every time connect_cached is 
>> called. Maybe you need to delete one or more of the attributes in a 
>> connect_cached.reused callback?
> 
> The problem is that connect_cached.reused never gets triggered (hence
> the absence of caching)

Right, duh. What if you change the callback to return a true value?

David



Re: using callbacks with connect_cached

2013-08-22 Thread Vincent Veyron
Le jeudi 22 août 2013 à 18:52 +0200, David E. Wheeler a écrit :
> On Aug 22, 2013, at 8:28 AM, Vincent Veyron  wrote:

> So, do you get a new handle for every query *without* the callback?
> 

Caching works as advertised if I take out the callback. Here's how
CachedKids looks after a couple dozen requests :

  'cached_kids' => '$VAR1 = {
  
\'dbname=aspro!www-data!!AutoCommit='1',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='iso'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit='1',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='SQL,
 dmy'\' => bless( {}, \'DBI::db\' )
};

Only two handles, as expected.


> Note that DBI will reset all the attributes every time connect_cached is 
> called. Maybe you need to delete one or more of the attributes in a 
> connect_cached.reused callback?

The problem is that connect_cached.reused never gets triggered (hence
the absence of caching)




Re: using callbacks with connect_cached

2013-08-22 Thread David E. Wheeler
On Aug 22, 2013, at 8:28 AM, Vincent Veyron  wrote:

>> Try the connected callback, instead:
>> 
>>  http://justatheory.com/computers/databases/postgresql/execute-on-select.html
>> 
> 
> 
> Hi David,
> 
> I did study your fine article for my research, thank you for that :-)
> 
> But you must have overlooked the part of my post where I write that the
> connected callback creates a new handle for each query in the database;
> no caching happens as one can see with CackedKids after a few queries

Oy, yes, sorry, I did miss that.

> Apache is configured with MaxClients=1, so that only one process is
> active.

Stranger and stranger.

> There should be only two cached handles (one with
> private_preferred_datestyle ='iso', one 'SQL, dmy') :

So, do you get a new handle for every query *without* the callback?

Note that DBI will reset all the attributes every time connect_cached is 
called. Maybe you need to delete one or more of the attributes in a 
connect_cached.reused callback?

  
http://www.justatheory.com/computers/programming/perl/dbi-connect-cached-hack.html

HTH,

David



Re: using callbacks with connect_cached

2013-08-21 Thread Vincent Veyron
Le jeudi 22 août 2013 à 00:08 +0200, David E. Wheeler a écrit :

> Try the connected callback, instead:
> 
>   http://justatheory.com/computers/databases/postgresql/execute-on-select.html
> 


Hi David,

I did study your fine article for my research, thank you for that :-)

But you must have overlooked the part of my post where I write that the
connected callback creates a new handle for each query in the database;
no caching happens as one can see with CackedKids after a few queries

Apache is configured with MaxClients=1, so that only one process is
active.

There should be only two cached handles (one with
private_preferred_datestyle ='iso', one 'SQL, dmy') :


  'cachedkids' => '$VAR1 = {
  
\'dbname=aspro!www-data!!AutoCommit='1',Callbacks='HASH(0x7f919fb1c480)',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='iso'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit='1',Callbacks='HASH(0x7f919faf2c78)',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='iso'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit='1',Callbacks='HASH(0x7f919fad0768)',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='iso'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit='1',Callbacks='HASH(0x7f919fb0dd68)',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='SQL,
 dmy'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit='1',Callbacks='HASH(0x7f919fb0d000)',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='iso'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit='1',Callbacks='HASH(0x7f919fb2c9f0)',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='iso'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit='1',Callbacks='HASH(0x7f919fa76b88)',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='iso'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit='1',Callbacks='HASH(0x7f919fab1d00)',PrintError='1',RaiseError='1',Username='www-data',dbi_connect_method='connect_cached',pg_bool_tf='t',private_preferred_datestyle='SQL,
 dmy'\' => bless( {}, \'DBI::db\' )
};

-- 
Salutations, Vincent Veyron 
http://marica.fr/ 
Gestion des contrats, des contentieux juridiques et des sinistres
d'assurance



Re: using callbacks with connect_cached

2013-08-21 Thread David E. Wheeler
On Aug 21, 2013, at 8:09 PM, Vincent Veyron  wrote:

>my $dbh = DBI->connect_cached( "DBI:Pg:dbname=aspro", 'www-data',
> undef, {
>   PrintError =>1,
>   RaiseError => 1,
>   AutoCommit => 1,
>   pg_bool_tf => 't',
>   private_preferred_datestyle => $preferred_datestyle,
> 
> Callbacks => {
> "connect_cached.new" => sub {
> shift->do(qq{
>   SET datestyle TO $preferred_datestyle
> });
>return;
> }
>}
>   
>  } ) 
>   or croak "Cannot connect to db: $DBI::errstr";
> 
>return $dbh;
> 
> }

Try the connected callback, instead:

  http://justatheory.com/computers/databases/postgresql/execute-on-select.html

Best,

David



using callbacks with connect_cached

2013-08-21 Thread Vincent Veyron
Hi list,

I use a package to return a cached connection for a mod_perl application 
connected to a Postgresql db, like so :

my $dbh_data = Aspro::db_handle::get_dbh_data($preferred_datestyle) ;

where $preferred_datestyle is either 'iso' or 'SQL, dmy', and is used for 
setting date formats in the user's session.

I then do :

$dbh_data->do( 'SET datestyle TO ?', undef, ( $preferred_datestyle ) ) ;

to set the datestyle.

Following the documentation, I would like to use instead a callback to set the 
date format at dbh creation time as you can see in my package's code below, but 
can't get it right.

Using the "connect_cached.new" key for the callback returns an error :

Can't call method "do" on an undefined value at /home/lib/Aspro/db_handle.pm

Using the "connected" key works, but creates a new db handle for each 
connection, as shown by Data::Dumper in CachedKids (apologies for the strangely 
encoded characters)

'cachedkids' => '$VAR1 = {
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff34f642d80)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'iso\\\'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff34f645990)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff34f6449b8)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff34f641208)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff34fb80aa0)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff34f63fcf0)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff34f643980)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=sessions!www-data!!AutoCommit=\\\'1\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff34f643b18)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'iso\\\'\'
 => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff350e68e58)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff350e447b8)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff350de4990)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' => bless( {}, \'DBI::db\' ),
  
\'dbname=aspro!www-data!!AutoCommit=\\\'1\\\',Callbacks=\\\'HASH(0x7ff350e69368)\\\',PrintError=\\\'1\\\',RaiseError=\\\'1\\\',Username=\\\'www-data\\\',dbi_connect_method=\\\'connect_cached\\\',pg_bool_tf=\\\'t\\\',private_preferred_datestyle=\\\'SQL,
 dmy\\\'\' =>