Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HuasoFoundries/phpPgAdmin6.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/controllers/DataexportController.php89
-rw-r--r--src/controllers/DataimportController.php216
-rw-r--r--src/controllers/MaterializedviewpropertiesController.php2
-rw-r--r--src/controllers/TablesController.php3
-rw-r--r--src/controllers/TblpropertiesController.php65
-rw-r--r--src/controllers/TypesController.php4
-rw-r--r--src/controllers/ViewpropertiesController.php2
-rw-r--r--src/database/Connection.php2
-rw-r--r--src/database/Postgres.php1
-rw-r--r--src/database/Postgres11.php3
-rw-r--r--src/database/databasetraits/ColumnTrait.php12
-rw-r--r--src/database/databasetraits/DatabaseTrait.php4
-rw-r--r--src/database/databasetraits/TableTrait.php155
-rw-r--r--src/traits/AdminTrait.php32
14 files changed, 316 insertions, 274 deletions
diff --git a/src/controllers/DataexportController.php b/src/controllers/DataexportController.php
index 559e94ed..f303efd4 100644
--- a/src/controllers/DataexportController.php
+++ b/src/controllers/DataexportController.php
@@ -36,7 +36,7 @@ class DataexportController extends BaseController
$format = 'N/A';
// force behavior to assume there is no pg_dump in the system
- $forcemimic = false;
+ $forcemimic = isset($_REQUEST['forcemimic']) ? $_REQUEST['forcemimic'] : false;
// If format is set, then perform the export
if (!isset($_REQUEST['what'])) {
@@ -89,11 +89,12 @@ class DataexportController extends BaseController
break;
}
+ $cleanprefix = $clean ? '' : '-- ';
- return $this->mimicDumpFeature($format, $clean, $oids);
+ return $this->mimicDumpFeature($format, $cleanprefix, $oids);
}
- protected function mimicDumpFeature($format, $clean, $oids)
+ protected function mimicDumpFeature($format, $cleanprefix, $oids)
{
$data = $this->misc->getDatabaseAccessor();
@@ -111,34 +112,8 @@ class DataexportController extends BaseController
// Include application functions
$this->setNoOutput(true);
- $clean = false;
- $response = $this
- ->container
- ->responseobj;
- // Make it do a download, if necessary
- if ('download' == $_REQUEST['output']) {
- // Set headers. MSIE is totally broken for SSL downloading, so
- // we need to have it download in-place as plain text
- if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS'])) {
- $response = $response
- ->withHeader('Content-type', 'text/plain');
- } else {
- $response = $response
- ->withHeader('Content-type', 'application/download');
-
- if (isset($this->extensions[$format])) {
- $ext = $this->extensions[$format];
- } else {
- $ext = 'txt';
- }
- $response = $response
- ->withHeader('Content-Disposition', 'attachment; filename=dump.'.$ext);
- }
- } else {
- $response = $response
- ->withHeader('Content-type', 'text/plain');
- }
+ $response = $this->_getResponse($format);
$this->coalesceArr($_REQUEST, 'query', '');
@@ -164,7 +139,7 @@ class DataexportController extends BaseController
// If the dump is not dataonly then dump the structure prefix
if ('dataonly' != $_REQUEST['what']) {
- $tabledefprefix = $data->getTableDefPrefix($object, $clean);
+ $tabledefprefix = $data->getTableDefPrefix($object, $cleanprefix);
$this->prtrace('tabledefprefix', $tabledefprefix);
echo $tabledefprefix;
}
@@ -178,12 +153,7 @@ class DataexportController extends BaseController
$data->conn->setFetchMode(\ADODB_FETCH_NUM);
// Execute the query, if set, otherwise grab all rows from the table
- if ($object) {
- $rs = $data->dumpRelation($object, $oids);
- } else {
- $rs = $data->conn->Execute($_REQUEST['query']);
- $this->prtrace('$_REQUEST[query]', $_REQUEST['query']);
- }
+ $rs = $this->_getRS($data, $object, $oids);
$response = $this->pickFormat($data, $object, $oids, $rs, $format, $response);
}
@@ -200,7 +170,47 @@ class DataexportController extends BaseController
return $response;
}
- public function pickFormat($data, $object, $oids, $rs, $format, $response)
+ private function _getRS($data, $object, $oids)
+ {
+ if ($object) {
+ return $data->dumpRelation($object, $oids);
+ }
+
+ $this->prtrace('$_REQUEST[query]', $_REQUEST['query']);
+
+ return $data->conn->Execute($_REQUEST['query']);
+ }
+
+ private function _getResponse($format)
+ {
+ $response = $this
+ ->container
+ ->responseobj;
+
+ // Make it do a download, if necessary
+ if ('download' !== $_REQUEST['output']) {
+ return $response
+ ->withHeader('Content-type', 'text/plain');
+ }
+ // Set headers. MSIE is totally broken for SSL downloading, so
+ // we need to have it download in-place as plain text
+ if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS'])) {
+ return $response
+ ->withHeader('Content-type', 'text/plain');
+ }
+ $response = $response
+ ->withHeader('Content-type', 'application/download');
+
+ $ext = 'txt';
+ if (isset($this->extensions[$format])) {
+ $ext = $this->extensions[$format];
+ }
+
+ return $response
+ ->withHeader('Content-Disposition', 'attachment; filename=dump.'.$ext);
+ }
+
+ private function pickFormat($data, $object, $oids, $rs, $format, $response)
{
if ('copy' == $format) {
$this->_mimicCopy($data, $object, $oids, $rs);
@@ -214,9 +224,8 @@ class DataexportController extends BaseController
$this->_mimicXml($data, $object, $oids, $rs);
} elseif ('sql' == $format) {
$this->_mimicSQL($data, $object, $oids, $rs);
- } else {
- $this->_csvOrTab($data, $object, $oids, $rs, $format);
}
+ $this->_csvOrTab($data, $object, $oids, $rs, $format);
return $response;
}
diff --git a/src/controllers/DataimportController.php b/src/controllers/DataimportController.php
index 82f518b9..fdeb5f70 100644
--- a/src/controllers/DataimportController.php
+++ b/src/controllers/DataimportController.php
@@ -27,7 +27,7 @@ class DataimportController extends BaseController
$this->printHeader();
$this->printTrail('table');
- $this->printTabs('table', 'import');
+ $tabs = $this->printTabs('table', 'import');
// Default state for XML parser
$state = 'XML';
@@ -179,127 +179,129 @@ class DataimportController extends BaseController
};
// Check that file is specified and is an uploaded file
- if (isset($_FILES['source']) && is_uploaded_file($_FILES['source']['tmp_name']) && is_readable($_FILES['source']['tmp_name'])) {
- $fd = fopen($_FILES['source']['tmp_name'], 'rb');
- // Check that file was opened successfully
- if (false !== $fd) {
- $null_array = self::loadNULLArray();
- $status = $data->beginTransaction();
- if (0 != $status) {
- $this->halt($this->lang['strimporterror']);
- }
+ if (!isset($_FILES['source']) || !is_uploaded_file($_FILES['source']['tmp_name']) || !is_readable($_FILES['source']['tmp_name'])) {
+ // Upload went wrong
+ $this->printMsg($this->lang['strimporterror-uploadedfile']);
- // If format is set to 'auto', then determine format automatically from file name
- if ('auto' == $_REQUEST['format']) {
- $extension = substr(strrchr($_FILES['source']['name'], '.'), 1);
- switch ($extension) {
- case 'csv':
- $_REQUEST['format'] = 'csv';
-
- break;
- case 'txt':
- $_REQUEST['format'] = 'tab';
-
- break;
- case 'xml':
- $_REQUEST['format'] = 'xml';
-
- break;
- default:
- $data->rollbackTransaction();
- $this->halt($this->lang['strimporterror-fileformat']);
- }
- }
+ return $this->printFooter();
+ }
+ $fd = fopen($_FILES['source']['tmp_name'], 'rb');
+ // Check that file was opened successfully
+ if (false === $fd) {
+ // File could not be opened
+ $this->printMsg($this->lang['strimporterror']);
- // Do different import technique depending on file format
- switch ($_REQUEST['format']) {
- case 'csv':
- case 'tab':
- // XXX: Length of CSV lines limited to 100k
- $csv_max_line = 100000;
- // Set delimiter to tabs or commas
- if ('csv' == $_REQUEST['format']) {
- $csv_delimiter = ',';
- } else {
- $csv_delimiter = "\t";
- }
+ return $this->printFooter();
+ }
+ $null_array = self::loadNULLArray();
+ $status = $data->beginTransaction();
+ if (0 != $status) {
+ $this->halt($this->lang['strimporterror']);
+ }
- // Get first line of field names
- $fields = fgetcsv($fd, $csv_max_line, $csv_delimiter);
- $row = 2; //We start on the line AFTER the field names
- while ($line = fgetcsv($fd, $csv_max_line, $csv_delimiter)) {
- // Build value map
- $t_fields = [];
- $vars = [];
- $nulls = [];
- $format = [];
- $types = [];
- $i = 0;
- foreach ($fields as $f) {
- // Check that there is a column
- if (!isset($line[$i])) {
- $this->halt(sprintf($this->lang['strimporterrorline-badcolumnnum'], $row));
- }
- $t_fields[$i] = $f;
-
- // Check for nulls
- if (self::determineNull($line[$i], $null_array)) {
- $nulls[$i] = 'on';
- }
- // Add to value array
- $vars[$i] = $line[$i];
- // Format is always VALUE
- $format[$i] = 'VALUE';
- // Type is always text
- $types[$i] = 'text';
- ++$i;
- }
-
- $status = $data->insertRow($_REQUEST['table'], $t_fields, $vars, $nulls, $format, $types);
- if (0 != $status) {
- $data->rollbackTransaction();
- $this->halt(sprintf($this->lang['strimporterrorline'], $row));
- }
- ++$row;
- }
+ // If format is set to 'auto', then determine format automatically from file name
+ if ('auto' == $_REQUEST['format']) {
+ $extension = substr(strrchr($_FILES['source']['name'], '.'), 1);
+ switch ($extension) {
+ case 'csv':
+ $_REQUEST['format'] = 'csv';
- break;
- case 'xml':
- $parser = xml_parser_create();
- xml_set_element_handler($parser, $_startElement, $_endElement);
- xml_set_character_data_handler($parser, $_charHandler);
+ break;
+ case 'txt':
+ $_REQUEST['format'] = 'tab';
+
+ break;
+ case 'xml':
+ $_REQUEST['format'] = 'xml';
+
+ break;
+ default:
+ $data->rollbackTransaction();
+ $this->halt($this->lang['strimporterror-fileformat']);
+ }
+ }
+
+ // Do different import technique depending on file format
+ switch ($_REQUEST['format']) {
+ case 'csv':
+ case 'tab':
+ // XXX: Length of CSV lines limited to 100k
+ $csv_max_line = 100000;
+ // Set delimiter to tabs or commas
+ if ('csv' == $_REQUEST['format']) {
+ $csv_delimiter = ',';
+ } else {
+ $csv_delimiter = "\t";
+ }
- while (!feof($fd)) {
- $line = fgets($fd, 4096);
- xml_parse($parser, $line);
+ // Get first line of field names
+ $fields = fgetcsv($fd, $csv_max_line, $csv_delimiter);
+ $row = 2; //We start on the line AFTER the field names
+ while ($line = fgetcsv($fd, $csv_max_line, $csv_delimiter)) {
+ // Build value map
+ $t_fields = [];
+ $vars = [];
+ $nulls = [];
+ $format = [];
+ $types = [];
+ $i = 0;
+ foreach ($fields as $f) {
+ // Check that there is a column
+ if (!isset($line[$i])) {
+ $this->halt(sprintf($this->lang['strimporterrorline-badcolumnnum'], $row));
}
+ $t_fields[$i] = $f;
- xml_parser_free($parser);
+ // Check for nulls
+ if (self::determineNull($line[$i], $null_array)) {
+ $nulls[$i] = 'on';
+ }
+ // Add to value array
+ $vars[$i] = $line[$i];
+ // Format is always VALUE
+ $format[$i] = 'VALUE';
+ // Type is always text
+ $types[$i] = 'text';
+ ++$i;
+ }
- break;
- default:
- // Unknown type
+ $status = $data->insertRow($_REQUEST['table'], $t_fields, $vars, $nulls, $format, $types);
+ if (0 != $status) {
$data->rollbackTransaction();
- $this->halt($this->lang['strinvalidparam']);
+ $this->halt(sprintf($this->lang['strimporterrorline'], $row));
+ }
+ ++$row;
}
- $status = $data->endTransaction();
- if (0 != $status) {
- $this->halt($this->lang['strimporterror']);
+ break;
+ case 'xml':
+ $parser = xml_parser_create();
+ xml_set_element_handler($parser, $_startElement, $_endElement);
+ xml_set_character_data_handler($parser, $_charHandler);
+
+ while (!feof($fd)) {
+ $line = fgets($fd, 4096);
+ xml_parse($parser, $line);
}
- fclose($fd);
- $this->printMsg($this->lang['strfileimported']);
- } else {
- // File could not be opened
- $this->printMsg($this->lang['strimporterror']);
- }
- } else {
- // Upload went wrong
- $this->printMsg($this->lang['strimporterror-uploadedfile']);
+ xml_parser_free($parser);
+
+ break;
+ default:
+ // Unknown type
+ $data->rollbackTransaction();
+ $this->halt($this->lang['strinvalidparam']);
}
- $this->printFooter();
+ $status = $data->endTransaction();
+ if (0 != $status) {
+ $this->printMsg($this->lang['strimporterror']);
+ }
+ fclose($fd);
+
+ $this->printMsg($this->lang['strfileimported']);
+
+ return $this->printFooter();
}
public static function loadNULLArray()
diff --git a/src/controllers/MaterializedviewpropertiesController.php b/src/controllers/MaterializedviewpropertiesController.php
index 55cf482f..91086e30 100644
--- a/src/controllers/MaterializedviewpropertiesController.php
+++ b/src/controllers/MaterializedviewpropertiesController.php
@@ -182,7 +182,6 @@ class MaterializedviewpropertiesController extends BaseController
switch ($_REQUEST['stage']) {
case 1:
-
$this->printTrail('column');
$this->printTitle($this->lang['stralter'], 'pg.column.alter');
$this->printMsg($msg);
@@ -224,7 +223,6 @@ class MaterializedviewpropertiesController extends BaseController
break;
case 2:
-
// Check inputs
if ('' == trim($_REQUEST['field'])) {
$_REQUEST['stage'] = 1;
diff --git a/src/controllers/TablesController.php b/src/controllers/TablesController.php
index 07e04927..b47ad507 100644
--- a/src/controllers/TablesController.php
+++ b/src/controllers/TablesController.php
@@ -42,7 +42,6 @@ class TablesController extends BaseController
switch ($this->action) {
case 'create':
-
if (isset($_POST['cancel'])) {
$this->doDefault();
} else {
@@ -515,7 +514,6 @@ class TablesController extends BaseController
break;
case 2:
-
// Check inputs
$fields = trim($_REQUEST['fields']);
if ('' == trim($_REQUEST['name'])) {
@@ -636,7 +634,6 @@ class TablesController extends BaseController
break;
case 3:
-
$this->coalesceArr($_REQUEST, 'notnull', []);
$this->coalesceArr($_REQUEST, 'uniquekey', []);
diff --git a/src/controllers/TblpropertiesController.php b/src/controllers/TblpropertiesController.php
index 67752f00..ca13bfdc 100644
--- a/src/controllers/TblpropertiesController.php
+++ b/src/controllers/TblpropertiesController.php
@@ -594,37 +594,38 @@ class TblpropertiesController extends BaseController
$this->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="'.\SUBFOLDER.'/src/views/dataimport" method="post" enctype="multipart/form-data">'.PHP_EOL;
- echo '<table>'.PHP_EOL;
- echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strformat']}</th>".PHP_EOL;
- echo "\t\t<td><select name=\"format\">".PHP_EOL;
- echo "\t\t\t<option value=\"auto\">{$this->lang['strauto']}</option>".PHP_EOL;
- echo "\t\t\t<option value=\"csv\">CSV</option>".PHP_EOL;
- echo "\t\t\t<option value=\"tab\">{$this->lang['strtabbed']}</option>".PHP_EOL;
- if (function_exists('xml_parser_create')) {
- echo "\t\t\t<option value=\"xml\">XML</option>".PHP_EOL;
- }
- echo "\t\t</select></td>\n\t</tr>".PHP_EOL;
- echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strallowednulls']}</th>".PHP_EOL;
- echo "\t\t<td><label><input type=\"checkbox\" name=\"allowednulls[0]\" value=\"\\N\" checked=\"checked\" />{$this->lang['strbackslashn']}</label><br />".PHP_EOL;
- echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[1]\" value=\"NULL\" />NULL</label><br />".PHP_EOL;
- echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[2]\" value=\"\" />{$this->lang['stremptystring']}</label></td>\n\t</tr>".PHP_EOL;
- echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strfile']}</th>".PHP_EOL;
- echo "\t\t<td><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />";
- echo "<input type=\"file\" name=\"source\" /></td>\n\t</tr>".PHP_EOL;
- echo '</table>'.PHP_EOL;
- echo '<p><input type="hidden" name="action" value="import" />'.PHP_EOL;
- echo $misc->form;
- echo '<input type="hidden" name="table" value="', htmlspecialchars($_REQUEST['table']), '" />'.PHP_EOL;
- echo "<input type=\"submit\" value=\"{$this->lang['strimport']}\" /></p>".PHP_EOL;
- echo '</form>'.PHP_EOL;
- }
- } else {
+ if (!ini_get('file_uploads')) {
echo "<p>{$this->lang['strnouploads']}</p>".PHP_EOL;
+
+ return;
+ }
+ // 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="'.\SUBFOLDER.'/src/views/dataimport" method="post" enctype="multipart/form-data">'.PHP_EOL;
+ echo '<table>'.PHP_EOL;
+ echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strformat']}</th>".PHP_EOL;
+ echo "\t\t<td><select name=\"format\">".PHP_EOL;
+ echo "\t\t\t<option value=\"auto\">{$this->lang['strauto']}</option>".PHP_EOL;
+ echo "\t\t\t<option value=\"csv\">CSV</option>".PHP_EOL;
+ echo "\t\t\t<option value=\"tab\">{$this->lang['strtabbed']}</option>".PHP_EOL;
+ if (function_exists('xml_parser_create')) {
+ echo "\t\t\t<option value=\"xml\">XML</option>".PHP_EOL;
+ }
+ echo "\t\t</select></td>\n\t</tr>".PHP_EOL;
+ echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strallowednulls']}</th>".PHP_EOL;
+ echo "\t\t<td><label><input type=\"checkbox\" name=\"allowednulls[0]\" value=\"\\N\" checked=\"checked\" />{$this->lang['strbackslashn']}</label><br />".PHP_EOL;
+ echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[1]\" value=\"NULL\" />NULL</label><br />".PHP_EOL;
+ echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[2]\" value=\"\" />{$this->lang['stremptystring']}</label></td>\n\t</tr>".PHP_EOL;
+ echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strfile']}</th>".PHP_EOL;
+ echo "\t\t<td><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />";
+ echo "<input type=\"file\" name=\"source\" /></td>\n\t</tr>".PHP_EOL;
+ echo '</table>'.PHP_EOL;
+ echo '<p><input type="hidden" name="action" value="import" />'.PHP_EOL;
+ echo $misc->form;
+ echo '<input type="hidden" name="table" value="', htmlspecialchars($_REQUEST['table']), '" />'.PHP_EOL;
+ echo "<input type=\"submit\" value=\"{$this->lang['strimport']}\" /></p>".PHP_EOL;
+ echo '</form>'.PHP_EOL;
}
}
@@ -743,7 +744,7 @@ class TblpropertiesController extends BaseController
}
$this->coalesceArr($_POST, 'length', '');
- $status = $data->addColumn(
+ list($status, $sql) = $data->addColumn(
$_POST['table'],
$_POST['field'],
$_POST['type'],
@@ -755,7 +756,7 @@ class TblpropertiesController extends BaseController
);
if (0 == $status) {
$misc->setReloadBrowser(true);
- $this->doDefault($this->lang['strcolumnadded']);
+ $this->doDefault(sprintf('%s %s %s', $sql, PHP_EOL, $this->lang['strcolumnadded']));
} else {
$_REQUEST['stage'] = 1;
$this->doAddColumn($this->lang['strcolumnaddedbad']);
diff --git a/src/controllers/TypesController.php b/src/controllers/TypesController.php
index bc0a2de2..a382349e 100644
--- a/src/controllers/TypesController.php
+++ b/src/controllers/TypesController.php
@@ -406,7 +406,6 @@ class TypesController extends BaseController
break;
case 2:
-
// Check inputs
$fields = trim($_REQUEST['fields']);
if ('' == trim($_REQUEST['name'])) {
@@ -486,7 +485,6 @@ class TypesController extends BaseController
break;
case 3:
-
// Check inputs
$fields = trim($_REQUEST['fields']);
if ('' == trim($_REQUEST['name'])) {
@@ -579,7 +577,6 @@ class TypesController extends BaseController
break;
case 2:
-
// Check inputs
$values = trim($_REQUEST['values']);
if ('' == trim($_REQUEST['name'])) {
@@ -627,7 +624,6 @@ class TypesController extends BaseController
break;
case 3:
-
// Check inputs
$values = trim($_REQUEST['values']);
if ('' == trim($_REQUEST['name'])) {
diff --git a/src/controllers/ViewpropertiesController.php b/src/controllers/ViewpropertiesController.php
index e89b5817..acdb54df 100644
--- a/src/controllers/ViewpropertiesController.php
+++ b/src/controllers/ViewpropertiesController.php
@@ -162,7 +162,6 @@ class ViewpropertiesController extends BaseController
switch ($_REQUEST['stage']) {
case 1:
-
$this->printTrail('column');
$this->printTitle($this->lang['stralter'], 'pg.column.alter');
$this->printMsg($msg);
@@ -204,7 +203,6 @@ class ViewpropertiesController extends BaseController
break;
case 2:
-
// Check inputs
if ('' == trim($_REQUEST['field'])) {
$_REQUEST['stage'] = 1;
diff --git a/src/database/Connection.php b/src/database/Connection.php
index c6156f79..34fa1a74 100644
--- a/src/database/Connection.php
+++ b/src/database/Connection.php
@@ -145,7 +145,7 @@ class Connection
$version_parts = explode('.', $version);
- if (in_array($version_parts[0], ['10','11'])) {
+ if (in_array($version_parts[0], ['10', '11'], true)) {
$major_version = $version_parts[0];
} else {
$major_version = implode('.', [$version_parts[0], $version_parts[1]]);
diff --git a/src/database/Postgres.php b/src/database/Postgres.php
index 0c386c0b..a176663a 100644
--- a/src/database/Postgres.php
+++ b/src/database/Postgres.php
@@ -17,7 +17,6 @@ namespace PHPPgAdmin\Database;
class Postgres extends ADOdbBase
{
use \PHPPgAdmin\Traits\HelperTrait;
-
use \PHPPgAdmin\Database\Traits\AggregateTrait;
use \PHPPgAdmin\Database\Traits\DatabaseTrait;
use \PHPPgAdmin\Database\Traits\DomainTrait;
diff --git a/src/database/Postgres11.php b/src/database/Postgres11.php
index c6ab4cf6..1a47fc32 100644
--- a/src/database/Postgres11.php
+++ b/src/database/Postgres11.php
@@ -1,13 +1,14 @@
<?php
+
/**
* PHPPgAdmin v6.0.0-beta.49
*/
+
namespace PHPPgAdmin\Database;
/**
* @file
* PostgreSQL 11.x support
- *
*/
/**
* Class to add support for Postgres10.
diff --git a/src/database/databasetraits/ColumnTrait.php b/src/database/databasetraits/ColumnTrait.php
index 0f7a451f..15ce6abc 100644
--- a/src/database/databasetraits/ColumnTrait.php
+++ b/src/database/databasetraits/ColumnTrait.php
@@ -23,7 +23,7 @@ trait ColumnTrait
* @param mixed $default The default for the column. '' for none.
* @param string $comment comment for the column
*
- * @return bool|int 0 success
+ * @return array first element is 0 on success, second element is sql sentence
*/
public function addColumn($table, $column, $type, $array, $length, $notnull, $default, $comment)
{
@@ -77,24 +77,26 @@ trait ColumnTrait
$status = $this->beginTransaction();
if ($status != 0) {
- return -1;
+ return [-1, $sql];
}
$status = $this->execute($sql);
if ($status != 0) {
$this->rollbackTransaction();
- return -1;
+ return [-1, $sql];
}
$status = $this->setComment('COLUMN', $column, $table, $comment);
if ($status != 0) {
$this->rollbackTransaction();
- return -1;
+ return [-1, $sql];
}
- return $this->endTransaction();
+ $status = $this->endTransaction();
+
+ return [$status, $sql];
}
/**
diff --git a/src/database/databasetraits/DatabaseTrait.php b/src/database/databasetraits/DatabaseTrait.php
index abdbb7aa..b7d0be75 100644
--- a/src/database/databasetraits/DatabaseTrait.php
+++ b/src/database/databasetraits/DatabaseTrait.php
@@ -520,7 +520,9 @@ trait DatabaseTrait
$sql .= " \"{$f_schema}\".\"{$table}\"";
}
- return $this->execute($sql);
+ $status = $this->execute($sql);
+
+ return [$status, $sql];
}
/**
diff --git a/src/database/databasetraits/TableTrait.php b/src/database/databasetraits/TableTrait.php
index 69558944..fc02d305 100644
--- a/src/database/databasetraits/TableTrait.php
+++ b/src/database/databasetraits/TableTrait.php
@@ -129,12 +129,12 @@ trait TableTrait
* Returns the SQL definition for the table.
* MUST be run within a transaction.
*
- * @param string $table The table to define
- * @param bool|true $clean True to issue drop command, false otherwise
+ * @param string $table The table to define
+ * @param string $cleanprefix set to '-- ' to avoid issuing DROP statement
*
* @return string A string containing the formatted SQL code
*/
- public function getTableDefPrefix($table, $clean = false)
+ public function getTableDefPrefix($table, $cleanprefix = '')
{
// Fetch table
$t = $this->getTable($table);
@@ -171,12 +171,7 @@ trait TableTrait
// Begin CREATE TABLE definition
$sql .= "-- Definition\n\n";
// DROP TABLE must be fully qualified in case a table with the same name exists
- // in pg_catalog.
- if (!$clean) {
- $sql .= '-- ';
- }
-
- $sql .= 'DROP TABLE ';
+ $sql .= $cleanprefix.'DROP TABLE ';
$sql .= "\"{$t->fields['nspname']}\".\"{$t->fields['relname']}\";\n";
$sql .= "CREATE TABLE \"{$t->fields['nspname']}\".\"{$t->fields['relname']}\" (\n";
@@ -397,6 +392,7 @@ trait TableTrait
break;
case 'user':
+ case 'role':
$this->fieldClean($v[1]);
$sql .= "\"{$v[1]}\";\n";
@@ -439,6 +435,7 @@ trait TableTrait
break;
case 'user':
+ case 'role':
$this->fieldClean($v[1]);
$sql .= "\"{$v[1]}\"";
@@ -480,15 +477,20 @@ trait TableTrait
$this->clean($c_schema);
$this->clean($table);
- $sql = "
+ $sql = '
SELECT
- c.relname, n.nspname, u.usename AS relowner,
+ c.relname, n.nspname, ';
+
+ $sql .= ($this->hasRoles() ? ' coalesce(u.usename,r.rolname) ' : ' u.usename')." AS relowner,
pg_catalog.obj_description(c.oid, 'pg_class') AS relcomment,
- (SELECT spcname FROM pg_catalog.pg_tablespace pt WHERE pt.oid=c.reltablespace) AS tablespace
+ pt.spcname AS tablespace
FROM pg_catalog.pg_class c
+ LEFT JOIN pg_catalog.pg_tablespace pt ON pt.oid=c.reltablespace
LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
- WHERE c.relkind = 'r'
+ LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace ";
+
+ $sql .= ($this->hasRoles() ? ' LEFT JOIN pg_catalog.pg_roles r ON c.relowner = r.oid ' : '').
+ " WHERE c.relkind = 'r'
AND n.nspname = '{$c_schema}'
AND n.oid = c.relnamespace
AND c.relname = '{$table}'";
@@ -497,55 +499,68 @@ trait TableTrait
}
/**
- * Retrieve the attribute definition of a table.
+ * Retrieve all attributes definition of a table.
*
- * @param string $table The name of the table
- * @param string $field (optional) The name of a field to return
+ * @param string $table The name of the table
+ * @param string $c_schema The name of the schema
*
* @return \PHPPgAdmin\ADORecordSet All attributes in order
*/
- public function getTableAttributes($table, $field = '')
+ private function _getTableAttributesAll($table, $c_schema)
{
- $c_schema = $this->_schema;
- $this->clean($c_schema);
- $this->clean($table);
- $this->clean($field);
+ $sql = "
+ SELECT
+ a.attname,
+ a.attnum,
+ pg_catalog.format_type(a.atttypid, a.atttypmod) AS TYPE,
+ a.atttypmod,
+ a.attnotnull,
+ a.atthasdef,
+ pg_catalog.pg_get_expr(adef.adbin, adef.adrelid, TRUE) AS adsrc,
+ a.attstattarget,
+ a.attstorage,
+ t.typstorage,
+ CASE
+ WHEN pc.oid IS NULL THEN FALSE
+ ELSE TRUE
+ END AS attisserial,
+ pg_catalog.col_description(a.attrelid, a.attnum) AS COMMENT
+
+ FROM pg_catalog.pg_tables tbl
+ JOIN pg_catalog.pg_class tbl_class ON tbl.tablename=tbl_class.relname
+ JOIN pg_catalog.pg_attribute a ON tbl_class.oid = a.attrelid
+ JOIN pg_catalog.pg_namespace ON pg_namespace.oid = tbl_class.relnamespace
+ AND pg_namespace.nspname=tbl.schemaname
+ LEFT JOIN pg_catalog.pg_attrdef adef ON a.attrelid=adef.adrelid
+ AND a.attnum=adef.adnum
+ LEFT JOIN pg_catalog.pg_type t ON a.atttypid=t.oid
+ LEFT JOIN pg_catalog.pg_depend pd ON pd.refobjid=a.attrelid
+ AND pd.refobjsubid=a.attnum
+ AND pd.deptype='i'
+ LEFT JOIN pg_catalog.pg_class pc ON pd.objid=pc.oid
+ AND pd.classid=pc.tableoid
+ AND pd.refclassid=pc.tableoid
+ AND pc.relkind='S'
+ WHERE tbl.tablename='{$table}'
+ AND tbl.schemaname='{$c_schema}'
+ AND a.attnum > 0 AND NOT a.attisdropped
+ ORDER BY a.attnum";
- if ($field == '') {
- // This query is made much more complex by the addition of the 'attisserial' field.
- // The subquery to get that field checks to see if there is an internally dependent
- // sequence on the field.
- $sql = "
- SELECT
- a.attname, a.attnum,
- pg_catalog.format_type(a.atttypid, a.atttypmod) as type,
- a.atttypmod,
- a.attnotnull, a.atthasdef, pg_catalog.pg_get_expr(adef.adbin, adef.adrelid, true) as adsrc,
- a.attstattarget, a.attstorage, t.typstorage,
- (
- SELECT 1 FROM pg_catalog.pg_depend pd, pg_catalog.pg_class pc
- WHERE pd.objid=pc.oid
- AND pd.classid=pc.tableoid
- AND pd.refclassid=pc.tableoid
- AND pd.refobjid=a.attrelid
- AND pd.refobjsubid=a.attnum
- AND pd.deptype='i'
- AND pc.relkind='S'
- ) IS NOT NULL AS attisserial,
- pg_catalog.col_description(a.attrelid, a.attnum) AS comment
- FROM
- pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef adef
- ON a.attrelid=adef.adrelid
- AND a.attnum=adef.adnum
- LEFT JOIN pg_catalog.pg_type t ON a.atttypid=t.oid
- WHERE
- a.attrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname='{$table}'
- AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE
- nspname = '{$c_schema}'))
- AND a.attnum > 0 AND NOT a.attisdropped
- ORDER BY a.attnum";
- } else {
- $sql = "
+ return $this->selectSet($sql);
+ }
+
+ /**
+ * Retrieve single attribute definition of a table.
+ *
+ * @param string $table The name of the table
+ * @param string $c_schema The schema of the table
+ * @param string $field (optional) The name of a field to return
+ *
+ * @return \PHPPgAdmin\ADORecordSet All attributes in order
+ */
+ private function _getTableAttribute($table, $c_schema, $field)
+ {
+ $sql = "
SELECT
a.attname, a.attnum,
pg_catalog.format_type(a.atttypid, a.atttypmod) as type,
@@ -564,12 +579,36 @@ trait TableTrait
AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE
nspname = '{$c_schema}'))
AND a.attname = '{$field}'";
- }
return $this->selectSet($sql);
}
/**
+ * Retrieve the attribute definition of a table.
+ *
+ * @param string $table The name of the table
+ * @param string $field (optional) The name of a field to return
+ *
+ * @return \PHPPgAdmin\ADORecordSet All attributes in order
+ */
+ public function getTableAttributes($table, $field = '')
+ {
+ $c_schema = $this->_schema;
+ $this->clean($c_schema);
+ $this->clean($table);
+
+ if ($field == '') {
+ // This query is made much more complex by the addition of the 'attisserial' field.
+ // The subquery to get that field checks to see if there is an internally dependent
+ // sequence on the field.
+ return $this->_getTableAttributesAll($table, $c_schema);
+ }
+ $this->clean($field);
+
+ return $this->_getTableAttribute($table, $c_schema, $field);
+ }
+
+ /**
* Returns a list of all constraints on a table.
*
* @param string $table The table to find rules for
diff --git a/src/traits/AdminTrait.php b/src/traits/AdminTrait.php
index cc400b9a..391786e7 100644
--- a/src/traits/AdminTrait.php
+++ b/src/traits/AdminTrait.php
@@ -514,28 +514,26 @@ trait AdminTrait
if (is_array($_REQUEST['table'])) {
$msg = '';
foreach ($_REQUEST['table'] as $t) {
- $status = $data->vacuumDB($t, isset($_REQUEST['vacuum_analyze']), isset($_REQUEST['vacuum_full']), isset($_REQUEST['vacuum_freeze']));
- if (0 == $status) {
- $msg .= sprintf('%s: %s<br />', htmlentities($t, ENT_QUOTES, 'UTF-8'), $this->lang['strvacuumgood']);
- } else {
- $this->doDefault(sprintf('%s %s%s: %s<br />', $type, $msg, htmlentities($t, ENT_QUOTES, 'UTF-8'), $this->lang['strvacuumbad']));
-
- return;
+ list($status, $sql) = $data->vacuumDB($t, isset($_REQUEST['vacuum_analyze']), isset($_REQUEST['vacuum_full']), isset($_REQUEST['vacuum_freeze']));
+ if (0 !== $status) {
+ return $this->doDefault(sprintf('%s %s%s: %s<br />', $type, $msg, htmlentities($t, ENT_QUOTES, 'UTF-8'), $this->lang['strvacuumbad']));
}
+ $msg .= sprintf('%s%s %s: %s<br />', $sql, PHP_EOL, htmlentities($t, ENT_QUOTES, 'UTF-8'), $this->lang['strvacuumgood']);
}
// Everything went fine, back to the Default page....
$this->misc->setReloadBrowser(true);
- $this->doDefault($msg);
- } else {
- //we must pass table here. When empty, vacuum the whole db
- $status = $data->vacuumDB($_REQUEST['table'], isset($_REQUEST['vacuum_analyze']), isset($_REQUEST['vacuum_full']), isset($_REQUEST['vacuum_freeze']));
- if (0 == $status) {
- $this->misc->setReloadBrowser(true);
- $this->doAdmin($type, $this->lang['strvacuumgood']);
- } else {
- $this->doAdmin($type, $this->lang['strvacuumbad']);
- }
+
+ return $this->doDefault($msg);
+ }
+ //we must pass table here. When empty, vacuum the whole db
+ list($status, $sql) = $data->vacuumDB($_REQUEST['table'], isset($_REQUEST['vacuum_analyze']), isset($_REQUEST['vacuum_full']), isset($_REQUEST['vacuum_freeze']));
+ if (0 == $status) {
+ $this->misc->setReloadBrowser(true);
+
+ return $this->doAdmin($type, sprintf('%s%s%s', $sql, PHP_EOL, $this->lang['strvacuumgood']));
}
+
+ return $this->doAdmin($type, $this->lang['strvacuumbad']);
}
/**