diff --git a/web/pgadmin/tools/sqleditor/command.py b/web/pgadmin/tools/sqleditor/command.py index 3e4549cb1..3c0b3d76d 100644 --- a/web/pgadmin/tools/sqleditor/command.py +++ b/web/pgadmin/tools/sqleditor/command.py @@ -23,6 +23,7 @@ from pgadmin.tools.sqleditor.utils.is_query_resultset_updatable \ import is_query_resultset_updatable from pgadmin.tools.sqleditor.utils.save_changed_data import save_changed_data from pgadmin.tools.sqleditor.utils.get_column_types import get_columns_types +from pgadmin.utils.preferences import Preferences from config import PG_DEFAULT_DRIVER @@ -173,6 +174,9 @@ class SQLFilter(object): self._data_sorting = kwargs.get('data_sorting', None) self._set_sorting_from_filter_dialog = False + data_sorting_by_pk = Preferences.module('sqleditor').preference( + 'table_view_data_by_pk').get() + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(self.sid) conn = manager.connection(did=self.did) @@ -183,15 +187,37 @@ class SQLFilter(object): # Fetch the Namespace Name and object Name query = render_template( "/".join([self.sql_path, 'objectname.sql']), - obj_id=self.obj_id + obj_id=self.obj_id, + pk=data_sorting_by_pk ) status, result = conn.execute_dict(query) if not status: raise Exception(result) - self.nsp_name = result['rows'][0]['nspname'] - self.object_name = result['rows'][0]['relname'] + rows = result['rows'] + if len(rows) > 0 and data_sorting_by_pk: + self.attname = rows[0]['attname'] + data_sorting_order = [{'name': self.attname, 'order': 'asc'}] + self._data_sorting = kwargs.get('data_sorting', + data_sorting_order) + else: + query = render_template( + "/".join([self.sql_path, 'objectname.sql']), + obj_id=self.obj_id, + pk=False + ) + + status, result = conn.execute_dict(query) + + if not status: + raise Exception(result) + + rows = result['rows'] + + self.nsp_name = rows[0]['nspname'] + self.object_name = rows[0]['relname'] + else: raise Exception(gettext( 'Not connected to server or connection with the server ' diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/default/objectname.sql b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/default/objectname.sql index 188e69db2..d23e1ad5e 100644 --- a/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/default/objectname.sql +++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/default/objectname.sql @@ -1,5 +1,16 @@ {# ============= Fetch the schema and object name for given object id ============= #} -{% if obj_id %} +{% if obj_id and pk %} +SELECT pg_attribute.attname, n.nspname, r.relname +FROM pg_attribute, pg_index, pg_class r + LEFT JOIN pg_namespace n ON (r.relnamespace = n.oid) +WHERE r.oid = {{obj_id}} AND +indrelid = r.oid AND +r.relnamespace = n.oid AND +pg_attribute.attrelid = r.oid AND +pg_attribute.attnum = any(pg_index.indkey) AND +indisprimary; +{% endif %} +{% if obj_id and not pk %} SELECT n.nspname, r.relname FROM pg_class r LEFT JOIN pg_namespace n ON (r.relnamespace = n.oid) diff --git a/web/pgadmin/tools/sqleditor/tests/test_view_data.py b/web/pgadmin/tools/sqleditor/tests/test_view_data.py index 3466e5c7c..9e2119386 100644 --- a/web/pgadmin/tools/sqleditor/tests/test_view_data.py +++ b/web/pgadmin/tools/sqleditor/tests/test_view_data.py @@ -10,6 +10,7 @@ import uuid import json import random +import sys from pgadmin.utils.route import BaseTestGenerator from pgadmin.browser.server_groups.servers.databases.tests import utils as \ @@ -18,6 +19,11 @@ from regression import parent_node_dict from regression.python_test_utils import test_utils from pgadmin.utils import server_utils, IS_PY2 +if sys.version_info < (3, 3): + from mock import patch +else: + from unittest.mock import patch + class TestViewData(BaseTestGenerator): """ @@ -36,6 +42,34 @@ class TestViewData(BaseTestGenerator): result_data='SELECT 0', rows_fetched_to=0 ) + ), + ( + 'Sort table data without primary key in the table', + dict( + table_sql="""Create Table ( + id integer Not Null, + json_val json Not Null + );""", + result_data='SELECT 0', + rows_fetched_to=0 + ) + ), + ( + 'Sort table data by default order with primary key in table', + dict( + table_sql="""Create Table ( + id integer Not Null, + json_val json Not Null, + Constraint table_pk_sort Primary Key(id) + );""", + result_data='SELECT 0', + rows_fetched_to=0, + mock_data={ + 'function_to_be_mocked': "pgadmin.utils.preferences." + "_Preference.get", + 'return_value': False + } + ) ) ] @@ -71,10 +105,18 @@ class TestViewData(BaseTestGenerator): # Initialize query tool self.trans_id = str(random.randint(1, 9999999)) - url = '/datagrid/initialize/datagrid/{0}/3/table/{1}/{2}/{3}/{4}'\ + url = '/datagrid/initialize/datagrid/{0}/3/table/{1}/{2}/{3}/{4}' \ .format(self.trans_id, test_utils.SERVER_GROUP, self.server_id, self.db_id, table_id) - response = self.tester.post(url) + + if hasattr(self, 'mock_data'): + with patch( + self.mock_data['function_to_be_mocked'], + return_value=self.mock_data['return_value'] + ): + response = self.tester.post(url) + else: + response = self.tester.post(url) self.assertEquals(response.status_code, 200) diff --git a/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py b/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py index a4d74e860..9448d6aae 100644 --- a/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py +++ b/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py @@ -271,6 +271,14 @@ def RegisterQueryToolPreferences(self): } ) + self.table_view_data_by_pk = self.preference.register( + 'Results_grid', 'table_view_data_by_pk', + gettext("Table View Data (By primary key)"), 'boolean', True, + category_label=gettext('Results grid'), + help_str=gettext("If set to True, data under sqleditor's results grid " + "will sort by primary key") + ) + self.results_grid_quote_char = self.preference.register( 'Results_grid', 'results_grid_quote_char', gettext("Result copy quote character"), 'options', '"',