public inbox for [email protected]  
help / color / mirror / Atom feed
From: Surinder Kumar <[email protected]>
To: Murtuza Zabuawala <[email protected]>
Cc: Dave Page <[email protected]>
Cc: pgadmin-hackers <[email protected]>
Subject: Re: Control for displaying "auto vacuum" fields into grid
Date: Mon, 11 Apr 2016 16:46:56 +0530
Message-ID: <CAM5-9D-v+6Jb=DCZgr66muizZAT4AjkcwTGf-rkG+-JF7o=_Eg@mail.gmail.com> (raw)
In-Reply-To: <CAKKotZTyq5xQmLjLQm4jetsUA2qKg0OcX+Md=WX9Kzzrup2rdA@mail.gmail.com>
References: <CAM5-9D9Nwm2SKkaRpWpMy=95RhKO+qm1O9TvhXE8dmCiUFe1Cw@mail.gmail.com>
	<CA+OCxoyfVBMqgLC7EevtULMg_pGu5voMmfST6k_eZ7rFsy=omg@mail.gmail.com>
	<CAM5-9D8=DMS75mhNCpPP3jn6=_JkT=drNkUr9gPRXBs5xLLDBg@mail.gmail.com>
	<[email protected]>
	<CAKKotZSzPO=X+wg=wD7AGocWWGsR1DJTugDAremJ8FimejQW4Q@mail.gmail.com>
	<CAKKotZTyq5xQmLjLQm4jetsUA2qKg0OcX+Md=WX9Kzzrup2rdA@mail.gmail.com>
List-Unsubscribe:  <mailto:[email protected]?body=unsub%20pgadmin-hackers>

Hi,

I have made few minor changes in this patch to make it to work with
Materialized View.

PFA patch with following changes:
1. Fixed typo issue for url parameter.
2. Check for 'hastoasttable' attribute in Disabled property of field
"toast_autovaccum" in VacuumSettingsSchema.
3. Use Simplejson library instead of json.


On Thu, Apr 7, 2016 at 4:19 PM, Murtuza Zabuawala <
[email protected]> wrote:

> Hi,
>
> Rebase patch and sent again.
>
>
> Regrds,
> Murtuza
>
> --
> Regards,
> Murtuza Zabuawala
> EnterpriseDB: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
> On Thu, Apr 7, 2016 at 4:07 PM, Murtuza Zabuawala <
> [email protected]> wrote:
>
>> Hi,
>>
>> Please find updated patch, I have moved everything at schema level and
>> tweak some code as well, so that we can use it in Table/View node.
>>
>>
>> Regards,
>> Murtuza
>>
>> --
>> Regards,
>> Murtuza Zabuawala
>> EnterpriseDB: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>> On Fri, Mar 25, 2016 at 4:50 PM, Murtuza Zabuawala <
>> [email protected]> wrote:
>>
>>> Hi Surinder,
>>>
>>> Can you please move all genereic logic & sql at schema level so that we
>>> can use it in table node as well?
>>> Currently it’s materialized view node centric only.
>>>
>>>
>>> Regards,
>>> Murtuza
>>>
>>>
>>> On 23-Mar-2016, at 9:34 pm, Surinder Kumar <
>>> [email protected]> wrote:
>>>
>>> Hi,
>>>
>>>
>>> On Fri, Mar 18, 2016 at 8:58 PM, Dave Page <[email protected]> wrote:
>>>
>>>> On Fri, Mar 18, 2016 at 10:37 AM, Surinder Kumar
>>>> <[email protected]> wrote:
>>>> > Hi,
>>>> >
>>>> > PFA control for displaying auto vacuum fields into grid. This control
>>>> is
>>>> > common for
>>>> > Materialized View Node and Table Node.
>>>> >
>>>> > Usage:
>>>> >
>>>> > {
>>>> >   id: 'vacuum_table', label: '{{ _("Vacuum Table") }}',
>>>> >   model: VacuumTableModel, editable: false, type: 'collection',
>>>> >   canEdit: true, group: '{{ _("Table") }}',
>>>> >   mode: ['edit', 'create'], url: 'get_vacuum_defaults',
>>>> >   control: Backform.VacuumCollectionControl.extend({
>>>> >     grid_columns :[
>>>> >       {
>>>> >         name: 'label', label: '{{ _("Label") }}',
>>>> >         cell: 'string', editable: false
>>>> >       },
>>>> >       {
>>>> >         name: 'value', label: '{{ _("Value") }}',
>>>> >         cellFunction: cellFunction, editable: function(m) {
>>>> >           if(m.handler.has('autovacuum_enabled')) {
>>>> >             return m.handler.get('autovacuum_enabled');
>>>> >           }
>>>> >           return !m.handler.isNew();
>>>> >         }
>>>> >       },
>>>> >       {
>>>> >         name: 'setting', label: '{{ _("Default value") }}',
>>>> >         cellFunction: cellFunction, editable: false
>>>> >       }
>>>> >     ]
>>>> >   }),
>>>> >
>>>> >
>>>> > When using this control, provide following parameters in schema:
>>>> > 1. model
>>>> > 2. url - to fetch default values for auto vacuum fields.
>>>> > 3. grid columns - Name of the columns to display in the grid.
>>>> >
>>>> >
>>>> > Please review the patch.
>>>>
>>>> It's hard to review this without being able to test. Do you have a
>>>> simple test case?
>>>>
>>>
>>> I have submitted patch for materialized view which is using this
>>> control. so you can test it in materialized view.
>>>
>>>>
>>>> --
>>>> Dave Page
>>>> Blog: http://pgsnake.blogspot.com
>>>> Twitter: @pgsnake
>>>>
>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>> The Enterprise PostgreSQL Company
>>>>
>>>
>>>
>>>
>>
>


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers


Attachments:

  [application/octet-stream] Updated_VaccumSettings_Control_v2.patch (15.0K, 3-Updated_VaccumSettings_Control_v2.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/js/schema.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/js/schema.js
index d465922..1ef405b 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/js/schema.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/js/schema.js
@@ -4,6 +4,247 @@ define(
         'pgadmin.browser.collection',
         'pgadmin.browser.server.privilege'],
 function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
+
+    // VaccumSettings Collection to display all settings parameters as Grid
+    var VacuumCollectionControl = Backform.VacuumCollectionControl =
+      Backform.Control.extend({
+
+      grid_columns:undefined,
+
+      initialize: function() {
+        Backform.Control.prototype.initialize.apply(this, arguments);
+        var self = this,
+            m = this.model;
+            url = self.field.get('url');
+
+        if (url && m.isNew()) {
+          var node = self.field.get('node'),
+              node_data = self.field.get('node_data'),
+              node_info = self.field.get('node_info'),
+              full_url = node.generate_url.apply(
+                node, [
+                  null, url, node_data, false, node_info
+                ]),
+              data;
+          m.trigger('pgadmin-view:fetching', m, self.field);
+
+          // fetch default values for autovacuum fields
+          $.ajax({
+            async: false,
+            url: full_url,
+            success: function (res) {
+              data = res;
+            },
+            error: function() {
+              m.trigger('pgadmin-view:fetch:error', m, self.field);
+            }
+          });
+          m.trigger('pgadmin-view:fetched', m, self.field);
+
+          // Add fetched models into collection
+          if (data && _.isArray(data)) {
+            m.get(self.field.get('name')).reset(data, {silent: true});
+          }
+        }
+      },
+
+      render: function() {
+        var self = this,
+            m = this.model,
+            attributes = self.field.attributes;
+
+        // remove grid
+        if(self.grid) {
+          self.grid.remove();
+          delete self.grid;
+          self.grid = undefined;
+        }
+
+        self.$el.empty();
+
+        var gridHeader = _.template([
+            '<div class="subnode-header">',
+            '  <label class="control-label col-sm-4"><%-label%></label>',
+            '</div>'].join("\n")),
+            gridBody = $('<div class="pgadmin-control-group backgrid form-group col-xs-12 object subnode"></div>').append(
+                gridHeader(attributes)
+                );
+
+        // Initialize a new Grid instance
+        var grid = self.grid = new Backgrid.Grid({
+          columns: self.grid_columns,
+          collection: self.model.get(self.field.get('name')),
+          className: "backgrid table-bordered"
+        });
+
+        // render grid
+        self.$el.append($(gridBody).append(grid.render().$el));
+
+        return self;
+      }
+    });
+
+  // We will use this function in VacuumSettings Control
+  // to convert data type on the fly
+  var cellFunction = Backform.cellFunction = function(model) {
+    var self = this,
+        m = model,
+        vartype = model.get('column_type');
+
+    switch(vartype) {
+      case "integer":
+        return Backgrid.IntegerCell;
+      break;
+      case "number":
+        return Backgrid.NumberCell;
+      break;
+      case "string":
+        return Backgrid.StringCell;
+      break;
+      default:
+        return Backgrid.Cell;
+      break;
+    }
+  };
+
+  // Define Security Model with fields and validation for VacuumSettings Control
+  var VacuumTableModel =  Backform.VacuumTableModel = pgAdmin.Browser.Node.Model.extend({
+    defaults: {
+      name: undefined,
+      setting: undefined,
+      label:undefined,
+      value: undefined,
+      column_type: undefined
+    },
+
+    toJSON: function(){
+      var d = pgAdmin.Browser.Node.Model.prototype.toJSON.apply(this);
+      delete d.label;
+      delete d.setting;
+      delete d.column_type;
+      return d;
+    }
+  });
+
+   // Extend the browser's collection class for VacuumSettingsModel
+    var VacuumSettingsSchema = Backform.VacuumSettingsSchema =
+     [{
+            id: 'autovacuum_custom', label: '{{ _("Custom auto-vacuum?") }}',
+              group: '{{ _("Table") }}', mode: ['edit', 'create'],
+              type: 'switch',
+              disabled: function(m) {
+                if(!m.top.inSchema.apply(this, [m])) {
+                  return false;
+                }
+                return true;
+              }
+          },{
+              id: 'autovacuum_enabled', label: '{{ _("Enabled?") }}',
+              group: '{{ _("Table") }}', mode: ['edit', 'create'],
+              type: 'switch',
+              deps: ['autovacuum_custom'],
+              disabled: function(m) {
+               if(!m.top.inSchema.apply(this, [m]) &&
+                  m.get('autovacuum_custom') == true) {
+                  return false;
+                }
+
+                // We also need to unset rest of all
+                setTimeout(function() {
+                  m.set('autovacuum_enabled', false);
+                  return true;
+                }, 10);
+                return true;
+              }
+          },{
+              id: 'vacuum_table', label: '{{ _("Vacuum Table") }}',
+              model: Backform.VacuumTableModel, editable: false, type: 'collection',
+              canEdit: true, group: '{{ _("Table") }}',
+              mode: ['edit', 'create'], url: 'get_table_vacuum',
+              control: Backform.VacuumCollectionControl.extend({
+                grid_columns :[
+                  {
+                    name: 'label', label: '{{ _("Label") }}',
+                    cell: 'string', editable: false
+                  },
+                  {
+                    name: 'value', label: '{{ _("Value") }}',
+                    cellFunction: Backform.cellFunction, editable: function(m) {
+                        return m.handler.get('autovacuum_enabled');
+                    }
+                  },
+                  {
+                    name: 'setting', label: '{{ _("Default value") }}',
+                    cellFunction: Backform.cellFunction, editable: false
+                  }
+                ]
+              }),
+              deps: ['autovacuum_enabled']
+          },{
+              id: 'toast_autovaccum', label: '{{ _("Custom auto-vaccum?") }}',
+              group: '{{ _("Toast Table") }}', mode: ['edit', 'create'],
+              type: 'switch',
+              disabled: function(m) {
+                // We need to check additional condition to toggle enable/disable
+                // for table auto-vacuum
+              if(!m.top.inSchema.apply(this, [m]) && m.isNew()) {
+                return false;
+              } else if(!m.top.inSchema.apply(this, [m]) &&
+                    m.get('toast_autovacuum_enabled') === true &&
+                    m.top.get('hastoasttable') === true ) {
+                  return false;
+                }
+                return true;
+              }
+          },{
+              id: 'toast_autovacuum_enabled', label: '{{ _("Enabled?") }}',
+              group: '{{ _("Toast Table") }}', mode: ['edit', 'create'],
+              type: 'switch',
+              deps:['toast_autovaccum'],
+              disabled: function(m) {
+              // If in schema & in create mode then enable it
+              if(!m.top.inSchema.apply(this, [m]) &&
+                  m.get('toast_autovaccum') === true) {
+                return false;
+              }
+
+              // we also need to unset rest of all
+              setTimeout(function() {
+                m.set('toast_autovacuum_enabled', false);
+                return true;
+              }, 10);
+
+              return true;
+
+              }
+          },{
+              id: 'vacuum_toast', label: '{{ _("Vacuum Toast Table") }}',
+              model: Backform.VacuumTableModel, type: 'collection', editable: function(m) {
+                return m.isNew();
+              },
+              canEdit: true, group: '{{ _("Toast Table") }}',
+              mode: ['edit', 'create'], url: 'get_toast_table_vacuum',
+              control: Backform.VacuumCollectionControl.extend({
+                grid_columns :[
+                  {
+                    name: 'label', label: '{{ _("Label") }}',
+                    cell: 'string', editable: false
+                  },
+                  {
+                    name: 'value', label: '{{ _("Value") }}',
+                    cellFunction: Backform.cellFunction, editable: function(m) {
+                        return m.handler.get('toast_autovacuum_enabled');
+                      }
+                  },
+                  {
+                    name: 'setting', label: '{{ _("Default value") }}',
+                    cellFunction: Backform.cellFunction, editable: false
+                  }
+                ]
+              }),
+              deps: ['toast_autovacuum_enabled']
+    }];
+
    // Extend the browser's collection class for SecurityLabel control
     var SecurityModel = Backform.SecurityModel = pgAdmin.Browser.Node.Model.extend({
     defaults: {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py
index 129c19e..7007d63 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py
@@ -13,6 +13,7 @@ from pgadmin.browser.collection import CollectionNodeModule
 from pgadmin.browser.utils import PGChildNodeView
 from flask import render_template
 from pgadmin.utils.ajax import internal_server_error
+import simplejson as json
 
 class SchemaChildModule(CollectionNodeModule):
     """
@@ -247,3 +248,143 @@ def parse_rule_definition(res):
     except Exception as e:
         return internal_server_error(errormsg=str(e))
     return res_data
+
+class VacuumSettings:
+    """
+    VacuumSettings Class.
+
+    This class includes common utilities to fetch and parse
+    vacuum defaults settings.
+
+    Methods:
+    -------
+    * get_vacuum_table_settings(conn):
+      - Returns vacuum table defaults settings.
+
+    * get_vacuum_toast_settings(conn):
+      - Returns vacuum toast defaults settings.
+
+    * parse_vacuum_data(conn, result, type):
+      - Returns result of an associated array
+        of fields name, label, value and column_type.
+        It adds name, label, column_type properties of table/toast
+        vacuum into the array and returns it.
+        args:
+        * conn - It is db connection object
+        * result - Resultset of vacuum data
+        * type - table/toast vacuum type
+
+    """
+    def get_vacuum_table_settings(self, conn):
+        """
+        Fetch the default values for autovacuum
+        fields, return an array of
+          - label
+          - name
+          - setting
+        values
+        """
+
+        # returns an array of name & label values
+        vacuum_fields = render_template("vacuum_settings/vacuum_fields.json")
+
+        vacuum_fields = json.loads(vacuum_fields)
+
+        # returns an array of setting & name values
+        vacuum_fields_keys = "'"+"','".join(
+            vacuum_fields['table'].keys())+"'"
+        SQL = render_template('vacuum_settings/sql/vacuum_defaults.sql',
+                              columns=vacuum_fields_keys)
+        status, res = conn.execute_dict(SQL)
+
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        for row in res['rows']:
+            row_name = row['name']
+            row['name'] = vacuum_fields['table'][row_name][0]
+            row['label'] = vacuum_fields['table'][row_name][1]
+            row['column_type'] = vacuum_fields['table'][row_name][2]
+
+        return res
+
+    def get_vacuum_toast_settings(self, conn):
+        """
+        Fetch the default values for autovacuum
+        fields, return an array of
+          - label
+          - name
+          - setting
+        values
+        """
+
+        # returns an array of name & label values
+        vacuum_fields = render_template("vacuum_settings/vacuum_fields.json")
+
+        vacuum_fields = json.loads(vacuum_fields)
+
+        # returns an array of setting & name values
+        vacuum_fields_keys = "'"+"','".join(
+            vacuum_fields['toast'].keys())+"'"
+        SQL = render_template('vacuum_settings/sql/vacuum_defaults.sql',
+                              columns=vacuum_fields_keys)
+        status, res = conn.execute_dict(SQL)
+
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        for row in res['rows']:
+            row_name = row['name']
+            row['name'] = vacuum_fields['toast'][row_name][0]
+            row['label'] = vacuum_fields['toast'][row_name][1]
+            row['column_type'] = vacuum_fields['table'][row_name][2]
+
+        return res
+
+    def parse_vacuum_data(self, conn, result, type):
+        """
+        This function returns result of an associated array
+        of fields name, label, value and column_type.
+        It adds name, label, column_type properties of table/toast
+        vacuum into the array and returns it.
+        args:
+        * conn - It is db connection object
+        * result - Resultset of vacuum data
+        * type - table/toast vacuum type
+        """
+
+        # returns an array of name & label values
+        vacuum_fields = render_template("vacuum_settings/vacuum_fields.json")
+
+        vacuum_fields = json.loads(vacuum_fields)
+
+        # returns an array of setting & name values
+        vacuum_fields_keys = "'"+"','".join(
+            vacuum_fields[type].keys()) + "'"
+        SQL = render_template('vacuum_settings/sql/vacuum_defaults.sql',
+                              columns=vacuum_fields_keys)
+        status, res = conn.execute_dict(SQL)
+
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        if type is 'table':
+            for row in res['rows']:
+                row_name = row['name']
+                row['name'] = vacuum_fields[type][row_name][0]
+                row['label'] = vacuum_fields[type][row_name][1]
+                row['column_type'] = vacuum_fields[type][row_name][2]
+                if result[row['name']] is not None:
+                    row['value'] = row['setting'] = float(result[row['name']])
+
+        elif type is 'toast':
+            for row in res['rows']:
+                row_old_name = row['name']
+                row_name = 'toast_{0}'.format(vacuum_fields[type][row_old_name][0])
+                row['name'] = vacuum_fields[type][row_old_name][0]
+                row['label'] = vacuum_fields[type][row_old_name][1]
+                row['column_type'] = vacuum_fields[type][row_old_name][2]
+                if result[row_name] and result[row_name] is not None:
+                    row['value'] = row['setting'] = float(result[row_name])
+
+        return res['rows']


view thread (8+ messages)

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected]
  Subject: Re: Control for displaying "auto vacuum" fields into grid
  In-Reply-To: <CAM5-9D-v+6Jb=DCZgr66muizZAT4AjkcwTGf-rkG+-JF7o=_Eg@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox