First cut at the query tool
authorDave Page <[email protected]>
Tue, 26 Aug 2008 16:38:13 +0000 (17:38 +0100)
committerDave Page <[email protected]>
Tue, 26 Aug 2008 16:38:13 +0000 (17:38 +0100)
12 files changed:
config.php.in
connections.php
css/iui-ext.css
gucs.php
index.php
info.php
locks.php
misc.php
query.php [new file with mode: 0644]
results.php [new file with mode: 0644]
server.php
transactions.php

index 28dce44d72e42b22ec251f0f608900582832a1e4..6e625663c310c8b5f97626119c8efa9bdd87c76c 100644 (file)
 // $servers[2]["connstr"] = "hostaddr=192.168.0.23 port=5444 dbname=pgphonehome user=pgphonehome password=FuBar";
 // $servers[2]["icon"] = "images/pg.png";
 
+// The following configuration options will not normally need to be changed.
+
+// The maximum size of a value that the query tool will display in characters.
+// Values longer than this will be truncated.
+$GLOBALS['config_max_field_size'] = 256;
+
+// The number of records to load at a time in the query tool
+$GLOBALS['config_query_batch_size'] = 25;
+
+// The maximum number of rows to return in the query tool. This is a safety net
+// to prevent webserver (and iPhone) resources being completely exhausted.
+$GLOBALS['config_max_result_rows'] = 1000;
+
 ?>
index 2d309fbaf8846572a680d63720099339786a5bb5..caaac7bf192729810cf89b9414a4e0b6de332917 100644 (file)
 
 require "global.php";
 
-// Set the panel name
-$panel = "connections" . $server; 
-
 // Get the server number
 $server = intval($_GET['server']);
 
+// Set the panel name
+$panel = "connections" . $server; 
+
 if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == "")
         www_error("Invalid server", "The specified server number ($server) does not have a valid configuration.", $panel);
 
@@ -25,7 +25,7 @@ if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == ""
 $db = @pg_connect($servers[$server]["connstr"]);
 
 if ($db === FALSE)
