[cgi-wiki-dev] updated table-prefix diff against 0.50_01

Jody Belka cgi-wiki-dev@earth.li
Thu, 4 Dec 2003 17:33:05 -0000 (GMT)


------=_20031204173305_66345
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 8bit

Enclosed is the updated version of my table-prefix diff, which includes
changes to the db setup scripts unlike the previous version. I promised
this to Kake a while back now, but only just got round to doing it, sorry.


-- 
Jody
knew (at) pimb (dot) org
------=_20031204173305_66345
Content-Type: text/plain; name="CGI-Wiki-Knew.diff"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="CGI-Wiki-Knew.diff"

diff -pubr CGI-Wiki-0.50_01/bin/cgi-wiki-setupdb CGI-Wiki-Knew/bin/cgi-wiki-setupdb
--- CGI-Wiki-0.50_01/bin/cgi-wiki-setupdb	Thu Apr 24 18:09:28 2003
+++ CGI-Wiki-Knew/bin/cgi-wiki-setupdb	Thu Dec  4 16:39:31 2003
@@ -2,12 +2,13 @@
 use strict;
 use Getopt::Long;
 
-my ($dbtype, $dbname, $dbuser, $dbpass, $dbhost, $help, $preclear);
+my ($dbtype, $dbname, $dbuser, $dbpass, $dbhost, $table_prefix, $help, $preclear);
 GetOptions( "type=s"         => \$dbtype,
 	    "name=s"         => \$dbname,
             "user=s"         => \$dbuser,
             "pass=s"         => \$dbpass,
             "host=s"         => \$dbhost,
+            "table-prefix=s" => \$table_prefix,
             "help"           => \$help,
             "force-preclear" => \$preclear
            );
