Administration: Die Funktion zur Aktualisierung von nicht aktuellen Datenbanken neu...
authorMoritz Bunkus <m.bunkus@linet-services.de>
Wed, 16 May 2007 15:13:20 +0000 (15:13 +0000)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Wed, 16 May 2007 15:13:20 +0000 (15:13 +0000)
16 files changed:
SL/User.pm
bin/mozilla/admin.pl
locale/de/admin
locale/de/all
templates/webpages/admin/dbadmin_de.html
templates/webpages/admin/dbadmin_master.html
templates/webpages/admin/dbupgrade_all_done_de.html [new file with mode: 0644]
templates/webpages/admin/dbupgrade_all_done_master.html [new file with mode: 0644]
templates/webpages/admin/dbupgrade_all_header_de.html [new file with mode: 0644]
templates/webpages/admin/dbupgrade_all_header_master.html [new file with mode: 0644]
templates/webpages/admin/dbupgrade_footer_de.html [new file with mode: 0644]
templates/webpages/admin/dbupgrade_footer_master.html [new file with mode: 0644]
templates/webpages/admin/dbupgrade_header_de.html [new file with mode: 0644]
templates/webpages/admin/dbupgrade_header_master.html [new file with mode: 0644]
templates/webpages/admin/update_dataset_de.html [new file with mode: 0644]
templates/webpages/admin/update_dataset_master.html [new file with mode: 0644]

index 0fb72d9..d2e914f 100644 (file)
@@ -40,6 +40,7 @@ use Fcntl qw(:seek);
 use SL::DBUpgrade2;
 use SL::DBUtils;
 use SL::Iconv;
