Fix #11490 UI for defining partitioning in create table window

Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
This commit is contained in:
Madhura Jayaratne 2015-09-25 14:36:55 +10:00
parent 12307045c0
commit 7c325469d5
8 changed files with 396 additions and 31 deletions

View File

@ -4,6 +4,7 @@ phpMyAdmin - ChangeLog
4.6.0.0 (not yet released)
+ issue #11456 Disabled storage engines
+ issue #11479 Allow setting routine wise privileges
+ issue #11490 UI for defining partitioning in create table window
4.5.1.0 (not yet released)
- issue Invalid argument supplied for foreach()

View File

@ -2742,6 +2742,10 @@ AJAX.registerTeardown('functions.js', function () {
$(document).off('submit', "form.create_table_form.ajax");
$(document).off('click', "form.create_table_form.ajax input[name=submit_num_fields]");
$(document).off('keyup', "form.create_table_form.ajax input");
$(document).off('change', "form.create_table_form.ajax input[name=partition_count]," +
"form.create_table_form.ajax input[name=subpartition_count]");
$(document).off('change', "form.create_table_form.ajax select[name=partition_by]");
$(document).off('change', "form.create_table_form.ajax select[name=subpartition_by]");
});
/**
@ -2855,24 +2859,21 @@ AJAX.registerOnload('functions.js', function () {
}); // end create table form (save)
/**
* Attach event handler for create table form (add fields)
* Submits the intermediate changes in the table creation form
* to refresh the UI accordingly
*/
$(document).on('click', "form.create_table_form.ajax input[name=submit_num_fields]", function (event) {
event.preventDefault();
function submitChangesInCreateTableForm (actionParam) {
/**
* @var the_form object referring to the create table form
*/
var $form = $(this).closest('form');
if (!checkFormElementInRange(this.form, 'added_fields', PMA_messages.strLeastColumnError, 1)) {
return;
}
var $form = $('form.create_table_form.ajax');
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
PMA_prepareForAjaxRequest($form);
//User wants to add more fields to the table
$.post($form.attr('action'), $form.serialize() + "&submit_num_fields=1", function (data) {
$.post($form.attr('action'), $form.serialize() + "&" + actionParam, function (data) {
if (typeof data !== 'undefined' && data.success) {
var $pageContent = $("#page_content");
$pageContent.html(data.message);
@ -2884,6 +2885,19 @@ AJAX.registerOnload('functions.js', function () {
PMA_ajaxShowMessage(data.error);
}
}); //end $.post()
}
/**
* Attach event handler for create table form (add fields)
*/
$(document).on('click', "form.create_table_form.ajax input[name=submit_num_fields]", function (event) {
event.preventDefault();
if (!checkFormElementInRange(this.form, 'added_fields', PMA_messages.strLeastColumnError, 1)) {
return;
}
submitChangesInCreateTableForm('submit_num_fields=1');
}); // end create table form (add fields)
$(document).on('keydown', "form.create_table_form.ajax input[name=added_fields]", function (event) {
@ -2896,6 +2910,28 @@ AJAX.registerOnload('functions.js', function () {
.click();
}
});
/**
* Attach event handler to manage changes in number of partitions and subpartitions
*/
$(document).on('change', "form.create_table_form.ajax input[name=partition_count]," +
"form.create_table_form.ajax input[name=subpartition_count]", function (event) {
submitChangesInCreateTableForm('submit_partition_change=1');
});
$(document).on('change', "form.create_table_form.ajax select[name=partition_by]", function (event) {
var value = $(this).val();
$('input[name=partition_expr], input[name=partition_count]').prop('required', (value != ''));
var listOrRange = value == 'LIST' || value == 'RANGE';
$('.partition_value').val('').prop('disabled', ! listOrRange);
});
$(document).on('change', "form.create_table_form.ajax select[name=subpartition_by]", function (event) {
var value = $(this).val();
$('input[name=subpartition_expr], input[name=subpartition_count]').prop('required', (value != ''));
});
$("input[value=AUTO_INCREMENT]").change(function(){
if (this.checked) {
var col = /\d/.exec($(this).attr('name'));

View File

@ -124,18 +124,24 @@ class PMA_StorageEngine
* @param string $selected The selected engine
* @param boolean $offerUnavailableEngines Should unavailable storage
* engines be offered?
* @param boolean $addEmpty Whether to provide empty option
*
* @static
* @return string html selectbox
*/
static public function getHtmlSelect(
$name = 'engine', $id = null,
$selected = null, $offerUnavailableEngines = false
$selected = null, $offerUnavailableEngines = false,
$addEmpty = false
) {
$selected = /*overload*/mb_strtolower($selected);
$output = '<select name="' . $name . '"'
. (empty($id) ? '' : ' id="' . $id . '"') . '>' . "\n";
if ($addEmpty) {
$output .= '<option value=""></option>';
}
foreach (PMA_StorageEngine::getStorageEngines() as $key => $details) {
// Don't show PERFORMANCE_SCHEMA engine (MySQL 5.5)
if (! $offerUnavailableEngines
@ -150,7 +156,7 @@ class PMA_StorageEngine
. (empty($details['Comment'])
? '' : ' title="' . htmlspecialchars($details['Comment']) . '"')
. (/*overload*/mb_strtolower($key) == $selected
|| (empty($selected) && $details['Support'] == 'DEFAULT')
|| (empty($selected) && $details['Support'] == 'DEFAULT' && ! $addEmpty)
? ' selected="selected"' : '')
. '>' . "\n"
. ' ' . htmlspecialchars($details['Engine']) . "\n"

View File

@ -292,6 +292,106 @@ function PMA_getColumnCreationStatements($is_create_tbl = true)
}
/**
* Returns the partitioning clause
*
* @return string partitioning clause
*/
function PMA_getPartitionsDefinition()
{
$sql_query = "";
if (! empty($_REQUEST['partition_by'])
&& ! empty($_REQUEST['partition_expr'])
&& ! empty($_REQUEST['partition_count'])
&& $_REQUEST['partition_count'] > 1
) {
$sql_query .= " PARTITION BY " . $_REQUEST['partition_by']
. " (" . $_REQUEST['partition_expr'] . ")"
. " PARTITIONS " . $_REQUEST['partition_count'];
}
if (! empty($_REQUEST['subpartition_by'])
&& ! empty($_REQUEST['subpartition_expr'])
&& ! empty($_REQUEST['subpartition_count'])
&& $_REQUEST['subpartition_count'] > 1
) {
$sql_query .= " SUBPARTITION BY " . $_REQUEST['subpartition_by']
. " (" . $_REQUEST['subpartition_expr'] . ")"
. " SUBPARTITIONS " . $_REQUEST['subpartition_count'];
}
if (! empty($_REQUEST['partitions'])) {
$i = 0;
$partitions = array();
foreach ($_REQUEST['partitions'] as $partition) {
$partitions[] = PMA_getPartitionDefinition('p' . $i, $partition);
$i++;
}
$sql_query .= " (" . implode(", ", $partitions) . ")";
}
return $sql_query;
}
/**
* Returns the definition of a partition/subpartition
*
* @param string $name name of the partition/subpartition
* @param array $partition array of parition/subpartition detiails
* @param boolean $isSubPartition whether a subpartition
*
* @return string partition/subpartition definition
*/
function PMA_getPartitionDefinition($name, $partition, $isSubPartition = false)
{
$sql_query = " " . ($isSubPartition ? "SUB" : "") . "PARTITION " . $name;
if (! empty($partition['value_type'])) {
$sql_query .= " VALUES " . $partition['value_type'];
if ($partition['value_type'] != 'LESS THAN MAXVALUE') {
$sql_query .= " (" . $partition['value'] . ")";
}
}
if (! empty($partition['engine'])) {
$sql_query .= " ENGINE = " . $partition['engine'];
}
if (! empty($partition['comment'])) {
$sql_query .= " COMMENT = '" . $partition['comment'] . "'";
}
if (! empty($partition['data_directory'])) {
$sql_query .= " DATA DIRECTORY = '" . $partition['data_directory'] . "'";
}
if (! empty($partition['index_directory'])) {
$sql_query .= " INDEX_DIRECTORY = '" . $partition['index_directory'] . "'";
}
if (! empty($partition['max_rows'])) {
$sql_query .= " MAX_ROWS = " . $partition['max_rows'];
}
if (! empty($partition['min_rows'])) {
$sql_query .= " MIN_ROWS = " . $partition['min_rows'];
}
if (! empty($partition['tablespace'])) {
$sql_query .= " TABLESPACE = " . $partition['tablespace'];
}
if (! empty($partition['node_group'])) {
$sql_query .= " NODEGROUP = " . $partition['node_group'];
}
if (! empty($partition['subpartitions'])) {
$j = 0;
$subpartitions = array();
foreach ($partition['subpartitions'] as $subpartition) {
$subpartitions[] = PMA_getPartitionDefinition($name . 's' . $j, $subpartition, true);
$j++;
}
$sql_query .= " (" . implode(", ", $subpartitions) . ")";
}
return $sql_query;
}
/**
* Function to get table creation sql query
*
@ -329,11 +429,7 @@ function PMA_getTableCreationQuery($db, $table)
$sql_query .= ' COMMENT = \''
. PMA_Util::sqlAddSlashes($_REQUEST['comment']) . '\'';
}
if (!empty($_REQUEST['partition_definition'])) {
$sql_query .= ' ' . PMA_Util::sqlAddSlashes(
$_REQUEST['partition_definition']
);
}
$sql_query .= PMA_getPartitionsDefinition();
$sql_query .= ';';
return $sql_query;
@ -346,13 +442,15 @@ function PMA_getTableCreationQuery($db, $table)
*/
function PMA_getNumberOfFieldsFromRequest()
{
if (isset($_REQUEST['submit_num_fields'])) {
if (isset($_REQUEST['submit_num_fields'])) { // adding new fields
$num_fields = $_REQUEST['orig_num_fields'] + $_REQUEST['added_fields'];
} elseif (isset($_REQUEST['orig_num_fields'])) { // retaining existing fields
$num_fields = $_REQUEST['orig_num_fields'];
} elseif (isset($_REQUEST['num_fields'])
&& intval($_REQUEST['num_fields']) > 0
) {
) { // new table with specified number of fields
$num_fields = (int) $_REQUEST['num_fields'];
} else {
} else { // new table with unspecified number of fields
$num_fields = 4;
}

View File

@ -121,7 +121,7 @@ if (isset($field_fulltext) && is_array($field_fulltext)) {
$submit_fulltext[$fulltext_indexkey] = $fulltext_indexkey;
}
}
if (isset($_REQUEST['submit_num_fields'])) {
if (isset($_REQUEST['submit_num_fields']) || isset($_REQUEST['submit_partition_change'])) {
//if adding new fields, set regenerate to keep the original values
$regenerate = 1;
}
@ -409,6 +409,7 @@ $html = PMA\Template::get('columns_definitions/column_definitions_form')->render
'action' => $action,
'form_params' => $form_params,
'content_cells' => $content_cells,
'partitions' => isset($partitions) ? $partitions : array()
)
);

View File

@ -100,6 +100,72 @@ if (isset($_REQUEST['do_save_data'])) {
//This global variable needs to be reset for the headerclass to function properly
$GLOBAL['table'] = '';
if (PMA_isValid($_REQUEST['partition_count'], 'numeric')
&& $_REQUEST['partition_count'] > 0
) {
$partitions = isset($_REQUEST['partitions']) ? $_REQUEST['partitions'] : array();
array_splice($partitions, $_REQUEST['partition_count']);
for ($i = 0; $i < $_REQUEST['partition_count']; $i++) {
if (! isset($partitions[$i])) {
$partitions[$i] = array(
'value_type' => '',
'value' => '',
'engine' => '',
'comment' => '',
'data_directory' => '',
'index_directory' => '',
'max_rows' => '',
'min_rows' => '',
'tablespace' => '',
'node_group' => '',
);
}
$partition =& $partitions[$i];
$partition['name'] = 'p' . $i;
$partition['prefix'] = 'partitions[' . $i . ']';
$partition['value_enabled'] = isset($_REQUEST['partition_by'])
&& ($_REQUEST['partition_by'] == 'RANGE'
|| $_REQUEST['partition_by'] == 'LIST');
if (PMA_isValid($_REQUEST['subpartition_count'], 'numeric')
&& $_REQUEST['subpartition_count'] > 0
) {
$partition['subpartition_count'] = $_REQUEST['subpartition_count'];
if (! isset($partition['subpartitions'])) {
$partition['subpartitions'] = array();
}
$subpartitions =& $partition['subpartitions'];
array_splice($subpartitions, $_REQUEST['subpartition_count']);
for ($j = 0; $j < $_REQUEST['subpartition_count']; $j++) {
if (! isset($subpartitions[$j])) {
$subpartitions[$j] = array(
'engine' => '',
'comment' => '',
'data_directory' => '',
'index_directory' => '',
'max_rows' => '',
'min_rows' => '',
'tablespace' => '',
'node_group' => '',
);
}
$subpartition =& $subpartitions[$j];
$subpartition['name'] = 'p' . $i . 's' . $j;
$subpartition['prefix'] = 'partitions[' . $i . ']'
. '[subpartitions][' . $j . ']';
}
} else {
unset($partition['subpartitions']);
unset($partition['subpartition_count']);
}
}
}
/**
* Displays the form used to define the structure of the table
*/

View File

@ -133,23 +133,16 @@
</tr>
<?php if (PMA_Partition::havePartitioning()): ?>
<tr class="vtop">
<th>
<th colspan="5">
<?php echo __('PARTITION definition:'); ?>
&nbsp;
<?php echo PMA_Util::showMySQLDocu('Partitioning'); ?>
</th>
</tr>
<tr>
<td>
<textarea name="partition_definition"
id="partitiondefinition"
cols="<?php echo $GLOBALS['cfg']['TextareaCols']; ?>"
rows="<?php echo $GLOBALS['cfg']['TextareaRows']; ?>"
dir="<?php echo $GLOBALS['text_dir']; ?>">
<?php echo (isset($_REQUEST['partition_definition']) ? htmlspecialchars($_REQUEST['partition_definition']) : ''); ?>
</textarea>
<td colspan="5">
<?php echo PMA\Template::get('columns_definitions/partitions_form')
->render(array('partitions' => $partitions)); ?>
</td>
</tr>
<?php endif; ?>

View File

@ -0,0 +1,164 @@
<?php
$partitionOptions = array('', 'HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY', 'RANGE', 'LIST');
$subPartitionOptions = array('', 'HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY');
$valueTypeOptions = array('', 'LESS THAN', 'LESS THAN MAXVALUE', 'IN');
?>
<table id="partition_table">
<tr class="vmiddle">
<td><label for="partition_by"><?php echo __('Partition by:'); ?></label></td>
<td>
<select name="partition_by" id="partition_by">
<?php foreach ($partitionOptions as $option): ?>
<option value="<?php echo $option?>"
<?php if (isset($_REQUEST['partition_by']) && $_REQUEST['partition_by'] == $option): ?>
selected="selected"
<?php endif; ?>
>
<?php echo $option; ?>
</option>
<?php endforeach; ?>
</select>
</td>
<td>(
<input name="partition_expr" type="text"
placeholder="<?php echo __('Expression or column list'); ?>"
value="<?php echo (isset($_REQUEST['partition_expr']) ? htmlspecialchars($_REQUEST['partition_expr']) : ''); ?>"/>
)</td>
</tr>
<tr class="vmiddle">
<td><label for="partition_count"><?php echo __('Partitions:'); ?></label></td>
<td>
<input name="partition_count" type="number" min="2"
value="<?php echo (isset($_REQUEST['partition_count']) ? htmlspecialchars($_REQUEST['partition_count']) : ''); ?>" />
</td>
</tr>
<?php if (isset($_REQUEST['partition_count']) && $_REQUEST['partition_count'] > 1): ?>
<tr class="vmiddle">
<td><label for="subpartition_by"><?php echo __('Subpartition by:'); ?></label></td>
<td>
<select name="subpartition_by" id="subpartition_by">
<?php foreach ($subPartitionOptions as $option): ?>
<option value="<?php echo $option?>"
<?php if (isset($_REQUEST['subpartition_by']) && $_REQUEST['subpartition_by'] == $option): ?>
selected="selected"
<?php endif; ?>
>
<?php echo $option; ?>
</option>
<?php endforeach; ?>
</select>
</td>
<td>(
<input name="subpartition_expr" type="text"
placeholder="<?php echo __('Expression or column list'); ?>"
value="<?php echo (isset($_REQUEST['subpartition_expr']) ? htmlspecialchars($_REQUEST['subpartition_expr']) : ''); ?>"/>
)</td>
</tr>
<tr class="vmiddle">
<td><label for="subpartition_count"><?php echo __('Subpartitions:'); ?></label></td>
<td>
<input name="subpartition_count" type="number" min="2"
value="<?php echo (isset($_REQUEST['subpartition_count']) ? htmlspecialchars($_REQUEST['subpartition_count']) : ''); ?>" />
</td>
</tr>
<?php endif; ?>
</table>
<?php if (isset($_REQUEST['partition_count']) && $_REQUEST['partition_count'] > 1): ?>
<table id="partition_definition_table">
<tr>
<th><?php echo __('Partition'); ?></th>
<th><?php echo __('Values'); ?></th>
<?php if (isset($_REQUEST['subpartition_count']) && $_REQUEST['subpartition_count'] > 1): ?>
<th><?php echo __('Subpartition'); ?></th>
<?php endif; ?>
<th><?php echo __('Engine'); ?></th>
<th><?php echo __('Comment'); ?></th>
<th><?php echo __('Data directory'); ?></th>
<th><?php echo __('Index directory'); ?></th>
<th><?php echo __('Max rows'); ?></th>
<th><?php echo __('Min rows'); ?></th>
<th><?php echo __('Table space'); ?></th>
<th><?php echo __('Node group'); ?></th>
</tr>
<?php $odd = true; ?>
<?php foreach ($partitions as $partition): ?>
<?php $rowspan = isset($partition['subpartition_count']) ? ($partition['subpartition_count'] + 1) : 2; ?>
<tr class="<?php echo ($odd ? 'odd' : 'even'); ?>">
<th rowspan="<?php echo $rowspan; ?>" class="vmiddle">
<?php echo htmlspecialchars($partition['name']); ?>
</th>
<td rowspan="<?php echo $rowspan; ?>" class="vmiddle">
<select class="partition_value" name="<?php echo $partition['prefix']; ?>[value_type]" <?php echo (! $partition['value_enabled'] ? 'disabled' : ''); ?> >
<?php foreach ($valueTypeOptions as $option): ?>
<option value="<?php echo $option?>"
<?php if (isset($partition['value_type']) && $partition['value_type'] == $option): ?>
selected="selected"
<?php endif; ?>
>
<?php echo $option; ?>
</option>
<?php endforeach; ?>
</select>
<input type="text" class="partition_value" name="<?php echo $partition['prefix']; ?>[value]" <?php echo (! $partition['value_enabled'] ? 'disabled' : ''); ?> />
</td>
</tr>
<?php
if (isset($partition['subpartitions'])):
$subpartitions = $partition['subpartitions'];
else:
$subpartitions = array($partition);
endif;
?>
<?php foreach ($subpartitions as $subpartition): ?>
<tr class="<?php echo ($odd ? 'odd' : 'even'); ?>">
<?php if (isset($partition['subpartitions'])): ?>
<th class="vmiddle"><?php echo htmlspecialchars($subpartition['name']); ?></th>
<?php endif; ?>
<td>
<?php echo PMA_StorageEngine::getHtmlSelect(
$subpartition['prefix'] . '[engine]',
null,
$subpartition['engine'],
false,
true
); ?>
</td>
<td>
<textarea name="<?php echo $subpartition['prefix']; ?>[comment]">
<?php echo htmlspecialchars($subpartition['comment']); ?>
</textarea>
</td>
<td>
<input type="text" name="<?php echo $subpartition['prefix']; ?>[data_directory]"
value="<?php echo htmlspecialchars($subpartition['data_directory']); ?>" />
</td>
<td>
<input type="text" name="<?php echo $subpartition['prefix']; ?>[index_directory]"
value="<?php echo htmlspecialchars($subpartition['index_directory']); ?>" />
</td>
<td>
<input type="number" name="<?php echo $subpartition['prefix']; ?>[max_rows]"
value="<?php echo htmlspecialchars($subpartition['max_rows']); ?>" />
</td>
<td>
<input type="number" min="0" name="<?php echo $subpartition['prefix']; ?>[min_rows]"
value="<?php echo htmlspecialchars($subpartition['min_rows']); ?>" />
</td>
<td>
<input type="text" min="0" name="<?php echo $subpartition['prefix']; ?>[tablespace]"
value="<?php echo htmlspecialchars($subpartition['tablespace']); ?>" />
</td>
<td>
<input type="text" name="<?php echo $subpartition['prefix']; ?>[node_group]"
value="<?php echo htmlspecialchars($subpartition['node_group']); ?>" />
</td>
</tr>
<?php endforeach; ?>
<?php $odd = !$odd; ?>
<?php endforeach; ?>
</table>
<?php endif; ?>