import Indexes from '../utils/IndexEnum';
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
import PMA_commonParams from '../variables/common_params';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage, PMA_showHints } from '../utils/show_ajax_messages';
import { PMA_prepareForAjaxRequest } from './AjaxRequest';
import { PMA_highlightSQL } from '../utils/sql';
import { PMA_previewSQL } from './Sql/PreviewSql';
import { PMA_verifyColumnsProperties } from './Table/TableColumns';
import { PMA_sprintf } from '../utils/sprintf';
import { PMA_init_slider } from '../utils/Slider';
import { PMA_reloadNavigation } from './navigation';
/**
* Returns the array of indexes based on the index choice
*
* @param index_choice index choice
*/
export function PMA_getIndexArray (index_choice) {
var source_array = null;
switch (index_choice.toLowerCase()) {
case 'primary':
source_array = Indexes.primary_indexes;
break;
case 'unique':
source_array = Indexes.unique_indexes;
break;
case 'index':
source_array = Indexes.indexes;
break;
case 'fulltext':
source_array = Indexes.fulltext_indexes;
break;
case 'spatial':
source_array = Indexes.spatial_indexes;
break;
default:
return null;
}
return source_array;
}
/**
* Hides/shows the inputs and submits appropriately depending
* on whether the index type chosen is 'SPATIAL' or not.
*/
export function checkIndexType () {
/**
* @var Object Dropdown to select the index choice.
*/
var $select_index_choice = $('#select_index_choice');
/**
* @var Object Dropdown to select the index type.
*/
var $select_index_type = $('#select_index_type');
/**
* @var Object Table header for the size column.
*/
var $size_header = $('#index_columns').find('thead tr th:nth-child(2)');
/**
* @var Object Inputs to specify the columns for the index.
*/
var $column_inputs = $('select[name="index[columns][names][]"]');
/**
* @var Object Inputs to specify sizes for columns of the index.
*/
var $size_inputs = $('input[name="index[columns][sub_parts][]"]');
/**
* @var Object Footer containg the controllers to add more columns
*/
var $add_more = $('#index_frm').find('.add_more');
if ($select_index_choice.val() === 'SPATIAL') {
// Disable and hide the size column
$size_header.hide();
$size_inputs.each(function () {
$(this)
.prop('disabled', true)
.parent('td').hide();
});
// Disable and hide the columns of the index other than the first one
var initial = true;
$column_inputs.each(function () {
var $column_input = $(this);
if (! initial) {
$column_input
.prop('disabled', true)
.parent('td').hide();
} else {
initial = false;
}
});
// Hide controllers to add more columns
$add_more.hide();
} else {
// Enable and show the size column
$size_header.show();
$size_inputs.each(function () {
$(this)
.prop('disabled', false)
.parent('td').show();
});
// Enable and show the columns of the index
$column_inputs.each(function () {
$(this)
.prop('disabled', false)
.parent('td').show();
});
// Show controllers to add more columns
$add_more.show();
}
if ($select_index_choice.val() === 'SPATIAL' ||
$select_index_choice.val() === 'FULLTEXT') {
$select_index_type.val('').prop('disabled', true);
} else {
$select_index_type.prop('disabled', false);
}
}
/**
* Sets current index information into form parameters.
*
* @param array source_array Array containing index columns
* @param string index_choice Choice of index
*
* @return void
*/
function PMA_setIndexFormParameters (source_array, index_choice) {
if (index_choice === 'index') {
$('input[name="indexes"]').val(JSON.stringify(source_array));
} else {
$('input[name="' + index_choice + '_indexes"]').val(JSON.stringify(source_array));
}
}
/**
* Removes a column from an Index.
*
* @param string col_index Index of column in form
*
* @return void
*/
export function PMA_removeColumnFromIndex (col_index) {
// Get previous index details.
var previous_index = $('select[name="field_key[' + col_index + ']"]')
.attr('data-index');
if (previous_index.length) {
previous_index = previous_index.split(',');
var source_array = PMA_getIndexArray(previous_index[0]);
if (source_array === null) {
return;
}
// Remove column from index array.
var source_length = source_array[previous_index[1]].columns.length;
for (var i = 0; i < source_length; i++) {
if (source_array[previous_index[1]].columns[i].col_index === col_index) {
source_array[previous_index[1]].columns.splice(i, 1);
}
}
// Remove index completely if no columns left.
if (source_array[previous_index[1]].columns.length === 0) {
source_array.splice(previous_index[1], 1);
}
// Update current index details.
$('select[name="field_key[' + col_index + ']"]').attr('data-index', '');
// Update form index parameters.
PMA_setIndexFormParameters(source_array, previous_index[0].toLowerCase());
}
}
/**
* Adds a column to an Index.
*
* @param array source_array Array holding corresponding indexes
* @param string array_index Index of an INDEX in array
* @param string index_choice Choice of Index
* @param string col_index Index of column on form
*
* @return void
*/
function PMA_addColumnToIndex (source_array, array_index, index_choice, col_index) {
if (col_index >= 0) {
// Remove column from other indexes (if any).
PMA_removeColumnFromIndex(col_index);
}
var index_name = $('input[name="index[Key_name]"]').val();
var index_comment = $('input[name="index[Index_comment]"]').val();
var key_block_size = $('input[name="index[Key_block_size]"]').val();
var parser = $('input[name="index[Parser]"]').val();
var index_type = $('select[name="index[Index_type]"]').val();
var columns = [];
$('#index_columns').find('tbody').find('tr').each(function () {
// Get columns in particular order.
var col_index = $(this).find('select[name="index[columns][names][]"]').val();
var size = $(this).find('input[name="index[columns][sub_parts][]"]').val();
columns.push({
'col_index': col_index,
'size': size
});
});
// Update or create an index.
source_array[array_index] = {
'Key_name': index_name,
'Index_comment': index_comment,
'Index_choice': index_choice.toUpperCase(),
'Key_block_size': key_block_size,
'Parser': parser,
'Index_type': index_type,
'columns': columns
};
// Display index name (or column list)
var displayName = index_name;
if (displayName === '') {
var columnNames = [];
$.each(columns, function () {
columnNames.push($('input[name="field_name[' + this.col_index + ']"]').val());
});
displayName = '[' + columnNames.join(', ') + ']';
}
$.each(columns, function () {
var id = 'index_name_' + this.col_index + '_8';
var $name = $('#' + id);
if ($name.length === 0) {
$name = $('<a id="' + id + '" href="#" class="ajax show_index_dialog"></a>');
$name.insertAfter($('select[name="field_key[' + this.col_index + ']"]'));
}
var $text = $('<small>').text(displayName);
$name.html($text);
});
if (col_index >= 0) {
// Update index details on form.
$('select[name="field_key[' + col_index + ']"]')
.attr('data-index', index_choice + ',' + array_index);
}
PMA_setIndexFormParameters(source_array, index_choice.toLowerCase());
}
/**
* Get choices list for a column to create a composite index with.
*
* @param string index_choice Choice of index
* @param array source_array Array hodling columns for particular index
*
* @return jQuery Object
*/
function PMA_getCompositeIndexList (source_array, col_index) {
// Remove any previous list.
if ($('#composite_index_list').length) {
$('#composite_index_list').remove();
}
// Html list.
var $composite_index_list = $(
'<ul id="composite_index_list">' +
'<div>' + PMA_messages.strCompositeWith + '</div>' +
'</ul>'
);
// Add each column to list available for composite index.
var source_length = source_array.length;
var already_present = false;
for (var i = 0; i < source_length; i++) {
var sub_array_len = source_array[i].columns.length;
var column_names = [];
for (var j = 0; j < sub_array_len; j++) {
column_names.push(
$('input[name="field_name[' + source_array[i].columns[j].col_index + ']"]').val()
);
if (col_index === source_array[i].columns[j].col_index) {
already_present = true;
}
}
$composite_index_list.append(
'<li>' +
'<input type="radio" name="composite_with" ' +
(already_present ? 'checked="checked"' : '') +
' id="composite_index_' + i + '" value="' + i + '">' +
'<label for="composite_index_' + i + '">' + column_names.join(', ') +
'</lablel>' +
'</li>'
);
}
return $composite_index_list;
}
/**
* Ensures indexes names are valid according to their type and, for a primary
* key, lock index name to 'PRIMARY'
* @param string form_id Variable which parses the form name as
* the input
* @return boolean false if there is no index form, true else
*/
export function checkIndexName (form_id) {
if ($('#' + form_id).length === 0) {
return false;
}
// Gets the elements pointers
var $the_idx_name = $('#input_index_name');
var $the_idx_choice = $('#select_index_choice');
// Index is a primary key
if ($the_idx_choice.find('option:selected').val() === 'PRIMARY') {
$the_idx_name.val('PRIMARY');
$the_idx_name.prop('disabled', true);
} else {
if ($the_idx_name.val() === 'PRIMARY') {
$the_idx_name.val('');
}
$the_idx_name.prop('disabled', false);
}
return true;
} // end of the 'checkIndexName()' function
/**
* Shows 'Add Index' dialog.
*
* @param array source_array Array holding particluar index
* @param string array_index Index of an INDEX in array
* @param array target_columns Columns for an INDEX
* @param string col_index Index of column on form
* @param object index Index detail object
*
* @return void
*/
export function PMA_showAddIndexDialog (source_array, array_index, target_columns, col_index, index) {
// Prepare post-data.
var $table = $('input[name="table"]');
var table = $table.length > 0 ? $table.val() : '';
var post_data = {
server: PMA_commonParams.get('server'),
db: $('input[name="db"]').val(),
table: table,
ajax_request: 1,
create_edit_table: 1,
index: index
};
var columns = {};
for (var i = 0; i < target_columns.length; i++) {
var column_name = $('input[name="field_name[' + target_columns[i] + ']"]').val();
var column_type = $('select[name="field_type[' + target_columns[i] + ']"]').val().toLowerCase();
columns[column_name] = [column_type, target_columns[i]];
}
post_data.columns = JSON.stringify(columns);
var button_options = {};
button_options[PMA_messages.strGo] = function () {
var is_missing_value = false;
$('select[name="index[columns][names][]"]').each(function () {
if ($(this).val() === '') {
is_missing_value = true;
}
});
if (! is_missing_value) {
PMA_addColumnToIndex(
source_array,
array_index,
index.Index_choice,
col_index
);
} else {
PMA_ajaxShowMessage(
'<div class="error"><img src="themes/dot.gif" title="" alt=""' +
' class="icon ic_s_error" /> ' + PMA_messages.strMissingColumn +
' </div>', false
);
return false;
}
$(this).dialog('close');
};
button_options[PMA_messages.strCancel] = function () {
if (col_index >= 0) {
// Handle state on 'Cancel'.
var $select_list = $('select[name="field_key[' + col_index + ']"]');
if (! $select_list.attr('data-index').length) {
$select_list.find('option[value*="none"]').attr('selected', 'selected');
} else {
var previous_index = $select_list.attr('data-index').split(',');
$select_list.find('option[value*="' + previous_index[0].toLowerCase() + '"]')
.attr('selected', 'selected');
}
}
$(this).dialog('close');
};
var $msgbox = PMA_ajaxShowMessage();
$.post('tbl_indexes.php', post_data, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxRemoveMessage($msgbox);
// Show dialog if the request was successful
var $div = $('<div/>');
$div
.append(data.message)
.dialog({
title: PMA_messages.strAddIndex,
width: 450,
minHeight: 250,
open: function () {
checkIndexName('index_frm');
PMA_showHints($div);
PMA_init_slider();
$('#index_columns').find('td').each(function () {
$(this).css('width', $(this).width() + 'px');
});
$('#index_columns').find('tbody').sortable({
axis: 'y',
containment: $('#index_columns').find('tbody'),
tolerance: 'pointer'
});
// We dont need the slider at this moment.
$(this).find('fieldset.tblFooters').remove();
},
modal: true,
buttons: button_options,
close: function () {
$(this).remove();
}
});
}
});
}
/**
* Creates a advanced index type selection dialog.
*
* @param array source_array Array holding a particular type of indexes
* @param string index_choice Choice of index
* @param string col_index Index of new column on form
*
* @return void
*/
export function PMA_indexTypeSelectionDialog (source_array, index_choice, col_index) {
var $single_column_radio = $('<input type="radio" id="single_column" name="index_choice"' +
' checked="checked">' +
'<label for="single_column">' + PMA_messages.strCreateSingleColumnIndex + '</label>');
var $composite_index_radio = $('<input type="radio" id="composite_index"' +
' name="index_choice">' +
'<label for="composite_index">' + PMA_messages.strCreateCompositeIndex + '</label>');
var $dialog_content = $('<fieldset id="advance_index_creator"></fieldset>');
$dialog_content.append('<legend>' + index_choice.toUpperCase() + '</legend>');
// For UNIQUE/INDEX type, show choice for single-column and composite index.
$dialog_content.append($single_column_radio);
$dialog_content.append($composite_index_radio);
var button_options = {};
// 'OK' operation.
button_options[PMA_messages.strGo] = function () {
if ($('#single_column').is(':checked')) {
var index = {
'Key_name': (index_choice === 'primary' ? 'PRIMARY' : ''),
'Index_choice': index_choice.toUpperCase()
};
PMA_showAddIndexDialog(source_array, (source_array.length), [col_index], col_index, index);
}
if ($('#composite_index').is(':checked')) {
if ($('input[name="composite_with"]').length !== 0 && $('input[name="composite_with"]:checked').length === 0
) {
PMA_ajaxShowMessage(
'<div class="error"><img src="themes/dot.gif" title=""' +
' alt="" class="icon ic_s_error" /> ' +
PMA_messages.strFormEmpty +
' </div>',
false
);
return false;
}
var array_index = $('input[name="composite_with"]:checked').val();
var source_length = source_array[array_index].columns.length;
var target_columns = [];
for (var i = 0; i < source_length; i++) {
target_columns.push(source_array[array_index].columns[i].col_index);
}
target_columns.push(col_index);
PMA_showAddIndexDialog(source_array, array_index, target_columns, col_index,
source_array[array_index]);
}
$(this).remove();
};
button_options[PMA_messages.strCancel] = function () {
// Handle state on 'Cancel'.
var $select_list = $('select[name="field_key[' + col_index + ']"]');
if (! $select_list.attr('data-index').length) {
$select_list.find('option[value*="none"]').attr('selected', 'selected');
} else {
var previous_index = $select_list.attr('data-index').split(',');
$select_list.find('option[value*="' + previous_index[0].toLowerCase() + '"]')
.attr('selected', 'selected');
}
$(this).remove();
};
var $dialog = $('<div/>').append($dialog_content).dialog({
minWidth: 525,
minHeight: 200,
modal: true,
title: PMA_messages.strAddIndex,
resizable: false,
buttons: button_options,
open: function () {
$('#composite_index').on('change', function () {
if ($(this).is(':checked')) {
$dialog_content.append(PMA_getCompositeIndexList(source_array, col_index));
}
});
$('#single_column').on('change', function () {
if ($(this).is(':checked')) {
if ($('#composite_index_list').length) {
$('#composite_index_list').remove();
}
}
});
},
close: function () {
$('#composite_index').off('change');
$('#single_column').off('change');
$(this).remove();
}
});
}
export function showIndexEditDialog ($outer) {
checkIndexType();
checkIndexName('index_frm');
var $indexColumns = $('#index_columns');
$indexColumns.find('td').each(function () {
$(this).css('width', $(this).width() + 'px');
});
$indexColumns.find('tbody').sortable({
axis: 'y',
containment: $indexColumns.find('tbody'),
tolerance: 'pointer'
});
PMA_showHints($outer);
PMA_init_slider();
// Add a slider for selecting how many columns to add to the index
$outer.find('.slider').slider({
animate: true,
value: 1,
min: 1,
max: 16,
slide: function (event, ui) {
$(this).closest('fieldset').find('input[type=submit]').val(
PMA_sprintf(PMA_messages.strAddToIndex, ui.value)
);
}
});
$('div.add_fields').removeClass('hide');
// focus index size input on column picked
$outer.find('table#index_columns select').on('change', function () {
if ($(this).find('option:selected').val() === '') {
return true;
}
$(this).closest('tr').find('input').focus();
});
// Focus the slider, otherwise it looks nearly transparent
$('a.ui-slider-handle').addClass('ui-state-focus');
// set focus on index name input, if empty
var input = $outer.find('input#input_index_name');
if (! input.val()) {
input.focus();
}
}
export function indexEditorDialog (url, title, callback_success, callback_failure) {
/* Remove the hidden dialogs if there are*/
var $editIndexDialog = $('#edit_index_dialog');
if ($editIndexDialog.length !== 0) {
$editIndexDialog.remove();
}
var $div = $('<div id="edit_index_dialog"></div>');
/**
* @var button_options Object that stores the options
* passed to jQueryUI dialog
*/
var button_options = {};
button_options[PMA_messages.strGo] = function () {
/**
* @var the_form object referring to the export form
*/
var $form = $('#index_frm');
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
PMA_prepareForAjaxRequest($form);
// User wants to submit the form
$.post($form.attr('action'), $form.serialize() + PMA_commonParams.get('arg_separator') + 'do_save_data=1', function (data) {
var $sqlqueryresults = $('.sqlqueryresults');
if ($sqlqueryresults.length !== 0) {
$sqlqueryresults.remove();
}
if (typeof data !== 'undefined' && data.success === true) {
PMA_ajaxShowMessage(data.message);
var $resultQuery = $('.result_query');
if ($resultQuery.length) {
$resultQuery.remove();
}
if (data.sql_query) {
$('<div class="result_query"></div>')
.html(data.sql_query)
.prependTo('#page_content');
PMA_highlightSQL($('#page_content'));
}
$('.result_query .notice').remove();
$resultQuery.prepend(data.message);
/* Reload the field form*/
$('#table_index').remove();
$('<div id=\'temp_div\'><div>')
.append(data.index_table)
.find('#table_index')
.insertAfter('#index_header');
var $editIndexDialog = $('#edit_index_dialog');
if ($editIndexDialog.length > 0) {
$editIndexDialog.dialog('close');
}
$('div.no_indexes_defined').hide();
if (callback_success) {
callback_success();
}
PMA_reloadNavigation();
} else {
var $temp_div = $('<div id=\'temp_div\'><div>').append(data.error);
var $error;
if ($temp_div.find('.error code').length !== 0) {
$error = $temp_div.find('.error code').addClass('error');
} else {
$error = $temp_div;
}
if (callback_failure) {
callback_failure();
}
PMA_ajaxShowMessage($error, false);
}
}); // end $.post()
};
button_options[PMA_messages.strPreviewSQL] = function () {
// Function for Previewing SQL
var $form = $('#index_frm');
PMA_previewSQL($form);
};
button_options[PMA_messages.strCancel] = function () {
$(this).dialog('close');
};
var $msgbox = PMA_ajaxShowMessage();
$.get('tbl_indexes.php', url, function (data) {
if (typeof data !== 'undefined' && data.success === false) {
// in the case of an error, show the error message returned.
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxRemoveMessage($msgbox);
// Show dialog if the request was successful
$div
.append(data.message)
.dialog({
title: title,
width: 'auto',
open: PMA_verifyColumnsProperties,
modal: true,
buttons: button_options,
close: function () {
$(this).remove();
}
});
$div.find('.tblFooters').remove();
showIndexEditDialog($div);
}
}); // end $.get()
}