+use SL::Inifile;
 
 sub new {
   $main::lxdebug->enter_sub();
@@ -666,84 +667,43 @@ sub dbneedsupdate {
 
   my ($self, $form) = @_;
 
-  my %dbsources = ();
-  my $query;
-
-  $form->{sid} = $form->{dbdefault};
-  &dbconnect_vars($form, $form->{dbdefault});
-
-  my $dbh =
-    DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
-    or $form->dberror;
-
-  if ($form->{dbdriver} eq 'Pg') {
+  my $members  = Inifile->new($main::memberfile);
+  my $controls = parse_dbupdate_controls($form, $form->{dbdriver});
 
-    $query =
-      qq|SELECT d.datname FROM pg_database d, pg_user u | .
-      qq|WHERE d.datdba = u.usesysid AND u.usename = ?|;
-    my $sth = prepare_execute_query($form, $dbh, $query, $form->{dbuser});
+  my ($query, $sth, %dbs_needing_updates);
 
-    while (my ($db) = $sth->fetchrow_array) {
+  foreach my $login (grep /[a-z]/, keys %{ $members }) {
+    my $member = $members->{$login};
 
-      next if ($db =~ /^template/);
+    map { $form->{$_} = $member->{$_} } qw(dbname dbuser dbpasswd dbhost dbport);
+    dbconnect_vars($form, $form->{dbname});
+    $main::lxdebug->dump(0, "form", $form);
+    my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd});
 
-      &dbconnect_vars($form, $db);
+    next unless $dbh;
 
-      my $dbh2 =
-        DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
-        or $form->dberror;
+    my $version;
 
-      $query =
-        qq|SELECT tablename FROM pg_tables | .
-        qq|WHERE tablename = 'defaults'|;
-      my $sth2 = prepare_execute_query($form, $dbh, $query);
-
-      if ($sth2->fetchrow_array) {
-        $query = qq|SELECT version FROM defaults|;
-        my ($version) = selectrow_query($form, $dbh2, $query);
-        $dbsources{$db} = $version;
-      }
-      $sth2->finish;
-      $dbh2->disconnect;
+    $query = qq|SELECT version FROM defaults|;
+    $sth = prepare_query($form, $dbh, $query);
+    if ($sth->execute()) {
+      ($version) = $sth->fetchrow_array();
     }
-    $sth->finish;
-  }
-
-  if ($form->{dbdriver} eq 'Oracle') {
-    $query =
-      qq|SELECT owner FROM dba_objects |.
-      qq|WHERE object_name = 'DEFAULTS' AND object_type = 'TABLE'|;
-
-    $sth = $dbh->prepare($query);
-    $sth->execute || $form->dberror($query);
-
-    while (my ($db) = $sth->fetchrow_array) {
-
-      $form->{dbuser} = $db;
-      &dbconnect_vars($form, $db);
-
-      my $dbh =
-        DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
-        or $form->dberror;
+    $sth->finish();
+    $dbh->disconnect();
 
-      $query = qq|SELECT version FROM defaults|;
-      my $sth = $dbh->prepare($query);
-      $sth->execute;
+    next unless $version;
 
-      if (my ($version) = $sth->fetchrow_array) {
-        $dbsources{$db} = $version;
-      }
-      $sth->finish;
-      $dbh->disconnect;
+    if (update_available($form->{dbdriver}, $version) || update2_available($form, $controls)) {
+      my $dbinfo = {};
+      map { $dbinfo->{$_} = $member->{$_} } grep /^db/, keys %{ $member };
+      $dbs_needing_updates{$member->{dbhost} . "::" . $member->{dbname}} = $dbinfo;
     }
-    $sth->finish;
   }
 
-  $dbh->disconnect;
-
   $main::lxdebug->leave_sub();
 
-  return %dbsources;
+  return values %dbs_needing_updates;
 }
 
 sub calc_version {
@@ -793,12 +753,9 @@ sub update_available {
 
   local *SQLDIR;
 
-  opendir(SQLDIR, "sql/${dbdriver}-upgrade")
-    or &error("", "sql/${dbdriver}-upgrade: $!");
-  my @upgradescripts =
-    grep(/$form->{dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/,
-         readdir(SQLDIR));
-  closedir(SQLDIR);
+  opendir SQLDIR, "sql/${dbdriver}-upgrade" || error("", "sql/${dbdriver}-upgrade: $!");
+  my @upgradescripts = grep /${dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/, readdir SQLDIR;
+  closedir SQLDIR;
 
   return ($#upgradescripts > -1);
 }
@@ -940,6 +897,8 @@ sub dbupdate2 {
 
     map({ $_->{"applied"} = 0; } @upgradescripts);
 
+    $self->create_schema_info_table($form, $dbh);
+
     $query = qq|SELECT tag FROM schema_info|;
     $sth = $dbh->prepare($query);
     $sth->execute() || $form->dberror($query);
index 37ac193..f3edde8 100644 (file)
@@ -41,6 +41,7 @@ use SL::Form;
 use SL::User;
 use SL::Common;
 use SL::Inifile;
+use SL::DBUpgrade2;
 
 require "bin/mozilla/common.pl";
 
@@ -570,117 +571,52 @@ sub continue {
 }
 
 sub update_dataset {
-
-  %needsupdate = User->dbneedsupdate(\%$form);
-
   $form->{title} =
       "Lx-Office ERP "
     . $locale->text('Database Administration') . " / "
     . $locale->text('Update Dataset');
 
-  $form->header;
-
-  print qq|
-<body class=admin>
-
-
-<center>
-<h2>$form->{title}</h2>
-|;
-  my $field_id = 0;
-  foreach $key (sort keys %needsupdate) {
-    if ($needsupdate{$key} ne $form->{dbversion}) {
-      $upd .= qq|<input id="$field_id" name="db$key" type="checkbox" value="1" checked> $key\n|;
-      $form->{dbupdate} .= "db$key ";
-      $field_id++;
-    }
-  }
-
-  chop $form->{dbupdate};
-
-  if ($form->{dbupdate}) {
-
-    print qq|
-<table width=100%>
-<form method=post action=$form->{script}>
-
-<input type=hidden name="dbhost"    value="$form->{dbhost}">
-<input type=hidden name="dbport"    value="$form->{dbport}">
-<input type=hidden name="dbuser"    value="$form->{dbuser}">
-<input type=hidden name="dbpasswd"  value="$form->{dbpasswd}">
-<input type=hidden name="dbdefault" value="$form->{dbdefault}">
+  my @need_updates      = User->dbneedsupdate($form);
+  $form->{NEED_UPDATES} = \@need_updates;
+  $form->{ALL_UPDATED}  = !scalar @need_updates;
 
-<tr class=listheading>
-  <th>| . $locale->text('The following Datasets need to be updated') . qq|</th>
-</tr>
-<tr>
-<td>
-
-$upd
+  $form->header();
+  print $form->parse_html_template("admin/update_dataset");
+}
 
-</td>
-</tr>
-<tr>
-<td>
+sub dbupdate {
+  $form->{stylesheet} = "lx-office-erp.css";
+  $form->{title}      = $locale->text("Dataset upgrade");
+  $form->header();
 
-<input name=dbupdate type=hidden value="$form->{dbupdate}">
+  my $rowcount           = $form->{rowcount} * 1;
+  my @update_rows        = grep { $form->{"update_$_"} } (1 .. $rowcount);
+  $form->{NOTHING_TO_DO} = !scalar @update_rows;
+  my $saved_form         = save_form();
 
-<input name=callback type=hidden value="$form->{script}?action=list_users&rpw=$form->{rpw}">
+  $| = 1;
 
-<input type=hidden name=rpw value=$form->{rpw}>
+  print $form->parse_html_template("admin/dbupgrade_all_header");
 
-<input type=hidden name=nextsub value=dbupdate>
+  foreach my $i (@update_rows) {
+    restore_form($saved_form);
 
-<hr size=3 noshade>
+    map { $form->{$_} = $form->{"${_}_${i}"} } qw(dbname dbdriver dbhost dbport dbuser dbpasswd);
 
-<br>
-<input type=submit class=submit name=action value="|
-      . $locale->text('Continue') . qq|">
+    my $controls = parse_dbupdate_controls($form, $form->{dbdriver});
 
-</td></tr>
-</table>
-</form>
-|;
+    print $form->parse_html_template("admin/dbupgrade_header");
 
-  } else {
+    $form->{dbupdate}        = $form->{dbname};
+    $form->{$form->{dbname}} = 1;
 
-    print $locale->text('All Datasets up to date!');
+    User->dbupdate($form);
+    User->dbupdate2($form, $controls);
 
+    print $form->parse_html_template("admin/dbupgrade_footer");
   }
 
-  print qq|
-
-</body>
-</html>
-|;
-
-}
-
-sub dbupdate {
-  $form->{"stylesheet"} = "lx-office-erp.css";
-  $form->{"title"} = $main::locale->text("Dataset upgrade");
-  $form->header();
-  my $dbname =
-    join(" ",
-         map({ s/\s//g; s/^db//; $_; }
-             grep({ $form->{$_} }
-                  split(/\s+/, $form->{"dbupdate"}))));
-  print($form->parse_html_template("dbupgrade/header",
-                                   { "dbname" => $dbname }));
-
-  User->dbupdate(\%$form);
-
-  print qq|
-<hr>
-
-| . $locale->text('Dataset updated!') . qq|
-
-<br>
-
-<a id="enddatasetupdate" href="admin.pl?action=login&| .
-join("&", map({ "$_=" . $form->escape($form->{$_}); } qw(rpw))) .
-qq|">| . $locale->text("Continue") . qq|</a>|;
-
+  print $form->parse_html_template("admin/dbupgrade_all_done");
 }
 
 sub create_dataset {
index a718e96..47c4af0 100644 (file)
@@ -3,14 +3,12 @@ $self->{texts} = {
   'Add User'                    => 'Benutzer erfassen',
   'Address'                     => 'Adresse',
   'Administration'              => 'Administration',
-  'All Datasets up to date!'    => 'Alle Datenbanken sind auf aktuellem Stand.',
   'Attempt to call an undefined sub named \'%s\'' => 'Es wurde versucht, eine nicht definierte Unterfunktion namens \'%s\' aufzurufen.',
   'Bin List'                    => 'Lagerliste',
   'CANCELED'                    => 'Storniert',
   'Cannot create Lock!'         => 'System kann nicht gesperrt werden!',
   'Change Admin Password'       => 'Administratorpasswort ändern',
   'Confirmation'                => 'Auftragsbestätigung',
-  'Continue'                    => 'Weiter',
   'Create Dataset'              => 'Datenbank anlegen',
   'Credit Note'                 => 'Gutschrift',
   'Customer Number'             => 'Kundennummer',
@@ -20,7 +18,6 @@ $self->{texts} = {
   'Database Administration'     => 'Datenbankadministration',
   'Database User missing!'      => 'Datenbankbenutzer fehlt!',
   'Dataset missing!'            => 'Datenbank fehlt!',
-  'Dataset updated!'            => 'Datenbank erneuert!',
   'Dataset upgrade'             => 'Datenbankaktualisierung',
   'Delete Dataset'              => 'Datenbank löschen',
   'Dependency loop detected:'   => 'Schleife in den Abh&auml;ngigkeiten entdeckt:',
@@ -77,7 +74,6 @@ $self->{texts} = {
   'Storno Packing List'         => 'Stornolieferschein',
   'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.',
   'The directory %s does not exist.' => 'Das Verzeichnis %s existiert nicht.',
-  'The following Datasets need to be updated' => 'Folgende Datenbanken müssen aktualisiert werden',
   'The login is missing.'       => 'Das Login fehlt.',
   'The passwords do not match.' => 'Die Passw&ouml;rter stimmen nicht &uuml;berein.',
   'Trying to call a sub without a name' => 'Es wurde versucht, eine Unterfunktion ohne Namen aufzurufen.',
index 8a58212..fe88533 100644 (file)
@@ -128,6 +128,7 @@ $self->{texts} = {
   'All Accounts'                => 'Alle Konten',
   'All Datasets up to date!'    => 'Alle Datenbanken sind auf aktuellem Stand.',
   'All changes in that file have been reverted.' => 'Alle &Auml;nderungen in dieser Datei wurden r&uuml;ckg&auml;ngig gemacht.',
+  'All database upgrades have been applied.' => 'Alle Datenbankupdates wurden eingespielt.',
   'Amended Advance Turnover Tax Return' => 'Berichtigte Anmeldung',
   'Amended Advance Turnover Tax Return (Nr. 10)' => 'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)',
   'Amount'                      => 'Betrag',
@@ -323,7 +324,6 @@ aktualisieren wollen?',
   'Database update error:'      => 'Fehler beim Datenbankupgrade:',
   'Dataset'                     => 'Datenbank',
   'Dataset missing!'            => 'Datenbank fehlt!',
-  'Dataset updated!'            => 'Datenbank erneuert!',
   'Dataset upgrade'             => 'Datenbankaktualisierung',
   'Date'                        => 'Datum',
   'Date Format'                 => 'Datumsformat',
@@ -699,6 +699,7 @@ gestartet',
   'No Dataset selected!'        => 'Keine Datenbank ausgewählt!',
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
+  'No datasets have been selected.' => 'Es wurden keine Datenbanken ausgew&auml;hlt.',
   'No employee was found matching the search parameters.' => 'Es wurde kein Angestellter gefunden, auf den die Suchparameter zutreffen.',
   'No entries were found which had no unit assigned to them.' => 'Es wurden keine Eintr&auml;ge gefunden, denen keine Einheit zugeordnet war.',
   'No licenses were found that match the search criteria.' => 'Es wurden keine Lizenzen gefunden, auf die die Suchkriterien zutreffen.',
@@ -1123,6 +1124,7 @@ gestartet',
   'Update Prices'               => 'Preise aktualisieren',
   'Update complete'             => 'Update beendet.',
   'Update prices'               => 'Preise aktualisieren',
+  'Update?'                     => 'Aktualisieren?',
   'Updated'                     => 'Erneuert am',
   'Use As Template'             => 'Als Vorlage verwenden',
   'Use Templates'               => 'benutze Vorlagen',
index 1ce19fa..7830c31 100644 (file)
@@ -54,7 +54,7 @@
       <br>
 
       <input type="submit" class="submit" name="action" value="Datenbank anlegen">
-      <!--       <input type="submit" class="submit" name="action" value="Datenbank aktualisieren"> -->
+      <input type="submit" class="submit" name="action" value="Datenbank aktualisieren">
       <input type="submit" class="submit" name="action" value="Datenbank löschen">
      </td>
     </tr>
index e6c316e..6e05c3c 100644 (file)
@@ -54,7 +54,7 @@
       <br>
 
       <input type="submit" class="submit" name="action" value="<translate>Create Dataset</translate>">
-      <!--       <input type="submit" class="submit" name="action" value="<translate>Update Dataset</translate>"> -->
+      <input type="submit" class="submit" name="action" value="<translate>Update Dataset</translate>">
       <input type="submit" class="submit" name="action" value="<translate>Delete Dataset</translate>">
      </td>
     </tr>
diff --git a/templates/webpages/admin/dbupgrade_all_done_de.html b/templates/webpages/admin/dbupgrade_all_done_de.html
new file mode 100644 (file)
index 0000000..d89f889
--- /dev/null
@@ -0,0 +1,19 @@
+<TMPL_IF NOTHING_TO_DO>
+ <p>Es wurden keine Datenbanken ausgew&auml;hlt.</p>
+
+ <TMPL_ELSE>
+
+ <hr>
+
+ <p>Alle Datenbankupdates wurden eingespielt.</p>
+</TMPL_IF>
+
+<form method="post" action="admin.pl">
+ <input type="hidden" name="nextsub" value="list_users">
+ <input type="hidden" name="rpw" value="<TMPL_VAR rpw ESCAPE=HTML>">
+
+ <input type="submit" name="action" value="Weiter">
+</form>
+
+</body>
+</html>
diff --git a/templates/webpages/admin/dbupgrade_all_done_master.html b/templates/webpages/admin/dbupgrade_all_done_master.html
new file mode 100644 (file)
index 0000000..0b71277
--- /dev/null
@@ -0,0 +1,19 @@
+<TMPL_IF NOTHING_TO_DO>
+ <p><translate>No datasets have been selected.</translate></p>
+
+ <TMPL_ELSE>
+
+ <hr>
+
+ <p><translate>All database upgrades have been applied.</translate></p>
+</TMPL_IF>
+
+<form method="post" action="admin.pl">
+ <input type="hidden" name="nextsub" value="list_users">
+ <input type="hidden" name="rpw" value="<TMPL_VAR rpw ESCAPE=HTML>">
+
+ <input type="submit" name="action" value="<translate>Continue</translate>">
+</form>
+
+</body>
+</html>
diff --git a/templates/webpages/admin/dbupgrade_all_header_de.html b/templates/webpages/admin/dbupgrade_all_header_de.html
new file mode 100644 (file)
index 0000000..68c7eca
--- /dev/null
@@ -0,0 +1,2 @@
+<body>
+
diff --git a/templates/webpages/admin/dbupgrade_all_header_master.html b/templates/webpages/admin/dbupgrade_all_header_master.html
new file mode 100644 (file)
index 0000000..68c7eca
--- /dev/null
@@ -0,0 +1,2 @@
+<body>
+
diff --git a/templates/webpages/admin/dbupgrade_footer_de.html b/templates/webpages/admin/dbupgrade_footer_de.html
new file mode 100644 (file)
index 0000000..3d31bbf
--- /dev/null
@@ -0,0 +1 @@
+<p>...fertig</p>
diff --git a/templates/webpages/admin/dbupgrade_footer_master.html b/templates/webpages/admin/dbupgrade_footer_master.html
new file mode 100644 (file)
index 0000000..9ac4e8a
--- /dev/null
@@ -0,0 +1 @@
+<p><translate>...done</translate></p>
diff --git a/templates/webpages/admin/dbupgrade_header_de.html b/templates/webpages/admin/dbupgrade_header_de.html
new file mode 100644 (file)
index 0000000..dff3423
--- /dev/null
@@ -0,0 +1 @@
+<div class="listtop" width="100%">Datenbankaktualisierung (<TMPL_VAR dbname ESCAPE=HTML>)</div>
diff --git a/templates/webpages/admin/dbupgrade_header_master.html b/templates/webpages/admin/dbupgrade_header_master.html
new file mode 100644 (file)
index 0000000..b25c7bd
--- /dev/null
@@ -0,0 +1 @@
+<div class="listtop" width="100%"><translate>Dataset upgrade</translate> (<TMPL_VAR dbname ESCAPE=HTML>)</div>
diff --git a/templates/webpages/admin/update_dataset_de.html b/templates/webpages/admin/update_dataset_de.html
new file mode 100644 (file)
index 0000000..badb290
--- /dev/null
@@ -0,0 +1,55 @@
+<body class="admin">
+
+ <h2><TMPL_VAR title></h2>
+
+ <TMPL_IF ALL_UPDATED>
+  Alle Datenbanken sind auf aktuellem Stand.
+
+  <TMPL_ELSE>
+
+  <form method="post" action="admin.pl">
+
+   <p>Folgende Datenbanken müssen aktualisiert werden:</p>
+
+   <table>
+    <tr>
+     <th class="listtop">Aktualisieren?</th>
+     <th class="listtop">Datenbank</th>
+     <th class="listtop">Treiber</th>
+     <th class="listtop">Datenbankcomputer</th>
+     <th class="listtop">Port</th>
+     <th class="listtop">Benutzer</th>
+    </tr>
+
+    <TMPL_LOOP NEED_UPDATES>
+     <tr class="listrow<TMPL_IF __odd__>1<TMPL_ELSE>0</TMPL_IF>">
+      <td><input type="checkbox" name="update_<TMPL_VAR __counter__>" value="1" checked></td>
+      <td><input type="hidden" name="dbname_<TMPL_VAR __counter__>" value="<TMPL_VAR dbname ESCAPE=HTML>"><TMPL_VAR dbname ESCAPE=HTML></td>
+      <td><input type="hidden" name="dbdriver_<TMPL_VAR __counter__>" value="Pg">PostgreSQL</td>
+      <td><input type="hidden" name="dbhost_<TMPL_VAR __counter__>" value="<TMPL_VAR dbhost ESCAPE=HTML>"><TMPL_VAR dbhost ESCAPE=HTML></td>
+      <td><input type="hidden" name="dbport_<TMPL_VAR __counter__>" value="<TMPL_VAR dbport ESCAPE=HTML>"><TMPL_VAR dbport ESCAPE=HTML></td>
+      <td><input type="hidden" name="dbuser_<TMPL_VAR __counter__>" value="<TMPL_VAR dbuser ESCAPE=HTML>"><TMPL_VAR dbuser ESCAPE=HTML></td>
+     </tr>
+
+     <TMPL_IF __last__>
+      <input type="hidden" name="rowcount" value="<TMPL_VAR __counter__>">
+     </TMPL_IF>
+    </TMPL_LOOP>
+   </table>
+
+   <input name="callback" type="hidden" value="admin.pl?action=list_users&rpw=<TMPL_VAR rpw ESCAPE=URL>">
+   <input type="hidden" name="rpw" value="<TMPL_VAR rpw ESCAPE=HTML>">
+   <input type="hidden" name="nextsub" value="dbupdate">
+
+   <hr size="3" noshade>
+
+   <br>
+
+   <input type="submit" class="submit" name="action" value="Weiter">
+
+  </form>
+
+ </TMPL_IF>
+
+</body>
+</html>
diff --git a/templates/webpages/admin/update_dataset_master.html b/templates/webpages/admin/update_dataset_master.html
new file mode 100644 (file)
index 0000000..6e1acff
--- /dev/null
@@ -0,0 +1,55 @@
+<body class="admin">
+
+ <h2><TMPL_VAR title></h2>
+
+ <TMPL_IF ALL_UPDATED>
+  <translate>All Datasets up to date!</translate>
+
+  <TMPL_ELSE>
+
+  <form method="post" action="admin.pl">
+
+   <p><translate>The following Datasets need to be updated</translate>:</p>
+
+   <table>
+    <tr>
+     <th class="listtop"><translate>Update?</translate></th>
+     <th class="listtop"><translate>Dataset</translate></th>
+     <th class="listtop"><translate>Driver</translate></th>
+     <th class="listtop"><translate>Host</translate></th>
+     <th class="listtop"><translate>Port</translate></th>
+     <th class="listtop"><translate>User</translate></th>
+    </tr>
+
+    <TMPL_LOOP NEED_UPDATES>
+     <tr class="listrow<TMPL_IF __odd__>1<TMPL_ELSE>0</TMPL_IF>">
+      <td><input type="checkbox" name="update_<TMPL_VAR __counter__>" value="1" checked></td>
+      <td><input type="hidden" name="dbname_<TMPL_VAR __counter__>" value="<TMPL_VAR dbname ESCAPE=HTML>"><TMPL_VAR dbname ESCAPE=HTML></td>
+      <td><input type="hidden" name="dbdriver_<TMPL_VAR __counter__>" value="Pg">PostgreSQL</td>
+      <td><input type="hidden" name="dbhost_<TMPL_VAR __counter__>" value="<TMPL_VAR dbhost ESCAPE=HTML>"><TMPL_VAR dbhost ESCAPE=HTML></td>
+      <td><input type="hidden" name="dbport_<TMPL_VAR __counter__>" value="<TMPL_VAR dbport ESCAPE=HTML>"><TMPL_VAR dbport ESCAPE=HTML></td>
+      <td><input type="hidden" name="dbuser_<TMPL_VAR __counter__>" value="<TMPL_VAR dbuser ESCAPE=HTML>"><TMPL_VAR dbuser ESCAPE=HTML></td>
+     </tr>
+
+     <TMPL_IF __last__>
+      <input type="hidden" name="rowcount" value="<TMPL_VAR __counter__>">
+     </TMPL_IF>
+    </TMPL_LOOP>
+   </table>
+
+   <input name="callback" type="hidden" value="admin.pl?action=list_users&rpw=<TMPL_VAR rpw ESCAPE=URL>">
+   <input type="hidden" name="rpw" value="<TMPL_VAR rpw ESCAPE=HTML>">
+   <input type="hidden" name="nextsub" value="dbupdate">
+
+   <hr size="3" noshade>
+
+   <br>
+
+   <input type="submit" class="submit" name="action" value="<translate>Continue</translate>">
+
+  </form>
+
+ </TMPL_IF>
+
+</body>
+</html>