Grid edit: fix bug - update where_clause precisely (previous version cannot handle space or special characters)

This commit is contained in:
Aris Feryanto 2011-08-03 10:21:41 +08:00
parent 65bea22f1f
commit 91d85841fc
3 changed files with 70 additions and 43 deletions

View File

@ -881,9 +881,10 @@
// loop each edited row
$('.to_be_saved').parents('tr').each(function() {
var where_clause = $(this).find('.where_clause').val();
var $tr = $(this);
var where_clause = $tr.find('.where_clause').val();
full_where_clause.push(unescape(where_clause.replace(/[+]/g, ' ')));
var new_clause = where_clause;
var condition_array = jQuery.parseJSON($tr.find('.condition_array').val());
/**
* multi edit variables, for current row
@ -894,14 +895,12 @@
var fields_null = Array();
// loop each edited cell in a row
$(this).find('.to_be_saved').each(function() {
$tr.find('.to_be_saved').each(function() {
/**
* @var $this_field Object referring to the td that is being edited
*/
var $this_field = $(this);
var $test_element = ''; // to test the presence of a element
/**
* @var field_name String containing the name of this field.
* @see getFieldName()
@ -916,10 +915,12 @@
if($this_field.is('.transformed')) {
transformation_fields = true;
}
this_field_params[field_name] = $this_field.data('value');
/**
* @var is_null String capturing whether 'checkbox_null_<field_name>_<row_index>' is checked.
*/
var is_null = $this_field.data('value') === null;
var is_null = this_field_params[field_name] === null;
fields_name.push(field_name);
@ -929,7 +930,6 @@
} else {
fields_null.push('');
fields.push($this_field.data('value'));
this_field_params[field_name] = $this_field.data('value');
var cell_index = $this_field.index('.to_be_saved');
if($this_field.is(":not(.relation, .enum, .set, .bit)")) {
@ -941,19 +941,31 @@
relation_fields[cell_index] = {};
$.extend(relation_fields[cell_index], this_field_params);
}
if (where_clause.indexOf(PMA_urlencode(field_name)) > -1) {
var fields_str = PMA_urlencode('`' + g.table + '`.' + '`' + field_name + '` = ');
fields_str = fields_str.replace(/[+]/g, '[+]'); // replace '+' sign with '[+]' (regex)
var old_sub_clause_regex = new RegExp(fields_str + '[^+]*');
var new_sub_clause = PMA_urlencode('`' + g.table + '`.' + '`' + field_name + "` = '" + this_field_params[field_name].replace(/'/g,"''") + "'");
new_clause = new_clause.replace(old_sub_clause_regex, new_sub_clause);
}
// check if edited field appears in WHERE clause
if (where_clause.indexOf(PMA_urlencode(field_name)) > -1) {
var field_str = '`' + g.table + '`.' + '`' + field_name + '`';
for (var field in condition_array) {
if (field.indexOf(field_str) > -1) {
condition_array[field] = is_null ? 'IS NULL' : "= '" + this_field_params[field_name].replace(/'/g,"''") + "'";
break;
}
}
}
// save new_clause
$this_field.parent('tr').data('new_clause', new_clause);
}); // end of loop for every edited cells in a row
// save new_clause
var new_clause = '';
for (var field in condition_array) {
new_clause += field + ' ' + condition_array[field] + ' AND ';
}
new_clause = new_clause.substring(0, new_clause.length - 5); // remove the last AND
new_clause = PMA_urlencode(new_clause);
$tr.data('new_clause', new_clause);
// save condition_array
$tr.find('.condition_array').val(JSON.stringify(condition_array));
me_fields_name.push(fields_name);
me_fields.push(fields);
me_fields_null.push(fields_null);

View File

@ -1890,9 +1890,15 @@ function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force
$unique_key = '';
$nonprimary_condition = '';
$preferred_condition = '';
$primary_key_array = array();
$unique_key_array = array();
$nonprimary_condition_array = array();
$condition_array = array();
for ($i = 0; $i < $fields_cnt; ++$i) {
$condition = '';
$con_key = '';
$con_val = '';
$field_flags = PMA_DBI_field_flags($handle, $i);
$meta = $fields_meta[$i];
@ -1934,20 +1940,21 @@ function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force
// (also, the syntax "CONCAT(field) IS NULL"
// that we need on the next "if" will work)
if ($meta->type == 'real') {
$condition = ' CONCAT(' . PMA_backquote($meta->table) . '.'
. PMA_backquote($meta->orgname) . ') ';
$con_key = 'CONCAT(' . PMA_backquote($meta->table) . '.'
. PMA_backquote($meta->orgname) . ')';
} else {
$condition = ' ' . PMA_backquote($meta->table) . '.'
. PMA_backquote($meta->orgname) . ' ';
$con_key = PMA_backquote($meta->table) . '.'
. PMA_backquote($meta->orgname);
} // end if... else...
$condition = ' ' . $con_key . ' ';
if (! isset($row[$i]) || is_null($row[$i])) {
$condition .= 'IS NULL AND';
$con_val = 'IS NULL';
} else {
// timestamp is numeric on some MySQL 4.1
// for real we use CONCAT above and it should compare to string
if ($meta->numeric && $meta->type != 'timestamp' && $meta->type != 'real') {
$condition .= '= ' . $row[$i] . ' AND';
$con_val = '= ' . $row[$i];
} elseif (($meta->type == 'blob' || $meta->type == 'string')
// hexify only if this is a true not empty BLOB or a BINARY
&& stristr($field_flags, 'BINARY')
@ -1956,25 +1963,29 @@ function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force
if (strlen($row[$i]) < 1000) {
// use a CAST if possible, to avoid problems
// if the field contains wildcard characters % or _
$condition .= '= CAST(0x' . bin2hex($row[$i])
. ' AS BINARY) AND';
$con_val = '= CAST(0x' . bin2hex($row[$i]) . ' AS BINARY)';
} else {
// this blob won't be part of the final condition
$condition = '';
$con_val = null;
}
} elseif ($meta->type == 'bit') {
$condition .= "= b'" . PMA_printable_bit_value($row[$i], $meta->length) . "' AND";
$con_val = "= b'" . PMA_printable_bit_value($row[$i], $meta->length) . "'";
} else {
$condition .= '= \''
. PMA_sqlAddSlashes($row[$i], false, true) . '\' AND';
$con_val = '= \'' . PMA_sqlAddSlashes($row[$i], false, true) . '\'';
}
}
if ($meta->primary_key > 0) {
$primary_key .= $condition;
} elseif ($meta->unique_key > 0) {
$unique_key .= $condition;
if ($con_val != null) {
$condition .= $con_val . ' AND';
if ($meta->primary_key > 0) {
$primary_key .= $condition;
$primary_key_array[$con_key] = $con_val;
} elseif ($meta->unique_key > 0) {
$unique_key .= $condition;
$unique_key_array[$con_key] = $con_val;
}
$nonprimary_condition .= $condition;
$nonprimary_condition_array[$con_key] = $con_val;
}
$nonprimary_condition .= $condition;
} // end for
// Correction University of Virginia 19991216:
@ -1983,15 +1994,18 @@ function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force
$clause_is_unique = true;
if ($primary_key) {
$preferred_condition = $primary_key;
$condition_array = $primary_key_array;
} elseif ($unique_key) {
$preferred_condition = $unique_key;
$condition_array = $unique_key_array;
} elseif (! $force_unique) {
$preferred_condition = $nonprimary_condition;
$condition_array = $nonprimary_condition_array;
$clause_is_unique = false;
}
$where_clause = trim(preg_replace('|\s?AND$|', '', $preferred_condition));
return(array($where_clause, $clause_is_unique));
return(array($where_clause, $clause_is_unique, $condition_array));
} // end function
/**

View File

@ -1285,7 +1285,7 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
* with only one field and it's a BLOB; in this case,
* avoid to display the delete and edit links
*/
list($where_clause, $clause_is_unique) = PMA_getUniqueCondition($dt_result, $fields_cnt, $fields_meta, $row);
list($where_clause, $clause_is_unique, $condition_array) = PMA_getUniqueCondition($dt_result, $fields_cnt, $fields_meta, $row);
$where_clause_html = urlencode($where_clause);
// 1.2 Defines the URLs for the modify/delete link(s)
@ -1377,14 +1377,14 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
if (! isset($js_conf)) {
$js_conf = '';
}
echo PMA_generateCheckboxAndLinks('left', $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $del_query, 'l', $edit_url, $copy_url, $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf);
echo PMA_generateCheckboxAndLinks('left', $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $condition_array, $del_query, 'l', $edit_url, $copy_url, $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf);
} else if (($GLOBALS['cfg']['RowActionLinks'] == 'none')
&& ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
|| $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) {
if (! isset($js_conf)) {
$js_conf = '';
}
echo PMA_generateCheckboxAndLinks('none', $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $del_query, 'l', $edit_url, $copy_url, $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf);
echo PMA_generateCheckboxAndLinks('none', $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $condition_array, $del_query, 'l', $edit_url, $copy_url, $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf);
} // end if (1.3)
} // end if (1)
@ -1669,7 +1669,7 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
if (! isset($js_conf)) {
$js_conf = '';
}
echo PMA_generateCheckboxAndLinks('right', $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $del_query, 'r', $edit_url, $copy_url, $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf);
echo PMA_generateCheckboxAndLinks('right', $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $condition_array, $del_query, 'r', $edit_url, $copy_url, $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf);
} // end if (3)
if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
@ -1696,7 +1696,7 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
}
if (!empty($del_url) && $is_display['del_lnk'] != 'kp') {
$vertical_display['row_delete'][$row_no] .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $del_query, '[%_PMA_CHECKBOX_DIR_%]', $alternating_color_class . $vertical_class);
$vertical_display['row_delete'][$row_no] .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $condition_array, $del_query, '[%_PMA_CHECKBOX_DIR_%]', $alternating_color_class . $vertical_class);
} else {
unset($vertical_display['row_delete'][$row_no]);
}
@ -2711,7 +2711,7 @@ function PMA_prepare_row_data($class, $condition_field, $analyzed_sql, $meta, $m
* @return string the generated HTML
*/
function PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $del_query, $id_suffix, $class) {
function PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $condition_array, $del_query, $id_suffix, $class) {
$ret = '';
if (! empty($del_url) && $is_display['del_lnk'] != 'kp') {
$ret .= '<td ';
@ -2722,6 +2722,7 @@ function PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_cla
. '<input type="checkbox" id="id_rows_to_delete' . $row_no . $id_suffix . '" name="rows_to_delete[' . $where_clause_html . ']"'
. ' class="multi_checkbox"'
. ' value="' . htmlspecialchars($del_query) . '" ' . (isset($GLOBALS['checkall']) ? 'checked="checked"' : '') . ' />'
. '<input type="hidden" class="condition_array" value="' . htmlspecialchars(json_encode($condition_array)) . '" />'
. ' </td>';
}
return $ret;
@ -2827,11 +2828,11 @@ function PMA_generateDeleteLink($del_url, $del_str, $js_conf, $class) {
* @param string $js_conf
* @return string the generated HTML
*/
function PMA_generateCheckboxAndLinks($position, $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $del_query, $id_suffix, $edit_url, $copy_url, $class, $edit_str, $copy_str, $del_str, $js_conf) {
function PMA_generateCheckboxAndLinks($position, $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $condition_array, $del_query, $id_suffix, $edit_url, $copy_url, $class, $edit_str, $copy_str, $del_str, $js_conf) {
$ret = '';
if ($position == 'left') {
$ret .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $del_query, $id_suffix='_left', '', '', '');
$ret .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $condition_array, $del_query, $id_suffix='_left', '', '', '');
$ret .= PMA_generateEditLink($edit_url, $class, $edit_str, $where_clause, $where_clause_html, '');
@ -2846,9 +2847,9 @@ function PMA_generateCheckboxAndLinks($position, $del_url, $is_display, $row_no,
$ret .= PMA_generateEditLink($edit_url, $class, $edit_str, $where_clause, $where_clause_html, '');
$ret .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $del_query, $id_suffix='_right', '', '', '');
$ret .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $condition_array, $del_query, $id_suffix='_right', '', '', '');
} else { // $position == 'none'
$ret .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $del_query, $id_suffix='_left', '', '', '');
$ret .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $condition_array, $del_query, $id_suffix='_left', '', '', '');
}
return $ret;
}