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