Hi Hackers,
Attached you can find 2 patches that correct the Redmine: #3308
<https://redmine.postgresql.org/issues/3308> A
Patches:
0001 - In this patch we update the SQL to retrieve the is_partitioned flag
from the database
0002 - Extract and refactor the icon css class retrieval. It was scattered
around the code and we moved it into it's own small class

We also realize that the class was present in some places in the javascript
world. What it is strange is that we only override the icon with the
partition one after a successful truncation or successful reset of
statistics.
Why was this behavior added? Can we remove that?


Thanks
Victoria & Joao
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/table/sql/gpdb_5.0_plus/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/table/sql/gpdb_5.0_plus/nodes.sql
index 3e877bfc..8c1e5878 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/table/sql/gpdb_5.0_plus/nodes.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/table/sql/gpdb_5.0_plus/nodes.sql
@@ -1,6 +1,7 @@
 SELECT rel.oid, rel.relname AS name,
     (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid) AS triggercount,
-    (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgenabled = 'O') AS has_enable_triggers
+    (SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgenabled = 'O') AS has_enable_triggers,
+    (CASE WHEN (SELECT count(*) from pg_partition where parrelid = rel.oid) > 0 THEN true ELSE false END) AS is_partitioned
 FROM pg_class rel
     WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ scid }}::oid
       AND rel.relname NOT IN (SELECT partitiontablename FROM pg_partitions)
-- 
2.17.0

diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
index d49ca20e..a4c229a1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
@@ -303,21 +303,17 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
         if len(rset['rows']) == 0:
                 return gone(gettext("Could not find the table."))
 
-        if 'is_partitioned' in rset['rows'][0] and \
-                rset['rows'][0]['is_partitioned']:
-            icon = "icon-partition"
-        else:
-            icon = "icon-table"
+        table_information = rset['rows'][0]
+        icon = self.get_icon_css_class(table_information)
 
         res = self.blueprint.generate_browser_node(
-            rset['rows'][0]['oid'],
+            table_information['oid'],
             scid,
-            rset['rows'][0]['name'],
+            table_information['name'],
             icon=icon,
-            tigger_count=rset['rows'][0]['triggercount'],
-            has_enable_triggers=rset['rows'][0]['has_enable_triggers'],
-            is_partitioned=rset['rows'][0]['is_partitioned'] if
-            'is_partitioned' in rset['rows'][0] else False
+            tigger_count=table_information['triggercount'],
+            has_enable_triggers=table_information['has_enable_triggers'],
+            is_partitioned=self.is_table_partitioned(table_information)
         )
 
         return make_json_response(
@@ -350,10 +346,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
             return internal_server_error(errormsg=rset)
 
         for row in rset['rows']:
-            if 'is_partitioned' in row and row['is_partitioned']:
-                icon = "icon-partition"
-            else:
-                icon = "icon-table"
+            icon = self.get_icon_css_class(row)
 
             res.append(
                 self.blueprint.generate_browser_node(
@@ -363,8 +356,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
                     icon=icon,
                     tigger_count=row['triggercount'],
                     has_enable_triggers=row['has_enable_triggers'],
-                    is_partitioned=row['is_partitioned'] if
-                    'is_partitioned' in row else False,
+                    is_partitioned=self.is_table_partitioned(row),
                     rows_cnt=0
                 ))
 
@@ -968,13 +960,11 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
 
         try:
             partitions_sql = ''
-            partitioned = False
-            if 'is_partitioned' in data and data['is_partitioned']:
+            if self.is_table_partitioned(data):
                 data['relkind'] = 'p'
                 # create partition scheme
                 data['partition_scheme'] = self.get_partition_scheme(data)
                 partitions_sql = self.get_partitions_sql(data)
-                partitioned = True
 
             SQL = render_template(
                 "/".join([self.table_template_path, 'create.sql']),
@@ -1021,8 +1011,8 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
                     tid,
                     scid,
                     data['name'],
-                    icon="icon-partition" if partitioned else "icon-table",
-                    is_partitioned=partitioned
+                    icon=self.get_icon_css_class(data),
+                    is_partitioned=self.is_table_partitioned(data)
                 )
             )
         except Exception as e:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/base_partition_table.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/base_partition_table.py
new file mode 100644
index 00000000..fd81f6da
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/base_partition_table.py
@@ -0,0 +1,23 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+class BasePartitionTable:
+    def is_table_partitioned(self, table_info):
+        if (
+            getattr(self, 'node_type', '') == 'partition' or
+            ('is_partitioned' in table_info and table_info['is_partitioned'])
+        ):
+            return True
+        return False
+
+    def get_icon_css_class(self, table_info):
+        if self.is_table_partitioned(table_info):
+            return 'icon-partition'
+        return 'icon-table'
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
index df195733..b1031d8b 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
@@ -308,7 +308,7 @@ class PartitionsView(BaseTableView, DataTypeReader, VacuumSettings):
                 row['oid'],
                 tid,
                 row['name'],
