diff --git a/docs/en_US/release_notes_4_21.rst b/docs/en_US/release_notes_4_21.rst index 89a1f3297..1913b9bc3 100644 --- a/docs/en_US/release_notes_4_21.rst +++ b/docs/en_US/release_notes_4_21.rst @@ -31,6 +31,7 @@ Bug fixes | `Issue #5053 `_ - Fixed an issue where changing the columns in the existing view throws an error. | `Issue #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 `_ - Fixed generated SQL when any token in FTS Configuration or any option in FTS Dictionary is changed. +| `Issue #5270 `_ - Ensure that OID should be shown in properties for Synonyms. | `Issue #5275 `_ - Fixed tab key navigation issue for parameters in table dialog. | `Issue #5314 `_ - Ensure that switch cell is in sync with switch control for accessibility. | `Issue #5351 `_ - Fixed compilation warnings while building pgAdmin. diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/__init__.py index b9f5d57df..648fe401e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/__init__.py @@ -270,7 +270,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): for row in rset['rows']: res.append( self.blueprint.generate_browser_node( - row['name'], + row['oid'], scid, row['name'], icon="icon-synonym" @@ -467,13 +467,16 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): SQL = render_template("/".join([self.template_path, 'get_parent_oid.sql']), data=data, conn=self.conn) - status, parent_id = self.conn.execute_scalar(SQL) + status, res = self.conn.execute_dict(SQL) if not status: return internal_server_error(errormsg=res) + parent_id = res['rows'][0]['scid'] + syid = res['rows'][0]['syid'] + return jsonify( node=self.blueprint.generate_browser_node( - data['name'], + syid, int(parent_id), data['name'], icon="icon-synonym" @@ -556,7 +559,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): data = request.form if request.form else json.loads( 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 if not isinstance(SQL, (str, unicode)): return SQL @@ -570,7 +573,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): node=self.blueprint.generate_browser_node( syid, scid, - syid, + name, icon="icon-synonym" ) ) @@ -598,7 +601,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): data[k] = v 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 if not isinstance(SQL, (str, unicode)): return SQL @@ -614,6 +617,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): """ This function will genrate sql from model data """ + name = None if syid is not None: SQL = render_template("/".join([self.template_path, 'properties.sql']), @@ -626,6 +630,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): gettext("Could not find the synonym on the server.") ) old_data = res['rows'][0] + name = old_data['name'] # If target schema/object is not present then take it from # old data, it means it does not changed if 'synobjschema' not in data: @@ -646,10 +651,11 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): if arg not in data: return "-- missing definition" + name = data['name'] SQL = render_template("/".join([self.template_path, 'create.sql']), comment=False, data=data, conn=self.conn) - return SQL.strip('\n') + return SQL.strip('\n'), name @check_precondition 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) for row in rset['rows']: - status, data = self._fetch_properties(scid, row['name']) + status, data = self._fetch_properties(scid, row['oid']) if status: res[row['name']] = data @@ -781,7 +787,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare): if data: if 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: if drop_sql: sql = self.delete(gid=gid, sid=sid, did=did, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js index 42c361633..057cb2d97 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js @@ -69,7 +69,7 @@ define('pgadmin.node.synonym', [ isNew: function() { return !this.fetchFromServer; }, - idAttribute: 'name', + idAttribute: 'oid', // Default values! initialize: function(attrs, args) { var isNew = (_.size(attrs) === 0); @@ -93,6 +93,9 @@ define('pgadmin.node.synonym', [ id: 'name', label: gettext('Name'), cell: 'string', type: 'text', mode: ['properties', 'create', 'edit'], 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', type: 'text', mode: ['properties', 'create', 'edit'], diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/9.2_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/9.2_plus/properties.sql index ec2724a0a..cb4c66c28 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/9.2_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/9.2_plus/properties.sql @@ -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 WHERE s.synnamespace={{scid}}::oid {% if syid %} - AND s.synname={{ syid|qtLiteral }} + AND s.oid={{syid}}::oid {% endif %} -ORDER BY synname; \ No newline at end of file +ORDER BY synname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/9.5_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/9.5_plus/properties.sql index ec2724a0a..0b3b82d97 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/9.5_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/9.5_plus/properties.sql @@ -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, COALESCE( (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 WHERE s.synnamespace={{scid}}::oid {% if syid %} - AND s.synname={{ syid|qtLiteral }} + AND s.oid={{syid}}::oid {% endif %} -ORDER BY synname; \ No newline at end of file +ORDER BY synname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/get_parent_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/get_parent_oid.sql index 08f07e031..e21f9683e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/get_parent_oid.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/get_parent_oid.sql @@ -1,5 +1,5 @@ -SELECT synnamespace as scid +SELECT s.oid as syid, synnamespace as scid FROM pg_synonym s WHERE synname = {{ data.name|qtLiteral }} AND synnamespace IN - ( SELECT oid FROM pg_namespace WHERE nspname = {{ data.schema|qtLiteral }} ); \ No newline at end of file + ( SELECT oid FROM pg_namespace WHERE nspname = {{ data.schema|qtLiteral }} ); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/nodes.sql index 1f8259b4a..c1df07f08 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/nodes.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/nodes.sql @@ -1,4 +1,4 @@ -SELECT synname as name +SELECT s.oid, synname as name FROM pg_synonym s JOIN pg_namespace ns ON s.synnamespace = ns.oid AND s.synnamespace = {{scid}}::oid diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/properties.sql index ce6d59b14..eab57c8e3 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/templates/synonyms/sql/default/properties.sql @@ -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 WHERE s.synnamespace={{scid}}::oid {% if syid %} - AND s.synname={{ syid|qtLiteral }} + AND s.oid={{syid}}::oid {% endif %} -ORDER BY synname; \ No newline at end of file +ORDER BY synname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_delete.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_delete.py index 88d749aec..bad95bf50 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_delete.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_delete.py @@ -59,11 +59,11 @@ class SynonymDeleteTestCase(BaseTestGenerator): self.sequence_id = sequence_utils.create_sequences( self.server, self.db_name, self.schema_name, self.sequence_name) self.synonym_name = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8] - synonym_utils.create_synonym(self.server, - self.db_name, - self.schema_name, - self.synonym_name, - self.sequence_name) + self.syn_oid = synonym_utils.create_synonym(self.server, + self.db_name, + self.schema_name, + self.synonym_name, + self.sequence_name) def runTest(self): """This function will delete synonym under schema node.""" @@ -77,7 +77,7 @@ class SynonymDeleteTestCase(BaseTestGenerator): response = self.tester.delete( self.url + str(utils.SERVER_GROUP) + '/' + 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) self.assertEquals(response.status_code, 200) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_delete_multiple.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_delete_multiple.py index e5b17469f..361f54713 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_delete_multiple.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_delete_multiple.py @@ -60,17 +60,18 @@ class SynonymDeleteMultipleTestCase(BaseTestGenerator): self.sequence_id = sequence_utils.create_sequences( self.server, self.db_name, self.schema_name, self.sequence_name) self.synonym_name = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8] - synonym_utils.create_synonym(self.server, - self.db_name, - self.schema_name, - self.synonym_name, - self.sequence_name) + self.syn_oid = synonym_utils.create_synonym(self.server, + self.db_name, + self.schema_name, + self.synonym_name, + self.sequence_name) + self.synonym_name_1 = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8] - synonym_utils.create_synonym(self.server, - self.db_name, - self.schema_name, - self.synonym_name_1, - self.sequence_name) + self.syn_oid_1 = synonym_utils.create_synonym(self.server, + self.db_name, + self.schema_name, + self.synonym_name_1, + self.sequence_name) def runTest(self): """This function will delete synonym under schema node.""" @@ -87,7 +88,7 @@ class SynonymDeleteMultipleTestCase(BaseTestGenerator): if not synonym_response: 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( self.url + str(utils.SERVER_GROUP) + '/' + str(self.server_id) + '/' + str(self.db_id) + '/' + diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_get.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_get.py index 60f565b35..6681f1e6d 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_get.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_get.py @@ -59,11 +59,11 @@ class SynonymGetTestCase(BaseTestGenerator): self.sequence_id = sequence_utils.create_sequences( self.server, self.db_name, self.schema_name, self.sequence_name) self.synonym_name = "test_synonym_get_%s" % str(uuid.uuid4())[1:8] - synonym_utils.create_synonym(self.server, - self.db_name, - self.schema_name, - self.synonym_name, - self.sequence_name) + self.syn_oid = synonym_utils.create_synonym(self.server, + self.db_name, + self.schema_name, + self.synonym_name, + self.sequence_name) def runTest(self): """This function will fetch synonym under schema node.""" @@ -71,7 +71,7 @@ class SynonymGetTestCase(BaseTestGenerator): response = self.tester.get( self.url + str(utils.SERVER_GROUP) + '/' + 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) self.assertEquals(response.status_code, 200) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_put.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_put.py index df0ab0000..b9faa7087 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_put.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/test_synonym_put.py @@ -66,11 +66,11 @@ class SynonymPutTestCase(BaseTestGenerator): self.sequence_id = sequence_utils.create_sequences( self.server, self.db_name, self.schema_name, self.sequence_name) self.synonym_name = "test_synonym_put_%s" % str(uuid.uuid4())[1:8] - synonym_utils.create_synonym(self.server, - self.db_name, - self.schema_name, - self.synonym_name, - self.sequence_name) + self.syn_oid = synonym_utils.create_synonym(self.server, + self.db_name, + self.schema_name, + self.synonym_name, + self.sequence_name) def runTest(self): """This function will update synonym under schema node.""" @@ -96,7 +96,7 @@ class SynonymPutTestCase(BaseTestGenerator): str(self.server_id) + '/' + str(self.db_id) + '/' + str(self.schema_id) + '/' + - str(self.synonym_name), + str(self.syn_oid), data=json.dumps(data), follow_redirects=True) self.assertEquals(response.status_code, 200) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/utils.py index a62cd706e..f5f4cbd42 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/tests/utils.py @@ -40,6 +40,14 @@ def create_synonym(server, db_name, schema_name, synonym_name, sequence_name): schema_name, synonym_name, schema_name, sequence_name) pg_cursor.execute(query) 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: traceback.print_exc(file=sys.stderr) diff --git a/web/pgadmin/tools/schema_diff/directory_compare.py b/web/pgadmin/tools/schema_diff/directory_compare.py index 4fabca1e7..23d195329 100644 --- a/web/pgadmin/tools/schema_diff/directory_compare.py +++ b/web/pgadmin/tools/schema_diff/directory_compare.py @@ -53,9 +53,6 @@ def compare_dictionaries(view_object, source_params, target_params, source_object_id = None if 'oid' in source_dict[item]: 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': temp_src_params = copy.deepcopy(source_params) @@ -96,9 +93,6 @@ def compare_dictionaries(view_object, source_params, target_params, target_object_id = None if 'oid' in target_dict[item]: 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': 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]: source_object_id = source_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 if are_dictionaries_identical(dict1[key], dict2[key], ignore_keys):