mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Add option to generate SQL with DROP table DDL in ERD Tool. #4997
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)=>{
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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==
|
||||
|
||||
Reference in New Issue
Block a user