Merge pull request #1334 from nisargjhaveri/feature_857
feature 857: Regex search and replace
This commit is contained in:
commit
7be74bf634
@ -1362,40 +1362,81 @@ EOT;
|
||||
}
|
||||
}
|
||||
$htmlOutput .= '</select>';
|
||||
|
||||
$htmlOutput .= '<br>' . PMA_Util::getCheckbox('useRegex' , __('Use regular expression'), false, false);
|
||||
return $htmlOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for previewing strings found and their replacements
|
||||
* Finds and returns Regex pattern and their replacements
|
||||
*
|
||||
* @param int $columnIndex index of the column
|
||||
* @param string $find string to find in the column
|
||||
* @param string $replaceWith string to replace with
|
||||
* @param string $charSet character set of the connection
|
||||
*
|
||||
* @return string HTML for previewing strings found and their replacements
|
||||
* @return array Array containing original values, replcaed values and count
|
||||
*/
|
||||
function getReplacePreview($columnIndex, $find, $replaceWith, $charSet)
|
||||
function _getRegexReplaceRows($columnIndex, $find, $replaceWith, $charSet)
|
||||
{
|
||||
$column = $this->_columnNames[$columnIndex];
|
||||
$sql_query = "SELECT "
|
||||
. PMA_Util::backquote($column) . ","
|
||||
. " REPLACE("
|
||||
. PMA_Util::backquote($column) . ", '" . $find . "', '" . $replaceWith
|
||||
. "'),"
|
||||
. " 1," // to add an extra column that will have replaced value
|
||||
. " COUNT(*)"
|
||||
. " FROM " . PMA_Util::backquote($this->_db)
|
||||
. "." . PMA_Util::backquote($this->_table)
|
||||
. " WHERE " . PMA_Util::backquote($column)
|
||||
. " LIKE '%" . $find . "%' COLLATE " . $charSet . "_bin"; // here we
|
||||
. " RLIKE '" . PMA_Util::sqlAddSlashes($find) . "' COLLATE " . $charSet . "_bin"; // here we
|
||||
// change the collation of the 2nd operand to a case sensitive
|
||||
// binary collation to make sure that the comparison is case sensitive
|
||||
$sql_query .= " GROUP BY " . PMA_Util::backquote($column)
|
||||
. " ORDER BY " . PMA_Util::backquote($column) . " ASC";
|
||||
|
||||
$resultSet = $GLOBALS['dbi']->query(
|
||||
$sql_query, null, PMA_DatabaseInterface::QUERY_STORE
|
||||
);
|
||||
$result = $GLOBALS['dbi']->fetchResult($sql_query, 0);
|
||||
|
||||
if (is_array($result)) {
|
||||
foreach ($result as $index=>$row) {
|
||||
$result[$index][1] = preg_replace("/" . $find . "/" , $replaceWith, $row[0]);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for previewing strings found and their replacements
|
||||
*
|
||||
* @param int $columnIndex index of the column
|
||||
* @param string $find string to find in the column
|
||||
* @param string $replaceWith string to replace with
|
||||
* @param boolean $useRegex to use Regex replace or not
|
||||
* @param string $charSet character set of the connection
|
||||
*
|
||||
* @return string HTML for previewing strings found and their replacements
|
||||
*/
|
||||
function getReplacePreview($columnIndex, $find, $replaceWith, $useRegex, $charSet)
|
||||
{
|
||||
$column = $this->_columnNames[$columnIndex];
|
||||
if( $useRegex ) {
|
||||
$result = $this->_getRegexReplaceRows($columnIndex, $find, $replaceWith, $charSet);
|
||||
} else {
|
||||
$sql_query = "SELECT "
|
||||
. PMA_Util::backquote($column) . ","
|
||||
. " REPLACE("
|
||||
. PMA_Util::backquote($column) . ", '" . $find . "', '" . $replaceWith
|
||||
. "'),"
|
||||
. " COUNT(*)"
|
||||
. " FROM " . PMA_Util::backquote($this->_db)
|
||||
. "." . PMA_Util::backquote($this->_table)
|
||||
. " WHERE " . PMA_Util::backquote($column)
|
||||
. " LIKE '%" . $find . "%' COLLATE " . $charSet . "_bin"; // here we
|
||||
// change the collation of the 2nd operand to a case sensitive
|
||||
// binary collation to make sure that the comparison is case sensitive
|
||||
$sql_query .= " GROUP BY " . PMA_Util::backquote($column)
|
||||
. " ORDER BY " . PMA_Util::backquote($column) . " ASC";
|
||||
|
||||
$result = $GLOBALS['dbi']->fetchResult($sql_query, 0);
|
||||
}
|
||||
|
||||
$htmlOutput = '<form method="post" action="tbl_find_replace.php"'
|
||||
. ' name="previewForm" id="previewForm" class="ajax">';
|
||||
@ -1404,9 +1445,11 @@ EOT;
|
||||
$htmlOutput .= '<input type="hidden" name="columnIndex" value="'
|
||||
. $columnIndex . '" />';
|
||||
$htmlOutput .= '<input type="hidden" name="findString"'
|
||||
. ' value="' . $find . '" />';
|
||||
. ' value="' . htmlspecialchars($find) . '" />';
|
||||
$htmlOutput .= '<input type="hidden" name="replaceWith"'
|
||||
. ' value="' . $replaceWith . '" />';
|
||||
. ' value="' . htmlspecialchars($replaceWith) . '" />';
|
||||
$htmlOutput .= '<input type="hidden" name="useRegex"'
|
||||
. ' value="' . $useRegex . '" />';
|
||||
|
||||
$htmlOutput .= '<fieldset id="fieldset_find_replace_preview">';
|
||||
$htmlOutput .= '<legend>' . __('Find and replace - preview') . '</legend>';
|
||||
@ -1420,18 +1463,20 @@ EOT;
|
||||
|
||||
$htmlOutput .= '<tbody>';
|
||||
$odd = true;
|
||||
while ($row = $GLOBALS['dbi']->fetchRow($resultSet)) {
|
||||
$val = $row[0];
|
||||
$replaced = $row[1];
|
||||
$count = $row[2];
|
||||
if (is_array($result)) {
|
||||
foreach ($result as $row) {
|
||||
$val = $row[0];
|
||||
$replaced = $row[1];
|
||||
$count = $row[2];
|
||||
|
||||
$htmlOutput .= '<tr class="' . ($odd ? 'odd' : 'even') . '">';
|
||||
$htmlOutput .= '<td class="right">' . htmlspecialchars($count) . '</td>';
|
||||
$htmlOutput .= '<td>' . htmlspecialchars($val) . '</td>';
|
||||
$htmlOutput .= '<td>' . htmlspecialchars($replaced) . '</td>';
|
||||
$htmlOutput .= '</tr>';
|
||||
$htmlOutput .= '<tr class="' . ($odd ? 'odd' : 'even') . '">';
|
||||
$htmlOutput .= '<td class="right">' . htmlspecialchars($count) . '</td>';
|
||||
$htmlOutput .= '<td>' . htmlspecialchars($val) . '</td>';
|
||||
$htmlOutput .= '<td>' . htmlspecialchars($replaced) . '</td>';
|
||||
$htmlOutput .= '</tr>';
|
||||
|
||||
$odd = ! $odd;
|
||||
$odd = ! $odd;
|
||||
}
|
||||
}
|
||||
$htmlOutput .= '</tbody>';
|
||||
$htmlOutput .= '</table>';
|
||||
@ -1449,26 +1494,45 @@ EOT;
|
||||
/**
|
||||
* Replaces a given string in a column with a give replacement
|
||||
*
|
||||
* @param int $columnIndex index of the column
|
||||
* @param string $find string to find in the column
|
||||
* @param string $replaceWith string to replace with
|
||||
* @param string $charSet character set of the connection
|
||||
* @param int $columnIndex index of the column
|
||||
* @param string $find string to find in the column
|
||||
* @param string $replaceWith string to replace with
|
||||
* @param boolean $useRegex to use Regex replace or not
|
||||
* @param string $charSet character set of the connection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function replace($columnIndex, $find, $replaceWith, $charSet)
|
||||
function replace($columnIndex, $find, $replaceWith, $useRegex, $charSet)
|
||||
{
|
||||
$column = $this->_columnNames[$columnIndex];
|
||||
$sql_query = "UPDATE " . PMA_Util::backquote($this->_db)
|
||||
. "." . PMA_Util::backquote($this->_table)
|
||||
. " SET " . PMA_Util::backquote($column) . " ="
|
||||
. " REPLACE("
|
||||
. PMA_Util::backquote($column) . ", '" . $find . "', '" . $replaceWith
|
||||
. "')"
|
||||
. " WHERE " . PMA_Util::backquote($column)
|
||||
. " LIKE '%" . $find . "%' COLLATE " . $charSet . "_bin"; // here we
|
||||
// change the collation of the 2nd operand to a case sensitive
|
||||
// binary collation to make sure that the comparison is case sensitive
|
||||
if ($useRegex) {
|
||||
$toReplace = $this->_getRegexReplaceRows($columnIndex, $find, $replaceWith, $charSet);
|
||||
$sql_query = "UPDATE " . PMA_Util::backquote($this->_db)
|
||||
. "." . PMA_Util::backquote($this->_table)
|
||||
. " SET " . PMA_Util::backquote($column) . " = CASE";
|
||||
if (is_array($toReplace)) {
|
||||
foreach ($toReplace as $row) {
|
||||
$sql_query .= "\n WHEN " . PMA_Util::backquote($column) . " = '" . PMA_Util::sqlAddSlashes($row[0]) . "' THEN '" . PMA_Util::sqlAddSlashes($row[1]) . "'";
|
||||
}
|
||||
}
|
||||
$sql_query .= " END"
|
||||
. " WHERE " . PMA_Util::backquote($column)
|
||||
. " RLIKE '" . PMA_Util::sqlAddSlashes($find) . "' COLLATE " . $charSet . "_bin"; // here we
|
||||
// change the collation of the 2nd operand to a case sensitive
|
||||
// binary collation to make sure that the comparison is case sensitive
|
||||
}
|
||||
else {
|
||||
$sql_query = "UPDATE " . PMA_Util::backquote($this->_db)
|
||||
. "." . PMA_Util::backquote($this->_table)
|
||||
. " SET " . PMA_Util::backquote($column) . " ="
|
||||
. " REPLACE("
|
||||
. PMA_Util::backquote($column) . ", '" . $find . "', '" . $replaceWith
|
||||
. "')"
|
||||
. " WHERE " . PMA_Util::backquote($column)
|
||||
. " LIKE '%" . $find . "%' COLLATE " . $charSet . "_bin"; // here we
|
||||
// change the collation of the 2nd operand to a case sensitive
|
||||
// binary collation to make sure that the comparison is case sensitive
|
||||
}
|
||||
$GLOBALS['dbi']->query(
|
||||
$sql_query, null, PMA_DatabaseInterface::QUERY_STORE
|
||||
);
|
||||
|
||||
@ -25,6 +25,7 @@ if (isset($_POST['find'])) {
|
||||
$_POST['columnIndex'],
|
||||
$_POST['find'],
|
||||
$_POST['replaceWith'],
|
||||
$_POST['useRegex'],
|
||||
$connectionCharSet
|
||||
);
|
||||
$response->addJSON('preview', $preview);
|
||||
@ -43,6 +44,7 @@ if (isset($_POST['replace'])) {
|
||||
$_POST['columnIndex'],
|
||||
$_POST['findString'],
|
||||
$_POST['replaceWith'],
|
||||
$_POST['useRegex'],
|
||||
$connectionCharSet
|
||||
);
|
||||
$htmlOutput .= PMA_Util::getMessage(
|
||||
|
||||
@ -74,6 +74,7 @@ class PMA_TableReplaceSearchTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
$find = 'findValue';
|
||||
$replaceWith = 'replaceWithValue';
|
||||
$useRegex = false;
|
||||
$charSet = 'charSetValue';
|
||||
|
||||
$expectedQuery = "SELECT `column1`, REPLACE(`column1`, '" . $find . "', '"
|
||||
@ -82,20 +83,14 @@ class PMA_TableReplaceSearchTest extends PHPUnit_Framework_TestCase
|
||||
. " `column1` ORDER BY `column1` ASC";
|
||||
// set expectations
|
||||
$dbi->expects($this->once())
|
||||
->method('query')
|
||||
->with($expectedQuery);
|
||||
$dbi->expects($this->at(1))
|
||||
->method('fetchRow')
|
||||
->will($this->returnValue(array('val1', 'replace1', 5)));
|
||||
$dbi->expects($this->at(2))
|
||||
->method('fetchRow')
|
||||
->will($this->returnValue(array('va<2', 'replac<2', 1)));
|
||||
$dbi->expects($this->at(3))
|
||||
->method('fetchRow')
|
||||
->will($this->returnValue(false));
|
||||
->method('fetchResult')
|
||||
->will($this->returnValue(array(
|
||||
array('val1', 'replace1', 5),
|
||||
array('va<2', 'replac<2', 1)
|
||||
)));
|
||||
$GLOBALS['dbi'] = $dbi;
|
||||
|
||||
$ret = $this->_object->getReplacePreview(0, $find, $replaceWith, $charSet);
|
||||
$ret = $this->_object->getReplacePreview(0, $find, $replaceWith, $useRegex, $charSet);
|
||||
|
||||
// assert whether hidden values are properly set
|
||||
$this->assertContains(
|
||||
@ -141,6 +136,7 @@ class PMA_TableReplaceSearchTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
$find = 'findValue';
|
||||
$replaceWith = 'replaceWithValue';
|
||||
$useRegex = false;
|
||||
$charSet = 'charSetValue';
|
||||
|
||||
$expectedQuery = "UPDATE `dbName`.`tableName`"
|
||||
@ -153,7 +149,7 @@ class PMA_TableReplaceSearchTest extends PHPUnit_Framework_TestCase
|
||||
->with($expectedQuery);
|
||||
$GLOBALS['dbi'] = $dbi;
|
||||
|
||||
$this->_object->replace(0, $find, $replaceWith, $charSet);
|
||||
$this->_object->replace(0, $find, $replaceWith, $useRegex, $charSet);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@ -239,8 +239,9 @@ class PMA_TableSearch_Test extends PHPUnit_Framework_TestCase
|
||||
$columnIndex = 0;
|
||||
$find = "Field";
|
||||
$replaceWith = "Column";
|
||||
$useRegex = false;
|
||||
$charSet = "UTF-8";
|
||||
$tableSearch->replace($columnIndex, $find, $replaceWith, $charSet);
|
||||
$tableSearch->replace($columnIndex, $find, $replaceWith, $useRegex, $charSet);
|
||||
|
||||
$sql_query = $GLOBALS['sql_query'];
|
||||
$result = "UPDATE `PMA`.`PMA_BookMark` SET `Field1` = "
|
||||
@ -288,11 +289,9 @@ class PMA_TableSearch_Test extends PHPUnit_Framework_TestCase
|
||||
|
||||
$dbi = $GLOBALS['dbi'];
|
||||
|
||||
$dbi->expects($this->at(3))->method('fetchRow')
|
||||
->will($this->returnValue($value));
|
||||
|
||||
$dbi->expects($this->at(4))->method('fetchRow')
|
||||
->will($this->returnValue(false));
|
||||
$dbi->expects($this->once())
|
||||
->method('fetchResult')
|
||||
->will($this->returnValue(array($value)));
|
||||
|
||||
$GLOBALS['dbi'] = $dbi;
|
||||
|
||||
@ -300,12 +299,14 @@ class PMA_TableSearch_Test extends PHPUnit_Framework_TestCase
|
||||
$columnIndex = 0;
|
||||
$find = "Field";
|
||||
$replaceWith = "Column";
|
||||
$useRegex = false;
|
||||
$charSet = "UTF-8";
|
||||
|
||||
$html = $tableSearch->getReplacePreview(
|
||||
$columnIndex,
|
||||
$find,
|
||||
$replaceWith,
|
||||
$useRegex,
|
||||
$charSet
|
||||
);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user