mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added Macro support. Fixes #1402
This commit is contained in:
committed by
Akshay Joshi
parent
952197f130
commit
4616a74029
@@ -33,6 +33,7 @@ from pgadmin.settings import get_setting
|
||||
from pgadmin.browser.utils import underscore_unescape
|
||||
from pgadmin.utils.exception import ObjectGone
|
||||
from pgadmin.utils.constants import MIMETYPE_APP_JS
|
||||
from pgadmin.tools.sqleditor.utils.macros import get_user_macros
|
||||
|
||||
MODULE_NAME = 'datagrid'
|
||||
|
||||
@@ -274,6 +275,8 @@ def panel(trans_id):
|
||||
|
||||
layout = get_setting('SQLEditor/Layout')
|
||||
|
||||
macros = get_user_macros()
|
||||
|
||||
return render_template(
|
||||
"datagrid/index.html",
|
||||
_=gettext,
|
||||
@@ -286,6 +289,7 @@ def panel(trans_id):
|
||||
bgcolor=bgcolor,
|
||||
fgcolor=fgcolor,
|
||||
layout=layout,
|
||||
macros=macros
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -377,6 +377,31 @@
|
||||
<i class="fa fa-download sql-icon-lg" aria-hidden="true" role="img"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="btn-group mr-1 user_macros" role="group" aria-label="">
|
||||
<button id="btn-macro-dropdown" type="button" class="btn btn-sm btn-primary-icon dropdown-toggle"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
||||
aria-label="{{ _('Macros') }}" title="{{ _('Macros') }}" tabindex="0">
|
||||
<i class="fa fa-scroll sql-icon-lg" aria-hidden="true" role="img"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="dropdown-item" id="btn-manage-macros" href="#" tabindex="0">
|
||||
<span> {{ _('Manage Macros...') }} </span>
|
||||
</a>
|
||||
</li>
|
||||
{% if macros|length > 0 %}
|
||||
<li class="dropdown-divider"></li>
|
||||
{% endif %}
|
||||
{% for i in macros %}
|
||||
<li>
|
||||
<a class="dropdown-item btn-macro" data-macro-id="{{ i.id }}" href="#" tabindex="0">
|
||||
<span> {{ _(i.name) }} </span>
|
||||
<span> ({{ i.key_label }}) </span>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="connection_status_wrapper d-flex">
|
||||
@@ -459,7 +484,8 @@ require(['sources/generated/browser_nodes', 'sources/generated/codemirror', 'sou
|
||||
sqlEditorController.start(
|
||||
{{ uniqueId }},
|
||||
{{ url_params|safe}},
|
||||
'{{ layout|safe }}'
|
||||
'{{ layout|safe }}',
|
||||
{{ macros|safe }}
|
||||
);
|
||||
|
||||
// If opening from schema diff, set the generated script to the SQL Editor
|
||||
|
||||
@@ -32,7 +32,7 @@ from pgadmin.tools.sqleditor.utils.update_session_grid_transaction import \
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils import get_storage_directory
|
||||
from pgadmin.utils.ajax import make_json_response, bad_request, \
|
||||
success_return, internal_server_error
|
||||
success_return, internal_server_error, make_response as ajax_response
|
||||
from pgadmin.utils.driver import get_driver
|
||||
from pgadmin.utils.menu import MenuItem
|
||||
from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost,\
|
||||
@@ -46,6 +46,8 @@ from pgadmin.tools.sqleditor.utils.filter_dialog import FilterDialog
|
||||
from pgadmin.tools.sqleditor.utils.query_history import QueryHistory
|
||||
from pgadmin.utils.constants import MIMETYPE_APP_JS, SERVER_CONNECTION_CLOSED,\
|
||||
ERROR_MSG_TRANS_ID_NOT_FOUND
|
||||
from pgadmin.tools.sqleditor.utils.macros import get_macros,\
|
||||
get_user_macros, set_macros
|
||||
|
||||
MODULE_NAME = 'sqleditor'
|
||||
|
||||
@@ -109,6 +111,9 @@ class SqlEditorModule(PgAdminModule):
|
||||
'sqleditor.get_query_history',
|
||||
'sqleditor.add_query_history',
|
||||
'sqleditor.clear_query_history',
|
||||
'sqleditor.get_macro',
|
||||
'sqleditor.get_macros',
|
||||
'sqleditor.set_macros'
|
||||
]
|
||||
|
||||
def register_preferences(self):
|
||||
@@ -1547,3 +1552,46 @@ def get_query_history(trans_id):
|
||||
check_transaction_status(trans_id)
|
||||
|
||||
return QueryHistory.get(current_user.id, trans_obj.sid, conn.db)
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
'/get_macros/<int:trans_id>',
|
||||
methods=["GET"], endpoint='get_macros'
|
||||
)
|
||||
@blueprint.route(
|
||||
'/get_macros/<int:macro_id>/<int:trans_id>',
|
||||
methods=["GET"], endpoint='get_macro'
|
||||
)
|
||||
@login_required
|
||||
def macros(trans_id, macro_id=None, json_resp=True):
|
||||
"""
|
||||
This method is used to get all the columns for data sorting dialog.
|
||||
|
||||
Args:
|
||||
trans_id: unique transaction id
|
||||
macro_id: Macro id
|
||||
"""
|
||||
|
||||
status, error_msg, conn, trans_obj, session_ob = \
|
||||
check_transaction_status(trans_id)
|
||||
|
||||
return get_macros(macro_id, json_resp)
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
'/set_macros/<int:trans_id>',
|
||||
methods=["PUT"], endpoint='set_macros'
|
||||
)
|
||||
@login_required
|
||||
def update_macros(trans_id):
|
||||
"""
|
||||
This method is used to get all the columns for data sorting dialog.
|
||||
|
||||
Args:
|
||||
trans_id: unique transaction id
|
||||
"""
|
||||
|
||||
status, error_msg, conn, trans_obj, session_ob = \
|
||||
check_transaction_status(trans_id)
|
||||
|
||||
return set_macros()
|
||||
|
||||
@@ -395,3 +395,32 @@ input.editor-checkbox:focus {
|
||||
.hide-vertical-scrollbar {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* Macros */
|
||||
|
||||
.macro-tab {
|
||||
top: 0px !important;
|
||||
}
|
||||
|
||||
.macro-tab .tab-pane {
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.macro_dialog .CodeMirror {
|
||||
overflow-y: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
.macro_dialog .sql-cell > div {
|
||||
overflow-y: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.macro_dialog .CodeMirror-cursor {
|
||||
width: 1px !important;
|
||||
height: 18px !important;
|
||||
}
|
||||
|
||||
.macro_dialog .pg-prop-status-bar {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ define('tools.querytool', [
|
||||
'tools/datagrid/static/js/datagrid_panel_title',
|
||||
'sources/window',
|
||||
'sources/is_native',
|
||||
'sources/sqleditor/macro',
|
||||
'sources/../bundle/slickgrid',
|
||||
'pgadmin.file_manager',
|
||||
'slick.pgadmin.formatters',
|
||||
@@ -57,7 +58,7 @@ define('tools.querytool', [
|
||||
GeometryViewer, historyColl, queryHist, querySources,
|
||||
keyboardShortcuts, queryToolActions, queryToolNotifications, Datagrid,
|
||||
modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, queryTxnStatus, csrfToken, panelTitleFunc,
|
||||
pgWindow, isNative) {
|
||||
pgWindow, isNative, MacroHandler) {
|
||||
/* Return back, this has been called more than once */
|
||||
if (pgAdmin.SqlEditor)
|
||||
return pgAdmin.SqlEditor;
|
||||
@@ -149,6 +150,9 @@ define('tools.querytool', [
|
||||
// Transaction control
|
||||
'click #btn-commit': 'on_commit_transaction',
|
||||
'click #btn-rollback': 'on_rollback_transaction',
|
||||
// Manage Macros
|
||||
'click #btn-manage-macros': 'on_manage_macros',
|
||||
'click .btn-macro': 'on_execute_macro',
|
||||
},
|
||||
|
||||
reflectPreferences: function() {
|
||||
@@ -2038,8 +2042,30 @@ define('tools.querytool', [
|
||||
|
||||
queryToolActions.executeRollback(this.handler);
|
||||
},
|
||||
|
||||
// Callback function for manage macros button click.
|
||||
on_manage_macros: function() {
|
||||
var self = this;
|
||||
|
||||
// Trigger the show_filter signal to the SqlEditorController class
|
||||
self.handler.trigger(
|
||||
'pgadmin-sqleditor:button:manage_macros',
|
||||
self,
|
||||
self.handler
|
||||
);
|
||||
},
|
||||
|
||||
// Callback function for manage macros button click.
|
||||
on_execute_macro: function(e) {
|
||||
let macroId = $(e.currentTarget).data('macro-id');
|
||||
this.handler.history_query_source = QuerySources.EXECUTE;
|
||||
queryToolActions.executeMacro(this.handler, macroId);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
/* Defining controller class for data grid, which actually
|
||||
* perform the operations like executing the sql query, poll the result,
|
||||
* render the data in the grid, Save/Refresh the data etc...
|
||||
@@ -2308,7 +2334,7 @@ define('tools.querytool', [
|
||||
* call the render method of the grid view to render the slickgrid
|
||||
* header and loading icon and start execution of the sql query.
|
||||
*/
|
||||
start: function(transId, url_params, layout) {
|
||||
start: function(transId, url_params, layout, macros) {
|
||||
var self = this;
|
||||
|
||||
self.is_query_tool = url_params.is_query_tool==='true'?true:false;
|
||||
@@ -2333,6 +2359,7 @@ define('tools.querytool', [
|
||||
layout: layout,
|
||||
});
|
||||
self.transId = self.gridView.transId = transId;
|
||||
self.macros = self.gridView.macros = macros;
|
||||
|
||||
self.gridView.current_file = undefined;
|
||||
|
||||
@@ -2474,12 +2501,14 @@ define('tools.querytool', [
|
||||
self.on('pgadmin-sqleditor:unindent_selected_code', self._unindent_selected_code, self);
|
||||
// Format
|
||||
self.on('pgadmin-sqleditor:format_sql', self._format_sql, self);
|
||||
self.on('pgadmin-sqleditor:button:manage_macros', self._manage_macros, self);
|
||||
self.on('pgadmin-sqleditor:button:execute_macro', self._execute_macro, self);
|
||||
|
||||
window.parent.$(window.parent.document).on('pgadmin-sqleditor:rows-copied', self._copied_in_other_session);
|
||||
},
|
||||
|
||||
// Checks if there is any dirty data in the grid before executing a query
|
||||
check_data_changes_to_execute_query: function(explain_prefix=null, shouldReconnect=false) {
|
||||
check_data_changes_to_execute_query: function(explain_prefix=null, shouldReconnect=false, macroId=undefined) {
|
||||
var self = this;
|
||||
|
||||
// Check if the data grid has any changes before running query
|
||||
@@ -2492,7 +2521,10 @@ define('tools.querytool', [
|
||||
gettext('The data has been modified, but not saved. Are you sure you wish to discard the changes?'),
|
||||
function() {
|
||||
// The user does not want to save, just continue
|
||||
if(self.is_query_tool) {
|
||||
if (macroId !== undefined) {
|
||||
self._execute_macro_query(explain_prefix, shouldReconnect, macroId);
|
||||
}
|
||||
else if(self.is_query_tool) {
|
||||
self._execute_sql_query(explain_prefix, shouldReconnect);
|
||||
}
|
||||
else {
|
||||
@@ -2508,7 +2540,10 @@ define('tools.querytool', [
|
||||
cancel: gettext('No'),
|
||||
});
|
||||
} else {
|
||||
if(self.is_query_tool) {
|
||||
if (macroId !== undefined) {
|
||||
self._execute_macro_query(explain_prefix, shouldReconnect, macroId);
|
||||
}
|
||||
else if(self.is_query_tool) {
|
||||
self._execute_sql_query(explain_prefix, shouldReconnect);
|
||||
}
|
||||
else {
|
||||
@@ -2602,6 +2637,37 @@ define('tools.querytool', [
|
||||
});
|
||||
},
|
||||
|
||||
// Executes sql query for macroin the editor in Query Tool mode
|
||||
_execute_macro_query: function(explain_prefix, shouldReconnect, macroId) {
|
||||
var self = this;
|
||||
|
||||
self.has_more_rows = false;
|
||||
self.fetching_rows = false;
|
||||
|
||||
$.ajax({
|
||||
url: url_for('sqleditor.get_macro', {'macro_id': macroId, 'trans_id': self.transId}),
|
||||
method: 'GET',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
})
|
||||
.done(function(res) {
|
||||
if (res) {
|
||||
// Replace the place holder
|
||||
let query = res.sql.replaceAll('$SELECTION$', self.gridView.query_tool_obj.getSelection());
|
||||
|
||||
const executeQuery = new ExecuteQuery.ExecuteQuery(self, pgAdmin.Browser.UserManagement);
|
||||
executeQuery.poll = pgBrowser.override_activity_event_decorator(executeQuery.poll).bind(executeQuery);
|
||||
executeQuery.execute(query, explain_prefix, shouldReconnect);
|
||||
} else {
|
||||
// Let it be for now
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
/* failure should not be ignored */
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// Executes sql query in the editor in Query Tool mode
|
||||
_execute_sql_query: function(explain_prefix, shouldReconnect) {
|
||||
var self = this, sql = '';
|
||||
@@ -3968,6 +4034,7 @@ define('tools.querytool', [
|
||||
$('#btn-file-menu-dropdown').prop('disabled', mode_disabled);
|
||||
$('#btn-find').prop('disabled', mode_disabled);
|
||||
$('#btn-find-menu-dropdown').prop('disabled', mode_disabled);
|
||||
$('#btn-macro-dropdown').prop('disabled', mode_disabled);
|
||||
|
||||
if (this.is_query_tool) {
|
||||
|
||||
@@ -4375,6 +4442,24 @@ define('tools.querytool', [
|
||||
});
|
||||
},
|
||||
|
||||
// This function will open the manage macro dialog
|
||||
_manage_macros: function() {
|
||||
let self = this;
|
||||
|
||||
/* When server is disconnected and connected, connection is lost,
|
||||
* To reconnect pass true
|
||||
*/
|
||||
MacroHandler.dialog(self);
|
||||
},
|
||||
|
||||
// This function will open the manage macro dialog
|
||||
_execute_macro: function() {
|
||||
|
||||
queryToolActions.executeMacro(this.handler);
|
||||
|
||||
},
|
||||
|
||||
|
||||
isQueryRunning: function() {
|
||||
return is_query_running;
|
||||
},
|
||||
|
||||
125
web/pgadmin/tools/sqleditor/tests/test_macros.py
Normal file
125
web/pgadmin/tools/sqleditor/tests/test_macros.py
Normal file
@@ -0,0 +1,125 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
import random
|
||||
|
||||
|
||||
class TestMacros(BaseTestGenerator):
|
||||
""" This class will test the query tool polling. """
|
||||
scenarios = [
|
||||
('Get all macros',
|
||||
dict(
|
||||
url='get_macros',
|
||||
method='get'
|
||||
)),
|
||||
('Set Macros',
|
||||
dict(
|
||||
url='set_macros',
|
||||
method='put',
|
||||
operation='update',
|
||||
data={
|
||||
'changed': [
|
||||
{'id': 1,
|
||||
'name': 'Test Macro 1',
|
||||
'sql': 'SELECT 1;'
|
||||
},
|
||||
{'id': 2,
|
||||
'name': 'Test Macro 2',
|
||||
'sql': 'SELECT 2;'
|
||||
},
|
||||
{'id': 3,
|
||||
'name': 'Test Macro 3',
|
||||
'sql': 'SELECT 3;'
|
||||
},
|
||||
]
|
||||
}
|
||||
)),
|
||||
('Clear Macros',
|
||||
dict(
|
||||
url='set_macros',
|
||||
method='put',
|
||||
operation='clear',
|
||||
data={
|
||||
'changed': [
|
||||
{'id': 1,
|
||||
'name': '',
|
||||
'sql': ''
|
||||
},
|
||||
{'id': 2,
|
||||
'name': '',
|
||||
'sql': ''
|
||||
},
|
||||
{'id': 3,
|
||||
'name': '',
|
||||
'sql': ''
|
||||
},
|
||||
]
|
||||
}
|
||||
))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
""" This function will check messages return by query tool polling. """
|
||||
database_info = parent_node_dict["database"][-1]
|
||||
self.server_id = database_info["server_id"]
|
||||
|
||||
self.db_id = database_info["db_id"]
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to the database.")
|
||||
|
||||
# Initialize query tool
|
||||
self.trans_id = str(random.randint(1, 9999999))
|
||||
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
|
||||
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
|
||||
response = self.tester.post(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def runTest(self):
|
||||
url = '/sqleditor/{0}/{1}'.format(self.url, self.trans_id)
|
||||
|
||||
if self.method == 'get':
|
||||
response = self.tester.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response_data = json.loads(response.data.decode('utf-8'))
|
||||
self.assertEqual(len(response_data['macro']), 22)
|
||||
else:
|
||||
response = self.tester.put(url,
|
||||
data=json.dumps(self.data),
|
||||
follow_redirects=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
for m in self.data['changed']:
|
||||
url = '/sqleditor/get_macros/{0}/{1}'.format(m['id'],
|
||||
self.trans_id)
|
||||
response = self.tester.get(url)
|
||||
|
||||
if self.operation == 'clear':
|
||||
self.assertEqual(response.status_code, 410)
|
||||
else:
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response_data = json.loads(response.data.decode('utf-8'))
|
||||
self.assertEqual(response_data['name'], m['name'])
|
||||
self.assertEqual(response_data['sql'], m['sql'])
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
||||
189
web/pgadmin/tools/sqleditor/utils/macros.py
Normal file
189
web/pgadmin/tools/sqleditor/utils/macros.py
Normal file
@@ -0,0 +1,189 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""Handle Macros for SQL Editor."""
|
||||
|
||||
import simplejson as json
|
||||
from flask_babelex import gettext
|
||||
from flask import current_app, request
|
||||
from flask_security import login_required, current_user
|
||||
from pgadmin.utils.ajax import make_response as ajax_response,\
|
||||
make_json_response
|
||||
from pgadmin.model import db, Macros, UserMacros
|
||||
from sqlalchemy import and_
|
||||
|
||||
|
||||
def get_macros(macro_id, json_resp):
|
||||
"""
|
||||
This method is used to get all the macros/specific macro.
|
||||
:param macro_id: Macro ID
|
||||
:param json_resp: Set True to return json response
|
||||
"""
|
||||
if macro_id:
|
||||
macro = UserMacros.query.filter_by(mid=macro_id,
|
||||
uid=current_user.id).first()
|
||||
if macro is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext("Macro not found.")
|
||||
)
|
||||
else:
|
||||
return ajax_response(
|
||||
response={'id': macro.mid,
|
||||
'name': macro.name,
|
||||
'sql': macro.sql},
|
||||
status=200
|
||||
)
|
||||
else:
|
||||
macros = db.session.query(Macros.id, Macros.alt, Macros.control,
|
||||
Macros.key, Macros.key_code,
|
||||
UserMacros.name, UserMacros.sql
|
||||
).outerjoin(
|
||||
UserMacros, and_(Macros.id == UserMacros.mid,
|
||||
UserMacros.uid == current_user.id)).all()
|
||||
|
||||
data = []
|
||||
|
||||
for m in macros:
|
||||
key_label = 'Ctrl + ' + m[3] if m[2] is True else 'Alt + ' + m[3]
|
||||
data.append({'id': m[0], 'alt': m[1],
|
||||
'control': m[2], 'key': m[3],
|
||||
'key_code': m[4], 'name': m[5],
|
||||
'sql': m[6],
|
||||
'key_label': key_label})
|
||||
|
||||
if not json_resp:
|
||||
return data
|
||||
|
||||
return ajax_response(
|
||||
response={'macro': data},
|
||||
status=200
|
||||
)
|
||||
|
||||
|
||||
def get_user_macros():
|
||||
"""
|
||||
This method is used to get all the user macros.
|
||||
"""
|
||||
|
||||
macros = db.session.query(UserMacros.name,
|
||||
Macros.id,
|
||||
Macros.alt, Macros.control,
|
||||
Macros.key, Macros.key_code
|
||||
).outerjoin(
|
||||
Macros, UserMacros.mid == Macros.id).filter(
|
||||
UserMacros.uid == current_user.id).order_by(UserMacros.name).all()
|
||||
|
||||
data = []
|
||||
|
||||
for m in macros:
|
||||
key_label = 'Ctrl + ' + m[4] if m[3] is True else 'Alt + ' + m[4]
|
||||
data.append({'name': m[0], 'id': m[1], 'key': m[4],
|
||||
'key_label': key_label, 'alt': 1 if m[2] else 0,
|
||||
'control': 1 if m[3] else 0, 'key_code': m[5]})
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def set_macros():
|
||||
"""
|
||||
This method is used to update the user defined macros.
|
||||
"""
|
||||
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
|
||||
if 'changed' not in data:
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext('Nothing to update.')
|
||||
)
|
||||
|
||||
for m in data['changed']:
|
||||
if m['id']:
|
||||
macro = UserMacros.query.filter_by(
|
||||
uid=current_user.id,
|
||||
mid=m['id']).first()
|
||||
if macro:
|
||||
status, msg = update_macro(m, macro)
|
||||
else:
|
||||
status, msg = create_macro(m)
|
||||
|
||||
if not status:
|
||||
return make_json_response(
|
||||
status=410, success=0, errormsg=msg
|
||||
)
|
||||
return ajax_response(status=200)
|
||||
|
||||
|
||||
def create_macro(macro):
|
||||
"""
|
||||
This method is used to create the user defined macros.
|
||||
:param macro: macro
|
||||
"""
|
||||
|
||||
required_args = [
|
||||
'name',
|
||||
'sql'
|
||||
]
|
||||
for arg in required_args:
|
||||
if arg not in macro:
|
||||
return False, gettext(
|
||||
"Could not find the required parameter ({}).").format(arg)
|
||||
|
||||
try:
|
||||
new_macro = UserMacros(
|
||||
uid=current_user.id,
|
||||
mid=macro['id'],
|
||||
name=macro['name'],
|
||||
sql=macro['sql']
|
||||
)
|
||||
db.session.add(new_macro)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
return True, None
|
||||
|
||||
|
||||
def update_macro(data, macro):
|
||||
"""
|
||||
This method is used to clear/update the user defined macros.
|
||||
:param data: updated macro data
|
||||
:param macro: macro
|
||||
"""
|
||||
|
||||
name = getattr(data, 'name', None)
|
||||
sql = getattr(data, 'sql', None)
|
||||
|
||||
if name or sql and macro.sql and name is None:
|
||||
return False, gettext(
|
||||
"Could not find the required parameter (name).")
|
||||
elif name or sql and macro.name and sql is None:
|
||||
return False, gettext(
|
||||
"Could not find the required parameter (sql).")
|
||||
|
||||
try:
|
||||
if name or sql:
|
||||
if name:
|
||||
macro.name = name
|
||||
if sql:
|
||||
macro.sql = sql
|
||||
else:
|
||||
db.session.delete(macro)
|
||||
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
return True, None
|
||||
Reference in New Issue
Block a user