Added support to create triggers from existing trigger functions in EPAS. Fixes #7387

pull/89/head
Yogesh Mahajan 2022-07-28 11:16:05 +05:30 committed by Akshay Joshi
parent 526ee51485
commit 6145dc76fc
17 changed files with 70 additions and 71 deletions

View File

@ -9,6 +9,7 @@ This release contains a number of bug fixes and new features since the release o
New features
************
| `Issue #7387 <https://redmine.postgresql.org/issues/7387>`_ - Added support to create triggers from existing trigger functions in EPAS.
Housekeeping
************

View File

@ -96,7 +96,7 @@ define('pgadmin.node.trigger_function', [
}),
language: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData, {noCache: true}, (res) => {
return _.reject(res, function(o) {
return o.label == 'sql' || o.label == 'edbspl';
return o.label == 'sql';
});
}),
nodeInfo: treeNodeInfo

View File

@ -149,6 +149,7 @@ export default class TriggerFunctionSchema extends BaseUISchema {
}, {
id: 'lanname', label: gettext('Language'), cell: 'text',
type: 'select', group: gettext('Definition'),
mode: ['create', 'properties', 'edit'],
disabled: obj.isDisabled, readonly: obj.isReadonly,
options: obj.fieldOptions.language,
controlProps: {

View File

@ -14,5 +14,5 @@ JOIN
WHERE
pr.prokind IN ('f', 'w')
AND typname IN ('trigger', 'event_trigger')
AND lanname NOT IN ('edbspl', 'sql', 'internal')
AND lanname NOT IN ('sql', 'internal')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -21,6 +21,6 @@ WHERE
AND CASE WHEN (SELECT COUNT(*) FROM pg_catalog.pg_depend
WHERE objid = pr.oid AND deptype = 'e') > 0 THEN FALSE ELSE TRUE END
{% endif %}
AND typname IN ('trigger', 'event_trigger') AND lanname != 'edbspl'
AND typname IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -26,7 +26,7 @@ LEFT OUTER JOIN
pg_catalog.pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass and des.objsubid = 0)
WHERE
pr.prokind IN ('f', 'w')
AND typname IN ('trigger', 'event_trigger') AND lanname != 'edbspl'
AND typname IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% else %}

View File

@ -14,5 +14,5 @@ JOIN
WHERE
proisagg = FALSE
AND typname IN ('trigger', 'event_trigger')
AND lanname NOT IN ('edbspl', 'sql', 'internal')
AND lanname NOT IN ('sql', 'internal')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -22,6 +22,6 @@ WHERE
WHERE objid = pr.oid AND deptype = 'e') > 0 THEN FALSE ELSE TRUE END
{% endif %}
AND typname IN ('trigger', 'event_trigger')
AND lanname NOT IN ('edbspl', 'sql', 'internal')
AND lanname NOT IN ('sql', 'internal')
ORDER BY
proname;

View File

@ -26,7 +26,7 @@ LEFT OUTER JOIN
WHERE
proisagg = FALSE
AND typname IN ('trigger', 'event_trigger')
AND lanname NOT IN ('edbspl', 'sql', 'internal')
AND lanname NOT IN ('sql', 'internal')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% else %}

View File

@ -13,5 +13,5 @@ JOIN
AND nsp.nspname={{ nspname|qtLiteral }}
WHERE
proisagg = FALSE
AND typname = 'trigger' AND lanname != 'edbspl'
AND typname = 'trigger'
AND pr.proname = {{ name|qtLiteral }};

View File

@ -17,6 +17,6 @@ WHERE
{% if scid %}
AND pronamespace = {{scid}}::oid
{% endif %}
AND typname = 'trigger' AND lanname != 'edbspl'
AND typname = 'trigger'
ORDER BY
proname;

View File

@ -26,7 +26,7 @@ LEFT OUTER JOIN
WHERE
proisagg = FALSE
AND typname IN ('trigger', 'event_trigger')
AND lanname NOT IN ('edbspl', 'sql', 'internal')
AND lanname NOT IN ('sql', 'internal')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% else %}

View File

@ -3,7 +3,7 @@ FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_language l
WHERE p.pronamespace = n.oid
AND p.prolang = l.oid
-- PGOID_TYPE_TRIGGER = 2279
AND l.lanname != 'edbspl' AND prorettype = 2279
AND prorettype = 2279
-- If Show SystemObjects is not true
{% if not show_system_objects %}
AND (nspname NOT LIKE 'pg\_%' AND nspname NOT in ('information_schema'))

View File

@ -3,7 +3,7 @@ FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_language l
WHERE p.pronamespace = n.oid
AND p.prolang = l.oid
-- PGOID_TYPE_TRIGGER = 2279
AND l.lanname != 'edbspl' AND prorettype = 2279
AND prorettype = 2279
-- If Show SystemObjects is not true
{% if not show_system_objects %}
AND (nspname NOT LIKE 'pg\_%' AND nspname NOT in ('information_schema'))

View File

