Merge pull request #13986 from mauriciofauth/normalization

Refactor PhpMyAdmin\Normalization class
This commit is contained in:
Maurício Meneghini Fauth 2018-02-10 02:37:58 -02:00 committed by GitHub
commit d61fba6d81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 401 additions and 316 deletions

View File

@ -1,7 +1,7 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* set of functions used for normalization
* Holds the PhpMyAdmin\Normalization class
*
* @package PhpMyAdmin
*/
@ -16,12 +16,29 @@ use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
/**
* PhpMyAdmin\Normalization class
* Set of functions used for normalization
*
* @package PhpMyAdmin
*/
class Normalization
{
/**
* DatabaseInterface instance
*
* @var DatabaseInterface
*/
private $dbi;
/**
* Constructor
*
* @param DatabaseInterface $dbi DatabaseInterface instance
*/
public function __construct(DatabaseInterface $dbi)
{
$this->dbi = $dbi;
}
/**
* build the html for columns of $colTypeCategory category
* in form of given $listType in a table
@ -34,25 +51,30 @@ class Normalization
*
* @return string HTML for list of columns in form of given list types
*/
public static function getHtmlForColumnsList(
$db, $table, $colTypeCategory='all', $listType='dropdown'
public function getHtmlForColumnsList(
$db,
$table,
$colTypeCategory = 'all',
$listType = 'dropdown'
) {
$columnTypeList = array();
$columnTypeList = [];
if ($colTypeCategory != 'all') {
$types = $GLOBALS['dbi']->types->getColumns();
$types = $this->dbi->types->getColumns();
$columnTypeList = $types[$colTypeCategory];
}
$GLOBALS['dbi']->selectDb($db);
$columns = $GLOBALS['dbi']->getColumns(
$db, $table, null,
$this->dbi->selectDb($db);
$columns = $this->dbi->getColumns(
$db,
$table,
null,
true
);
$type = "";
$selectColHtml = "";
foreach ($columns as $column => $def) {
if (isset($def['Type'])) {
$extracted_columnspec = Util::extractColumnSpec($def['Type']);
$type = $extracted_columnspec['type'];
$extractedColumnSpec = Util::extractColumnSpec($def['Type']);
$type = $extractedColumnSpec['type'];
}
if (empty($columnTypeList)
|| in_array(mb_strtoupper($type), $columnTypeList)
@ -76,78 +98,79 @@ class Normalization
/**
* get the html of the form to add the new column to given table
*
* @param integer $num_fields number of columns to add
* @param integer $numFields number of columns to add
* @param string $db current database
* @param string $table current table
* @param array $columnMeta array containing default values for the fields
*
* @return string HTML
*/
public static function getHtmlForCreateNewColumn(
$num_fields, $db, $table, array $columnMeta = array()
public function getHtmlForCreateNewColumn(
$numFields,
$db,
$table,
array $columnMeta = []
) {
$cfgRelation = Relation::getRelationsParam();
$content_cells = array();
$available_mime = array();
$mime_map = array();
$contentCells = [];
$availableMime = [];
$mimeMap = [];
if ($cfgRelation['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
$mime_map = Transformations::getMIME($db, $table);
$available_mime = Transformations::getAvailableMIMEtypes();
$mimeMap = Transformations::getMIME($db, $table);
$availableMime = Transformations::getAvailableMIMEtypes();
}
$comments_map = Relation::getComments($db, $table);
for ($columnNumber = 0; $columnNumber < $num_fields; $columnNumber++) {
$content_cells[$columnNumber] = array(
$commentsMap = Relation::getComments($db, $table);
for ($columnNumber = 0; $columnNumber < $numFields; $columnNumber++) {
$contentCells[$columnNumber] = [
'column_number' => $columnNumber,
'column_meta' => $columnMeta,
'type_upper' => '',
'length_values_input_size' => 8,
'length' => '',
'extracted_columnspec' => array(),
'extracted_columnspec' => [],
'submit_attribute' => null,
'comments_map' => $comments_map,
'comments_map' => $commentsMap,
'fields_meta' => null,
'is_backup' => true,
'move_columns' => array(),
'move_columns' => [],
'cfg_relation' => $cfgRelation,
'available_mime' => isset($available_mime)?$available_mime:array(),
'mime_map' => $mime_map
);
'available_mime' => isset($availableMime) ? $availableMime : [],
'mime_map' => $mimeMap
];
}
return Template::get(
'columns_definitions/table_fields_definitions'
)
->render(
array(
'is_backup' => true,
'fields_meta' => null,
'mimework' => $cfgRelation['mimework'],
'content_cells' => $content_cells,
'change_column' => $_REQUEST['change_column'],
'is_virtual_columns_supported' => Util::isVirtualColumnsSupported(),
'browse_mime' => $GLOBALS['cfg']['BrowseMIME'],
'server_type' => Util::getServerType(),
'max_rows' => intval($GLOBALS['cfg']['MaxRows']),
'char_editing' => $GLOBALS['cfg']['CharEditing'],
'attribute_types' => $GLOBALS['dbi']->types->getAttributes(),
'privs_available' => $GLOBALS['col_priv'] && $GLOBALS['is_reload_priv'],
'max_length' => $GLOBALS['dbi']->getVersion() >= 50503 ? 1024 : 255,
'dbi' => $GLOBALS['dbi'],
'disable_is' => $GLOBALS['cfg']['Server']['DisableIS'],
)
);
)->render([
'is_backup' => true,
'fields_meta' => null,
'mimework' => $cfgRelation['mimework'],
'content_cells' => $contentCells,
'change_column' => $_REQUEST['change_column'],
'is_virtual_columns_supported' => Util::isVirtualColumnsSupported(),
'browse_mime' => $GLOBALS['cfg']['BrowseMIME'],
'server_type' => Util::getServerType(),
'max_rows' => intval($GLOBALS['cfg']['MaxRows']),
'char_editing' => $GLOBALS['cfg']['CharEditing'],
'attribute_types' => $this->dbi->types->getAttributes(),
'privs_available' => $GLOBALS['col_priv'] && $GLOBALS['is_reload_priv'],
'max_length' => $this->dbi->getVersion() >= 50503 ? 1024 : 255,
'dbi' => $this->dbi,
'disable_is' => $GLOBALS['cfg']['Server']['DisableIS'],
]);
}
/**
* build the html for step 1.1 of normalization
*
* @param string $db current database
* @param string $table current table
* @param string $normalizedTo up to which step normalization will go,
* possible values 1nf|2nf|3nf
* possible values 1nf|2nf|3nf
*
* @return string HTML for step 1.1
*/
public static function getHtmlFor1NFStep1($db, $table, $normalizedTo)
public function getHtmlFor1NFStep1($db, $table, $normalizedTo)
{
$step = 1;
$stepTxt = __('Make all columns atomic');
@ -176,7 +199,7 @@ class Normalization
. '<option selected="selected" disabled="disabled">'
. __('Select one…') . "</option>"
. "<option value='no_such_col'>" . __('No such column') . "</option>"
. self::getHtmlForColumnsList(
. $this->getHtmlForColumnsList(
$db,
$table,
_pgettext('string types', 'String')
@ -200,7 +223,7 @@ class Normalization
*
* @return string HTML contents for step 1.2
*/
public static function getHtmlContentsFor1NFStep2($db, $table)
public function getHtmlContentsFor1NFStep2($db, $table)
{
$step = 2;
$stepTxt = __('Have a primary key');
@ -220,7 +243,8 @@ class Normalization
);
$subText = '<a href="#" id="createPrimaryKey">'
. Util::getIcon(
'b_index_add', __(
'b_index_add',
__(
'Add a primary key on existing column(s)'
)
)
@ -232,13 +256,13 @@ class Normalization
. '<a href="#" id="addNewPrimary">'
. __('+ Add a new primary key column') . '</a>';
}
$res = array(
$res = [
'legendText' => $legendText,
'headText' => $headText,
'subText' => $subText,
'hasPrimaryKey' => $hasPrimaryKey,
'extra' => $extra
);
];
return $res;
}
@ -250,7 +274,7 @@ class Normalization
*
* @return string HTML contents for step 1.4
*/
public static function getHtmlContentsFor1NFStep4($db, $table)
public function getHtmlContentsFor1NFStep4($db, $table)
{
$step = 4;
$stepTxt = __('Remove redundant columns');
@ -265,18 +289,18 @@ class Normalization
"Check the columns which are redundant and click on remove. "
. "If no redundant column, click on 'No redundant column'"
);
$extra = self::getHtmlForColumnsList($db, $table, 'all', "checkbox") . "</br>"
$extra = $this->getHtmlForColumnsList($db, $table, 'all', "checkbox") . "</br>"
. '<input type="submit" id="removeRedundant" value="'
. __('Remove selected') . '"/>'
. '<input type="submit" value="' . __('No redundant column')
. '" onclick="goToFinish1NF();"'
. '/>';
$res = array(
$res = [
'legendText' => $legendText,
'headText' => $headText,
'subText' => $subText,
'extra' => $extra
);
];
return $res;
}
@ -288,7 +312,7 @@ class Normalization
*
* @return string HTML contents for step 1.3
*/
public static function getHtmlContentsFor1NFStep3($db, $table)
public function getHtmlContentsFor1NFStep3($db, $table)
{
$step = 3;
$stepTxt = __('Move repeating groups');
@ -305,7 +329,7 @@ class Normalization
"Check the columns which form a repeating group. "
. "If no such group, click on 'No repeating group'"
);
$extra = self::getHtmlForColumnsList($db, $table, 'all', "checkbox") . "</br>"
$extra = $this->getHtmlForColumnsList($db, $table, 'all', "checkbox") . "</br>"
. '<input type="submit" id="moveRepeatingGroup" value="'
. __('Done') . '"/>'
. '<input type="submit" value="' . __('No repeating group')
@ -313,17 +337,17 @@ class Normalization
. '/>';
$primary = Index::getPrimary($table, $db);
$primarycols = $primary->getColumns();
$pk = array();
$pk = [];
foreach ($primarycols as $col) {
$pk[] = $col->getName();
}
$res = array(
$res = [
'legendText' => $legendText,
'headText' => $headText,
'subText' => $subText,
'extra' => $extra,
'primary_key' => json_encode($pk)
);
];
return $res;
}
@ -335,12 +359,12 @@ class Normalization
*
* @return string HTML contents for 2NF step 2.1
*/
public static function getHtmlFor2NFstep1($db, $table)
public function getHtmlFor2NFstep1($db, $table)
{
$legendText = __('Step 2.') . "1 " . __('Find partial dependencies');
$primary = Index::getPrimary($table, $db);
$primarycols = $primary->getColumns();
$pk = array();
$pk = [];
$subText = '';
$selectPkForm = "";
$extra = "";
@ -352,9 +376,10 @@ class Normalization
}
$key = implode(', ', $pk);
if (count($primarycols) > 1) {
$GLOBALS['dbi']->selectDb($db);
$columns = (array) $GLOBALS['dbi']->getColumnNames(
$db, $table
$this->dbi->selectDb($db);
$columns = (array) $this->dbi->getColumnNames(
$db,
$table
);
if (count($pk) == count($columns)) {
$headText = sprintf(
@ -362,7 +387,8 @@ class Normalization
'No partial dependencies possible as '
. 'no non-primary column exists since primary key ( %1$s ) '
. 'is composed of all the columns in the table.'
), htmlspecialchars($key)
),
htmlspecialchars($key)
) . '<br/>';
$extra = '<h3>' . __('Table is already in second normal form.')
. '</h3>';
@ -371,7 +397,8 @@ class Normalization
__(
'The primary key ( %1$s ) consists of more than one column '
. 'so we need to find the partial dependencies.'
), htmlspecialchars($key)
),
htmlspecialchars($key)
) . '<br/>' . __(
'Please answer the following question(s) '
. 'carefully to obtain a correct normalization.'
@ -391,7 +418,8 @@ class Normalization
if (!in_array($column, $pk)) {
$cnt++;
$extra .= "<b>" . sprintf(
__('\'%1$s\' depends on:'), htmlspecialchars($column)
__('\'%1$s\' depends on:'),
htmlspecialchars($column)
) . "</b><br>";
$extra .= '<form id="pk_' . $cnt . '" data-colname="'
. htmlspecialchars($column) . '" class="smallIndent">'
@ -404,17 +432,18 @@ class Normalization
__(
'No partial dependencies possible as the primary key'
. ' ( %1$s ) has just one column.'
), htmlspecialchars($key)
),
htmlspecialchars($key)
) . '<br/>';
$extra = '<h3>' . __('Table is already in second normal form.') . '</h3>';
}
$res = array(
$res = [
'legendText' => $legendText,
'headText' => $headText,
'subText' => $subText,
'extra' => $extra,
'primary_key' => $key
);
];
return $res;
}
@ -426,22 +455,23 @@ class Normalization
*
* @return string HTML
*/
public static function getHtmlForNewTables2NF(array $partialDependencies, $table)
public function getHtmlForNewTables2NF(array $partialDependencies, $table)
{
$html = '<p><b>' . sprintf(
__(
'In order to put the '
. 'original table \'%1$s\' into Second normal form we need '
. 'to create the following tables:'
), htmlspecialchars($table)
),
htmlspecialchars($table)
) . '</b></p>';
$tableName = $table;
$i = 1;
foreach ($partialDependencies as $key=>$dependents) {
foreach ($partialDependencies as $key => $dependents) {
$html .= '<p><input type="text" name="' . htmlspecialchars($key)
. '" value="' . htmlspecialchars($tableName) . '"/>'
. '( <u>' . htmlspecialchars($key) . '</u>'
. (count($dependents)>0?', ':'')
. (count($dependents)>0?', ':'')
. htmlspecialchars(implode(', ', $dependents)) . ' )';
$i++;
$tableName = 'table' . $i;
@ -459,25 +489,25 @@ class Normalization
*
* @return array
*/
public static function createNewTablesFor2NF(array $partialDependencies, $tablesName, $table, $db)
public function createNewTablesFor2NF(array $partialDependencies, $tablesName, $table, $db)
{
$dropCols = false;
$nonPKCols = array();
$queries = array();
$nonPKCols = [];
$queries = [];
$error = false;
$headText = '<h3>' . sprintf(
__('The second step of normalization is complete for table \'%1$s\'.'),
htmlspecialchars($table)
) . '</h3>';
if (count((array)$partialDependencies) == 1) {
return array(
return [
'legendText'=>__('End of step'), 'headText'=>$headText,
'queryError'=>$error
);
];
}
$message = '';
$GLOBALS['dbi']->selectDb($db);
foreach ($partialDependencies as $key=>$dependents) {
$this->dbi->selectDb($db);
foreach ($partialDependencies as $key => $dependents) {
if ($tablesName->$key != $table) {
$backquotedKey = implode(', ', Util::backquote(explode(', ', $key)));
$queries[] = 'CREATE TABLE ' . Util::backquote($tablesName->$key)
@ -505,11 +535,11 @@ class Normalization
$queries[] = 'DROP TABLE ' . Util::backquote($table);
}
foreach ($queries as $query) {
if (!$GLOBALS['dbi']->tryQuery($query)) {
if (!$this->dbi->tryQuery($query)) {
$message = Message::error(__('Error in processing!'));
$message->addMessage(
Message::rawError(
$GLOBALS['dbi']->getError()
$this->dbi->getError()
),
'<br /><br />'
);
@ -517,12 +547,12 @@ class Normalization
break;
}
}
return array(
return [
'legendText' => __('End of step'),
'headText' => $headText,
'queryError' => $error,
'extra' => $message
);
];
}
/**
@ -535,18 +565,18 @@ class Normalization
*
* @return array containing html and the list of new tables
*/
public static function getHtmlForNewTables3NF($dependencies, array $tables, $db)
public function getHtmlForNewTables3NF($dependencies, array $tables, $db)
{
$html = "";
$i = 1;
$newTables = array();
foreach ($tables as $table=>$arrDependson) {
$newTables = [];
foreach ($tables as $table => $arrDependson) {
if (count(array_unique($arrDependson)) == 1) {
continue;
}
$primary = Index::getPrimary($table, $db);
$primarycols = $primary->getColumns();
$pk = array();
$pk = [];
foreach ($primarycols as $col) {
$pk[] = $col->getName();
}
@ -555,10 +585,11 @@ class Normalization
'In order to put the '
. 'original table \'%1$s\' into Third normal form we need '
. 'to create the following tables:'
), htmlspecialchars($table)
),
htmlspecialchars($table)
) . '</b></p>';
$tableName = $table;
$columnList = array();
$columnList = [];
foreach ($arrDependson as $key) {
$dependents = $dependencies->$key;
if ($key == $table) {
@ -572,17 +603,17 @@ class Normalization
. htmlspecialchars($tableName)
. '" value="' . htmlspecialchars($tableName) . '"/>'
. '( <u>' . htmlspecialchars($key) . '</u>'
. (count($dependents)>0?', ':'')
. (count($dependents)>0?', ':'')
. htmlspecialchars(implode(', ', $dependents)) . ' )';
$newTables[$table][$tableName] = array(
$newTables[$table][$tableName] = [
"pk"=>$key, "nonpk"=>implode(', ', $dependents)
);
];
$i++;
$tableName = 'table' . $i;
}
}
}
return array('html' => $html, 'newTables' => $newTables, 'success' => true);
return ['html' => $html, 'newTables' => $newTables, 'success' => true];
}
/**
@ -593,30 +624,32 @@ class Normalization
*
* @return array
*/
public static function createNewTablesFor3NF(array $newTables, $db)
public function createNewTablesFor3NF(array $newTables, $db)
{
$queries = array();
$queries = [];
$dropCols = false;
$error = false;
$headText = '<h3>' .
__('The third step of normalization is complete.')
. '</h3>';
if (count((array)$newTables) == 0) {
return array(
return [
'legendText'=>__('End of step'), 'headText'=>$headText,
'queryError'=>$error
);
];
}
$message = '';
$GLOBALS['dbi']->selectDb($db);
foreach ($newTables as $originalTable=>$tablesList) {
foreach ($tablesList as $table=>$cols) {
$this->dbi->selectDb($db);
foreach ($newTables as $originalTable => $tablesList) {
foreach ($tablesList as $table => $cols) {
if ($table != $originalTable) {
$quotedPk = implode(
', ', Util::backquote(explode(', ', $cols->pk))
', ',
Util::backquote(explode(', ', $cols->pk))
);
$quotedNonpk = implode(
', ', Util::backquote(explode(', ', $cols->nonpk))
', ',
Util::backquote(explode(', ', $cols->nonpk))
);
$queries[] = 'CREATE TABLE ' . Util::backquote($table)
. ' SELECT DISTINCT ' . $quotedPk
@ -629,11 +662,13 @@ class Normalization
}
}
if ($dropCols) {
$columns = (array) $GLOBALS['dbi']->getColumnNames(
$db, $originalTable
$columns = (array) $this->dbi->getColumnNames(
$db,
$originalTable
);
$colPresent = array_merge(
explode(', ', $dropCols->pk), explode(', ', $dropCols->nonpk)
explode(', ', $dropCols->pk),
explode(', ', $dropCols->nonpk)
);
$query = 'ALTER TABLE ' . Util::backquote($originalTable);
foreach ($columns as $col) {
@ -650,11 +685,11 @@ class Normalization
$dropCols = false;
}
foreach ($queries as $query) {
if (!$GLOBALS['dbi']->tryQuery($query)) {
if (!$this->dbi->tryQuery($query)) {
$message = Message::error(__('Error in processing!'));
$message->addMessage(
Message::rawError(
$GLOBALS['dbi']->getError()
$this->dbi->getError()
),
'<br /><br />'
);
@ -662,20 +697,20 @@ class Normalization
break;
}
}
return array(
return [
'legendText' => __('End of step'),
'headText' => $headText,
'queryError' => $error,
'extra' => $message
);
];
}
/**
* move the repeating group of columns to a new table
*
* @param string $repeatingColumns comma separated list of repeating group columns
* @param string $primary_columns comma separated list of column in primary key
* of $table
* @param string $primaryColumns comma separated list of column in primary key
* of $table
* @param string $newTable name of the new table to be created
* @param string $newColumn name of the new column in the new table
* @param string $table current table
@ -683,14 +718,20 @@ class Normalization
*
* @return array
*/
public static function moveRepeatingGroup(
$repeatingColumns, $primary_columns, $newTable, $newColumn, $table, $db
public function moveRepeatingGroup(
$repeatingColumns,
$primaryColumns,
$newTable,
$newColumn,
$table,
$db
) {
$repeatingColumnsArr = (array)Util::backquote(
explode(', ', $repeatingColumns)
);
$primary_columns = implode(
',', Util::backquote(explode(',', $primary_columns))
$primaryColumns = implode(
',',
Util::backquote(explode(',', $primaryColumns))
);
$query1 = 'CREATE TABLE ' . Util::backquote($newTable);
$query2 = 'ALTER TABLE ' . Util::backquote($table);
@ -707,20 +748,20 @@ class Normalization
$query1 .= ' UNION ';
}
$first = false;
$query1 .= ' SELECT ' . $primary_columns . ',' . $repeatingColumn
$query1 .= ' SELECT ' . $primaryColumns . ',' . $repeatingColumn
. ' as ' . Util::backquote($newColumn)
. ' FROM ' . Util::backquote($table);
$query2 .= ' DROP ' . $repeatingColumn . ',';
}
$query2 = trim($query2, ',');
$queries = array($query1, $query2);
$GLOBALS['dbi']->selectDb($db);
$queries = [$query1, $query2];
$this->dbi->selectDb($db);
foreach ($queries as $query) {
if (!$GLOBALS['dbi']->tryQuery($query)) {
if (!$this->dbi->tryQuery($query)) {
$message = Message::error(__('Error in processing!'));
$message->addMessage(
Message::rawError(
$GLOBALS['dbi']->getError()
$this->dbi->getError()
),
'<br /><br />'
);
@ -728,9 +769,9 @@ class Normalization
break;
}
}
return array(
return [
'queryError' => $error, 'message' => $message
);
];
}
/**
@ -741,7 +782,7 @@ class Normalization
*
* @return string
*/
public static function getHtmlFor3NFstep1($db, array $tables)
public function getHtmlFor3NFstep1($db, array $tables)
{
$legendText = __('Step 3.') . "1 " . __('Find transitive dependencies');
$extra = "";
@ -762,13 +803,14 @@ class Normalization
$primary = Index::getPrimary($table, $db);
$primarycols = $primary->getColumns();
$selectTdForm = "";
$pk = array();
$pk = [];
foreach ($primarycols as $col) {
$pk[] = $col->getName();
}
$GLOBALS['dbi']->selectDb($db);
$columns = (array) $GLOBALS['dbi']->getColumnNames(
$db, $table
$this->dbi->selectDb($db);
$columns = (array) $this->dbi->getColumnNames(
$db,
$table
);
if (count($columns) - count($pk) <= 1) {
continue;
@ -784,7 +826,8 @@ class Normalization
if (!in_array($column, $pk)) {
$cnt++;
$extra .= "<b>" . sprintf(
__('\'%1$s\' depends on:'), htmlspecialchars($column)
__('\'%1$s\' depends on:'),
htmlspecialchars($column)
)
. "</b><br>";
$extra .= '<form id="td_' . $cnt . '" data-colname="'
@ -803,12 +846,12 @@ class Normalization
$subText = "";
$extra = "<h3>" . __("Table is already in Third normal form!") . "</h3>";
}
$res = array(
$res = [
'legendText' => $legendText,
'headText' => $headText,
'subText' => $subText,
'extra' => $extra
);
];
return $res;
}
@ -817,28 +860,31 @@ class Normalization
*
* @return string HTML
*/
public static function getHtmlForNormalizetable()
public function getHtmlForNormalizeTable()
{
$html_output = '<form method="post" action="normalization.php" '
$htmlOutput = '<form method="post" action="normalization.php" '
. 'name="normalize" '
. 'id="normalizeTable" '
. '>'
. Url::getHiddenInputs($GLOBALS['db'], $GLOBALS['table'])
. '<input type="hidden" name="step1" value="1">';
$html_output .= '<fieldset>';
$html_output .= '<legend>'
$htmlOutput .= '<fieldset>';
$htmlOutput .= '<legend>'
. __('Improve table structure (Normalization):') . '</legend>';
$html_output .= '<h3>' . __('Select up to what step you want to normalize')
$htmlOutput .= '<h3>' . __('Select up to what step you want to normalize')
. '</h3>';
$choices = array(
$choices = [
'1nf' => __('First step of normalization (1NF)'),
'2nf' => __('Second step of normalization (1NF+2NF)'),
'3nf' => __('Third step of normalization (1NF+2NF+3NF)'));
'3nf' => __('Third step of normalization (1NF+2NF+3NF)')];
$html_output .= Util::getRadioFields(
'normalizeTo', $choices, '1nf', true
$htmlOutput .= Util::getRadioFields(
'normalizeTo',
$choices,
'1nf',
true
);
$html_output .= '</fieldset><fieldset class="tblFooters">'
$htmlOutput .= '</fieldset><fieldset class="tblFooters">'
. "<span class='floatleft'>" . __(
'Hint: Please follow the procedure carefully in order '
. 'to obtain correct normalization'
@ -848,7 +894,7 @@ class Normalization
. '</form>'
. '</div>';
return $html_output;
return $htmlOutput;
}
/**
@ -859,39 +905,44 @@ class Normalization
*
* @return string HTML containing the list of all the possible partial dependencies
*/
public static function findPartialDependencies($table, $db)
public function findPartialDependencies($table, $db)
{
$dependencyList = array();
$GLOBALS['dbi']->selectDb($db);
$columns = (array) $GLOBALS['dbi']->getColumnNames(
$db, $table
$dependencyList = [];
$this->dbi->selectDb($db);
$columns = (array) $this->dbi->getColumnNames(
$db,
$table
);
$columns = (array)Util::backquote($columns);
$totalRowsRes = $GLOBALS['dbi']->fetchResult(
$totalRowsRes = $this->dbi->fetchResult(
'SELECT COUNT(*) FROM (SELECT * FROM '
. Util::backquote($table) . ' LIMIT 500) as dt;'
);
$totalRows = $totalRowsRes[0];
$primary = Index::getPrimary($table, $db);
$primarycols = $primary->getColumns();
$pk = array();
$pk = [];
foreach ($primarycols as $col) {
$pk[] = Util::backquote($col->getName());
}
$partialKeys = self::getAllCombinationPartialKeys($pk);
$distinctValCount = self::findDistinctValuesCount(
$partialKeys = $this->getAllCombinationPartialKeys($pk);
$distinctValCount = $this->findDistinctValuesCount(
array_unique(
array_merge($columns, $partialKeys)
), $table
),
$table
);
foreach ($columns as $column) {
if (!in_array($column, $pk)) {
foreach ($partialKeys as $partialKey) {
if ($partialKey
&& self::checkPartialDependency(
$partialKey, $column, $table,
&& $this->checkPartialDependency(
$partialKey,
$column,
$table,
$distinctValCount[$partialKey],
$distinctValCount[$column], $totalRows
$distinctValCount[$column],
$totalRows
)
) {
$dependencyList[$partialKey][] = $column;
@ -905,7 +956,7 @@ class Normalization
. 'and is not necessarily accurate. '
)
. '<div class="dependencies_box">';
foreach ($dependencyList as $dependon=>$colList) {
foreach ($dependencyList as $dependon => $colList) {
$html .= '<span class="displayblock">'
. '<input type="button" class="pickPd" value="' . __('Pick') . '"/>'
. '<span class="determinants">'
@ -927,7 +978,7 @@ class Normalization
* check whether a particular column is dependent on given subset of primary key
*
* @param string $partialKey the partial key, subset of primary key,
* each column in key supposed to be backquoted
* each column in key supposed to be backquoted
* @param string $column backquoted column on whose dependency being checked
* @param string $table current table
* @param integer $pkCnt distinct value count for given partial key
@ -936,14 +987,19 @@ class Normalization
*
* @return boolean TRUE if $column is dependent on $partialKey, False otherwise
*/
public static function checkPartialDependency(
$partialKey, $column, $table, $pkCnt, $colCnt, $totalRows
private function checkPartialDependency(
$partialKey,
$column,
$table,
$pkCnt,
$colCnt,
$totalRows
) {
$query = 'SELECT '
. 'COUNT(DISTINCT ' . $partialKey . ',' . $column . ') as pkColCnt '
. 'FROM (SELECT * FROM ' . Util::backquote($table)
. ' LIMIT 500) as dt' . ';';
$res = $GLOBALS['dbi']->fetchResult($query, null, null);
. ' LIMIT 500) as dt' . ';';
$res = $this->dbi->fetchResult($query, null, null);
$pkColCnt = $res[0];
if ($pkCnt && $pkCnt == $colCnt && $colCnt == $pkColCnt) {
return true;
@ -958,25 +1014,25 @@ class Normalization
* function to get distinct values count of all the column in the array $columns
*
* @param array $columns array of backquoted columns whose distinct values
* need to be counted.
* need to be counted.
* @param string $table table to which these columns belong
*
* @return array associative array containing the count
*/
public static function findDistinctValuesCount(array $columns, $table)
private function findDistinctValuesCount(array $columns, $table)
{
$result = array();
$result = [];
$query = 'SELECT ';
foreach ($columns as $column) {
if ($column) { //each column is already backquoted
$query .= 'COUNT(DISTINCT ' . $column . ') as \''
$query .= 'COUNT(DISTINCT ' . $column . ') as \''
. $column . '_cnt\', ';
}
}
$query = trim($query, ', ');
$query .= ' FROM (SELECT * FROM ' . Util::backquote($table)
. ' LIMIT 500) as dt' . ';';
$res = $GLOBALS['dbi']->fetchResult($query, null, null);
$res = $this->dbi->fetchResult($query, null, null);
foreach ($columns as $column) {
if ($column) {
$result[$column] = $res[0][$column . '_cnt'];
@ -992,13 +1048,14 @@ class Normalization
*
* @return array containing all the possible partial keys(subset of primary key)
*/
public static function getAllCombinationPartialKeys(array $primaryKey)
private function getAllCombinationPartialKeys(array $primaryKey)
{
$results = array('');
$results = [''];
foreach ($primaryKey as $element) {
foreach ($results as $combination) {
array_push(
$results, trim($element . ',' . $combination, ',')
$results,
trim($element . ',' . $combination, ',')
);
}
}

View File

@ -11,16 +11,15 @@ use PhpMyAdmin\Normalization;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
/**
*
*/
require_once 'libraries/common.inc.php';
$normalization = new Normalization($GLOBALS['dbi']);
if (isset($_REQUEST['getColumns'])) {
$html = '<option selected disabled>' . __('Select one…') . '</option>'
. '<option value="no_such_col">' . __('No such column') . '</option>';
//get column whose datatype falls under string category
$html .= Normalization::getHtmlForColumnsList(
$html .= $normalization->getHtmlForColumnsList(
$db,
$table,
_pgettext('string types', 'String')
@ -30,7 +29,7 @@ if (isset($_REQUEST['getColumns'])) {
}
if (isset($_REQUEST['splitColumn'])) {
$num_fields = min(4096, intval($_REQUEST['numFields']));
$html = Normalization::getHtmlForCreateNewColumn($num_fields, $db, $table);
$html = $normalization->getHtmlForCreateNewColumn($num_fields, $db, $table);
$html .= Url::getHiddenInputs($db, $table);
echo $html;
exit;
@ -38,7 +37,7 @@ if (isset($_REQUEST['splitColumn'])) {
if (isset($_REQUEST['addNewPrimary'])) {
$num_fields = 1;
$columnMeta = array('Field'=>$table . "_id", 'Extra'=>'auto_increment');
$html = Normalization::getHtmlForCreateNewColumn(
$html = $normalization->getHtmlForCreateNewColumn(
$num_fields, $db, $table, $columnMeta
);
$html .= Url::getHiddenInputs($db, $table);
@ -46,14 +45,14 @@ if (isset($_REQUEST['addNewPrimary'])) {
exit;
}
if (isset($_REQUEST['findPdl'])) {
$html = Normalization::findPartialDependencies($table, $db);
$html = $normalization->findPartialDependencies($table, $db);
echo $html;
exit;
}
if (isset($_REQUEST['getNewTables2NF'])) {
$partialDependencies = json_decode($_REQUEST['pd']);
$html = Normalization::getHtmlForNewTables2NF($partialDependencies, $table);
$html = $normalization->getHtmlForNewTables2NF($partialDependencies, $table);
echo $html;
exit;
}
@ -63,7 +62,7 @@ $response = Response::getInstance();
if (isset($_REQUEST['getNewTables3NF'])) {
$dependencies = json_decode($_REQUEST['pd']);
$tables = json_decode($_REQUEST['tables']);
$newTables = Normalization::getHtmlForNewTables3NF($dependencies, $tables, $db);
$newTables = $normalization->getHtmlForNewTables3NF($dependencies, $tables, $db);
$response->disable();
Core::headerJSON();
echo json_encode($newTables);
@ -81,13 +80,13 @@ if (Core::isValid($_REQUEST['normalizeTo'], array('1nf', '2nf', '3nf'))) {
if (isset($_REQUEST['createNewTables2NF'])) {
$partialDependencies = json_decode($_REQUEST['pd']);
$tablesName = json_decode($_REQUEST['newTablesName']);
$res = Normalization::createNewTablesFor2NF($partialDependencies, $tablesName, $table, $db);
$res = $normalization->createNewTablesFor2NF($partialDependencies, $tablesName, $table, $db);
$response->addJSON($res);
exit;
}
if (isset($_REQUEST['createNewTables3NF'])) {
$newtables = json_decode($_REQUEST['newTables']);
$res = Normalization::createNewTablesFor3NF($newtables, $db);
$res = $normalization->createNewTablesFor3NF($newtables, $db);
$response->addJSON($res);
exit;
}
@ -96,31 +95,31 @@ if (isset($_POST['repeatingColumns'])) {
$newTable = $_POST['newTable'];
$newColumn = $_POST['newColumn'];
$primary_columns = $_POST['primary_columns'];
$res = Normalization::moveRepeatingGroup(
$res = $normalization->moveRepeatingGroup(
$repeatingColumns, $primary_columns, $newTable, $newColumn, $table, $db
);
$response->addJSON($res);
exit;
}
if (isset($_REQUEST['step1'])) {
$html = Normalization::getHtmlFor1NFStep1($db, $table, $normalForm);
$html = $normalization->getHtmlFor1NFStep1($db, $table, $normalForm);
$response->addHTML($html);
} elseif (isset($_REQUEST['step2'])) {
$res = Normalization::getHtmlContentsFor1NFStep2($db, $table);
$res = $normalization->getHtmlContentsFor1NFStep2($db, $table);
$response->addJSON($res);
} elseif (isset($_REQUEST['step3'])) {
$res = Normalization::getHtmlContentsFor1NFStep3($db, $table);
$res = $normalization->getHtmlContentsFor1NFStep3($db, $table);
$response->addJSON($res);
} elseif (isset($_REQUEST['step4'])) {
$res = Normalization::getHtmlContentsFor1NFStep4($db, $table);
$res = $normalization->getHtmlContentsFor1NFStep4($db, $table);
$response->addJSON($res);
} elseif (isset($_REQUEST['step']) && $_REQUEST['step'] == '2.1') {
$res = Normalization::getHtmlFor2NFstep1($db, $table);
$res = $normalization->getHtmlFor2NFstep1($db, $table);
$response->addJSON($res);
} elseif (isset($_REQUEST['step']) && $_REQUEST['step'] == '3.1') {
$tables = $_REQUEST['tables'];
$res = Normalization::getHtmlFor3NFstep1($db, $tables);
$res = $normalization->getHtmlFor3NFstep1($db, $tables);
$response->addJSON($res);
} else {
$response->addHTML(Normalization::getHtmlForNormalizetable());
$response->addHTML($normalization->getHtmlForNormalizeTable());
}

View File

@ -13,10 +13,9 @@ use PhpMyAdmin\Theme;
use PhpMyAdmin\Types;
use PhpMyAdmin\Util;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use stdClass;
$GLOBALS['server'] = 1;
/**
* tests for PhpMyAdmin\Normalization
*
@ -24,6 +23,8 @@ $GLOBALS['server'] = 1;
*/
class NormalizationTest extends TestCase
{
private $normalization;
/**
* prepares environment for tests
*
@ -58,30 +59,30 @@ class NormalizationTest extends TestCase
->method('getColumns')
->will(
$this->returnValue(
array(
"id"=>array("Type"=>"integer"),
"col1"=>array("Type"=>'varchar(100)'),
"col2"=>array("Type"=>'DATETIME')
)
[
"id"=>["Type"=>"integer"],
"col1"=>["Type"=>'varchar(100)'],
"col2"=>["Type"=>'DATETIME']
]
)
);
$dbi->expects($this->any())
->method('getColumnNames')
->will($this->returnValue(array("id", "col1", "col2")));
$map = array(
array('PMA_db', 'PMA_table1', DatabaseInterface::CONNECT_USER, array()),
array(
->will($this->returnValue(["id", "col1", "col2"]));
$map = [
['PMA_db', 'PMA_table1', DatabaseInterface::CONNECT_USER, []],
[
'PMA_db', 'PMA_table', DatabaseInterface::CONNECT_USER,
array(array('Key_name'=>'PRIMARY', 'Column_name'=>'id'))
),
array(
[['Key_name'=>'PRIMARY', 'Column_name'=>'id']]
],
[
'PMA_db', 'PMA_table2', DatabaseInterface::CONNECT_USER,
array(
array('Key_name'=>'PRIMARY', 'Column_name'=>'id'),
array('Key_name'=>'PRIMARY', 'Column_name'=>'col1')
)
),
);
[
['Key_name'=>'PRIMARY', 'Column_name'=>'id'],
['Key_name'=>'PRIMARY', 'Column_name'=>'col1']
]
],
];
$dbi->expects($this->any())
->method('getTableIndexes')
->will($this->returnValueMap($map));
@ -90,43 +91,44 @@ class NormalizationTest extends TestCase
->will($this->returnValue(true));
$dbi->expects($this->any())
->method('fetchResult')
->will($this->returnValue(array(0)));
->will($this->returnValue([0]));
$this->normalization = new Normalization($dbi);
}
/**
* Test for Normalization::getHtmlForColumnsList
* Test for getHtmlForColumnsList
*
* @return void
*/
public function testPMAGetHtmlForColumnsList()
public function testGetHtmlForColumnsList()
{
$db = "PMA_db";
$table= "PMA_table";
$this->assertContains(
'<option value="id">id [ integer ]</option>',
Normalization::getHtmlForColumnsList($table, $db)
$this->normalization->getHtmlForColumnsList($table, $db)
);
$this->assertEquals(
'<input type="checkbox" value="col1"/>col1 [ varchar(100) ]</br>',
Normalization::getHtmlForColumnsList($table, $db, 'String', 'checkbox')
$this->normalization->getHtmlForColumnsList($table, $db, 'String', 'checkbox')
);
}
/**
* Test for Normalization::getHtmlForCreateNewColumn
* Test for getHtmlForCreateNewColumn
*
* @return void
*/
public function testPMAGetHtmlForCreateNewColumn()
public function testGetHtmlForCreateNewColumn()
{
$GLOBALS['cfg']['BrowseMIME'] = true;
$GLOBALS['cfg']['MaxRows'] = 25;
$GLOBALS['col_priv'] = false;
$db = "PMA_db";
$table= "PMA_table";
$num_fields = 1;
$result = Normalization::getHtmlForCreateNewColumn($num_fields, $db, $table);
$table = "PMA_table";
$numFields = 1;
$result = $this->normalization->getHtmlForCreateNewColumn($numFields, $db, $table);
$this->assertContains(
'<table id="table_columns"',
$result
@ -134,16 +136,16 @@ class NormalizationTest extends TestCase
}
/**
* Test for Normalization::getHtmlFor1NFStep1
* Test for getHtmlFor1NFStep1
*
* @return void
*/
public function testPMAGetHtmlFor1NFStep1()
public function testGetHtmlFor1NFStep1()
{
$db = "PMA_db";
$table= "PMA_table";
$normalizedTo = '1nf';
$result = Normalization::getHtmlFor1NFStep1($db, $table, $normalizedTo);
$result = $this->normalization->getHtmlFor1NFStep1($db, $table, $normalizedTo);
$this->assertContains(
"<h3 class='center'>"
. __('First step of normalization (1NF)') . "</h3>",
@ -171,23 +173,25 @@ class NormalizationTest extends TestCase
);
$this->assertContains(
Normalization::getHtmlForColumnsList(
$db, $table, _pgettext('string types', 'String')
), $result
$this->normalization->getHtmlForColumnsList(
$db,
$table,
_pgettext('string types', 'String')
),
$result
);
}
/**
* Test for Normalization::getHtmlContentsFor1NFStep2
* Test for getHtmlContentsFor1NFStep2
*
* @return void
*/
public function testPMAGetHtmlContentsFor1NFStep2()
public function testGetHtmlContentsFor1NFStep2()
{
$db = "PMA_db";
$table= "PMA_table1";
$result = Normalization::getHtmlContentsFor1NFStep2($db, $table);
$result = $this->normalization->getHtmlContentsFor1NFStep2($db, $table);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('legendText', $result);
$this->assertArrayHasKey('headText', $result);
@ -204,20 +208,20 @@ class NormalizationTest extends TestCase
);
$this->assertEquals('0', $result['hasPrimaryKey']);
$this->assertContains(__('Step 1.') . 2, $result['legendText']);
$result1 = Normalization::getHtmlContentsFor1NFStep2($db, 'PMA_table');
$result1 = $this->normalization->getHtmlContentsFor1NFStep2($db, 'PMA_table');
$this->assertEquals('1', $result1['hasPrimaryKey']);
}
/**
* Test for Normalization::getHtmlContentsFor1NFStep4
* Test for getHtmlContentsFor1NFStep4
*
* @return void
*/
public function testPMAGetHtmlContentsFor1NFStep4()
public function testGetHtmlContentsFor1NFStep4()
{
$db = "PMA_db";
$table= "PMA_table";
$result = Normalization::getHtmlContentsFor1NFStep4($db, $table);
$result = $this->normalization->getHtmlContentsFor1NFStep4($db, $table);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('legendText', $result);
$this->assertArrayHasKey('headText', $result);
@ -225,7 +229,7 @@ class NormalizationTest extends TestCase
$this->assertArrayHasKey('extra', $result);
$this->assertContains(__('Step 1.') . 4, $result['legendText']);
$this->assertContains(
Normalization::getHtmlForColumnsList($db, $table, 'all', "checkbox"),
$this->normalization->getHtmlForColumnsList($db, $table, 'all', "checkbox"),
$result['extra']
);
$this->assertContains(
@ -235,15 +239,15 @@ class NormalizationTest extends TestCase
}
/**
* Test for Normalization::getHtmlContentsFor1NFStep3
* Test for getHtmlContentsFor1NFStep3
*
* @return void
*/
public function testPMAGetHtmlContentsFor1NFStep3()
public function testGetHtmlContentsFor1NFStep3()
{
$db = "PMA_db";
$table= "PMA_table";
$result = Normalization::getHtmlContentsFor1NFStep3($db, $table);
$result = $this->normalization->getHtmlContentsFor1NFStep3($db, $table);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('legendText', $result);
$this->assertArrayHasKey('headText', $result);
@ -252,26 +256,26 @@ class NormalizationTest extends TestCase
$this->assertArrayHasKey('primary_key', $result);
$this->assertContains(__('Step 1.') . 3, $result['legendText']);
$this->assertContains(
Normalization::getHtmlForColumnsList($db, $table, 'all', "checkbox"),
$this->normalization->getHtmlForColumnsList($db, $table, 'all', "checkbox"),
$result['extra']
);
$this->assertContains(
'<input type="submit" id="moveRepeatingGroup"',
$result['extra']
);
$this->assertEquals(json_encode(array('id')), $result['primary_key']);
$this->assertEquals(json_encode(['id']), $result['primary_key']);
}
/**
* Test for Normalization::getHtmlFor2NFstep1
* Test for getHtmlFor2NFstep1
*
* @return void
*/
public function testPMAGetHtmlFor2NFstep1()
public function testGetHtmlFor2NFstep1()
{
$db = "PMA_db";
$table= "PMA_table";
$result = Normalization::getHtmlFor2NFstep1($db, $table);
$result = $this->normalization->getHtmlFor2NFstep1($db, $table);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('legendText', $result);
$this->assertArrayHasKey('headText', $result);
@ -280,7 +284,7 @@ class NormalizationTest extends TestCase
$this->assertArrayHasKey('primary_key', $result);
$this->assertContains(__('Step 2.') . 1, $result['legendText']);
$this->assertEquals('id', $result['primary_key']);
$result1 = Normalization::getHtmlFor2NFstep1($db, "PMA_table2");
$result1 = $this->normalization->getHtmlFor2NFstep1($db, "PMA_table2");
$this->assertEquals('id, col1', $result1['primary_key']);
$this->assertContains(
'<a href="#" id="showPossiblePd"',
@ -293,15 +297,15 @@ class NormalizationTest extends TestCase
}
/**
* Test for Normalization::getHtmlForNewTables2NF
* Test for getHtmlForNewTables2NF
*
* @return void
*/
public function testPMAGetHtmlForNewTables2NF()
public function testGetHtmlForNewTables2NF()
{
$table= "PMA_table";
$partialDependencies = array('col1'=>array('col2'));
$result = Normalization::getHtmlForNewTables2NF($partialDependencies, $table);
$partialDependencies = ['col1'=>['col2']];
$result = $this->normalization->getHtmlForNewTables2NF($partialDependencies, $table);
$this->assertContains(
'<input type="text" name="col1"',
$result
@ -309,28 +313,34 @@ class NormalizationTest extends TestCase
}
/**
* Test for Normalization::createNewTablesFor2NF
* Test for createNewTablesFor2NF
*
* @return void
*/
public function testPMACreateNewTablesFor2NF()
public function testCreateNewTablesFor2NF()
{
$table= "PMA_table";
$db = 'PMA_db';
$tablesName = new stdClass();
$tablesName->id = 'PMA_table';
$tablesName->col1 = 'PMA_table1';
$partialDependencies = array('id'=>array('col2'));
$result = Normalization::createNewTablesFor2NF(
$partialDependencies, $tablesName, $table, $db
$partialDependencies = ['id'=>['col2']];
$result = $this->normalization->createNewTablesFor2NF(
$partialDependencies,
$tablesName,
$table,
$db
);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('legendText', $result);
$this->assertArrayHasKey('headText', $result);
$this->assertArrayHasKey('queryError', $result);
$partialDependencies = array('id'=>array('col2'), 'col1'=>array('col2'));
$result1 = Normalization::createNewTablesFor2NF(
$partialDependencies, $tablesName, $table, $db
$partialDependencies = ['id'=>['col2'], 'col1'=>['col2']];
$result1 = $this->normalization->createNewTablesFor2NF(
$partialDependencies,
$tablesName,
$table,
$db
);
$this->assertArrayHasKey('extra', $result1);
$this->assertEquals(__('End of step'), $result1['legendText']);
@ -338,54 +348,56 @@ class NormalizationTest extends TestCase
}
/**
* Test for Normalization::getHtmlForNewTables3NF
* Test for getHtmlForNewTables3NF
*
* @return void
*/
public function testPMAGetHtmlForNewTables3NF()
public function testGetHtmlForNewTables3NF()
{
$tables= array("PMA_table"=>array('col1'));
$tables= ["PMA_table"=>['col1']];
$db = 'PMA_db';
$dependencies = new stdClass();
$dependencies->col1 = array('col2');
$result = Normalization::getHtmlForNewTables3NF($dependencies, $tables, $db);
$dependencies->col1 = ['col2'];
$result = $this->normalization->getHtmlForNewTables3NF($dependencies, $tables, $db);
$this->assertEquals(
array(
[
'html' => '',
'success' => true,
'newTables' => array()
), $result
'newTables' => []
],
$result
);
$tables= array("PMA_table"=>array('col1', 'PMA_table'));
$dependencies->PMA_table = array('col4', 'col5');
$result1 = Normalization::getHtmlForNewTables3NF($dependencies, $tables, $db);
$tables= ["PMA_table"=>['col1', 'PMA_table']];
$dependencies->PMA_table = ['col4', 'col5'];
$result1 = $this->normalization->getHtmlForNewTables3NF($dependencies, $tables, $db);
$this->assertInternalType('array', $result1);
$this->assertContains(
'<input type="text" name="PMA_table"',
$result1['html']
);
$this->assertEquals(
array(
'PMA_table' => array (
'PMA_table' => array (
[
'PMA_table' => [
'PMA_table' => [
'pk' => 'col1',
'nonpk' => 'col2'
),
'table2' => array (
],
'table2' => [
'pk' => 'id',
'nonpk' => 'col4, col5'
)
)
), $result1['newTables']
]
]
],
$result1['newTables']
);
}
/**
* Test for Normalization::createNewTablesFor3NF
* Test for createNewTablesFor3NF
*
* @return void
*/
public function testPMACreateNewTablesFor3NF()
public function testCreateNewTablesFor3NF()
{
$db = 'PMA_db';
$cols = new stdClass();
@ -394,17 +406,19 @@ class NormalizationTest extends TestCase
$cols1 = new stdClass();
$cols1->pk = 'col2';
$cols1->nonpk = 'col3, col4';
$newTables = array('PMA_table'=>array('PMA_table'=>$cols, 'table1'=>$cols1));
$result = Normalization::createNewTablesFor3NF(
$newTables, $db
$newTables = ['PMA_table'=>['PMA_table'=>$cols, 'table1'=>$cols1]];
$result = $this->normalization->createNewTablesFor3NF(
$newTables,
$db
);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('legendText', $result);
$this->assertArrayHasKey('headText', $result);
$this->assertArrayHasKey('queryError', $result);
$newTables1 = array();
$result1 = Normalization::createNewTablesFor3NF(
$newTables1, $db
$newTables1 = [];
$result1 = $this->normalization->createNewTablesFor3NF(
$newTables1,
$db
);
$this->assertArrayHasKey('queryError', $result1);
$this->assertEquals(__('End of step'), $result1['legendText']);
@ -412,39 +426,45 @@ class NormalizationTest extends TestCase
}
/**
* Test for Normalization::moveRepeatingGroup
* Test for moveRepeatingGroup
*
* @return void
*/
public function testPMAMoveRepeatingGroup()
public function testMoveRepeatingGroup()
{
$repeatingColumns = 'col1, col2';
$primary_columns = 'id,col1';
$primaryColumns = 'id,col1';
$newTable = 'PMA_newTable';
$newColumn = 'PMA_newCol';
$table= "PMA_table";
$db = 'PMA_db';
$result = Normalization::moveRepeatingGroup(
$repeatingColumns, $primary_columns, $newTable, $newColumn, $table, $db
$result = $this->normalization->moveRepeatingGroup(
$repeatingColumns,
$primaryColumns,
$newTable,
$newColumn,
$table,
$db
);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('queryError', $result);
$this->assertArrayHasKey('message', $result);
$this->assertInstanceOf(
'PhpMyAdmin\Message', $result['message']
'PhpMyAdmin\Message',
$result['message']
);
}
/**
* Test for Normalization::getHtmlFor3NFstep1
* Test for getHtmlFor3NFstep1
*
* @return void
*/
public function testPMAGetHtmlFor3NFstep1()
public function testGetHtmlFor3NFstep1()
{
$db = "PMA_db";
$tables= array("PMA_table");
$result = Normalization::getHtmlFor3NFstep1($db, $tables);
$tables= ["PMA_table"];
$result = $this->normalization->getHtmlFor3NFstep1($db, $tables);
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('legendText', $result);
$this->assertArrayHasKey('headText', $result);
@ -459,49 +479,54 @@ class NormalizationTest extends TestCase
'<input type="checkbox" name="pd" value="col1"',
$result['extra']
);
$result1 = Normalization::getHtmlFor3NFstep1($db, array("PMA_table2"));
$result1 = $this->normalization->getHtmlFor3NFstep1($db, ["PMA_table2"]);
$this->assertEquals(
'', $result1['subText']
'',
$result1['subText']
);
}
/**
* Test for Normalization::getHtmlForNormalizetable
* Test for getHtmlForNormalizeTable
*
* @return void
*/
public function testPMAGetHtmlForNormalizetable()
public function testgetHtmlForNormalizeTable()
{
$result = Normalization::getHtmlForNormalizetable();
$result = $this->normalization->getHtmlForNormalizeTable();
$this->assertContains(
'<form method="post" action="normalization.php"'
. ' name="normalize" id="normalizeTable"',
$result
);
$this->assertContains(
'<input type="hidden" name="step1" value="1">', $result
'<input type="hidden" name="step1" value="1">',
$result
);
$choices = array(
$choices = [
'1nf' => __('First step of normalization (1NF)'),
'2nf' => __('Second step of normalization (1NF+2NF)'),
'3nf' => __('Third step of normalization (1NF+2NF+3NF)'));
'3nf' => __('Third step of normalization (1NF+2NF+3NF)')];
$html_tmp = Util::getRadioFields(
'normalizeTo', $choices, '1nf', true
$htmlTmp = Util::getRadioFields(
'normalizeTo',
$choices,
'1nf',
true
);
$this->assertContains($html_tmp, $result);
$this->assertContains($htmlTmp, $result);
}
/**
* Test for Normalization::findPartialDependencies
* Test for findPartialDependencies
*
* @return void
*/
public function testPMAFindPartialDependencies()
public function testFindPartialDependencies()
{
$table= "PMA_table2";
$db = 'PMA_db';
$result = Normalization::findPartialDependencies($table, $db);
$result = $this->normalization->findPartialDependencies($table, $db);
$this->assertContains(
'<div class="dependencies_box"',
$result
@ -510,16 +535,20 @@ class NormalizationTest extends TestCase
}
/**
* Test for Normalization::getAllCombinationPartialKeys
* Test for getAllCombinationPartialKeys
*
* @return void
*/
public function testPMAGetAllCombinationPartialKeys()
public function testGetAllCombinationPartialKeys()
{
$primaryKey = array('id', 'col1', 'col2');
$result = Normalization::getAllCombinationPartialKeys($primaryKey);
$class = new ReflectionClass(Normalization::class);
$method = $class->getMethod('getAllCombinationPartialKeys');
$method->setAccessible(true);
$primaryKey = ['id', 'col1', 'col2'];
$result = $method->invokeArgs($this->normalization, [$primaryKey]);
$this->assertEquals(
array('', 'id', 'col1', 'col1,id', 'col2', 'col2,id', 'col2,col1'),
['', 'id', 'col1', 'col1,id', 'col2', 'col2,id', 'col2,col1'],
$result
);
}