Index: /trunk/t/high-funcid-starvation.t
===================================================================
--- /trunk/t/high-funcid-starvation.t (revision 58)
+++ /trunk/t/high-funcid-starvation.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 8;
+use Test::More tests => 12;
 
 run_tests(4, sub {
@@ -19,5 +19,5 @@
     }
 
-    my $db1 = DBI->connect(dsn_for("ts1"), 'root', '');
+    my $db1 = DBI->connect(dsn_for("ts1"), $ENV{TS_DB_USER}, $ENV{TS_DB_PASS});
     die unless $db1;
 
Index: /trunk/t/coalesce.t
===================================================================
--- /trunk/t/coalesce.t (revision 84)
+++ /trunk/t/coalesce.t (revision 164)
@@ -7,5 +7,5 @@
 
 use TheSchwartz;
-use Test::More tests => 28;
+use Test::More tests => 14 * 3;
 
 run_tests(14, sub {
Index: /trunk/t/evenly-distribute.t
===================================================================
--- /trunk/t/evenly-distribute.t (revision 89)
+++ /trunk/t/evenly-distribute.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 8;
+use Test::More tests => 12;
 
 run_tests(4, sub {
@@ -19,6 +19,6 @@
     }
 
-    my $db1 = DBI->connect(dsn_for("ts1"), 'root', '');
-    my $db2 = DBI->connect(dsn_for("ts2"), 'root', '');
+    my $db1 = DBI->connect(dsn_for("ts1"), $ENV{TS_DB_USER}, $ENV{TS_DB_PASS});
+    my $db2 = DBI->connect(dsn_for("ts2"), $ENV{TS_DB_USER}, $ENV{TS_DB_PASS});
     die unless $db1 && $db2;
 
Index: /trunk/t/priority.t
===================================================================
--- /trunk/t/priority.t (revision 136)
+++ /trunk/t/priority.t (revision 164)
@@ -7,5 +7,5 @@
 
 use TheSchwartz;
-use Test::More tests => 62;
+use Test::More tests => 31*3;
 
 our $record_expected;
@@ -58,4 +58,5 @@
     my ($class, $job) = @_;
     my $priority = $job->priority;
+
     ok((!defined($main::record_expected) && (!defined($priority)))
         || ($priority == $main::record_expected), "priority matches expected priority");
Index: /trunk/t/empty-db.t
===================================================================
--- /trunk/t/empty-db.t (revision 36)
+++ /trunk/t/empty-db.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 6;
+use Test::More tests => 9;
 
 run_tests(3, sub {
@@ -16,6 +16,6 @@
                                                 {
                                                     dsn  => dsn_for('tempty1'),
-                                                    user => "root",
-                                                    pass => "",
+                                                    user => $ENV{TS_DB_USER},
+                                                    pass =>  $ENV{TS_DB_PASS},
                                                 },
                                                 ]);
Index: /trunk/t/fail-working-multiple.t
===================================================================
--- /trunk/t/fail-working-multiple.t (revision 84)
+++ /trunk/t/fail-working-multiple.t (revision 164)
@@ -7,5 +7,5 @@
 
 use TheSchwartz;
-use Test::More tests => 8;
+use Test::More tests => 12;
 
 run_tests(4, sub {
Index: /trunk/t/scoreboard.t
===================================================================
--- /trunk/t/scoreboard.t (revision 160)
+++ /trunk/t/scoreboard.t (revision 164)
@@ -6,5 +6,5 @@
 require 't/lib/db-common.pl';
 
-use Test::More tests => 20;
+use Test::More tests => 30;
 
 use TheSchwartz;
@@ -26,6 +26,6 @@
                                           map { {
                                               dsn  => dsn_for($_),
-                                              user => "root",
-                                              pass => "",
+                                              user => $ENV{TS_DB_USER},
+                                              pass => $ENV{TS_DB_PASS},
                                               prefix => $pfx,
                                           } } @$dbs
Index: /trunk/t/replace-with.t
===================================================================
--- /trunk/t/replace-with.t (revision 84)
+++ /trunk/t/replace-with.t (revision 164)
@@ -7,5 +7,5 @@
 
 use TheSchwartz;
-use Test::More tests => 20;
+use Test::More tests => 30;
 
 run_tests(10, sub {
Index: /trunk/t/cleanup.t
===================================================================
--- /trunk/t/cleanup.t (revision 114)
+++ /trunk/t/cleanup.t (revision 164)
@@ -7,5 +7,5 @@
 
 use TheSchwartz;
-use Test::More tests => 20;
+use Test::More tests => 30;
 
 # for testing:
@@ -15,5 +15,5 @@
 run_tests(10, sub {
     my $client = test_client(dbs => ['ts1']);
-    my $dbh = DBI->connect(dsn_for("ts1"), 'root', '');
+    my $dbh = DBI->connect(dsn_for("ts1"), $ENV{TS_DB_USER}, $ENV{TS_DB_PASS});
     $client->can_do("Worker::Fail");
     $client->can_do("Worker::Complete");
Index: /trunk/t/grab_and_work_on.t
===================================================================
--- /trunk/t/grab_and_work_on.t (revision 141)
+++ /trunk/t/grab_and_work_on.t (revision 164)
@@ -7,5 +7,5 @@
 
 use TheSchwartz;
-use Test::More tests => 18;
+use Test::More tests => 27;
 
 run_tests(9, sub {
Index: /trunk/t/retry-delay.t
===================================================================
--- /trunk/t/retry-delay.t (revision 36)
+++ /trunk/t/retry-delay.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 16;
+use Test::More tests => 24;
 
 run_tests(8, sub {
Index: /trunk/t/server-time.t
===================================================================
--- /trunk/t/server-time.t (revision 161)
+++ /trunk/t/server-time.t (revision 164)
@@ -7,5 +7,5 @@
 
 use TheSchwartz;
-use Test::More tests => 4;
+use Test::More tests => 6;
 
 run_tests(2, sub {
Index: /trunk/t/dead-dbs.t
===================================================================
--- /trunk/t/dead-dbs.t (revision 36)
+++ /trunk/t/dead-dbs.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 4;
+use Test::More tests => 6;
 
 run_tests(2, sub {
Index: /trunk/t/lib/db-common.pl
===================================================================
--- /trunk/t/lib/db-common.pl (revision 160)
+++ /trunk/t/lib/db-common.pl (revision 164)
@@ -9,4 +9,5 @@
 
     run_tests_mysql($n, $code);
+    run_tests_pgsql($n, $code);
     run_tests_sqlite($n, $code);
 }
@@ -21,7 +22,19 @@
   SKIP: {
       local $ENV{USE_MYSQL} = 1;
+      local $ENV{TS_DB_USER} ||= 'root';
       my $dbh = eval { mysql_dbh() };
       skip "MySQL not accessible as root on localhost", $n if $@;
       skip "InnoDB not available on localhost's MySQL", $n if $innodb && ! has_innodb($dbh);
+      $code->();
+  }
+}
+
+sub run_tests_pgsql {
+    my ($n, $code) = @_;
+  SKIP: {
+      local $ENV{USE_PGSQL} = 1;
+      local $ENV{TS_DB_USER} ||= 'postgres';
+      my $dbh = eval { pgsql_dbh() };
+      skip "PgSQL not accessible as root on localhost", $n if $@;
       $code->();
   }
@@ -70,6 +83,6 @@
                                           map { {
                                               dsn  => dsn_for($_),
-                                              user => "root",
-                                              pass => "",
+                                              user => $ENV{TS_DB_USER},
+                                              pass => $ENV{TS_DB_PASS},
                                               prefix => $pfx,
                                           } } @$dbs
@@ -92,4 +105,5 @@
 sub schema_file {
     return "doc/schema.sql" if $ENV{USE_MYSQL};
+    return "doc/schema-postgres.sql" if $ENV{USE_PGSQL};
     return "t/schema-sqlite.sql";
 }
@@ -109,4 +123,7 @@
     if ($ENV{USE_MYSQL}) {
         return 'dbi:mysql:' . mysql_dbname($dbname);
+    }
+    elsif ($ENV{USE_PGSQL}) {
+        return 'dbi:Pg:dbname=' . mysql_dbname($dbname);
     } else {
         return 'dbi:SQLite:dbname=' . db_filename($dbname);
@@ -130,10 +147,14 @@
             create_mysql_db(mysql_dbname($dbname));
         }
+        elsif ($ENV{USE_PGSQL}) {
+            create_pgsql_db(mysql_dbname($dbname));
+        }
         my $dbh = DBI->connect(dsn_for($dbname),
-            'root', '', { RaiseError => 1, PrintError => 0 })
+            $ENV{TS_DB_USER}, $ENV{TS_DB_PASS}, { RaiseError => 1, PrintError => 0 })
             or die "Couldn't connect: $!\n";
         my @sql = load_sql($schema);
         for my $sql (@sql) {
-            $sql =~ s!^\s*create\s+table\s+(\w+)!CREATE TABLE ${pfx}$1!i;
+            $sql =~ s!^\s*create\s+table\s+(\w+)!CREATE TABLE ${pfx}$1!mi;
+            $sql =~ s!^\s*(create.*?index)\s+(\w+)\s+on\s+(\w+)!$1 $2 ON ${pfx}$3!i;
             $sql .= " ENGINE=INNODB\n" if $ENV{USE_MYSQL};
             $dbh->do($sql);
@@ -148,4 +169,13 @@
 }
 
+my $pg_dbh;
+
+sub pgsql_dbh {
+    return $pg_dbh if $pg_dbh;
+    $pg_dbh ||=
+        DBI->connect("DBI:Pg:dbname=postgres", "postgres", "", { RaiseError => 1 })
+            or die "Couldn't connect to database";
+}
+
 sub create_mysql_db {
     my $dbname = shift;
@@ -156,4 +186,15 @@
     my $dbname = shift;
     mysql_dbh()->do("DROP DATABASE IF EXISTS $dbname");
+}
+
+sub create_pgsql_db {
+    my $dbname = shift;
+    pgsql_dbh()->do("CREATE DATABASE $dbname");
+}
+
+sub drop_pgsql_db {
+    my $dbname = shift;
+    undef $pg_dbh;
+    eval { pgsql_dbh()->do("DROP DATABASE IF EXISTS $dbname") };
 }
 
@@ -163,4 +204,6 @@
         if ($ENV{USE_MYSQL}) {
             drop_mysql_db(mysql_dbname($db));
+        } elsif ($ENV{USE_PGSQL}) {
+            drop_pgsql_db(mysql_dbname($db));
         } else {
             my $file = db_filename($db);
Index: /trunk/t/insert-and-do.t
===================================================================
--- /trunk/t/insert-and-do.t (revision 103)
+++ /trunk/t/insert-and-do.t (revision 164)
@@ -7,5 +7,5 @@
 
 use TheSchwartz;
-use Test::More tests => 52;
+use Test::More tests => 26*3;
 
 run_tests(26, sub {
Index: /trunk/t/work-before-funcids-exist.t
===================================================================
--- /trunk/t/work-before-funcids-exist.t (revision 43)
+++ /trunk/t/work-before-funcids-exist.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 4;
+use Test::More tests => 6;
 
 run_tests(2, sub {
Index: /trunk/t/unique.t
===================================================================
--- /trunk/t/unique.t (revision 64)
+++ /trunk/t/unique.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 12;
+use Test::More tests => 18;
 
 #use Data::ObjectDriver;
Index: /trunk/t/funcid.t
===================================================================
--- /trunk/t/funcid.t (revision 42)
+++ /trunk/t/funcid.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 16;
+use Test::More tests => 24;
 
 run_tests(8, sub {
Index: /trunk/t/api.t
===================================================================
--- /trunk/t/api.t (revision 161)
+++ /trunk/t/api.t (revision 164)
@@ -8,5 +8,5 @@
 
 use TheSchwartz;
-use Test::More tests => 108;
+use Test::More tests => 54*3;
 
 run_tests(54, sub {
Index: /trunk/doc/schema-postgres.sql
===================================================================
--- /trunk/doc/schema-postgres.sql (revision 131)
+++ /trunk/doc/schema-postgres.sql (revision 164)
@@ -32,7 +32,8 @@
         grabbed_until   INTEGER NOT NULL,
         priority        SMALLINT,
-        coalesce        VARCHAR(255),
-        UNIQUE(funcid, uniqkey)
+        coalesce        VARCHAR(255)
 );
+
+CREATE UNIQUE INDEX job_funcid_uniqkey ON job (funcid, uniqkey);
 
 CREATE INDEX job_funcid_runafter ON job (funcid, run_after);
