[cgi-wiki-dev] passing active database handles vs params

Chris Winters cgi-wiki-dev@earth.li
Wed, 2 Jun 2004 23:01:12 -0400


--Apple-Mail-3-550290177
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed

On Jun 2, 2004, at 10:26 PM, Kate L Pugh wrote:
> Go for it!  If it goes wrong for someone I'm sure they'll send a 
> failing
> test, right?  :)
>
> And I'll find it useful for interfacing a wiki with the bulletin board
> I wrote today.

Here you go. This does ::Store::Database and all the ::Setup classes 
except ::SII.

Chris


--Apple-Mail-3-550290177
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="database_handle_param.patch"
Content-Disposition: attachment;
	filename=database_handle_param.patch

diff -aur CGI.old/Wiki/Setup/DBIxFTSMySQL.pm CGI/Wiki/Setup/DBIxFTSMySQL.pm
--- CGI.old/Wiki/Setup/DBIxFTSMySQL.pm	Wed Jun  2 22:52:29 2004
+++ CGI/Wiki/Setup/DBIxFTSMySQL.pm	Wed Jun  2 22:46:58 2004
@@ -39,12 +39,7 @@
 {
   my ($dbname, $dbuser, $dbpass, $dbhost) = (@_);
 
-    my $dsn = "dbi:mysql:$dbname";
-    $dsn .= ";host=$dbhost" if $dbhost;
-    my $dbh = DBI->connect($dsn, $dbuser, $dbpass,
-			   { PrintError => 1, RaiseError => 1,
-			     AutoCommit => 1 } )
-      or croak DBI::errstr;
+  my $dbh = _get_connection( $dbname, $dbuser, $dbpass, $dbhost );
 
   # Drop FTS indexes if they already exist.
   my $fts = DBIx::FullTextSearch->open($dbh, "_content_and_title_fts");
@@ -77,6 +72,19 @@
     $fts_all->index_document($name);
   }
   $sth->finish;
+}
+
+sub _get_connection {
+    my ( $dbname, $dbuser, $dbpass, $dbhost ) = @_;
+    return $dbname if ref( $dbname ); # it's a database handle...
+
+    my $dsn = "dbi:mysql:$dbname";
+    $dsn .= ";host=$dbhost" if $dbhost;
+    my $dbh = DBI->connect($dsn, $dbuser, $dbpass,
+			   { PrintError => 1, RaiseError => 1,
+			     AutoCommit => 1 } )
+      or croak DBI::errstr;
+    return $dbh;
 }
 
 =head1 AUTHOR
diff -aur CGI.old/Wiki/Setup/MySQL.pm CGI/Wiki/Setup/MySQL.pm
--- CGI.old/Wiki/Setup/MySQL.pm	Wed Jun  2 22:52:29 2004
+++ CGI/Wiki/Setup/MySQL.pm	Wed Jun  2 22:46:58 2004
@@ -71,10 +71,17 @@
 
   use CGI::Wiki::Setup::MySQL;
   CGI::Wiki::Setup::MySQL::setup($dbname, $dbuser, $dbpass, $dbhost);
-
-Takes three mandatory arguments -- the database name, the username and the
-password. The username must be able to create and drop tables in the
-database.
+ 
+  or
+ 
+  CGI::Wiki::Setup::MySQL::setup($dbh);
+
+You can either provide an active database handle C<$dbh> or connection
+parameters.
+
+If you provide connection parameters the following arguments are
+mandatory -- the database name, the username and the password. The
+username must be able to create and drop tables in the database.
 
 The $dbhost argument is optional -- omit it if the database is local.
 
