diff --git a/docs/en_US/images/server_advanced.png b/docs/en_US/images/server_advanced.png
index dfd3c9133..898bf9dfc 100644
Binary files a/docs/en_US/images/server_advanced.png and b/docs/en_US/images/server_advanced.png differ
diff --git a/docs/en_US/server_dialog.rst b/docs/en_US/server_dialog.rst
index 3cd33c238..06901803e 100644
--- a/docs/en_US/server_dialog.rst
+++ b/docs/en_US/server_dialog.rst
@@ -44,4 +44,5 @@ Click the *Advanced* tab to continue.
Use the fields in the *Advanced* tab to configure a connection:
-* Specify the IP address of the server host. Using this field to specify the host IP address will avoid a DNS lookup on connection, however it may be useful to specify both a host name and address when using Kerberos, GSSAPI, or SSPI authentication methods, as well as for verify-full SSL certificate verification
\ No newline at end of file
+* Specify the IP address of the server host. Using this field to specify the host IP address will avoid a DNS lookup on connection, however it may be useful to specify both a host name and address when using Kerberos, GSSAPI, or SSPI authentication methods, as well as for verify-full SSL certificate verification
+* The DB restriction field allows you to enter an SQL restriction that will be used against the pg_database table to limit the databases that you see. For example, you might enter: *live_db test_db* so that only live_db and test_db are shown in the pgAdmin browser. Separate entries with a comma or tab as you type.
\ No newline at end of file
diff --git a/web/migrations/versions/d85a62333272_.py b/web/migrations/versions/d85a62333272_.py
new file mode 100644
index 000000000..54da9d06e
--- /dev/null
+++ b/web/migrations/versions/d85a62333272_.py
@@ -0,0 +1,28 @@
+
+"""empty message
+
+Revision ID: d85a62333272
+Revises: 3c1e4b6eda55
+Create Date: 2017-07-07 16:03:23.842734
+
+"""
+from alembic import op
+import sqlalchemy as sa
+from pgadmin.model import db
+
+
+# revision identifiers, used by Alembic.
+revision = 'd85a62333272'
+down_revision = 'f195f9a4923d'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ db.engine.execute(
+ 'ALTER TABLE server ADD COLUMN db_res TEXT'
+ )
+
+
+def downgrade():
+ pass
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index 5e9d378cf..a74436efa 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -380,7 +380,8 @@ class ServerNode(PGChildNodeView):
'sslmode': 'ssl_mode',
'gid': 'servergroup_id',
'comment': 'comment',
- 'role': 'role'
+ 'role': 'role',
+ 'db_res': 'db_res'
}
disp_lbl = {
@@ -398,6 +399,8 @@ class ServerNode(PGChildNodeView):
data = request.form if request.form else json.loads(
request.data, encoding='utf-8'
)
+ if 'db_res' in data:
+ data['db_res'] = ','.join(data['db_res'])
if 'hostaddr' in data and data['hostaddr'] != '':
if not self.pat4.match(data['hostaddr']):
@@ -497,7 +500,8 @@ class ServerNode(PGChildNodeView):
'role': server.role,
'connected': connected,
'version': manager.ver,
- 'server_type': manager.server_type if connected else 'pg'
+ 'server_type': manager.server_type if connected else 'pg',
+ 'db_res': server.db_res.split(',') if server.db_res else None
})
return ajax_response(
@@ -544,7 +548,8 @@ class ServerNode(PGChildNodeView):
'connected': connected,
'version': manager.ver,
'sslmode': server.ssl_mode,
- 'server_type': manager.server_type if connected else 'pg'
+ 'server_type': manager.server_type if connected else 'pg',
+ 'db_res': server.db_res.split(',') if server.db_res else None
}
)
@@ -597,7 +602,8 @@ class ServerNode(PGChildNodeView):
username=data[u'username'],
ssl_mode=data[u'sslmode'],
comment=data[u'comment'] if u'comment' in data else None,
- role=data[u'role'] if u'role' in data else None
+ role=data[u'role'] if u'role' in data else None,
+ db_res=','.join(data[u'db_res']) if u'db_res' in data else None
)
db.session.add(server)
db.session.commit()
diff --git a/web/pgadmin/browser/server_groups/servers/databases/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/__init__.py
index e40c78753..010049d7b 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/__init__.py
@@ -28,7 +28,9 @@ from pgadmin.utils.ajax import gone
from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER
-
+from pgadmin.browser.server_groups.servers import ServerNode
+from flask_security import current_user
+from pgadmin.model import Server
class DatabaseModule(CollectionNodeModule):
NODE_TYPE = 'database'
@@ -166,11 +168,18 @@ class DatabaseView(PGChildNodeView):
(self.manager.db_info[self.manager.did])['datlastsysoid'] \
if self.manager.db_info is not None and \
self.manager.did in self.manager.db_info else 0
+
+ db_disp_res = None
+ params = None
+ if self.manager and self.manager.db_res:
+ db_disp_res = ", ".join(['%s'] * len(self.manager.db_res.split(',')))
+ params = tuple(self.manager.db_res.split(','))
+
SQL = render_template(
"/".join([self.template_path, 'properties.sql']),
- conn=self.conn, last_system_oid=last_system_oid
+ conn=self.conn, last_system_oid=last_system_oid, db_restrictions=db_disp_res
)
- status, res = self.conn.execute_dict(SQL)
+ status, res = self.conn.execute_dict(SQL, params)
if not status:
return internal_server_error(errormsg=res)
@@ -188,12 +197,19 @@ class DatabaseView(PGChildNodeView):
if self.manager.db_info is not None and \
self.manager.did in self.manager.db_info else 0
)
+ server_node_res = self.manager
+ db_disp_res = None
+ params = None
+ if server_node_res and server_node_res.db_res:
+ db_disp_res = ", ".join(['%s']*len(server_node_res.db_res.split(',')))
+ params = tuple(server_node_res.db_res.split(','))
SQL = render_template(
"/".join([self.template_path, 'nodes.sql']),
- last_system_oid=last_system_oid
+ last_system_oid=last_system_oid,
+ db_restrictions=db_disp_res
)
- status, rset = self.conn.execute_dict(SQL)
+ status, rset = self.conn.execute_dict(SQL, params)
if not status:
return internal_server_error(errormsg=rset)
@@ -851,12 +867,17 @@ class DatabaseView(PGChildNodeView):
if self.manager.db_info is not None and \
self.manager.did in self.manager.db_info else 0
+ db_disp_res = None
+ params = None
+ if self.manager and self.manager.db_res:
+ db_disp_res = ", ".join(['%s'] * len(self.manager.db_res.split(',')))
+ params = tuple(self.manager.db_res.split(','))
+
conn = self.manager.connection()
- status, res = conn.execute_dict(
- render_template(
- "/".join([self.template_path, 'stats.sql']),
- did=did, conn=conn, last_system_oid=last_system_oid
- )
+ status, res = conn.execute_dict(render_template(
+ "/".join([self.template_path, 'stats.sql']),
+ did=did, conn=conn, last_system_oid=last_system_oid, db_restrictions=db_disp_res
+ ),params
)
if not status:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql
index cb1a454ea..928124fae 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql
@@ -41,5 +41,10 @@ db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
db.datname = {{ name|qtLiteral }}::text{% else %}
db.oid > {{ last_system_oid|qtLiteral }}::OID
{% endif %}{% endif %}
+{% if db_restrictions %}
+
+AND
+db.datname in ({{db_restrictions}})
+{% endif %}
ORDER BY datname;
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/stats.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/stats.sql
index 5b192432c..ee920a97a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/stats.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/stats.sql
@@ -29,5 +29,10 @@ WHERE {% if did %}
db.datid = {{ did|qtLiteral }}::OID{% else %}
db.datid > {{ last_system_oid|qtLiteral }}::OID
{% endif %}
+{% if db_restrictions %}
+
+AND
+db.datname in ({{db_restrictions}})
+{% endif %}
ORDER BY db.datname;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/nodes.sql
index b05880c37..82c58d0e2 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/nodes.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/nodes.sql
@@ -8,5 +8,10 @@ WHERE {% if did %}
db.oid = {{ did|qtLiteral }}::OID{% else %}
db.oid > {{ last_system_oid }}::OID
{% endif %}
+{% if db_restrictions %}
+
+AND
+db.datname in ({{db_restrictions}})
+{% endif %}
ORDER BY datname;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql
index 2f6e42319..a251ebd59 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql
@@ -34,5 +34,10 @@ db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
db.datname = {{ name|qtLiteral }}::text{% else %}
db.oid > {{ last_system_oid|qtLiteral }}::OID
{% endif %}{% endif %}
+{% if db_restrictions %}
+
+AND
+db.datname in ({{db_restrictions}})
+{% endif %}
ORDER BY datname;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/stats.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/stats.sql
index 4f23b9db6..5cc5d6704 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/stats.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/stats.sql
@@ -24,5 +24,10 @@ WHERE {% if did %}
db.datid = {{ did|qtLiteral }}::OID{% else %}
db.datid > {{ last_system_oid|qtLiteral }}::OID
{% endif %}
+{% if db_restrictions %}
+
+AND
+db.datname in ({{db_restrictions}})
+{% endif %}
ORDER BY db.datname;
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js
index c57a0e241..a337dfe9f 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/server.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js
@@ -624,7 +624,8 @@ define('pgadmin.node.server', [
role: null,
connect_now: true,
password: undefined,
- save_password: false
+ save_password: false,
+ db_res: ''
},
// Default values!
initialize: function(attrs, args) {
@@ -669,6 +670,10 @@ define('pgadmin.node.server', [
},{
id: 'hostaddr', label: gettext('Host address'), type: 'text', group: gettext('Advanced'),
mode: ['properties', 'edit', 'create'], disabled: 'isConnected'
+ },{
+ id: 'db_res', label: gettext('DB restriction'), type: 'select2', group: gettext('Advanced'),
+ mode: ['properties', 'edit', 'create'], disabled: 'isConnected', select2: {multiple: true, allowClear: false,
+ tags: true, tokenSeparators: [','], first_empty: false, selectOnClose: true, emptyOptions: true}
},{
id: 'port', label: gettext('Port'), type: 'int', group: gettext('Connection'),
mode: ['properties', 'edit', 'create'], disabled: 'isConnected', min: 1024, max: 65535
diff --git a/web/pgadmin/model/__init__.py b/web/pgadmin/model/__init__.py
index 2205508ba..e1e1d4a73 100644
--- a/web/pgadmin/model/__init__.py
+++ b/web/pgadmin/model/__init__.py
@@ -128,6 +128,8 @@ class Server(db.Model):
servers = db.relationship('ServerGroup',
backref=db.backref('server', cascade="all, delete-orphan"),
lazy='joined')
+ db_res = db.Column(db.Text(), nullable=True)
+
diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js
index dec018559..af95d9f42 100644
--- a/web/pgadmin/static/js/backform.pgadmin.js
+++ b/web/pgadmin/static/js/backform.pgadmin.js
@@ -1707,7 +1707,8 @@
defaults: _.extend({}, Backform.SelectControl.prototype.defaults, {
select2: {
first_empty: true,
- multiple: false
+ multiple: false,
+ emptyOptions: false
}
}),
formatter: Select2Formatter,
@@ -1761,7 +1762,8 @@
data.select2 = data.select2 || {};
_.defaults(data.select2, this.defaults.select2, {
first_empty: true,
- multiple: false
+ multiple: false,
+ emptyOptions: false
});
// Evaluate the disabled, visible, and required option
@@ -1807,8 +1809,29 @@
* Add empty option as Select2 requires any empty '