<?php
//===============================================/
// select verb for ubiquity
// by mitcho (Michael Yoshitaka Erlewine)
// code at mitcho.com
// http://mitcho.com/code/select/
// license: MPL
// ---
// Postgresql port (initialy designed for mysql)
// by Metrokid (Jonathan Winandy)
// jonathan.winandy at gmail.com
// http://jonyboy.wordpress.com
//===============================================/


//==USAGE========================================/
// 1. Configure the database config below.
// 2. Put this file on your server.
// 3. Go to this script on your server.
//    You should get a success message.
// 4. Subscribe to the verbs on mitcho.com/code/select/
//    if you haven't already.
// 5. Select the URL to the script (including "http://..."),
//    enter ubiquity and run `setup-select this` on the URL.
//===============================================/

$version '1.0'// this is the "API version"

//==DATABASE CONFIG==============================/
$pghost 'localhost'// e.g. localhost
$pguser 'USER';
$pgpass 'PASS';
$pgdb   'DATABASE';
$pgschema 'public';
//===============================================/


header("Cache-control: private");

$db = @pg_connect("host=$pghost dbname=$pgdb user=$pguser password=$pgpass"); //connect to server.
if (!$db) {
  echo 
"<p style='color:red'><code>select</code> could not connect to the database.";
}

if (isset(
$_REQUEST['task'])) {
  switch(
$_REQUEST['task']) {
    case 
'version':
      echo 
$version;
      break;
    case 
'list-tables':
    
    
$first true;
      
$query_results pg_query("select tablename from pg_tables where tableowner = CURRENT_USER and schemaname = '$pgschema'");
      echo 
"[";
      while (
$table pg_fetch_array($query_results)) {
        echo (
$first?'':', ')."'$table[0]'";
        
$first false;
      }
      echo 
"]";
      break;
    case 
'list-columns':
      
$first true;
      
$query_results pg_query("select column_name FROM information_schema.columns WHERE table_name = '".$_REQUEST['table']."'");
      echo 
"[";
      while (
$table pg_fetch_array($query_results)) {
        echo (
$first?'':', ')."'$table[0]'";
        
$first false;
      }
      echo 
"]";
      break;
    case 
'select':
    case 
'show':
      if (!empty(
$_REQUEST['select']))
        
$query "select ".stripslashes($_REQUEST['select']);
      if (!empty(
$_REQUEST['show'])) {
        
// not supported by PG.
        //$query = 'show '.$_REQUEST['show']; 
      
}
      if (!isset(
$query))
        
$query "select tablename from pg_tables where tableowner = CURRENT_USER and schemaname = '$pgschema'";
      
prepareQuery($query);
      
      if (!(
$result_query = @pg_query($query))) {
        echo 
"<p style='color:red;'>ERROR  : ".pg_result_error()."</p>";
        exit;
      }
      
      
displayResults($result_query);
      break;
  }
} else {
  echo 
"Successfully installed and connected to $pglhost (postgres)";
}

//==QUERY PREP==================================/
function prepareQuery(&$query){
  
// make sure there's a limit to these things
  
if (stristr($query,'select ') !== false and stristr($query,'limit') === false)
    
$query .= " limit 30";
  
  
  
  
// make sure we only are executing one statement; protect against attacks.
  
$i 0;
  
$quot false;
  
$dblquot false;
  
$escape false;
  while (
$i strlen($query)) {
    
$beginescape $escape;
    
$focus substr($query,$i,1);
    if (
$focus == '\\')
      
$escape = !$escape;
    if (!
$escape and !$quot and $focus == '"')
      
$dblquot = !$dblquot;
    if (!
$escape and !$dblquot and $focus == "'")
      
$quot = !$quot;
    if (!
$quot and !$dblquot and $focus == ';') {
      echo 
"<p style='color:red'>You can only execute one statement at a time.</p>";
      exit;
    }
    if (
$beginescape)
      
$escape false;
    if (isset(
$_REQUEST['testfilter']))
      echo 
"$focus$quot$dblquot$escape --- ";

    
$i++;
  }
}

//===============================================/


//==DISPLAY=====================================/

function displayResults($result_query) {

  
// if there was only one value found, and we want to paste it, just return it.
  
if (pg_num_rows($result_query) == and pg_num_fields($result_query) == and isset($_REQUEST['paste'])) {
    
$row pg_fetch_array($result_query);
    echo 
"$row[0]";
    return;
  }

  echo 
"<table>";
  echo 
"<tr>";
  
$i pg_num_fields($result_query);
  for (
$j 0$j $i$j++) {
  echo 
"<th style='text-align:left;font-weight:bold;'>".htmlentities(pg_field_name($result_query$j))."</th>";
  }
  echo 
"</tr>";
  
  while(
$row = @pg_fetch_row($result_query)) {
    echo 
"<tr>";
    foreach (
$row as $val) {
      echo 
"<td>".htmlentities($val)."</td>";
    }
    echo 
"</tr>";
  }
  echo 
"</table>";
  
  
  
/*
  TODO : select count(*) FROM .... 
  $count_query = mysql_query('select found_rows() as rows');
  $count = mysql_fetch_array($count_query);
  if ($count[0] >= $rows and !isset($_REQUEST['paste'])) // there are some cases (show's, etc.) where the count is wrong, so we ignore those.
    echo "<p>$count[0] row".(($count[0] == 1)?"":'s')." found</p>";  
    */
}
//===============================================/

?>