Hi,

Please find the attached patch for RM #2846 : Add a context menu option to
manually (re)count rows in tables, including those with >2K rows

Thanks,
Khushboo
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 1b24ee5..aa2adc9 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
@@ -242,7 +242,8 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
         'select_sql': [{'get': 'select_sql'}],
         'insert_sql': [{'get': 'insert_sql'}],
         'update_sql': [{'get': 'update_sql'}],
-        'delete_sql': [{'get': 'delete_sql'}]
+        'delete_sql': [{'get': 'delete_sql'}],
+        'count_rows': [{'get': 'count_rows'}]
     })
 
     @BaseTableView.check_precondition
@@ -346,7 +347,8 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
                     icon="icon-partition" if 'is_partitioned' in row and row['is_partitioned'] else "icon-table",
                     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=row['is_partitioned'] if 'is_partitioned' in row else False,
+                    rows_cnt=0
                 ))
 
         return make_json_response(
@@ -1461,4 +1463,39 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
         """
         return BaseTableView.get_table_statistics(self, scid, tid)
 
+    @BaseTableView.check_precondition
+    def count_rows(self, gid, sid, did, scid, tid):
+        """
+        Count the rows of a table.
+        Args:
+            gid: Server Group Id
+            sid: Server Id
+            did: Database Id
+            scid: Schema Id
+            tid: Table Id
+
+        Returns the total rows of a table.
+        """
+        data = {}
+        data['schema'], data['name'] = \
+            super(TableView, self).get_schema_and_table_name(tid)
+
+        SQL = render_template(
+            "/".join(
+                [self.table_template_path, 'get_table_row_count.sql']
+            ), data=data
+        )
+
+        status, count = self.conn.execute_scalar(SQL)
+
+        if not status:
+            return internal_server_error(errormsg=count)
+
+        return make_json_response(
+            status=200,
+            info=gettext("Table rows counted"),
+            data={'total_rows': count}
+        )
+
+
 TableView.register_node_view(blueprint)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js
index 90217e0..359a356 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js
@@ -90,6 +90,11 @@ define('pgadmin.node.table', [
           applies: ['object', 'context'], callback: 'reset_table_stats',
           category: 'Reset', priority: 4, label: gettext('Reset Statistics'),
           icon: 'fa fa-bar-chart', enable : 'canCreate'
+        },{
+          name: 'count_table_rows', node: 'table', module: this,
+          applies: ['object', 'context'], callback: 'count_table_rows',
+          category: 'Count', priority: 2, label: gettext('Count'),
+          enable: true
         }
         ]);
         pgBrowser.Events.on(
@@ -206,8 +211,8 @@ define('pgadmin.node.table', [
             }
           }, function() {}
         );
-       },
-       reset_table_stats: function(args) {
+        },
+        reset_table_stats: function(args) {
           var input = args || {},
             obj = this,
             t = pgBrowser.tree,
@@ -255,7 +260,41 @@ define('pgadmin.node.table', [
             },
             function() {}
           );
-       }
+        },
+        count_table_rows: function(args) {
+          var input = args || {},
+          obj = this,
+          t = pgBrowser.tree,
+          i = input.item || t.selected(),
+          d = i && i.length == 1 ? t.itemData(i) : undefined;
+          if (!d)
+            return false;
+
+          // Fetch the total rows of a table
+          $.ajax({
+            url: obj.generate_url(i, 'count_rows' , d, true),
+            type:'GET',
+            success: function(res) {
+                alertify.success(res.info);
+                d.rows_cnt = res.data.total_rows;
+                t.unload(i);
+                t.setInode(i);
+                t.deselect(i);
+                setTimeout(function() {
+                  t.select(i);
+                }, 10);
+            },
+            error: function(xhr, status, error) {
+              try {
+                var err = $.parseJSON(xhr.responseText);
+                if (err.success == 0) {
+                  alertify.error(err.errormsg);
+                }
+              } catch (e) {}
+              t.unload(i);
+            }
+          });
+        }
       },
       model: pgBrowser.Node.Model.extend({
         defaults: {
@@ -781,7 +820,24 @@ define('pgadmin.node.table', [
         },{
           id: 'rows_cnt', label: gettext('Rows (counted)'), cell: 'string',
           type: 'text', mode: ['properties'], group: gettext('Advanced'),
-          disabled: 'inSchema'
+          disabled: 'inSchema', control: Backform.InputControl.extend({
+            formatter: {
+               fromRaw: function (rawData, model) {
+                  var t = pgAdmin.Browser.tree,
+                  i = t.selected(),
+                  d = i && i.length == 1 ? t.itemData(i) : undefined;
+
+                  // Return the actual rows count if the selected node has already counted.
+                  if(d && d.rows_cnt && parseInt(d.rows_cnt, 10) > 0)
+                    return d.rows_cnt;
+                  else
+                    return rawData;
+               },
+               toRaw: function (formattedData, model) {
+                  return formattedData;
+               }
+            }
+          })
         },{
           id: 'relhassubclass', label: gettext('Inherits tables?'), cell: 'switch',
           type: 'switch', mode: ['properties'], group: gettext('Advanced'),
diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js
index fefe9cc..9a5b894 100644
--- a/web/pgadmin/browser/static/js/node.js
+++ b/web/pgadmin/browser/static/js/node.js
@@ -453,7 +453,7 @@ define(
        *
        * args must be a object containing:
        *   action - create/edit/properties
-       *   item   - The properties of the item (tree ndoe item)
+       *   item   - The properties of the item (tree node item)
        *
        * NOTE:
        * if item is not provided, the action will be done on the

Reply via email to