chg: [diagnostic:db_schema] Added support of default_value and quick fix

pull/5412/head
mokaddem 2019-11-19 12:07:30 -05:00
parent bcd5ce2362
commit b8b5880ef6
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
7 changed files with 54 additions and 67 deletions

View File

@ -2205,7 +2205,21 @@ misp.direct_call(relative_path, body)
if (!$this->_isSiteAdmin()) {
throw new MethodNotAllowedException(__('Only site admin accounts get the DB schema diagnostic.'));
}
return $this->RestResponse->viewData($this->Server->dbSchemaDiagnostic(), $this->response->type());
$dbSchemaDiagnostics = $this->Server->dbSchemaDiagnostic();
if ($this->_isRest()) {
return $this->RestResponse->viewData($dbSchemaDiagnostics, $this->response->type());
} else {
$this->set('checkedTableColumn', $dbSchemaDiagnostics['checked_table_column']);
$this->set('dbSchemaDiagnostics', $dbSchemaDiagnostics['diagnostic']);
$this->set('expectedDbVersion', $dbSchemaDiagnostics['expected_db_version']);
$this->set('actualDbVersion', $dbSchemaDiagnostics['actual_db_version']);
$this->set('error', $dbSchemaDiagnostics['error']);
$this->set('remainingLockTime', $dbSchemaDiagnostics['remaining_lock_time']);
$this->set('updateFailNumberReached', $dbSchemaDiagnostics['update_fail_number_reached']);
$this->set('updateLocked', $dbSchemaDiagnostics['update_locked']);
$this->render('/Elements/healthElements/db_schema_diagnostic');
}
}
public function execSQLQuery() {
@ -2222,6 +2236,13 @@ misp.direct_call(relative_path, body)
} catch (Exception $e) {
$errorMessage = $e->getMessage();
}
if (!$this->_isRest()) {
if (empty($errorMessage)) {
$this->Flash->success(__('Query executed successfully'));
} else {
$this->Flash->error($errorMessage);
}
}
return $this->RestResponse->viewData(array('success' => empty($errorMessage), 'error' => $errorMessage), $this->response->type());
}
}

View File

