Skip Menu |

This queue is for tickets about the DBIx-Simple CPAN distribution.

Report information
The Basics
Id: 89258
Status: open
Priority: 0/
Queue: DBIx-Simple

People
Owner: Nobody in particular
Requestors: MARKSTOS [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.35
Fixed in: (no value)



Subject: PATCH: Add DBIx::Simple::Connector
Juerd, As we discussed by email some time ago, attached is a patch which supplies DBIx::Simple::Connector, including code, tests and docs. I added _clear_cache() to DBIx::Simple as you asked, and it was also necessary to create internal calls in DBIx::Simple to reference 'dbh()' instead of {dbh}.
Subject: dbix_simple_connector.diff
Fri Oct 4 11:35:57 EDT 2013 Mark Stosberg <mark@summersault.com> * Implement DBIx::Simple::Connector. To implement this, some required changes were made to DBIx::Simple as well: - Use $self->dbh internally instead of $self->{dbh} - Add $self->_clear_cache(); diff -rN -u old-rt-9160-DBIx-Simple/Changes new-rt-9160-DBIx-Simple/Changes --- old-rt-9160-DBIx-Simple/Changes 2013-10-04 11:37:58.000000000 -0400 +++ new-rt-9160-DBIx-Simple/Changes 2013-10-04 11:37:58.000000000 -0400 @@ -3,6 +3,17 @@ Incompatible changes are marked with "!!". Incompatibility with and changes in "undocumented features" are not always specifically mentioned here. +1.40 Sat Oct 5 12:00 2013 + - DBIx::Simple::Connector has been added to the distribution for + built-in integration with DBIx::Connector. DBIx::Connector helps with + making connections persistent, automatically reconnecting and + avoiding pinging the database so much to test if the connection is + up. (Mark Stosberg) + + - Internally, we now maximally call $self->dbh instead of $self->{dbh}, + allowing sub-classes the flexibility to implement their own dbh() method. + (Mark Stosberg) + 1.35 Tue Jan 4 23:48 2010 !! - RaiseError is now enabled by default, as announced three years ago. Set PERL_DBIX_SIMPLE_NO_RAISEERROR=1 to get the old behavior. diff -rN -u old-rt-9160-DBIx-Simple/lib/DBIx/Simple/Connector.pm new-rt-9160-DBIx-Simple/lib/DBIx/Simple/Connector.pm --- old-rt-9160-DBIx-Simple/lib/DBIx/Simple/Connector.pm 1969-12-31 19:00:00.000000000 -0500 +++ new-rt-9160-DBIx-Simple/lib/DBIx/Simple/Connector.pm 2013-10-04 11:37:58.000000000 -0400 @@ -0,0 +1,84 @@ +use 5.006; +use strict; + +$DBIx::Simple::Connector::VERSION = '1.40'; + +my $no_raiseerror = $ENV{PERL_DBIX_SIMPLE_NO_RAISEERROR}; + +package DBIx::Simple::Connector; +use base 'DBIx::Simple'; +use DBIx::Connector; +use Data::Dumper; + +sub connect { + my ($class, @arguments) = @_; + my $self = { + lc_columns => 1, + result_class => 'DBIx::Simple::Result', + dont_disconnect => 1, + }; + + if (defined $arguments[0] and UNIVERSAL::isa($arguments[0], 'DBIx::Connector')) { + $self->{conn} = shift @arguments; + Carp::carp("Additional arguments for $class->connect are ignored") if @arguments; + } else { + $arguments[3]->{PrintError} = 0 + unless defined $arguments[3] and exists $arguments[3]{PrintError}; + $arguments[3]->{RaiseError} = 1 + unless $no_raiseerror + or defined $arguments[3] and exists $arguments[3]{RaiseError}; + $self->{conn} = DBIx::Connector->new(@arguments); + } + + return undef unless $self->{conn}; + bless $self, $class; + $self->{dbd} = $self->{conn}->dbh->{Driver}->{Name}; + + return $self; +} + +sub dbh { + my $self = shift; + + # If the database handle has changed, invalidate our statement handle caches. + my $new_dbh = $self->{conn}->dbh; + if (defined $self->{old_dbh} and "$self->{old_dbh}" ne "$new_dbh") { + $self->_clear_cache; + } + + $self->{old_dbh} = "$new_dbh"; + return $new_dbh; +} + + + +1; + +=head1 NAME + +DBIx::Simple::Connector - Initialize DBIx::Simple with a DBIx::Connector object + +=head1 SYNOPSIS + + my $db = DBIx::Simple::Connector->new( DBIx::Connector->new(...) ); + + my $db = DBIx::Simple::Connector->new($dsn, $username, $password, \%args); + +=head1 DESCRIPTION + +Works just like L<DBIx::Simple>, but accepts a DBIx::Connector object as argument to C<new()> +instead of a raw database handle. + +Alternately, arguments to C<new()> will be passed to DBIx::Connector to make a database connection. + +=head1 AUTHORS + +Mark Stosberg <mark@stosberg.com> and Juerd Waalboer <#####@juerd.nl> <http://juerd.nl/> + +=head1 SEE ALSO + +L<DBIx::Simple> + +L<DBIx::Connector> + +=cut diff -rN -u old-rt-9160-DBIx-Simple/lib/DBIx/Simple.pm new-rt-9160-DBIx-Simple/lib/DBIx/Simple.pm --- old-rt-9160-DBIx-Simple/lib/DBIx/Simple.pm 2013-10-04 11:37:58.000000000 -0400 +++ new-rt-9160-DBIx-Simple/lib/DBIx/Simple.pm 2013-10-04 11:37:58.000000000 -0400 @@ -3,7 +3,7 @@ use DBI; use Carp (); -$DBIx::Simple::VERSION = '1.35'; +$DBIx::Simple::VERSION = '1.40'; $Carp::Internal{$_} = 1 for qw(DBIx::Simple DBIx::Simple::Result DBIx::Simple::DeadObject); @@ -34,6 +34,14 @@ bless $hash2, $tempref; } +# Used by DBIx::Simple::Connector +sub _clear_cache { + my $self = shift; + delete $statements{$self}; + delete $old_statements{$self}; +} + + ### constructor sub connect { @@ -83,7 +91,7 @@ sub error { my ($self) = @_; - return 'DBI error: ' . (ref $self ? $self->{dbh}->errstr : $DBI::errstr); + return 'DBI error: ' . (ref $self ? $self->dbh->errstr : $DBI::errstr); } sub dbh { $_[0]->{dbh} } @@ -121,7 +129,7 @@ unless ($self->{dont_disconnect}) { # Conditional, because destruction order is not guaranteed # during global destruction. - $self->{dbh}->disconnect() if defined $self->{dbh}; + $self->dbh->disconnect() if defined $self->dbh; } _swap( @@ -150,7 +158,7 @@ $st = splice(@$old, $i, 1)->[1]; $sth = $st->{sth}; } else { - eval { $sth = $self->{dbh}->prepare($query) } or do { + eval { $sth = $self->dbh->prepare($query) } or do { if ($@) { $@ =~ s/ at \S+ line \d+\.\n\z//; Carp::croak($@); @@ -184,11 +192,11 @@ return bless { st => $st, lc_columns => $self->{lc_columns} }, $self->{result_class}; } -sub begin_work { $_[0]->{dbh}->begin_work } +sub begin_work { $_[0]->dbh->begin_work } sub begin { $_[0]->begin_work } -sub commit { $_[0]->{dbh}->commit } -sub rollback { $_[0]->{dbh}->rollback } -sub func { shift->{dbh}->func(@_) } +sub commit { $_[0]->dbh->commit } +sub rollback { $_[0]->dbh->rollback } +sub func { shift->dbh->func(@_) } sub last_insert_id { my ($self) = @_; @@ -198,7 +206,7 @@ "--this is only $self->{dbi_version}, stopped" ); - return shift->{dbh}->last_insert_id(@_); + return shift->dbh->last_insert_id(@_); } sub disconnect { @@ -601,6 +609,11 @@ $result = $db->query(...) +=head2 DBIx::Simple + DBIx::Connector + + $db = DBIx::Simple::Connector->new($conn); + $db = DBIx::Simple::Connector->new($dsn,$username,$password,\%args); + =head2 DBIx::SImple + SQL::Interp $result = $db->iquery(...) @@ -1009,6 +1022,23 @@ =back +=head2 DBIx::Simple::Connector + +L<DBIx::Simple::Connector> allows you to initialize DBIx::Simple with a +L<DBIx::Connector> object instead of a direct database handle, and otherwise +works the same. Benefits include helping you automatically re-connect to the +database if the connection is dropped, and potentially avoiding re-checking if +the database handle is working by issuing issuing a "ping" call before every +query. + +Connecting to a database can be expensive; you don't want your application to +re-connect every time you need to run a query. The efficient thing to do is to +hang on to a database handle to maintain a connection to the database in order +to minimize that overhead. DBIx::Connector lets you do that without having to +worry about dropped or corrupted connections. + +See L<DBIx::Simple::Connector> and L<DBIx::Connector> for further details. + =head2 Object construction DBIx::Simple has basic support for returning results as objects. The actual diff -rN -u old-rt-9160-DBIx-Simple/t/sqlite.t new-rt-9160-DBIx-Simple/t/sqlite.t --- old-rt-9160-DBIx-Simple/t/sqlite.t 2013-10-04 11:37:58.000000000 -0400 +++ new-rt-9160-DBIx-Simple/t/sqlite.t 2013-10-04 11:37:58.000000000 -0400 @@ -7,7 +7,6 @@ eval { DBD::SQLite->VERSION >= 1 } or plan skip_all => 'DBD::SQLite >= 1.00 required'; - plan tests => 57; use_ok('DBIx::Simple'); } @@ -119,4 +118,34 @@ is_deeply(scalar $db->query($q)->objects('Mock', 42, 21), [ 1 ]); # wantarray true } +SKIP: { + eval { require DBIx::Connector } or skip "DBIx::Connector required", 1; + use DBIx::Simple::Connector; + { + my $dsc = DBIx::Simple::Connector->connect('dbi:SQLite:dbname=:memory:'); + ok($dsc->query('CREATE TABLE connector_1 (FOO, bar, baz)'), + 'DBIx::Simple::Connector, with DSN'); + $dsc->disconnect(); + } + { + my $conn = DBIx::Connector->new('dbi:SQLite:dbname=:memory:'); + my $dsc = DBIx::Simple::Connector->connect($conn); + ok($dsc->query('CREATE TABLE connector_1 (FOO, bar, baz)'), + 'DBIx::Simple::Connector, with existing DBIx::Connector object'); + + my $old_dbh = $dsc->dbh; + + # Simulate a DB disconnection. + $conn->{_dbh} = undef; + + ok($dsc->query('CREATE TABLE connector_1 (FOO, bar, baz)'), + 'DBIx::Simple::Connector, automatically reconnects'); + + isnt($old_dbh,$dsc->dbh, "The database handle was indeed updated."); + $dsc->disconnect(); + } +} + ok($db->disconnect); + +done_testing();
From: slobodan [...] miskovic.ca
Any chance this will get merged soon?