Merge pull request #438 from kasunchathuranga/relView

Relational view interface improvements
This commit is contained in:
Isaac Bennetch 2013-06-26 08:45:54 -07:00
commit 45b0820234
8 changed files with 369 additions and 168 deletions

View File

@ -881,8 +881,7 @@ TableSeparator or disabling that feature.
3.6 What is currently not supported in phpMyAdmin about InnoDB?
---------------------------------------------------------------
In Relation view, being able to choose a table in another database, or
having more than one index column in the foreign key. In Query-by-
In Relation view, having more than one index column in the foreign key. In Query-by-
example (Query), automatic generation of the query LEFT JOIN from the
foreign table.
@ -1378,7 +1377,7 @@ look for the word "upload" in this document.
---------------------------------------------------------
Here is an example with the tables persons, towns and countries, all
located in the database mydb. If you don't have a ``pma__relation``
located in the database "mydb". If you don't have a ``pma__relation``
table, create it as explained in the configuration section. Then
create the example tables:
@ -1416,8 +1415,10 @@ create the example tables:
To setup appropriate links and display information:
* on table "REL\_persons" click Structure, then Relation view
* in Links, for "town\_code" choose "REL\_towns->code"
* in Links, for "country\_code" choose "REL\_countries->country\_code"
* for "town\_code", choose from dropdowns, "mydb", "REL\_towns", "code"
for foreign database, table and column respectively
* for "country\_code", choose from dropdowns, "mydb", "REL\_countries",
"country\_code" for foreign database, table and column respectively
* on table "REL\_towns" click Structure, then Relation view
* in "Choose column to display", choose "description"
* repeat the two previous steps for table "REL\_countries"

View File