@@ -49,12 +50,16 @@ if ( $@ ) {
 
 if ($preclear) {
     no strict 'refs';
-    &{$class."::cleardb"}($dbname, $dbuser, $dbpass, $dbhost);
+    &{$class."::cleardb"}(dbname => $dbname, dbuser => $dbuser, 
+                          dbpass => $dbpass, dbhost => $dbhost, 
+                          table_prefix => $table_prefix);
 }
 
 {
     no strict 'refs';
-    &{$class."::setup"}($dbname, $dbuser, $dbpass, $dbhost);
+    &{$class."::setup"}(dbname => $dbname, dbuser => $dbuser,
+                        dbpass => $dbpass, dbhost => $dbhost, 
+                        table_prefix => $table_prefix);
 }
 
 =head1 NAME
@@ -83,7 +88,7 @@ cgi-wiki-setupdb - Set up a database sto
 
 =head1 DESCRIPTION
 
-Takes three mandatory arguments:
+Takes two mandatory arguments:
 
 =over 4
 
@@ -95,17 +100,17 @@ The database type.  Should be one of 'po
 
 The database name.
 
-=item user
-
-The user that connects to the database. It must have permission
-to create and drop tables in the database.
-
 =back
 
-two optional arguments:
+four optional arguments:
 
 =over 4
 
+=item user
+
+The user that connects to the database. It must have permission
+to create and drop tables in the database.
+
 =item pass
 
 The user's database password.
@@ -114,6 +119,11 @@ The user's database password.
 
 The hostname of the machine the database server is running on (omit
 for local databases).
+
+=item table-prefix
+
+A prefix to add to all table names, thus allowing the co-existence of
+multiple wikis within one database.
 
 =back
 
diff -pubr CGI-Wiki-0.50_01/bin/user-setup-mysql-dbixfts.pl CGI-Wiki-Knew/bin/user-setup-mysql-dbixfts.pl
--- CGI-Wiki-0.50_01/bin/user-setup-mysql-dbixfts.pl	Sat Nov  9 19:13:51 2002
+++ CGI-Wiki-Knew/bin/user-setup-mysql-dbixfts.pl	Thu Dec  4 16:39:37 2003
@@ -4,10 +4,12 @@ use strict;
 use Getopt::Long;
 use CGI::Wiki::Setup::DBIxFTSMySQL;
 
-my ($dbname, $dbuser, $dbpass, $help);
+my ($dbname, $dbuser, $dbpass, $dbhost, $table_prefix, $help);
 GetOptions("name=s" => \$dbname,
            "user=s" => \$dbuser,
            "pass=s" => \$dbpass,
+           "host=s"         => \$dbhost,
+           "table-prefix=s" => \$table_prefix,
            "help"   => \$help,);
 
 unless (defined($dbname)) {
@@ -16,12 +18,18 @@ unless (defined($dbname)) {
     exit 1;
 }
 
+unless (defined($dbuser)) {
+    print "You must supply a database user with the --user option\n";
+    print "further help can be found by typing 'perldoc $0'\n";
+    exit 1;
+}
+
 if ($help) {
     print "Help can be found by typing 'perldoc $0'\n";
     exit 0;
 }
 
-CGI::Wiki::Setup::DBIxFTSMySQL::setup($dbname, $dbuser, $dbpass);
+CGI::Wiki::Setup::DBIxFTSMySQL::setup($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
 
 =head1 NAME
 
@@ -32,10 +40,11 @@ user-setup-mysql-dbixfts - set up a DBIx
   user-setup-mysql-dbixfts --name mywiki \
                            --user wiki  \
                            --pass wiki  \
+                           --host 'db.example.com'
 
 =head1 DESCRIPTION
 
-Takes three arguments:
+Takes two mandatory arguments:
 
 =over 4
 
@@ -48,9 +57,25 @@ The database name.
 The user that connects to the database. It must have permission
 to create and drop tables in the database.
 
+=back
+
+and three optional arguments:
+
+over 4
+
 =item pass
 
 The user's database password.
+
+=item host
+
+The hostname of the machine the database server is running on (omit
+for local databases).
+
+=item table-prefix
+
+A prefix to add to all table names, thus allowing the co-existence of
+multiple wikis within one database.
 
 =back
 
diff -pubr CGI-Wiki-0.50_01/lib/CGI/Wiki/Setup/DBIxFTSMySQL.pm CGI-Wiki-Knew/lib/CGI/Wiki/Setup/DBIxFTSMySQL.pm
--- CGI-Wiki-0.50_01/lib/CGI/Wiki/Setup/DBIxFTSMySQL.pm	Thu Nov 20 14:25:57 2003
+++ CGI-Wiki-Knew/lib/CGI/Wiki/Setup/DBIxFTSMySQL.pm	Mon Nov 24 20:49:15 2003
@@ -16,7 +16,7 @@ CGI::Wiki::Setup::DBIxFTSMySQL - set up 
 =head1 SYNOPSIS
 
   use CGI::Wiki::Setup::DBIxFTSMySQL;
-  CGI::Wiki::Setup::DBIxFTSMySQL::setup($dbname, $dbuser, $dbpass, $dbhost);
+  CGI::Wiki::Setup::DBIxFTSMySQL::setup($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
 
 Omit $dbhost if the database is local.
 
@@ -29,6 +29,9 @@ drop tables in the database.
 
 The $dbhost argument is optional -- omit it if the database is local.
 
+The $table_prefix argument is optional -- it is only needed if you wish
+to share one database between multiple CGI::Wiki systems.
+
 Note that any pre-existing L<CGI::Wiki> indexes stored in the database
 will be I<cleared> by this function, so if you have existing data you
 probably want to use the C<store> parameter to get it re-indexed.
@@ -37,7 +40,7 @@ probably want to use the C<store> parame
 
 sub setup
 {
-  my ($dbname, $dbuser, $dbpass, $dbhost) = (@_);
+  my ($dbname, $dbuser, $dbpass, $dbhost, $table_prefix) = (@_);
 
     my $dsn = "dbi:mysql:$dbname";
     $dsn .= ";host=$dbhost" if $dbhost;
@@ -46,30 +49,34 @@ sub setup
 			     AutoCommit => 1 } )
       or croak DBI::errstr;
 
+  $table_prefix = $table_prefix || '';
+
   # Drop FTS indexes if they already exist.
-  my $fts = DBIx::FullTextSearch->open($dbh, "_content_and_title_fts");
+  my $fts = DBIx::FullTextSearch->open($dbh, $table_prefix . "_content_and_title_fts");
   $fts->drop if $fts;
-  $fts = DBIx::FullTextSearch->open($dbh, "_title_fts");
+  $fts = DBIx::FullTextSearch->open($dbh, $table_prefix . "_title_fts");
   $fts->drop if $fts;
 
+  my $node_table = $table_prefix . "node";
+
   # Set up FullText indexes and index anything already extant.
-  my $fts_all = DBIx::FullTextSearch->create($dbh, "_content_and_title_fts",
+  my $fts_all = DBIx::FullTextSearch->create($dbh, $table_prefix . "_content_and_title_fts",
 					     frontend       => "table",
 					     backend        => "phrase",
-					     table_name     => "node",
+					     table_name     => $node_table,
 					     column_name    => ["name","text"],
 					     column_id_name => "name",
 					     stemmer        => "en-uk");
 
-  my $fts_title = DBIx::FullTextSearch->create($dbh, "_title_fts",
+  my $fts_title = DBIx::FullTextSearch->create($dbh, $table_prefix . "_title_fts",
 					       frontend       => "table",
 					       backend        => "phrase",
-					       table_name     => "node",
+					       table_name     => $node_table,
 					       column_name    => "name",
 					       column_id_name => "name",
 					       stemmer        => "en-uk");
 
-  my $sql = "SELECT name FROM node";
+  my $sql = "SELECT name FROM $node_table";
   my $sth = $dbh->prepare($sql);
   $sth->execute();
   while (my ($name, $version) = $sth->fetchrow_array) {
diff -pubr CGI-Wiki-0.50_01/lib/CGI/Wiki/Setup/MySQL.pm CGI-Wiki-Knew/lib/CGI/Wiki/Setup/MySQL.pm
--- CGI-Wiki-0.50_01/lib/CGI/Wiki/Setup/MySQL.pm	Thu Nov 20 14:39:27 2003
+++ CGI-Wiki-Knew/lib/CGI/Wiki/Setup/MySQL.pm	Mon Nov 24 20:49:15 2003
@@ -55,7 +55,7 @@ CGI::Wiki::Setup::MySQL - Set up tables 
 =head1 SYNOPSIS
 
   use CGI::Wiki::Setup::MySQL;
-  CGI::Wiki::Setup::MySQL::setup($dbname, $dbuser, $dbpass, $dbhost);
+  CGI::Wiki::Setup::MySQL::setup($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
 
 Omit $dbhost if the database is local.
 
@@ -70,7 +70,7 @@ Set up a MySQL database for use as a CGI
 =item B<setup>
 
   use CGI::Wiki::Setup::MySQL;
-  CGI::Wiki::Setup::MySQL::setup($dbname, $dbuser, $dbpass, $dbhost);
+  CGI::Wiki::Setup::MySQL::setup($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
 
 Takes three mandatory arguments -- the database name, the username and the
 password. The username must be able to create and drop tables in the
@@ -87,7 +87,7 @@ again with a fresh database, run C<clear
 =cut
 
 sub setup {
-    my ($dbname, $dbuser, $dbpass, $dbhost) = _get_args(@_);
+    my ($dbname, $dbuser, $dbpass, $dbhost, $table_prefix) = _get_args(@_);
 
     my $dsn = "dbi:mysql:$dbname";
     $dsn .= ";host=$dbhost" if $dbhost;
@@ -96,6 +96,8 @@ sub setup {
 			     AutoCommit => 1 } )
       or croak DBI::errstr;
 
+    $table_prefix = $table_prefix || '';
+
     # Check whether tables exist, set them up if not.
     my $sth = $dbh->prepare("SHOW TABLES") or croak $dbh->errstr;
     $sth->execute;
@@ -105,11 +107,15 @@ sub setup {
     }
 
     foreach my $required ( keys %create_sql ) {
-        if ( $tables{$required} ) {
-            print "Table $required already exists... skipping...\n";
+        if ( $tables{$table_prefix . $required} ) {
+            print "Table $table_prefix$required already exists... skipping...\n";
         } else {
-            print "Creating table $required... done\n";
+            print "Creating MySQL table $table_prefix$required... done\n";
             foreach my $sql ( @{ $create_sql{$required} } ) {
+                my $_sql = $sql;
+                $_sql =~ s/TABLE $required/TABLE $table_prefix$required/;
+                $_sql =~ s/INDEX $required/INDEX $table_prefix$required/;
+                $_sql =~ s/ON $required/ON $table_prefix$required/;
                 $dbh->do($sql) or croak $dbh->errstr;
             }
         }
@@ -124,8 +130,8 @@ sub setup {
   use CGI::Wiki::Setup::MySQL;
 
   # Clear out the old database completely, then set up tables afresh.
-  CGI::Wiki::Setup::MySQL::cleardb($dbname, $dbuser, $dbpass, $dbhost);
-  CGI::Wiki::Setup::MySQL::setup($dbname, $dbuser, $dbpass, $dbhost);
+  CGI::Wiki::Setup::MySQL::cleardb($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
+  CGI::Wiki::Setup::MySQL::setup($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
 
 Takes three mandatory arguments -- the database name, the username and the
 password. The username must be able to drop tables in the database.
@@ -143,7 +149,7 @@ which search backend you're using.
 =cut
 
 sub cleardb {
-    my ($dbname, $dbuser, $dbpass, $dbhost) = _get_args(@_);
+    my ($dbname, $dbuser, $dbpass, $dbhost, $table_prefix) = _get_args(@_);
 
     my $dsn = "dbi:mysql:$dbname";
     $dsn .= ";host=$dbhost" if $dbhost;
@@ -152,8 +158,10 @@ sub cleardb {
 			     AutoCommit => 1 } )
       or croak DBI::errstr;
 
-    print "Dropping tables... ";
-    $dbh->do("DROP TABLE IF EXISTS " . join( ",", keys %create_sql ) )
+    $table_prefix = $table_prefix || '';
+
+    print "Dropping MySQL tables($table_prefix)... ";
+    $dbh->do("DROP TABLE IF EXISTS " . $table_prefix . join( ",$table_prefix", keys %create_sql ) )
       or croak $dbh->errstr;
     print "done\n";
 
@@ -164,7 +172,7 @@ sub cleardb {
 sub _get_args {
     if ( ref $_[0] ) {
         my %hash = %{$_[0]};
-        return @hash{ qw( dbname dbuser dbpass dbhost ) };
+        return @hash{ qw( dbname dbuser dbpass dbhost table_prefix ) };
     } else {
         return @_;
     }
@@ -176,14 +184,15 @@ sub _get_args {
 
 As requested by Podmaster.  Instead of passing arguments to the methods as
 
-  ($dbname, $dbuser, $dbpass, $dbhost)
+  ($dbname, $dbuser, $dbpass, $dbhost, $table_prefix)
 
 you can pass them as
 
   ( { dbname => $dbname,
       dbuser => $dbuser,
       dbpass => $dbpass,
-      dbhost => $dbhost
+      dbhost => $dbhost,
+      table_prefix => $table_prefix,
     }
   )
 
diff -pubr CGI-Wiki-0.50_01/lib/CGI/Wiki/Setup/Pg.pm CGI-Wiki-Knew/lib/CGI/Wiki/Setup/Pg.pm
--- CGI-Wiki-0.50_01/lib/CGI/Wiki/Setup/Pg.pm	Thu Nov 20 12:53:07 2003
+++ CGI-Wiki-Knew/lib/CGI/Wiki/Setup/Pg.pm	Mon Nov 24 20:49:15 2003
@@ -61,7 +61,7 @@ CGI::Wiki::Setup::Pg - Set up tables for
 =head1 SYNOPSIS
 
   use CGI::Wiki::Setup::Pg;
-  CGI::Wiki::Setup::Pg::setup($dbname, $dbuser, $dbpass, $dbhost);
+  CGI::Wiki::Setup::Pg::setup($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
 
 Omit $dbhost if the database is local.
 
@@ -76,7 +76,7 @@ Set up a Postgres database for use as a 
 =item B<setup>
 
   use CGI::Wiki::Setup::Pg;
-  CGI::Wiki::Setup::Pg::setup($dbname, $dbuser, $dbpass, $dbhost);
+  CGI::Wiki::Setup::Pg::setup($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
 
 Takes three mandatory arguments -- the database name, the username and the
 password. The username must be able to create and drop tables in the
@@ -93,7 +93,7 @@ again with a fresh database, run C<clear
 =cut
 
 sub setup {
-    my ($dbname, $dbuser, $dbpass, $dbhost) = _get_args(@_);
+    my ($dbname, $dbuser, $dbpass, $dbhost, $table_prefix) = _get_args(@_);
 
     my $dsn = "dbi:Pg:dbname=$dbname";
     $dsn .= ";host=$dbhost" if $dbhost;
@@ -102,10 +102,12 @@ sub setup {
                              AutoCommit => 1 } )
       or croak DBI::errstr;
 
+    $table_prefix = $table_prefix || '';
+
     # Check whether tables exist, set them up if not.
     my $sql = "SELECT tablename FROM pg_tables
                WHERE tablename in ("
-            . join( ",", map { $dbh->quote($_) } keys %create_sql ) . ")";
+            . join( ",", map { $dbh->quote($table_prefix . $_) } keys %create_sql ) . ")";
     my $sth = $dbh->prepare($sql) or croak $dbh->errstr;
     $sth->execute;
     my %tables;
@@ -114,12 +116,16 @@ sub setup {
     }
 
     foreach my $required ( keys %create_sql ) {
-        if ( $tables{$required} ) {
-            print "Table $required already exists... skipping...\n";
+        if ( $tables{$table_prefix . $required} ) {
+            print "Table $table_prefix$required already exists... skipping...\n";
         } else {
-            print "Creating table $required... done\n";
+            print "Creating Pg table $table_prefix$required... done\n";
             foreach my $sql ( @{ $create_sql{$required} } ) {
-                $dbh->do($sql) or croak $dbh->errstr;
+                my $_sql = $sql;
+                $_sql =~ s/TABLE $required/TABLE $table_prefix$required/;
+                $_sql =~ s/INDEX $required/INDEX $table_prefix$required/;
+                $_sql =~ s/ON $required/ON $table_prefix$required/;
+                $dbh->do($_sql) or croak $dbh->errstr;
             }
         }
     }
@@ -133,8 +139,8 @@ sub setup {
   use CGI::Wiki::Setup::Pg;
 
   # Clear out the old database completely, then set up tables afresh.
-  CGI::Wiki::Setup::Pg::cleardb($dbname, $dbuser, $dbpass, $dbhost);
-  CGI::Wiki::Setup::Pg::setup($dbname, $dbuser, $dbpass, $dbhost);
+  CGI::Wiki::Setup::Pg::cleardb($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
+  CGI::Wiki::Setup::Pg::setup($dbname, $dbuser, $dbpass, $dbhost, $table_prefix);
 
 Takes three mandatory arguments -- the database name, the username and the
 password. The username must be able to drop tables in the database.
@@ -152,7 +158,7 @@ which search backend you're using.
 =cut
 
 sub cleardb {
-    my ($dbname, $dbuser, $dbpass, $dbhost) = _get_args(@_);
+    my ($dbname, $dbuser, $dbpass, $dbhost, $table_prefix) = _get_args(@_);
 
     my $dsn = "dbi:Pg:dbname=$dbname";
     $dsn .= ";host=$dbhost" if $dbhost;
@@ -161,10 +167,12 @@ sub cleardb {
 			     AutoCommit => 1 } )
       or croak DBI::errstr;
 
-    print "Dropping tables... ";
+    $table_prefix = $table_prefix || '';
+
+    print "Dropping Pg tables($table_prefix)... ";
     my $sql = "SELECT tablename FROM pg_tables
                WHERE tablename in ("
-            . join( ",", map { $dbh->quote($_) } keys %create_sql ) . ")";
+            . join( ",", map { $dbh->quote($table_prefix . $_) } keys %create_sql ) . ")";
     foreach my $tableref (@{$dbh->selectall_arrayref($sql)}) {
         $dbh->do("DROP TABLE $tableref->[0]") or croak $dbh->errstr;
     }
@@ -177,7 +185,7 @@ sub cleardb {
 sub _get_args {
     if ( ref $_[0] ) {
         my %hash = %{$_[0]};
-        return @hash{ qw( dbname dbuser dbpass dbhost ) };
+        return @hash{ qw( dbname dbuser dbpass dbhost table_prefix ) };
     } else {
         return @_;
     }
@@ -189,14 +197,15 @@ sub _get_args {
 
 As requested by Podmaster.  Instead of passing arguments to the methods as
 
-  ($dbname, $dbuser, $dbpass, $dbhost)
+  ($dbname, $dbuser, $dbpass, $dbhost, $table_prefix)
 
 you can pass them as
 
   ( { dbname => $dbname,
       dbuser => $dbuser,
       dbpass => $dbpass,
-      dbhost => $dbhost
+      dbhost => $dbhost,
+      table_prefix => $table_prefix,
     }
   )
 
diff -pubr CGI-Wiki-0.50_01/lib/CGI/Wiki/Setup/SQLite.pm CGI-Wiki-Knew/lib/CGI/Wiki/Setup/SQLite.pm
--- CGI-Wiki-0.50_01/lib/CGI/Wiki/Setup/SQLite.pm	Thu Nov 20 12:53:15 2003
+++ CGI-Wiki-Knew/lib/CGI/Wiki/Setup/SQLite.pm	Mon Nov 24 20:49:15 2003
@@ -52,7 +52,7 @@ CGI::Wiki::Setup::SQLite - Set up tables
 =head1 SYNOPSIS
 
   use CGI::Wiki::Setup::SQLite;
-  CGI::Wiki::Setup::MySQLite::setup($dbfile);
+  CGI::Wiki::Setup::MySQLite::setup($dbfile, $table_prefix);
 
 =head1 DESCRIPTION
 
@@ -65,10 +65,11 @@ Set up a SQLite database for use as a CG
 =item B<setup>
 
   use CGI::Wiki::Setup::SQLite;
-  CGI::Wiki::Setup::SQLite::setup($dbfile);
+  CGI::Wiki::Setup::SQLite::setup($dbfile, $table_prefix);
+
+Takes two arguments - the name of the file that the SQLite database is
+stored in (mandatory), and a prefix to add to the table names (optional).
 
-Takes one argument - the name of the file that the SQLite database is
-stored in.
 
 B<NOTE:> If a table that the module wants to create already exists,
 C<setup> will leave it alone. This means that you can safely run this
@@ -79,17 +80,19 @@ again with a fresh database, run C<clear
 =cut
 
 sub setup {
-    my $dbfile = _get_args(@_);
+    my ($dbfile, $table_prefix) = _get_args(@_);
 
     my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", "", "",
 			   { PrintError => 1, RaiseError => 1,
 			     AutoCommit => 1 } )
       or croak DBI::errstr;
 
+    $table_prefix = $table_prefix || '';
+
     # Check whether tables exist, set them up if not.
     my $sql = "SELECT name FROM sqlite_master
                WHERE type='table' AND name in ("
-            . join( ",", map { $dbh->quote($_) } keys %create_sql ) . ")";
+            . join( ",", map { $dbh->quote($table_prefix . $_) } keys %create_sql ) . ")";
     my $sth = $dbh->prepare($sql) or croak $dbh->errstr;
     $sth->execute;
     my %tables;
@@ -98,11 +101,13 @@ sub setup {
     }
 
     foreach my $required ( keys %create_sql ) {
-        if ( $tables{$required} ) {
-            print "Table $required already exists... skipping...\n";
+        if ( $tables{$table_prefix . $required} ) {
+            print "Table $table_prefix$required already exists... skipping...\n";
         } else {
-            print "Creating table $required... done\n";
-            $dbh->do($create_sql{$required}) or croak $dbh->errstr;
+            print "Creating SQLite table $table_prefix$required... done\n";
+            my $sql = $create_sql{$required};
+            $sql =~ s/TABLE $required/TABLE $table_prefix$required/;
+            $dbh->do($sql) or croak $dbh->errstr;
         }
     }
 
@@ -115,11 +120,11 @@ sub setup {
   use CGI::Wiki::Setup::SQLite;
 
   # Clear out the old database completely, then set up tables afresh.
-  CGI::Wiki::Setup::SQLite::cleardb($dbfile);
-  CGI::Wiki::Setup::SQLite::setup($dbfile);
+  CGI::Wiki::Setup::SQLite::cleardb($dbfile, $table_prefix);
+  CGI::Wiki::Setup::SQLite::setup($dbfile, $table_prefix);
 
-Takes one argument - the name of the file that the SQLite database is
-stored in.
+Takes two arguments - the name of the file that the SQLite database is
+stored in (mandatory), and a prefix to add to the table names (optional).
 
 Clears out all L<CGI::Wiki> store tables from the database. B<NOTE>
 that this will lose all your data; you probably only want to use this
@@ -132,17 +137,19 @@ which search backend you're using.
 =cut
 
 sub cleardb {
-    my $dbfile = _get_args(@_);
+    my ($dbfile, $table_prefix) = _get_args(@_);
 
     my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", "", "",
 			   { PrintError => 1, RaiseError => 1,
 			     AutoCommit => 1 } )
       or croak DBI::errstr;
 
-    print "Dropping tables... ";
+    $table_prefix = $table_prefix || '';
+
+    print "Dropping SQLite tables($table_prefix)... ";
     my $sql = "SELECT name FROM sqlite_master
                WHERE type='table' AND name in ("
-            . join( ",", map { $dbh->quote($_) } keys %create_sql ) . ")";
+            . join( ",", map { $dbh->quote($table_prefix . $_) } keys %create_sql ) . ")";
     foreach my $tableref (@{$dbh->selectall_arrayref($sql)}) {
         $dbh->do("DROP TABLE $tableref->[0]") or croak $dbh->errstr;
     }
@@ -153,14 +160,12 @@ sub cleardb {
 }
 
 sub _get_args {
-    my @args;
     if ( ref $_[0] ) {
         my %hash = %{$_[0]};
-        @args = @hash{ qw( dbname ) };
+        return @hash{ qw( dbname table_prefix ) };
     } else {
-        @args = @_;
+        return @_;
     }
-    return $args[0];
 }
 
 =back
@@ -169,11 +174,12 @@ sub _get_args {
 
 As requested by Podmaster.  Instead of passing arguments to the methods as
 
-  ($dbfile)
+  ($dbfile, $table_prefix)
 
 you can pass them as
 
-  ( { dbname => $dbfile
+  ( { dbname => $dbfile,
+      table_prefix => $table_prefix,
     }
   )
 
diff -pubr CGI-Wiki-0.50_01/lib/CGI/Wiki/Store/Database.pm CGI-Wiki-Knew/lib/CGI/Wiki/Store/Database.pm
--- CGI-Wiki-0.50_01/lib/CGI/Wiki/Store/Database.pm	Thu Nov 20 11:31:25 2003
+++ CGI-Wiki-Knew/lib/CGI/Wiki/Store/Database.pm	Mon Nov 24 20:49:15 2003
@@ -34,11 +34,13 @@ Can't see yet why you'd want to use the 
   my $store = CGI::Wiki::Store::MySQL->new( dbname => "wiki",
 					    dbuser => "wiki",
 					    dbpass => "wiki",
-                                            dbhost => "db.example.com" );
+                                            dbhost => "db.example.com",
+                                            table_prefix => "something" );
 
 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.
+method doesn't require it. C<table_prefix> is also optional, and is only
+needed if you wish to share one database between multiple CGI::Wiki systems.
 
 =cut
 
@@ -60,6 +62,7 @@ sub _init {
     $self->{_dbuser} = $args{dbuser} || "";
     $self->{_dbpass} = $args{dbpass} || "";
     $self->{_dbhost} = $args{dbhost} || "";
+    $self->{_table_prefix} = $args{table_prefix} || "";
 
     # Connect to database and store the database handle.
     my ($dbname, $dbuser, $dbpass, $dbhost) =
@@ -134,11 +137,13 @@ sub _retrieve_node_data {
     my %data = $self->_retrieve_node_content( %args );
     return $data{content} unless wantarray;
 
+    my $metadata_table = $self->{_table_prefix} . "metadata";
+
     # If we want additional data then get it.  Note that $data{version}
     # will already have been set by C<_retrieve_node_content>, if it wasn't
     # specified in the call.
     my $dbh = $self->dbh;
-    my $sql = "SELECT metadata_type, metadata_value FROM metadata WHERE "
+    my $sql = "SELECT metadata_type, metadata_value FROM $metadata_table WHERE "
          . "node=" . $dbh->quote($args{name}) . " AND "
          . "version=" . $dbh->quote($data{version});
     my $sth = $dbh->prepare($sql);
@@ -163,13 +168,17 @@ sub _retrieve_node_content {
     my ($self, %args) = @_;
     croak "No valid node name supplied" unless $args{name};
     my $dbh = $self->dbh;
+
+    my $node_table = $self->{_table_prefix} . "node";
+    my $content_table = $self->{_table_prefix} . "content";
+
     my $sql;
     if ( $args{version} ) {
-        $sql = "SELECT text, version, modified FROM content"
+        $sql = "SELECT text, version, modified FROM $content_table"
              . " WHERE  name=" . $dbh->quote($args{name})
              . " AND version=" . $dbh->quote($args{version});
     } else {
-        $sql = "SELECT text, version, modified FROM node
+        $sql = "SELECT text, version, modified FROM $node_table
                 WHERE name=" . $dbh->quote($args{name});
     }
     my @results = $dbh->selectrow_array($sql);
@@ -260,7 +269,10 @@ sub list_backlinks {
     my $node = $args{node};
     croak "Must supply a node name" unless $node;
     my $dbh = $self->dbh;
-    my $sql = "SELECT link_from FROM internal_links WHERE link_to="
+
+    my $internal_links_table = $self->{_table_prefix} . "internal_links";
+
+    my $sql = "SELECT link_from FROM $internal_links_table WHERE link_to="
             . $dbh->quote($node);
     my $sth = $dbh->prepare($sql);
     $sth->execute or croak $dbh->errstr;
@@ -285,10 +297,14 @@ link to it.
 sub list_dangling_links {
     my $self = shift;
     my $dbh = $self->dbh;
-    my $sql = "SELECT DISTINCT internal_links.link_to
-               FROM internal_links LEFT JOIN node
-                                   ON node.name=internal_links.link_to
-               WHERE node.version IS NULL";
+
+    my $node_table = $self->{_table_prefix} . "node";
+    my $internal_links_table = $self->{_table_prefix} . "internal_links";
+
+    my $sql = "SELECT DISTINCT $internal_links_table.link_to
+               FROM $internal_links_table LEFT JOIN $node_table
+                                   ON $node_table.name=$internal_links_table.link_to
+               WHERE $node_table.version IS NULL";
     my $sth = $dbh->prepare($sql);
     $sth->execute or croak $dbh->errstr;
     my @links;
@@ -353,27 +369,32 @@ sub write_node_post_locking {
                                 @args{ qw( node content links_to metadata) };
     my $dbh = $self->dbh;
 
+    my $metadata_table = $self->{_table_prefix} . "metadata";
+    my $node_table = $self->{_table_prefix} . "node";
+    my $content_table = $self->{_table_prefix} . "content";
+    my $internal_links_table = $self->{_table_prefix} . "internal_links";
+
     my $timestamp = $self->_get_timestamp();
     my @links_to = @{ $links_to_ref || [] }; # default to empty array
     my $version;
 
     # Either inserting a new page or updating an old one.
-    my $sql = "SELECT count(*) FROM node WHERE name=" . $dbh->quote($node);
+    my $sql = "SELECT count(*) FROM $node_table WHERE name=" . $dbh->quote($node);
     my $exists = @{ $dbh->selectcol_arrayref($sql) }[0] || 0;
     if ($exists) {
-        $sql = "SELECT max(version) FROM content
+        $sql = "SELECT max(version) FROM $content_table
                 WHERE name=" . $dbh->quote($node);
         $version = @{ $dbh->selectcol_arrayref($sql) }[0] || 0;
         croak "Can't get version number" unless $version;
         $version++;
-        $sql = "UPDATE node SET version=" . $dbh->quote($version)
+        $sql = "UPDATE $node_table SET version=" . $dbh->quote($version)
 	     . ", text=" . $dbh->quote($content)
 	     . ", modified=" . $dbh->quote($timestamp)
 	     . " WHERE name=" . $dbh->quote($node);
 	$dbh->do($sql) or croak "Error updating database: " . DBI->errstr;
     } else {
         $version = 1;
-        $sql = "INSERT INTO node (name, version, text, modified)
+        $sql = "INSERT INTO $node_table (name, version, text, modified)
                 VALUES ("
              . join(", ", map { $dbh->quote($_) }
 		              ($node, $version, $content, $timestamp)
@@ -383,7 +404,7 @@ sub write_node_post_locking {
     }
 
     # In either case we need to add to the history.
-    $sql = "INSERT INTO content (name, version, text, modified)
+    $sql = "INSERT INTO $content_table (name, version, text, modified)
             VALUES ("
          . join(", ", map { $dbh->quote($_) }
 		          ($node, $version, $content, $timestamp)
@@ -392,10 +413,10 @@ sub write_node_post_locking {
     $dbh->do($sql) or croak "Error updating database: " . DBI->errstr;
 
     # And to the backlinks.
-    $dbh->do("DELETE FROM internal_links WHERE link_from="
+    $dbh->do("DELETE FROM $internal_links_table WHERE link_from="
              . $dbh->quote($node) ) or croak $dbh->errstr;
     foreach my $links_to ( @links_to ) {
-        $sql = "INSERT INTO internal_links (link_from, link_to) VALUES ("
+        $sql = "INSERT INTO $internal_links_table (link_from, link_to) VALUES ("
              . join(", ", map { $dbh->quote($_) } ( $node, $links_to ) ) . ")";
         # Better to drop a backlink or two than to lose the whole update.
         # Shevek wants a case-sensitive wiki, Jerakeen wants a case-insensitive
@@ -427,7 +448,7 @@ sub write_node_post_locking {
             @values = keys %unique;
 
             foreach my $value ( @values ) {
-                my $sql = "INSERT INTO metadata "
+                my $sql = "INSERT INTO $metadata_table "
                     . "(node, version, metadata_type, metadata_value) VALUES ("
                     . join(", ", map { $dbh->quote($_) }
                                  ( $node, $version, $type, $value )
@@ -439,7 +460,7 @@ sub write_node_post_locking {
         # Otherwise grab a checksum and store that.
             my $type_to_store  = "__" . $type . "__checksum";
             my $value_to_store = $self->_checksum_hashes( @values );
-            my $sql = "INSERT INTO metadata "
+            my $sql = "INSERT INTO $metadata_table "
                     . "(node, version, metadata_type, metadata_value) VALUES ("
                     . join(", ", map { $dbh->quote($_) }
                            ( $node, $version, $type_to_store, $value_to_store )
@@ -488,14 +509,20 @@ sub delete_node {
     my ($self, $node) = @_;
     my $dbh = $self->dbh;
     my $name = $dbh->quote($node);
+
+    my $metadata_table = $self->{_table_prefix} . "metadata";
+    my $node_table = $self->{_table_prefix} . "node";
+    my $content_table = $self->{_table_prefix} . "content";
+    my $internal_links_table = $self->{_table_prefix} . "internal_links";
+
     # Should start a transaction here.  FIXME.
-    my $sql = "DELETE FROM node WHERE name=$name";
+    my $sql = "DELETE FROM $node_table WHERE name=$name";
     $dbh->do($sql) or croak "Deletion failed: " . DBI->errstr;
-    $sql = "DELETE FROM content WHERE name=$name";
+    $sql = "DELETE FROM $content_table WHERE name=$name";
     $dbh->do($sql) or croak "Deletion failed: " . DBI->errstr;
-    $sql = "DELETE FROM internal_links WHERE link_from=$name";
+    $sql = "DELETE FROM $internal_links_table WHERE link_from=$name";
     $dbh->do($sql) or croak $dbh->errstr;
-    $sql = "DELETE FROM metadata WHERE node=$name";
+    $sql = "DELETE FROM $metadata_table WHERE node=$name";
     $dbh->do($sql) or croak $dbh->errstr;
     # And finish it here.
     return 1;
@@ -617,8 +644,13 @@ sub _find_recent_changes_by_criteria {
                                                 metadata_was metadata_wasnt) };
     my $dbh = $self->dbh;
 
+    my $metadata_table = $self->{_table_prefix} . "metadata";
+    my $node_table = $self->{_table_prefix} . "node";
+    my $content_table = $self->{_table_prefix} . "content";
+    my $internal_links_table = $self->{_table_prefix} . "internal_links";
+
     my @where;
-    my $main_table = "node";
+    my $main_table = $node_table;
     if ( $metadata_is ) {
         if ( scalar keys %$metadata_is > 1 ) {
             croak "metadata_is must have one key and one value only";
@@ -627,8 +659,8 @@ sub _find_recent_changes_by_criteria {
         my $value  = $metadata_is->{$type};
         croak "metadata_is must have one key and one value only"
           if ref $value;
-	push @where, "metadata.metadata_type=" . $dbh->quote($type);
-	push @where, "metadata.metadata_value=" . $dbh->quote($value);
+	push @where, "$metadata_table.metadata_type=" . $dbh->quote($type);
+	push @where, "$metadata_table.metadata_value=" . $dbh->quote($value);
     } elsif ( $metadata_isnt ) {
         if ( scalar keys %$metadata_isnt > 1 ) {
             croak "metadata_isnt must have one key and one value only";
@@ -640,11 +672,11 @@ sub _find_recent_changes_by_criteria {
         my @omit = $self->list_nodes_by_metadata(
             metadata_type  => $type,
             metadata_value => $value );
-        push @where, "node.name NOT IN ("
+        push @where, "$node_table.name NOT IN ("
                    . join(",", map { $dbh->quote($_) } @omit ) . ")"
           if scalar @omit;
     } elsif ( $metadata_was ) {
-        $main_table = "content";
+        $main_table = $content_table;
         if ( scalar keys %$metadata_was > 1 ) {
             croak "metadata_was must have one key and one value only";
 	}
@@ -652,10 +684,10 @@ sub _find_recent_changes_by_criteria {
 	my $value  = $metadata_was->{$type};
             croak "metadata_was must have one key and one value only"
           if ref $value;
-        push @where, "metadata.metadata_type=" . $dbh->quote($type);
-	push @where, "metadata.metadata_value=" . $dbh->quote($value);
+        push @where, "$metadata_table.metadata_type=" . $dbh->quote($type);
+	push @where, "$metadata_table.metadata_value=" . $dbh->quote($value);
     } elsif ( $metadata_wasnt ) {
-        $main_table = "content";
+        $main_table = $content_table;
         if ( scalar keys %$metadata_wasnt > 1 ) {
             croak "metadata_wasnt must have one key and one value only";
 	}
@@ -668,8 +700,8 @@ sub _find_recent_changes_by_criteria {
             metadata_was => $metadata_wasnt,
         );
         foreach my $omit ( @omits ) {
-            push @where, "( content.name != " . $dbh->quote($omit->{name})
-                 . "  OR content.version != " . $dbh->quote($omit->{version})
+            push @where, "( $content_table.name != " . $dbh->quote($omit->{name})
+                 . "  OR $content_table.version != " . $dbh->quote($omit->{version})
                  . ")";
 	}
     }
@@ -684,9 +716,9 @@ sub _find_recent_changes_by_criteria {
                                $main_table.version,
                                $main_table.modified
                FROM $main_table
-                    LEFT JOIN metadata
-                           ON $main_table.name=metadata.node
-                          AND $main_table.version=metadata.version
+                    LEFT JOIN $metadata_table
+                           ON $main_table.name=$metadata_table.node
+                          AND $main_table.version=$metadata_table.version
               "
             . ( scalar @where ? " WHERE " . join(" AND ",@where)
 			                     : "" )
@@ -704,7 +736,7 @@ sub _find_recent_changes_by_criteria {
     foreach my $find ( @finds ) {
         my %metadata;
         my $sth = $dbh->prepare( "SELECT metadata_type, metadata_value
-                                  FROM metadata WHERE node=? AND version=?" );
+                                  FROM $metadata_table WHERE node=? AND version=?" );
         $sth->execute( $find->{name}, $find->{version} );
         while ( my ($type, $value) = $sth->fetchrow_array ) {
 	    if ( defined $metadata{$type} ) {
@@ -730,7 +762,10 @@ won't be in any kind of order; do any so
 sub list_all_nodes {
     my $self = shift;
     my $dbh = $self->dbh;
-    my $sql = "SELECT name FROM node;";
+
+    my $node_table = $self->{_table_prefix} . "node";
+
+    my $sql = "SELECT name FROM $node_table;";
     my $nodes = $dbh->selectall_arrayref($sql); 
     return ( map { $_->[0] } (@$nodes) );
 }
@@ -794,12 +829,17 @@ sub list_nodes_by_metadata {
 }
 
 sub _get_list_by_metadata_sql {
+    my $self = shift;
+
+    my $metadata_table = $self->{_table_prefix} . "metadata";
+    my $node_table = $self->{_table_prefix} . "node";
+
     # can be over-ridden by database-specific subclasses
-    return "SELECT node.name FROM node, metadata"
-         . " WHERE node.name=metadata.node"
-         . " AND node.version=metadata.version"
-         . " AND metadata.metadata_type = ? "
-         . " AND metadata.metadata_value = ? ";
+    return "SELECT $node_table.name FROM $node_table, $metadata_table"
+         . " WHERE $node_table.name=$metadata_table.node"
+         . " AND $node_table.version=$metadata_table.version"
+         . " AND $metadata_table.metadata_type = ? "
+         . " AND $metadata_table.metadata_value = ? ";
 }
 
 =item B<dbh>
@@ -866,6 +906,19 @@ backend storage.
 sub dbhost {
     my $self = shift;
     return $self->{_dbhost};
+}
+
+=item B<table_prefix>
+
+  my $table_prefix = $store->table_prefix;
+
+Returns the optional prefix for tables in the database backend.
+
+=cut
+
+sub table_prefix {
+    my $self = shift;
+    return $self->{_table_prefix};
 }
 
 # Cleanup.
diff -pubr CGI-Wiki-0.50_01/lib/CGI/Wiki/Store/Pg.pm CGI-Wiki-Knew/lib/CGI/Wiki/Store/Pg.pm
--- CGI-Wiki-0.50_01/lib/CGI/Wiki/Store/Pg.pm	Thu Nov 20 11:31:25 2003
+++ CGI-Wiki-Knew/lib/CGI/Wiki/Store/Pg.pm	Mon Nov 24 20:49:15 2003
@@ -79,18 +79,22 @@ sub check_and_write_node {
 
 sub _get_list_by_metadata_sql {
     my ($self, %args) = @_;
+
+    my $metadata_table = $self->{_table_prefix} . "metadata";
+    my $node_table = $self->{_table_prefix} . "node";
+
     if ( $args{ignore_case} ) {
-        return "SELECT node.name FROM node, metadata"
-             . " WHERE node.name=metadata.node"
-             . " AND node.version=metadata.version"
-             . " AND lower(metadata.metadata_type) = ? "
-             . " AND lower(metadata.metadata_value) = ? ";
+        return "SELECT $node_table.name FROM $node_table, $metadata_table"
+             . " WHERE $node_table.name=$metadata_table.node"
+             . " AND $node_table.version=$metadata_table.version"
+             . " AND lower($metadata_table.metadata_type) = ? "
+             . " AND lower($metadata_table.metadata_value) = ? ";
     } else {
-        return "SELECT node.name FROM node, metadata"
-             . " WHERE node.name=metadata.node"
-             . " AND node.version=metadata.version"
-             . " AND metadata.metadata_type = ? "
-             . " AND metadata.metadata_value = ? ";
+        return "SELECT $node_table.name FROM $node_table, $metadata_table"
+             . " WHERE $node_table.name=$metadata_table.node"
+             . " AND $node_table.version=$metadata_table.version"
+             . " AND $metadata_table.metadata_type = ? "
+             . " AND $metadata_table.metadata_value = ? ";
     }
 }
 
diff -pubr CGI-Wiki-0.50_01/lib/CGI/Wiki/Store/SQLite.pm CGI-Wiki-Knew/lib/CGI/Wiki/Store/SQLite.pm
--- CGI-Wiki-0.50_01/lib/CGI/Wiki/Store/SQLite.pm	Thu Nov 20 11:31:25 2003
+++ CGI-Wiki-Knew/lib/CGI/Wiki/Store/SQLite.pm	Mon Nov 24 20:49:15 2003
@@ -93,18 +93,22 @@ sub check_and_write_node {
 
 sub _get_list_by_metadata_sql {
     my ($self, %args) = @_;
+
+    my $metadata_table = $self->{_table_prefix} . "metadata";
+    my $node_table = $self->{_table_prefix} . "node";
+
     if ( $args{ignore_case} ) {
-        return "SELECT node.name FROM node, metadata"
-             . " WHERE node.name=metadata.node"
-             . " AND node.version=metadata.version"
-             . " AND metadata.metadata_type LIKE ? "
-             . " AND metadata.metadata_value LIKE ? ";
+        return "SELECT $node_table.name FROM $node_table, $metadata_table"
+             . " WHERE $node_table.name=$metadata_table.node"
+             . " AND $node_table.version=$metadata_table.version"
+             . " AND $metadata_table.metadata_type LIKE ? "
+             . " AND $metadata_table.metadata_value LIKE ? ";
     } else {
-        return "SELECT node.name FROM node, metadata"
-             . " WHERE node.name=metadata.node"
-             . " AND node.version=metadata.version"
-             . " AND metadata.metadata_type = ? "
-             . " AND metadata.metadata_value = ? ";
+        return "SELECT $node_table.name FROM $node_table, $metadata_table"
+             . " WHERE $node_table.name=$metadata_table.node"
+             . " AND $node_table.version=$metadata_table.version"
+             . " AND $metadata_table.metadata_type = ? "
+             . " AND $metadata_table.metadata_value = ? ";
     }
 }
 
diff -pubr CGI-Wiki-0.50_01/lib/CGI/Wiki/TestLib.pm CGI-Wiki-Knew/lib/CGI/Wiki/TestLib.pm
--- CGI-Wiki-0.50_01/lib/CGI/Wiki/TestLib.pm	Thu Nov 20 12:14:05 2003
+++ CGI-Wiki-Knew/lib/CGI/Wiki/TestLib.pm	Mon Nov 24 20:49:15 2003
@@ -41,13 +41,16 @@ search and storage backends.
 
 my %configured = %CGI::Wiki::TestConfig::config;
 
+my @prefixes = ( undef, '', 'one_' );
+
 my %datastore_info;
 foreach my $dbtype (qw( MySQL Pg SQLite )) {
+  foreach my $tblprefix (0..$#prefixes) {
     if ( $configured{$dbtype}{dbname} ) {
         my %config = %{ $configured{$dbtype} };
 	my $store_class = "CGI::Wiki::Store::$dbtype";
 	my $setup_class = "CGI::Wiki::Setup::$dbtype";
-        $datastore_info{$dbtype} = {
+        $datastore_info{$dbtype . $tblprefix} = {
                                      class  => $store_class,
                                      setup_class => $setup_class,
                                      params => {
@@ -55,23 +58,28 @@ foreach my $dbtype (qw( MySQL Pg SQLite 
 		       		                 dbuser => $config{dbuser},
 				                 dbpass => $config{dbpass},
 			                         dbhost => $config{dbhost},
+                                                 table_prefix => $prefixes[$tblprefix],
                                                },
                                    };
     }
+  }
 }
 
 my %dbixfts_info;
 # DBIxFTS only works with MySQL.
 if ( $configured{dbixfts} && $configured{MySQL}{dbname} ) {
+  foreach my $tblprefix (0..$#prefixes) {
     my %config = %{ $configured{MySQL} };
-    $dbixfts_info{MySQL} = {
+    $dbixfts_info{'MySQL' . $tblprefix} = {
                              db_params => {
                                             dbname => $config{dbname},
 		       		            dbuser => $config{dbuser},
 				            dbpass => $config{dbpass},
 			                    dbhost => $config{dbhost},
+                                            table_prefix => $prefixes[$tblprefix],
                                           },
                            };
+  }
 }
 
 my %sii_info;
@@ -126,23 +134,27 @@ if ( $configured{search_invertedindex} )
 # @wiki_info describes which searches work with which stores.
 
 # Database-specific searchers.
-push @wiki_info, { datastore_info => $datastore_info{MySQL},
-                   dbixfts_info   => $dbixfts_info{MySQL} }
-  if ( $datastore_info{MySQL} and $dbixfts_info{MySQL} );
-push @wiki_info, { datastore_info => $datastore_info{MySQL},
+foreach my $tblprefix (0..$#prefixes) {
+  push @wiki_info, { datastore_info => $datastore_info{'MySQL' . $tblprefix},
+                     dbixfts_info   => $dbixfts_info{'MySQL' . $tblprefix} }
+    if ( $datastore_info{'MySQL' . $tblprefix} and $dbixfts_info{'MySQL'} . $tblprefix );
+  push @wiki_info, { datastore_info => $datastore_info{'MySQL' . $tblprefix},
                    sii_info       => $sii_info{MySQL} }
-  if ( $datastore_info{MySQL} and $sii_info{MySQL} );
-push @wiki_info, { datastore_info => $datastore_info{Pg},
+    if ( $datastore_info{'MySQL' . $tblprefix} and $sii_info{MySQL} );
+  push @wiki_info, { datastore_info => $datastore_info{'Pg' . $tblprefix},
                    sii_info       => $sii_info{Pg} }
-  if ( $datastore_info{Pg} and $sii_info{Pg} );
+    if ( $datastore_info{'Pg' . $tblprefix} and $sii_info{Pg} );
+}
 
 # All stores are compatible with the default S::II search, and with no search.
 foreach my $dbtype ( qw( MySQL Pg SQLite ) ) {
-    push @wiki_info, { datastore_info => $datastore_info{$dbtype},
+  foreach my $tblprefix (0..$#prefixes) {
+    push @wiki_info, { datastore_info => $datastore_info{$dbtype . $tblprefix},
                        sii_info       => $sii_info{DB_File} }
-      if ( $datastore_info{$dbtype} and $sii_info{DB_File} );
-    push @wiki_info, { datastore_info => $datastore_info{$dbtype} }
-      if $datastore_info{$dbtype};
+      if ( $datastore_info{$dbtype . $tblprefix} and $sii_info{DB_File} );
+    push @wiki_info, { datastore_info => $datastore_info{$dbtype . $tblprefix} }
+      if $datastore_info{$dbtype . $tblprefix};
+  }
 }
 
 =head1 METHODS
@@ -170,7 +182,7 @@ sub new_wiki_maker {
     bless $iterator, $class;
     return $iterator;
 }
-
+use Data::Dumper;
 sub new_wiki {
     my $self = shift;
     return undef if $$self > $#wiki_info;
@@ -183,7 +195,13 @@ sub new_wiki {
     eval "require $setup_class";
     {
       no strict "refs";
-      &{"$setup_class\:\:cleardb"}( $datastore_info{params} );
+
+      my $_params = { %{$datastore_info{params}} };
+      foreach my $tblprefix (@prefixes) {
+        $_params->{table_prefix} = $tblprefix;
+        &{"$setup_class\:\:cleardb"}( $_params );
+      }
+      #&{"$setup_class\:\:cleardb"}( $datastore_info{params} );
       &{"$setup_class\:\:setup"}( $datastore_info{params} );
     }
     my $class =  $datastore_info{class};
@@ -202,7 +220,7 @@ sub new_wiki {
           or croak "Can't connect to $dbconfig{dbname} using $dsn: " . DBI->errstr;
         require CGI::Wiki::Setup::DBIxFTSMySQL;
         CGI::Wiki::Setup::DBIxFTSMySQL::setup(
-                                        @dbconfig{ qw( dbuser dbname dbpass ) }
+                                        @dbconfig{ qw( dbuser dbname dbpass dbhost table_prefix ) }
                                              );
         require CGI::Wiki::Search::DBIxFTS;
         $wiki_config{search} = CGI::Wiki::Search::DBIxFTS->new( dbh => $dbh );
diff -pubr CGI-Wiki-0.50_01/t/010_metadata.t CGI-Wiki-Knew/t/010_metadata.t
--- CGI-Wiki-0.50_01/t/010_metadata.t	Thu Nov 20 13:53:59 2003
+++ CGI-Wiki-Knew/t/010_metadata.t	Mon Nov 24 20:49:15 2003
@@ -69,7 +69,8 @@ while ( my $wiki = $iterator->new_wiki )
     SKIP: {
         skip "Test only works on database backends", 1 unless $dbh;
         # White box testing.
-        my $sql = "SELECT metadata_type, metadata_value FROM metadata
+        my $metadata_table = $wiki->store->table_prefix . "metadata";
+        my $sql = "SELECT metadata_type, metadata_value FROM $metadata_table
                    WHERE node='Reun Thai'";
         my $sth = $dbh->prepare($sql);
         $sth->execute;
------=_20031204173305_66345--