@@ -89,12 +96,7 @@
 sub setup {
     my ($dbname, $dbuser, $dbpass, $dbhost) = _get_args(@_);
 
-    my $dsn = "dbi:mysql:$dbname";
-    $dsn .= ";host=$dbhost" if $dbhost;
-    my $dbh = DBI->connect($dsn, $dbuser, $dbpass,
-			   { PrintError => 1, RaiseError => 1,
-			     AutoCommit => 1 } )
-      or croak DBI::errstr;
+    my $dbh = _get_connection( $dbname, $dbuser, $dbpass, $dbhost );
 
     # Check whether tables exist, set them up if not.
     my $sth = $dbh->prepare("SHOW TABLES") or croak $dbh->errstr;
@@ -145,12 +147,7 @@
 sub cleardb {
     my ($dbname, $dbuser, $dbpass, $dbhost) = _get_args(@_);
 
-    my $dsn = "dbi:mysql:$dbname";
-    $dsn .= ";host=$dbhost" if $dbhost;
-    my $dbh = DBI->connect($dsn, $dbuser, $dbpass,
-			   { PrintError => 1, RaiseError => 1,
-			     AutoCommit => 1 } )
-      or croak DBI::errstr;
+    my $dbh = _get_connection( $dbname, $dbuser, $dbpass, $dbhost );
 
     print "Dropping tables... ";
     $dbh->do("DROP TABLE IF EXISTS " . join( ",", keys %create_sql ) )
@@ -168,6 +165,19 @@
     } else {
         return @_;
     }
+}
+
+sub _get_connection {
+    my ($dbname, $dbuser, $dbpass, $dbhost) = @_;
+    return $dbname if ref( $dbname ); # it's a database handle...
+
+    my $dsn = "dbi:mysql:$dbname";
+    $dsn .= ";host=$dbhost" if $dbhost;
+    my $dbh = DBI->connect($dsn, $dbuser, $dbpass,
+			   { PrintError => 1, RaiseError => 1,
+			     AutoCommit => 1 } )
+      or croak DBI::errstr;
+    return $dbh;
 }
 
 =back
diff -aur CGI.old/Wiki/Setup/Pg.pm CGI/Wiki/Setup/Pg.pm
--- CGI.old/Wiki/Setup/Pg.pm	Wed Jun  2 22:52:29 2004
+++ CGI/Wiki/Setup/Pg.pm	Wed Jun  2 22:46:58 2004
@@ -95,12 +95,7 @@
 sub setup {
     my ($dbname, $dbuser, $dbpass, $dbhost) = _get_args(@_);
 
-    my $dsn = "dbi:Pg:dbname=$dbname";
-    $dsn .= ";host=$dbhost" if $dbhost;
-    my $dbh = DBI->connect($dsn, $dbuser, $dbpass,
-                           { PrintError => 1, RaiseError => 1,
-                             AutoCommit => 1 } )
-      or croak DBI::errstr;
+    my $dbh = _get_connection( $dbname, $dbuser, $dbpass, $dbhost );
 
     # Check whether tables exist, set them up if not.
     my $sql = "SELECT tablename FROM pg_tables
@@ -154,12 +149,7 @@
 sub cleardb {
     my ($dbname, $dbuser, $dbpass, $dbhost) = _get_args(@_);
 
-    my $dsn = "dbi:Pg:dbname=$dbname";
-    $dsn .= ";host=$dbhost" if $dbhost;
-    my $dbh = DBI->connect($dsn, $dbuser, $dbpass,
-			   { PrintError => 1, RaiseError => 1,
-			     AutoCommit => 1 } )
-      or croak DBI::errstr;
+    my $dbh = _get_connection( $dbname, $dbuser, $dbpass, $dbhost );
 
     print "Dropping tables... ";
     my $sql = "SELECT tablename FROM pg_tables
@@ -181,6 +171,19 @@
     } else {
         return @_;
     }
+}
+
+sub _get_connection {
+    my ( $dbname, $dbuser, $dbpass, $dbhost ) = @_;
+    return $dbname if ref( $dbname ); # it's a database handle...
+
+    my $dsn = "dbi:Pg:dbname=$dbname";
+    $dsn .= ";host=$dbhost" if $dbhost;
+    my $dbh = DBI->connect($dsn, $dbuser, $dbpass,
+                           { PrintError => 1, RaiseError => 1,
+                             AutoCommit => 1 } )
+      or croak DBI::errstr;
+    return $dbh;
 }
 
 =back
diff -aur CGI.old/Wiki/Setup/SQLite.pm CGI/Wiki/Setup/SQLite.pm
--- CGI.old/Wiki/Setup/SQLite.pm	Wed Jun  2 22:52:29 2004
+++ CGI/Wiki/Setup/SQLite.pm	Wed Jun  2 22:46:58 2004
@@ -81,10 +81,7 @@
 sub setup {
     my $dbfile = _get_args(@_);
 
-    my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", "", "",
-			   { PrintError => 1, RaiseError => 1,
-			     AutoCommit => 1 } )
-      or croak DBI::errstr;
+    my $dbh = _get_connection( $dbfile );
 
     # Check whether tables exist, set them up if not.
     my $sql = "SELECT name FROM sqlite_master
@@ -134,10 +131,7 @@
 sub cleardb {
     my $dbfile = _get_args(@_);
 
-    my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", "", "",
-			   { PrintError => 1, RaiseError => 1,
-			     AutoCommit => 1 } )
-      or croak DBI::errstr;
+    my $dbh = _get_connection( $dbfile );
 
     print "Dropping tables... ";
     my $sql = "SELECT name FROM sqlite_master