-       www_error("Couldn't connect to the site database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
+       www_error("Couldn't connect to the database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
 
 // Get the connections
 $sql = "SELECT *, CASE WHEN client_port = -1 THEN 'Unix socket' ELSE client_port::text END AS port FROM pg_stat_activity ORDER BY procpid";
@@ -57,21 +57,21 @@ while ($row = pg_fetch_assoc($res)) {
 
        $list .= "      <li class=\"double\"><a href=\"#" . $subpanel . "\">PID: <span class=\"coloredValue\">" . www_clean($row['procpid']) . "</span> Source: <span class=\"coloredValue\">" . www_clean($row['client_addr']) . ":" . www_clean($row['client_port']) . "</span><br />User: <span class=\"coloredValue\">" . www_clean($row['usename']) . "</span> DB: <span class=\"coloredValue\">" . www_clean($row['datname']) . "</span></a></li>\n";
 
-       $divs .= "<div id=\"" . $subpanel . "\" class=\"panel\" title=\"Connection\">\n";
-       $divs .= "      <div class=\"dialogHeader\">$message2</div>\n";
-       $divs .= "      <h2>Process ID</h2><div class=\"valueBox\">" . www_clean($row['procpid']) . "</div>\n";
-       $divs .= "      <h2>Source address</h2><div class=\"valueBox\">" . www_clean($row['client_addr']) . "</div>\n";
-       $divs .= "      <h2>Source port</h2><div class=\"valueBox\">" . www_clean($row['port']) . "</div>\n";
-       $divs .= "      <h2>Database</h2><div class=\"valueBox\">" . www_clean($row['datname']) . "</div>\n";
-       $divs .= "      <h2>Username</h2><div class=\"valueBox\">" . www_clean($row['usename']) . "</div>\n";
-       $divs .= "      <h2>Connection start</h2><div class=\"valueBox\">" . www_clean($row['backend_start']) . "</div>\n";
+       $divs .= "<div id=\"" . $subpanel . "\" class=\"panel\" title=\"Connection\">";
+       $divs .= "<div class=\"dialogHeader\">$message2</div>";
+       $divs .= "<h2>Process ID</h2><div class=\"valueBox\">" . www_clean($row['procpid']) . "</div>";
+       $divs .= "<h2>Source address</h2><div class=\"valueBox\">" . www_clean($row['client_addr']) . "</div>";
+       $divs .= "<h2>Source port</h2><div class=\"valueBox\">" . www_clean($row['port']) . "</div>";
+       $divs .= "<h2>Database</h2><div class=\"valueBox\">" . www_clean($row['datname']) . "</div>";
+       $divs .= "<h2>Username</h2><div class=\"valueBox\">" . www_clean($row['usename']) . "</div>";
+       $divs .= "<h2>Connection start</h2><div class=\"valueBox\">" . www_clean($row['backend_start']) . "</div>";
 
        if (array_key_exists("xact_start", $row))
-               $divs .= "      <h2>Transaction start</h2><div class=\"valueBox\">" . www_clean($row['xact_start']) . "</div>\n";
+               $divs .= "<h2>Transaction start</h2><div class=\"valueBox\">" . www_clean($row['xact_start']) . "</div>";
 
-       $divs .= "      <h2>Query start</h2><div class=\"valueBox\">" . www_clean($row['query_start']) . "</div>\n";
-       $divs .= "      <h2>Current query</h2><div class=\"valueBox\">" . www_clean($row['current_query']) . "</div>\n";
-       $divs .= "</div>\n";
+       $divs .= "<h2>Query start</h2><div class=\"valueBox\">" . www_clean($row['query_start']) . "</div>";
+       $divs .= "<h2>Current query</h2><div class=\"valueBox\">" . www_clean($row['current_query']) . "</div>";
+       $divs .= "</div>";
 }
 
 pg_free_result($res);
@@ -80,10 +80,9 @@ pg_free_result($res);
 // Output just the HTML snippet to be loaded via AJAX
 $text = <<<EOT
 <ul id="$panel" title="Connections"> 
-       <li class="group">$message</li>
-       $list
+<li class="group">$message</li>
+$list
 </ul>
-
 $divs
 EOT;
 
index 8cc867f1345ecb1d5ae78a960a47a49607de074e..e844927aaa1d12416641ee33956fb0c374497a14 100644 (file)
@@ -58,3 +58,12 @@ span.note {
        padding-right: 5px;
        float: left;
 }
+
+/* Textarea */
+textarea {
+       width: 95%; 
+       height: 100px; 
+       border: 0px; 
+       padding: 5px; 
+}
+
index 8cb206b7035c65aa9ec30c0369e14213b78147a5..111f54c2254341fa112be497bf00550950196aaf 100644 (file)
--- a/gucs.php
+++ b/gucs.php
 
 require "global.php";
 
-// Set the display panel
-$panel = "gucs" . $server;
-
 // Get the server number
 $server = intval($_GET['server']);
 
+// Set the display panel
+$panel = "gucs" . $server;
+
 if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == "")
        www_error("Invalid server", "The specified server number ($server) does not have a valid configuration.", $panel);
 
@@ -26,7 +26,7 @@ if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == ""
 $db = @pg_connect($servers[$server]["connstr"]);
 
 if ($db === FALSE)
-       www_error("Couldn't connect to the site database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
+       www_error("Couldn't connect to the database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
 
 // Get the GUCs
 $sql = "SHOW all;";
@@ -35,13 +35,15 @@ $res = @pg_query($db, $sql);
 if ($res === false)
                www_error("Query execution error", $php_errormsg, $panel);
 
+$gucs = "";
+
 $rows = pg_numrows($res);
 
 for ($x=0; $x < $rows; $x++) {
        $guc_name = www_clean(pg_fetch_result($res, $x, "name"));
        $guc_value = www_clean(pg_fetch_result($res, $x, "setting"));
 
-       $gucs .= "      <h2>" . $guc_name . "</h2><div class=\"valueBox\">" . $guc_value . "</div>";
+       $gucs .= "<h2>" . $guc_name . "</h2><div class=\"valueBox\">" . $guc_value . "</div>";
 }
 
 pg_free_result($res);
@@ -51,7 +53,7 @@ $message = "Server: " . $servers[$server]["description"];
 // Echo the HTML snippet
 $text = <<<EOT
 <div id="$panel" class="panel" title="GUCs">
-       <div class="dialogHeader">$message</div>
+<div class="dialogHeader">$message</div>
 $gucs
 </div>
 EOT;
index 8718037f798f7a1e6381595760d64590ef6d13e7..edea87d28482275abb270d0c8cd7801b6f0043dd 100644 (file)
--- a/index.php
+++ b/index.php
@@ -27,21 +27,21 @@ foreach ($servers as $key=>$server) {
 
                // Can we connect?
                if ($db === false) {
-                       $svrlist .= "<li>" . $icon . "<s>" . $server["description"] . "</s><br /><span class=\"note\">" . html_entity_decode($php_errormsg, ENT_QUOTES) . "</span></li>\n";
+                       $svrlist .= "<li>" . $icon . "<s>" . $server["description"] . "</s><br /><span class=\"note\">" . html_entity_decode($php_errormsg, ENT_QUOTES) . "</span></li>";
                } else {
                        // Valid server version?
                        $res = @pg_query($db, "SHOW server_version_num;");
                        if (@pg_fetch_result($res, 0, 0) < 80200) {
-                               $svrlist .= "<li>" . $icon . "<s>" . $server["description"] . "</s><br /><span class=\"note\">Server version is less than 8.2</span></li>\n";
+                               $svrlist .= "<li>" . $icon . "<s>" . $server["description"] . "</s><br /><span class=\"note\">Server version is less than 8.2</span></li>";
                        } else {
                                // Have we got superuser privs?
                                @pg_free_result($res);
                                $res = @pg_query($db, "SELECT usesuper FROM pg_shadow WHERE usename = current_user;");
                                if (pg_fetch_result($res, 0, 0) != "t") {
-                                       $svrlist .= "<li>" . $icon . "<s>" . $server["description"] . "</s><br /><span class=\"note\">The connecting user is not a superuser</span></li>\n";
+                                       $svrlist .= "<li>" . $icon . "<s>" . $server["description"] . "</s><br /><span class=\"note\">The connecting user is not a superuser</span></li>";
                                } else {
                                        // Looks good - let's go!
-                                       $svrlist .= "<li>" . $icon . "<a href=\"server.php?server=" . $key . "\">" . $server["description"] . "</a></li>\n";
+                                       $svrlist .= "<li>" . $icon . "<a href=\"server.php?server=" . $key . "\">" . $server["description"] . "</a></li>";
                                }
                        }
                        pg_free_result($res);
@@ -58,9 +58,7 @@ $message = "Servers: $svrcount configured";
 
 // Echo the main HTML body. Everything else is loaded a snippet at a time, via AJAX
 $text = <<<EOT
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title>$APP_NAME v$APP_VERSION</title>
@@ -69,29 +67,25 @@ $text = <<<EOT
 <style type="text/css" media="screen">@import "css/iui-ext.css";</style>
 <script type="application/x-javascript" src="iui/iui.js"></script>
 </head>
-
 <body>
-       <div class="toolbar">
-               <h1 id="pageTitle"></h1>
-               <a id="backButton" class="button" href="#"></a>
-       </div>
-
-       <ul id="servers" title="$APP_NAME" selected="true"> 
-               <li class="group">$message</li>
+<div class="toolbar">
+<h1 id="pageTitle"></h1>
+<a id="backButton" class="button" href="#"></a>
+</div>
+<ul id="servers" title="$APP_NAME" selected="true"> 
+<li class="group">$message</li>
 $svrlist
-               <li class="double"><a href="#about">About</a></li>
-       </ul>
-       
-       <div id="about" class="panel" title="About">
-                <h2>$APP_NAME v$APP_VERSION</h2>
-               <p>$APP_NAME is a remote monitoring interface for your Postgres and Postgres Plus servers.</p>
-               <p>For support, please visit the EnterpriseDB <a href="http://forums.enterprisedb.com" target="_new">forums</a>.</p>
-               <p>$APP_NAME is released under the <a href="http://www.opensource.org/licenses/gpl-2.0.php" target="_new">GNU General Public Licence</a>.</p>
-               <p>$APP_COPYRIGHT</p>
-               <p>&nbsp;</p>
-               <center><a href="http://www.enterprisedb.com" target="_new"><img src="images/enterprisedb.png" alt="EnterpriseDB Logo" style="border-style: none" /></a></center>
-       </div>
-       
+<li class="double"><a href="#about">About</a></li>
+</ul>
+<div id="about" class="panel" title="About">
+<h2>$APP_NAME v$APP_VERSION</h2>
+<p>$APP_NAME is a remote monitoring interface for your Postgres and Postgres Plus servers.</p>
+<p>For support, please visit the EnterpriseDB <a href="http://forums.enterprisedb.com" target="_new">forums</a>.</p>
+<p>$APP_NAME is released under the <a href="http://www.opensource.org/licenses/gpl-2.0.php" target="_new">GNU General Public Licence</a>.</p>
+<p>$APP_COPYRIGHT</p>
+<p>&nbsp;</p>
+<center><a href="http://www.enterprisedb.com" target="_new"><img src="images/enterprisedb.png" alt="EnterpriseDB Logo" style="border-style: none" /></a></center>
+</div>
 </body>
 </html>
 EOT;
index a2653758a8ce8461aa53f63ba6ac264f125239c3..c93dab881a755cf084f92623220ef33ac4c72d01 100644 (file)
--- a/info.php
+++ b/info.php
 
 require "global.php";
 
-// Set the display panel
-$panel = "info" . $server;
-
 // Get the server number
 $server = intval($_GET['server']);
 
+// Set the display panel
+$panel = "info" . $server;
+
 if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == "")
        www_error("Invalid server", "The specified server number ($server) does not have a valid configuration.", $panel);
 
@@ -26,7 +26,7 @@ if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == ""
 $db = @pg_connect($servers[$server]["connstr"]);
 
 if ($db === FALSE)
-       www_error("Couldn't connect to the site database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
+       www_error("Couldn't connect to the database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
 
 // Get the server version
 $sql = "SELECT version() AS version, current_user AS username, (SELECT count(*) FROM pg_stat_activity) AS connections;";
@@ -55,14 +55,14 @@ $message = "Server: " . $servers[$server]["description"];
 // Echo the HTML snippet
 $text = <<<EOT
 <div id="$panel" class="panel" title="Info">
-       <div class="dialogHeader">$message</div>
-       <h2>Server version</h2><div class="valueBox">$version</div>
-       <h2>Server host</h2><div class="valueBox">$host</div>
-       <h2>Server port</h2><div class="valueBox">$port</div>
-       <h2>Active connections</h2><div class="valueBox">$connections</div>
-       <h2>Current database</h2><div class="valueBox">$database</div>
-       <h2>Current username</h2><div class="valueBox">$username</div>
-       <h2>Current backend PID</h2><div class="valueBox">$pid</div>
+<div class="dialogHeader">$message</div>
+<h2>Server version</h2><div class="valueBox">$version</div>
+<h2>Server host</h2><div class="valueBox">$host</div>
+<h2>Server port</h2><div class="valueBox">$port</div>
+<h2>Active connections</h2><div class="valueBox">$connections</div>
+<h2>Current database</h2><div class="valueBox">$database</div>
+<h2>Current username</h2><div class="valueBox">$username</div>
+<h2>Current backend PID</h2><div class="valueBox">$pid</div>
 </div>
 EOT;
 
index 99e20f145818d5f2806c6fadc16f69c8e8ba5367..b08f3bbc1b47eca6a09c2a3ec813ef9f3ba46f8b 100644 (file)
--- a/locks.php
+++ b/locks.php
 
 require "global.php";
 
-// Set the panel name
-$panel = "locks" . $server; 
-
 // Get the server number
 $server = intval($_GET['server']);
 
+// Set the panel name
+$panel = "locks" . $server; 
+
 if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == "")
         www_error("Invalid server", "The specified server number ($server) does not have a valid configuration.", $panel);
 
@@ -25,7 +25,7 @@ if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == ""
 $db = @pg_connect($servers[$server]["connstr"]);
 
 if ($db === FALSE)
-       www_error("Couldn't connect to the site database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
+       www_error("Couldn't connect to the database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
 
 // Get the server version, so we can use the right query
 $res = @pg_query($db, "SHOW server_version_num;");
@@ -96,20 +96,20 @@ while ($row = pg_fetch_assoc($res)) {
 
        $list .= "      <li class=\"double\"><a href=\"#" . $subpanel . "\">Class: <span class=\"coloredValue\">" . www_clean($row['class']) . "</span><br />Mode: <span class=\"coloredValue\">" . www_clean($row['mode']) . "</span><br /></span> DB: <span class=\"coloredValue\">" . www_clean($row['dbname']) . "</span></a></li>\n";
 
-       $divs .= "<div id=\"" . $subpanel . "\" class=\"panel\" title=\"Lock\">\n";
-       $divs .= "      <div class=\"dialogHeader\">$message2</div>\n";
-       $divs .= "      <h2>PID</h2><div class=\"valueBox\">" . www_clean($row['pid']) . "</div>\n";
-       $divs .= "      <h2>Database</h2><div class=\"valueBox\">" . www_clean($row['dbname']) . "</div>\n";
-       $divs .= "      <h2>Class</h2><div class=\"valueBox\">" . www_clean($row['class']) . "</div>\n";
-       $divs .= "      <h2>Username</h2><div class=\"valueBox\">" . www_clean($row['user']) . "</div>\n";
+       $divs .= "<div id=\"" . $subpanel . "\" class=\"panel\" title=\"Lock\">";
+       $divs .= "<div class=\"dialogHeader\">$message2</div>";
+       $divs .= "<h2>PID</h2><div class=\"valueBox\">" . www_clean($row['pid']) . "</div>";
+       $divs .= "<h2>Database</h2><div class=\"valueBox\">" . www_clean($row['dbname']) . "</div>";
+       $divs .= "<h2>Class</h2><div class=\"valueBox\">" . www_clean($row['class']) . "</div>";
+       $divs .= "<h2>Username</h2><div class=\"valueBox\">" . www_clean($row['user']) . "</div>";
        if ($version >= 80300)
-               $divs .= "      <h2>Virtual XID</h2><div class=\"valueBox\">" . www_clean($row['virtualxid']) . "</div>\n";
-       $divs .= "      <h2>Transaction</h2><div class=\"valueBox\">" . www_clean($row['transaction']) . "</div>\n";
-       $divs .= "      <h2>Mode</h2><div class=\"valueBox\">" . www_clean($row['mode']) . "</div>\n";
-       $divs .= "      <h2>Granted?</h2><div class=\"valueBox\">" . ($row['granted'] == "t" ? "Yes" : "No") . "</div>\n";
-       $divs .= "      <h2>Query</h2><div class=\"valueBox\">" . www_clean($row['current_query']) . "</div>\n";
-       $divs .= "      <h2>Query start</h2><div class=\"valueBox\">" . www_clean($row['query_start']) . "</div>\n";
-       $divs .= "</div>\n";
+               $divs .= "<h2>Virtual XID</h2><div class=\"valueBox\">" . www_clean($row['virtualxid']) . "</div>";
+       $divs .= "<h2>Transaction</h2><div class=\"valueBox\">" . www_clean($row['transaction']) . "</div>";
+       $divs .= "<h2>Mode</h2><div class=\"valueBox\">" . www_clean($row['mode']) . "</div>";
+       $divs .= "<h2>Granted?</h2><div class=\"valueBox\">" . ($row['granted'] == "t" ? "Yes" : "No") . "</div>";
+       $divs .= "<h2>Query</h2><div class=\"valueBox\">" . www_clean($row['current_query']) . "</div>";
+       $divs .= "<h2>Query start</h2><div class=\"valueBox\">" . www_clean($row['query_start']) . "</div>";
+       $divs .= "</div>";
 }
 
 pg_free_result($res);
@@ -118,10 +118,9 @@ pg_free_result($res);
 // Output just the HTML snippet to be loaded via AJAX
 $text = <<<EOT
 <ul id="$panel" title="Locks"> 
-       <li class="group">$message</li>
-       $list
+<li class="group">$message</li>
+$list
 </ul>
-
 $divs
 EOT;
 
index 4d561270684a750e458cce4f2e32473700527cd1..4bdc0d0606d6674ebaf14802514c35b20f340297 100644 (file)
--- a/misc.php
+++ b/misc.php
@@ -15,10 +15,10 @@ function www_error($message, $detail, $div)
 {
     $text = <<<EOT
 <div id="$div" class="panel" title="Error">
-  <p>An error has occured in $APP_NAME:</p>
-  <p style="color: red; font-weight: bold;">$message</p>
-  <p style="color: red; font-weight: normal;">$detail</p>
-  <p>For support, please visit the EnterpriseDB <a href="http://forums.enterprisedb.com" target="_new">forums</a>.</p>
+<p>An error has occured in $APP_NAME:</p>
+<p style="color: red; font-weight: bold;">$message</p>
+<p style="color: red; font-weight: normal;">$detail</p>
+<p>For support, please visit the EnterpriseDB <a href="http://forums.enterprisedb.com" target="_new">forums</a>.</p>
 </div>
 EOT;
 
@@ -35,5 +35,22 @@ function www_clean($text)
                return htmlspecialchars($text);
 }
 
+// Truncate a value for display
+function truncate_value($text)
+{
+       if (strlen($text) > $GLOBALS['config_max_field_size'])
+               return substr($text, 0, $GLOBALS['config_max_field_size']) . " [value truncated]";
+       else
+               return $text;
+}
+
+// Truncate a value for use on a menu
+function truncate_title($text)
+{
+       if (strlen($text) > 30)
+                return substr($text, 0, 30) . "...";
+       else
+                return $text;
+}
 ?>
 
diff --git a/query.php b/query.php
new file mode 100644 (file)
index 0000000..6863396
--- /dev/null
+++ b/query.php
@@ -0,0 +1,78 @@
+<?php
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// pgPhoneHome - Postgres Monitor for iPhone
+// Copyright 2008, EnterpriseDB UK Ltd.
+// Dave Page ([email protected])
+//
+// query.php - Server GUCs
+//
+///////////////////////////////////////////////////////////////////////////////
+
+require "global.php";
+
+// Get the server number
+$server = intval($_GET['server']);
+
+// Set the display panel
+$panel = "query" . $server;
+
+if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == "")
+       www_error("Invalid server", "The specified server number ($server) does not have a valid configuration.", $panel);
+
+$database = $_GET['db'];
+
+if ($database == "") {
+
+       // Connect the database
+       $db = @pg_connect($servers[$server]["connstr"]);
+       
+       if ($db === FALSE)
+               www_error("Couldn't connect to the database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
+       
+       // Get the connections
+       $sql = "SELECT datname FROM pg_database WHERE datistemplate=false AND datallowconn=true ORDER BY datname";
+       $res = @pg_query($db, $sql);
+
+       if ($res === false)
+               www_error("Query execution error", $php_errormsg, $panel);
+
+       $message = "Databases: " . pg_num_rows($res);;
+
+       while ($row = pg_fetch_assoc($res)) {
+               $list .= "<li><img src=\"images/database.png\" class=\"menuImage\"><a href=\"query.php?server=" . $server . "&db=" . www_clean($row['datname']) . "\">" . www_clean($row['datname']) . "</a></li>";
+       }
+
+       $text = <<<EOT
+<ul id="$panel" title="Databases"> 
+<li class="group">$message</li>
+$list
+</ul>
+EOT;
+
+
+} else {
+       $message = "Database: " . www_clean($database);
+
+       // Echo the query page
+       $text = <<<EOT
+<div id="$panel" class="panel" title="Query tool">
+<form class="panel" action="results.php?server=$server&db=$database" method="POST" selected="true">
+<div class="dialogHeader">$message</div>
+<h2>SQL query</h2>
+<fieldset>
+<div class="row">
+<textarea name="sql">SELECT * FROM pg_database;</textarea>
+</div>
+</fieldset>
+<a class="grayButton" type="submit" href="#">Execute</a>
+</form>
+</div>
+EOT;
+}
+
+echo $text;
+exit();
+
+?>
diff --git a/results.php b/results.php
new file mode 100644 (file)
index 0000000..5497ee9
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// pgPhoneHome - Postgres Monitor for iPhone
+// Copyright 2008, EnterpriseDB UK Ltd.
+// Dave Page ([email protected])
+//
+// query.php - Server GUCs
+//
+///////////////////////////////////////////////////////////////////////////////
+
+require "global.php";
+
+// Get the server number
+$server = intval($_GET['server']);
+
+// Set the display panel
+$panel = "results" . $server;
+
+if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == "")
+       www_error("Invalid server", "The specified server number ($server) does not have a valid configuration.", $panel);
+
+$database = $_GET['db'];
+
+// Connect the database. 
+$connstr = preg_replace("(dbname=[^\ ]*)", "dbname=" . $database, $servers[$server]["connstr"]);
+$db = @pg_connect($connstr);
+
+if ($db === FALSE)
+       www_error("Couldn't connect to the database. $constr", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
+
+// Get the SQL
+if ($_POST['sql'])
+       $sql = $_POST['sql'];
+else
+       www_error("Invalid query", "An invalid SQL query was specified.", $panel);
+
+// Run the query 
+$res = @pg_query($db, $sql);
+
+if ($res === false)
+       www_error("Query execution error", $php_errormsg, $panel);
+
+// Start a session to store the results in
+session_start();
+
+$message = "Rows: " . pg_affected_rows($res);
+
+$list = "";
+$divs = "";
+$rownum = 0;
+
+// Display the results
+if (pg_num_fields($res) > 0) {
+
+       $message = "Rows: " . pg_num_rows($res);
+
+       if (pg_num_rows($res) > $GLOBALS['config_max_result_rows'])
+               $message .= " (limited to " . $GLOBALS['config_max_result_rows'] . ")";
+
+       while (($row = pg_fetch_array($res)) && ($rownum < $GLOBALS['config_max_result_rows'])) {
+
+               // Set the sub-panel ID
+               $subpanel = $panel . "row" . $rownum++;
+
+               // Build the row preview list.
+               $list .= "<li class=\"double\"><a href=\"#" . $subpanel . "\">";
+
+               $list .= www_clean(pg_field_name($res, 0)) . ": <span class=\"coloredValue\">" . www_clean(truncate_title($row[0])) . "</span>";
+
+               if (pg_num_fields($res) >= 2)
+               $list .= "<br />" . www_clean(pg_field_name($res, 1)) . ": <span class=\"coloredValue\">" . www_clean($row[1]) . "</span>";
+
+               if (pg_num_fields($res) >= 3)
+                       $list .= "<br />" . www_clean(pg_field_name($res, 2)) . ": <span class=\"coloredValue\">" . www_clean($row[2]) . "</span>";
+
+               $list .= "</a></li>";
+
+               // Build the panel for this row
+               $divs .= "<div id=\"" . $subpanel . "\" class=\"panel\" title=\"Query row\">";
+               $divs .= "<div class=\"dialogHeader\">Row: " . $rownum . "</div>";
+
+               for ($x = 0; $x < pg_num_fields($res); $x++) {
+                       $divs .= "<h2>" . www_clean(pg_field_name($res, $x)) . "</h2><div class=\"valueBox\">" . www_clean(truncate_value($row[$x])) . "</div>";
+               }
+
+               $divs .= "</div>";
+       }
+
+       // Echo the HTML snippet
+       $text = <<<EOT
+<ul id="$panel" title="Results"> 
+<li class="group">$message</li>
+$list
+</ul>
+$divs
+EOT;
+
+} else {
+       $message = "Affected rows: " . pg_affected_rows($res);
+       
+       $text = <<<EOT
+<div id="$panel" class="panel" title="Result">
+<h2>Query completed</h2>
+<p>$message</p>
+</div>
+EOT;
+
+}
+
+echo $text;
+exit();
+
+?>
index 1efd8c7f30d53a9bdcdcf957b6c65eb621d43afb..4b51013b674aa753ccd8b100cfd6f7b097df9746 100644 (file)
@@ -24,12 +24,13 @@ $description = $servers[$server]["description"];
 // Echo the main menus for a server
 $text = <<<EOT
 <ul id="server$server" title="Menu"> 
-       <li class="group">Server: $description</li>
-       <li><img src="images/info.png" class="menuImage"><a href="info.php?server=$server">Info</a></li>
-       <li><img src="images/gucs.png" class="menuImage"><a href="gucs.php?server=$server">GUCs</a></li>
-       <li><img src="images/connections.png" class="menuImage"><a href="connections.php?server=$server">Connections</a></li>
-       <li><img src="images/locks.png" class="menuImage"><a href="locks.php?server=$server">Locks</a></li>
-       <li><img src="images/transactions.png" class="menuImage"><a href="transactions.php?server=$server">Prepared transactions</a></li>
+<li class="group">Server: $description</li>
+<li><img src="images/info.png" class="menuImage"><a href="info.php?server=$server">Info</a></li>
+<li><img src="images/connections.png" class="menuImage"><a href="connections.php?server=$server">Connections</a></li>
+<li><img src="images/gucs.png" class="menuImage"><a href="gucs.php?server=$server">GUCs</a></li>
+<li><img src="images/locks.png" class="menuImage"><a href="locks.php?server=$server">Locks</a></li>
+<li><img src="images/query.png" class="menuImage"><a href="query.php?server=$server">Query tool</a></li>
+<li><img src="images/transactions.png" class="menuImage"><a href="transactions.php?server=$server">Prepared transactions</a></li>
 </ul>
 EOT;
 
index 3c64bbff03aef013619ece418d4ff8d78a46f92e..8f95910dff3240766a7f20857bf03a85dc9fb1a7 100644 (file)
 
 require "global.php";
 
-// Set the panel name
-$panel = "transactions" . $server; 
-
 // Get the server number
 $server = intval($_GET['server']);
 
+// Set the panel name
+$panel = "transactions" . $server; 
+
 if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == "")
         www_error("Invalid server", "The specified server number ($server) does not have a valid configuration.", $panel);
 
@@ -25,7 +25,7 @@ if ($servers[$server]["description"] == "" || $servers[$server]["connstr"] == ""
 $db = @pg_connect($servers[$server]["connstr"]);
 
 if ($db === FALSE)
-       www_error("Couldn't connect to the site database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
+       www_error("Couldn't connect to the database.", html_entity_decode($php_errormsg, ENT_QUOTES), $panel);
 
 // Get the connections
 $sql = "SELECT * FROM pg_prepared_xacts;";
@@ -54,16 +54,16 @@ while ($row = pg_fetch_assoc($res)) {
        // Set the sub-panel ID
        $subpanel = $panel . "row" . $rownum++;
 
-       $list .= "      <li class=\"double\"><a href=\"#" . $subpanel . "\">XID: <span class=\"coloredValue\">" . www_clean($row['transaction']) . "</span><br />User: <span class=\"coloredValue\">" . www_clean($row['owner']) . "</span> DB: <span class=\"coloredValue\">" . www_clean($row['database']) . "</span></a></li>\n";
+       $list .= "      <li class=\"double\"><a href=\"#" . $subpanel . "\">XID: <span class=\"coloredValue\">" . www_clean($row['transaction']) . "</span><br />User: <span class=\"coloredValue\">" . www_clean($row['owner']) . "</span> DB: <span class=\"coloredValue\">" . www_clean($row['database']) . "</span></a></li>";
 
-       $divs .= "<div id=\"" . $subpanel . "\" class=\"panel\" title=\"Transaction\">\n";
-       $divs .= "      <div class=\"dialogHeader\">$message2</div>\n";
-       $divs .= "      <h2>XID</h2><div class=\"valueBox\">" . www_clean($row['transaction']) . "</div>\n";
-       $divs .= "      <h2>Global ID</h2><div class=\"valueBox\">" . www_clean($row['gid']) . "</div>\n";
-       $divs .= "      <h2>Time</h2><div class=\"valueBox\">" . www_clean($row['prepared']) . "</div>\n";
-       $divs .= "      <h2>Owner</h2><div class=\"valueBox\">" . www_clean($row['owner']) . "</div>\n";
-       $divs .= "      <h2>Database</h2><div class=\"valueBox\">" . www_clean($row['database']) . "</div>\n";
-       $divs .= "</div>\n";
+       $divs .= "<div id=\"" . $subpanel . "\" class=\"panel\" title=\"Transaction\">";
+       $divs .= "<div class=\"dialogHeader\">$message2</div>";
+       $divs .= "<h2>XID</h2><div class=\"valueBox\">" . www_clean($row['transaction']) . "</div>";
+       $divs .= "<h2>Global ID</h2><div class=\"valueBox\">" . www_clean($row['gid']) . "</div>";
+       $divs .= "<h2>Time</h2><div class=\"valueBox\">" . www_clean($row['prepared']) . "</div>";
+       $divs .= "<h2>Owner</h2><div class=\"valueBox\">" . www_clean($row['owner']) . "</div>";
+       $divs .= "<h2>Database</h2><div class=\"valueBox\">" . www_clean($row['database']) . "</div>";
+       $divs .= "</div>";
 }
 
 pg_free_result($res);
@@ -72,10 +72,9 @@ pg_free_result($res);
 // Output just the HTML snippet to be loaded via AJAX
 $text = <<<EOT
 <ul id="$panel" title="Transactions"> 
-       <li class="group">$message</li>
-       $list
+<li class="group">$message</li>
+$list
 </ul>
-
 $divs
 EOT;