diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/templates/extensions/js/extensions.js b/web/pgadmin/browser/server_groups/servers/databases/extensions/templates/extensions/js/extensions.js index b43de6447..7ecc49fed 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/extensions/templates/extensions/js/extensions.js +++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/templates/extensions/js/extensions.js @@ -173,27 +173,20 @@ function($, _, S, pgAdmin, pgBrowser) { }, { id: 'owner', label:'{{ _('Owner') }}', control: 'node-list-by-name', - mode: ['properties'], node: 'role', cell: 'string' + mode: ['properties'], node: 'role', cell: 'string', + cache_level: 'server' }, { - id: 'schema', label: '{{ _('Schema')}}', type: 'text', control: 'node-ajax-options', - mode: ['properties', 'create', 'edit'], group: '{{ _('Definition')}}', deps: ['relocatable'], - url: 'schemas', first_empty: true, disabled: function(m) { - + id: 'schema', label: '{{ _('Schema')}}', type: 'text', + control: 'node-list-by-name', group: '{{ _('Definition')}}', + mode: ['properties', 'create', 'edit'], deps: ['relocatable'], + node: 'schema', first_empty: true, + disabled: function(m) { /* * enable or disable schema field if model's relocatable * attribute is True or False */ return (m.has('relocatable') ? !m.get('relocatable') : false); - }, - transform: function(data) { - var res = []; - if (data && _.isArray(data)) { - _.each(data, function(d) { - res.push({label: d.schema, value: d.schema}); - }) - } - return res; } }, { diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/templates/extensions/sql/schemas.sql b/web/pgadmin/browser/server_groups/servers/databases/extensions/templates/extensions/sql/schemas.sql deleted file mode 100644 index bd43f097b..000000000 --- a/web/pgadmin/browser/server_groups/servers/databases/extensions/templates/extensions/sql/schemas.sql +++ /dev/null @@ -1,3 +0,0 @@ -{#===================fetch all schemas==========================#} -SELECT nspname As schema FROM pg_namespace - ORDER BY nspname diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/templates/collation/js/collation.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/templates/collation/js/collation.js index 29e2d7e53..f600c2d4b 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/templates/collation/js/collation.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/templates/collation/js/collation.js @@ -62,7 +62,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { lc_collate: undefined, description: undefined }, - + // Default values! initialize: function(attrs, args) { var isNew = (_.size(attrs) === 0); @@ -76,7 +76,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { } pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments); }, - + schema: [{ id: 'name', label: '{{ _('Name') }}', cell: 'string', type: 'text', mode: ['properties', 'create', 'edit'], @@ -87,7 +87,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { },{ id: 'owner', label:'{{ _('Owner') }}', cell: 'string', type: 'text', mode: ['properties', 'create', 'edit'], - disabled: 'inSchema', control: 'node-list-by-name', node: 'role' + disabled: 'inSchema', control: 'node-list-by-name', + node: 'role' },{ id: 'schema', label:'{{ _('Schema') }}', cell: 'string', type: 'text', mode: ['create', 'edit'], node: 'schema', diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/templates/domains/js/domains.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/templates/domains/js/domains.js index 19013eae7..7d5327b8f 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/templates/domains/js/domains.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/templates/domains/js/domains.js @@ -205,10 +205,12 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { id: 'description', label:'{{ _('Comment') }}', cell: 'string', type: 'multiline' },{ - id: 'basetype', label:'{{ _('Base type') }}', cell: 'string', control: 'node-ajax-options', - type: 'text', mode:['properties', 'create', 'edit'], group: '{{ _('Definition') }}', url: 'get_types', - disabled: function(m) { return !m.isNew(); }, first_empty: true, - transform: function(d){ + id: 'basetype', label:'{{ _('Base type') }}', cell: 'string', + control: 'node-ajax-options', type: 'text', url: 'get_types', + mode:['properties', 'create', 'edit'], group: '{{ _('Definition') }}', + cache_level: 'database', cache_node: 'schema', disabled: function(m) { + return !m.isNew(); + }, first_empty: true, transform: function(d) { this.model.type_options = d; return d; } @@ -279,8 +281,10 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { 'size': 'small' } },{ - id: 'collname', label:'{{ _('Collation') }}', cell: 'string', control: 'node-ajax-options', - type: 'text', group: '{{ _('Definition') }}', url: 'get_collations', disabled: function(m) { + id: 'collname', label:'{{ _('Collation') }}', cell: 'string', + control: 'node-ajax-options', type: 'text', url: 'get_collations', + group: '{{ _('Definition') }}', cache_level: 'database', + cache_node: 'schema', disabled: function(m) { return !m.isNew(); } },{ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/templates/fts_dictionary/js/fts_dictionary.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/templates/fts_dictionary/js/fts_dictionary.js index 0a9baef93..4ee3848b3 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/templates/fts_dictionary/js/fts_dictionary.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/templates/fts_dictionary/js/fts_dictionary.js @@ -126,14 +126,15 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { },{ id: 'schema', label: '{{ _('Schema')}}', cell: 'string', type: 'text', mode: ['create','edit'], node: 'schema', - control: 'node-list-by-id' + cache_node: 'database', control: 'node-list-by-id' },{ id: 'description', label:'{{ _('Comment') }}', cell: 'string', type: 'multiline', cellHeaderClasses: 'width_percent_50' },{ id: 'template', label: '{{ _('Template')}}',type: 'text', disabled: function(m) { return !m.isNew(); }, url: 'fetch_templates', - group: '{{ _('Definition') }}',control: 'node-ajax-options' + group: '{{ _('Definition') }}', control: 'node-ajax-options', + cache_node: 'database' },{ id: 'options', label: '{{ _('Option') }}', type: 'collection', group: '{{ _('Options') }}', control: 'unique-col-collection', @@ -182,4 +183,4 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { } return pgBrowser.Nodes['coll-fts_dictionary']; -}); \ No newline at end of file +}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/templates/fts_parser/js/fts_parser.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/templates/fts_parser/js/fts_parser.js index f342d3dd2..944f823ec 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/templates/fts_parser/js/fts_parser.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/templates/fts_parser/js/fts_parser.js @@ -93,27 +93,33 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { id: 'prsstart', label: '{{ _('Start function')}}', type: 'text', disabled: function(m) { return !m.isNew(); }, control: 'node-ajax-options', url: 'start_functions', - group: '{{ _('Definition') }}' + group: '{{ _('Definition') }}', cache_level: 'database', + cache_node: 'schema' },{ id: 'prstoken', label: '{{ _('Get next token function')}}', type: 'text', disabled: function(m) { return !m.isNew(); }, control: 'node-ajax-options', url: 'token_functions', - group: '{{ _('Definition') }}' + group: '{{ _('Definition') }}', cache_level: 'database', + cache_node: 'schema' },{ id: 'prsend', label: '{{ _('End function')}}', type: 'text', disabled: function(m) { return !m.isNew(); }, control: 'node-ajax-options', url: 'end_functions', - group: '{{ _('Definition') }}' + group: '{{ _('Definition') }}', cache_level: 'database', + cache_node: 'schema', + cache_node: 'schema' },{ id: 'prslextype', label: '{{ _('Lextypes function')}}', type: 'text', disabled: function(m) { return !m.isNew(); }, control: 'node-ajax-options', url: 'lextype_functions', - group: '{{ _('Definition') }}' + group: '{{ _('Definition') }}', cache_level: 'database', + cache_node: 'schema' },{ id: 'prsheadline', label: '{{ _('Headline function')}}', type: 'text', disabled: function(m) { return !m.isNew(); }, control: 'node-ajax-options', url: 'headline_functions', - group: '{{ _('Definition') }}' + group: '{{ _('Definition') }}', cache_level: 'database', + cache_node: 'schema' }], /* @@ -192,4 +198,4 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { } return pgBrowser.Nodes['coll-fts_parser']; -}); \ No newline at end of file +}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/templates/fts_template/js/fts_templates.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/templates/fts_template/js/fts_templates.js index 9c079367b..e737eaa0e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/templates/fts_template/js/fts_templates.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/templates/fts_template/js/fts_templates.js @@ -83,13 +83,16 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { id: 'description', label:'{{ _('Comment') }}', cell: 'string', type: 'multiline', cellHeaderClasses: 'width_percent_50' },{ - id: 'tmplinit', label: '{{ _('Init function')}}', group: '{{ _('Definition') }}', - type: 'text', disabled: function(m) { return !m.isNew(); }, - control: 'node-ajax-options', url: 'get_init' + id: 'tmplinit', label: '{{ _('Init function')}}', + group: '{{ _('Definition') }}', type: 'text', disabled: function(m) { + return !m.isNew(); + }, control: 'node-ajax-options', url: 'get_init', + cache_level: 'database', cache_node: 'schema' },{ id: 'tmpllexize', label: '{{ _('Lexize function')}}', group: '{{ _('Definition') }}', type: 'text', disabled: function(m) { return !m.isNew(); }, - control: 'node-ajax-options', url: 'get_lexize' + control: 'node-ajax-options', url: 'get_lexize', cache_level: 'database', + cache_node: 'schema' }], /* @@ -132,4 +135,4 @@ function($, _, S, pgAdmin, pgBrowser, alertify) { } return pgBrowser.Nodes['coll-fts_template']; -}); \ No newline at end of file +}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/js/databases.js b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/js/databases.js index 0408a5266..00fa23dcc 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/js/databases.js +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/js/databases.js @@ -257,12 +257,12 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) { id: 'encoding', label: '{{ _('Encoding') }}', editable: false, type: 'text', group: 'Definition', disabled: function(m) { return !m.isNew(); }, url: 'get_encodings', - control: 'node-ajax-options' + control: 'node-ajax-options', cache_level: 'server' },{ id: 'template', label: '{{ _('Template') }}', editable: false, type: 'text', group: 'Definition', disabled: function(m) { return !m.isNew(); }, - control: 'node-list-by-name', node: 'database' + control: 'node-list-by-name', node: 'database', cache_level: 'server' },{ id: 'spcname', label: '{{ _('Tablespace') }}', editable: false, type: 'text', group: 'Definition', @@ -275,12 +275,12 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) { id: 'datcollate', label: '{{ _('Collation') }}', editable: false, type: 'text', group: 'Definition', disabled: function(m) { return !m.isNew(); }, url: 'get_ctypes', - control: 'node-ajax-options' + control: 'node-ajax-options', cache_level: 'server' },{ id: 'datctype', label: '{{ _('Character Type') }}', editable: false, type: 'text', group: 'Definition', disabled: function(m) { return !m.isNew(); }, url: 'get_ctypes', - control: 'node-ajax-options' + control: 'node-ajax-options', cache_level: 'server' },{ id: 'datconnlimit', label: '{{ _('Connection Limit') }}', editable: false, type: 'int', group: 'Definition', min: -1 diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/nodes.sql index 3ce9645a3..b05880c37 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/nodes.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/nodes.sql @@ -3,7 +3,7 @@ SELECT has_database_privilege(db.oid, 'CREATE') as cancreate, datdba as owner FROM pg_database db - LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid{% if did %} + LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid WHERE {% if did %} db.oid = {{ did|qtLiteral }}::OID{% else %} db.oid > {{ last_system_oid }}::OID diff --git a/web/pgadmin/browser/static/js/node.ui.js b/web/pgadmin/browser/static/js/node.ui.js index 6cd3d684d..cfb23effd 100644 --- a/web/pgadmin/browser/static/js/node.ui.js +++ b/web/pgadmin/browser/static/js/node.ui.js @@ -79,22 +79,28 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) { if (url) { var node = this.field.get('schema_node'), node_info = this.field.get('node_info'), + with_id = this.field.get('url_with_id') || false, full_url = node.generate_url.apply( node, [ - null, url, this.field.get('node_data'), - this.field.get('url_with_id') || false, node_info + null, url, this.field.get('node_data'), with_id, node_info ]), - cache_level = this.field.get('cache_level') || node.type, + cache_level, cache_node = this.field.get('cache_node'); cache_node = (cache_node && pgAdmin.Browser.Nodes['cache_node']) || node; + if (this.field.has('cache_level')) { + cache_level = this.field.get('cache_level'); + } else { + cache_level = cache_node.cache_level(node_info, with_id); + } + /* * We needs to check, if we have already cached data for this url. * If yes - use that, and do not bother about fetching it again, * and use it. */ - var data = cache_node.cache(url, node_info, cache_level); + var data = cache_node.cache(node.type + '#' + url, node_info, cache_level); if (this.field.get('version_compatible') && (_.isUndefined(data) || _.isNull(data))) { @@ -107,7 +113,7 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) { * We will cache this data for short period of time for avoiding * same calls. */ - data = cache_node.cache(url, node_info, cache_level, res.data); + data = cache_node.cache(node.type + '#' + url, node_info, cache_level, res.data); }, error: function() { m.trigger('pgadmin:view:fetch:error', m, self.field); @@ -341,22 +347,28 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) { eventHandler = m.top || m, node = column.get('schema_node'), node_info = column.get('node_info'), + with_id = column.get('url_with_id') || false, full_url = node.generate_url.apply( node, [ - null, url, column.get('node_data'), - column.get('url_with_id') || false, node_info + null, url, column.get('node_data'), with_id, node_info ]), - cache_level = column.get('cache_level') || node.type, + cache_level, cache_node = column.get('cache_node'); cache_node = (cache_node && pgAdmin.Browser.Nodes['cache_node']) || node; + if (this.field.has('cache_level')) { + cache_level = this.field.get('cache_level'); + } else { + cache_level = cache_node.cache_level(node_info, with_id); + } + /* * We needs to check, if we have already cached data for this url. * If yes - use that, and do not bother about fetching it again, * and use it. */ - var data = cache_node.cache(url, node_info, cache_level); + var data = cache_node.cache(node.type + '#' + url, node_info, cache_level); if (column.get('version_compatible') && (_.isUndefined(data) || _.isNull(data))) { @@ -369,7 +381,7 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) { * We will cache this data for short period of time for avoiding * same calls. */ - data = cache_node.cache(url, node_info, cache_level, res.data); + data = cache_node.cache(node.type + '#' + url, node_info, cache_level, res.data); }, error: function() { eventHandler.trigger('pgadmin:view:fetch:error', m, column); diff --git a/web/pgadmin/browser/templates/browser/js/node.js b/web/pgadmin/browser/templates/browser/js/node.js index 23d559c1a..5810e74b6 100644 --- a/web/pgadmin/browser/templates/browser/js/node.js +++ b/web/pgadmin/browser/templates/browser/js/node.js @@ -903,9 +903,12 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { // Closing this panel this.close(); }.bind(panel), - updateTreeItem = function() { + updateTreeItem = function(that) { var panel = this; + // Clear the cache for this node now. + setTimeout(function() { that.clear_cache.apply(that, item); }, 0); + // Update the item lable (if label is modified.) if (view.model.tnode) { var itemData = tree.itemData(item), @@ -925,11 +928,18 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { tree.deselect(item); panel.$container.removeAttr('action-mode'); setTimeout(function() { closePanel(); }, 0); - setTimeout(function() { tree.select(item, {focus: true}); }, 10); + + pgBrowser.Events.trigger( + 'pgadmin-node:updated:' + that.type, item, that + ); }, - saveNewNode = function() { + saveNewNode = function(that) { var panel = this; + + // Clear the cache for this node now. + setTimeout(function() { that.clear_cache.apply(that, item); }, 0); + /* TODO:: Create new tree node for this */ if (view.model.tnode && '_id' in view.model.tnode) { var d = _.extend({}, view.model.tnode), @@ -938,6 +948,9 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { if (i) { tree.select(i, {focus: true}); } + pgBrowser.Events.trigger( + 'pgadmin-node:created:' + that.type, i, that + ); }, found = false; delete view.model.tnode; @@ -1092,9 +1105,15 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { tree.open(item, { success: function (item, options){ setTimeout(function() {closePanel();}, 0); + pgBrowser.Events.trigger( + 'pgadmin-node:created:' + that.type, item, that + ); }, fail: function (item, options){ setTimeout(function() {closePanel();}, 0); + pgBrowser.Events.trigger( + 'pgadmin-node:created:' + that.type, item, that + ); }, unanimated: animation }); @@ -1125,7 +1144,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { } setTimeout(function() {closePanel();}, 0); } - }.bind(panel), + }.bind(panel, that), editInNewPanel = function() { // Open edit in separate panel setTimeout(function() { @@ -1136,7 +1155,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { }, 0); }, onCancelFunc = closePanel, - onSaveFunc = updateTreeItem.bind(panel), + onSaveFunc = updateTreeItem.bind(panel, that), onEdit = editFunc.bind(panel); if (action) { @@ -1280,12 +1299,45 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) { } if (_.isUndefined(data)) { - return cached[hash]; + var res = cached[hash]; + + if (!_.isUndefined(res) && + (res.at - Date.now() > 300000)) { + res = undefined; + } + return res; } - var res = cached[hash] = {data: data, at: Date(), level: level}; + res = cached[hash] = {data: data, at: Date.now(), level: level}; return res; + }, + clear_cache: function(item) { + /* + * Reset the cache, when new node is created. + * + * FIXME: + * At the moment, we will clear all the cache for this node. But - we + * would like to clear the cache only this nodes parent, so that - it + * fetches the new data. + */ + this.cached = {}; + }, + cache_level: function(node_info, with_id) { + if (node_info) { + if (with_id && this.type in node_info) { + return this.type; + } + if (_.isArray(this.parent_type)) { + for (var parent in this.parent_type) { + if (parent in node_info) { + return parent; + } + } + return this.type; + } + return this.parent_type; + } } }); diff --git a/web/pgadmin/static/css/overrides.css b/web/pgadmin/static/css/overrides.css index 81074e653..c90b1d783 100755 --- a/web/pgadmin/static/css/overrides.css +++ b/web/pgadmin/static/css/overrides.css @@ -947,6 +947,11 @@ ul.nav.nav-tabs { padding-left: 20px; } +.select2-results span.wcTabIcon { + padding-left: 20px; + background-position: 0px 2px; +} + .pgadmin-controls.SQL>.CodeMirror { height: 500px!important; } diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js index 59729789a..282a81a30 100644 --- a/web/pgadmin/static/js/backform.pgadmin.js +++ b/web/pgadmin/static/js/backform.pgadmin.js @@ -1993,13 +1993,15 @@ // Refresh SQL Field to refresh the control lazily after it renders setTimeout(function() { self.refreshTextArea.apply(self); - }, 100); + }, 0); return self; }, refreshTextArea: function() { - this.sqlCtrl.refresh(); + if (this.sqlCtrl) { + this.sqlCtrl.refresh(); + } }, remove: function() { diff --git a/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js index 999ac7cd7..55ba7c0a0 100644 --- a/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js +++ b/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js @@ -450,7 +450,11 @@ this.undelegateEvents(); if (this.$select) { - this.$select.select2('destroy'); + if ( this.$select.data('select2')) { + this.$select.select2('destroy'); + } + delete this.$select; + this.$select = null; } this.$el.empty(); @@ -530,7 +534,9 @@ remove: function() { this.$select.off('change', this.onSave); - this.$select.select2('destroy'); + if (this.$select.data('select2')) { + this.$select.select2('destroy'); + } this.$el.empty(); Backgrid.SelectCell.prototype.remove.apply(this, arguments); }