Add option to generate SQL with DROP table DDL in ERD Tool. #4997

This commit is contained in:
Aditya Toshniwal
2022-10-06 09:30:45 +05:30
committed by GitHub
parent cc55c8db89
commit b086e1fd83
14 changed files with 104 additions and 20 deletions

View File

@@ -1627,7 +1627,7 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
if status:
self.cmd = 'delete'
sql = super(TableView, self).get_delete_sql(res)
sql = super(TableView, self).get_delete_sql(res['rows'][0])
self.cmd = None
return sql

View File

@@ -1442,7 +1442,8 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
if 'relacl' in data:
data['relacl'] = parse_priv_to_db(data['relacl'], self.acl)
def get_sql(self, did, scid, tid, data, res, add_not_exists_clause=False):
def get_sql(self, did, scid, tid, data, res, add_not_exists_clause=False,
with_drop=False):
"""
This function will generate create/update sql from model data
coming from client
@@ -1539,10 +1540,14 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
# Update the vacuum toast table settings.
self.update_vacuum_settings('vacuum_toast', data)
sql = render_template("/".join([self.table_template_path,
sql = ''
if with_drop:
sql = self.get_delete_sql(data) + '\n\n'
sql += render_template("/".join([self.table_template_path,
self._CREATE_SQL]),
data=data, conn=self.conn,
add_not_exists_clause=add_not_exists_clause)
data=data, conn=self.conn,
add_not_exists_clause=add_not_exists_clause)
# Append SQL for partitions
sql += '\n' + partitions_sql
@@ -1969,12 +1974,10 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
}
)
def get_delete_sql(self, res):
def get_delete_sql(self, data):
# Below will decide if it's simple drop or drop with cascade call
cascade = self._check_cascade_operation()
data = res['rows'][0]
return render_template(
"/".join([self.table_template_path, self._DELETE_SQL]),
data=data, cascade=cascade,
@@ -1993,7 +1996,7 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
tid: Table ID
"""
sql = self.get_delete_sql(res)
sql = self.get_delete_sql(res['rows'][0])
status, res = self.conn.execute_scalar(sql)
if not status:

View File

@@ -28,7 +28,7 @@ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
from pgadmin.browser.server_groups.servers.databases.schemas.tables. \
constraints.foreign_key import utils as fkey_utils
from pgadmin.utils.constants import PREF_LABEL_KEYBOARD_SHORTCUTS, \
PREF_LABEL_DISPLAY
PREF_LABEL_DISPLAY, PREF_LABEL_OPTIONS
from .utils import ERDHelper
from pgadmin.utils.exception import ConnectionLost
@@ -371,6 +371,19 @@ class ERDModule(PgAdminModule):
fields=shortcut_fields
)
self.preference.register(
'options',
'sql_with_drop',
gettext('SQL With DROP Table'),
'boolean',
False,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'If enabled, the SQL generated by the ERD Tool will add '
'DROP table DDL before each CREATE table DDL.'
)
)
blueprint = ERDModule(MODULE_NAME, __name__, static_url_path='/static')
@@ -562,6 +575,10 @@ def translate_foreign_keys(tab_fks, tab_data, all_nodes):
@login_required
def sql(trans_id, sgid, sid, did):
data = json.loads(request.data, encoding='utf-8')
with_drop = False
if request.args and 'with_drop' in request.args:
with_drop = True if request.args.get('with_drop') == 'true' else False
helper = ERDHelper(trans_id, sid, did)
conn = _get_connection(sid, did, trans_id)
@@ -572,7 +589,7 @@ def sql(trans_id, sgid, sid, did):
tab_fks = tab_data.pop('foreign_key', [])
tab_foreign_keys.extend(translate_foreign_keys(tab_fks, tab_data,
all_nodes))
sql += '\n\n' + helper.get_table_sql(tab_data)
sql += '\n\n' + helper.get_table_sql(tab_data, with_drop=with_drop)
for tab_fk in tab_foreign_keys:
fk_sql, name = fkey_utils.get_sql(conn, tab_fk, None)

View File

