diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/controllers/InfoController.php | 602 | ||||
-rw-r--r-- | src/controllers/TblpropertiesController.php | 328 | ||||
-rw-r--r-- | src/database/databasetraits/DatabaseTrait.php | 2 | ||||
-rw-r--r-- | src/database/databasetraits/TableTrait.php | 414 |
4 files changed, 751 insertions, 595 deletions
diff --git a/src/controllers/InfoController.php b/src/controllers/InfoController.php index 8a66ae30..c702e2d0 100644 --- a/src/controllers/InfoController.php +++ b/src/controllers/InfoController.php @@ -51,7 +51,7 @@ class InfoController extends BaseController $this->printMsg($msg); // common params for printVal - $shownull = ['null' => true]; + $this->shownull = ['null' => true]; // Fetch info $referrers = $data->getReferrers($_REQUEST['table']); @@ -68,306 +68,342 @@ class InfoController extends BaseController && (0 == $tablestatstups->recordCount() && 0 == $tablestatsio->recordCount() && 0 == $indexstatstups->recordCount() && 0 == $indexstatsio->recordCount())) { $this->printMsg($this->lang['strnoinfo']); - } else { - // Referring foreign tables - if ($referrers !== -99 && $referrers->recordCount() > 0) { - echo "<h3>{$this->lang['strreferringtables']}</h3>".PHP_EOL; - - $columns = [ - 'schema' => [ - 'title' => $this->lang['strschema'], - 'field' => Decorator::field('nspname'), - ], - 'table' => [ - 'title' => $this->lang['strtable'], - 'field' => Decorator::field('relname'), - ], - 'name' => [ - 'title' => $this->lang['strname'], - 'field' => Decorator::field('conname'), - ], - 'definition' => [ - 'title' => $this->lang['strdefinition'], - 'field' => Decorator::field('consrc'), - ], - 'actions' => [ - 'title' => $this->lang['stractions'], - ], - ]; - - $actions = [ - 'properties' => [ - 'content' => $this->lang['strproperties'], - 'attr' => [ - 'href' => [ - 'url' => 'constraints', - 'urlvars' => [ - 'schema' => Decorator::field('nspname'), - 'table' => Decorator::field('relname'), - ], - ], - ], - ], - ]; - echo $this->printTable($referrers, $columns, $actions, 'info-referrers', $this->lang['strnodata']); - } + return; + } + // Referring foreign tables + if ($referrers !== -99 && $referrers->recordCount() > 0) { + $this->_printReferring($referrers); + } - // Parent tables - if ($parents->recordCount() > 0) { - echo "<h3>{$this->lang['strparenttables']}</h3>".PHP_EOL; + // Parent tables + if ($parents->recordCount() > 0) { + $this->_printParents($parents); + } - $columns = [ - 'schema' => [ - 'title' => $this->lang['strschema'], - 'field' => Decorator::field('nspname'), - ], - 'table' => [ - 'title' => $this->lang['strtable'], - 'field' => Decorator::field('relname'), - ], - 'actions' => [ - 'title' => $this->lang['stractions'], - ], - ]; - - $actions = [ - 'properties' => [ - 'content' => $this->lang['strproperties'], - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties', - 'urlvars' => [ - 'schema' => Decorator::field('nspname'), - 'table' => Decorator::field('relname'), - ], - ], - ], - ], - ]; + // Child tables + if ($children->recordCount() > 0) { + $this->_printChildren($children); + } - echo $this->printTable($parents, $columns, $actions, 'info-parents', $this->lang['strnodata']); - } + // Row performance + if ($tablestatstups->recordCount() > 0) { + $this->_printTablestatstups($tablestatstups); + } - // Child tables - if ($children->recordCount() > 0) { - echo "<h3>{$this->lang['strchildtables']}</h3>".PHP_EOL; + // I/O performance + if ($tablestatsio->recordCount() > 0) { + $this->_printTablestatsio($tablestatsio); + } - $columns = [ - 'schema' => [ - 'title' => $this->lang['strschema'], - 'field' => Decorator::field('nspname'), - ], - 'table' => [ - 'title' => $this->lang['strtable'], - 'field' => Decorator::field('relname'), - ], - 'actions' => [ - 'title' => $this->lang['stractions'], - ], - ]; - - $actions = [ - 'properties' => [ - 'content' => $this->lang['strproperties'], - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties', - 'urlvars' => [ - 'schema' => Decorator::field('nspname'), - 'table' => Decorator::field('relname'), - ], - ], + // Index row performance + if ($indexstatstups->recordCount() > 0) { + $this->_printIndexstatstups($indexstatstups); + } + + // Index I/0 performance + if ($indexstatsio->recordCount() > 0) { + $this->_printIndexstatsio($indexstatsio); + } + } + + private function _printChildren($children) + { + echo "<h3>{$this->lang['strchildtables']}</h3>".PHP_EOL; + + $columns = [ + 'schema' => [ + 'title' => $this->lang['strschema'], + 'field' => Decorator::field('nspname'), + ], + 'table' => [ + 'title' => $this->lang['strtable'], + 'field' => Decorator::field('relname'), + ], + 'actions' => [ + 'title' => $this->lang['stractions'], + ], + ]; + + $actions = [ + 'properties' => [ + 'content' => $this->lang['strproperties'], + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties', + 'urlvars' => [ + 'schema' => Decorator::field('nspname'), + 'table' => Decorator::field('relname'), ], ], - ]; + ], + ], + ]; + + echo $this->printTable($children, $columns, $actions, 'info-children', $this->lang['strnodata']); + } + + private function _printTablestatstups($tablestatstups) + { + echo "<h3>{$this->lang['strrowperf']}</h3>".PHP_EOL; + + echo '<table>'.PHP_EOL; + echo "\t<tr>".PHP_EOL; + echo "\t\t<th class=\"data\" colspan=\"2\">{$this->lang['strsequential']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\" colspan=\"2\">{$this->lang['strindex']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strrows2']}</th>".PHP_EOL; + echo "\t</tr>".PHP_EOL; + echo "\t<tr>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strscan']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strread']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strscan']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strfetch']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strinsert']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strupdate']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strdelete']}</th>".PHP_EOL; + echo "\t</tr>".PHP_EOL; + $i = 0; + + while (!$tablestatstups->EOF) { + $id = (0 == ($i % 2) ? '1' : '2'); + echo "\t<tr class=\"data{$id}\">".PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['seq_scan'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['seq_tup_read'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['idx_scan'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['idx_tup_fetch'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['n_tup_ins'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['n_tup_upd'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['n_tup_del'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t</tr>".PHP_EOL; + $tablestatstups->movenext(); + ++$i; + } + + echo '</table>'.PHP_EOL; + } - echo $this->printTable($children, $columns, $actions, 'info-children', $this->lang['strnodata']); + private function _printTablestatsio($tablestatsio) + { + echo "<h3>{$this->lang['strioperf']}</h3>".PHP_EOL; + + echo '<table>'.PHP_EOL; + echo "\t<tr>".PHP_EOL; + echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strheap']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strindex']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strtoast']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strtoastindex']}</th>".PHP_EOL; + echo "\t</tr>".PHP_EOL; + echo "\t<tr>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; + echo "\t</tr>".PHP_EOL; + $i = 0; + + while (!$tablestatsio->EOF) { + $id = (0 == ($i % 2) ? '1' : '2'); + echo "\t<tr class=\"data{$id}\">".PHP_EOL; + + $total = $tablestatsio->fields['heap_blks_hit'] + $tablestatsio->fields['heap_blks_read']; + if ($total > 0) { + $percentage = round(($tablestatsio->fields['heap_blks_hit'] / $total) * 100); + } else { + $percentage = 0; } - // Row performance - if ($tablestatstups->recordCount() > 0) { - echo "<h3>{$this->lang['strrowperf']}</h3>".PHP_EOL; - - echo '<table>'.PHP_EOL; - echo "\t<tr>".PHP_EOL; - echo "\t\t<th class=\"data\" colspan=\"2\">{$this->lang['strsequential']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\" colspan=\"2\">{$this->lang['strindex']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strrows2']}</th>".PHP_EOL; - echo "\t</tr>".PHP_EOL; - echo "\t<tr>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strscan']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strread']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strscan']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strfetch']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strinsert']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strupdate']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strdelete']}</th>".PHP_EOL; - echo "\t</tr>".PHP_EOL; - $i = 0; - - while (!$tablestatstups->EOF) { - $id = (0 == ($i % 2) ? '1' : '2'); - echo "\t<tr class=\"data{$id}\">".PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['seq_scan'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['seq_tup_read'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['idx_scan'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['idx_tup_fetch'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['n_tup_ins'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['n_tup_upd'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatstups->fields['n_tup_del'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t</tr>".PHP_EOL; - $tablestatstups->movenext(); - ++$i; - } - - echo '</table>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['heap_blks_read'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['heap_blks_hit'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; + + $total = $tablestatsio->fields['idx_blks_hit'] + $tablestatsio->fields['idx_blks_read']; + if ($total > 0) { + $percentage = round(($tablestatsio->fields['idx_blks_hit'] / $total) * 100); + } else { + $percentage = 0; } - // I/O performance - if ($tablestatsio->recordCount() > 0) { - echo "<h3>{$this->lang['strioperf']}</h3>".PHP_EOL; - - echo '<table>'.PHP_EOL; - echo "\t<tr>".PHP_EOL; - echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strheap']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strindex']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strtoast']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\" colspan=\"3\">{$this->lang['strtoastindex']}</th>".PHP_EOL; - echo "\t</tr>".PHP_EOL; - echo "\t<tr>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; - echo "\t</tr>".PHP_EOL; - $i = 0; - - while (!$tablestatsio->EOF) { - $id = (0 == ($i % 2) ? '1' : '2'); - echo "\t<tr class=\"data{$id}\">".PHP_EOL; - - $total = $tablestatsio->fields['heap_blks_hit'] + $tablestatsio->fields['heap_blks_read']; - if ($total > 0) { - $percentage = round(($tablestatsio->fields['heap_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['heap_blks_read'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['heap_blks_hit'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; - - $total = $tablestatsio->fields['idx_blks_hit'] + $tablestatsio->fields['idx_blks_read']; - if ($total > 0) { - $percentage = round(($tablestatsio->fields['idx_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['idx_blks_read'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['idx_blks_hit'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; - - $total = $tablestatsio->fields['toast_blks_hit'] + $tablestatsio->fields['toast_blks_read']; - if ($total > 0) { - $percentage = round(($tablestatsio->fields['toast_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['toast_blks_read'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['toast_blks_hit'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; - - $total = $tablestatsio->fields['tidx_blks_hit'] + $tablestatsio->fields['tidx_blks_read']; - if ($total > 0) { - $percentage = round(($tablestatsio->fields['tidx_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['tidx_blks_read'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['tidx_blks_hit'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; - echo "\t</tr>".PHP_EOL; - $tablestatsio->movenext(); - ++$i; - } - - echo '</table>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['idx_blks_read'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['idx_blks_hit'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; + + $total = $tablestatsio->fields['toast_blks_hit'] + $tablestatsio->fields['toast_blks_read']; + if ($total > 0) { + $percentage = round(($tablestatsio->fields['toast_blks_hit'] / $total) * 100); + } else { + $percentage = 0; } - // Index row performance - if ($indexstatstups->recordCount() > 0) { - echo "<h3>{$this->lang['stridxrowperf']}</h3>".PHP_EOL; - - echo '<table>'.PHP_EOL; - echo "\t<tr>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strindex']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strscan']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strread']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strfetch']}</th>".PHP_EOL; - echo "\t</tr>".PHP_EOL; - $i = 0; - - while (!$indexstatstups->EOF) { - $id = (0 == ($i % 2) ? '1' : '2'); - echo "\t<tr class=\"data{$id}\">".PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($indexstatstups->fields['indexrelname']), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($indexstatstups->fields['idx_scan'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($indexstatstups->fields['idx_tup_read'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($indexstatstups->fields['idx_tup_fetch'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t</tr>".PHP_EOL; - $indexstatstups->movenext(); - ++$i; - } - - echo '</table>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['toast_blks_read'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['toast_blks_hit'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; + + $total = $tablestatsio->fields['tidx_blks_hit'] + $tablestatsio->fields['tidx_blks_read']; + if ($total > 0) { + $percentage = round(($tablestatsio->fields['tidx_blks_hit'] / $total) * 100); + } else { + $percentage = 0; } - // Index I/0 performance - if ($indexstatsio->recordCount() > 0) { - echo "<h3>{$this->lang['stridxioperf']}</h3>".PHP_EOL; - - echo '<table>'.PHP_EOL; - echo "\t<tr>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strindex']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; - echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; - echo "\t</tr>".PHP_EOL; - $i = 0; - - while (!$indexstatsio->EOF) { - $id = (0 == ($i % 2) ? '1' : '2'); - echo "\t<tr class=\"data{$id}\">".PHP_EOL; - $total = $indexstatsio->fields['idx_blks_hit'] + $indexstatsio->fields['idx_blks_read']; - if ($total > 0) { - $percentage = round(($indexstatsio->fields['idx_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $this->misc->printVal($indexstatsio->fields['indexrelname']), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($indexstatsio->fields['idx_blks_read'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>", $this->misc->printVal($indexstatsio->fields['idx_blks_hit'], 'int4', $shownull), '</td>'.PHP_EOL; - echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; - echo "\t</tr>".PHP_EOL; - $indexstatsio->movenext(); - ++$i; - } - - echo '</table>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['tidx_blks_read'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($tablestatsio->fields['tidx_blks_hit'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; + echo "\t</tr>".PHP_EOL; + $tablestatsio->movenext(); + ++$i; + } + + echo '</table>'.PHP_EOL; + } + + private function _printIndexstatstups($indexstatstups) + { + echo "<h3>{$this->lang['stridxrowperf']}</h3>".PHP_EOL; + + echo '<table>'.PHP_EOL; + echo "\t<tr>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strindex']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strscan']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strread']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strfetch']}</th>".PHP_EOL; + echo "\t</tr>".PHP_EOL; + $i = 0; + + while (!$indexstatstups->EOF) { + $id = (0 == ($i % 2) ? '1' : '2'); + echo "\t<tr class=\"data{$id}\">".PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($indexstatstups->fields['indexrelname']), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($indexstatstups->fields['idx_scan'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($indexstatstups->fields['idx_tup_read'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($indexstatstups->fields['idx_tup_fetch'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t</tr>".PHP_EOL; + $indexstatstups->movenext(); + ++$i; + } + + echo '</table>'.PHP_EOL; + } + + private function _printIndexstatsio($indexstatsio) + { + echo "<h3>{$this->lang['stridxioperf']}</h3>".PHP_EOL; + + echo '<table>'.PHP_EOL; + echo "\t<tr>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strindex']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strdisk']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strcache']}</th>".PHP_EOL; + echo "\t\t<th class=\"data\">{$this->lang['strpercent']}</th>".PHP_EOL; + echo "\t</tr>".PHP_EOL; + $i = 0; + + while (!$indexstatsio->EOF) { + $id = (0 == ($i % 2) ? '1' : '2'); + echo "\t<tr class=\"data{$id}\">".PHP_EOL; + $total = $indexstatsio->fields['idx_blks_hit'] + $indexstatsio->fields['idx_blks_read']; + if ($total > 0) { + $percentage = round(($indexstatsio->fields['idx_blks_hit'] / $total) * 100); + } else { + $percentage = 0; } + + echo "\t\t<td>", $this->misc->printVal($indexstatsio->fields['indexrelname']), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($indexstatsio->fields['idx_blks_read'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>", $this->misc->printVal($indexstatsio->fields['idx_blks_hit'], 'int4', $this->shownull), '</td>'.PHP_EOL; + echo "\t\t<td>({$percentage}{$this->lang['strpercent']})</td>".PHP_EOL; + echo "\t</tr>".PHP_EOL; + $indexstatsio->movenext(); + ++$i; } + + echo '</table>'.PHP_EOL; + } + + private function _printParents($parents) + { + echo "<h3>{$this->lang['strparenttables']}</h3>".PHP_EOL; + + $columns = [ + 'schema' => [ + 'title' => $this->lang['strschema'], + 'field' => Decorator::field('nspname'), + ], + 'table' => [ + 'title' => $this->lang['strtable'], + 'field' => Decorator::field('relname'), + ], + 'actions' => [ + 'title' => $this->lang['stractions'], + ], + ]; + + $actions = [ + 'properties' => [ + 'content' => $this->lang['strproperties'], + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties', + 'urlvars' => [ + 'schema' => Decorator::field('nspname'), + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + ]; + + echo $this->printTable($parents, $columns, $actions, 'info-parents', $this->lang['strnodata']); + } + + private function _printReferring($referrers) + { + echo "<h3>{$this->lang['strreferringtables']}</h3>".PHP_EOL; + + $columns = [ + 'schema' => [ + 'title' => $this->lang['strschema'], + 'field' => Decorator::field('nspname'), + ], + 'table' => [ + 'title' => $this->lang['strtable'], + 'field' => Decorator::field('relname'), + ], + 'name' => [ + 'title' => $this->lang['strname'], + 'field' => Decorator::field('conname'), + ], + 'definition' => [ + 'title' => $this->lang['strdefinition'], + 'field' => Decorator::field('consrc'), + ], + 'actions' => [ + 'title' => $this->lang['stractions'], + ], + ]; + + $actions = [ + 'properties' => [ + 'content' => $this->lang['strproperties'], + 'attr' => [ + 'href' => [ + 'url' => 'constraints', + 'urlvars' => [ + 'schema' => Decorator::field('nspname'), + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + ]; + + echo $this->printTable($referrers, $columns, $actions, 'info-referrers', $this->lang['strnodata']); } } diff --git a/src/controllers/TblpropertiesController.php b/src/controllers/TblpropertiesController.php index 37acdd8c..930cf29f 100644 --- a/src/controllers/TblpropertiesController.php +++ b/src/controllers/TblpropertiesController.php @@ -103,172 +103,25 @@ class TblpropertiesController extends BaseController */ public function doDefault($msg = '') { - $misc = $this->misc; - $data = $misc->getDatabaseAccessor(); - - $attPre = function (&$rowdata, $actions) use ($data) { - $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); - $attname = $rowdata->fields['attname']; - $table = $_REQUEST['table']; - $data->fieldClean($attname); - $data->fieldClean($table); - - $actions['browse']['attr']['href']['urlvars']['query'] = "SELECT \"{$attname}\", count(*) AS \"count\" - FROM \"{$table}\" GROUP BY \"{$attname}\" ORDER BY \"{$attname}\""; - - return $actions; - }; - - $cstrRender = function ($s, $p) use ($misc, $data) { - $str = ''; - foreach ($p['keys'] as $k => $c) { - if (is_null($p['keys'][$k]['consrc'])) { - $atts = $data->getAttributeNames($_REQUEST['table'], explode(' ', $p['keys'][$k]['indkey'])); - $c['consrc'] = ('u' == $c['contype'] ? 'UNIQUE (' : 'PRIMARY KEY (').join(',', $atts).')'; - } - - if ($c['p_field'] == $s) { - switch ($c['contype']) { - case 'p': - $str .= '<a href="constraints?'.$misc->href.'&table='.urlencode($c['p_table']).'&schema='.urlencode($c['p_schema']).'"><img src="'. - $misc->icon('PrimaryKey').'" alt="[pk]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>'; - - break; - case 'f': - $str .= '<a href="tblproperties?'.$misc->href.'&table='.urlencode($c['f_table']).'&schema='.urlencode($c['f_schema']).'"><img src="'. - $misc->icon('ForeignKey').'" alt="[fk]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>'; - - break; - case 'u': - $str .= '<a href="constraints?'.$misc->href.'&table='.urlencode($c['p_table']).'&schema='.urlencode($c['p_schema']).'"><img src="'. - $misc->icon('UniqueConstraint').'" alt="[uniq]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>'; - - break; - case 'c': - $str .= '<a href="constraints?'.$misc->href.'&table='.urlencode($c['p_table']).'&schema='.urlencode($c['p_schema']).'"><img src="'. - $misc->icon('CheckConstraint').'" alt="[check]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>'; - } - } - } - - return $str; - }; + $misc = $this->misc; + $this->data = $misc->getDatabaseAccessor(); $this->printTrail('table'); $this->printTabs('table', 'columns'); $this->printMsg($msg); // Get table - $tdata = $data->getTable($_REQUEST['table']); + $tdata = $this->data->getTable($_REQUEST['table']); // Get columns - $attrs = $data->getTableAttributes($_REQUEST['table']); + $attrs = $this->data->getTableAttributes($_REQUEST['table']); // Get constraints keys - $ck = $data->getConstraintsWithFields($_REQUEST['table']); + $ck = $this->data->getConstraintsWithFields($_REQUEST['table']); // Show comment if any if (null !== $tdata->fields['relcomment']) { echo '<p class="comment">', $misc->printVal($tdata->fields['relcomment']), '</p>'.PHP_EOL; } - - $columns = [ - 'column' => [ - 'title' => $this->lang['strcolumn'], - 'field' => Decorator::field('attname'), - 'url' => "colproperties?subject=column&{$misc->href}&table=".urlencode($_REQUEST['table']).'&', - 'vars' => ['column' => 'attname'], - ], - 'type' => [ - 'title' => $this->lang['strtype'], - 'field' => Decorator::field('+type'), - ], - 'notnull' => [ - 'title' => $this->lang['strnotnull'], - 'field' => Decorator::field('attnotnull'), - 'type' => 'bool', - 'params' => ['true' => 'NOT NULL', 'false' => ''], - ], - 'default' => [ - 'title' => $this->lang['strdefault'], - 'field' => Decorator::field('adsrc'), - ], - 'keyprop' => [ - 'title' => $this->lang['strconstraints'], - 'class' => 'constraint_cell', - 'field' => Decorator::field('attname'), - 'type' => 'callback', - 'params' => [ - 'function' => $cstrRender, - 'keys' => $ck->getArray(), - ], - ], - 'actions' => [ - 'title' => $this->lang['stractions'], - ], - 'comment' => [ - 'title' => $this->lang['strcomment'], - 'field' => Decorator::field('comment'), - ], - ]; - - $actions = [ - 'browse' => [ - 'content' => $this->lang['strbrowse'], - 'attr' => [ - 'href' => [ - 'url' => 'display', - 'urlvars' => [ - 'table' => $_REQUEST['table'], - 'subject' => 'column', - 'return' => 'table', - 'column' => Decorator::field('attname'), - ], - ], - ], - ], - 'alter' => [ - 'content' => $this->lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'colproperties', - 'urlvars' => [ - 'subject' => 'column', - 'action' => 'properties', - 'table' => $_REQUEST['table'], - 'column' => Decorator::field('attname'), - ], - ], - ], - ], - 'privileges' => [ - 'content' => $this->lang['strprivileges'], - 'attr' => [ - 'href' => [ - 'url' => 'privileges', - 'urlvars' => [ - 'subject' => 'column', - 'table' => $_REQUEST['table'], - 'column' => Decorator::field('attname'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $this->lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties', - 'urlvars' => [ - 'subject' => 'column', - 'action' => 'confirm_drop', - 'table' => $_REQUEST['table'], - 'column' => Decorator::field('attname'), - ], - ], - ], - ], - ]; - - echo $this->printTable($attrs, $columns, $actions, 'tblproperties-tblproperties', $this->lang['strnodata'], $attPre); + $this->_printTable($ck, $attrs); $navlinks = [ 'browse' => [ @@ -805,4 +658,173 @@ class TblpropertiesController extends BaseController } } } + + private function _getAttPre($data) + { + $attPre = function (&$rowdata, $actions) use ($data) { + $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); + $attname = $rowdata->fields['attname']; + $table = $_REQUEST['table']; + $data->fieldClean($attname); + $data->fieldClean($table); + + $actions['browse']['attr']['href']['urlvars']['query'] = "SELECT \"{$attname}\", count(*) AS \"count\" + FROM \"{$table}\" GROUP BY \"{$attname}\" ORDER BY \"{$attname}\""; + + return $actions; + }; + + return $attPre; + } + + private function _getCstrRender($misc, $data) + { + $cstrRender = function ($s, $p) use ($misc, $data) { + $str = ''; + foreach ($p['keys'] as $k => $c) { + if (is_null($p['keys'][$k]['consrc'])) { + $atts = $data->getAttributeNames($_REQUEST['table'], explode(' ', $p['keys'][$k]['indkey'])); + $c['consrc'] = ('u' == $c['contype'] ? 'UNIQUE (' : 'PRIMARY KEY (').join(',', $atts).')'; + } + + if ($c['p_field'] == $s) { + switch ($c['contype']) { + case 'p': + $str .= '<a href="constraints?'.$misc->href.'&table='.urlencode($c['p_table']).'&schema='.urlencode($c['p_schema']).'"><img src="'. + $misc->icon('PrimaryKey').'" alt="[pk]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>'; + + break; + case 'f': + $str .= '<a href="tblproperties?'.$misc->href.'&table='.urlencode($c['f_table']).'&schema='.urlencode($c['f_schema']).'"><img src="'. + $misc->icon('ForeignKey').'" alt="[fk]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>'; + + break; + case 'u': + $str .= '<a href="constraints?'.$misc->href.'&table='.urlencode($c['p_table']).'&schema='.urlencode($c['p_schema']).'"><img src="'. + $misc->icon('UniqueConstraint').'" alt="[uniq]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>'; + + break; + case 'c': + $str .= '<a href="constraints?'.$misc->href.'&table='.urlencode($c['p_table']).'&schema='.urlencode($c['p_schema']).'"><img src="'. + $misc->icon('CheckConstraint').'" alt="[check]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>'; + } + } + } + + return $str; + }; + + return $cstrRender; + } + + private function _printTable($ck, $attrs) + { + $misc = $this->misc; + + $data = $this->data; + + $attPre = $this->_getAttPre($data); + + $cstrRender = $this->_getCstrRender($misc, $data); + + $columns = [ + 'column' => [ + 'title' => $this->lang['strcolumn'], + 'field' => Decorator::field('attname'), + 'url' => "colproperties?subject=column&{$misc->href}&table=".urlencode($_REQUEST['table']).'&', + 'vars' => ['column' => 'attname'], + ], + 'type' => [ + 'title' => $this->lang['strtype'], + 'field' => Decorator::field('+type'), + ], + 'notnull' => [ + 'title' => $this->lang['strnotnull'], + 'field' => Decorator::field('attnotnull'), + 'type' => 'bool', + 'params' => ['true' => 'NOT NULL', 'false' => ''], + ], + 'default' => [ + 'title' => $this->lang['strdefault'], + 'field' => Decorator::field('adsrc'), + ], + 'keyprop' => [ + 'title' => $this->lang['strconstraints'], + 'class' => 'constraint_cell', + 'field' => Decorator::field('attname'), + 'type' => 'callback', + 'params' => [ + 'function' => $cstrRender, + 'keys' => $ck->getArray(), + ], + ], + 'actions' => [ + 'title' => $this->lang['stractions'], + ], + 'comment' => [ + 'title' => $this->lang['strcomment'], + 'field' => Decorator::field('comment'), + ], + ]; + + $actions = [ + 'browse' => [ + 'content' => $this->lang['strbrowse'], + 'attr' => [ + 'href' => [ + 'url' => 'display', + 'urlvars' => [ + 'table' => $_REQUEST['table'], + 'subject' => 'column', + 'return' => 'table', + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + 'alter' => [ + 'content' => $this->lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'colproperties', + 'urlvars' => [ + 'subject' => 'column', + 'action' => 'properties', + 'table' => $_REQUEST['table'], + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + 'privileges' => [ + 'content' => $this->lang['strprivileges'], + 'attr' => [ + 'href' => [ + 'url' => 'privileges', + 'urlvars' => [ + 'subject' => 'column', + 'table' => $_REQUEST['table'], + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + 'drop' => [ + 'content' => $this->lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties', + 'urlvars' => [ + 'subject' => 'column', + 'action' => 'confirm_drop', + 'table' => $_REQUEST['table'], + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + ]; + + echo $this->printTable($attrs, $columns, $actions, 'tblproperties-tblproperties', $this->lang['strnodata'], $attPre); + } } diff --git a/src/database/databasetraits/DatabaseTrait.php b/src/database/databasetraits/DatabaseTrait.php index ece84844..45029e83 100644 --- a/src/database/databasetraits/DatabaseTrait.php +++ b/src/database/databasetraits/DatabaseTrait.php @@ -117,7 +117,7 @@ trait DatabaseTrait if (isset($server_info['hiddendbs']) && $server_info['hiddendbs']) { $hiddendbs = $server_info['hiddendbs']; - $not_in = "('" . implode("','", $hiddendbs) . "')"; + $not_in = "('".implode("','", $hiddendbs)."')"; $clause .= " AND pdb.datname NOT IN {$not_in} "; } diff --git a/src/database/databasetraits/TableTrait.php b/src/database/databasetraits/TableTrait.php index c364516a..759e9e4c 100644 --- a/src/database/databasetraits/TableTrait.php +++ b/src/database/databasetraits/TableTrait.php @@ -163,22 +163,114 @@ trait TableTrait } // Output a reconnect command to create the table as the correct user - $sql = $this->getChangeUserSQL($t->fields['relowner']) . "\n\n"; + $sql = $this->getChangeUserSQL($t->fields['relowner'])."\n\n"; - // Set schema search path - $sql .= "SET search_path = \"{$t->fields['nspname']}\", pg_catalog;\n\n"; - - // Begin CREATE TABLE definition - $sql .= "-- Definition\n\n"; - // DROP TABLE must be fully qualified in case a table with the same name exists - $sql .= $cleanprefix . 'DROP TABLE '; - $sql .= "\"{$t->fields['nspname']}\".\"{$t->fields['relname']}\";\n"; - $sql .= "CREATE TABLE \"{$t->fields['nspname']}\".\"{$t->fields['relname']}\" (\n"; + $sql = $this->_dumpCreate($t, $sql, $cleanprefix); // Output all table columns $col_comments_sql = ''; // Accumulate comments on columns $num = $atts->RecordCount() + $cons->RecordCount(); $i = 1; + + $sql = $this->_dumpSerials($atts, $sql, $col_comments_sql, $num); + + $consOutput = $this->_dumpConstraints($cons, $sql, $num); + + if ($consOutput === null) { + return null; + } + $sql = $consOutput; + + $sql .= ')'; + + // @@@@ DUMP CLUSTERING INFORMATION + + // Inherits + /** + * XXX: This is currently commented out as handling inheritance isn't this simple. + * You also need to make sure you don't dump inherited columns and defaults, as well + * as inherited NOT NULL and CHECK constraints. So for the time being, we just do + * not claim to support inheritance. + * $parents = $this->getTableParents($table); + * if ($parents->RecordCount() > 0) { + * $sql .= " INHERITS ("; + * while (!$parents->EOF) { + * $this->fieldClean($parents->fields['relname']); + * // Qualify the parent table if it's in another schema + * if ($parents->fields['schemaname'] != $this->_schema) { + * $this->fieldClean($parents->fields['schemaname']); + * $sql .= "\"{$parents->fields['schemaname']}\"."; + * } + * $sql .= "\"{$parents->fields['relname']}\"";. + * + * $parents->moveNext(); + * if (!$parents->EOF) $sql .= ', '; + * } + * $sql .= ")"; + * } + */ + + // Handle WITHOUT OIDS + if ($this->hasObjectID($table)) { + $sql .= ' WITH OIDS'; + } else { + $sql .= ' WITHOUT OIDS'; + } + + $sql .= ";\n"; + + $colStorage = $this->_dumpColStats($atts, $sql); + + if ($colStorage === null) { + return null; + } + $sql = $colStorage; + + // Comment + if ($t->fields['relcomment'] !== null) { + $this->clean($t->fields['relcomment']); + $sql .= "\n-- Comment\n\n"; + $sql .= "COMMENT ON TABLE \"{$t->fields['nspname']}\".\"{$t->fields['relname']}\" IS '{$t->fields['relcomment']}';\n"; + } + + // Add comments on columns, if any + if ($col_comments_sql != '') { + $sql .= $col_comments_sql; + } + + // Privileges + $privs = $this->getPrivileges($table, 'table'); + if (!is_array($privs)) { + $this->rollbackTransaction(); + + return null; + } + + $privsOutput = $this->_dumpPrivileges($privs, $sql); + + if ($privsOutput === null) { + return null; + } + $sql .= $privsOutput; + + // Add a newline to separate data that follows (if any) + $sql .= "\n"; + + return $sql; + } + + /** + * Dumps serial-like columns in the table. + * + * @param \PHPPgAdmin\ADORecordSet $atts table attributes + * @param string $sql The sql sentence generated so far + * @param string $col_comments_sql Column comments, passed by reference + * @param int $num Table attributes count + table constraints count + * + * @return string original $sql plus appended strings + */ + private function _dumpSerials($atts, $sql, &$col_comments_sql, $num) + { while (!$atts->EOF) { $this->fieldClean($atts->fields['attname']); $sql .= " \"{$atts->fields['attname']}\""; @@ -191,7 +283,7 @@ trait TableTrait $sql .= ' BIGSERIAL'; } } else { - $sql .= ' ' . $this->formatType($atts->fields['type'], $atts->fields['atttypmod']); + $sql .= ' '.$this->formatType($atts->fields['type'], $atts->fields['atttypmod']); // Add NOT NULL if necessary if ($this->phpBool($atts->fields['attnotnull'])) { @@ -220,6 +312,21 @@ trait TableTrait $atts->moveNext(); ++$i; } + + return $sql; + } + + /** + * Dumps constraints. + * + * @param \PHPPgAdmin\ADORecordSet $cons The table constraints + * @param string $sql The sql sentence generated so far + * @param int $num Table attributes count + table constraints count + * + * @return string original $sql plus appended strings + */ + private function _dumpConstraints($cons, $sql, $num) + { // Output all table constraints while (!$cons->EOF) { $this->fieldClean($cons->fields['conname']); @@ -231,12 +338,12 @@ trait TableTrait switch ($cons->fields['contype']) { case 'p': $keys = $this->getAttributeNames($table, explode(' ', $cons->fields['indkey'])); - $sql .= 'PRIMARY KEY (' . join(',', $keys) . ')'; + $sql .= 'PRIMARY KEY ('.join(',', $keys).')'; break; case 'u': $keys = $this->getAttributeNames($table, explode(' ', $cons->fields['indkey'])); - $sql .= 'UNIQUE (' . join(',', $keys) . ')'; + $sql .= 'UNIQUE ('.join(',', $keys).')'; break; default: @@ -258,44 +365,19 @@ trait TableTrait ++$i; } - $sql .= ')'; - - // @@@@ DUMP CLUSTERING INFORMATION - - // Inherits - /** - * XXX: This is currently commented out as handling inheritance isn't this simple. - * You also need to make sure you don't dump inherited columns and defaults, as well - * as inherited NOT NULL and CHECK constraints. So for the time being, we just do - * not claim to support inheritance. - * $parents = $this->getTableParents($table); - * if ($parents->RecordCount() > 0) { - * $sql .= " INHERITS ("; - * while (!$parents->EOF) { - * $this->fieldClean($parents->fields['relname']); - * // Qualify the parent table if it's in another schema - * if ($parents->fields['schemaname'] != $this->_schema) { - * $this->fieldClean($parents->fields['schemaname']); - * $sql .= "\"{$parents->fields['schemaname']}\"."; - * } - * $sql .= "\"{$parents->fields['relname']}\"";. - * - * $parents->moveNext(); - * if (!$parents->EOF) $sql .= ', '; - * } - * $sql .= ")"; - * } - */ - - // Handle WITHOUT OIDS - if ($this->hasObjectID($table)) { - $sql .= ' WITH OIDS'; - } else { - $sql .= ' WITHOUT OIDS'; - } - - $sql .= ";\n"; + return $sql; + } + /** + * Dumps col statistics. + * + * @param \PHPPgAdmin\ADORecordSet $atts table attributes + * @param string $sql The sql sentence generated so far + * + * @return string original $sql plus appended strings + */ + private function _dumpColStats($atts, $sql) + { // Column storage and statistics $atts->moveFirst(); $first = true; @@ -340,126 +422,142 @@ trait TableTrait $atts->moveNext(); } - // Comment - if ($t->fields['relcomment'] !== null) { - $this->clean($t->fields['relcomment']); - $sql .= "\n-- Comment\n\n"; - $sql .= "COMMENT ON TABLE \"{$t->fields['nspname']}\".\"{$t->fields['relname']}\" IS '{$t->fields['relcomment']}';\n"; - } - - // Add comments on columns, if any - if ($col_comments_sql != '') { - $sql .= $col_comments_sql; - } - - // Privileges - $privs = $this->getPrivileges($table, 'table'); - if (!is_array($privs)) { - $this->rollbackTransaction(); + return $sql; + } - return null; - } + /** + * Dumps privileges. + * + * @param \PHPPgAdmin\ADORecordSet $privs The table privileges + * @param string $sql The sql sentence generated so far + * + * @return string original $sql plus appended strings + */ + private function _dumpPrivileges($privs, $sql) + { + if (sizeof($privs) <= 0) { + return $sql; + } + $sql .= "\n-- Privileges\n\n"; + /* + * Always start with REVOKE ALL FROM PUBLIC, so that we don't have to + * wire-in knowledge about the default public privileges for different + * kinds of objects. + */ + $sql .= "REVOKE ALL ON TABLE \"{$t->fields['nspname']}\".\"{$t->fields['relname']}\" FROM PUBLIC;\n"; + foreach ($privs as $v) { + // Get non-GRANT OPTION privs + $nongrant = array_diff($v[2], $v[4]); - if (sizeof($privs) > 0) { - $sql .= "\n-- Privileges\n\n"; - /* - * Always start with REVOKE ALL FROM PUBLIC, so that we don't have to - * wire-in knowledge about the default public privileges for different - * kinds of objects. - */ - $sql .= "REVOKE ALL ON TABLE \"{$t->fields['nspname']}\".\"{$t->fields['relname']}\" FROM PUBLIC;\n"; - foreach ($privs as $v) { - // Get non-GRANT OPTION privs - $nongrant = array_diff($v[2], $v[4]); - - // Skip empty or owner ACEs - if (sizeof($v[2]) == 0 || ($v[0] == 'user' && $v[1] == $t->fields['relowner'])) { - continue; - } + // Skip empty or owner ACEs + if (sizeof($v[2]) == 0 || ($v[0] == 'user' && $v[1] == $t->fields['relowner'])) { + continue; + } - // Change user if necessary - if ($this->hasGrantOption() && $v[3] != $t->fields['relowner']) { - $grantor = $v[3]; - $this->clean($grantor); - $sql .= "SET SESSION AUTHORIZATION '{$grantor}';\n"; - } + // Change user if necessary + if ($this->hasGrantOption() && $v[3] != $t->fields['relowner']) { + $grantor = $v[3]; + $this->clean($grantor); + $sql .= "SET SESSION AUTHORIZATION '{$grantor}';\n"; + } - // Output privileges with no GRANT OPTION - $sql .= 'GRANT ' . join(', ', $nongrant) . " ON TABLE \"{$t->fields['relname']}\" TO "; - switch ($v[0]) { - case 'public': - $sql .= "PUBLIC;\n"; + // Output privileges with no GRANT OPTION + $sql .= 'GRANT '.join(', ', $nongrant)." ON TABLE \"{$t->fields['relname']}\" TO "; + switch ($v[0]) { + case 'public': + $sql .= "PUBLIC;\n"; - break; - case 'user': - case 'role': - $this->fieldClean($v[1]); - $sql .= "\"{$v[1]}\";\n"; + break; + case 'user': + case 'role': + $this->fieldClean($v[1]); + $sql .= "\"{$v[1]}\";\n"; - break; - case 'group': - $this->fieldClean($v[1]); - $sql .= "GROUP \"{$v[1]}\";\n"; + break; + case 'group': + $this->fieldClean($v[1]); + $sql .= "GROUP \"{$v[1]}\";\n"; - break; - default: - // Unknown privilege type - fail - $this->rollbackTransaction(); + break; + default: + // Unknown privilege type - fail + $this->rollbackTransaction(); - return null; - } + return null; + } - // Reset user if necessary - if ($this->hasGrantOption() && $v[3] != $t->fields['relowner']) { - $sql .= "RESET SESSION AUTHORIZATION;\n"; - } + // Reset user if necessary + if ($this->hasGrantOption() && $v[3] != $t->fields['relowner']) { + $sql .= "RESET SESSION AUTHORIZATION;\n"; + } - // Output privileges with GRANT OPTION + // Output privileges with GRANT OPTION - // Skip empty or owner ACEs - if (!$this->hasGrantOption() || sizeof($v[4]) == 0) { - continue; - } + // Skip empty or owner ACEs + if (!$this->hasGrantOption() || sizeof($v[4]) == 0) { + continue; + } - // Change user if necessary - if ($this->hasGrantOption() && $v[3] != $t->fields['relowner']) { - $grantor = $v[3]; - $this->clean($grantor); - $sql .= "SET SESSION AUTHORIZATION '{$grantor}';\n"; - } + // Change user if necessary + if ($this->hasGrantOption() && $v[3] != $t->fields['relowner']) { + $grantor = $v[3]; + $this->clean($grantor); + $sql .= "SET SESSION AUTHORIZATION '{$grantor}';\n"; + } - $sql .= 'GRANT ' . join(', ', $v[4]) . " ON \"{$t->fields['relname']}\" TO "; - switch ($v[0]) { - case 'public': - $sql .= 'PUBLIC'; + $sql .= 'GRANT '.join(', ', $v[4])." ON \"{$t->fields['relname']}\" TO "; + switch ($v[0]) { + case 'public': + $sql .= 'PUBLIC'; - break; - case 'user': - case 'role': - $this->fieldClean($v[1]); - $sql .= "\"{$v[1]}\""; + break; + case 'user': + case 'role': + $this->fieldClean($v[1]); + $sql .= "\"{$v[1]}\""; - break; - case 'group': - $this->fieldClean($v[1]); - $sql .= "GROUP \"{$v[1]}\""; + break; + case 'group': + $this->fieldClean($v[1]); + $sql .= "GROUP \"{$v[1]}\""; - break; - default: - // Unknown privilege type - fail - return null; - } - $sql .= " WITH GRANT OPTION;\n"; + break; + default: + // Unknown privilege type - fail + return null; + } + $sql .= " WITH GRANT OPTION;\n"; - // Reset user if necessary - if ($this->hasGrantOption() && $v[3] != $t->fields['relowner']) { - $sql .= "RESET SESSION AUTHORIZATION;\n"; - } + // Reset user if necessary + if ($this->hasGrantOption() && $v[3] != $t->fields['relowner']) { + $sql .= "RESET SESSION AUTHORIZATION;\n"; } } - // Add a newline to separate data that follows (if any) - $sql .= "\n"; + return $sql; + } + + /** + * Dumps a create. + * + * @param \PHPPgAdmin\ADORecordSet $tblfields table fields object + * @param string $sql The sql sentence generated so far + * @param string $cleanprefix set to '-- ' to avoid issuing DROP statement + * @param mixed $fields + * + * @return string original $sql plus appended strings + */ + private function _dumpCreate($fields, $sql, $cleanprefix) + { + // Set schema search path + $sql .= "SET search_path = \"{$tblfields->fields['nspname']}\", pg_catalog;\n\n"; + + // Begin CREATE TABLE definition + $sql .= "-- Definition\n\n"; + // DROP TABLE must be fully qualified in case a table with the same name exists + $sql .= $cleanprefix.'DROP TABLE '; + $sql .= "\"{$tblfields->fields['nspname']}\".\"{$tblfields->fields['relname']}\";\n"; + $sql .= "CREATE TABLE \"{$tblfields->fields['nspname']}\".\"{$tblfields->fields['relname']}\" (\n"; return $sql; } @@ -481,7 +579,7 @@ trait TableTrait SELECT c.relname, n.nspname, '; - $sql .= ($this->hasRoles() ? ' coalesce(u.usename,r.rolname) ' : ' u.usename') . " AS relowner, + $sql .= ($this->hasRoles() ? ' coalesce(u.usename,r.rolname) ' : ' u.usename')." AS relowner, pg_catalog.obj_description(c.oid, 'pg_class') AS relcomment, pt.spcname AS tablespace FROM pg_catalog.pg_class c @@ -489,7 +587,7 @@ trait TableTrait LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner 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 ' : '') . + $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 @@ -704,7 +802,7 @@ trait TableTrait if ($indexes->RecordCount() > 0) { $sql .= "\n-- Indexes\n\n"; while (!$indexes->EOF) { - $sql .= $indexes->fields['inddef'] . ";\n"; + $sql .= $indexes->fields['inddef'].";\n"; $indexes->moveNext(); } @@ -739,7 +837,7 @@ trait TableTrait if ($rules->RecordCount() > 0) { $sql .= "\n-- Rules\n\n"; while (!$rules->EOF) { - $sql .= $rules->fields['definition'] . "\n"; + $sql .= $rules->fields['definition']."\n"; $rules->moveNext(); } @@ -967,7 +1065,7 @@ trait TableTrait } } if (count($primarykeycolumns) > 0) { - $sql .= ', PRIMARY KEY (' . implode(', ', $primarykeycolumns) . ')'; + $sql .= ', PRIMARY KEY ('.implode(', ', $primarykeycolumns).')'; } $sql .= ')'; @@ -1290,7 +1388,7 @@ trait TableTrait $sql = "TRUNCATE TABLE \"{$f_schema}\".\"{$table}\" "; if ($cascade) { - $sql = $sql . ' CASCADE'; + $sql = $sql.' CASCADE'; } $status = $this->execute($sql); @@ -1390,7 +1488,7 @@ trait TableTrait // Actually retrieve the rows if ($oids) { - $oid_str = $this->id . ', '; + $oid_str = $this->id.', '; } else { $oid_str = ''; } @@ -1531,7 +1629,7 @@ trait TableTrait $params[] = "autovacuum_vacuum_cost_limit='{$vaccostlimit}'"; } - $sql = $sql . implode(',', $params) . ');'; + $sql = $sql.implode(',', $params).');'; return $this->execute($sql); } |