-                icon="icon-partition",
+                icon=self.get_icon_css_class({}),
                 tigger_count=row['triggercount'],
                 has_enable_triggers=row['has_enable_triggers'],
                 is_partitioned=row['is_partitioned'],
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/tests/test_base_partition_table.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/tests/test_base_partition_table.py
new file mode 100644
index 00000000..38c040f0
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/tests/test_base_partition_table.py
@@ -0,0 +1,107 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+from pgadmin.browser.server_groups.servers.databases.schemas\
+    .tables.base_partition_table import BasePartitionTable
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class TestBasePartitionTable(BaseTestGenerator):
+    scenarios = [
+        ('#is_table_partitioned when table information does not '
+         'have partition information, '
+         'it returns false',
+         dict(
+             test='is_table_partitioned',
+             input_parameters=dict(),
+             expected_return=False
+         )),
+        ('#is_table_partitioned when table information '
+         'has partition information and table is partitioned, '
+         'it returns true',
+         dict(
+             test='is_table_partitioned',
+             input_parameters=dict(
+                 is_partitioned=True
+             ),
+             expected_return=True
+         )),
+        ('#is_table_partitioned when table information '
+         'has partition information and table is not partitioned, '
+         'it returns false',
+         dict(
+             test='is_table_partitioned',
+             input_parameters=dict(
+                 is_partitioned=False
+             ),
+             expected_return=False
+         )),
+        ('#is_table_partitioned when node_type is present '
+         'and is partition, '
+         'it returns true',
+         dict(
+             test='is_table_partitioned',
+             input_parameters=dict(
+                 is_partitioned=False
+             ),
+             node_type='partition',
+             expected_return=True
+         )),
+        ('#is_table_partitioned when node_type is present '
+         'and is not partition '
+         'and table is not partitioned '
+         'it returns true',
+         dict(
+             test='is_table_partitioned',
+             input_parameters=dict(
+                 is_partitioned=False
+             ),
+             node_type='table',
+             expected_return=False
+         )),
+
+
+        ('#get_icon_css_class when table is partitioned '
+         'it returns icon-partition class',
+         dict(
+             test='get_icon_css_class',
+             input_parameters=dict(
+                 is_partitioned=True
+             ),
+             expected_return='icon-partition'
+         )),
+        ('#get_icon_css_class when table is not partitioned '
+         'it returns icon-table class',
+         dict(
+             test='get_icon_css_class',
+             input_parameters=dict(
+                 is_partitioned=False
+             ),
+             expected_return='icon-table'
+         ))
+    ]
+
+    def runTest(self):
+        if self.test == 'is_table_partitioned':
+            self.__test_is_table_partitioned()
+        elif self.test == 'get_icon_css_class':
+            self.__test_get_icon_css_class()
+
+    def __test_is_table_partitioned(self):
+        subject = BasePartitionTable()
+        if hasattr(self, 'node_type'):
+            subject.node_type = self.node_type
+
+        self.assertEqual(subject.is_table_partitioned(self.input_parameters),
+                         self.expected_return)
+
+    def __test_get_icon_css_class(self):
+        subject = BasePartitionTable()
+
+        self.assertEqual(subject.get_icon_css_class(self.input_parameters),
+                         self.expected_return)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py
index 732ff55d..b4e88840 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py
@@ -14,6 +14,9 @@ from functools import wraps
 import simplejson as json
 from flask import render_template, jsonify, request
 from flask_babelex import gettext
+
+from pgadmin.browser.server_groups.servers.databases.schemas\
+    .tables.base_partition_table import BasePartitionTable
 from pgadmin.utils.ajax import make_json_response, internal_server_error, \
     make_response as ajax_response
 from pgadmin.browser.server_groups.servers.databases.schemas.utils \
@@ -26,7 +29,7 @@ from pgadmin.utils.driver import get_driver
 from config import PG_DEFAULT_DRIVER
 
 
-class BaseTableView(PGChildNodeView):
+class BaseTableView(PGChildNodeView, BasePartitionTable):
     """
     This class is base class for tables and partitioned tables.
 
@@ -2068,13 +2071,7 @@ class BaseTableView(PGChildNodeView):
                     partitions_oid['created'] = created
                     partitions_oid['attached'] = attached
 
-            if self.node_type == 'partition':
-                icon = "icon-partition"
-            elif 'is_partitioned' in res['rows'][0] and \
-                    res['rows'][0]['is_partitioned']:
-                icon = "icon-partition"
-            else:
-                icon = "icon-table"
+            icon = self.get_icon_css_class(res['rows'][0])
 
             if 'relkind' in res['rows'][0] and \
                     res['rows'][0]['relkind'] == 'p':
-- 
2.17.0

Reply via email to