diff --git a/js/messages.php b/js/messages.php
index dda85093b4..241b574803 100644
--- a/js/messages.php
+++ b/js/messages.php
@@ -317,6 +317,11 @@ $js_messages['strShowPossiblePd'] = __('Show me the possible partial dependencie
$js_messages['strHidePd'] = __('Hide partial dependencies list');
$js_messages['strWaitForPd'] = __('Sit tight! It may take few seconds depending on data size and column count of the table.');
$js_messages['strStep'] = __('Step');
+$js_messages['strMoveRepeatingGroup'] = '
' . __('The following actions will be performed:') . ''
+ . '
' . __('DROP columns %1s from the table %2s') . '
'
+ . '
' . __('Create the following new table') . '
';
+$js_messages['strNewTablePlaceholder'] = 'Enter new table name';
+$js_messages['strNewColumnPlaceholder'] = 'Enter column name';
/* For server_variables.js */
$js_messages['strSave'] = __('Save');
diff --git a/js/normalization.js b/js/normalization.js
index 16751a14fe..e0b1a730f8 100644
--- a/js/normalization.js
+++ b/js/normalization.js
@@ -12,7 +12,7 @@
*/
var normalizeto = '1nf';
-
+var primary_key;
function appendHtmlColumnsList()
{
$.get(
@@ -70,6 +70,30 @@ function goToFinish1NF()
$('.tblFooters').html('');
}
+function goToStep4()
+{
+ $.post(
+ "normalization.php",
+ {
+ "token": PMA_commonParams.get('token'),
+ "ajax_request": true,
+ "db": PMA_commonParams.get('db'),
+ "table": PMA_commonParams.get('table'),
+ "step4": true
+ }, function(data) {
+ $("#mainContent legend").html(data.legendText);
+ $("#mainContent h4").html(data.headText);
+ $("#mainContent p").html(data.subText);
+ $("#mainContent #extra").html(data.extra);
+ $("#mainContent #newCols").html('');
+ $('.tblFooters').html('');
+ for(var pk in primary_key) {
+ $("#extra input[value='"+primary_key[pk]+"']").attr("disabled","disabled");
+ }
+ }
+ );
+}
+
function goToStep3()
{
$.post(
@@ -87,6 +111,10 @@ function goToStep3()
$("#mainContent #extra").html(data.extra);
$("#mainContent #newCols").html('');
$('.tblFooters').html('');
+ primary_key = $.parseJSON(data.primary_key);
+ for(var pk in primary_key) {
+ $("#extra input[value='"+primary_key[pk]+"']").attr("disabled","disabled");
+ }
}
);
}
@@ -238,7 +266,44 @@ function processPartialDependancies(primary_key)
goTo2NFStep2(pd, primary_key);
return false;
}
-
+function moveRepeatingGroup(repeatingCols) {
+ newTable = $("input[name=repeatGroupTable]").val();
+ newColumn = $("input[name=repeatGroupColumn]").val();
+ if (!newTable) {
+ $("input[name=repeatGroupTable]").focus();
+ return false;
+ }
+ if (!newColumn) {
+ $("input[name=repeatGroupColumn]").focus();
+ return false;
+ }
+ datastring = {"token": PMA_commonParams.get('token'),
+ "ajax_request": true,
+ "db": PMA_commonParams.get('db'),
+ "table": PMA_commonParams.get('table'),
+ "repeatingColumns": repeatingCols,
+ "newTable":newTable,
+ "newColumn":newColumn,
+ "primary_columns":primary_key.toString()
+ };
+ $.ajax({
+ type: "POST",
+ url: "normalization.php",
+ data: datastring,
+ async:false,
+ success: function(data) {
+ if (data.success === true) {
+ if(data.queryError === false) {
+ goToStep3();
+ }
+ PMA_ajaxShowMessage(data.message, false);
+ $("#pma_navigation_reload").click();
+ } else {
+ PMA_ajaxShowMessage(data.error, false);
+ }
+ }
+ });
+}
AJAX.registerTeardown('normalization.js', function () {
$("#extra").off("click", "#selectNonAtomicCol");
$("#splitGo").unbind('click');
@@ -397,7 +462,24 @@ AJAX.registerOnload('normalization.js', function() {
}
);
});
+ $("#extra").on("click", "#moveRepeatingGroup", function() {
+ var repeatingCols = '';
+ $("#extra input[type=checkbox]:checked").each(function() {
+ repeatingCols += $(this).val() + ', ';
+ });
+ if (repeatingCols !== '') {
+ newColName = $("#extra input[type=checkbox]:checked:first").val();
+ repeatingCols = repeatingCols.slice(0, -2);
+ confirmStr = $.sprintf(PMA_messages.strMoveRepeatingGroup, escapeHtml(repeatingCols), escapeHtml(PMA_commonParams.get('table')));
+ confirmStr += ''+
+ '( '+escapeHtml(primary_key.toString())+', )'+
+ '';
+ $("#newCols").html(confirmStr);
+ $('.tblFooters').html(''+
+ '');
+ }
+ });
$("#mainContent p").on("click", "#createPrimaryKey", function(event) {
event.preventDefault();
var url = { create_index: 1,
diff --git a/libraries/normalization.lib.php b/libraries/normalization.lib.php
index 117b0d2d0f..d6e5c20be2 100644
--- a/libraries/normalization.lib.php
+++ b/libraries/normalization.lib.php
@@ -195,16 +195,16 @@ function PMA_getHtmlContentsFor1NFStep2($db, $table)
}
/**
- * build the html contents of various html elements in step 1.3
+ * build the html contents of various html elements in step 1.4
*
* @param string $db current database
* @param string $table current table
*
- * @return HTML contents for step 1.3
+ * @return HTML contents for step 1.4
*/
-function PMA_getHtmlContentsFor1NFStep3($db, $table)
+function PMA_getHtmlContentsFor1NFStep4($db, $table)
{
- $step = 3;
+ $step = 4;
$stepTxt = __('Remove redundant columns');
$legendText = __('Step 1.') . $step . " " . $stepTxt;
$headText = __(
@@ -229,6 +229,52 @@ function PMA_getHtmlContentsFor1NFStep3($db, $table)
);
return $res;
}
+
+/**
+ * build the html contents of various html elements in step 1.3
+ *
+ * @param string $db current database
+ * @param string $table current table
+ *
+ * @return HTML contents for step 1.3
+ */
+function PMA_getHtmlContentsFor1NFStep3($db, $table)
+{
+ $step = 3;
+ $stepTxt = __('Move repeating groups');
+ $legendText = __('Step 1.') . $step . " " . $stepTxt;
+ $headText = __(
+ "Do you have group of two or more columns that are closely "
+ . " related and are all repeating same attribute? For example, "
+ . "if a table that records data on book, has "
+ . " columns book_id, author1, author2, author3 and so on which form a "
+ . "repeating group. In this case new table (book_id, author) should "
+ . "be created. another examples can be"
+ . " phone1, phone2, phone3 and so on Or picture1, picture2 etc"
+ );
+ $subText = __(
+ "Check the columns which form a repeating group. "
+ . "If no such group, click on 'No repeating group'"
+ );
+ $extra = PMA_getHtmlForColumnsList($db, $table, 'all', "checkbox") . ""
+ . ''
+ . '';
+ $primary = PMA_Index::getPrimary($table, $db);
+ $primarycols = $primary->getColumns();
+ $pk = array();
+ foreach ($primarycols as $col) {
+ $pk[] = $col->getName();
+ }
+ $res = array(
+ 'legendText'=>$legendText, 'headText'=>$headText,
+ 'subText'=>$subText, 'extra'=>$extra, 'primary_key'=> json_encode($pk)
+ );
+ return $res;
+}
+
/**
* build html contents for 2NF step 2.1
*
@@ -420,6 +466,69 @@ function PMA_createNewTablesFor2NF($partialDependencies, $tablesName, $table, $d
'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 $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
+ * @param string $db current database
+ *
+ * @return array
+ */
+function PMA_moveRepeatingGroup(
+ $repeatingColumns, $primary_columns, $newTable, $newColumn, $table, $db
+) {
+ $repeatingColumnsArr = (array)PMA_Util::backquote(
+ explode(', ', $repeatingColumns)
+ );
+ $primary_columns = implode(
+ ',', PMA_Util::backquote(explode(',', $primary_columns))
+ );
+ $query1 = 'CREATE TABLE ' . PMA_Util::backquote($newTable);
+ $query2 = 'ALTER TABLE ' . PMA_Util::backquote($table);
+ $message = PMA_Message::success(
+ sprintf(
+ __('Selected repeating group has been moved the to the table \'%s\''),
+ htmlspecialchars($table)
+ )
+ );
+ $first = true;
+ $error = false;
+ foreach ($repeatingColumnsArr as $repeatingColumn) {
+ if (!$first) {
+ $query1 .= ' UNION ';
+ }
+ $first = false;
+ $query1 .= ' SELECT ' . $primary_columns . ',' . $repeatingColumn
+ . ' as ' . PMA_Util::backquote($newColumn)
+ . ' FROM ' . PMA_Util::backquote($table);
+ $query2 .= ' DROP ' . $repeatingColumn . ',';
+ }
+ $query2 = trim($query2, ',');
+ $queries = array($query1, $query2);
+ $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
+ foreach ($queries as $query) {
+ if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['userlink'])) {
+ $message = PMA_Message::error(__('Error in processing!'));
+ $message->addMessage('