Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpmyadmin/phpmyadmin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Foellmann <foellmann@foe-services.de>2014-12-23 14:48:13 +0300
committerChristian Foellmann <foellmann@foe-services.de>2014-12-23 14:48:13 +0300
commit2bfb20e57418ebf396149782be9f98e868fe8608 (patch)
treea5ec4011410970603d3f462a535a5a359057fa77 /libraries/relation.lib.php
parent20f1bf77c8281efc675a14e0f6bf52f657dabd9a (diff)
UPDATE 4.3.34.3.3
Diffstat (limited to 'libraries/relation.lib.php')
-rw-r--r--libraries/relation.lib.php713
1 files changed, 528 insertions, 185 deletions
diff --git a/libraries/relation.lib.php b/libraries/relation.lib.php
index 349eb49f8f..f4c5987e26 100644
--- a/libraries/relation.lib.php
+++ b/libraries/relation.lib.php
@@ -88,10 +88,7 @@ function PMA_getRelationsParamDiagnostic($cfgRelation)
$messages = array();
$messages['error'] = '<font color="red"><strong>'
. __('not OK')
- . '</strong></font>'
- . ' [ <a href="%s" target="documentation">'
- . __('Documentation')
- . '</a> ]';
+ . '</strong></font>';
$messages['ok'] = '<font color="green"><strong>'
. _pgettext('Correctly working', 'OK')
@@ -101,12 +98,16 @@ function PMA_getRelationsParamDiagnostic($cfgRelation)
$messages['disabled'] = '<font color="red">' . __('Disabled') . '</font>';
if (false === $GLOBALS['cfg']['Server']['pmadb']) {
- $retval .= 'PMA Database ... '
- . sprintf($messages['error'], 'pmadb')
+ $retval .= __('Configuration of pmadb… ')
+ . $messages['error']
+ . PMA_Util::showDocu('setup', 'linked-tables')
. '<br />' . "\n"
. __('General relation features')
. ' <font color="green">' . __('Disabled')
. '</font>' . "\n";
+ if (! empty($GLOBALS['db']) && $GLOBALS['cfg']['ZeroConf']) {
+ $retval .= PMA_getHtmlFixPMATables();
+ }
} else {
$retval .= '<table>' . "\n";
$retval .= PMA_getDiagMessageForParameter(
@@ -150,7 +151,7 @@ function PMA_getRelationsParamDiagnostic($cfgRelation)
'pdf_pages'
);
$retval .= PMA_getDiagMessageForFeature(
- __('Creation of PDFs'),
+ __('Designer and creation of PDFs'),
'pdfwork',
$messages
);
@@ -172,8 +173,12 @@ function PMA_getRelationsParamDiagnostic($cfgRelation)
$messages
);
if ($cfgRelation['commwork'] && ! $cfgRelation['mimework']) {
- $retval .= '<tr><td colspan=2 class="left">';
- $retval .= __('Please see the documentation on how to update your column_comments table.');
+ $retval .= '<tr><td colspan=2 class="left error">';
+ $retval .= __(
+ 'Please see the documentation on how to'
+ . ' update your column_info table. '
+ );
+ $retval .= PMA_Util::showDocu('config', 'cfg_Servers_column_info');
$retval .= '</td></tr>';
}
$retval .= PMA_getDiagMessageForParameter(
@@ -199,17 +204,6 @@ function PMA_getRelationsParamDiagnostic($cfgRelation)
$messages
);
$retval .= PMA_getDiagMessageForParameter(
- 'designer_coords',
- isset($cfgRelation['designer_coords']),
- $messages,
- 'designer_coords'
- );
- $retval .= PMA_getDiagMessageForFeature(
- __('Designer'),
- 'designerwork',
- $messages
- );
- $retval .= PMA_getDiagMessageForParameter(
'recent',
isset($cfgRelation['recent']),
$messages,
@@ -292,35 +286,53 @@ function PMA_getRelationsParamDiagnostic($cfgRelation)
'savedsearcheswork',
$messages
);
- $retval .= '</table>' . "\n";
-
- $retval .= '<p>' . __('Quick steps to setup advanced features:') . '</p>';
- $retval .= '<ul>';
- $retval .= '<li>';
- $retval .= __(
- 'Create the needed tables with the '
- . '<code>examples/create_tables.sql</code>.'
- );
- $retval .= ' ' . PMA_Util::showDocu('setup', 'linked-tables');
- $retval .= '</li>';
- $retval .= '<li>';
- $retval .= __('Create a pma user and give access to these tables.');
- $retval .= ' ' . PMA_Util::showDocu('config', 'cfg_Servers_controluser');
- $retval .= '</li>';
- $retval .= '<li>';
- $retval .= __(
- 'Enable advanced features in configuration file '
- . '(<code>config.inc.php</code>), for example by '
- . 'starting from <code>config.sample.inc.php</code>.'
+ $retval .= PMA_getDiagMessageForParameter(
+ 'central_columns',
+ isset($cfgRelation['central_columns']),
+ $messages,
+ 'central_columns'
);
- $retval .= ' ' . PMA_Util::showDocu('setup', 'quick-install');
- $retval .= '</li>';
- $retval .= '<li>';
- $retval .= __(
- 'Re-login to phpMyAdmin to load the updated configuration file.'
+ $retval .= PMA_getDiagMessageForFeature(
+ __('Managing Central list of columns'),
+ 'central_columnswork',
+ $messages
);
- $retval .= '</li>';
- $retval .= '</ul>';
+ $retval .= '</table>' . "\n";
+
+ if (! $cfgRelation['allworks']) {
+
+ $retval .= '<p>' . __('Quick steps to setup advanced features:')
+ . '</p>';
+ $retval .= '<ul>';
+ $retval .= '<li>';
+ $retval .= sprintf(
+ __(
+ 'Create the needed tables with the '
+ . '<code>%screate_tables.sql</code>.'
+ ),
+ htmlspecialchars(EXAMPLES_DIR)
+ );
+ $retval .= ' ' . PMA_Util::showDocu('setup', 'linked-tables');
+ $retval .= '</li>';
+ $retval .= '<li>';
+ $retval .= __('Create a pma user and give access to these tables.');
+ $retval .= ' ' . PMA_Util::showDocu('config', 'cfg_Servers_controluser');
+ $retval .= '</li>';
+ $retval .= '<li>';
+ $retval .= __(
+ 'Enable advanced features in configuration file '
+ . '(<code>config.inc.php</code>), for example by '
+ . 'starting from <code>config.sample.inc.php</code>.'
+ );
+ $retval .= ' ' . PMA_Util::showDocu('setup', 'quick-install');
+ $retval .= '</li>';
+ $retval .= '<li>';
+ $retval .= __(
+ 'Re-login to phpMyAdmin to load the updated configuration file.'
+ );
+ $retval .= '</li>';
+ $retval .= '</ul>';
+ }
}
return $retval;
@@ -340,7 +352,9 @@ function PMA_getDiagMessageForFeature($feature_name,
$relation_parameter, $messages, $skip_line = true
) {
$retval = ' <tr><td colspan=2 class="right">' . $feature_name . ': ';
- if ($GLOBALS['cfgRelation'][$relation_parameter]) {
+ if (isset($GLOBALS['cfgRelation'][$relation_parameter])
+ && $GLOBALS['cfgRelation'][$relation_parameter]
+ ) {
$retval .= $messages['enabled'];
} else {
$retval .= $messages['disabled'];
@@ -402,27 +416,28 @@ function PMA_checkRelationsParam()
$cfgRelation['recentwork'] = false;
$cfgRelation['uiprefswork'] = false;
$cfgRelation['trackingwork'] = false;
- $cfgRelation['designerwork'] = false;
$cfgRelation['userconfigwork'] = false;
$cfgRelation['menuswork'] = false;
$cfgRelation['navwork'] = false;
$cfgRelation['allworks'] = false;
$cfgRelation['savedsearcheswork'] = false;
+ $cfgRelation['central_columnswork'] = false;
$cfgRelation['user'] = null;
$cfgRelation['db'] = null;
if ($GLOBALS['server'] == 0
|| empty($GLOBALS['cfg']['Server']['pmadb'])
- || ! $GLOBALS['dbi']->selectDb($GLOBALS['cfg']['Server']['pmadb'], $GLOBALS['controllink'])
+ || ! $GLOBALS['dbi']->selectDb(
+ $GLOBALS['cfg']['Server']['pmadb'], $GLOBALS['controllink']
+ )
) {
// No server selected -> no bookmark table
// we return the array with the falses in it,
- // to avoid some 'Unitialized string offset' errors later
+ // to avoid some 'Uninitialized string offset' errors later
$GLOBALS['cfg']['Server']['pmadb'] = false;
return $cfgRelation;
}
-
$cfgRelation['user'] = $GLOBALS['cfg']['Server']['user'];
$cfgRelation['db'] = $GLOBALS['cfg']['Server']['pmadb'];
@@ -454,8 +469,6 @@ function PMA_checkRelationsParam()
$cfgRelation['table_info'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['table_coords']) {
$cfgRelation['table_coords'] = $curr_table[0];
- } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['designer_coords']) {
- $cfgRelation['designer_coords'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['column_info']) {
$cfgRelation['column_info'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['pdf_pages']) {
@@ -478,6 +491,8 @@ function PMA_checkRelationsParam()
$cfgRelation['navigationhiding'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['savedsearches']) {
$cfgRelation['savedsearches'] = $curr_table[0];
+ } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['central_columns']) {
+ $cfgRelation['central_columns'] = $curr_table[0];
}
} // end while
$GLOBALS['dbi']->freeResult($tab_rs);
@@ -495,7 +510,9 @@ function PMA_checkRelationsParam()
if (isset($cfgRelation['column_info'])) {
$cfgRelation['commwork'] = true;
- $cfgRelation['mimework'] = true;
+ // phpMyAdmin 4.3+
+ // Check for input transformations upgrade.
+ $cfgRelation['mimework'] = PMA_tryUpgradeTransformations();
}
if (isset($cfgRelation['history'])) {
@@ -518,12 +535,6 @@ function PMA_checkRelationsParam()
$cfgRelation['userconfigwork'] = true;
}
- // we do not absolutely need that the internal relations or the PDF
- // schema feature be activated
- if (isset($cfgRelation['designer_coords'])) {
- $cfgRelation['designerwork'] = true;
- }
-
if (isset($cfgRelation['bookmark'])) {
$cfgRelation['bookmarkwork'] = true;
}
@@ -540,12 +551,16 @@ function PMA_checkRelationsParam()
$cfgRelation['savedsearcheswork'] = true;
}
+ if (isset($cfgRelation['central_columns'])) {
+ $cfgRelation['central_columnswork'] = true;
+ }
+
if ($cfgRelation['relwork'] && $cfgRelation['displaywork']
&& $cfgRelation['pdfwork'] && $cfgRelation['commwork']
&& $cfgRelation['mimework'] && $cfgRelation['historywork']
&& $cfgRelation['recentwork'] && $cfgRelation['uiprefswork']
&& $cfgRelation['trackingwork'] && $cfgRelation['userconfigwork']
- && $cfgRelation['bookmarkwork'] && $cfgRelation['designerwork']
+ && $cfgRelation['bookmarkwork'] && $cfgRelation['central_columnswork']
&& $cfgRelation['menuswork'] && $cfgRelation['navwork']
&& $cfgRelation['savedsearcheswork']
) {
@@ -556,6 +571,69 @@ function PMA_checkRelationsParam()
} // end of the 'PMA_getRelationsParam()' function
/**
+ * Check whether column_info table input transformation
+ * upgrade is required and try to upgrade silently
+ *
+ * @return bool false if upgrade failed
+ *
+ * @access public
+ */
+function PMA_tryUpgradeTransformations()
+{
+ // From 4.3, new input oriented transformation feature was introduced.
+ // Check whether column_info table has input transformation columns
+ $new_cols = array(
+ "input_transformation",
+ "input_transformation_options"
+ );
+ $query = 'SHOW COLUMNS FROM '
+ . PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb'])
+ . '.' . PMA_Util::backquote($GLOBALS['cfg']['Server']['column_info'])
+ . ' WHERE Field IN (\'' . implode('\', \'', $new_cols) . '\')';
+ $result = PMA_queryAsControlUser(
+ $query, false, PMA_DatabaseInterface::QUERY_STORE
+ );
+ if ($result) {
+ $rows = $GLOBALS['dbi']->numRows($result);
+ $GLOBALS['dbi']->freeResult($result);
+ // input transformations are present
+ // no need to upgrade
+ if ($rows === 2) {
+ return true;
+ // try silent upgrade without disturbing the user
+ } else {
+ // read upgrade query file
+ $query = @file_get_contents(EXAMPLES_DIR . 'upgrade_column_info_4_3_0+.sql');
+ // replace database name from query to with set in config.inc.php
+ $query = str_replace(
+ '`phpmyadmin`',
+ PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']),
+ $query
+ );
+ // replace pma__column_info table name from query
+ // to with set in config.inc.php
+ $query = str_replace(
+ '`pma__column_info`',
+ PMA_Util::backquote($GLOBALS['cfg']['Server']['column_info']),
+ $query
+ );
+ $GLOBALS['dbi']->tryMultiQuery($query, $GLOBALS['controllink']);
+ // skips result sets of query as we are not interested in it
+ while ($GLOBALS['dbi']->moreResults($GLOBALS['controllink'])
+ && $GLOBALS['dbi']->nextResult($GLOBALS['controllink'])
+ ) {
+ }
+ $error = $GLOBALS['dbi']->getError($GLOBALS['controllink']);
+ // return true if no error exists otherwise false
+ return empty($error);
+ }
+ }
+ // some failure, either in upgrading or something else
+ // make some noise, time to wake up user.
+ return false;
+}
+
+/**
* Gets all Relations to foreign tables for a given table or
* optionally a given column in a table
*
@@ -583,7 +661,7 @@ function PMA_getForeigners($db, $table, $column = '', $source = 'both')
. '.' . PMA_Util::backquote($cfgRelation['relation']) . '
WHERE `master_db` = \'' . PMA_Util::sqlAddSlashes($db) . '\'
AND `master_table` = \'' . PMA_Util::sqlAddSlashes($table) . '\' ';
- if (strlen($column)) {
+ if (/*overload*/mb_strlen($column)) {
$rel_query .= ' AND `master_field` = '
. '\'' . PMA_Util::sqlAddSlashes($column) . '\'';
}
@@ -592,61 +670,26 @@ function PMA_getForeigners($db, $table, $column = '', $source = 'both')
);
}
- if (($source == 'both' || $source == 'foreign') && strlen($table)) {
+ if (($source == 'both' || $source == 'foreign') && /*overload*/mb_strlen($table)
+ ) {
$showCreateTableQuery = 'SHOW CREATE TABLE '
. PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table);
$show_create_table = $GLOBALS['dbi']->fetchValue(
$showCreateTableQuery, 0, 1
);
- $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
-
- foreach ($analyzed_sql[0]['foreign_keys'] as $one_key) {
- // The analyzer may return more than one column name in the
- // index list or the ref_index_list; if this happens,
- // the current logic just discards the whole index; having
- // more than one index field is currently unsupported (see FAQ 3.6)
- if (count($one_key['index_list']) == 1) {
- foreach ($one_key['index_list'] as $i => $field) {
- // If a foreign key is defined in the 'internal' source (pmadb)
- // and as a native foreign key, we won't get it twice
- // if $source='both' because we use $field as key
-
- // The parser looks for a CONSTRAINT clause just before
- // the FOREIGN KEY clause. It finds it (as output from
- // SHOW CREATE TABLE) in MySQL 4.0.13, but not in older
- // versions like 3.23.58.
- // In those cases, the FOREIGN KEY parsing will put numbers
- // like -1, 0, 1... instead of the constraint number.
-
- if (isset($one_key['constraint'])) {
- $foreign[$field]['constraint'] = $one_key['constraint'];
- }
-
- if (isset($one_key['ref_db_name'])) {
- $foreign[$field]['foreign_db'] = $one_key['ref_db_name'];
- } else {
- $foreign[$field]['foreign_db'] = $db;
- }
- $foreign[$field]['foreign_table'] = $one_key['ref_table_name'];
- $foreign[$field]['foreign_field']
- = $one_key['ref_index_list'][$i];
- if (isset($one_key['on_delete'])) {
- $foreign[$field]['on_delete'] = $one_key['on_delete'];
- }
- if (isset($one_key['on_update'])) {
- $foreign[$field]['on_update'] = $one_key['on_update'];
- }
- }
- }
+ if ($show_create_table) {
+ $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
+ $foreign['foreign_keys_data'] = $analyzed_sql[0]['foreign_keys'];
}
}
/**
* Emulating relations for some information_schema and data_dictionary tables
*/
- $isInformationSchema = strtolower($db) == 'information_schema';
- $is_data_dictionary = PMA_DRIZZLE && strtolower($db) == 'data_dictionary';
+ $isInformationSchema = /*overload*/mb_strtolower($db) == 'information_schema';
+ $is_data_dictionary = PMA_DRIZZLE
+ && /*overload*/mb_strtolower($db) == 'data_dictionary';
if (($isInformationSchema || $is_data_dictionary)
&& ($source == 'internal' || $source == 'both')
) {
@@ -659,8 +702,9 @@ function PMA_getForeigners($db, $table, $column = '', $source = 'both')
}
if (isset($GLOBALS[$relations_key][$table])) {
foreach ($GLOBALS[$relations_key][$table] as $field => $relations) {
- if ((! strlen($column) || $column == $field)
- && (! isset($foreign[$field]) || ! strlen($foreign[$field]))
+ if ((! /*overload*/mb_strlen($column) || $column == $field)
+ && (! isset($foreign[$field])
+ || ! /*overload*/mb_strlen($foreign[$field]))
) {
$foreign[$field] = $relations;
}
@@ -843,7 +887,7 @@ function PMA_setDbComment($db, $comment = '')
return false;
}
- if (strlen($comment)) {
+ if (/*overload*/mb_strlen($comment)) {
$upd_query = 'INSERT INTO '
. PMA_Util::backquote($cfgRelation['db']) . '.'
. PMA_Util::backquote($cfgRelation['column_info'])
@@ -885,9 +929,10 @@ function PMA_setDbComment($db, $comment = '')
*/
function PMA_setHistory($db, $table, $username, $sqlquery)
{
+ $maxCharactersInDisplayedSQL = $GLOBALS['cfg']['MaxCharactersInDisplayedSQL'];
// Prevent to run this automatically on Footer class destroying in testsuite
if (defined('TESTSUITE')
- || strlen($sqlquery) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']
+ || /*overload*/mb_strlen($sqlquery) > $maxCharactersInDisplayedSQL
) {
return;
}
@@ -898,13 +943,7 @@ function PMA_setHistory($db, $table, $username, $sqlquery)
$_SESSION['sql_history'] = array();
}
- $key = md5($sqlquery . $db . $table);
-
- if (isset($_SESSION['sql_history'][$key])) {
- unset($_SESSION['sql_history'][$key]);
- }
-
- $_SESSION['sql_history'][$key] = array(
+ $_SESSION['sql_history'][] = array(
'db' => $db,
'table' => $table,
'sqlquery' => $sqlquery,
@@ -935,6 +974,9 @@ function PMA_setHistory($db, $table, $username, $sqlquery)
NOW(),
\'' . PMA_Util::sqlAddSlashes($sqlquery) . '\')'
);
+
+ PMA_purgeHistory($username);
+
} // end of 'PMA_setHistory()' function
/**
@@ -950,22 +992,26 @@ function PMA_getHistory($username)
{
$cfgRelation = PMA_getRelationsParam();
+ if (! $cfgRelation['historywork']) {
+ return false;
+ }
+
/**
* if db-based history is disabled but there exists a session-based
* history, use it
*/
- if (! $GLOBALS['cfg']['QueryHistoryDB'] && isset($_SESSION['sql_history'])) {
+ if (! $GLOBALS['cfg']['QueryHistoryDB']) {
+ if (isset($_SESSION['sql_history'])) {
return array_reverse($_SESSION['sql_history']);
- }
-
- if (! $cfgRelation['historywork']) {
+ }
return false;
}
$hist_query = '
SELECT `db`,
`table`,
- `sqlquery`
+ `sqlquery`,
+ `timevalue`
FROM ' . PMA_Util::backquote($cfgRelation['db'])
. '.' . PMA_Util::backquote($cfgRelation['history']) . '
WHERE `username` = \'' . PMA_Util::sqlAddSlashes($username) . '\'
@@ -1007,7 +1053,9 @@ function PMA_purgeHistory($username)
ORDER BY `timevalue` DESC
LIMIT ' . $GLOBALS['cfg']['QueryHistoryMax'] . ', 1';
- if ($max_time = $GLOBALS['dbi']->fetchValue($search_query, 0, 0, $GLOBALS['controllink'])) {
+ if ($max_time = $GLOBALS['dbi']->fetchValue(
+ $search_query, 0, 0, $GLOBALS['controllink']
+ )) {
PMA_queryAsControlUser(
'DELETE FROM '
. PMA_Util::backquote($cfgRelation['db']) . '.'
@@ -1052,14 +1100,16 @@ function PMA_buildForeignDropdown($foreign, $data, $mode)
}
foreach ($foreign as $key => $value) {
- if ($GLOBALS['PMA_String']->strlen($value) <= $GLOBALS['cfg']['LimitChars']
+ if (/*overload*/mb_strlen($value) <= $GLOBALS['cfg']['LimitChars']
) {
$vtitle = '';
$value = htmlspecialchars($value);
} else {
$vtitle = htmlspecialchars($value);
$value = htmlspecialchars(
- substr($value, 0, $GLOBALS['cfg']['LimitChars']) . '...'
+ /*overload*/mb_substr(
+ $value, 0, $GLOBALS['cfg']['LimitChars']
+ ) . '...'
);
}
@@ -1171,11 +1221,11 @@ function PMA_foreignDropdown($disp_row, $foreign_field, $foreign_display, $data,
/**
* Gets foreign keys in preparation for a drop-down selector
*
- * @param array $foreigners array of the foreign keys
- * @param string $field the foreign field name
- * @param bool $override_total whether to override the total
- * @param string $foreign_filter a possible filter
- * @param string $foreign_limit a possible LIMIT clause
+ * @param array|boolean $foreigners array of the foreign keys
+ * @param string $field the foreign field name
+ * @param bool $override_total whether to override the total
+ * @param string $foreign_filter a possible filter
+ * @param string $foreign_limit a possible LIMIT clause
*
* @return array data about the foreign keys
*
@@ -1188,11 +1238,18 @@ function PMA_getForeignData(
// we always show the foreign field in the drop-down; if a display
// field is defined, we show it besides the foreign field
$foreign_link = false;
- if ($foreigners && isset($foreigners[$field])) {
- $foreigner = $foreigners[$field];
- $foreign_db = $foreigner['foreign_db'];
- $foreign_table = $foreigner['foreign_table'];
- $foreign_field = $foreigner['foreign_field'];
+ do {
+ if (! $foreigners) {
+ break;
+ }
+ $foreigner = PMA_searchColumnInForeigners($foreigners, $field);
+ if ($foreigner != false) {
+ $foreign_db = $foreigner['foreign_db'];
+ $foreign_table = $foreigner['foreign_table'];
+ $foreign_field = $foreigner['foreign_field'];
+ } else {
+ break;
+ }
// Count number of rows in the foreign table. Currently we do
// not use a drop-down if more than ForeignKeyMaxLimit rows in the
@@ -1234,18 +1291,15 @@ function PMA_getForeignData(
$f_query_limit = isset($foreign_limit) ? $foreign_limit : '';
if (!empty($foreign_filter)) {
- $res = $GLOBALS['dbi']->query(
+ $the_total = $GLOBALS['dbi']->fetchValue(
'SELECT COUNT(*)' . $f_query_from . $f_query_filter
);
- if ($res) {
- $the_total = $GLOBALS['dbi']->fetchValue($res);
- @$GLOBALS['dbi']->freeResult($res);
- } else {
+ if ($the_total === false) {
$the_total = 0;
}
}
- $disp = $GLOBALS['dbi']->query(
+ $disp = $GLOBALS['dbi']->tryQuery(
$f_query_main . $f_query_from . $f_query_filter
. $f_query_order . $f_query_limit
);
@@ -1259,12 +1313,18 @@ function PMA_getForeignData(
$disp_row[] = $single_disp_row;
}
@$GLOBALS['dbi']->freeResult($disp);
+ } else {
+ // Either no data in the foreign table or
+ // user does not have select permission to foreign table/field
+ // Show an input field with a 'Browse foreign values' link
+ $disp_row = null;
+ $foreign_link = true;
}
} else {
$disp_row = null;
$foreign_link = true;
}
- } // end if $foreigners
+ } while (false);
$foreignData = array();
$foreignData['foreign_link'] = $foreign_link;
@@ -1289,16 +1349,18 @@ function PMA_getForeignData(
function PMA_getRelatives($all_tables, $master)
{
$fromclause = '';
+ $left_joins = array();
$emerg = '';
+ $ignore_internal_relations = false;
// The list of tables that we still couldn't connect
$remaining_tables = $all_tables;
unset($remaining_tables[$master]);
- // The list of allready connected tables
+ // The list of already connected tables
$known_tables = array();
$known_tables[$master] = $master;
$run = 0;
- while (count($remaining_tables) > 0) {
+ while ($GLOBALS['cfgRelation']['relwork'] && count($remaining_tables) > 0) {
// Whether to go from master to foreign or vice versa
if ($run % 2 == 0) {
$from = 'master';
@@ -1322,14 +1384,18 @@ function PMA_getRelatives($all_tables, $master)
while ($row = $GLOBALS['dbi']->fetchAssoc($relations)) {
$found_table = $row[$to . '_table'];
if (isset($remaining_tables[$found_table])) {
- $fromclause
- .= "\n" . ' LEFT JOIN '
- . PMA_Util::backquote($GLOBALS['db']) . '.'
- . PMA_Util::backquote($row[$to . '_table']) . ' ON '
- . PMA_Util::backquote($row[$from . '_table']) . '.'
+ $left_join_with = PMA_Util::backquote($GLOBALS['db']) . '.'
+ . PMA_Util::backquote($row[$to . '_table']);
+ $on_condition = PMA_Util::backquote($row[$from . '_table']) . '.'
. PMA_Util::backquote($row[$from . '_field']) . ' = '
. PMA_Util::backquote($row[$to . '_table']) . '.'
- . PMA_Util::backquote($row[$to . '_field']) . ' ';
+ . PMA_Util::backquote($row[$to . '_field']);
+
+ $left_joins[$left_join_with] = array(
+ 'left_join_with' => $left_join_with,
+ 'on_condition' => array($on_condition)
+ );
+
$known_tables[$found_table] = $found_table;
unset($remaining_tables[$found_table]);
}
@@ -1342,6 +1408,55 @@ function PMA_getRelatives($all_tables, $master)
}
}
} // end while
+
+ // Generate 'LEFT JOIN's for InnoDB foreign keys.
+ $remaining_tables = $all_tables;
+ foreach ($remaining_tables as $one_table) {
+ $foreigners = PMA_getForeigners($GLOBALS['db'], $one_table, '', 'foreign');
+ foreach ($foreigners['foreign_keys_data'] as $one_key) {
+ if (in_array($one_key['ref_table_name'], $all_tables)
+ && ! isset($one_key['ref_db_name'])
+ && ($one_key['ref_table_name'] == $master
+ || $one_key['ref_table_name'] == $one_table)
+ ) {
+ $left_join_with = PMA_Util::backquote($GLOBALS['db']) . '.'
+ . PMA_Util::backquote($one_table);
+ if (! isset($left_joins[$left_join_with])) {
+ $left_joins[$left_join_with] = array(
+ 'left_join_with' =>$left_join_with,
+ 'on_condition' => array()
+ );
+ }
+
+ foreach ($one_key['ref_index_list'] as $key => $one_column) {
+ $on_condition = PMA_Util::backquote($one_key['ref_table_name'])
+ . '.' . PMA_Util::backquote($one_column) . ' = '
+ . PMA_Util::backquote($one_table) . '.'
+ . PMA_Util::backquote($one_key['index_list'][$key]);
+
+ if (! in_array($on_condition, $left_joins[$left_join_with]['on_condition'])) {
+ $left_joins[$left_join_with]['on_condition'][]
+ = $on_condition;
+ }
+ }
+ $ignore_internal_relations = true;
+ unset($remaining_tables[$one_table]);
+ }
+ }
+ }
+
+ if ($ignore_internal_relations) {
+ $emerg = '';
+ }
+
+ // Build the 'FROM' clause.
+ foreach ($left_joins as $one_join) {
+ $fromclause .= "\n" . ' LEFT JOIN '
+ . $one_join['left_join_with']
+ . ' ON '
+ . implode(' AND ', $one_join['on_condition']);
+ }
+
$fromclause = $emerg . $fromclause;
return $fromclause;
} // end of the "PMA_getRelatives()" function
@@ -1495,15 +1610,6 @@ function PMA_REL_renameTable($source_db, $target_db, $source_table, $target_tabl
'db_name', 'table_name'
);
}
-
- if ($GLOBALS['cfgRelation']['designerwork']) {
- PMA_REL_renameSingleTable(
- 'designer_coords',
- $source_db, $target_db,
- $source_table, $target_table,
- 'db_name', 'table_name'
- );
- }
}
/**
@@ -1536,6 +1642,7 @@ function PMA_REL_createPage($newpage, $cfgRelation, $db)
/**
* Get child table references for a table column.
+ * This works only if 'DisableIS' is false. An empty array is returned otherwise.
*
* @param string $db name of master table db.
* @param string $table name of master table.
@@ -1543,26 +1650,26 @@ function PMA_REL_createPage($newpage, $cfgRelation, $db)
*
* @return array $child_references
*/
-function PMA_getChildReferences($db, $table, $column)
+function PMA_getChildReferences($db, $table, $column = '')
{
$child_references = array();
- $i=0;
- $rel_query = 'SELECT `column_name`,'
- . ' `table_name`,'
- . '`table_schema`'
- . ' FROM `information_schema`.`key_column_usage`'
- . ' WHERE `referenced_column_name` = \''
- . PMA_Util::sqlAddSlashes($column) . '\''
- . ' AND `referenced_table_name` = \''
- . PMA_Util::sqlAddSlashes($table) . '\''
- . ' AND `referenced_table_schema` = \''
- . PMA_Util::sqlAddSlashes($db) . '\'';
-
- $result = $GLOBALS['dbi']->tryQuery($rel_query, $GLOBALS['controllink']);
- if ($result == true) {
- while (($row = $GLOBALS['dbi']->fetchAssoc($result))) {
- $child_references[$i++] = $row;
+ if (! $GLOBALS['cfg']['Server']['DisableIS']) {
+ $rel_query = "SELECT `column_name`, `table_name`,"
+ . " `table_schema`, `referenced_column_name`"
+ . " FROM `information_schema`.`key_column_usage`"
+ . " WHERE `referenced_table_name` = '"
+ . PMA_Util::sqlAddSlashes($table) . "'"
+ . " AND `referenced_table_schema` = '"
+ . PMA_Util::sqlAddSlashes($db) . "'";
+ if ($column) {
+ $rel_query .= " AND `referenced_column_name` = '"
+ . PMA_Util::sqlAddSlashes($column) . "'";
}
+
+ $child_references = $GLOBALS['dbi']->fetchResult(
+ $rel_query, array('referenced_column_name', null),
+ null, $GLOBALS['controllink']
+ );
}
return $child_references;
}
@@ -1570,24 +1677,47 @@ function PMA_getChildReferences($db, $table, $column)
/**
* Check child table references and foreign key for a table column.
*
- * @param string $db name of master table db.
- * @param string $table name of master table.
- * @param string $column name of master table column.
+ * @param string $db name of master table db.
+ * @param string $table name of master table.
+ * @param string $column name of master table column.
+ * @param array $foreigners_full foreiners array for the whole table.
+ * @param array $child_references_full child references for the whole table.
*
* @return array $column_status telling about references if foreign key.
*/
-function PMA_checkChildForeignReferences($db, $table, $column)
-{
+function PMA_checkChildForeignReferences(
+ $db, $table, $column, $foreigners_full = null, $child_references_full = null
+) {
$column_status = array();
$column_status['isEditable'] = false;
$column_status['isReferenced'] = false;
$column_status['isForeignKey'] = false;
$column_status['references'] = array();
- $foreigners = PMA_getForeigners($db, $table, $column);
- $child_references = PMA_getChildReferences($db, $table, $column);
+
+ $foreigners = array();
+ if ($foreigners_full !== null) {
+ if (isset($foreigners_full[$column])) {
+ $foreigners[$column] = $foreigners_full[$column];
+ }
+ if (isset($foreigners_full['foreign_keys_data'])) {
+ $foreigners['foreign_keys_data'] = $foreigners_full['foreign_keys_data'];
+ }
+ } else {
+ $foreigners = PMA_getForeigners($db, $table, $column, 'foreign');
+ }
+ $foreigner = PMA_searchColumnInForeigners($foreigners, $column);
+
+ $child_references = array();
+ if ($child_references_full !== null) {
+ if (isset($child_references_full[$column])) {
+ $child_references = $child_references_full[$column];
+ }
+ } else {
+ $child_references = PMA_getChildReferences($db, $table, $column);
+ }
if (sizeof($child_references, 0) > 0
- || (! empty($foreigners[$column]) && sizeof($foreigners[$column], 0) > 0)
+ || $foreigner
) {
if (sizeof($child_references, 0) > 0) {
$column_status['isReferenced'] = true;
@@ -1600,7 +1730,7 @@ function PMA_checkChildForeignReferences($db, $table, $column)
}
}
- if (!empty($foreigners[$column]) && sizeof($foreigners[$column], 0) > 0) {
+ if ($foreigner) {
$column_status['isForeignKey'] = true;
}
} else {
@@ -1609,4 +1739,217 @@ function PMA_checkChildForeignReferences($db, $table, $column)
return $column_status;
}
+
+/**
+ * Search a table column in foreign data.
+ *
+ * @param array $foreigners Table Foreign data
+ * @param string $column Column name
+ *
+ * @return bool|array
+ */
+function PMA_searchColumnInForeigners($foreigners, $column)
+{
+ if (isset($foreigners[$column])) {
+ return $foreigners[$column];
+ } else {
+ $foreigner = array();
+ foreach ($foreigners['foreign_keys_data'] as $key => $one_key) {
+ $column_index = array_search($column, $one_key['index_list']);
+ if ($column_index !== false) {
+ $foreigner['foreign_field']
+ = $one_key['ref_index_list'][$column_index];
+ $foreigner['foreign_db'] = isset($one_key['ref_db_name'])
+ ? $one_key['ref_db_name']
+ : $GLOBALS['db'];
+ $foreigner['foreign_table'] = $one_key['ref_table_name'];
+ $foreigner['constraint'] = $one_key['constraint'];
+
+ return $foreigner;
+ }
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Searches a DB for the existence of PMA tables.
+ *
+ * @param string $db Database
+ * @param array $tables Default table names
+ *
+ * @return bool
+ */
+function PMA_searchPMATablesInDb($db, $tables)
+{
+ $tab_rs = $GLOBALS['dbi']->getTables($db);
+
+ if ($tab_rs === false) {
+ return false;
+ }
+
+ foreach ($tab_rs as $curr_table) {
+ if (in_array($curr_table, $tables)) {
+ $tables = array_diff($tables, array($curr_table));
+ }
+ }
+
+ if (count($tables) != 0) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Returns default PMA table names and their create queries.
+ *
+ * @return array table name, create query
+ */
+function PMA_getDefaultPMATableNames()
+{
+ $pma_tables = array();
+ if (PMA_DRIZZLE) {
+ $create_tables_file = file_get_contents(
+ EXAMPLES_DIR. 'create_tables_drizzle.sql'
+ );
+ } else {
+ $create_tables_file = file_get_contents(
+ EXAMPLES_DIR. 'create_tables.sql'
+ );
+ }
+
+ $queries = explode(';', $create_tables_file);
+
+ foreach ($queries as $query) {
+ if (preg_match(
+ '/CREATE TABLE IF NOT EXISTS `(.*)` \(/',
+ $query,
+ $table
+ )
+ ) {
+ $pma_tables[$table[1]] = $query . ';';
+ }
+ }
+
+ return $pma_tables;
+}
+
+/**
+ * Creates PMA tables in the given db, updates if already exists.
+ *
+ * @param string $db Database
+ *
+ * @return void
+ */
+function PMA_fixPMATables($db)
+{
+ $default_tables = PMA_getDefaultPMATableNames();
+ $GLOBALS['dbi']->selectDb($db);
+
+ foreach ($default_tables as $table => $create_query) {
+ $GLOBALS['dbi']->tryQuery($create_query);
+
+ if ($error = $GLOBALS['dbi']->getError()) {
+ $GLOBALS['message'] = $error;
+ break;
+ }
+
+ if ($table == 'pma__bookmark') {
+ $GLOBALS['cfg']['Server']['bookmarktable'] = $table;
+ } elseif ($table == 'pma__relation') {
+ $GLOBALS['cfg']['Server']['relation'] = $table;
+ } elseif ($table == 'pma__table_info') {
+ $GLOBALS['cfg']['Server']['table_info'] = $table;
+ } elseif ($table == 'pma__table_coords') {
+ $GLOBALS['cfg']['Server']['table_coords'] = $table;
+ } elseif ($table == 'pma__column_info') {
+ $GLOBALS['cfg']['Server']['column_info'] = $table;
+ } elseif ($table == 'pma__pdf_pages') {
+ $GLOBALS['cfg']['Server']['pdf_pages'] = $table;
+ } elseif ($table == 'pma__history') {
+ $GLOBALS['cfg']['Server']['history'] = $table;
+ } elseif ($table == 'pma__recent') {
+ $GLOBALS['cfg']['Server']['recent'] = $table;
+ } elseif ($table == 'pma__table_uiprefs') {
+ $GLOBALS['cfg']['Server']['table_uiprefs'] = $table;
+ } elseif ($table == 'pma__tracking') {
+ $GLOBALS['cfg']['Server']['tracking'] = $table;
+ } elseif ($table == 'pma__userconfig') {
+ $GLOBALS['cfg']['Server']['userconfig'] = $table;
+ } elseif ($table == 'pma__users') {
+ $GLOBALS['cfg']['Server']['users'] = $table;
+ } elseif ($table == 'pma__usergroups') {
+ $GLOBALS['cfg']['Server']['usergroups'] = $table;
+ } elseif ($table == 'pma__navigationhiding') {
+ $GLOBALS['cfg']['Server']['navigationhiding'] = $table;
+ } elseif ($table == 'pma__savedsearches') {
+ $GLOBALS['cfg']['Server']['savedsearches'] = $table;
+ } elseif ($table == 'pma__central_columns') {
+ $GLOBALS['cfg']['Server']['central_columns'] = $table;
+ } else if ($table == 'pma__designer_coords') {
+ $GLOBALS['cfg']['Server']['designer_coords'] = $table;
+ }
+ }
+ $GLOBALS['cfg']['Server']['pmadb'] = $db;
+ $_SESSION['relation'][$GLOBALS['server']] = PMA_checkRelationsParam();
+}
+
+/**
+ * Get Html for PMA tables fixing anchor.
+ *
+ * @return string Html
+ */
+function PMA_getHtmlFixPMATables()
+{
+ $retval = '';
+
+ $url_query = PMA_URL_getCommon(array('db' => $GLOBALS['db']));
+ $url_query .= '&amp;goto=db_operations.php&amp;fix_pmadb=1';
+ $message = PMA_Message::notice(
+ __(
+ '%sCreate%s the phpMyAdmin configuration storage in the '
+ . 'current database.'
+ )
+ );
+ $message->addParam(
+ '<a href="' . $GLOBALS['cfg']['PmaAbsoluteUri']
+ . 'chk_rel.php' . $url_query . '">',
+ false
+ );
+ $message->addParam('</a>', false);
+
+ $retval .= $message->getDisplay();
+
+ return $retval;
+}
+
+/**
+ * Gets the relations info and status, depending on the condition
+ *
+ * @param boolean $condition whether to look for foreigners or not
+ * @param string $db database name
+ * @param string $table table name
+ *
+ * @return array ($res_rel, $have_rel)
+ */
+function PMA_getRelationsAndStatus($condition, $db, $table)
+{
+ if ($condition) {
+ // Find which tables are related with the current one and write it in
+ // an array
+ $res_rel = PMA_getForeigners($db, $table);
+
+ if (count($res_rel) > 0) {
+ $have_rel = true;
+ } else {
+ $have_rel = false;
+ }
+ } else {
+ $have_rel = false;
+ $res_rel = array();
+ } // end if
+ return(array($res_rel, $have_rel));
+}
?>