@ -5,30 +5,123 @@
*/
function show_hide_clauses($thisDropdown)
{
// here, one span contains the label and the clause dropdown
// and we have one span for ON DELETE and one for ON UPDATE
//
if ($thisDropdown.val() !== '') {
$thisDropdown.parent().nextAll('span').show();
} else {
if ($thisDropdown.val() == '') {
$thisDropdown.parent().nextAll('span').hide();
} else {
if ($thisDropdown.is('select[name^="destination_foreign_column"]')) {
$thisDropdown.parent().nextAll('span').show();
}
}
}
/**
* Retrieves and populates dropdowns to the left based on the selected value
*
* @param $dropdown the dropdown whose value got changed
*/
function getDropdownValues($dropdown) {
var foreignDb = null, foreignTable = null;
var $tableDd, $columnDd;
var foreign = '';
// if the changed dropdown is for foreign key constraints
if ($dropdown.is('select[name^="destination_foreign"]')) {
$tableDd = $dropdown.parent().find('select[name^="destination_foreign_table"]');
$columnDd = $dropdown.parent().find('select[name^="destination_foreign_column"]');
foreign = '_foreign';
} else { // internal relations
$tableDd = $dropdown.parent().find('select[name^="destination_table"]');
$columnDd = $dropdown.parent().find('select[name^="destination_column"]');
}
// if the changed dropdown is a database selector
if ($dropdown.is('select[name^="destination' + foreign + '_db"]')) {
foreignDb = $dropdown.val();
// if no database is selected empty table and column dropdowns
if (foreignDb == '') {
setDropdownValues($tableDd, []);
setDropdownValues($columnDd, []);
return;
}
} else { // if a table selector
foreignDb = $dropdown.parent()
.find('select[name^="destination' + foreign + '_db"]').val();
foreignTable = $dropdown.val();
// if no table is selected empty the column dropdown
if (foreignTable == '') {
setDropdownValues($columnDd, []);
return;
}
}
var $msgbox = PMA_ajaxShowMessage();
var $form = $dropdown.parents('form');
var url = 'tbl_relation.php?getDropdownValues=true&ajax_request=true'
+ '&token=' + $form.find('input[name="token"]').val()
+ '&db=' + $form.find('input[name="db"]').val()
+ '&table=' + $form.find('input[name="table"]').val()
+ '&foreign=' + (foreign != '')
+ '&foreignDb=' + encodeURIComponent(foreignDb)
+ (foreignTable !== null ?
'&foreignTable=' + encodeURIComponent(foreignTable) : ''
);
$.ajax({
url: url,
datatype: 'json',
success: function(data) {
PMA_ajaxRemoveMessage($msgbox);
if (data.success) {
// if the changed dropdown is a database selector
if (foreignTable == null) {
// set values for table and column dropdowns
setDropdownValues($tableDd, data.tables);
setDropdownValues($columnDd, []);
} else { // if a table selector
// set values for the column dropdown
setDropdownValues($columnDd, data.columns);
}
} else {
PMA_ajaxShowMessage(data.error, false);
}
}
});
}
function setDropdownValues($dropdown, values) {
$dropdown.empty();
var optionsAsString = '';
// add an empty string to the beginning for empty selection
values.unshift('');
$.each(values, function() {
optionsAsString += "<option value='" + this + "'>" + this + "</option>";
})
$dropdown.append($(optionsAsString));
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('tbl_relation.js', function () {
$('select.referenced_column_dropdown').unbind('change');
$('select[name^="destination_foreign"]').unbind('change');
$('select[name^="destination_db"],'
+ ' select[name^="destination_table"],'
+ ' select[name^="destination_foreign_db"],'
+ ' select[name^="destination_foreign_table"]').unbind('change');
});
AJAX.registerOnload('tbl_relation.js', function () {
// initial display
$('select.referenced_column_dropdown').each(function (index, one_dropdown) {
$('select[name^="destination_foreign_column"]').each(function (index, one_dropdown) {
show_hide_clauses($(one_dropdown));
});
// change
$('select.referenced_column_dropdown').change(function () {
$('select[name^="destination_foreign"]').change(function () {
show_hide_clauses($(this));
});
$('select[name^="destination_db"],'
+ ' select[name^="destination_table"],'
+ ' select[name^="destination_foreign_db"],'
+ ' select[name^="destination_foreign_table"]')
.change(function() {
getDropdownValues($(this));
});
});

View File

@ -1314,10 +1314,11 @@ class PMA_Table
* - UNIQUE(x,y) // NONE
*
* @param bool $backquoted whether to quote name with backticks ``
* @param bool $fullName whether to include full name of the table as a prefix
*
* @return array
*/
public function getUniqueColumns($backquoted = true)
public function getUniqueColumns($backquoted = true, $fullName = true)
{
$sql = $GLOBALS['dbi']->getTableIndexesSql(
$this->getDbName(),
@ -1335,7 +1336,7 @@ class PMA_Table
if (count($index) > 1) {
continue;
}
$return[] = $this->getFullName($backquoted) . '.'
$return[] = ($fullName ? $this->getFullName($backquoted) . '.' : '')
. ($backquoted ? PMA_Util::backquote($index[0]) : $index[0]);
}

View File

@ -1427,8 +1427,8 @@ function PMA_getHtmlForReferentialIntegrityCheck($foreign, $url_params)
. '<a href="sql.php'
. PMA_generate_common_url($this_url_params)
. '">'
. $master . '&nbsp;->&nbsp;' . $arr['foreign_table'] . '.'
. $arr['foreign_field']
. $master . '&nbsp;->&nbsp;' . $arr['foreign_db'] . '.'
. $arr['foreign_table'] . '.' . $arr['foreign_field']
. '</a></li>' . "\n";
} // foreach $foreign
$html_output .= '</ul></fieldset></div>';

View File

@ -88,9 +88,9 @@ function PMA_getSQLToDropForeignKey($table, $fk)
*
* @param string $table table name
* @param string $field field name
* @param string $foreignDb back-quoted foreign database name
* @param string $foreignTable back-quoted foreign table name
* @param string $foreignField back-quoted foreign field name
* @param string $foreignDb foreign database name
* @param string $foreignTable foreign table name
* @param string $foreignField foreign field name
* @param string $name name of the constraint
* @param string $onDelete on delete action
* @param string $onUpdate on update action
@ -107,8 +107,9 @@ function PMA_getSQLToCreateForeignKey($table, $field, $foreignDb, $foreignTable,
}
$sql_query .= ' FOREIGN KEY (' . PMA_Util::backquote($field) . ')'
. ' REFERENCES ' . $foreignDb . '.' . $foreignTable
. '(' . $foreignField . ')';
. ' REFERENCES ' . PMA_Util::backquote($foreignDb)
. '.' . PMA_Util::backquote($foreignTable)
. '(' . PMA_Util::backquote($foreignField) . ')';
if (! empty($onDelete)) {
$sql_query .= ' ON DELETE ' . $onDelete;
@ -120,4 +121,36 @@ function PMA_getSQLToCreateForeignKey($table, $field, $foreignDb, $foreignTable,
return $sql_query;
}
/**
* Creates and populates dropdowns to select foreign db/table/column
*
* @param string $name name of the dropdowns
* @param array $values dropdown values
* @param string $foreign value of the item to be selected
*
* @return string HTML for the dropdown
*/
function PMA_generateRelationalDropdown($name, $values = array(), $foreign = false)
{
$html_output = '<select name="' . $name . '">';
$html_output .= '<option value=""></option>';
$seen_key = false;
foreach ($values as $value) {
$html_output .= '<option value="' . htmlspecialchars($value) . '"';
if ($foreign && $value == $foreign) {
$html_output .= ' selected="selected"';
$seen_key = true;
}
$html_output .= '>' . htmlspecialchars($value) . '</option>';
}
if ($foreign && ! $seen_key) {
$html_output .= '<option value="' . htmlspecialchars($foreign) . '"'
. ' selected="selected">' . htmlspecialchars($foreign) . '</option>';
}
$html_output .= '</select>';
return $html_output;
}
?>

View File

@ -9,8 +9,6 @@
* for internal relations (but foreign keys relations are correct)
* @todo foreign key constraints require both fields being of equal type and size
* @todo check foreign fields to be from same type and size, all other makes no sense
* @todo add an link to create an index required for constraints,
* or an option to do automatically
* @todo if above todos are fullfilled we can add all fields meet requirements
* in the select dropdown
* @package PhpMyAdmin
@ -24,6 +22,59 @@ require_once 'libraries/index.lib.php';
require_once 'libraries/tbl_relation.lib.php';
$response = PMA_Response::getInstance();
// Send table of column names to populate corresponding dropdowns depending
// on the current selection
if (isset($_REQUEST['getDropdownValues'])
&& $_REQUEST['getDropdownValues'] === 'true'
) {
$foreignDb = $_REQUEST['foreignDb'];
if (isset($_REQUEST['foreignTable'])) { // if both db and table are selected
$foreignTable = $_REQUEST['foreignTable'];
$table_obj = new PMA_Table($foreignTable, $foreignDb);
$columns = array();
foreach ($table_obj->getUniqueColumns(false, false) as $column) {
$columns[] = htmlspecialchars($column);
}
$response->addJSON('columns', $columns);
} else { // if only the db is selected
$foreign = isset($_REQUEST['foreign']) && $_REQUEST['foreign'] === 'true';
if ($foreign) {
$query = 'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($foreignDb);
$tbl_storage_engine = strtoupper(
PMA_Table::sGetStatusInfo(
$_REQUEST['db'],
$_REQUEST['table'],
'Engine'
)
);
} else {
$query = 'SHOW TABLES FROM ' . PMA_Util::backquote($foreignDb);
}
$tables_rs = $GLOBALS['dbi']->query(
$query,
null,
PMA_DatabaseInterface::QUERY_STORE
);
$tables = array();
while ($row = $GLOBALS['dbi']->fetchRow($tables_rs)) {
if ($foreign) {
if (isset($row[1])
&& strtoupper($row[1]) == $tbl_storage_engine
) {
$tables[] = htmlspecialchars($row[0]);
}
} else {
$tables[] = htmlspecialchars($row[0]);
}
}
$response->addJSON('tables', $tables);
}
exit;
}
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('tbl_relation.js');
@ -33,8 +84,12 @@ $scripts->addFile('indexes.js');
* Sets globals from $_POST
*/
$post_params = array(
'destination',
'destination_foreign',
'destination_db',
'destination_table',
'destination_column',
'destination_foreign_db',
'destination_foreign_table',
'destination_foreign_column',
'display_field',
'fields_name',
'on_delete',
@ -85,18 +140,20 @@ $multi_edit_columns_name = isset($_REQUEST['fields_name'])
$html_output = '';
// u p d a t e s f o r I n t e r n a l r e l a t i o n s
if (isset($destination) && $cfgRelation['relwork']) {
if (isset($destination_db) && $cfgRelation['relwork']) {
foreach ($destination as $master_field_md5 => $foreign_string) {
foreach ($destination_db as $master_field_md5 => $foreign_db) {
$upd_query = false;
// Map the fieldname's md5 back to its real name
$master_field = $multi_edit_columns_name[$master_field_md5];
if (! empty($foreign_string)) {
$foreign_string = trim($foreign_string, '`');
list($foreign_db, $foreign_table, $foreign_field)
= explode('.', $foreign_string);
$foreign_table = $destination_table[$master_field_md5];
$foreign_field = $destination_column[$master_field_md5];
if (! empty($foreign_db)
&& ! empty($foreign_table)
&& ! empty($foreign_field)
) {
if (! isset($existrel[$master_field])) {
$upd_query = 'INSERT INTO '
. PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
@ -110,7 +167,11 @@ if (isset($destination) && $cfgRelation['relwork']) {
. '\'' . PMA_Util::sqlAddSlashes($foreign_db) . '\', '
. '\'' . PMA_Util::sqlAddSlashes($foreign_table) . '\','
. '\'' . PMA_Util::sqlAddSlashes($foreign_field) . '\')';
} elseif ($existrel[$master_field]['foreign_db'] . '.' .$existrel[$master_field]['foreign_table'] . '.' . $existrel[$master_field]['foreign_field'] != $foreign_string) {
} elseif ($existrel[$master_field]['foreign_db'] != $foreign_db
|| $existrel[$master_field]['foreign_table'] != $foreign_table
|| $existrel[$master_field]['foreign_field'] != $foreign_field
) {
$upd_query = 'UPDATE '
. PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
. '.' . PMA_Util::backquote($cfgRelation['relation']) . ' SET'
@ -120,7 +181,8 @@ if (isset($destination) && $cfgRelation['relwork']) {
. PMA_Util::sqlAddSlashes($foreign_table) . '\', '
. ' foreign_field = \''
. PMA_Util::sqlAddSlashes($foreign_field) . '\' '
. ' WHERE master_db = \'' . PMA_Util::sqlAddSlashes($db) . '\''
. ' WHERE master_db = \''
. PMA_Util::sqlAddSlashes($db) . '\''
. ' AND master_table = \''
. PMA_Util::sqlAddSlashes($table) . '\''
. ' AND master_field = \''
@ -145,25 +207,28 @@ if (isset($destination) && $cfgRelation['relwork']) {
// (for now, one index name only; we keep the definitions if the
// foreign db is not the same)
if (isset($_REQUEST['destination_foreign'])) {
if (isset($destination_foreign_db)) {
$display_query = '';
$seen_error = false;
foreach ($_REQUEST['destination_foreign'] as $master_field_md5 => $foreign_string) {
foreach ($destination_foreign_db as $master_field_md5 => $foreign_db) {
$create = false;
$drop = false;
// Map the fieldname's md5 back to it's real name
$master_field = $multi_edit_columns_name[$master_field_md5];
if (! empty($foreign_string)) {
list($foreign_db, $foreign_table, $foreign_field)
= PMA_backquoteSplit($foreign_string);
$foreign_table = $destination_foreign_table[$master_field_md5];
$foreign_field = $destination_foreign_column[$master_field_md5];
if (! empty($foreign_db)
&& ! empty($foreign_table)
&& ! empty($foreign_field)
) {
if (! isset($existrel_foreign[$master_field])) {
// no key defined for this field
$create = true;
} elseif (PMA_Util::backquote($existrel_foreign[$master_field]['foreign_db']) != $foreign_db
|| PMA_Util::backquote($existrel_foreign[$master_field]['foreign_table']) != $foreign_table
|| PMA_Util::backquote($existrel_foreign[$master_field]['foreign_field']) != $foreign_field
} elseif ($existrel_foreign[$master_field]['foreign_db'] != $foreign_db
|| $existrel_foreign[$master_field]['foreign_table'] != $foreign_table
|| $existrel_foreign[$master_field]['foreign_field'] != $foreign_field
|| $_REQUEST['constraint_name'][$master_field_md5] != $existrel_foreign[$master_field]['constraint']
|| ($_REQUEST['on_delete'][$master_field_md5] != (! empty($existrel_foreign[$master_field]['on_delete']) ? $existrel_foreign[$master_field]['on_delete'] : 'RESTRICT'))
|| ($_REQUEST['on_update'][$master_field_md5] != (! empty($existrel_foreign[$master_field]['on_update']) ? $existrel_foreign[$master_field]['on_update'] : 'RESTRICT'))
@ -233,10 +298,11 @@ if (isset($_REQUEST['destination_foreign'])) {
// a rollback may be better here
$sql_query_recreate = '# Restoring the dropped constraint...' . "\n";
$sql_query_recreate .= PMA_getSQLToCreateForeignKey(
$table, $master_field,
PMA_Util::backquote($existrel_foreign[$master_field]['foreign_db']),
PMA_Util::backquote($existrel_foreign[$master_field]['foreign_table']),
PMA_Util::backquote($existrel_foreign[$master_field]['foreign_field']),
$table,
$master_field,
$existrel_foreign[$master_field]['foreign_db'],
$existrel_foreign[$master_field]['foreign_table'],
$existrel_foreign[$master_field]['foreign_field'],
$existrel_foreign[$master_field]['constraint'],
$options_array[$existrel_foreign[$master_field]['on_delete']],
$options_array[$existrel_foreign[$master_field]['on_update']]
@ -291,10 +357,10 @@ if ($cfgRelation['displaywork'] && isset($display_field)) {
} // end if
// If we did an update, refresh our data
if (isset($destination) && $cfgRelation['relwork']) {
if (isset($destination_db) && $cfgRelation['relwork']) {
$existrel = PMA_getForeigners($db, $table, '', 'internal');
}
if (isset($destination_foreign)
if (isset($destination_foreign_db)
&& PMA_Util::isForeignKeySupported($tbl_storage_engine)
) {
$existrel_foreign = PMA_getForeigners($db, $table, '', 'foreign');
@ -313,57 +379,6 @@ if ($cfgRelation['displaywork']) {
$html_output .= '<form method="post" action="tbl_relation.php">' . "\n"
. PMA_generate_common_hidden_inputs($db, $table);
// relations
if ($cfgRelation['relwork']
|| PMA_Util::isForeignKeySupported($tbl_storage_engine)
) {
// To choose relations we first need all tables names in current db
// and if the main table supports foreign keys
// we use SHOW TABLE STATUS because we need to find other tables of the
// same engine.
if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
$tab_query = 'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db);
// [0] of the row is the name
// [1] is the type
} else {
$tab_query = 'SHOW TABLES FROM ' . PMA_Util::backquote($db);
// [0] of the row is the name
}
$tab_rs = $GLOBALS['dbi']->query(
$tab_query, null, PMA_DatabaseInterface::QUERY_STORE
);
$selectboxall[] = '';
$selectboxall_foreign[] = '';
while ($curr_table = $GLOBALS['dbi']->fetchRow($tab_rs)) {
$current_table = new PMA_Table($curr_table[0], $db);
// explicitely ask for non-quoted list of indexed columns
$selectboxall = array_merge(
$selectboxall,
$current_table->getUniqueColumns($backquoted = false)
);
// if foreign keys are supported, collect all keys from other
// tables of the same engine
if (PMA_Util::isForeignKeySupported($tbl_storage_engine)
&& isset($curr_table[1])
&& strtoupper($curr_table[1]) == $tbl_storage_engine
) {
// explicitely ask for non-quoted list of indexed columns
// need to obtain backquoted values to support dots inside values
$selectboxall_foreign = array_merge(
$selectboxall_foreign,
$current_table->getIndexedColumns($backquoted = true)
);
}
} // end while over tables
} // end if
// Now find out the columns of our $table
// need to use PMA_DatabaseInterface::QUERY_STORE with $GLOBALS['dbi']->numRows() in mysqli
$columns = $GLOBALS['dbi']->getColumns($db, $table);
@ -377,7 +392,7 @@ if (count($columns) > 0) {
$saved_row_cnt = count($save_row);
$html_output .= '<fieldset>'
. '<legend>' . __('Relations'). '</legend>'
. '<table>'
. '<table id="relationalTable">'
. '<tr><th>' . __('Column') . '</th>';
if ($cfgRelation['relwork']) {
@ -418,84 +433,133 @@ if (count($columns) > 0) {
$odd_row = ! $odd_row;
if ($cfgRelation['relwork']) {
$html_output .= '<td><select name="destination[' . $myfield_md5 . ']">';
// PMA internal relations
if (isset($existrel[$myfield])) {
$foreign_field = $existrel[$myfield]['foreign_db'] . '.'
. $existrel[$myfield]['foreign_table'] . '.'
. $existrel[$myfield]['foreign_field'];
} else {
$foreign_field = false;
}
$seen_key = false;
foreach ($selectboxall as $value) {
$html_output .= '<option value="' . htmlspecialchars($value) . '"';
if ($foreign_field && $value == $foreign_field) {
$html_output .= ' selected="selected"';
$seen_key = true;
}
$html_output .= '>' . htmlspecialchars($value) . '</option>'. "\n";
} // end while
$html_output .= '<td>';
// if the link defined in relationtable points to a foreign field
// that is not a key in the foreign table, we show the link
// (will not be shown with an arrow)
if ($foreign_field && !$seen_key) {
$html_output .= '<option value="' . htmlspecialchars($foreign_field)
. '"'
. ' selected="selected">' . $foreign_field . '</option>'. "\n";
$foreign_db = false;
$foreign_table = false;
$foreign_column = false;
// database dropdown
if (isset($existrel[$myfield])) {
$foreign_db = $existrel[$myfield]['foreign_db'];
} else {
$foreign_db = $db;
}
$html_output .= '</select>'
. '</td>';
$html_output .= PMA_generateRelationalDropdown(
'destination_db[' . $myfield_md5 . ']',
$GLOBALS['pma']->databases,
$foreign_db
);
// end of database dropdown
// table dropdown
$tables = array();
if ($foreign_db) {
if (isset($existrel[$myfield])) {
$foreign_table = $existrel[$myfield]['foreign_table'];
}
$tables_rs = $GLOBALS['dbi']->query(
'SHOW TABLES FROM ' . PMA_Util::backquote($foreign_db),
null,
PMA_DatabaseInterface::QUERY_STORE
);
while ($row = $GLOBALS['dbi']->fetchRow($tables_rs)) {
$tables[] = $row[0];
}
}
$html_output .= PMA_generateRelationalDropdown(
'destination_table[' . $myfield_md5 . ']',
$tables,
$foreign_table
);
// end of table dropdown
// column dropdown
$columns = array();
if ($foreign_db && $foreign_table) {
if (isset($existrel[$myfield])) {
$foreign_column = $existrel[$myfield]['foreign_field'];
}
$table_obj = new PMA_Table($foreign_table, $foreign_db);
$columns = $table_obj->getUniqueColumns(false, false);
}
$html_output .= PMA_generateRelationalDropdown(
'destination_column[' . $myfield_md5 . ']',
$columns,
$foreign_column
);
// end of column dropdown
$html_output .= '</td>';
} // end if (internal relations)
if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
$html_output .= '<td>';
if (!empty($save_row[$i]['Key'])) {
$html_output .= '<span class="formelement">'
. '<select name="destination_foreign[' . $myfield_md5 . ']"'
. ' class="referenced_column_dropdown">';
if (! empty($save_row[$i]['Key'])) {
$foreign_db = false;
$foreign_table = false;
$foreign_column = false;
// foreign database dropdown
if (isset($existrel_foreign[$myfield])) {
// need to PMA_Util::backquote to support a dot character inside
// an element
$foreign_field = PMA_Util::backquote(
$existrel_foreign[$myfield]['foreign_db']
)
. '.' . PMA_Util::backquote(
$existrel_foreign[$myfield]['foreign_table']
)
. '.' . PMA_Util::backquote(
$existrel_foreign[$myfield]['foreign_field']
);
$foreign_db = $existrel_foreign[$myfield]['foreign_db'];
} else {
$foreign_field = false;
$foreign_db = $db;
}
$html_output .= '<span class="formelement clearfloat">';
$html_output .= PMA_generateRelationalDropdown(
'destination_foreign_db[' . $myfield_md5 . ']',
$GLOBALS['pma']->databases,
$foreign_db
);
// end of foreign database dropdown
$found_foreign_field = false;
foreach ($selectboxall_foreign as $value) {
$html_output .= '<option value="'
. htmlspecialchars($value) . '"';
if ($foreign_field && $value == $foreign_field) {
$html_output .= ' selected="selected"';
$found_foreign_field = true;
// foreign table dropdown
$tables = array();
if ($foreign_db) {
if (isset($existrel_foreign[$myfield])) {
$foreign_table = $existrel_foreign[$myfield]['foreign_table'];
}
$tables_rs = $GLOBALS['dbi']->query(
'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($foreign_db),
null,
PMA_DatabaseInterface::QUERY_STORE
);
while ($row = $GLOBALS['dbi']->fetchRow($tables_rs)) {
if (isset($row[1])
&& strtoupper($row[1]) == $tbl_storage_engine
) {
$tables[] = $row[0];
}
}
$html_output .= '>' . htmlspecialchars($value)
. '</option>'. "\n";
} // end while
// we did not find the foreign field in the tables of current db,
// must be defined in another db so show it to avoid erasing it
if (!$found_foreign_field && $foreign_field) {
$html_output .= '<option value="'
. htmlspecialchars($foreign_field) . '"'
. ' selected="selected"'
. '>' . $foreign_field . '</option>' . "\n";
}
$html_output .= '</select>'
. '</span>';
$html_output .= PMA_generateRelationalDropdown(
'destination_foreign_table[' . $myfield_md5 . ']',
$tables,
$foreign_table
);
// end of foreign table dropdown
// foreign column dropdown
$columns = array();
if ($foreign_db && $foreign_table) {
if (isset($existrel_foreign[$myfield])) {
$foreign_column = $existrel_foreign[$myfield]['foreign_field'];
}
$table_obj = new PMA_Table($foreign_table, $foreign_db);
$columns = $table_obj->getUniqueColumns(false, false);
}
$html_output .= PMA_generateRelationalDropdown(
'destination_foreign_column[' . $myfield_md5 . ']',
$columns,
$foreign_column
);
$html_output .= '</span>';
// end of foreign column dropdown
// For constraint name
$html_output .= '<span class="formelement">';
$html_output .= '<span class="formelement clearfloat">';
$constraint_name = isset($existrel_foreign[$myfield]['constraint'])
? $existrel_foreign[$myfield]['constraint'] : '';
$html_output .= __('Constraint name');
@ -504,7 +568,7 @@ if (count($columns) > 0) {
. ' value="' . $constraint_name . '"/>';
$html_output .= '</span>' . "\n";
$html_output .= '<span class="formelement">';
$html_output .= '<span class="formelement clearfloat">';
// For ON DELETE and ON UPDATE, the default action
// is RESTRICT as per MySQL doc; however, a SHOW CREATE TABLE
// won't display the clause if it's set as RESTRICT.
@ -518,7 +582,7 @@ if (count($columns) > 0) {
);
$html_output .= '</span>' . "\n";
$html_output .= '<span class="formelement">' . "\n";
$html_output .= '<span class="formelement clearfloat">' . "\n";
$on_update = isset($existrel_foreign[$myfield]['on_update'])
? $existrel_foreign[$myfield]['on_update'] : 'RESTRICT';
$html_output .= PMA_generateDropdown(
@ -574,5 +638,4 @@ if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
}
// Render HTML output
PMA_Response::getInstance()->addHTML($html_output);
?>

View File

@ -2572,3 +2572,8 @@ div.jqplot-noData-container {
text-align: center;
background-color: rgba(96%, 96%, 96%, 0.3);
}
#relationalTable select {
width: 125px;
margin-right: 5px;
}

View File

@ -2778,6 +2778,11 @@ fieldset .disabled-field td {
padding-<?php echo $left; ?>: 20px;
}
#relationalTable select {
width: 125px;
margin-right: 5px;
}
/* css for timepicker */
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
.ui-timepicker-div dl { text-align: <?php echo $left; ?>; }