@ -4310,7 +4310,7 @@ class Server extends AppModel
*/
private function __attachRecoveryQuery($field, $table)
{
if ($field['is_critical']) {
if (isset($field['error_type'])) {
$length = false;
if (in_array($field['error_type'], array('missing_column', 'column_different'))) {
if ($field['expected']['data_type'] === 'int') {
@ -4327,25 +4327,24 @@ class Server extends AppModel
switch($field['error_type']) {
case 'missing_column':
$field['sql'] = sprintf(
'ALTER TABLE `%s` ADD COLUMN `%s` %s%s %s %s;',
'ALTER TABLE `%s` ADD COLUMN `%s` %s%s %s %s %s;',
$table,
$field['column_name'],
$field['expected']['data_type'],
$length !== null ? sprintf('(%d)', $length) : '',
isset($field['expected']['default']) ? 'DEFAULT "' . $field['expected']['default'] . '"' : '',
isset($field['expected']['column_default']) ? $field['expected']['column_default'] . '"' : '',
$field['expected']['is_nullable'] === 'NO' ? 'NOT NULL' : 'NULL',
empty($field['expected']['collation_name']) ? '' : 'COLLATE ' . $field['expected']['collation_name']
);
break;
case 'column_different':
$field['sql'] = sprintf(
'ALTER TABLE `%s` CHANGE `%s` `%s` %s%s %s %s;',
'ALTER TABLE `%s` MODIFY COLUMN `%s` %s%s %s %s %s;',
$table,
$field['column_name'],
$field['column_name'],
$field['expected']['data_type'],
$length !== null ? sprintf('(%d)', $length) : '',
isset($field['expected']['default']) ? 'DEFAULT "' . $field['expected']['default'] . '"' : '',
isset($field['expected']['column_default']) ? 'DEFAULT "' . $field['expected']['column_default'] . '"' : '',
$field['expected']['is_nullable'] === 'NO' ? 'NOT NULL' : 'NULL',
empty($field['expected']['collation_name']) ? '' : 'COLLATE ' . $field['expected']['collation_name']
);
@ -4391,7 +4390,8 @@ class Server extends AppModel
'character_maximum_length',
'numeric_precision',
// 'datetime_precision', -- Only available on MySQL 5.6+
'collation_name'
'collation_name',
'column_default'
)
){
$dbActualSchema = array();
@ -4432,8 +4432,7 @@ class Server extends AppModel
'description' => sprintf(__('Table `%s` does not exist'), $tableName),
'error_type' => 'missing_table',
'column_name' => $tableName,
'is_critical' => true,
'SQLQueryFix' => $this->generateSQLQueryFix($tableName, $column, 'CREATE')
'is_critical' => true
);
} else {
// perform schema comparison for table's columns
@ -4483,8 +4482,7 @@ class Server extends AppModel
'error_type' => 'column_different',
'actual' => $keyedActualColumn[$columnName],
'expected' => $column,
'is_critical' => $isCritical,
'SQLQueryFix' => $this->generateSQLQueryFix($tableName, $column, 'MODIFY')
'is_critical' => $isCritical
);
}
// ALTER TABLE test MODIFY COLUMN locationExpect VARCHAR(120);
@ -4495,8 +4493,7 @@ class Server extends AppModel
'error_type' => 'missing_column',
'actual' => array(),
'expected' => $column,
'is_critical' => true,
'SQLQueryFix' => $this->generateSQLQueryFix($tableName, $column, 'ADD')
'is_critical' => true
);
}
@ -4514,47 +4511,6 @@ class Server extends AppModel
return $dbDiff;
}
public function generateSQLQueryFix($tableName, $expected, $type)
{
$query = '';
if ($type == 'ADD') {
$query .= sprintf('ALTER TABLE `%s` ADD COLUMN ', $tableName);
} elseif ($type == 'MODIFY') {
$query .= sprintf('ALTER TABLE `%s` MODIFY COLUMN ', $tableName);
} elseif ($type == 'CREATE') {
// $query .= sprintf('CREATE TABLE IF NOT EXISTS `%s` (%s)', $tableName);
// CREATE TABLE IF NOT EXISTS `taxonomies` (
// `id` int(11) NOT NULL AUTO_INCREMENT,
// `namespace` varchar(255) COLLATE utf8_bin NOT NULL,
// )
}
$query .= $this->generateSQLQueryFixCol($expected);
return $query;
}
public function generateSQLQueryFixCol($col)
{
$colQuery = array();
$colQuery[] = sprintf('`%s`', $col['column_name']);
$precision = null;
if (!is_null($col['character_maximum_length'])) {
$precision = $col['character_maximum_length'];
} elseif (!is_null($col['numeric_precision'])) {
$precision = $col['numeric_precision'];
}
$colQuery[] = $col['data_type'];
if (!is_null($precision)) {
$colQuery[] = sprintf('(%s)', $precision);
}
if (!is_null($col['collation_name'])) {
$colQuery[] = sprintf('COLLATE %s', $col['collation_name']);
}
$colQuery[] = sprintf('%s NULL', $col['is_nullable'] == 'NO' ? 'NOT' : '');
return implode(' ', $colQuery);
}
public function writeableDirsDiagnostics(&$diagnostic_errors)
{
App::uses('File', 'Utility');

View File

@ -88,12 +88,11 @@
$rows .= sprintf('<td class="dbColumnDiagnosticRow" data-table="%s" data-index="%s">%s</td>', h($tableName), h($i), implode(' ', $saneExpected));
$rows .= sprintf('<td class="dbColumnDiagnosticRow" data-table="%s" data-index="%s">%s</td>', h($tableName), h($i), implode(' ', $saneActual));
$rows .= sprintf('<td class="" data-table="%s" data-index="%s">%s</td>', h($tableName), h($i),
empty($columnDiagnostic['SQLQueryFix']) ? '' :
empty($columnDiagnostic['sql']) ? '' :
sprintf('%s%s%s%s',
$this->Form->create('server', array('url' => 'execSQLQuery', 'style' => "margin-bottom: 0px;", 'data-ajax' => true)),
// sprintf('<i class="fa fa-wrench useCursorPointer" onclick="submitSQLQueryFix(this)" title="%s" data-query="%s"></i>', __('Fix schema'), h($columnDiagnostic['SQLQueryFix'])),
sprintf('<i class="fa fa-wrench useCursorPointer" onclick="popoverConfirm(this, \'%s\')" title="%s" data-query="%s"></i>', h($columnDiagnostic['SQLQueryFix']), __('Fix schema'), h($columnDiagnostic['SQLQueryFix'])),
$this->Form->input('sqlQuery', array('type' => 'hidden', 'value' => '123')),
sprintf('<i class="fa fa-wrench useCursorPointer" onclick="popoverConfirm(this, \'%s\', \'left\')" title="%s" data-query="%s"></i>', h($columnDiagnostic['sql']), __('Fix schema'), h($columnDiagnostic['sql'])),
$this->Form->input('sqlQuery', array('type' => 'hidden', 'value' => $columnDiagnostic['sql'])),
$this->Form->end()
)

View File

@ -227,8 +227,8 @@
echo '</div>';
?>
<h4><?php echo __('Schema status');?></h4>
<div style="width: 70vw; padding-left: 10px;">
<?php echo $this->element('/healthElements/db_schema_status', array(
<div id="schemaStatusDiv" style="width: 70vw; padding-left: 10px;">
<?php echo $this->element('/healthElements/db_schema_diagnostic', array(
'checkedTableColumn' => $dbSchemaDiagnostics['checked_table_column'],
'dbSchemaDiagnostics' => $dbSchemaDiagnostics['diagnostic'],
'expectedDbVersion' => $dbSchemaDiagnostics['expected_db_version'],

View File

@ -0,0 +1,10 @@
<?php echo $this->element('/healthElements/db_schema_diagnostic', array(
'checkedTableColumn' => $dbSchemaDiagnostics['checked_table_column'],
'dbSchemaDiagnostics' => $dbSchemaDiagnostics['diagnostic'],
'expectedDbVersion' => $dbSchemaDiagnostics['expected_db_version'],
'actualDbVersion' => $dbSchemaDiagnostics['actual_db_version'],
'error' => $dbSchemaDiagnostics['error'],
'remainingLockTime' => $dbSchemaDiagnostics['remaining_lock_time'],
'updateFailNumberReached' => $dbSchemaDiagnostics['update_fail_number_reached'],
'updateLocked' => $dbSchemaDiagnostics['update_locked']
)); ?>

View File

@ -1686,14 +1686,15 @@ function popoverPopup(clicked, id, context, target, admin) {
}
// create a confirm popover on the clicked html node.
function popoverConfirm(clicked, message) {
function popoverConfirm(clicked, message, placement) {
var $clicked = $(clicked);
var popoverContent = '<div>';
popoverContent += message === undefined ? '' : '<p>' + message + '</p>';
popoverContent += '<button id="popoverConfirmOK" class="btn btn-primary" style="margin-right: 5px;" onclick=submitPopover(this)>Yes</button>';
popoverContent += '<button class="btn btn-inverse" style="float: right;" onclick=cancelPrompt()>Cancel</button>';
popoverContent += '</div>';
openPopover($clicked, popoverContent);
placement = placement === undefined ? 'auto' : placement;
openPopover($clicked, popoverContent, undefined, placement);
$("#popoverConfirmOK")
.focus()
.bind("keydown", function(e) {
@ -1727,9 +1728,9 @@ function submitPopover(clicked) {
},
complete:function() {
$(".loading").hide();
// $("#popover_form").fadeOut();
// $("#gray_out").fadeOut();
// $('#temp').remove();
$("#popover_form").fadeOut();
$("#gray_out").fadeOut();
$('#temp').remove();
},
type:"post",
url: $form.attr('action')

File diff suppressed because one or more lines are too long