Ensure that OID should be shown in properties for Synonyms. Fixes #5270

This commit is contained in:
Khushboo Vashi 2020-04-10 13:19:52 +05:30 committed by Akshay Joshi
parent c8646f99c0
commit e238ecf182
14 changed files with 68 additions and 59 deletions

View File

@ -31,6 +31,7 @@ Bug fixes
| `Issue #5053 <https://redmine.postgresql.org/issues/5053>`_ - Fixed an issue where changing the columns in the existing view throws an error. | `Issue #5053 <https://redmine.postgresql.org/issues/5053>`_ - Fixed an issue where changing the columns in the existing view throws an error.
| `Issue #5180 <https://redmine.postgresql.org/issues/5180>`_ - Fixed an issue where the autovacuum_enabled parameter is added automatically in the RE-SQL when the table has been created using the WITH clause. | `Issue #5180 <https://redmine.postgresql.org/issues/5180>`_ - Fixed an issue where the autovacuum_enabled parameter is added automatically in the RE-SQL when the table has been created using the WITH clause.
| `Issue #5268 <https://redmine.postgresql.org/issues/5268>`_ - Fixed generated SQL when any token in FTS Configuration or any option in FTS Dictionary is changed. | `Issue #5268 <https://redmine.postgresql.org/issues/5268>`_ - Fixed generated SQL when any token in FTS Configuration or any option in FTS Dictionary is changed.
| `Issue #5270 <https://redmine.postgresql.org/issues/5270>`_ - Ensure that OID should be shown in properties for Synonyms.
| `Issue #5275 <https://redmine.postgresql.org/issues/5275>`_ - Fixed tab key navigation issue for parameters in table dialog. | `Issue #5275 <https://redmine.postgresql.org/issues/5275>`_ - Fixed tab key navigation issue for parameters in table dialog.
| `Issue #5314 <https://redmine.postgresql.org/issues/5314>`_ - Ensure that switch cell is in sync with switch control for accessibility. | `Issue #5314 <https://redmine.postgresql.org/issues/5314>`_ - Ensure that switch cell is in sync with switch control for accessibility.
| `Issue #5351 <https://redmine.postgresql.org/issues/5351>`_ - Fixed compilation warnings while building pgAdmin. | `Issue #5351 <https://redmine.postgresql.org/issues/5351>`_ - Fixed compilation warnings while building pgAdmin.

View File

