From f6a7525818476454cc28ba233b71d58e6b0f7d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Wed, 14 Apr 2004 12:55:00 +0000 Subject: [PATCH] Really support export of UPDATE queries (bug #914237), condition generation used from previous implementation in display_tbl.lib.php and moved to common.lib.php. --- ChangeLog | 4 ++ libraries/common.lib.php | 94 +++++++++++++++++++++++++++++++++-- libraries/display_tbl.lib.php | 80 +---------------------------- libraries/export/sql.php | 46 +++++++---------- 4 files changed, 114 insertions(+), 110 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f531b5a6..b476e127d 100755 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,10 @@ $Source$ 2004-03-25 Michal Cihar * lang/czech: Updated. * tbl_select.php: Fixed undefined variable warning. + * libraries/common.lib.php, libraries/display_tbl.lib.php, + libraries/export/sql.php: Really support export of UPDATE queries (bug + #914237), condition generation used from previous implementation in + display_tbl.lib.php and moved to common.lib.php. 2004-04-13 Marc Delisle * libraries/relation.lib.php: bug 930445 when PMA_table_info not defined, diff --git a/libraries/common.lib.php b/libraries/common.lib.php index 5a8cb76fd..09c8e5d6a 100644 --- a/libraries/common.lib.php +++ b/libraries/common.lib.php @@ -557,10 +557,10 @@ if ($is_minimum_common == FALSE) { * Get the complete list of Databases a user can access * * @param boolean whether to include check on failed 'only_db' operations - * @param ressource database handle (superuser) + * @param resource database handle (superuser) * @param integer amount of databases inside the 'only_db' container - * @param ressource possible ressource from a failed previous query - * @param ressource database handle (user) + * @param resource possible resource from a failed previous query + * @param resource database handle (user) * @param array configuration * @param array previous list of databases * @@ -1896,6 +1896,7 @@ if (typeof(document.getElementById) != 'undefined' * * @access public * @author Michal Cihar (nijel@users.sourceforge.net) + * @return bool Whether extension is valid */ function PMA_checkFileExtensions($file, $extension) { if (substr($file, -1 * strlen($extension)) == $extension) { @@ -1914,5 +1915,92 @@ if (typeof(document.getElementById) != 'undefined' return FALSE; } // end function + /** + * Function to generate unique condition for specified row. + * + * @param resource handle for current query + * @param integer number of fields + * @param array meta information about fields + * @param array current row + * + * @access public + * @author Michal Cihar (michal@cihar.com) + * @return string calculated condition + */ + function PMA_getUvaCondition($handle, $fields_cnt, $fields_meta, $row) { + + $primary_key = ''; + $unique_key = ''; + $uva_nonprimary_condition = ''; + + for ($i = 0; $i < $fields_cnt; ++$i) { + $field_flags = PMA_DBI_field_flags($handle, $i); + $meta = $fields_meta[$i]; + // do not use an alias in a condition + $column_for_condition = $meta->name; + if (isset($analyzed_sql[0]['select_expr']) && is_array($analyzed_sql[0]['select_expr'])) { + foreach($analyzed_sql[0]['select_expr'] AS $select_expr_position => $select_expr) { + $alias = $analyzed_sql[0]['select_expr'][$select_expr_position]['alias']; + if (!empty($alias)) { + $true_column = $analyzed_sql[0]['select_expr'][$select_expr_position]['column']; + if ($alias == $meta->name) { + $column_for_condition = $true_column; + } // end if + } // end if + } // end while + } + + // to fix the bug where float fields (primary or not) + // can't be matched because of the imprecision of + // floating comparison, use CONCAT + // (also, the syntax "CONCAT(field) IS NULL" + // that we need on the next "if" will work) + if ($meta->type == 'real') { + $condition = ' CONCAT(' . PMA_backquote($column_for_condition) . ') '; + } else { + // string and blob fields have to be converted using + // the system character set (always utf8) since + // mysql4.1 can use different charset for fields. + if (PMA_MYSQL_INT_VERSION >= 40100 && ($meta->type == 'string' || $meta->type == 'blob')) { + $condition = ' CONVERT(' . PMA_backquote($column_for_condition) . ' USING utf8) '; + } else { + $condition = ' ' . PMA_backquote($column_for_condition) . ' '; + } + } // end if... else... + + if (!isset($row[$i]) || is_null($row[$i])) { + $condition .= 'IS NULL AND'; + } else { + if ($meta->type == 'blob' + // hexify only if this is a true not empty BLOB + && stristr($field_flags, 'BINARY') + && !empty($row[$i])) { + $condition .= 'LIKE 0x' . bin2hex($row[$i]). ' AND'; + } else { + $condition .= '= \'' . PMA_sqlAddslashes($row[$i], FALSE, TRUE) . '\' AND'; + } + } + if ($meta->primary_key > 0) { + $primary_key .= $condition; + } else if ($meta->unique_key > 0) { + $unique_key .= $condition; + } + $uva_nonprimary_condition .= $condition; + } // end for + + // Correction uva 19991216: prefer primary or unique keys + // for condition, but use conjunction of all values if no + // primary key + if ($primary_key) { + $uva_condition = $primary_key; + } else if ($unique_key) { + $uva_condition = $unique_key; + } else { + $uva_condition = $uva_nonprimary_condition; + } + + return preg_replace('|\s?AND$|', '', $uva_condition); + } // end function + } // end if: minimal common.lib needed? ?> diff --git a/libraries/display_tbl.lib.php b/libraries/display_tbl.lib.php index a91a08418..1544cd44c 100644 --- a/libraries/display_tbl.lib.php +++ b/libraries/display_tbl.lib.php @@ -1026,88 +1026,10 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) // 1. Prepares the row (gets primary keys to use) if ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') { - $primary_key = ''; - $unique_key = ''; - $uva_nonprimary_condition = ''; - // 1.1 Results from a "SELECT" statement -> builds the // "primary" key to use in links if ($is_display['edit_lnk'] == 'ur' /* || $is_display['edit_lnk'] == 'dr' */) { - for ($i = 0; $i < $fields_cnt; ++$i) { - $field_flags = PMA_DBI_field_flags($dt_result, $i); - $meta = $fields_meta[$i]; - // do not use an alias in a condition - $column_for_condition = $meta->name; - if (isset($analyzed_sql[0]['select_expr']) && is_array($analyzed_sql[0]['select_expr'])) { - foreach($analyzed_sql[0]['select_expr'] AS $select_expr_position => $select_expr) { - $alias = $analyzed_sql[0]['select_expr'][$select_expr_position]['alias']; - if (!empty($alias)) { - $true_column = $analyzed_sql[0]['select_expr'][$select_expr_position]['column']; - if ($alias == $meta->name) { - $column_for_condition = $true_column; - } // end if - } // end if - } // end while - } - - // to fix the bug where float fields (primary or not) - // can't be matched because of the imprecision of - // floating comparison, use CONCAT - // (also, the syntax "CONCAT(field) IS NULL" - // that we need on the next "if" will work) - if ($meta->type == 'real') { - $condition = ' CONCAT(' . PMA_backquote($column_for_condition) . ') '; - } else { - // string and blob fields have to be converted using - // the system character set (always utf8) since - // mysql4.1 can use different charset for fields. - if (PMA_MYSQL_INT_VERSION >= 40100 && ($meta->type == 'string' || $meta->type == 'blob')) { - $condition = ' CONVERT(' . PMA_backquote($column_for_condition) . ' USING utf8) '; - } else { - $condition = ' ' . PMA_backquote($column_for_condition) . ' '; - } - } // end if... else... - - // loic1: To fix bug #474943 under php4, the row - // pointer will depend on whether the "is_null" - // php4 function is available or not - // ne0x: Not used anymore because PMA needs PHP > 4.1.0 where - // the "is_null" function is available. - // - // $pointer = (function_exists('is_null') ? $i : $meta->name); - - if (!isset($row[$i]) || is_null($row[$i])) { - $condition .= 'IS NULL AND'; - } else { - if ($meta->type == 'blob' - // hexify only if this is a true not empty BLOB - && stristr($field_flags, 'BINARY') - && !empty($row[$i])) { - $condition .= 'LIKE 0x' . bin2hex($row[$i]). ' AND'; - } else { - $condition .= '= \'' . PMA_sqlAddslashes($row[$i], FALSE, TRUE) . '\' AND'; - } - } - if ($meta->primary_key > 0) { - $primary_key .= $condition; - } else if ($meta->unique_key > 0) { - $unique_key .= $condition; - } - $uva_nonprimary_condition .= $condition; - } // end for - - // Correction uva 19991216: prefer primary or unique keys - // for condition, but use conjunction of all values if no - // primary key - if ($primary_key) { - $uva_condition = $primary_key; - } else if ($unique_key) { - $uva_condition = $unique_key; - } else { - $uva_condition = $uva_nonprimary_condition; - } - - $uva_condition = urlencode(preg_replace('|\s?AND$|', '', $uva_condition)); + $uva_condition = urlencode(PMA_getUvaCondition($dt_result, $fields_cnt, $fields_meta, $row)); } // end if (1.1) // 1.2 Defines the urls for the modify/delete link(s) diff --git a/libraries/export/sql.php b/libraries/export/sql.php index 0ecb494e9..b84a1ed5d 100644 --- a/libraries/export/sql.php +++ b/libraries/export/sql.php @@ -426,32 +426,17 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) $result = PMA_DBI_query($sql_query, NULL, PMA_DBI_QUERY_UNBUFFERED); if ($result != FALSE) { - $fields_cnt = PMA_DBI_num_fields($result); + $fields_cnt = PMA_DBI_num_fields($result); + + $fields_meta = PMA_DBI_get_fields_meta($result); - // Checks whether the field is an integer or not for ($j = 0; $j < $fields_cnt; $j++) { - if (isset($analyzed_sql[0]['select_expr'][$j]['column'])) { $field_set[$j] = PMA_backquote($analyzed_sql[0]['select_expr'][$j]['column'], $use_backquotes); } else { - $field_set[$j] = PMA_backquote(PMA_DBI_field_name($result, $j), $use_backquotes); + $field_set[$j] = PMA_backquote($fields_meta[$j]->name, $use_backquotes); } - - $type = $field_types[$field_set[$j]]; - - if ($type == 'tinyint' || $type == 'smallint' || $type == 'mediumint' || $type == 'int' || - $type == 'bigint' || (PMA_MYSQL_INT_VERSION < 40100 && $type == 'timestamp')) { - $field_num[$j] = TRUE; - } else { - $field_num[$j] = FALSE; - } - // blob - if ($type == 'blob' || $type == 'mediumblob' || $type == 'longblob' || $type == 'tinyblob') { - $field_blob[$j] = TRUE; - } else { - $field_blob[$j] = FALSE; - } - } // end for + } if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'update') { // update @@ -459,7 +444,6 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) if (isset($GLOBALS['sql_ignore'])) $schema_insert .= 'IGNORE '; $schema_insert .= PMA_backquote($table, $use_backquotes) . ' SET '; - $fields_no = count($field_set); } else { // insert or replace if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'replace') { @@ -498,21 +482,25 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) while ($row = PMA_DBI_fetch_row($result)) { $current_row++; for ($j = 0; $j < $fields_cnt; $j++) { - if (!isset($row[$j])) { + $field_flags = PMA_DBI_field_flags($result, $j); + if (!isset($row[$j]) || is_null($row[$j])) { $values[] = 'NULL'; } else if ($row[$j] == '0' || $row[$j] != '') { // a number - if ($field_num[$j]) { + if ($fields_meta[$j]->numeric) { $values[] = $row[$j]; - // a not empty blob - } else if ($field_blob[$j] && !empty($row[$j])) { + // a blob + } else if ($fields_meta[$j]->blob + // hexify only if this is a true not empty BLOB + && stristr($field_flags, 'BINARY') + && !empty($row[$j])) { $values[] = '0x' . bin2hex($row[$j]); // a string } else { - $values[] = "'" . str_replace($search, $replace, PMA_sqlAddslashes($row[$j])) . "'"; + $values[] = '\'' . str_replace($search, $replace, PMA_sqlAddslashes($row[$j])) . '\''; } } else { - $values[] = "''"; + $values[] = '\'\''; } // end if } // end for @@ -520,13 +508,15 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'update') { $insert_line = $schema_insert; - for ($i = 0; $i < $fields_no; $i++) { + for ($i = 0; $i < $fields_cnt; $i++) { if ($i > 0) { $insert_line .= ', '; } $insert_line .= $field_set[$i] . ' = ' . $values[$i]; } + $insert_line .= ' WHERE ' . PMA_getUvaCondition($result, $fields_cnt, $fields_meta, $row); + } else { // Extended inserts case