* Fix all uses of setComment that do double escaping
+NEEDS TESTING
+-------------
+
+* Comment stuff
+* Import
+* Script execution
* Allow adding array columns to tables
* Allow creating domains with type length and arrays
* Show domain base type and comment in domains list
+* Allow import of CSV data
+* Allow upload and execution of _basic_ SQL scripts
Bugs
* Fix pg_dump output for PostgreSQL 7.0.x and 7.1.x
/**
* Class to hold various commonly used functions
*
- * $Id: Misc.php,v 1.59 2004/02/13 08:53:05 chriskl Exp $
+ * $Id: Misc.php,v 1.60 2004/04/12 06:30:55 chriskl Exp $
*/
class Misc {
global $lang;
$vars = $this->href . '&table=' . urlencode($_REQUEST['table']);
-
+ // Width of each cell
+ $width = round(100 / 9) . '%';
+
echo "<table class=\"navbar\" border=\"0\" width=\"100%\" cellpadding=\"5\" cellspacing=\"3\"><tr>\n";
- echo "<td width=\"12%\"><a href=\"tblproperties.php?{$vars}\">{$lang['strcolumns']}</a></td>\n";
- echo "<td width=\"13%\"><a href=\"indexes.php?{$vars}\">{$lang['strindexes']}</a></td>\n";
- echo "<td width=\"12%\"><a href=\"constraints.php?{$vars}\">{$lang['strconstraints']}</a></td>\n";
- echo "<td width=\"13%\"><a href=\"triggers.php?{$vars}\">{$lang['strtriggers']}</a></td>\n";
- echo "<td width=\"12%\"><a href=\"rules.php?{$vars}\">{$lang['strrules']}</a></td>\n";
- echo "<td width=\"13%\"><a href=\"info.php?{$vars}\">{$lang['strinfo']}</a></td>\n";
- echo "<td width=\"12%\"><a href=\"privileges.php?{$vars}&type=table&object=", urlencode($_REQUEST['table']), "\">{$lang['strprivileges']}</a></td>\n";
- echo "<td width=\"13%\"><a href=\"tblproperties.php?{$vars}&action=export\">{$lang['strexport']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"tblproperties.php?{$vars}\">{$lang['strcolumns']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"indexes.php?{$vars}\">{$lang['strindexes']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"constraints.php?{$vars}\">{$lang['strconstraints']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"triggers.php?{$vars}\">{$lang['strtriggers']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"rules.php?{$vars}\">{$lang['strrules']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"info.php?{$vars}\">{$lang['strinfo']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"privileges.php?{$vars}&type=table&object=", urlencode($_REQUEST['table']), "\">{$lang['strprivileges']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"tblproperties.php?{$vars}&action=import\">{$lang['strimport']}</a></td>\n";
+ echo "<td width=\"{$width}\"><a href=\"tblproperties.php?{$vars}&action=export\">{$lang['strexport']}</a></td>\n";
echo "</tr></table>\n";
}
echo "-->\n";
echo "</script>\n";
}
-
+
+ /**
+ * Converts a PHP.INI size variable to bytes. Taken from publically available
+ * function by Chris DeRose, here: http://www.php.net/manual/en/configuration.directives.php#ini.file-uploads
+ * @param $strIniSize The PHP.INI variable
+ * @return size in bytes, false on failure
+ */
+ function inisizeToBytes($strIniSize) {\r
+ // This function will take the string value of an ini 'size' parameter,\r
+ // and return a double (64-bit float) representing the number of bytes that the parameter represents. Or false if $strIniSize is unparseable.\r
+ $a_IniParts = array();\r
+ \r
+ if (!is_string( $strIniSize ))\r
+ return false;\r
+ \r
+ if (!preg_match ('/^(\d+)([bkm]*)$/i', $strIniSize,$a_IniParts))\r
+ return false;\r
+ \r
+ $nSize = (double) $a_IniParts[1];\r
+ $strUnit = strtolower($a_IniParts[2]);\r
+ \r
+ switch($strUnit) {\r
+ case 'm':\r
+ return ($nSize * (double) 1048576);\r
+ case 'k':\r
+ return ($nSize * (double) 1024);\r
+ case 'b':\r
+ default:\r
+ return $nSize;\r
+ }\r
+ }
}
?>
* A class that implements the DB interface for Postgres
* Note: This class uses ADODB and returns RecordSets.
*
- * $Id: BaseDB.php,v 1.42 2004/03/29 02:05:31 chriskl Exp $
+ * $Id: BaseDB.php,v 1.43 2004/04/12 06:30:55 chriskl Exp $
*/
include_once('./classes/database/ADODB_base.php');
/**
* Adds a new row to a table
* @param $table The table in which to insert
- * @param $values An array mapping new values for the row
+ * @param $var An array mapping new values for the row
* @param $nulls An array mapping column => something if it is to be null
* @param $format An array of the data type (VALUE or EXPRESSION)
* @param $types An array of field types
* A class that implements the DB interface for Postgres
* Note: This class uses ADODB and returns RecordSets.
*
- * $Id: Postgres.php,v 1.190 2004/04/01 15:10:31 soranzo Exp $
+ * $Id: Postgres.php,v 1.191 2004/04/12 06:30:55 chriskl Exp $
*/
// @@@ THOUGHT: What about inherits? ie. use of ONLY???
return $this->selectSet($sql);
}
+ // Script execution functions
+
+ /**
+ * Executes an SQL script as a series of SQL statements. Returns
+ * the result of the final step.
+ * @param $name Entry in $_FILES to use
+ * @return Result of final query, false on any failure.
+ */
+ function executeScript($name) {
+ if (!is_uploaded_file($_FILES[$name]['tmp_name'])) return false;
+
+ $fd = fopen($_FILES[$name]['tmp_name'], 'r');
+ if (!$fd) return false;
+
+ // Loop over each line in the file
+ while (!feof($fd)) {\r
+ $sql = fgets($fd, 32768);
+ // Execute the query, ignoring errors for the time being
+ // XXX: This needs to handle COPY to and from
+ $res = @pg_query($sql);
+ }
+
+ fclose($fd);
+
+ return new ADORecordSet_empty();
+ }
+
// Type conversion routines
/**
/**
* Manage schemas within a database
*
- * $Id: database.php,v 1.37 2004/03/12 08:56:51 chriskl Exp $
+ * $Id: database.php,v 1.38 2004/04/12 06:30:55 chriskl Exp $
*/
// Include application functions
echo "<h2>", $misc->printVal($_REQUEST['database']), ": {$lang['strsql']}</h2>\n";
echo "<p>{$lang['strentersql']}</p>\n";
- echo "<form action=\"sql.php\" method=\"post\">\n";
+ echo "<form action=\"sql.php\" method=\"post\" enctype=\"multipart/form-data\">\n";
echo "<p>{$lang['strsql']}<br />\n";
echo "<textarea style=\"width:100%;\" rows=\"20\" cols=\"50\" name=\"query\">",
- htmlspecialchars($_REQUEST['query']), "</textarea></p>\n";
-
+ htmlspecialchars($_REQUEST['query']), "</textarea>\n";
+
+ // Check that file uploads are enabled
+ if (ini_get('file_uploads')) {
+ // Don't show upload option if max size of uploads is zero
+ $max_size = $misc->inisizeToBytes(ini_get('upload_max_filesize'));
+ if (is_double($max_size) && $max_size > 0) {
+ echo "<br /><br /><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />\n";
+ echo " {$lang['struploadscript']} <input name=\"script\" type=\"file\" /></p>\n";
+ }
+ }
+ else echo "</p>\n";
echo "<input type=\"checkbox\" name=\"paginate\"", (isset($_REQUEST['paginate']) ? ' checked="checked"' : ''), " /> {$lang['strpaginate']}\n";
echo "<br />\n";
echo "<p><input type=\"submit\" value=\"{$lang['strgo']}\" />\n";
* Does an export to the screen or as a download. This checks to
* see if they have pg_dump set up, and will use it if possible.
*
- * $Id: dataexport.php,v 1.12 2004/03/29 02:05:31 chriskl Exp $
+ * $Id: dataexport.php,v 1.13 2004/04/12 06:30:55 chriskl Exp $
*/
$extensions = array(
echo $misc->form;
echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n";
echo "</form>\n";
+
+ $misc->printFooter();
}
?>
* English language file for phpPgAdmin. Use this as a basis
* for new translations.
*
- * $Id: english.php,v 1.136 2004/04/05 21:22:13 soranzo Exp $
+ * $Id: english.php,v 1.137 2004/04/12 06:30:55 chriskl Exp $
*/
// Language and character set
$lang['strsetting'] = 'Setting';
$lang['streditsql'] = 'Edit SQL';
$lang['strpaginate'] = 'Paginate results';
+ $lang['struploadscript'] = 'or upload an SQL script:';
$lang['strstarttime'] = 'Start Time';
+ $lang['strfile'] = 'File';
+ $lang['strfileimported'] = 'File imported.';
// Error handling
$lang['strnoframes'] = 'You need a frames-enabled browser to use this application.';
$lang['strnoobjects'] = 'No objects found.';
$lang['strrownotunique'] = 'No unique identifier for this row.';
$lang['strnoreportsdb'] = 'You have not created the reports database. Read the INSTALL file for directions.';
+ $lang['strnouploads'] = 'File uploads are disabled.';
+ $lang['strimporterror'] = 'Import error.';
+ $lang['strimporterrorline'] = 'Import error on line %s.';
// Tables
$lang['strtable'] = 'Table';
* English language file for phpPgAdmin. Use this as a basis
* for new translations.
*
- * $Id: english.php,v 1.89 2004/04/05 21:22:19 soranzo Exp $
+ * $Id: english.php,v 1.90 2004/04/12 06:30:56 chriskl Exp $
*/
// Language and character set
$lang['strsetting'] = 'Setting';
$lang['streditsql'] = 'Edit SQL';
$lang['strpaginate'] = 'Paginate results';
+ $lang['struploadscript'] = 'or upload an SQL script:';
$lang['strstarttime'] = 'Start Time';
+ $lang['strfile'] = 'File';
+ $lang['strfileimported'] = 'File imported.';
// Error handling
$lang['strnoframes'] = 'You need a frames-enabled browser to use this application.';
$lang['strnoobjects'] = 'No objects found.';
$lang['strrownotunique'] = 'No unique identifier for this row.';
$lang['strnoreportsdb'] = 'You have not created the reports database. Read the INSTALL file for directions.';
+ $lang['strnouploads'] = 'File uploads are disabled.';
+ $lang['strimporterror'] = 'Import error.';
+ $lang['strimporterrorline'] = 'Import error on line %s.';
// Tables
$lang['strtable'] = 'Table';
* how many SQL statements have been strung together with semi-colons
* @param $query The SQL query string to execute
*
- * $Id: sql.php,v 1.18 2004/02/23 07:23:15 chriskl Exp $
+ * $Id: sql.php,v 1.19 2004/04/12 06:30:55 chriskl Exp $
*/
// Include application functions
// Set fetch mode to NUM so that duplicate field names are properly returned
$data->conn->setFetchMode(ADODB_FETCH_NUM);
- // Execute the query
- $rs = $data->conn->Execute($_POST['query']);
+
+ // Execute the query. If it's a script upload, special handling is necessary
+ if (isset($_FILES['script']) && $_FILES['script']['size'] > 0)
+ $rs = $data->executeScript('script');
+ else
+ $rs = $data->conn->Execute($_POST['query']);
// $rs will only be an object if there is no error
if (is_object($rs)) {
/**
* List tables in a database
*
- * $Id: tblproperties.php,v 1.39 2004/04/01 15:53:01 soranzo Exp $
+ * $Id: tblproperties.php,v 1.40 2004/04/12 06:30:55 chriskl Exp $
*/
// Include application functions
echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n";
echo "</form>\n";
}
+
+ function doImport($msg = '') {
+ global $data, $misc;
+ global $PHP_SELF, $lang;
+
+ $misc->printTableNav();
+ echo "<h2>", $misc->printVal($_REQUEST['database']), ": ", $misc->printVal($_REQUEST['table']), ": {$lang['strimport']}</h2>\n";
+ $misc->printMsg($msg);
+
+ // Check that file uploads are enabled
+ if (ini_get('file_uploads')) {
+ // Don't show upload option if max size of uploads is zero
+ $max_size = $misc->inisizeToBytes(ini_get('upload_max_filesize'));
+ if (is_double($max_size) && $max_size > 0) {
+ echo "<form action=\"dataimport.php\" method=\"post\" enctype=\"multipart/form-data\">\n";
+ echo "<table>\n";
+ echo "<tr><th class=\"data left required\">{$lang['strformat']}</th>";
+ echo "<td><select name=\"format\">\n";
+ //echo "<option value=\"copy\">COPY</option>\n";
+ //echo "<option value=\"sql\">SQL</option>\n";
+ echo "<option value=\"csv\">CSV</option>\n";
+ //echo "<option value=\"tab\">Tabbed</option>\n";
+ //echo "<option value=\"html\">XHTML</option>\n";
+ //echo "<option value=\"xml\">XML</option>\n";
+ echo "</select>\n</td>\n</tr>\n";
+ echo "<tr><th class=\"data left required\">{$lang['strfile']}</th>";
+ echo "<td><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />\n";
+ echo "<input type=\"file\" name=\"source\" />\n";
+ echo "</table>\n";
+ echo "<p><input type=\"hidden\" name=\"action\" value=\"import\" />\n";
+ echo $misc->form;
+ echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n";
+ echo "<input type=\"submit\" value=\"{$lang['strimport']}\" /></p>\n";
+ echo "</form>\n";
+ }
+ }
+ else echo "<p>{$lang['strnouploads']}</p>\n";
+ }
/**
* Displays a screen where they can add a column
case 'confirm_alter':
doAlter();
break;
+ case 'import':
+ doImport();
+ break;
case 'export':
doExport();
break;