@@ -161,6 +155,17 @@
         @args = @_;
     }
     return $args[0];
+}
+
+sub _get_connection {
+    my ( $dbfile ) = @_;
+    return $dbfile if ref( $dbfile ); # it's a database handle...
+
+    my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", "", "",
+			   { PrintError => 1, RaiseError => 1,
+			     AutoCommit => 1 } )
+      or croak DBI::errstr;
+    return $dbh;
 }
 
 =back
diff -aur CGI.old/Wiki/Store/Database.pm CGI/Wiki/Store/Database.pm
--- CGI.old/Wiki/Store/Database.pm	Wed Jun  2 22:52:18 2004
+++ CGI/Wiki/Store/Database.pm	Wed Jun  2 22:48:26 2004
@@ -35,10 +35,35 @@
 					    dbuser => "wiki",
 					    dbpass => "wiki",
                                             dbhost => "db.example.com" );
+ 
+  or
+ 
+  my $store = CGI::Wiki::Store::MySQL->new( database => $dbh );
+
+If you do not provide an active database handle in C<database>
+C<dbname> is mandatory. C<dbpass>, C<dbuser> and C<dbhost> are
+optional, but you'll want to supply them unless your database's
+authentication method doesn't require it.
+
+If you do provide C<database> then it must have the following
+parameters set, otherwise you should just provide the connection
+information and let us create our own handle:
 
-C<dbname> is mandatory. C<dbpass>, C<dbuser> and C<dbhost> are optional, but
-you'll want to supply them unless your database's authentication
-method doesn't require it.
+=over 4
+
+=item *
+
+C<RaiseError> = 1
+
+=item *
+
+C<PrintError> = 0
+
+=item *
+
+C<AutoCommit> = 1
+
+=back
 
 =cut
 
@@ -52,25 +77,33 @@
 sub _init {
     my ($self, %args) = @_;
 
+    if ( $args{database} ) {
+        $self->{_dbh} = $args{database};
+
+        # so we do not disconnect at DESTROY-time
+        $self->{_external_dbh} = 1;
+    }
+
     # Store parameters.
-    foreach ( qw(dbname) ) {
-        die "Must supply a value for $_" unless defined $args{$_};
-        $self->{"_$_"} = $args{$_};
-    }
-    $self->{_dbuser} = $args{dbuser} || "";
-    $self->{_dbpass} = $args{dbpass} || "";
-    $self->{_dbhost} = $args{dbhost} || "";
+    else {
+        foreach ( qw(dbname) ) {
+            die "Must supply a value for $_" unless defined $args{$_};
+            $self->{"_$_"} = $args{$_};
+        }
+        $self->{_dbuser} = $args{dbuser} || "";
+        $self->{_dbpass} = $args{dbpass} || "";
+        $self->{_dbhost} = $args{dbhost} || "";
 
-    # Connect to database and store the database handle.
-    my ($dbname, $dbuser, $dbpass, $dbhost) =
+        # Connect to database and store the database handle.
+        my ($dbname, $dbuser, $dbpass, $dbhost) =
                                @$self{qw(_dbname _dbuser _dbpass _dbhost)};
-    my $dsn = $self->_dsn($dbname, $dbhost)
-       or croak "No data source string provided by class";
-    $self->{_dbh} = DBI->connect($dsn, $dbuser, $dbpass,
-				 { PrintError => 0, RaiseError => 1,
-				   AutoCommit => 1 } )
-       or croak "Can't connect to database $dbname using $dsn: " . DBI->errstr;
-
+        my $dsn = $self->_dsn($dbname, $dbhost)
+           or croak "No data source string provided by class";
+        $self->{_dbh} = DBI->connect($dsn, $dbuser, $dbpass,
+		    		 { PrintError => 0, RaiseError => 1,
+			    	   AutoCommit => 1 } )
+           or croak "Can't connect to database $dbname using $dsn: " . DBI->errstr;
+    }
     return $self;
 }
 
@@ -871,8 +904,10 @@
 # Cleanup.
 sub DESTROY {
     my $self = shift;
-    my $dbh = $self->dbh;
-    $dbh->disconnect if $dbh;
+    unless ( $self->{_external_dbh} ) {
+        my $dbh = $self->dbh;
+        $dbh->disconnect if $dbh;
+    }
 }
 
 1;

--Apple-Mail-3-550290177
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed


--
Chris Winters
Creating enterprise-capable snack systems since 1988

--Apple-Mail-3-550290177--