@ -314,38 +314,36 @@ class TriggerView(PGChildNodeView, SchemaDiffObjectCompare):
return gone(
gettext("Could not find the specified trigger function"))
# For language EDB SPL we should not display any node.
if rset['rows'][0]['lanname'] != 'edbspl':
trigger_function_schema_oid = rset['rows'][0]['tfuncschoid']
trigger_function_schema_oid = rset['rows'][0]['tfuncschoid']
sql = render_template("/".join(
[self.trigger_function_template_path, self._NODE_SQL]),
scid=trigger_function_schema_oid,
fnid=rset['rows'][0]['tfuncoid']
)
status, res = self.conn.execute_2darray(sql)
if not status:
return internal_server_error(errormsg=rset)
sql = render_template("/".join(
[self.trigger_function_template_path, self._NODE_SQL]),
scid=trigger_function_schema_oid,
fnid=rset['rows'][0]['tfuncoid']
)
status, res = self.conn.execute_2darray(sql)
if not status:
return internal_server_error(errormsg=rset)
if len(res['rows']) == 0:
return gone(gettext(
"Could not find the specified trigger function"))
if len(res['rows']) == 0:
return gone(gettext(
"Could not find the specified trigger function"))
row = res['rows'][0]
func_name = row['name']
# If trigger function is from another schema then we should
# display the name as schema qulified name.
if scid != trigger_function_schema_oid:
func_name = \
rset['rows'][0]['tfuncschema'] + '.' + row['name']
row = res['rows'][0]
func_name = row['name']
# If trigger function is from another schema then we should
# display the name as schema qulified name.
if scid != trigger_function_schema_oid:
func_name = \
rset['rows'][0]['tfuncschema'] + '.' + row['name']
trigger_func = current_app.blueprints['NODE-trigger_function']
nodes.append(trigger_func.generate_browser_node(
row['oid'], trigger_function_schema_oid,
gettext(func_name),
icon="icon-trigger_function", funcowner=row['funcowner'],
language=row['lanname'], inode=False)
)
trigger_func = current_app.blueprints['NODE-trigger_function']
nodes.append(trigger_func.generate_browser_node(
row['oid'], trigger_function_schema_oid,
gettext(func_name),
icon="icon-trigger_function", funcowner=row['funcowner'],
language=row['lanname'], inode=False)
)
except Exception as e:
return internal_server_error(errormsg=str(e))

View File

@ -103,41 +103,37 @@ def get_trigger_function_and_columns(conn, data, tid,
# If language is 'edbspl' then trigger function should be
# 'Inline EDB-SPL' else we will find the trigger function
# with schema name.
if data['lanname'] == 'edbspl':
data['tfunction'] = 'Inline EDB-SPL'
data['tgargs'] = None
else:
SQL = render_template("/".join(
[template_path, 'get_triggerfunctions.sql']),
tgfoid=data['tgfoid'],
show_system_objects=show_system_objects
)
SQL = render_template("/".join(
[template_path, 'get_triggerfunctions.sql']),
tgfoid=data['tgfoid'],
show_system_objects=show_system_objects
)
status, result = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=result)
status, result = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=result)
# Update the trigger function which we have fetched with
# schema name
if 'rows' in result and len(result['rows']) > 0 and \
'tfunctions' in result['rows'][0]:
data['tfunction'] = result['rows'][0]['tfunctions']
if 'rows' in result and len(result['rows']) > 0 and \
'tfunctions' in result['rows'][0]:
data['tfunction'] = result['rows'][0]['tfunctions']
if len(data['custom_tgargs']) > 0:
driver = get_driver(PG_DEFAULT_DRIVER)
# We know that trigger has more than 1 argument, let's join them
# and convert it to string
formatted_args = [driver.qtLiteral(arg)
for arg in data['custom_tgargs']]
formatted_args = ', '.join(formatted_args)
if len(data['custom_tgargs']) > 0:
driver = get_driver(PG_DEFAULT_DRIVER)
# We know that trigger has more than 1 argument, let's join them
# and convert it to string
formatted_args = [driver.qtLiteral(arg)
for arg in data['custom_tgargs']]
formatted_args = ', '.join(formatted_args)
data['tgargs'] = formatted_args
else:
data['tgargs'] = None
data['tgargs'] = formatted_args
else:
data['tgargs'] = None
if len(data['tgattr']) >= 1:
columns = ', '.join(data['tgattr'].split(' '))
data['columns'] = get_column_details(conn, tid, columns)
if len(data['tgattr']) >= 1:
columns = ', '.join(data['tgattr'].split(' '))
data['columns'] = get_column_details(conn, tid, columns)
return data

View File

@ -60,9 +60,12 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
"<h1>test</h1>")
def _role_node_expandable(self, role):
self.page.expand_server_child_node("Server", self.server['name'],
self.server['db_password'],
'Login/Group Roles')
retry = 3
while retry > 0:
if self.page.expand_server_child_node(
"Server", self.server['name'], self.server['db_password'],
'Login/Group Roles'):
retry = 0
role_node = self.page.check_if_element_exists_with_scroll(
TreeAreaLocators.role_node(role))