mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Modified some logic for the EPAS server as the user can change the view definition without dropping it. Fixes #5053
This commit is contained in:
committed by
Akshay Joshi
parent
41be5479af
commit
030741bba5
@@ -496,7 +496,7 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
|
||||
"Could not find the required parameter (%s).") % arg
|
||||
)
|
||||
try:
|
||||
SQL, nameOrError = self.getSQL(gid, sid, did, scid, data)
|
||||
SQL, nameOrError = self.getSQL(gid, sid, did, data)
|
||||
if SQL is None:
|
||||
return nameOrError
|
||||
SQL = SQL.strip('\n').strip(' ')
|
||||
@@ -541,7 +541,7 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
try:
|
||||
SQL, name = self.getSQL(gid, sid, did, scid, data, vid)
|
||||
SQL, name = self.getSQL(gid, sid, did, data, vid)
|
||||
if SQL is None:
|
||||
return name
|
||||
SQL = SQL.strip('\n').strip(' ')
|
||||
@@ -678,7 +678,7 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
|
||||
except ValueError:
|
||||
data[k] = v
|
||||
|
||||
sql, nameOrError = self.getSQL(gid, sid, did, scid, data, vid)
|
||||
sql, nameOrError = self.getSQL(gid, sid, did, data, vid)
|
||||
if sql is None:
|
||||
return nameOrError
|
||||
|
||||
@@ -692,7 +692,7 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
|
||||
status=200
|
||||
)
|
||||
|
||||
def getSQL(self, gid, sid, did, scid, data, vid=None):
|
||||
def getSQL(self, gid, sid, did, data, vid=None):
|
||||
"""
|
||||
This function will generate sql from model data
|
||||
"""
|
||||
@@ -716,22 +716,6 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
|
||||
if 'schema' not in data:
|
||||
data['schema'] = res['rows'][0]['schema']
|
||||
|
||||
DEL_SQL = None
|
||||
if 'definition' in data:
|
||||
new_def = re.sub(r"\W", "", data['definition']).split('FROM')
|
||||
old_def = re.sub(r"\W", "", res['rows'][0]['definition']
|
||||
).split('FROM')
|
||||
if 'definition' in data and (
|
||||
len(old_def) > 1 or len(new_def) > 1
|
||||
) and(
|
||||
old_def[0] != new_def[0] and
|
||||
old_def[0] not in new_def[0]
|
||||
):
|
||||
DEL_SQL = self.delete(gid=gid, sid=sid, did=did,
|
||||
scid=scid,
|
||||
vid=vid, only_sql=True
|
||||
)
|
||||
|
||||
try:
|
||||
acls = render_template(
|
||||
"/".join([self.template_path, 'sql/allowed_privs.json'])
|
||||
@@ -750,14 +734,53 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
|
||||
data[aclcol][key] = parse_priv_to_db(
|
||||
data[aclcol][key], allowedacl['acl']
|
||||
)
|
||||
data['del_sql'] = False
|
||||
old_data['acl_sql'] = ''
|
||||
|
||||
if 'definition' in data and self.manager.server_type == 'pg':
|
||||
new_def = re.sub(r"\W", "", data['definition']).split('FROM')
|
||||
old_def = re.sub(r"\W", "", res['rows'][0]['definition']
|
||||
).split('FROM')
|
||||
if 'definition' in data and (
|
||||
len(old_def) > 1 or len(new_def) > 1
|
||||
) and(
|
||||
old_def[0] != new_def[0] and
|
||||
old_def[0] not in new_def[0]
|
||||
):
|
||||
data['del_sql'] = True
|
||||
|
||||
# If we drop and recreate the view, the
|
||||
# privileges must be restored
|
||||
|
||||
# Fetch all privileges for view
|
||||
sql_acl = render_template("/".join(
|
||||
[self.template_path, 'sql/acl.sql']), vid=vid)
|
||||
status, dataclres = self.conn.execute_dict(sql_acl)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
for row in dataclres['rows']:
|
||||
priv = parse_priv_from_db(row)
|
||||
res['rows'][0].setdefault(row['deftype'], []
|
||||
).append(priv)
|
||||
|
||||
old_data.update(res['rows'][0])
|
||||
|
||||
# Privileges
|
||||
for aclcol in acls:
|
||||
if aclcol in old_data:
|
||||
allowedacl = acls[aclcol]
|
||||
old_data[aclcol] = parse_priv_to_db(
|
||||
old_data[aclcol], allowedacl['acl'])
|
||||
|
||||
old_data['acl_sql'] = render_template("/".join(
|
||||
[self.template_path, 'sql/grant.sql']), data=old_data)
|
||||
|
||||
try:
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'sql/update.sql']), data=data,
|
||||
o_data=old_data, conn=self.conn)
|
||||
|
||||
if DEL_SQL:
|
||||
SQL = DEL_SQL + SQL
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return None, internal_server_error(errormsg=str(e))
|
||||
@@ -1457,7 +1480,7 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
|
||||
if data:
|
||||
if diff_schema:
|
||||
data['schema'] = diff_schema
|
||||
sql, nameOrError = self.getSQL(gid, sid, did, scid, data, oid)
|
||||
sql, nameOrError = self.getSQL(gid, sid, did, data, oid)
|
||||
if sql.find('DROP VIEW') != -1:
|
||||
sql = gettext("""
|
||||
-- Changing the columns in a view requires dropping and re-creating the view.
|
||||
@@ -1539,7 +1562,7 @@ class MViewNode(ViewNode, VacuumSettings):
|
||||
'9.3_plus'
|
||||
)
|
||||
|
||||
def getSQL(self, gid, sid, did, scid, data, vid=None):
|
||||
def getSQL(self, gid, sid, did, data, vid=None):
|
||||
"""
|
||||
This function will generate sql from model data
|
||||
"""
|
||||
|
||||
@@ -158,7 +158,7 @@ define('pgadmin.node.view', [
|
||||
control: Backform.SqlCodeControl.extend({
|
||||
onChange: function() {
|
||||
Backform.SqlCodeControl.prototype.onChange.apply(this, arguments);
|
||||
if(this.model && this.model.changed) {
|
||||
if(this.model && this.model.changed && this.model.node_info.server.server_type == 'pg') {
|
||||
if(this.model.origSessAttrs && (this.model.changed.definition != this.model.origSessAttrs.definition)) {
|
||||
let old_def = this.model.origSessAttrs.definition.replace(/\s/gi, '').split('FROM'),
|
||||
new_def = [];
|
||||
|
||||
@@ -9,5 +9,5 @@ LEFT JOIN pg_namespace nsp ON c.relnamespace = nsp.oid
|
||||
WHERE
|
||||
c.relfilenode = {{ vid }};
|
||||
{% elif (name and nspname) %}
|
||||
DROP VIEW {{ conn|qtIdent(nspname, name) }} {% if cascade %} CASCADE {% endif %};
|
||||
DROP VIEW {{ conn|qtIdent(nspname, name) }}{% if cascade %} CASCADE {% endif %};
|
||||
{% endif %}
|
||||
|
||||
@@ -13,11 +13,10 @@ ALTER VIEW {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ALTER VIEW {{ conn|qtIdent(o_data.schema, view_name ) }}
|
||||
SET SCHEMA {{ conn|qtIdent(data.schema) }};
|
||||
{% endif %}
|
||||
{% if data.owner and data.owner != o_data.owner %}
|
||||
ALTER TABLE {{ conn|qtIdent(view_schema, view_name) }}
|
||||
OWNER TO {{ conn|qtIdent(data.owner) }};
|
||||
{% endif %}
|
||||
{% if def and def != o_data.definition.rstrip(';') %}
|
||||
{% if data.del_sql %}
|
||||
DROP VIEW {{ conn|qtIdent(view_schema, view_name) }};
|
||||
{% endif %}
|
||||
CREATE OR REPLACE VIEW {{ conn|qtIdent(view_schema, view_name) }}
|
||||
{% if ((data.check_option and data.check_option.lower() != 'no') or data.security_barrier) %}
|
||||
WITH ({% if (data.check_option or o_data.check_option) %}check_option={{ data.check_option if data.check_option else o_data.check_option }}{{', ' }}{% endif %}security_barrier={{ data.security_barrier|lower if data.security_barrier is defined else o_data.security_barrier|default('false', 'true')|lower }})
|
||||
@@ -36,13 +35,23 @@ ALTER VIEW {{ conn|qtIdent(view_schema, view_name) }}
|
||||
ALTER VIEW {{ conn|qtIdent(view_schema, view_name) }} RESET (check_option);
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if data.owner and data.owner != o_data.owner %}
|
||||
ALTER TABLE {{ conn|qtIdent(view_schema, view_name) }}
|
||||
OWNER TO {{ conn|qtIdent(data.owner) }};
|
||||
{% endif %}
|
||||
{% set old_comment = o_data.comment|default('', true) %}
|
||||
{% if (data.comment is defined and (data.comment != old_comment)) %}
|
||||
|
||||
COMMENT ON VIEW {{ conn|qtIdent(view_schema, view_name) }}
|
||||
IS {{ data.comment|qtLiteral }};
|
||||
{% elif data.del_sql == True %}
|
||||
COMMENT ON VIEW {{ conn|qtIdent(view_schema, view_name) }}
|
||||
IS {{ old_comment|qtLiteral }};
|
||||
{% endif %}
|
||||
{# The SQL generated below will change privileges #}
|
||||
{% if o_data.acl_sql and o_data.acl_sql != '' %}
|
||||
{{o_data['acl_sql']}}
|
||||
{% endif %}
|
||||
{% if data.datacl %}
|
||||
{% if 'deleted' in data.datacl %}
|
||||
{% for priv in data.datacl.deleted %}
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
ALTER VIEW public."testview_$%{}[]()&*^!@""'`\/#"
|
||||
SET (security_barrier=true);
|
||||
ALTER VIEW public."testview_$%{}[]()&*^!@""'`\/#"
|
||||
SET (check_option=cascaded);
|
||||
GRANT SELECT ON TABLE public."testview_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
DROP VIEW public."testview_$%{}[]()&*^!@""'`\/#";
|
||||
CREATE OR REPLACE VIEW public."testview_$%{}[]()&*^!@""'`\/#"
|
||||
AS
|
||||
SELECT * FROM test_view_table;
|
||||
COMMENT ON VIEW public."testview_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Testcomment-updated';
|
||||
GRANT ALL ON TABLE public."testview_$%{}[]()&*^!@""'`\/#" TO postgres;
|
||||
|
||||
@@ -57,6 +57,18 @@
|
||||
"expected_sql_file": "alter_view.sql",
|
||||
"expected_msql_file": "alter_view_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter View (changing code)",
|
||||
"endpoint": "NODE-view.obj_id",
|
||||
"sql_endpoint": "NODE-view.sql_id",
|
||||
"msql_endpoint": "NODE-view.msql_id",
|
||||
"data": {
|
||||
"definition": "SELECT * FROM test_view_table;"
|
||||
},
|
||||
"expected_sql_file": "alter_view_definition.sql",
|
||||
"expected_msql_file": "alter_view_definition_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter View (adding privileges)",
|
||||
@@ -64,6 +76,12 @@
|
||||
"sql_endpoint": "NODE-view.sql_id",
|
||||
"msql_endpoint": "NODE-view.msql_id",
|
||||
"data": {
|
||||
"name": "testview_$%{}[]()&*^!@\"'`\\/#",
|
||||
"owner": "postgres",
|
||||
"schema": "public",
|
||||
"check_option": "cascaded",
|
||||
"security_barrier": true,
|
||||
"comment":"Testcomment-updated",
|
||||
"datacl":{
|
||||
"added":[
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user