@@ -1,6 +1,7 @@
export const ERD_EVENTS = {
LOAD_DIAGRAM: 'LOAD_DIAGRAM',
SAVE_DIAGRAM: 'SAVE_DIAGRAM',
TRIGGER_SHOW_SQL: 'TRIGGER_SHOW_SQL',
SHOW_SQL: 'SHOW_SQL',
DOWNLOAD_IMAGE: 'DOWNLOAD_IMAGE',
ADD_NODE: 'ADD_NODE',

View File

@@ -234,7 +234,7 @@ class ERDTool extends React.Component {
this.eventBus.fireEvent(ERD_EVENTS.SAVE_DIAGRAM, true);
}],
[this.state.preferences.generate_sql, ()=>{
this.eventBus.fireEvent(ERD_EVENTS.SHOW_SQL);
this.eventBus.fireEvent(ERD_EVENTS.TRIGGER_SHOW_SQL);
}],
[this.state.preferences.download_image, ()=>{
this.eventBus.fireEvent(ERD_EVENTS.DOWNLOAD_IMAGE);
@@ -619,7 +619,7 @@ class ERDTool extends React.Component {
}
}
onSQLClick() {
onSQLClick(sqlWithDrop=false) {
let scriptHeader = gettext('-- This script was generated by a beta version of the ERD tool in pgAdmin 4.\n');
scriptHeader += gettext('-- Please log an issue at https://redmine.postgresql.org/projects/pgadmin4/issues/new if you find any bugs, including reproduction steps.\n');
@@ -630,6 +630,10 @@ class ERDTool extends React.Component {
did: this.props.params.did,
});
if(sqlWithDrop) {
url += '?with_drop=true';
}
this.setLoading(gettext('Preparing the SQL...'));
this.apiObj.post(url, this.diagram.serializeData())
.then((resp)=>{

View File

@@ -69,13 +69,25 @@ export function MainToolBar({preferences, eventBus}) {
const {openMenuName, toggleMenu, onMenuClose} = usePgMenuGroup();
const saveAsMenuRef = React.useRef(null);
const sqlMenuRef = React.useRef(null);
const isDirtyRef = React.useRef(null);
const [checkedMenuItems, setCheckedMenuItems] = React.useState({});
const modal = useModal();
const setDisableButton = useCallback((name, disable=true)=>{
setButtonsDisabled((prev)=>({...prev, [name]: disable}));
}, []);
const checkMenuClick = useCallback((e)=>{
setCheckedMenuItems((prev)=>{
let newVal = !prev[e.value];
return {
...prev,
[e.value]: newVal,
};
});
}, []);
const onHelpClick=()=>{
let url = url_for('help.static', {'filename': 'erd_tool.html'});
window.open(url, 'pgadmin_help');
@@ -98,6 +110,17 @@ export function MainToolBar({preferences, eventBus}) {
);
};
useEffect(()=>{
if(preferences) {
/* Get the prefs first time */
if(_.isUndefined(checkedMenuItems.sql_with_drop)) {
setCheckedMenuItems({
sql_with_drop: preferences.sql_with_drop,
});
}
}
}, [preferences]);
useEffect(()=>{
const events = [
[ERD_EVENTS.SINGLE_NODE_SELECTED, (selected)=>{
@@ -125,6 +148,16 @@ export function MainToolBar({preferences, eventBus}) {
};
}, []);
useEffect(()=>{
const showSql = ()=>{
eventBus.fireEvent(ERD_EVENTS.SHOW_SQL, checkedMenuItems['sql_with_drop']);
};
eventBus.registerListener(ERD_EVENTS.TRIGGER_SHOW_SQL, showSql);
return ()=>{
eventBus.deregisterListener(ERD_EVENTS.TRIGGER_SHOW_SQL, showSql);
};
}, [checkedMenuItems['sql_with_drop']]);
return (
<>
<Box className={classes.root}>
@@ -148,8 +181,11 @@ export function MainToolBar({preferences, eventBus}) {
<PgIconButton title={gettext('Generate SQL')} icon={<SQLFileIcon />}
shortcut={preferences.generate_sql}
onClick={()=>{
eventBus.fireEvent(ERD_EVENTS.SHOW_SQL);
eventBus.fireEvent(ERD_EVENTS.TRIGGER_SHOW_SQL);
}} />
<PgIconButton title={gettext('SQL Options')} icon={<KeyboardArrowDownIcon />} splitButton
name="menu-sql" ref={sqlMenuRef} onClick={toggleMenu}
/>
<PgIconButton title={gettext('Download image')} icon={<ImageRoundedIcon />}
shortcut={preferences.download_image}
onClick={()=>{
@@ -239,6 +275,14 @@ export function MainToolBar({preferences, eventBus}) {
eventBus.fireEvent(ERD_EVENTS.SAVE_DIAGRAM, true);
}}>{gettext('Save as')}</PgMenuItem>
</PgMenu>
<PgMenu
anchorRef={sqlMenuRef}
open={openMenuName=='menu-sql'}
onClose={onMenuClose}
label={gettext('SQL Options')}
>
<PgMenuItem hasCheck value="sql_with_drop" checked={checkedMenuItems['sql_with_drop']} onClick={checkMenuClick}>{gettext('With DROP Table')}</PgMenuItem>
</PgMenu>
</>
);
}

View File

@@ -20,9 +20,10 @@ class ERDTableView(BaseTableView, DataTypeReader):
super(BaseTableView, self).__init__(cmd='erd')
@BaseTableView.check_precondition
def sql(self, conn_id=None, did=None, sid=None, data={}):
def sql(self, conn_id=None, did=None, sid=None, data={}, with_drop=False):
return BaseTableView.get_sql(self, did, None, None, data, None,
add_not_exists_clause=True)
add_not_exists_clause=True,
with_drop=with_drop)
@BaseTableView.check_precondition
def get_types(self, conn_id=None, did=None, sid=None):
@@ -59,10 +60,10 @@ class ERDHelper:
return self.table_view.get_types(
conn_id=self.conn_id, did=self.did, sid=self.sid)
def get_table_sql(self, data):
def get_table_sql(self, data, with_drop=False):
SQL, name = self.table_view.sql(
conn_id=self.conn_id, did=self.did, sid=self.sid,
data=data)
data=data, with_drop=with_drop)
return SQL
def get_all_tables(self):

View File

@@ -9201,7 +9201,7 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
process@~0.11.0:
process@^0.11.10, process@~0.11.0:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==