mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
parent
b52ed4ccf0
commit
c17bf2f94b
@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@ -130,7 +131,7 @@ func MigrateAPI(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, &Response{Code: "internal_error", Message: err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, &Response{Name: request.Name})
|
||||
c.JSON(http.StatusOK, &Response{Name: fmt.Sprintf("%d_%s", timestamp, request.Name)})
|
||||
default:
|
||||
c.JSON(http.StatusMethodNotAllowed, &gin.H{"message": "Method not allowed"})
|
||||
}
|
||||
|
@ -234,8 +234,7 @@ export const passRemoveUniqueKey = () => {
|
||||
};
|
||||
|
||||
export const passMTDeleteCol = () => {
|
||||
// cy.get(getElementFromAlias(`edit-${getColName(0)}`)).click();
|
||||
// cy.wait(500);
|
||||
cy.get(getElementFromAlias('modify-table-edit-column-1')).click();
|
||||
cy.get(getElementFromAlias('modify-table-column-1-remove')).click();
|
||||
cy.on('window:alert', str => {
|
||||
expect(str === 'Are you sure you want to delete?').to.be.true;
|
||||
|
@ -40,31 +40,8 @@ const showNotification = ({
|
||||
Notifications.show(
|
||||
{
|
||||
position,
|
||||
autoDismiss: level === 'error' ? 0 : 5,
|
||||
dismissible: level === 'error' ? 'click' : 'both',
|
||||
children: json ? jsonFormat(json) : null,
|
||||
...options,
|
||||
},
|
||||
level
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const showTempNotification = ({
|
||||
level = 'info',
|
||||
position = 'tr',
|
||||
json,
|
||||
...options
|
||||
} = {}) => {
|
||||
return dispatch => {
|
||||
dispatch(Notifications.removeAll());
|
||||
dispatch(
|
||||
Notifications.show(
|
||||
{
|
||||
position,
|
||||
autoDismiss: 2,
|
||||
dismissible: 'both',
|
||||
autoDismiss: ['error', 'warning'].includes(level) ? 0 : 5,
|
||||
dismissible: ['error', 'warning'].includes(level) ? 'button' : 'both',
|
||||
children: json ? jsonFormat(json) : null,
|
||||
...options,
|
||||
},
|
||||
@ -161,5 +138,4 @@ export {
|
||||
notifExpand,
|
||||
notifMsg,
|
||||
showNotification,
|
||||
showTempNotification,
|
||||
};
|
||||
|
@ -853,6 +853,10 @@ code {
|
||||
background: #f2f2f2 !important;
|
||||
}
|
||||
|
||||
.text_gray {
|
||||
color: #767E96
|
||||
}
|
||||
|
||||
.docsButton {
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
import AceEditor from 'react-ace';
|
||||
import { showNotification, showTempNotification } from '../../App/Actions';
|
||||
import { showNotification } from '../../App/Actions';
|
||||
import { notifExpand, notifMsg } from '../../App/Actions';
|
||||
import Button from '../../Common/Button/Button';
|
||||
|
||||
const styles = require('../../Common/TableCommon/Table.scss');
|
||||
|
||||
const showErrorNotification = (title, message, reqBody, error) => {
|
||||
const showErrorNotification = (title, message, error) => {
|
||||
let modMessage;
|
||||
let refreshBtn;
|
||||
|
||||
@ -36,7 +36,7 @@ const showErrorNotification = (title, message, reqBody, error) => {
|
||||
} else {
|
||||
modMessage = error.code;
|
||||
}
|
||||
} else if (error && 'internal' in error) {
|
||||
} else if (error && 'internal' in error && 'error' in error.internal) {
|
||||
modMessage = error.code + ' : ' + error.internal.error.message;
|
||||
} else if (error && 'custom' in error) {
|
||||
modMessage = error.custom;
|
||||
@ -146,19 +146,6 @@ const showSuccessNotification = (title, message) => {
|
||||
};
|
||||
};
|
||||
|
||||
const showTempErrorNotification = (title, message) => {
|
||||
return dispatch => {
|
||||
dispatch(
|
||||
showTempNotification({
|
||||
level: 'error',
|
||||
title,
|
||||
message: message ? message : null,
|
||||
autoDismiss: 3,
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const showInfoNotification = title => {
|
||||
return dispatch => {
|
||||
dispatch(
|
||||
@ -170,9 +157,42 @@ const showInfoNotification = title => {
|
||||
};
|
||||
};
|
||||
|
||||
const showWarningNotification = (title, message, dataObj) => {
|
||||
const children = [];
|
||||
if (dataObj) {
|
||||
children.push(
|
||||
<div className={styles.aceBlock}>
|
||||
<AceEditor
|
||||
readOnly
|
||||
showPrintMargin={false}
|
||||
mode="json"
|
||||
showGutter={false}
|
||||
theme="github"
|
||||
name="notification-response"
|
||||
value={JSON.stringify(dataObj, null, 4)}
|
||||
minLines={1}
|
||||
maxLines={15}
|
||||
width="100%"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return dispatch => {
|
||||
dispatch(
|
||||
showNotification({
|
||||
level: 'warning',
|
||||
title,
|
||||
message,
|
||||
children,
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export {
|
||||
showErrorNotification,
|
||||
showSuccessNotification,
|
||||
showInfoNotification,
|
||||
showTempErrorNotification,
|
||||
showWarningNotification,
|
||||
};
|
||||
|
@ -136,7 +136,6 @@ class AddTable extends Component {
|
||||
showErrorNotification(
|
||||
'Error creating table!',
|
||||
'Minimum one column required',
|
||||
'',
|
||||
{
|
||||
custom: ATLEAST_ONE_COLUMN_MSG,
|
||||
}
|
||||
@ -155,7 +154,6 @@ class AddTable extends Component {
|
||||
showErrorNotification(
|
||||
'Error creating table!',
|
||||
'Column name cannot be empty',
|
||||
'',
|
||||
{
|
||||
custom: 'Column name cannot be empty',
|
||||
}
|
||||
@ -167,7 +165,6 @@ class AddTable extends Component {
|
||||
showErrorNotification(
|
||||
gqlColumnErrorNotif[0],
|
||||
gqlColumnErrorNotif[1],
|
||||
gqlColumnErrorNotif[2],
|
||||
gqlColumnErrorNotif[3]
|
||||
)
|
||||
);
|
||||
@ -192,7 +189,6 @@ class AddTable extends Component {
|
||||
showErrorNotification(
|
||||
gqlColumnErrorNotif[0],
|
||||
gqlColumnErrorNotif[1],
|
||||
gqlColumnErrorNotif[2],
|
||||
gqlColumnErrorNotif[3]
|
||||
)
|
||||
);
|
||||
@ -214,7 +210,6 @@ class AddTable extends Component {
|
||||
showErrorNotification(
|
||||
'Error creating table!',
|
||||
'Select atleast one primary key',
|
||||
'',
|
||||
{
|
||||
custom: ATLEAST_ONE_PRIMARY_KEY_MSG,
|
||||
}
|
||||
@ -233,7 +228,6 @@ class AddTable extends Component {
|
||||
showErrorNotification(
|
||||
'Error creating table!',
|
||||
'Table name cannot be empty',
|
||||
'',
|
||||
{
|
||||
custom: 'Table name cannot be empty. Please add a name',
|
||||
}
|
||||
@ -245,7 +239,6 @@ class AddTable extends Component {
|
||||
showErrorNotification(
|
||||
gqlTableErrorNotif[0],
|
||||
gqlTableErrorNotif[1],
|
||||
gqlTableErrorNotif[2],
|
||||
gqlTableErrorNotif[3]
|
||||
)
|
||||
);
|
||||
|
@ -435,34 +435,23 @@ const setTable = tableName => ({ type: SET_TABLE, tableName });
|
||||
/* **********Shared functions between table actions********* */
|
||||
|
||||
const handleMigrationErrors = (title, errorMsg) => dispatch => {
|
||||
const requestMsg = title;
|
||||
if (globals.consoleMode === SERVER_CONSOLE_MODE) {
|
||||
// handle errors for run_sql based workflow
|
||||
dispatch(showErrorNotification(title, errorMsg.code, requestMsg, errorMsg));
|
||||
dispatch(showErrorNotification(title, errorMsg.code, errorMsg));
|
||||
} else if (errorMsg.code === 'migration_failed') {
|
||||
dispatch(
|
||||
showErrorNotification(title, 'Migration Failed', requestMsg, errorMsg)
|
||||
);
|
||||
dispatch(showErrorNotification(title, 'Migration Failed', errorMsg));
|
||||
} else if (errorMsg.code === 'data_api_error') {
|
||||
const parsedErrorMsg = errorMsg;
|
||||
parsedErrorMsg.message = JSON.parse(errorMsg.message);
|
||||
dispatch(
|
||||
showErrorNotification(
|
||||
title,
|
||||
parsedErrorMsg.message.error,
|
||||
requestMsg,
|
||||
parsedErrorMsg
|
||||
)
|
||||
showErrorNotification(title, parsedErrorMsg.message.error, parsedErrorMsg)
|
||||
);
|
||||
} else {
|
||||
// any other unhandled codes
|
||||
const parsedErrorMsg = errorMsg;
|
||||
parsedErrorMsg.message = JSON.parse(errorMsg.message);
|
||||
dispatch(
|
||||
showErrorNotification(title, errorMsg.code, requestMsg, parsedErrorMsg)
|
||||
);
|
||||
dispatch(showErrorNotification(title, errorMsg.code, parsedErrorMsg));
|
||||
}
|
||||
// dispatch(showErrorNotification(msg, firstDisplay, request, response));
|
||||
};
|
||||
|
||||
const makeMigrationCall = (
|
||||
@ -512,7 +501,7 @@ const makeMigrationCall = (
|
||||
body: JSON.stringify(finalReqBody),
|
||||
};
|
||||
|
||||
const onSuccess = () => {
|
||||
const onSuccess = data => {
|
||||
if (!shouldSkipSchemaReload) {
|
||||
if (globals.consoleMode === 'cli') {
|
||||
dispatch(loadMigrationStatus()); // don't call for server mode
|
||||
@ -522,7 +511,7 @@ const makeMigrationCall = (
|
||||
if (successMsg) {
|
||||
dispatch(showSuccessNotification(successMsg));
|
||||
}
|
||||
customOnSuccess();
|
||||
customOnSuccess(data, globals.consoleMode, currMigrationMode);
|
||||
};
|
||||
|
||||
const onError = err => {
|
||||
@ -600,7 +589,6 @@ const fetchColumnTypeInfo = () => {
|
||||
showErrorNotification(
|
||||
'Error fetching column types',
|
||||
'Kindly reach out to us in case you face this issue again',
|
||||
error,
|
||||
error
|
||||
)
|
||||
);
|
||||
|
@ -113,7 +113,6 @@ const executeSQL = (isMigration, migrationName) => (dispatch, getState) => {
|
||||
showErrorNotification(
|
||||
'SQL execution failed!',
|
||||
'Something is wrong. Data sent back an invalid response json.',
|
||||
requestBody,
|
||||
parsedErrorMsg
|
||||
)
|
||||
);
|
||||
|
@ -13,7 +13,6 @@ export const createNewSchema = (schemaName, successCb, errorCb) => {
|
||||
showErrorNotification(
|
||||
gqlSchemaErrorNotif[0],
|
||||
gqlSchemaErrorNotif[1],
|
||||
gqlSchemaErrorNotif[2],
|
||||
gqlSchemaErrorNotif[3]
|
||||
)
|
||||
);
|
||||
|
@ -95,9 +95,7 @@ const editItem = (tableName, colValues) => {
|
||||
);
|
||||
},
|
||||
err => {
|
||||
dispatch(
|
||||
showErrorNotification('Edit failed!', err.error, reqBody, err)
|
||||
);
|
||||
dispatch(showErrorNotification('Edit failed!', err.error, err));
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -195,9 +195,7 @@ const deleteItem = pkClause => {
|
||||
);
|
||||
},
|
||||
err => {
|
||||
dispatch(
|
||||
showErrorNotification('Deleting row failed!', err.error, reqBody, err)
|
||||
);
|
||||
dispatch(showErrorNotification('Deleting row failed!', err.error, err));
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -100,9 +100,7 @@ const insertItem = (tableName, colValues) => {
|
||||
);
|
||||
},
|
||||
err => {
|
||||
dispatch(
|
||||
showErrorNotification('Insert failed!', err.error, reqBody, err)
|
||||
);
|
||||
dispatch(showErrorNotification('Insert failed!', err.error, err));
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -38,7 +38,6 @@ const useColumnEditor = (dispatch, tableName) => {
|
||||
showErrorNotification(
|
||||
gqlColumnErrorNotif[0],
|
||||
gqlColumnErrorNotif[1],
|
||||
gqlColumnErrorNotif[2],
|
||||
gqlColumnErrorNotif[3]
|
||||
)
|
||||
);
|
||||
@ -47,7 +46,6 @@ const useColumnEditor = (dispatch, tableName) => {
|
||||
showErrorNotification(
|
||||
'Error creating column!',
|
||||
'Column name/type cannot be empty',
|
||||
'',
|
||||
{
|
||||
custom: 'Column name/type cannot be empty',
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import SearchableSelectBox from '../../../Common/SearchableSelect/SearchableSelect';
|
||||
import CustomInputAutoSuggest from '../../../Common/CustomInputAutoSuggest/CustomInputAutoSuggest';
|
||||
@ -8,7 +8,6 @@ import { getValidAlterOptions } from './utils';
|
||||
const ColumnEditor = ({
|
||||
onSubmit,
|
||||
dispatch,
|
||||
columnComment,
|
||||
columnProperties,
|
||||
selectedProperties,
|
||||
editColumn,
|
||||
@ -23,12 +22,6 @@ const ColumnEditor = ({
|
||||
|
||||
const styles = require('./ModifyTable.scss');
|
||||
|
||||
useEffect(() => {
|
||||
if (columnComment) {
|
||||
dispatch(editColumn(colName, 'comment', columnComment || ''));
|
||||
}
|
||||
}, [columnComment]);
|
||||
|
||||
const getColumnType = () => {
|
||||
return (
|
||||
colName in selectedProperties &&
|
||||
@ -78,7 +71,7 @@ const ColumnEditor = ({
|
||||
dispatch(editColumn(colName, 'isUnique', e.target.value === 'true'));
|
||||
};
|
||||
|
||||
const getDefaultInput = () => {
|
||||
const getColumnDefaultInput = () => {
|
||||
const theme = require('../../../Common/CustomInputAutoSuggest/CustomThemes/EditColumnDefault.scss');
|
||||
|
||||
return (
|
||||
@ -156,19 +149,7 @@ const ColumnEditor = ({
|
||||
</div>
|
||||
<div className={`${styles.display_flex} form-group`}>
|
||||
<label className="col-xs-2">Default</label>
|
||||
<div className="col-xs-6">
|
||||
{getDefaultInput()}
|
||||
{/*
|
||||
<input
|
||||
className="input-sm form-control"
|
||||
value={selectedProperties[colName].default || ''}
|
||||
onChange={updateColumnDef}
|
||||
type="text"
|
||||
disabled={columnProperties.pkConstraint}
|
||||
data-test="edit-col-default"
|
||||
/>
|
||||
*/}
|
||||
</div>
|
||||
<div className="col-xs-6">{getColumnDefaultInput()}</div>
|
||||
</div>
|
||||
<div className={`${styles.display_flex} form-group`}>
|
||||
<label className="col-xs-2">Comment</label>
|
||||
|
@ -71,16 +71,17 @@ const ColumnEditorList = ({
|
||||
: false,
|
||||
// uniqueConstraint: columnUniqueConstraints[colName],
|
||||
default: col.column_default || '',
|
||||
comment: col.comment || '',
|
||||
};
|
||||
|
||||
const onSubmit = () => {
|
||||
dispatch(saveColumnChangesSql(colName, col));
|
||||
const onSubmit = toggleEditor => {
|
||||
dispatch(saveColumnChangesSql(colName, col, toggleEditor));
|
||||
};
|
||||
|
||||
const onDelete = () => {
|
||||
const isOk = confirm('Are you sure you want to delete?');
|
||||
if (isOk) {
|
||||
dispatch(deleteColumnSql(tableName, colName, col));
|
||||
dispatch(deleteColumnSql(col, tableSchema));
|
||||
}
|
||||
};
|
||||
|
||||
@ -91,11 +92,13 @@ const ColumnEditorList = ({
|
||||
}
|
||||
const isOk = window.confirm(confirmMessage);
|
||||
if (isOk) {
|
||||
dispatch(deleteColumnSql(tableName, colName, col));
|
||||
dispatch(deleteColumnSql(col, tableSchema));
|
||||
}
|
||||
};
|
||||
|
||||
const keyProperties = () => {
|
||||
const propertiesDisplay = [];
|
||||
|
||||
const propertiesList = [];
|
||||
|
||||
propertiesList.push(columnProperties.display_type_name);
|
||||
@ -118,7 +121,17 @@ const ColumnEditorList = ({
|
||||
|
||||
const keyPropertiesString = propertiesList.join(', ');
|
||||
|
||||
return <i>{keyPropertiesString && `- ${keyPropertiesString}`}</i>;
|
||||
propertiesDisplay.push(
|
||||
<i key={'props'}>{keyPropertiesString && `- ${keyPropertiesString}`}</i>
|
||||
);
|
||||
propertiesDisplay.push(<br />);
|
||||
propertiesDisplay.push(
|
||||
<span key={'comment'} className={styles.text_gray}>
|
||||
{columnProperties.comment && `${columnProperties.comment}`}
|
||||
</span>
|
||||
);
|
||||
|
||||
return propertiesDisplay;
|
||||
};
|
||||
|
||||
const collapsedLabel = () => {
|
||||
@ -192,7 +205,6 @@ const ColumnEditorList = ({
|
||||
tableName={tableName}
|
||||
dispatch={dispatch}
|
||||
currentSchema={currentSchema}
|
||||
columnComment={col.comment}
|
||||
columnProperties={columnProperties}
|
||||
selectedProperties={columnEdit}
|
||||
editColumn={editColumn}
|
||||
|
@ -11,6 +11,7 @@ import { SET_SQL } from '../RawSQL/Actions';
|
||||
import {
|
||||
showErrorNotification,
|
||||
showSuccessNotification,
|
||||
showWarningNotification,
|
||||
} from '../../Common/Notification';
|
||||
import dataHeaders from '../Common/Headers';
|
||||
import { UPDATE_MIGRATION_STATUS_ERROR } from '../../../Main/Actions';
|
||||
@ -497,7 +498,6 @@ const changeTableOrViewName = (isTable, oldName, newName) => {
|
||||
showErrorNotification(
|
||||
gqlValidationError[4],
|
||||
gqlValidationError[1],
|
||||
gqlValidationError[2],
|
||||
gqlValidationError[3]
|
||||
)
|
||||
);
|
||||
@ -750,12 +750,7 @@ const fetchViewDefinition = (viewName, isRedirect) => {
|
||||
},
|
||||
err => {
|
||||
dispatch(
|
||||
showErrorNotification(
|
||||
'Fetching definition failed!',
|
||||
err.error,
|
||||
reqBody,
|
||||
err
|
||||
)
|
||||
showErrorNotification('Fetching definition failed!', err.error, err)
|
||||
);
|
||||
}
|
||||
);
|
||||
@ -808,11 +803,143 @@ const deleteViewSql = viewName => {
|
||||
};
|
||||
};
|
||||
|
||||
const deleteColumnSql = (tableName, colName) => {
|
||||
const deleteColumnSql = (column, tableSchema) => {
|
||||
return (dispatch, getState) => {
|
||||
const currentSchema = getState().tables.currentSchema;
|
||||
const deleteQueryUp =
|
||||
'ALTER TABLE ' +
|
||||
const name = column.column_name;
|
||||
const tableName = column.table_name;
|
||||
const currentSchema = column.table_schema;
|
||||
const comment = column.comment;
|
||||
const is_nullable = column.is_nullable;
|
||||
const col_type = column.udt_name;
|
||||
const foreign_key_constraints = tableSchema.foreign_key_constraints.filter(
|
||||
fkc => {
|
||||
const columnKeys = Object.keys(fkc.column_mapping);
|
||||
return columnKeys.includes(name);
|
||||
}
|
||||
);
|
||||
const opp_foreign_key_constraints = tableSchema.opp_foreign_key_constraints.filter(
|
||||
fkc => {
|
||||
const columnKeys = Object.values(fkc.column_mapping);
|
||||
return columnKeys.includes(name);
|
||||
}
|
||||
);
|
||||
const unique_constraints = tableSchema.unique_constraints.filter(uc =>
|
||||
uc.columns.includes(name)
|
||||
);
|
||||
const alterStatement =
|
||||
'ALTER TABLE ' + '"' + currentSchema + '"' + '.' + '"' + tableName + '" ';
|
||||
|
||||
const schemaChangesUp = [
|
||||
{
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql: alterStatement + 'DROP COLUMN ' + '"' + name + '" CASCADE',
|
||||
},
|
||||
},
|
||||
];
|
||||
const schemaChangesDown = [];
|
||||
|
||||
schemaChangesDown.push({
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql: alterStatement + 'ADD COLUMN ' + '"' + name + '"' + ' ' + col_type,
|
||||
},
|
||||
});
|
||||
|
||||
if (is_nullable) {
|
||||
schemaChangesDown.push({
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql:
|
||||
alterStatement +
|
||||
'ALTER COLUMN ' +
|
||||
'"' +
|
||||
name +
|
||||
'" ' +
|
||||
'DROP NOT NULL',
|
||||
},
|
||||
});
|
||||
} else {
|
||||
schemaChangesDown.push({
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql:
|
||||
alterStatement +
|
||||
'ALTER COLUMN ' +
|
||||
'"' +
|
||||
name +
|
||||
'" ' +
|
||||
'SET NOT NULL',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const merged_fkc = foreign_key_constraints.concat(opp_foreign_key_constraints);
|
||||
if (merged_fkc.length > 0) {
|
||||
merged_fkc.forEach(fkc => {
|
||||
// add foreign key constraint to down migration
|
||||
const lcol = Object.keys(fkc.column_mapping);
|
||||
const rcol = Object.values(fkc.column_mapping);
|
||||
const onUpdate = pgConfTypes[fkc.on_update];
|
||||
const onDelete = pgConfTypes[fkc.on_delete];
|
||||
schemaChangesDown.push({
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql:
|
||||
alterStatement +
|
||||
'ADD CONSTRAINT ' +
|
||||
`${fkc.constraint_name} ` +
|
||||
'FOREIGN KEY ' +
|
||||
`(${lcol.join(', ')}) ` +
|
||||
'REFERENCES ' +
|
||||
`"${fkc.ref_table_table_schema}"."${fkc.ref_table}" ` +
|
||||
`(${rcol.join(', ')}) ` +
|
||||
`ON DELETE ${onDelete} ` +
|
||||
`ON UPDATE ${onUpdate}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (unique_constraints.length > 0) {
|
||||
unique_constraints.forEach(uc => {
|
||||
// add unique constraint to down migration
|
||||
schemaChangesDown.push({
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql:
|
||||
alterStatement +
|
||||
'ADD CONSTRAINT ' +
|
||||
`${uc.constraint_name} ` +
|
||||
'UNIQUE ' +
|
||||
`(${uc.columns.join(', ')})`,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (column.column_default !== null) {
|
||||
// add column default to down migration
|
||||
schemaChangesDown.push({
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql:
|
||||
alterStatement +
|
||||
'ALTER COLUMN ' +
|
||||
`"${name}" ` +
|
||||
'SET DEFAULT ' +
|
||||
column.column_default,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// COMMENT ON COLUMN my_table.my_column IS 'Employee ID number';
|
||||
if (comment) {
|
||||
schemaChangesDown.push({
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql:
|
||||
'COMMENT ON COLUMN ' +
|
||||
'"' +
|
||||
currentSchema +
|
||||
'"' +
|
||||
@ -820,49 +947,47 @@ const deleteColumnSql = (tableName, colName) => {
|
||||
'"' +
|
||||
tableName +
|
||||
'"' +
|
||||
' DROP COLUMN ' +
|
||||
'.' +
|
||||
'"' +
|
||||
colName +
|
||||
'"';
|
||||
const schemaChangesUp = [
|
||||
{
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
sql: deleteQueryUp,
|
||||
name +
|
||||
'"' +
|
||||
' ' +
|
||||
'IS ' +
|
||||
"'" +
|
||||
comment +
|
||||
"'",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
/*
|
||||
const schemaChangesDown = [{
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
'sql': deleteQueryDown
|
||||
});
|
||||
}
|
||||
}];
|
||||
*/
|
||||
|
||||
// Apply migrations
|
||||
const migrationName =
|
||||
'alter_table_' +
|
||||
currentSchema +
|
||||
'_' +
|
||||
tableName +
|
||||
'_drop_column_' +
|
||||
colName;
|
||||
'alter_table_' + currentSchema + '_' + tableName + '_drop_column_' + name;
|
||||
|
||||
const requestMsg = 'Deleting Column...';
|
||||
const successMsg = 'Column deleted';
|
||||
const errorMsg = 'Deleting column failed';
|
||||
|
||||
const customOnSuccess = () => {};
|
||||
const customOnSuccess = (data, consoleMode, migrationMode) => {
|
||||
if (consoleMode === 'cli' && migrationMode) {
|
||||
// show warning information
|
||||
dispatch(
|
||||
showWarningNotification(
|
||||
'Check down migration',
|
||||
'Please verify that the down migration will reset the DB to the previous state (you ' +
|
||||
'might need to add recreation of some dependent objects like indexes, etc.)',
|
||||
data
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
const customOnError = () => {};
|
||||
|
||||
makeMigrationCall(
|
||||
dispatch,
|
||||
getState,
|
||||
schemaChangesUp,
|
||||
[],
|
||||
schemaChangesDown,
|
||||
migrationName,
|
||||
customOnSuccess,
|
||||
customOnError,
|
||||
@ -1159,7 +1284,7 @@ const isColumnUnique = (tableSchema, colName) => {
|
||||
);
|
||||
};
|
||||
|
||||
const saveColumnChangesSql = (colName, column) => {
|
||||
const saveColumnChangesSql = (colName, column, onSuccess) => {
|
||||
// eslint-disable-line no-unused-vars
|
||||
return (dispatch, getState) => {
|
||||
const columnEdit = getState().tables.modify.columnEdit[colName];
|
||||
@ -1663,7 +1788,6 @@ const saveColumnChangesSql = (colName, column) => {
|
||||
showErrorNotification(
|
||||
gqlColumnErrorNotif[4],
|
||||
gqlColumnErrorNotif[1],
|
||||
gqlColumnErrorNotif[2],
|
||||
gqlColumnErrorNotif[3]
|
||||
)
|
||||
);
|
||||
@ -1696,7 +1820,8 @@ const saveColumnChangesSql = (colName, column) => {
|
||||
const errorMsg = 'Modifying column failed';
|
||||
|
||||
const customOnSuccess = () => {
|
||||
dispatch(setColumnEdit(columnEdit));
|
||||
dispatch(resetColumnEdit(colName));
|
||||
onSuccess();
|
||||
};
|
||||
const customOnError = () => {};
|
||||
|
||||
@ -1750,7 +1875,6 @@ const fetchColumnCasts = () => {
|
||||
showErrorNotification(
|
||||
'Error fetching column casts information',
|
||||
'Kindly reach out to us in case you face this issue again',
|
||||
error,
|
||||
error
|
||||
)
|
||||
);
|
||||
|
@ -371,7 +371,6 @@ const addRelViewMigrate = (tableSchema, toggleEditor) => (
|
||||
showErrorNotification(
|
||||
'Error adding relationship!',
|
||||
'Please select a name for the relationship',
|
||||
'',
|
||||
{ custom: 'Relationship name cannot be empty' }
|
||||
)
|
||||
);
|
||||
@ -380,7 +379,6 @@ const addRelViewMigrate = (tableSchema, toggleEditor) => (
|
||||
showErrorNotification(
|
||||
gqlRelErrorNotif[0],
|
||||
gqlRelErrorNotif[1],
|
||||
gqlRelErrorNotif[2],
|
||||
gqlRelErrorNotif[3]
|
||||
)
|
||||
);
|
||||
|
@ -52,7 +52,6 @@ class RelationshipEditor extends React.Component {
|
||||
showErrorNotification(
|
||||
gqlRelErrorNotif[4],
|
||||
gqlRelErrorNotif[1],
|
||||
gqlRelErrorNotif[2],
|
||||
gqlRelErrorNotif[3]
|
||||
)
|
||||
);
|
||||
|
@ -52,7 +52,6 @@ const addRelationshipCellView = (
|
||||
showErrorNotification(
|
||||
'Error adding relationship!',
|
||||
'Please select a name for the relationship',
|
||||
'',
|
||||
{ custom: 'Relationship name cannot be empty' }
|
||||
)
|
||||
);
|
||||
@ -62,7 +61,6 @@ const addRelationshipCellView = (
|
||||
showErrorNotification(
|
||||
gqlRelErrorNotif[0],
|
||||
gqlRelErrorNotif[1],
|
||||
gqlRelErrorNotif[2],
|
||||
gqlRelErrorNotif[3]
|
||||
)
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import defaultState from './AddState';
|
||||
import _push from '../push';
|
||||
import { loadTriggers, makeMigrationCall, setTrigger } from '../EventActions';
|
||||
import { showSuccessNotification } from '../Notification';
|
||||
import { showSuccessNotification } from '../../Common/Notification';
|
||||
import { UPDATE_MIGRATION_STATUS_ERROR } from '../../../Main/Actions';
|
||||
import { updateSchemaInfo } from '../../Data/DataActions';
|
||||
|
||||
|
@ -27,7 +27,7 @@ import {
|
||||
loadTableList,
|
||||
} from './AddActions';
|
||||
import { listDuplicate } from '../../../../utils/data';
|
||||
import { showErrorNotification } from '../Notification';
|
||||
import { showErrorNotification } from '../../Common/Notification';
|
||||
import { createTrigger } from './AddActions';
|
||||
|
||||
import DropdownButton from '../../../Common/DropdownButton/DropdownButton';
|
||||
@ -146,7 +146,7 @@ class AddTrigger extends Component {
|
||||
this.props.dispatch(createTrigger());
|
||||
} else {
|
||||
this.props.dispatch(
|
||||
showErrorNotification('Error creating trigger!', errorMsg, '', {
|
||||
showErrorNotification('Error creating trigger!', errorMsg, {
|
||||
custom: customMsg,
|
||||
})
|
||||
);
|
||||
|
@ -5,7 +5,10 @@ import processedEventsReducer from './ProcessedEvents/ViewActions';
|
||||
import pendingEventsReducer from './PendingEvents/ViewActions';
|
||||
import runningEventsReducer from './RunningEvents/ViewActions';
|
||||
import streamingLogsReducer from './StreamingLogs/LogActions';
|
||||
import { showErrorNotification, showSuccessNotification } from './Notification';
|
||||
import {
|
||||
showSuccessNotification,
|
||||
showErrorNotification,
|
||||
} from '../Common/Notification';
|
||||
import dataHeaders from './Common/Headers';
|
||||
import { loadMigrationStatus } from '../../Main/Actions';
|
||||
import returnMigrateUrl from './Common/getMigrateUrl';
|
||||
@ -317,34 +320,23 @@ const setRedeliverEvent = eventId => dispatch => {
|
||||
/* **********Shared functions between table actions********* */
|
||||
|
||||
const handleMigrationErrors = (title, errorMsg) => dispatch => {
|
||||
const requestMsg = title;
|
||||
if (globals.consoleMode === SERVER_CONSOLE_MODE) {
|
||||
// handle errors for run_sql based workflow
|
||||
dispatch(showErrorNotification(title, errorMsg.code, requestMsg, errorMsg));
|
||||
dispatch(showErrorNotification(title, errorMsg.code, errorMsg));
|
||||
} else if (errorMsg.code === 'migration_failed') {
|
||||
dispatch(
|
||||
showErrorNotification(title, 'Migration Failed', requestMsg, errorMsg)
|
||||
);
|
||||
dispatch(showErrorNotification(title, 'Migration Failed', errorMsg));
|
||||
} else if (errorMsg.code === 'data_api_error') {
|
||||
const parsedErrorMsg = errorMsg;
|
||||
parsedErrorMsg.message = JSON.parse(errorMsg.message);
|
||||
dispatch(
|
||||
showErrorNotification(
|
||||
title,
|
||||
parsedErrorMsg.message.error,
|
||||
requestMsg,
|
||||
parsedErrorMsg
|
||||
)
|
||||
showErrorNotification(title, parsedErrorMsg.message.error, parsedErrorMsg)
|
||||
);
|
||||
} else {
|
||||
// any other unhandled codes
|
||||
const parsedErrorMsg = errorMsg;
|
||||
parsedErrorMsg.message = JSON.parse(errorMsg.message);
|
||||
dispatch(
|
||||
showErrorNotification(title, errorMsg.code, requestMsg, parsedErrorMsg)
|
||||
);
|
||||
dispatch(showErrorNotification(title, errorMsg.code, parsedErrorMsg));
|
||||
}
|
||||
// dispatch(showErrorNotification(msg, firstDisplay, request, response));
|
||||
};
|
||||
|
||||
const makeMigrationCall = (
|
||||
|
@ -1,7 +1,7 @@
|
||||
import defaultState from './State';
|
||||
import { loadTriggers, makeMigrationCall, setTrigger } from '../EventActions';
|
||||
import { UPDATE_MIGRATION_STATUS_ERROR } from '../../../Main/Actions';
|
||||
import { showErrorNotification } from '../Notification';
|
||||
import { showErrorNotification } from '../../Common/Notification';
|
||||
|
||||
import { MANUAL_TRIGGER_VAR } from './utils';
|
||||
|
||||
@ -70,7 +70,7 @@ export const REQUEST_COMPLETE = 'ModifyTrigger/REQUEST_COMPLETE';
|
||||
export const showValidationError = message => {
|
||||
return dispatch => {
|
||||
dispatch(
|
||||
showErrorNotification('Error modifying trigger!', 'Invalid input', '', {
|
||||
showErrorNotification('Error modifying trigger!', 'Invalid input', {
|
||||
custom: message,
|
||||
})
|
||||
);
|
||||
|
@ -1,178 +0,0 @@
|
||||
import React from 'react';
|
||||
import AceEditor from 'react-ace';
|
||||
import { showNotification, showTempNotification } from '../../App/Actions';
|
||||
import { notifExpand, notifMsg } from '../../App/Actions';
|
||||
import Button from '../../Common/Button/Button';
|
||||
|
||||
const styles = require('../../Common/TableCommon/Table.scss');
|
||||
|
||||
const showErrorNotification = (title, message, reqBody, error) => {
|
||||
let modMessage;
|
||||
let refreshBtn;
|
||||
|
||||
if (
|
||||
error &&
|
||||
error.message &&
|
||||
(error.message.error === 'postgres query error' ||
|
||||
error.message.error === 'query execution failed')
|
||||
) {
|
||||
if (error.message.internal) {
|
||||
modMessage =
|
||||
error.message.code + ': ' + error.message.internal.error.message;
|
||||
} else {
|
||||
modMessage = error.code + ': ' + error.message.error;
|
||||
}
|
||||
} else if (error && 'info' in error) {
|
||||
modMessage = error.info;
|
||||
} else if (error && 'message' in error) {
|
||||
if (error.code) {
|
||||
if (error.message.error) {
|
||||
modMessage = error.message.error.message;
|
||||
} else {
|
||||
modMessage = error.message;
|
||||
}
|
||||
} else if (error && error.message && 'code' in error.message) {
|
||||
modMessage = error.message.code + ' : ' + message;
|
||||
} else {
|
||||
modMessage = error.code;
|
||||
}
|
||||
} else if (error && 'internal' in error) {
|
||||
modMessage = error.code + ' : ' + error.internal.error.message;
|
||||
} else if (error && 'custom' in error) {
|
||||
modMessage = error.custom;
|
||||
} else if (error && 'code' in error && 'error' in error && 'path' in error) {
|
||||
// Data API error
|
||||
modMessage = error.error;
|
||||
} else {
|
||||
modMessage = error ? error : message;
|
||||
}
|
||||
|
||||
let finalJson = error ? error.message : '{}';
|
||||
|
||||
if (error && 'action' in error) {
|
||||
refreshBtn = (
|
||||
<Button
|
||||
className={styles.add_mar_top_small}
|
||||
color="yellow"
|
||||
size="sm"
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
window.location.reload();
|
||||
}}
|
||||
>
|
||||
Refresh Console
|
||||
</Button>
|
||||
);
|
||||
finalJson = error.action;
|
||||
} else if (error && 'internal' in error) {
|
||||
finalJson = error.internal;
|
||||
}
|
||||
|
||||
return dispatch => {
|
||||
const expandClicked = finalMsg => {
|
||||
// trigger a modal with a bigger view
|
||||
dispatch(notifExpand(true));
|
||||
dispatch(notifMsg(JSON.stringify(finalMsg, null, 4)));
|
||||
};
|
||||
|
||||
const getNotificationAction = () => {
|
||||
let action = null;
|
||||
|
||||
if (reqBody) {
|
||||
const notification = [
|
||||
<div className={styles.aceBlock}>
|
||||
<i
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
expandClicked(finalJson);
|
||||
}}
|
||||
className={styles.aceBlockExpand + ' fa fa-expand'}
|
||||
/>
|
||||
<AceEditor
|
||||
readOnly
|
||||
showPrintMargin={false}
|
||||
mode="json"
|
||||
showGutter={false}
|
||||
theme="github"
|
||||
name="notification-response"
|
||||
value={JSON.stringify(finalJson, null, 4)}
|
||||
minLines={1}
|
||||
maxLines={15}
|
||||
width="100%"
|
||||
/>
|
||||
{refreshBtn}
|
||||
</div>,
|
||||
];
|
||||
|
||||
action = {
|
||||
label: 'Details',
|
||||
callback: () => {
|
||||
dispatch(
|
||||
showNotification({
|
||||
level: 'error',
|
||||
title,
|
||||
message: modMessage,
|
||||
dismissible: 'button',
|
||||
children: notification,
|
||||
})
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return action;
|
||||
};
|
||||
|
||||
dispatch(
|
||||
showNotification({
|
||||
level: 'error',
|
||||
title,
|
||||
message: modMessage,
|
||||
action: getNotificationAction(),
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const showSuccessNotification = (title, message) => {
|
||||
return dispatch => {
|
||||
dispatch(
|
||||
showNotification({
|
||||
level: 'success',
|
||||
title,
|
||||
message: message ? message : null,
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const showTempErrorNotification = (title, message) => {
|
||||
return dispatch => {
|
||||
dispatch(
|
||||
showTempNotification({
|
||||
level: 'error',
|
||||
title,
|
||||
message: message ? message : null,
|
||||
autoDismiss: 3,
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const showInfoNotification = title => {
|
||||
return dispatch => {
|
||||
dispatch(
|
||||
showNotification({
|
||||
title,
|
||||
autoDismiss: 0,
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export {
|
||||
showErrorNotification,
|
||||
showSuccessNotification,
|
||||
showInfoNotification,
|
||||
showTempErrorNotification,
|
||||
};
|
@ -6,7 +6,7 @@ import { findTableFromRel } from '../utils';
|
||||
import {
|
||||
showSuccessNotification,
|
||||
showErrorNotification,
|
||||
} from '../Notification';
|
||||
} from '../../Common/Notification';
|
||||
import dataHeaders from '../Common/Headers';
|
||||
|
||||
/* ****************** View actions *************/
|
||||
@ -192,9 +192,7 @@ const deleteItem = pkClause => {
|
||||
);
|
||||
},
|
||||
err => {
|
||||
dispatch(
|
||||
showErrorNotification('Deleting row failed!', err.error, reqBody, err)
|
||||
);
|
||||
dispatch(showErrorNotification('Deleting row failed!', err.error, err));
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -306,7 +306,6 @@ export const addAllowedQueries = (queries, isEmptyList, callback) => {
|
||||
showErrorNotification(
|
||||
'Adding query to allow-list failed',
|
||||
null,
|
||||
null,
|
||||
error
|
||||
)
|
||||
);
|
||||
@ -338,7 +337,6 @@ export const deleteAllowList = () => {
|
||||
showErrorNotification(
|
||||
'Deleting queries from allow-list failed',
|
||||
null,
|
||||
null,
|
||||
error
|
||||
)
|
||||
);
|
||||
@ -372,7 +370,6 @@ export const deleteAllowedQuery = (queryName, isLastQuery) => {
|
||||
showErrorNotification(
|
||||
'Deleting query from allow-list failed',
|
||||
null,
|
||||
null,
|
||||
error
|
||||
)
|
||||
);
|
||||
@ -399,12 +396,7 @@ export const updateAllowedQuery = (queryName, newQuery) => {
|
||||
error => {
|
||||
console.error(error);
|
||||
dispatch(
|
||||
showErrorNotification(
|
||||
'Updating allow-list query failed',
|
||||
null,
|
||||
null,
|
||||
error
|
||||
)
|
||||
showErrorNotification('Updating allow-list query failed', null, error)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -63,7 +63,6 @@ class ExportMetadata extends Component {
|
||||
showErrorNotification(
|
||||
'Metadata export failed',
|
||||
'Something is wrong.',
|
||||
requestBody,
|
||||
parsedErrorMsg
|
||||
)
|
||||
);
|
||||
|
@ -63,7 +63,6 @@ class ImportMetadata extends Component {
|
||||
showErrorNotification(
|
||||
'Metadata import failed',
|
||||
'Something is wrong.',
|
||||
requestBody,
|
||||
parsedErrorMsg
|
||||
)
|
||||
);
|
||||
|
@ -66,7 +66,6 @@ class ResetMetadata extends Component {
|
||||
showErrorNotification(
|
||||
'Metadata reset failed',
|
||||
'Something went wrong.',
|
||||
requestBody,
|
||||
parsedErrorMsg
|
||||
)
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user