@ -270,7 +270,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
for row in rset['rows']: for row in rset['rows']:
res.append( res.append(
self.blueprint.generate_browser_node( self.blueprint.generate_browser_node(
row['name'], row['oid'],
scid, scid,
row['name'], row['name'],
icon="icon-synonym" icon="icon-synonym"
@ -467,13 +467,16 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'get_parent_oid.sql']), 'get_parent_oid.sql']),
data=data, conn=self.conn) data=data, conn=self.conn)
status, parent_id = self.conn.execute_scalar(SQL) status, res = self.conn.execute_dict(SQL)
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
parent_id = res['rows'][0]['scid']
syid = res['rows'][0]['syid']
return jsonify( return jsonify(
node=self.blueprint.generate_browser_node( node=self.blueprint.generate_browser_node(
data['name'], syid,
int(parent_id), int(parent_id),
data['name'], data['name'],
icon="icon-synonym" icon="icon-synonym"
@ -556,7 +559,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
data = request.form if request.form else json.loads( data = request.form if request.form else json.loads(
request.data, encoding='utf-8' request.data, encoding='utf-8'
) )
SQL = self.get_sql(gid, sid, data, scid, syid) SQL, name = self.get_sql(gid, sid, data, scid, syid)
# Most probably this is due to error # Most probably this is due to error
if not isinstance(SQL, (str, unicode)): if not isinstance(SQL, (str, unicode)):
return SQL return SQL
@ -570,7 +573,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
node=self.blueprint.generate_browser_node( node=self.blueprint.generate_browser_node(
syid, syid,
scid, scid,
syid, name,
icon="icon-synonym" icon="icon-synonym"
) )
) )
@ -598,7 +601,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v data[k] = v
try: try:
SQL = self.get_sql(gid, sid, data, scid, syid) SQL, name = self.get_sql(gid, sid, data, scid, syid)
# Most probably this is due to error # Most probably this is due to error
if not isinstance(SQL, (str, unicode)): if not isinstance(SQL, (str, unicode)):
return SQL return SQL
@ -614,6 +617,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
""" """
This function will genrate sql from model data This function will genrate sql from model data
""" """
name = None
if syid is not None: if syid is not None:
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'properties.sql']), 'properties.sql']),
@ -626,6 +630,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
gettext("Could not find the synonym on the server.") gettext("Could not find the synonym on the server.")
) )
old_data = res['rows'][0] old_data = res['rows'][0]
name = old_data['name']
# If target schema/object is not present then take it from # If target schema/object is not present then take it from
# old data, it means it does not changed # old data, it means it does not changed
if 'synobjschema' not in data: if 'synobjschema' not in data:
@ -646,10 +651,11 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
if arg not in data: if arg not in data:
return "-- missing definition" return "-- missing definition"
name = data['name']
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'create.sql']), comment=False, 'create.sql']), comment=False,
data=data, conn=self.conn) data=data, conn=self.conn)
return SQL.strip('\n') return SQL.strip('\n'), name
@check_precondition @check_precondition
def sql(self, gid, sid, did, scid, syid, diff_schema=None, def sql(self, gid, sid, did, scid, syid, diff_schema=None,
@ -757,7 +763,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
for row in rset['rows']: for row in rset['rows']:
status, data = self._fetch_properties(scid, row['name']) status, data = self._fetch_properties(scid, row['oid'])
if status: if status:
res[row['name']] = data res[row['name']] = data
@ -781,7 +787,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
if data: if data:
if diff_schema: if diff_schema:
data['schema'] = diff_schema data['schema'] = diff_schema
sql = self.get_sql(gid, sid, data, scid, oid) sql, name = self.get_sql(gid, sid, data, scid, oid)
else: else:
if drop_sql: if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did, sql = self.delete(gid=gid, sid=sid, did=did,

View File

@ -69,7 +69,7 @@ define('pgadmin.node.synonym', [
isNew: function() { isNew: function() {
return !this.fetchFromServer; return !this.fetchFromServer;
}, },
idAttribute: 'name', idAttribute: 'oid',
// Default values! // Default values!
initialize: function(attrs, args) { initialize: function(attrs, args) {
var isNew = (_.size(attrs) === 0); var isNew = (_.size(attrs) === 0);
@ -93,6 +93,9 @@ define('pgadmin.node.synonym', [
id: 'name', label: gettext('Name'), cell: 'string', id: 'name', label: gettext('Name'), cell: 'string',
type: 'text', mode: ['properties', 'create', 'edit'], type: 'text', mode: ['properties', 'create', 'edit'],
disabled: 'inSchema', readonly: function(m) { return !m.isNew(); }, disabled: 'inSchema', readonly: function(m) { return !m.isNew(); },
},{
id: 'oid', label: gettext('OID'), cell: 'string',
type: 'text', mode: ['properties'],
},{ },{
id: 'owner', label: gettext('Owner'), cell: 'string', id: 'owner', label: gettext('Owner'), cell: 'string',
type: 'text', mode: ['properties', 'create', 'edit'], type: 'text', mode: ['properties', 'create', 'edit'],

View File

@ -26,6 +26,6 @@ SELECT synname AS name, pg_get_userbyid(synowner) AS owner,
FROM pg_synonym s JOIN pg_namespace ns ON s.synnamespace = ns.oid FROM pg_synonym s JOIN pg_namespace ns ON s.synnamespace = ns.oid
WHERE s.synnamespace={{scid}}::oid WHERE s.synnamespace={{scid}}::oid
{% if syid %} {% if syid %}
AND s.synname={{ syid|qtLiteral }} AND s.oid={{syid}}::oid
{% endif %} {% endif %}
ORDER BY synname; ORDER BY synname;

View File

@ -1,4 +1,4 @@
SELECT synname AS name, pg_get_userbyid(synowner) AS owner, SELECT s.oid, synname AS name, pg_get_userbyid(synowner) AS owner,
synobjschema, synobjname, ns.nspname as schema, synobjschema, synobjname, ns.nspname as schema,
COALESCE( COALESCE(
(SELECT relkind (SELECT relkind
@ -26,6 +26,6 @@ SELECT synname AS name, pg_get_userbyid(synowner) AS owner,
FROM pg_synonym s JOIN pg_namespace ns ON s.synnamespace = ns.oid FROM pg_synonym s JOIN pg_namespace ns ON s.synnamespace = ns.oid
WHERE s.synnamespace={{scid}}::oid WHERE s.synnamespace={{scid}}::oid
{% if syid %} {% if syid %}
AND s.synname={{ syid|qtLiteral }} AND s.oid={{syid}}::oid
{% endif %} {% endif %}
ORDER BY synname; ORDER BY synname;

View File

@ -1,4 +1,4 @@
SELECT synnamespace as scid SELECT s.oid as syid, synnamespace as scid
FROM pg_synonym s FROM pg_synonym s
WHERE synname = {{ data.name|qtLiteral }} WHERE synname = {{ data.name|qtLiteral }}
AND synnamespace IN AND synnamespace IN

View File

@ -1,4 +1,4 @@
SELECT synname as name SELECT s.oid, synname as name
FROM pg_synonym s FROM pg_synonym s
JOIN pg_namespace ns ON s.synnamespace = ns.oid JOIN pg_namespace ns ON s.synnamespace = ns.oid
AND s.synnamespace = {{scid}}::oid AND s.synnamespace = {{scid}}::oid

View File

@ -14,6 +14,6 @@ SELECT synname AS name, pg_get_userbyid(synowner) AS owner,
FROM pg_synonym s JOIN pg_namespace ns ON s.synnamespace = ns.oid FROM pg_synonym s JOIN pg_namespace ns ON s.synnamespace = ns.oid
WHERE s.synnamespace={{scid}}::oid WHERE s.synnamespace={{scid}}::oid
{% if syid %} {% if syid %}
AND s.synname={{ syid|qtLiteral }} AND s.oid={{syid}}::oid
{% endif %} {% endif %}
ORDER BY synname; ORDER BY synname;

View File

@ -59,7 +59,7 @@ class SynonymDeleteTestCase(BaseTestGenerator):
self.sequence_id = sequence_utils.create_sequences( self.sequence_id = sequence_utils.create_sequences(
self.server, self.db_name, self.schema_name, self.sequence_name) self.server, self.db_name, self.schema_name, self.sequence_name)
self.synonym_name = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8] self.synonym_name = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8]
synonym_utils.create_synonym(self.server, self.syn_oid = synonym_utils.create_synonym(self.server,
self.db_name, self.db_name,
self.schema_name, self.schema_name,
self.synonym_name, self.synonym_name,
@ -77,7 +77,7 @@ class SynonymDeleteTestCase(BaseTestGenerator):
response = self.tester.delete( response = self.tester.delete(
self.url + str(utils.SERVER_GROUP) + '/' + self.url + str(utils.SERVER_GROUP) + '/' +
str(self.server_id) + '/' + str(self.db_id) + '/' + str(self.server_id) + '/' + str(self.db_id) + '/' +
str(self.schema_id) + '/' + str(self.synonym_name), str(self.schema_id) + '/' + str(self.syn_oid),
follow_redirects=True) follow_redirects=True)
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)

View File

@ -60,13 +60,14 @@ class SynonymDeleteMultipleTestCase(BaseTestGenerator):
self.sequence_id = sequence_utils.create_sequences( self.sequence_id = sequence_utils.create_sequences(
self.server, self.db_name, self.schema_name, self.sequence_name) self.server, self.db_name, self.schema_name, self.sequence_name)
self.synonym_name = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8] self.synonym_name = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8]
synonym_utils.create_synonym(self.server, self.syn_oid = synonym_utils.create_synonym(self.server,
self.db_name, self.db_name,
self.schema_name, self.schema_name,
self.synonym_name, self.synonym_name,
self.sequence_name) self.sequence_name)
self.synonym_name_1 = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8] self.synonym_name_1 = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8]
synonym_utils.create_synonym(self.server, self.syn_oid_1 = synonym_utils.create_synonym(self.server,
self.db_name, self.db_name,
self.schema_name, self.schema_name,
self.synonym_name_1, self.synonym_name_1,
@ -87,7 +88,7 @@ class SynonymDeleteMultipleTestCase(BaseTestGenerator):
if not synonym_response: if not synonym_response:
raise Exception("No synonym node to delete.") raise Exception("No synonym node to delete.")
data = {'ids': [self.synonym_name, self.synonym_name_1]} data = {'ids': [self.syn_oid, self.syn_oid_1]}
response = self.tester.delete( response = self.tester.delete(
self.url + str(utils.SERVER_GROUP) + '/' + self.url + str(utils.SERVER_GROUP) + '/' +
str(self.server_id) + '/' + str(self.db_id) + '/' + str(self.server_id) + '/' + str(self.db_id) + '/' +

View File

@ -59,7 +59,7 @@ class SynonymGetTestCase(BaseTestGenerator):
self.sequence_id = sequence_utils.create_sequences( self.sequence_id = sequence_utils.create_sequences(
self.server, self.db_name, self.schema_name, self.sequence_name) self.server, self.db_name, self.schema_name, self.sequence_name)
self.synonym_name = "test_synonym_get_%s" % str(uuid.uuid4())[1:8] self.synonym_name = "test_synonym_get_%s" % str(uuid.uuid4())[1:8]
synonym_utils.create_synonym(self.server, self.syn_oid = synonym_utils.create_synonym(self.server,
self.db_name, self.db_name,
self.schema_name, self.schema_name,
self.synonym_name, self.synonym_name,
@ -71,7 +71,7 @@ class SynonymGetTestCase(BaseTestGenerator):
response = self.tester.get( response = self.tester.get(
self.url + str(utils.SERVER_GROUP) + '/' + self.url + str(utils.SERVER_GROUP) + '/' +
str(self.server_id) + '/' + str(self.db_id) + '/' + str(self.server_id) + '/' + str(self.db_id) + '/' +
str(self.schema_id) + '/' + str(self.synonym_name), str(self.schema_id) + '/' + str(self.syn_oid),
follow_redirects=True) follow_redirects=True)
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)

View File

@ -66,7 +66,7 @@ class SynonymPutTestCase(BaseTestGenerator):
self.sequence_id = sequence_utils.create_sequences( self.sequence_id = sequence_utils.create_sequences(
self.server, self.db_name, self.schema_name, self.sequence_name) self.server, self.db_name, self.schema_name, self.sequence_name)
self.synonym_name = "test_synonym_put_%s" % str(uuid.uuid4())[1:8] self.synonym_name = "test_synonym_put_%s" % str(uuid.uuid4())[1:8]
synonym_utils.create_synonym(self.server, self.syn_oid = synonym_utils.create_synonym(self.server,
self.db_name, self.db_name,
self.schema_name, self.schema_name,
self.synonym_name, self.synonym_name,
@ -96,7 +96,7 @@ class SynonymPutTestCase(BaseTestGenerator):
str(self.server_id) + '/' + str(self.server_id) + '/' +
str(self.db_id) + '/' + str(self.db_id) + '/' +
str(self.schema_id) + '/' + str(self.schema_id) + '/' +
str(self.synonym_name), str(self.syn_oid),
data=json.dumps(data), data=json.dumps(data),
follow_redirects=True) follow_redirects=True)
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)

View File

@ -40,6 +40,14 @@ def create_synonym(server, db_name, schema_name, synonym_name, sequence_name):
schema_name, synonym_name, schema_name, sequence_name) schema_name, synonym_name, schema_name, sequence_name)
pg_cursor.execute(query) pg_cursor.execute(query)
connection.commit() connection.commit()
# Get 'oid' from newly created synonym
pg_cursor.execute("SELECT s.oid as name FROM"
" pg_synonym s WHERE s.synname='%s'" %
synonym_name)
synonym = pg_cursor.fetchone()
connection.close()
return synonym[0]
except Exception: except Exception:
traceback.print_exc(file=sys.stderr) traceback.print_exc(file=sys.stderr)

View File

@ -53,9 +53,6 @@ def compare_dictionaries(view_object, source_params, target_params,
source_object_id = None source_object_id = None
if 'oid' in source_dict[item]: if 'oid' in source_dict[item]:
source_object_id = source_dict[item]['oid'] source_object_id = source_dict[item]['oid']
elif 'name' in source_dict[item]:
# For synonyms use name as OID
source_object_id = source_dict[item]['name']
if node == 'table': if node == 'table':
temp_src_params = copy.deepcopy(source_params) temp_src_params = copy.deepcopy(source_params)
@ -96,9 +93,6 @@ def compare_dictionaries(view_object, source_params, target_params,
target_object_id = None target_object_id = None
if 'oid' in target_dict[item]: if 'oid' in target_dict[item]:
target_object_id = target_dict[item]['oid'] target_object_id = target_dict[item]['oid']
elif 'name' in target_dict[item]:
# For synonyms use name as OID
target_object_id = target_dict[item]['name']
if node == 'table': if node == 'table':
temp_tgt_params = copy.deepcopy(target_params) temp_tgt_params = copy.deepcopy(target_params)
@ -140,10 +134,6 @@ def compare_dictionaries(view_object, source_params, target_params,
if 'oid' in source_dict[key]: if 'oid' in source_dict[key]:
source_object_id = source_dict[key]['oid'] source_object_id = source_dict[key]['oid']
target_object_id = target_dict[key]['oid'] target_object_id = target_dict[key]['oid']
elif 'name' in target_dict[key]:
# For synonyms use name as OID
source_object_id = source_dict[key]['name']
target_object_id = target_dict[key]['name']
# Recursively Compare the two dictionary # Recursively Compare the two dictionary
if are_dictionaries_identical(dict1[key], dict2[key], ignore_keys): if are_dictionaries_identical(dict1[key], dict2[key], ignore_keys):