Hi,
PFA updated patches:
I have made changes as per Ashesh's suggestions.
--
*Harshal Dhumal*
*Software Engineer *
EenterpriseDB <http://www.enterprisedb.com>
diff --git a/web/pgadmin/browser/server_groups/servers/databases/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/__init__.py
new file mode 100644
index 0000000..31fc4fa
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/__init__.py
@@ -0,0 +1,712 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2016, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import json
+from flask import render_template, make_response, current_app, request, jsonify
+from flask.ext.babel import gettext
+from pgadmin.utils.ajax import make_json_response, \
+ make_response as ajax_response, internal_server_error
+from pgadmin.browser.utils import NodeView, parse_privileges as parse_db_privileges
+from pgadmin.browser.collection import CollectionNodeModule
+import pgadmin.browser.server_groups.servers as servers
+from pgadmin.utils.ajax import precondition_required
+from pgadmin.utils.driver import get_driver
+from config import PG_DEFAULT_DRIVER
+from functools import wraps
+
+class DatabaseModule(CollectionNodeModule):
+ NODE_TYPE = 'database'
+ COLLECTION_LABEL = gettext("Databases")
+
+ def __init__(self, *args, **kwargs):
+ self.min_ver = None
+ self.max_ver = None
+
+ super(DatabaseModule, self).__init__(*args, **kwargs)
+
+ def get_nodes(self, gid, sid):
+ """
+ Generate the collection node
+ """
+ yield self.generate_browser_collection_node(sid)
+
+ @property
+ def script_load(self):
+ """
+ Load the module script for server, when any of the server-group node is
+ initialized.
+ """
+ return servers.ServerModule.NODE_TYPE
+
+ @property
+ def csssnippets(self):
+ """
+ Returns a snippet of css to include in the page
+ """
+ snippets = [
+ render_template(
+ "browser/css/collection.css",
+ node_type=self.node_type,
+ _=gettext
+ ),
+ render_template(
+ "databases/css/database.css",
+ node_type=self.node_type,
+ _=gettext
+ )
+ ]
+
+ for submodule in self.submodules:
+ snippets.extend(submodule.csssnippets)
+
+ return snippets
+
+
+blueprint = DatabaseModule(__name__)
+
+
+class DatabaseView(NodeView):
+ node_type = blueprint.node_type
+
+ parent_ids = [
+ {'type': 'int', 'id': 'gid'},
+ {'type': 'int', 'id': 'sid'}
+ ]
+ ids = [
+ {'type': 'int', 'id': 'did'}
+ ]
+
+ operations = dict({
+ 'obj': [
+ {'get': 'properties', 'delete': 'delete', 'put': 'update'},
+ {'get': 'list', 'post': 'create'}
+ ],
+ 'nodes': [{'get': 'node'}, {'get': 'nodes'}],
+ 'sql': [{'get': 'sql'}],
+ 'msql': [{'get': 'msql'}, {'get': 'msql'}],
+ 'stats': [{'get': 'statistics'}],
+ 'dependency': [{'get': 'dependencies'}],
+ 'dependent': [{'get': 'dependents'}],
+ 'children': [{'get': 'children'}],
+ 'module.js': [{}, {}, {'get': 'module_js'}],
+ 'connect': [{
+ 'get': 'connect_status', 'post': 'connect', 'delete': 'disconnect'
+ }],
+ 'get_encodings': [{'get': 'getEncodings'}, {'get': 'getEncodings'}],
+ 'get_ctypes': [{'get': 'getCtypes'}, {'get': 'getCtypes'}],
+ 'vopts': [{}, {'get': 'variable_options'}]
+ })
+
+ def check_precondition(f):
+ """
+ This function will behave as a decorator which will checks
+ database connection before running view, it will also attaches
+ manager,conn & template_path properties to self
+ """
+ @wraps(f)
+ def wrap(*args, **kwargs):
+ # Here args[0] will hold self & kwargs will hold gid,sid,did
+ self = args[0]
+ self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid'])
+ if 'did' in kwargs:
+ self.conn = self.manager.connection(did=kwargs['did'])
+ else:
+ self.conn = self.manager.connection()
+ # If DB not connected then return error to browser
+ if not self.conn.connected():
+ return precondition_required(
+ gettext(
+ "Connection to the server has been lost!"
+ )
+ )
+
+ ver = self.manager.version
+ server_type = self.manager.server_type
+ # we will set template path for sql scripts
+ if ver >= 90200:
+ self.template_path = 'databases/sql/9.2_plus'
+ else:
+ self.template_path = 'databases/sql/9.1_plus'
+ return f(*args, **kwargs)
+
+ return wrap
+
+
+ @check_precondition
+ def list(self, gid, sid):
+ SQL = render_template("/".join([self.template_path, 'properties.sql']))
+ status, res = self.conn.execute_dict(SQL)
+
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ return ajax_response(
+ response=res['rows'],
+ status=200
+ )
+
+ @check_precondition
+ def nodes(self, gid, sid):
+ res = []
+ SQL = render_template("/".join([self.template_path, 'get_nodes.sql']))
+ status, rset = self.conn.execute_2darray(SQL)
+
+ if not status:
+ return internal_server_error(errormsg=rest)
+
+ for row in rset['rows']:
+ if self.manager.db == row['name']:
+ connected=True
+ canDisConn=False
+ else:
+ conn=self.manager.connection(row['name'])
+ connected=conn.connected()
+ canDisConn=True
+
+
+ res.append(
+ self.blueprint.generate_browser_node(
+ row['did'],
+ row['name'],
+ icon="icon-database-not-connected" if not connected \
+ else "pg-icon-database",
+ connected=connected,
+ tablespace=row['spcname'],
+ allowConn=row['datallowconn'],
+ canCreate=row['cancreate'],
+ canDisconn=canDisConn
+ )
+ )
+
+ return make_json_response(
+ data=res,
+ status=200
+ )
+
+ @check_precondition
+ def node(self, gid, sid, did):
+ SQL = render_template("/".join([self.template_path, 'get_nodes.sql']), did=did)
+ status, rset = self.conn.execute_2darray(SQL)
+
+ if not status:
+ return internal_server_error(errormsg=rest)
+
+ for row in rset['rows']:
+ if self.manager.db == row['name']:
+ connected=True
+ else:
+ conn=self.manager.connection(row['name'])
+ connected=self.conn.connected()
+ return make_json_response(
+ data=self.blueprint.generate_browser_node(
+ row['did'],
+ row['name'],
+ icon="icon-database-not-connected" if not connected \
+ else "pg-icon-database",
+ connected=connected,
+ spcname=row['spcname'],
+ allowConn=row['datallowconn'],
+ canCreate=row['cancreate']
+ ),
+ status=200
+ )
+ @check_precondition
+ def properties(self, gid, sid, did):
+ SQL = render_template("/".join([self.template_path, 'properties.sql']), did=did)
+ status, res = self.conn.execute_dict(SQL)
+
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ SQL = render_template("/".join([self.template_path, 'acl.sql']), did=did)
+ status, dataclres = self.conn.execute_dict(SQL)
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ for row in dataclres['rows']:
+ priv = parse_db_privileges(row)
+ if row['deftype'] in res['rows'][0]:
+ res['rows'][0][row['deftype']].append(priv)
+ else:
+ res['rows'][0][row['deftype']] = [priv]
+
+ SQL = render_template("/".join([self.template_path, 'defacl.sql']), did=did)
+ status, defaclres = self.conn.execute_dict(SQL)
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ for row in defaclres['rows']:
+ priv = parse_db_privileges(row)
+ if row['deftype'] in res['rows'][0]:
+ res['rows'][0][row['deftype']].append(priv)
+ else:
+ res['rows'][0][row['deftype']] = [priv]
+
+ result = res['rows'][0]
+ # Fetching variable for database
+ SQL = render_template("/".join([self.template_path, 'get_variables.sql']), did=did)
+
+ status, res1 = self.conn.execute_dict(SQL)
+
+ if not status:
+ return internal_server_error(errormsg=res1)
+ # sending result to formtter
+ frmtd_reslt = self.formatter(result, res1)
+ # mergeing formated result with main result again
+ result.update(frmtd_reslt)
+ return ajax_response(
+ response=result,
+ status=200
+ )
+
+ @staticmethod
+ def formatter(result, varibles_rset):
+ """ We will use this function to format our output for
+ security label & variables"""
+ frmtd_result = dict()
+ sec_lbls = []
+ if 'seclabels' in result and result['seclabels'] is not None:
+ for sec in result['seclabels']:
+ sec = re.search(r'([^=]+)=(.*$)', sec)
+ sec_lbls.append({
+ 'provider': sec.group(1),
+ 'security_label': sec.group(2)
+ })
+ frmtd_result.update({"seclabels" :sec_lbls})
+
+ variablesLst = []
+ for row in varibles_rset['rows']:
+ for d in row['setconfig']:
+ var_name, var_value = d.split("=")
+ # Because we save as boolean string in db so it needs conversion
+ if var_value == 'false' or var_value == 'off':
+ var_value = False
+ variablesLst.append({'role': row['user_name'], 'name': var_name, 'value': var_value, 'database': row['db_name']})
+ frmtd_result.update({"variables" : variablesLst})
+ # returning final result
+ return frmtd_result
+
+
+ def module_js(self):
+ """
+ This property defines (if javascript) exists for this node.
+ Override this property for your own logic.
+ """
+ return make_response(
+ render_template(
+ "databases/js/databases.js",
+ _=gettext
+ ),
+ 200, {'Content-Type': 'application/x-javascript'}
+ )
+
+
+ def connect(self, gid, sid, did):
+ """Connect the Database."""
+ from pgadmin.utils.driver import get_driver
+ manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
+ conn = manager.connection(did=did, auto_reconnect=True)
+ status, errmsg = conn.connect()
+
+ if not status:
+ current_app.logger.error(
+ "Could not connected to database(#{0}).\nError: {2}".format(
+ did, errmsg
+ )
+ )
+
+ return internal_server_error(errmsg)
+ else:
+ current_app.logger.info('Connection Established for Database Id: \
+ %s' % (did))
+
+ return make_json_response(
+ success=1,
+ info=gettext("Database Connected."),
+ data={
+ 'icon': 'pg-icon-database',
+ 'connected': True
+ }
+ )
+
+ def disconnect(self, gid, sid, did):
+ """Disconnect the database."""
+
+ # Release Connection
+ from pgadmin.utils.driver import get_driver
+ manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
+
+ status = manager.release(did=did)
+
+ if not status:
+ return unauthorized(gettext("Database Could Not Disconnect."))
+ else:
+ return make_json_response(
+ success=1,
+ info=gettext("Database Disconnected."),
+ data={
+ 'icon': 'icon-database-not-connected',
+ 'connected': False
+ }
+ )
+
+ @check_precondition
+ def getEncodings(self, gid, sid, did=None):
+ """
+ This function to return list of avialable encodings
+ """
+ res = [{ 'label': '', 'value': '' }]
+ try:
+ SQL = render_template("/".join([self.template_path, 'get_encodings.sql']))
+ status, rset = self.conn.execute_2darray(SQL)
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ for row in rset['rows']:
+ res.append(
+ { 'label': row['encoding'], 'value': row['encoding'] }
+ )
+
+ return make_json_response(
+ data=res,
+ status=200
+ )
+
+ except Exception as e:
+ return internal_server_error(errormsg=str(e))
+
+ @check_precondition
+ def getCtypes(self, gid, sid, did=None):
+ """
+ This function to return list of available collation/character types
+ """
+ res = [{ 'label': '', 'value': '' }]
+ default_list = ['C', 'POSIX']
+ for val in default_list:
+ res.append(
+ {'label': val, 'value': val}
+ )
+ try:
+ SQL = render_template("/".join([self.template_path, 'get_ctypes.sql']))
+ status, rset = self.conn.execute_2darray(SQL)
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ for row in rset['rows']:
+ if row['cname'] not in default_list:
+ res.append(
+ { 'label': row['cname'], 'value': row['cname'] }
+ )
+
+ return make_json_response(
+ data=res,
+ status=200
+ )
+
+ except Exception as e:
+ return internal_server_error(errormsg=str(e))
+
+ @check_precondition
+ def create(self, gid, sid):
+ """Create the database."""
+ required_args = [
+ u'name'
+ ]
+
+ data = request.form if request.form else json.loads(request.data.decode())
+
+ for arg in required_args:
+ if arg not in data:
+ return make_json_response(
+ status=410,
+ success=0,
+ errormsg=gettext(
+ "Couldn't find the required parameter (%s)." % arg
+ )
+ )
+ try:
+ # The below SQL will execute CREATE DDL only
+ SQL = render_template("/".join([self.template_path, 'create.sql']), data=data, conn=self.conn)
+ status, msg = self.conn.execute_scalar(SQL)
+ if not status:
+ return internal_server_error(errormsg=msg)
+
+ if 'datacl' in data:
+ data['datacl'] = self.parse_privileges(data['datacl'])
+
+ # The below SQL will execute rest DMLs because we can not execute CREATE with any other
+ SQL = render_template("/".join([self.template_path, 'grant.sql']), data=data, conn=self.conn)
+ if SQL:
+ status, msg = self.conn.execute_scalar(SQL)
+ if not status:
+ return internal_server_error(errormsg=msg)
+
+ # We need oid of newly created database
+ SQL = render_template("/".join([self.template_path, 'properties.sql']), name=data['name'])
+ status, res = self.conn.execute_dict(SQL)
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ response=res['rows'][0]
+
+ return jsonify(
+ node=self.blueprint.generate_browser_node(
+ response['did'],
+ response['name'],
+ icon="icon-database-not-connected",
+ connected=False,
+ tablespace=response['default_tablespace'],
+ allowConn=True,
+ canCreate=response['cancreate'],
+ canDisconn=True
+ )
+ )
+
+ except Exception as e:
+ return make_json_response(
+ status=410,
+ success=0,
+ errormsg=e.message
+ )
+
+
+ @check_precondition
+ def update(self, gid, sid, did):
+ """Update the database."""
+
+ data = request.form if request.form else json.loads(request.data.decode())
+
+ try:
+ SQL = self.getSQL(gid, sid, data, did)
+ if SQL:
+ status, msg = conn.execute_scalar(SQL)
+
+ if not status:
+ return internal_server_error(errormsg=msg)
+
+ info = "Database updated."
+ else:
+ info = "Nothing to update."
+
+ return make_json_response(
+ success=1,
+ info = info,
+ data={
+ 'id': did,
+ 'sid': sid,
+ 'gid': gid,
+ }
+ )
+
+ except Exception as e:
+ return make_json_response(
+ status=410,
+ success=0,
+ errormsg=str(e)
+ )
+
+ @check_precondition
+ def delete(self, gid, sid, did):
+ """Delete the database."""
+
+ SQL = render_template("/".join([self.template_path, 'delete.sql']), did=did)
+ status, res = self.conn.execute_scalar(SQL)
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ if res is None:
+ return make_json_response(
+ success=0,
+ errormsg=gettext(
+ 'The specified database could not be found.\n'
+ )
+ )
+ else:
+ try:
+ SQL = render_template("/".join([self.template_path, 'delete.sql']), datname=res, conn=self.conn)
+ status, res = self.conn.execute_scalar(SQL)
+ if not status:
+ return internal_server_error(errormsg=res)
+ except Exception as e:
+ return make_json_response(
+ success=0,
+ errormsg=str(e))
+
+ try:
+ info = traceback.format_exc()
+ except Exception as e:
+ info = str(e)
+
+ return make_json_response(success=1,
+ info=info)
+
+ @staticmethod
+ def parse_privileges(str_privileges, object_type= 'DATABASE'):
+ """Parse Privileges."""
+ db_privileges = {
+ 'c': 'CONNECT',
+ 'C': 'CREATE',
+ 'T': 'TEMPORARY',
+ 'a': 'INSERT',
+ 'r': 'SELECT',
+ 'w': 'UPDATE',
+ 'd': 'DELETE',
+ 'D': 'TRUNCATE',
+ 'x': 'REFERENCES',
+ 't': 'TRIGGER',
+ 'U': 'USAGE',
+ 'X': 'EXECUTE'
+ }
+ privileges_max_cnt = {
+ 'DATABASE': 3,
+ 'TABLE': 7,
+ 'SEQUENCE': 3,
+ 'FUNCTION': 1,
+ 'TYPE': 1
+ }
+
+ privileges = []
+
+ for priv in str_privileges:
+ priv_with_grant = []
+ priv_without_grant = []
+ for privilege in priv['privileges']:
+ if privilege['with_grant']:
+ priv_with_grant.append(db_privileges[privilege['privilege_type']])
+ elif privilege['privilege']:
+ priv_without_grant.append(db_privileges[privilege['privilege_type']])
+
+ if object_type == "DATABASE":
+ priv_with_grant = ", ".join(priv_with_grant) if len(priv_with_grant) < privileges_max_cnt[object_type.upper()] else 'ALL'
+ priv_without_grant = ", ".join(priv_without_grant) if len(priv_without_grant) < privileges_max_cnt[object_type.upper()] else 'ALL'
+ else:
+ priv_with_grant = ", ".join(priv_with_grant)
+ priv_without_grant = ", ".join(priv_without_grant)
+
+ privileges.append({'grantee': priv['grantee'], 'with_grant': priv_with_grant, 'without_grant': priv_without_grant})
+
+ return privileges
+
+ @check_precondition
+ def msql(self, gid, sid, did=None):
+ """
+ This function to return modified SQL
+ """
+ data = {}
+ for k, v in request.args.items():
+ try:
+ data[k] = json.loads(v)
+ except ValueError:
+ data[k] = v
+
+ SQL = self.getSQL(gid, sid, data, did)
+
+ if isinstance(SQL, str) and SQL and SQL.strip('\n') and SQL.strip(' '):
+ return make_json_response(
+ data=SQL,
+ status=200
+ )
+ else:
+ return make_json_response(
+ data="-- modified SQL",
+ status=200
+ )
+
+ def getSQL(self, gid, sid, data, did=None):
+ """
+ This function will generate sql from model data
+ """
+
+ try:
+ if did is not None:
+ # Fetch the name of database for comperision
+ SQL = render_template("/".join([self.template_path, 'update.sql']), did=did)
+ status, name = self.conn.execute_scalar(SQL)
+ if not status:
+ return internal_server_error(errormsg=name)
+
+ data['old_name'] = name
+ if 'name' not in data:
+ data['name'] = name
+
+ for key in ['datacl', 'deftblacl', 'defseqacl', 'deffuncacl', 'deftypeacl']:
+ if key in data and data[key] is not None:
+ if 'added' in data[key]:
+ data[key]['added'] = self.parse_privileges(data[key]['added'])
+ if 'changed' in data[key]:
+ data[key]['changed'] = self.parse_privileges(data[key]['changed'])
+ if 'deleted' in data[key]:
+ data[key]['deleted'] = self.parse_privileges(data[key]['deleted'])
+
+ SQL = render_template("/".join([self.template_path, 'update.sql']), data=data, conn=self.conn)
+
+ else:
+
+ required_args = [
+ u'name'
+ ]
+
+ for arg in required_args:
+ if arg not in data:
+ return " -- definition incomplete"
+
+ for key in ['datacl', 'deftblacl', 'defseqacl', 'deffuncacl', 'deftypeacl']:
+ if key in data and data[key] is not None:
+ data[key] = self.parse_privileges(data[key])
+
+ SQL = render_template("/".join([self.template_path, 'create.sql']), data=data)
+ SQL += "\n"
+ SQL += render_template("/".join([self.template_path, 'grant.sql']), data=data)
+ return SQL
+
+ except Exception as e:
+ return internal_server_error(errormsg=str(e))
+
+ @check_precondition
+ def variable_options(self, gid, sid):
+ res = []
+ SQL = render_template("/".join([self.template_path, 'variables.sql']))
+ status, rset = self.conn.execute_dict(SQL)
+ if not status:
+ return internal_server_error(errormsg=rset)
+
+ return make_json_response(
+ data=rset['rows'],
+ status=200
+ )
+
+ @check_precondition
+ def sql(self, gid, sid, did):
+ """
+ This function will generate sql for sql panel
+ """
+ try:
+ SQL = render_template("/".join([self.template_path, 'properties.sql']), did=did)
+ status, res = self.conn.execute_dict(SQL)
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ result = res['rows'][0]
+
+ SQL = render_template("/".join([self.template_path, 'get_variables.sql']), did=did)
+ status, res1 = self.conn.execute_dict(SQL)
+ if not status:
+ return internal_server_error(errormsg=res1)
+
+ frmtd_reslt = self.formatter(result, res1)
+ result.update(frmtd_reslt)
+
+ SQL = render_template("/".join([self.template_path, 'create.sql']), data=result, conn=self.conn)
+ SQL += "\n\n"
+ SQL += render_template("/".join([self.template_path, 'grant.sql']), data=result, conn=self.conn)
+ return ajax_response(response=SQL)
+
+ except Exception as e:
+ return ajax_response(response=str(e))
+
+DatabaseView.register_node_view(blueprint)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/img/coll-database.png b/web/pgadmin/browser/server_groups/servers/databases/static/img/coll-database.png
new file mode 100755
index 0000000000000000000000000000000000000000..bfc0966c24b062675a6d2923e6670b238bd5b5e4
GIT binary patch
literal 771
zcmV+e1N{7nP)<h;3K|Lk000e1NJLTq000mG000mO0{{R3C@l|D0004TP)t-s0002P
zuxhuUORttU#<XeL%Z}#UsqN^!^76v(?6>6KqSnrc%Drv8tx~U;H^HrB-O!o;{qFz$
z<No>B`T5cH@Wt`&yzJ?+<>jm7;h^8&o5#Fru$VjP;kW$x+4}d-^z_H>?!N8qyX@(|
z?d{6+^xORT^0=Z-tdcO}*}Li7x$We=_3+g7^4a_Q@&5k%_w?xS?b7V&#OmO<+tIG{
z>e&DI^Z)nm{`AxI?6vFRnB&=l;M#lN+Jxlbm*3Z&(Zre1zLDkAv-0G}_Uy*=?6T_N
zm)z8W*v)v+#CyuSeAB~><JrCB*Sg@&tJK1h$FqLHt#iPva?8Ae*UFgV+p_TO*ZlnV
zvz$cb+rRSY+5h_V|NQm-_T~Kf?fdxY`T6Db^3(F~%>ViB>*JW?-htuVgyh_q&b*P|
z*MHN-jOE?J^6J_C`Q`ok`0nYx&A@fAnK|3Wl<nQM^X9(u>#ynIlibvI)5vDYxm?r5
zk;P-HF8}}l0d!JMQvg8b*k%9#010qNS#tmY07w7;07w8v$!k6U007BJL_t&-(_>%&
z0!AigAYfu-fC3g)Hg*n9E^Z!PJ`k5*Ku}0nL{v;%LQ+baA1ELrD<~u<ub`-;tfH!>
z4iwPP)Y8_`)zi~AFf=mO0123wnweWzT3OrJ+S!8z92}jTU0mJVJv_a<!2&+Me*OW0
zLBS!RVc`)Vfyk)nnAo^@{e;9MZHO6B(a9E;DXBJT=}<E=z-D9u&B(%TMs`kgOm19!
z9?*<@u!>+)Gmse|cNBmG7z+7|ic3n%$}1}Q`5?ZnLiRoYZDKCz4W-Rk0000bbVXQn
zWMOn=I%9HWVRU5xGB7bPEip1JFfmjzFgi3dIy5vZFf}?bFgTed9smFUC3HntbYx+4
zWjbwdWNBu305UK!FfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1g|G
BtCs)(
literal 0
HcmV?d00001
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/img/database.png b/web/pgadmin/browser/server_groups/servers/databases/static/img/database.png
new file mode 100755
index 0000000000000000000000000000000000000000..1a743d7a37e5781872a37dedc5a03bb9df931973
GIT binary patch
literal 706
zcmV;z0zLhSP)<h;3K|Lk000e1NJLTq000mG000mO0{{R3C@l|D0003sP)t-s0002f
z#gW6XYPX<Eua-Bmn>)s|Y1+$<=G>|6=)Lmt!td<2<lmy!&WOsrZM>~gub4K$tz+HL
zng9Ln|NZ0s`PljS(e?1f@$S6r>9XbJtK{LJ-`|_ZylSwRJL%!K{Q24X_s{h7$L{XF
z?d`kl>A&sm%JlTx{Q2^@qE4)mFyq_3>D;;P<Gc0n)b;Y&`}^_!{`>dz=<w~*?CHen
z;=1MC!u0Cc|M>I&_wN4m)Aa1M>*1K=*n{BOd*9lG<l&a+<E!)O+V<|W>*JW=+=S@h
ztMcgC|N8Ia-ht%bmjC+n|M~9!^V9R`w&dKH>gB8c^wHznf%59v?B|y0<f_ZOg8%sP
z;@X1b-<Zw7b+DN^!mef8#+2>dwe#k_^Xsqa;gj6dchksb$+=v;sZg(&I9k(EZvX%Q
z0d!JMQvg8b*k%9#010qNS#tmY07w7;07w8v$!k6U006{EL_t&-(_>&@U|?ioW&r|b
zCI$##Wn<^y<l^Sx<>MCs@dbs1MMTBKB_yS!Wn=|`0&?=gA_|I1$||aA>Kd9r0WEDE
zT|IpR14AQY6H_gafSI|4rIodft)0DtBSgRnDB$ekYUk?U1`%+#@Bj*U+PQi`Rk(Zm
z`1-j3wRpL~1+1(=D*PRhwAgq8RRll{_4Wv~b_oIsKve_-wfKdA3=IVfgqeqf%!shF
zkBkBdFhs}1#>FQjCMBn&ra}FS?0o>+m?|%1vwO+_001R)MObuXVRU6WV{&C-bY%cC
zFflMKF)}SMF;p@zIy5snG&CzPH99abIGH6L0000bbVXQnWMOn=I&E)cX=Zr<GB7bP
oEigGPFfmjzGdeUhIxsdXFf}?bFv^!ztN;K207*qoM6N<$g7w#XBLDyZ
literal 0
HcmV?d00001
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/img/databasebad.png b/web/pgadmin/browser/server_groups/servers/databases/static/img/databasebad.png
new file mode 100644
index 0000000000000000000000000000000000000000..96832908714ed515d594bd898486b8b925c7331f
GIT binary patch
literal 814
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47;6K3LR^8|%SR_3-jKC@f%p1p
z=FjdOxOljC(`@TwTQYB*?t6A;<=Yo~KYcp%{>}C$_ZM9|*KulZ?w++l>t~o9T$_CN
z!p#4F-~Ipl_}|YPKYw2Q`r+uucYEHv-1PM6>L(8u+`m8j_@1l{Gpt`e-2Uh1&0pWo
zfBAC!-Mf8n-|l|%a{t@6r@nl-{paVW9gF<dOfq<Ud+*CTJKsLu{q@6@ub*!I{{8Xa
zzu(`#y!i0;(wmn@UOn3N^zNZAuWtPR@%jJvcXv|4k1{Y^jkSMxv*p39>PxY9yKO{1
zzr1xfE$Lf%`Ne3nkKy5WGc!NExcRND>|0UM*Sx$7QO586{oi?b{{QvmZhF$!+}tl2
z8K0AqK7@w;|M~87V&cc>=nugm?|uE=xx4@W_5R<N%Qus}-uwDqiF5l99Q@wL=bfwT
z8$0{g78ajg-TV*~^xoV1t&8hxbMse*hA*|XPw#2^|Krn#z`%E2UT>XUUZ|=*S5Vk6
z)AG=|)Z53VT#fdA>*Rd-MB3>fo#*ljd+fwd1=`$BPkH-fS2-{O7)yfuf*Bm1-ADs+
zI14-?i-EKU7`vU!wgWO=c)B=-NL)@%0D_dHG)AU0HMcN@{>I+9&6B%lw@>encL?B6
zQP5G+Qqxn^RMl11R@dhd2?!7o4Gszm3=O`1;mRd8t`{#}y_A-al9Zf1W7f>q4J<l3
zYuDuFynQ44MmBfu0j6_ddfV1*%j3)2_HLV;0;9inw0^#PbbNHVeSP!>2Zsf@0R<ho
z8WZ>f1qITQrR4-AMR`pRU)EAHJ7;EOcgu`1sk_*rr#Ck#sK`qz#8v7-&zByb+iTv)
zY>?bJt#aE>)>en;qOPvSZ3a`OOq+T;?8dLKu$y7cAq{)ulcSlx)UC~xWoD@JF#fK#
zIy4LDXVntdh?11Vl2ohYqEsNoU}RuuplfKPYhV~+WME}tY-M7iZD49;U|=y*RSrc%
nZhlH;S|vn-fhAZ2NVS!L8AQXW>7i?Y8W=oX{an^LB{Ts5xrU7;
literal 0
HcmV?d00001
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css
new file mode 100644
index 0000000..f59bc8e
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css
@@ -0,0 +1,12 @@
+.pg-icon-database {
+ background-image: url('{{ url_for('NODE-database.static', filename='img/database.png') }}') !important;
+ background-repeat: no-repeat;
+ align-content: center;
+ vertical-align: middle;
+ height: 1.3em;
+}
+
+.icon-database-not-connected {
+ background-image: url('{{ url_for('NODE-database.static', filename='img/databasebad.png') }}') !important;
+ border-radius: 10px
+}
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
new file mode 100644
index 0000000..6bc8eba
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/js/databases.js
@@ -0,0 +1,358 @@
+define(
+ [
+ 'jquery', 'underscore', 'underscore.string', 'pgadmin',
+ 'pgadmin.browser', 'alertify', 'pgadmin.browser.collection',
+ 'pgadmin.browser.server.privilege', 'pgadmin.browser.server.variable',
+ ],
+function($, _, S, pgAdmin, pgBrowser, Alertify) {
+
+ if (!pgBrowser.Nodes['coll-database']) {
+ var databases = pgAdmin.Browser.Nodes['coll-database'] =
+ pgAdmin.Browser.Collection.extend({
+ node: 'database',
+ label: '{{ _('Databases') }}',
+ type: 'coll-database',
+ columns: ['name', 'did', 'datowner', 'comments']
+ });
+ };
+
+ var SecurityModel = pgAdmin.Browser.Node.Model.extend({
+ defaults: {
+ provider: undefined,
+ securitylabel: undefined
+ },
+ schema: [{
+ id: 'provider', label: '{{ _('Provider') }}',
+ type: 'text', editable: true
+ },{
+ id: 'security_label', label: '{{ _('Security Label') }}',
+ type: 'text', editable: true
+ }],
+ validate: function() {
+ var err = {},
+ errmsg = null,
+ data = this.toJSON();
+
+ if (_.isUndefined(data.label) ||
+ _.isNull(data.label) ||
+ String(data.label).replace(/^\s+|\s+$/g, '') == '') {
+ return _("Please specify the value for all the security providers.");
+ }
+ return null;
+ }
+ });
+
+ if (!pgBrowser.Nodes['database']) {
+ pgAdmin.Browser.Nodes['database'] = pgAdmin.Browser.Node.extend({
+ parent_type: 'server',
+ type: 'database',
+ hasSQL: true,
+ canDrop: true,
+ label: '{{ _('Database') }}',
+ Init: function() {
+ /* Avoid mulitple registration of menus */
+ if (this.initialized)
+ return;
+
+ this.initialized = true;
+
+ pgBrowser.add_menus([{
+ name: 'create_database_on_server', node: 'server', module: this,
+ applies: ['object', 'context'], callback: 'show_obj_properties',
+ category: 'create', priority: 4, label: '{{ _('Database...') }}',
+ icon: 'wcTabIcon pg-icon-database', data: {action: 'create'}
+ },{
+ name: 'create_database_on_coll', node: 'coll-database', module: this,
+ applies: ['object', 'context'], callback: 'show_obj_properties',
+ category: 'create', priority: 4, label: '{{ _('Database...') }}',
+ icon: 'wcTabIcon pg-icon-database', data: {action: 'create'}
+ },{
+ name: 'create_database', node: 'database', module: this,
+ applies: ['object', 'context'], callback: 'show_obj_properties',
+ category: 'create', priority: 4, label: '{{ _('Database...') }}',
+ icon: 'wcTabIcon pg-icon-database', data: {action: 'create'}
+ },{
+ name: 'connect_database', node: 'database', module: this,
+ applies: ['object', 'context'], callback: 'connect_database',
+ category: 'connect', priority: 4, label: '{{ _('Connect Database...') }}',
+ icon: 'fa fa-link', enable : 'is_not_connected'
+ },{
+ name: 'disconnect_database', node: 'database', module: this,
+ applies: ['object', 'context'], callback: 'disconnect_database',
+ category: 'drop', priority: 5, label: '{{ _('Disconnect Database...') }}',
+ icon: 'fa fa-chain-broken', enable : 'is_connected'
+ },{
+ name: 'drop_database', node: 'database', module: this,
+ applies: ['object', 'context'], callback: 'delete_obj',
+ category: 'drop', priority: 4, label: '{{ _('Drop Database...') }}',
+ icon: 'fa fa-chain-broken'
+ }]);
+
+ },
+ is_not_connected: function(node) {
+ return (node && node.connected != true);
+ },
+ is_connected: function(node) {
+ return (node && node.connected == true && node.canDisconn == true);
+ },
+ callbacks: {
+ /* Connect the database */
+ connect_database: 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;
+
+ connect_to_database(obj, d, t, i);
+ return false;
+ },
+ /* Disconnect the database */
+ disconnect_database: 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;
+
+ Alertify.confirm(
+ '{{ _('Disconnect the database') }}',
+ S('{{ _('Are you sure you want to disconnect the database - %%s ?') }}').sprintf(d.label).value(),
+ function(evt) {
+ $.ajax({
+ url: obj.generate_url(i, 'connect', d, true),
+ type:'DELETE',
+ success: function(res) {
+ if (res.success == 1) {
+ Alertify.success("{{ _('" + res.info + "') }}");
+ t.removeIcon(i);
+ d.connected = false;
+ d.icon = 'icon-database-not-connected';
+ t.addIcon(i, {icon: d.icon});
+ t.unload(i);
+ t.setInode(i);
+ }
+ },
+ error: function(xhr, status, error) {
+ try {
+ var err = $.parseJSON(xhr.responseText);
+ if (err.success == 0) {
+ msg = S('{{ _(' + err.errormsg + ')}}').value();
+ Alertify.error("{{ _('" + err.errormsg + "') }}");
+ }
+ } catch (e) {}
+ t.unload(i);
+ }
+ });
+ },
+ function(evt) {
+ return true;
+ });
+
+ return false;
+ },
+
+ /* Connect the database (if not connected), before opening this node */
+ beforeopen: function(item, data) {
+ if(!data || data._type != 'database') {
+ return false;
+ }
+
+ pgBrowser.tree.addIcon(item, {icon: data.icon});
+ if (!data.connected) {
+ connect_to_database(this, data, pgBrowser.tree, item);
+ return false;
+ }
+ return true;
+ },
+ },
+ model: pgAdmin.Browser.Node.Model.extend({
+ defaults: {
+ name: undefined,
+ owner: undefined,
+ comment: undefined,
+ encoding: 'UTF8',
+ template: undefined,
+ tablespace: undefined,
+ collation: undefined,
+ char_type: undefined,
+ conn_limit: -1,
+ variables: [],
+ privileges: [],
+ securities: [],
+ datacl: [],
+ deftblacl: [],
+ deffuncacl: [],
+ defseqacl: [],
+ deftypeacl: []
+ },
+ schema: [{
+ id: 'name', label: '{{ _('Database') }}', cell: 'string',
+ editable: false, type: 'text'
+ },{
+ id: 'did', label:'{{ _('Oid') }}', cell: 'string', mode: ['properties'],
+ editable: false, type: 'text', visible: false
+ },{
+ id: 'datowner', label:'{{ _('Owner') }}',
+ editable: false, type: 'text', node: 'role',
+ control: Backform.NodeListByNameControl
+ },{
+ id: 'comments', label:'{{ _('Comment') }}',
+ editable: false, type: 'multiline'
+ },{
+ id: 'encoding', label: '{{ _('Encoding') }}',
+ editable: false, type: 'text', group: 'Definition',
+ disabled: function(m) { return !m.isNew(); }, url: 'get_encodings',
+ control: 'node-ajax-options'
+ },{
+ id: 'template', label: '{{ _('Template') }}',
+ editable: false, type: 'text', group: 'Definition',
+ disabled: function(m) { return !m.isNew(); },
+ control: 'node-list-by-name', node: 'database'
+ },{
+ id: 'spcname', label: '{{ _('Tablespace') }}',
+ editable: false, type: 'text', group: 'Definition',
+ control: 'node-list-by-name', node: 'tablespace',
+ filter: function(m) {
+ if (m.label == "pg_global") return false;
+ else return true;
+ }
+ },{
+ id: 'datcollate', label: '{{ _('Collation') }}',
+ editable: false, type: 'text', group: 'Definition',
+ disabled: function(m) { return !m.isNew(); }, url: 'get_ctypes',
+ control: 'node-ajax-options'
+ },{
+ id: 'datctype', label: '{{ _('Character Type') }}',
+ editable: false, type: 'text', group: 'Definition',
+ disabled: function(m) { return !m.isNew(); }, url: 'get_ctypes',
+ control: 'node-ajax-options'
+ },{
+ id: 'conn_limit', label: '{{ _('Connection Limit') }}',
+ editable: false, type: 'int', group: 'Definition', min: -1
+ },{
+ id: 'datacl', label: '{{ _('Privileges') }}', model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend(
+ {privileges: ['C', 'T', 'c']}), uniqueCol : ['grantee', 'grantor'],
+ editable: false, type: 'collection', group: '{{ _('Security') }}', mode: ['properties', 'edit', 'create'],
+ canAdd: true, canDelete: true, control: 'unique-col-collection',
+ },{
+ id: 'variables', label: '{{ _('Variables') }}', type: 'collection',
+ model: pgAdmin.Browser.Node.VariableModel, editable: false,
+ group: '{{ _('Security') }}', mode: ['properties', 'edit', 'create'],
+ canAdd: true, canEdit: false, canDelete: true, hasRole: true,
+ control: Backform.VariableCollectionControl, node: 'role'
+ },{
+ id: 'securities', label: '{{ _('Securitiy Labels') }}', model: SecurityModel,
+ editable: false, type: 'collection', canEdit: false,
+ group: '{{ _('Security') }}', canDelete: true,
+ mode: ['properties', 'edit', 'create'], canAdd: true,
+ control: 'unique-col-collection', uniqueCol : ['provider'],
+ min_version: 90200
+ },{
+ type: 'nested', control: 'tab', group: '{{ _('Default Privileges') }}',
+ schema:[{
+ id: 'deftblacl', model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend(
+ {privileges: ['a', 'r', 'w', 'd', 'D', 'x', 't']}), label: '{{ _('Default Privileges: Tables') }}',
+ editable: false, type: 'collection', group: '{{ _('Tables') }}',
+ mode: ['edit', 'create'], control: 'unique-col-collection',
+ canAdd: true, canDelete: true, uniqueCol : ['grantee', 'grantor']
+ },{
+ id: 'defseqacl', model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend(
+ {privileges: ['r', 'w', 'U']}), label: '{{ _('Default Privileges: Sequences') }}',
+ editable: false, type: 'collection', group: '{{ _('Sequences') }}',
+ mode: ['edit', 'create'], control: 'unique-col-collection',
+ canAdd: true, canDelete: true, uniqueCol : ['grantee', 'grantor']
+ },{
+ id: 'deffuncacl', model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend(
+ {privileges: ['X']}), label: '{{ _('Default Privileges: Functions') }}',
+ editable: false, type: 'collection', group: '{{ _('Functions') }}',
+ mode: ['edit', 'create'], control: 'unique-col-collection',
+ canAdd: true, canDelete: true, uniqueCol : ['grantee', 'grantor']
+ },{
+ id: 'deftypeacl', model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend(
+ {privileges: ['U']}), label: '{{ _('Default Privileges: Types') }}',
+ editable: false, type: 'collection', group: '{{ _('Types') }}',
+ mode: ['edit', 'create'], control: 'unique-col-collection',
+ canAdd: true, canDelete: true, uniqueCol : ['grantee', 'grantor'],
+ min_version: 90200
+ }]
+ }
+ ],
+ validate: function(keys) {
+ var name = this.get('name');
+ if (_.isUndefined(name) || _.isNull(name) ||
+ String(name).replace(/^\s+|\s+$/g, '') == '') {
+ var msg = '{{ _('Name can not be empty!') }}';
+ this.errorModel.set('name', msg);
+ return msg;
+ } else {
+ this.errorModel.unset('name');
+ }
+ return null;
+ }
+ })
+ });
+ function connect_to_database(obj, data, tree, item) {
+ var onFailure = function(xhr, status, error, _model, _data, _tree, _item) {
+
+ tree.setInode(_item);
+ tree.addIcon(_item, {icon: 'icon-database-not-connected'});
+
+ Alertify.pgNotifier('error', xhr, error, function(msg) {
+ setTimeout(function() {
+ Alertify.dlgServerPass(
+ '{{ _('Connect to Database') }}',
+ msg, _model, _data, _tree, _item
+ ).resizeTo();
+ }, 100);
+ });
+ },
+ onSuccess = function(res, model, data, tree, item) {
+ tree.deselect(item);
+ tree.setInode(item);
+
+ if (res && res.data) {
+ if(typeof res.data.connected == 'boolean') {
+ data.connected = res.data.connected;
+ }
+ if (typeof res.data.icon == 'string') {
+ tree.removeIcon(item);
+ data.icon = res.data.icon;
+ tree.addIcon(item, {icon: data.icon});
+ }
+
+ Alertify.success(res.info);
+ setTimeout(function() {tree.select(item);}, 10);
+ setTimeout(function() {tree.open(item);}, 100);
+ }
+ };
+ Alertify.confirm(
+ '{{ _('Connect to Database') }}',
+ '{{ _('Do you want to connect the database?') }}',
+ function(evt) {
+ url = obj.generate_url(item, "connect", data, true);
+ $.post(url)
+ .done(
+ function(res) {
+ if (res.success == 1) {
+ return onSuccess(res, obj, data, tree, item);
+ }
+ })
+ .fail(
+ function(xhr, status, error) {
+ return onFailure(xhr, status, error, obj, data, tree, item);
+ });
+ },
+ function() {});
+ }
+
+ }
+
+ return pgBrowser.Nodes['coll-database'];
+});
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/acl.sql
new file mode 100644
index 0000000..99b4dab
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/acl.sql
@@ -0,0 +1,33 @@
+SELECT 'datacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT datacl FROM pg_database db
+ LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID
+ LEFT OUTER JOIN pg_shdescription descr ON (
+ db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)
+{% if did %}
+ WHERE db.oid = {{ did|qtLiteral }}::OID
+{% endif %}
+ ) acl,
+ aclexplode(datacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/create.sql
new file mode 100644
index 0000000..b3138e6
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/create.sql
@@ -0,0 +1,22 @@
+CREATE DATABASE {{ conn|qtIdent(data.name) }}
+{% if data.datowner %}
+ WITH {% endif %}{% if data.datowner %}OWNER = {{ conn|qtIdent(data.datowner) }}
+{% endif %}
+{% if data.template %}
+ TEMPLATE = {{ conn|qtIdent(data.template) }}
+{% endif %}
+{% if data.encoding %}
+ ENCODING = {{ data.encoding|qtLiteral }}
+{% endif %}
+{% if data.datcollate %}
+ LC_COLLATE = {{ data.datcollate|qtLiteral }}
+{% endif %}
+{% if data.datctype %}
+ LC_CTYPE = {{ data.datctype|qtLiteral }}
+{% endif %}
+{% if data.spcname %}
+ TABLESPACE = {{ conn|qtIdent(data.spcname) }}
+{% endif %}
+{% if data.conn_limit %}
+ CONNECTION LIMIT = {{ data.conn_limit }}
+{% endif %};
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/defacl.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/defacl.sql
new file mode 100644
index 0000000..5adb7f8
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/defacl.sql
@@ -0,0 +1,87 @@
+SELECT * FROM
+(SELECT
+ 'deftblacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT defaclacl defacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='r') acl,
+ aclexplode(defacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
+UNION ALL
+SELECT
+ 'defseqacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT defaclacl defacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='S') acl,
+ aclexplode(defacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
+UNION ALL
+SELECT
+ 'deffuncacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT defaclacl defacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='f') acl,
+ aclexplode(defacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
+) t
+
+ORDER BY deftype, grantee;
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/delete.sql
new file mode 100644
index 0000000..042113e
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/delete.sql
@@ -0,0 +1,8 @@
+{# We need database name before we execute drop #}
+{% if did %}
+SELECT db.datname as name FROM pg_database as db WHERE db.oid = {{did}}
+{% endif %}
+{# Using name from above query we will drop the database #}
+{% if datname %}
+ DROP DATABASE {{ conn|qtIdent(datname) }};
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_ctypes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_ctypes.sql
new file mode 100644
index 0000000..d559aa0
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_ctypes.sql
@@ -0,0 +1,5 @@
+SELECT DISTINCT(datctype) AS cname
+FROM pg_database
+UNION
+SELECT DISTINCT(datcollate) AS cname
+FROM pg_database
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_encodings.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_encodings.sql
new file mode 100644
index 0000000..03ae601
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_encodings.sql
@@ -0,0 +1,17 @@
+{#
+-- Given SQL is workaround
+-- We need to implement a mechanism to check for valid supported server encoding
+#}
+SELECT * FROM
+(SELECT pg_encoding_to_char(s.i) AS encoding
+ FROM (SELECT generate_series(0, 100, 1) as i) s) a
+WHERE encoding != '';
+
+{#
+-- For future use, Do not delete
+--SELECT * FROM
+--(SELECT s.i as id, pg_encoding_to_char(s.i)
+-- as encoding
+-- FROM (SELECT generate_series(0, 100, 1) as i) s) a
+--WHERE encoding != ''
+#}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_nodes.sql
new file mode 100644
index 0000000..87e32e5
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_nodes.sql
@@ -0,0 +1,7 @@
+SELECT
+ db.oid as did, db.datname as name, ta.spcname as spcname, db.datallowconn,
+ has_database_privilege(db.oid, 'CREATE') as cancreate
+FROM
+ pg_database db
+ LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid
+ {% if did %}WHERE db.oid={{did}}::int {% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_variables.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_variables.sql
new file mode 100644
index 0000000..a9ab7a9
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_variables.sql
@@ -0,0 +1,5 @@
+SELECT rl.*, r.rolname AS user_name, db.datname as db_name
+FROM pg_db_role_setting AS rl
+ LEFT JOIN pg_roles AS r ON rl.setrole = r.oid
+ LEFT JOIN pg_database AS db ON rl.setdatabase = db.oid
+WHERE setdatabase = {{did}}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/grant.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/grant.sql
new file mode 100644
index 0000000..64e7d43
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/grant.sql
@@ -0,0 +1,47 @@
+{#
+# CREATE DATABSE does not allow us to run any
+# other sql statments along with it, so we wrote
+# seprate sql for rest alter sql statments here
+#}
+{% import 'macros/variable.macros' as VARIABLE %}
+{% import 'macros/privilege.macros' as PRIVILEGE %}
+{% import 'macros/default_privilege.macros' as DEFAULT_PRIVILEGE %}
+{% if data.comments %}
+COMMENT ON DATABASE {{ conn|qtIdent(data.name) }}
+ IS {{ data.comments|qtLiteral }};
+{% endif %}
+
+{# We will generate Variable SQL's using macro #}
+{% if data.variables %}
+{% for var in data.variables %}
+{% if var.value == True %}
+{{ VARIABLE.APPLY(conn, data.name, var.role, var.name, 'on') }}
+{% elif var.value == False %}
+{{ VARIABLE.APPLY(conn, data.name, var.role, var.name, 'off') }}
+{% else %}
+{{ VARIABLE.APPLY(conn, data.name, var.role, var.name, var.value) }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if data.datacl %}
+{% for priv in data.datacl %}
+{{ PRIVILEGE.APPLY(conn, 'DATABASE', priv.grantee, data.name, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+
+{% if data.deftblacl %}
+{% for priv in data.deftblacl %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if data.defseqacl %}
+{% for priv in data.defseqacl %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'SEQUENCES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if data.deffuncacl %}
+{% for priv in data.deffuncacl %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'FUNCTIONS', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql
new file mode 100644
index 0000000..3d8dcb5
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql
@@ -0,0 +1,19 @@
+SELECT
+ db.oid as did, db.datname as name, db.dattablespace AS spcoid,
+ spcname, datallowconn, pg_encoding_to_char(encoding) AS encoding,
+ pg_get_userbyid(datdba) AS datowner,
+ has_database_privilege(db.oid, 'CREATE') as cancreate,
+ current_setting('default_tablespace') AS default_tablespace,
+ descr.description as comments
+FROM pg_database db
+ LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID
+ LEFT OUTER JOIN pg_shdescription descr ON (
+ db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
+ )
+{% if did %}
+WHERE db.oid= {{did}}::int
+{% endif %}
+{% if name %}
+WHERE db.datname = {{name|qtLiteral}}
+{% endif %}
+ORDER BY datname
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/update.sql
new file mode 100644
index 0000000..a750f67
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/update.sql
@@ -0,0 +1,163 @@
+{% import 'macros/variable.macros' as VARIABLE %}
+{% if data %}
+{# The SQL generated below will change name #}
+{% if data.old_name != data.name %}
+ALTER DATABASE {{ conn|qtIdent(data.old_name) }} RENAME TO {{ conn|qtIdent(data.name) }};
+{% endif %}
+{# The SQL generated below will change owner #}
+{% if data.datowner %}
+ALTER DATABASE {{ conn|qtIdent(data.name) }} OWNER TO {{ conn|qtIdent(data.datowner) }};
+{% endif %}
+{# The SQL generated below will change comments #}
+{% if data.comments %}
+COMMENT ON DATABASE {{ conn|qtIdent(data.name) }}
+IS '{{ data.comments }}';
+{% endif %}
+{# The SQL generated below will change tablespace #}
+{% if data.spcname %}
+ALTER DATABASE {{ conn|qtIdent(data.name) }} SET TABLESPACE {{ conn|qtIdent(data.spcname) }};
+{% endif %}
+{# The SQL generated below will change conn limit #}
+{% if data.conn_limit %}
+ALTER DATABASE {{ conn|qtIdent(data.name) }} WITH CONNECTION LIMIT = {{ conn|qtIdent(data.conn_limit) }};
+{% endif %}
+{# The SQL generated below will change Variables #}
+{% if data.variables and data.variables|length > 0 %}
+{% set variables = data.variables %}
+{% if 'deleted' in variables and variables.deleted|length > 0 %}
+{% for var in variables.deleted %}
+{{ VARIABLE.RESET(conn, var.database, var.role, var.name) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in variables and variables.added|length > 0 %}
+{% for var in variables.added %}
+{{ VARIABLE.APPLY(conn, var.database, var.role, var.name, var.value) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in variables and variables.changed|length > 0 %}
+{% for var in variables.changed %}
+{{ VARIABLE.APPLY(conn, var.database, var.role, var.name, var.value) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{# The SQL generated below will change priviledges #}
+{% if data.datacl %}
+{% if 'deleted' in data.datacl %}
+{% for priv in data.datacl.deleted %}
+{{ PRIVILEGE.RESETALL(conn, 'DATABASE', priv.grantee, data.name) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.datacl %}
+{% for priv in data.datacl.changed %}
+{{ PRIVILEGE.RESETALL(conn, 'DATABASE', priv.grantee, data.name) }}
+{{ PRIVILEGE.APPLY(conn, 'DATABASE', priv.grantee, data.name, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.datacl %}
+{% for priv in data.datacl.added %}
+{{ PRIVILEGE.APPLY(conn, 'DATABASE', priv.grantee, data.name, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if data.deftblacl %}
+{% if 'deleted' in data.deftblacl %}
+{% for priv in data.deftblacl.deleted %}
+{{ DEFAULT_PRIVILEGE.RESET(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.deftblacl %}
+{% for priv in data.deftblacl.changed %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.deftblacl %}
+{% for priv in data.deftblacl.added %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{# The SQL generated below will change priviledges #}
+{% if data.datacl %}
+{% if 'deleted' in data.datacl %}
+{% for priv in data.datacl.deleted %}
+{{ PRIVILEGE.RESETALL(conn, 'DATABASE', priv.grantee, data.name) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.datacl %}
+{% for priv in data.datacl.changed %}
+{{ PRIVILEGE.RESETALL(conn, 'DATABASE', priv.grantee, data.name) }}
+{{ PRIVILEGE.APPLY(conn, 'DATABASE', priv.grantee, data.name, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.datacl %}
+{% for priv in data.datacl.added %}
+{{ PRIVILEGE.APPLY(conn, 'DATABASE', priv.grantee, data.name, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if data.deftblacl %}
+{% if 'deleted' in data.deftblacl %}
+{% for priv in data.deftblacl.deleted %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'TABLES', priv.grantee) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.deftblacl %}
+{% for priv in data.deftblacl.changed %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'TABLES', priv.grantee) }}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.deftblacl %}
+{% for priv in data.deftblacl.added %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if data.defseqacl %}
+{% if 'deleted' in data.defseqacl %}
+{% for priv in data.defseqacl.deleted %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'SEQUENCES', priv.grantee) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.defseqacl %}
+{% for priv in data.defseqacl.changed %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'SEQUENCES', priv.grantee) }}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'SEQUENCES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.defseqacl %}
+{% for priv in data.defseqacl.added %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'SEQUENCES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if data.deffuncacl %}
+{% if 'deleted' in data.deffuncacl %}
+{% for priv in data.deffuncacl.deleted %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'FUNCTIONS', priv.grantee) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.deffuncacl %}
+{% for priv in data.deffuncacl.changed %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'FUNCTIONS', priv.grantee) }}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'FUNCTIONS', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.deffuncacl %}
+{% for priv in data.deffuncacl.added %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'FUNCTIONS', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% endif %}
+{# We need database name #}
+{% if did %}
+SELECT db.datname as name FROM pg_database as db WHERE db.oid = {{did}}
+{% endif %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/variables.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/variables.sql
new file mode 100644
index 0000000..b4e59ec
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/variables.sql
@@ -0,0 +1,2 @@
+SELECT name, vartype, min_val, max_val, enumvals
+FROM pg_settings WHERE context in ('user', 'superuser')
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/acl.sql
new file mode 100644
index 0000000..99b4dab
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/acl.sql
@@ -0,0 +1,33 @@
+SELECT 'datacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT datacl FROM pg_database db
+ LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID
+ LEFT OUTER JOIN pg_shdescription descr ON (
+ db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)
+{% if did %}
+ WHERE db.oid = {{ did|qtLiteral }}::OID
+{% endif %}
+ ) acl,
+ aclexplode(datacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/create.sql
new file mode 100644
index 0000000..b3138e6
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/create.sql
@@ -0,0 +1,22 @@
+CREATE DATABASE {{ conn|qtIdent(data.name) }}
+{% if data.datowner %}
+ WITH {% endif %}{% if data.datowner %}OWNER = {{ conn|qtIdent(data.datowner) }}
+{% endif %}
+{% if data.template %}
+ TEMPLATE = {{ conn|qtIdent(data.template) }}
+{% endif %}
+{% if data.encoding %}
+ ENCODING = {{ data.encoding|qtLiteral }}
+{% endif %}
+{% if data.datcollate %}
+ LC_COLLATE = {{ data.datcollate|qtLiteral }}
+{% endif %}
+{% if data.datctype %}
+ LC_CTYPE = {{ data.datctype|qtLiteral }}
+{% endif %}
+{% if data.spcname %}
+ TABLESPACE = {{ conn|qtIdent(data.spcname) }}
+{% endif %}
+{% if data.conn_limit %}
+ CONNECTION LIMIT = {{ data.conn_limit }}
+{% endif %};
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/defacl.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/defacl.sql
new file mode 100644
index 0000000..03084cf
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/defacl.sql
@@ -0,0 +1,114 @@
+SELECT * FROM
+(SELECT
+ 'deftblacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT defaclacl defacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='r') acl,
+ aclexplode(defacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
+UNION ALL
+SELECT
+ 'defseqacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT defaclacl defacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='S') acl,
+ aclexplode(defacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
+UNION ALL
+SELECT
+ 'deffuncacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT defaclacl defacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='f') acl,
+ aclexplode(defacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
+UNION ALL
+SELECT
+ 'deftypeacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT defaclacl defacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='T') acl,
+ aclexplode(defacl) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname) t
+
+ORDER BY deftype, grantee;
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/delete.sql
new file mode 100644
index 0000000..042113e
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/delete.sql
@@ -0,0 +1,8 @@
+{# We need database name before we execute drop #}
+{% if did %}
+SELECT db.datname as name FROM pg_database as db WHERE db.oid = {{did}}
+{% endif %}
+{# Using name from above query we will drop the database #}
+{% if datname %}
+ DROP DATABASE {{ conn|qtIdent(datname) }};
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_ctypes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_ctypes.sql
new file mode 100644
index 0000000..d559aa0
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_ctypes.sql
@@ -0,0 +1,5 @@
+SELECT DISTINCT(datctype) AS cname
+FROM pg_database
+UNION
+SELECT DISTINCT(datcollate) AS cname
+FROM pg_database
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_encodings.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_encodings.sql
new file mode 100644
index 0000000..03ae601
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_encodings.sql
@@ -0,0 +1,17 @@
+{#
+-- Given SQL is workaround
+-- We need to implement a mechanism to check for valid supported server encoding
+#}
+SELECT * FROM
+(SELECT pg_encoding_to_char(s.i) AS encoding
+ FROM (SELECT generate_series(0, 100, 1) as i) s) a
+WHERE encoding != '';
+
+{#
+-- For future use, Do not delete
+--SELECT * FROM
+--(SELECT s.i as id, pg_encoding_to_char(s.i)
+-- as encoding
+-- FROM (SELECT generate_series(0, 100, 1) as i) s) a
+--WHERE encoding != ''
+#}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_nodes.sql
new file mode 100644
index 0000000..87e32e5
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_nodes.sql
@@ -0,0 +1,7 @@
+SELECT
+ db.oid as did, db.datname as name, ta.spcname as spcname, db.datallowconn,
+ has_database_privilege(db.oid, 'CREATE') as cancreate
+FROM
+ pg_database db
+ LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid
+ {% if did %}WHERE db.oid={{did}}::int {% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_variables.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_variables.sql
new file mode 100644
index 0000000..a9ab7a9
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/get_variables.sql
@@ -0,0 +1,5 @@
+SELECT rl.*, r.rolname AS user_name, db.datname as db_name
+FROM pg_db_role_setting AS rl
+ LEFT JOIN pg_roles AS r ON rl.setrole = r.oid
+ LEFT JOIN pg_database AS db ON rl.setdatabase = db.oid
+WHERE setdatabase = {{did}}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/grant.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/grant.sql
new file mode 100644
index 0000000..56958de
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/grant.sql
@@ -0,0 +1,60 @@
+{#
+# CREATE DATABSE does not allow us to run any
+# other sql statments along with it, so we wrote
+# seprate sql for rest alter sql statments here
+#}
+{% import 'macros/security.macros' as SECLABLE %}
+{% import 'macros/variable.macros' as VARIABLE %}
+{% import 'macros/privilege.macros' as PRIVILEGE %}
+{% import 'macros/default_privilege.macros' as DEFAULT_PRIVILEGE %}
+{% if data.comments %}
+COMMENT ON DATABASE {{ conn|qtIdent(data.name) }}
+ IS {{ data.comments|qtLiteral }};
+{% endif %}
+
+{# We will generate Security Label SQL's using macro #}
+{% if data.securities %}
+{% for r in data.securities %}
+{{ SECLABLE.APPLY(conn, 'DATABASE', data.name, r.provider, r.securitylabel) }}
+{% endfor %}
+{% endif %}
+
+{# We will generate Variable SQL's using macro #}
+{% if data.variables %}
+{% for var in data.variables %}
+{% if var.value == True %}
+{{ VARIABLE.APPLY(conn, data.name, var.role, var.name, 'on') }}
+{% elif var.value == False %}
+{{ VARIABLE.APPLY(conn, data.name, var.role, var.name, 'off') }}
+{% else %}
+{{ VARIABLE.APPLY(conn, data.name, var.role, var.name, var.value) }}
+{% endif %}
+{% endfor %}
+
+{% endif %}
+{% if data.datacl %}
+{% for priv in data.datacl %}
+{{ PRIVILEGE.APPLY(conn, 'DATABASE', priv.grantee, data.name, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+
+{% if data.deftblacl %}
+{% for priv in data.deftblacl %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if data.defseqacl %}
+{% for priv in data.defseqacl %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'SEQUENCES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if data.deffuncacl %}
+{% for priv in data.deffuncacl %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'FUNCTIONS', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if data.deftypeacl %}
+{% for priv in data.deftypeacl %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TYPES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
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
new file mode 100644
index 0000000..978629d
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql
@@ -0,0 +1,20 @@
+SELECT
+ db.oid as did, db.datname as name, db.dattablespace AS spcoid,
+ spcname, datallowconn, pg_encoding_to_char(encoding) AS encoding,
+ pg_get_userbyid(datdba) AS datowner,
+ has_database_privilege(db.oid, 'CREATE') as cancreate,
+ current_setting('default_tablespace') AS default_tablespace,
+ descr.description as comments
+ ,(SELECT array_agg(provider || '=' || label) FROM pg_shseclabel sl1 WHERE sl1.objoid=db.oid) AS seclabels
+FROM pg_database db
+ LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID
+ LEFT OUTER JOIN pg_shdescription descr ON (
+ db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
+ )
+{% if did %}
+WHERE db.oid= {{did}}::int
+{% endif %}
+{% if name %}
+WHERE db.datname = {{name|qtLiteral}}
+{% endif %}
+ORDER BY datname
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/update.sql
new file mode 100644
index 0000000..4abad80
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/update.sql
@@ -0,0 +1,178 @@
+{% import 'macros/security.macros' as SECLABLE %}
+{% import 'macros/variable.macros' as VARIABLE %}
+{% import 'macros/privilege.macros' as PRIVILEGE %}
+{% import 'macros/default_privilege.macros' as DEFAULT_PRIVILEGE %}
+{% if data %}
+{# The SQL generated below will change name #}
+{% if data.old_name != data.name %}
+ALTER DATABASE {{ conn|qtIdent(data.old_name) }} RENAME TO {{ conn|qtIdent(data.name) }};
+{% endif %}
+{# The SQL generated below will change owner #}
+{% if data.datowner %}
+ALTER DATABASE {{ conn|qtIdent(data.name) }} OWNER TO {{ conn|qtIdent(data.datowner) }};
+{% endif %}
+{# The SQL generated below will change comments #}
+{% if data.comments %}
+COMMENT ON DATABASE {{ conn|qtIdent(data.name) }}
+IS '{{ data.comments }}';
+{% endif %}
+{# The SQL generated below will change tablespace #}
+{% if data.spcname %}
+ALTER DATABASE {{ conn|qtIdent(data.name) }} SET TABLESPACE {{ conn|qtIdent(data.spcname) }};
+{% endif %}
+{# The SQL generated below will change conn limit #}
+{% if data.conn_limit %}
+ALTER DATABASE {{ conn|qtIdent(data.name) }} WITH CONNECTION LIMIT = {{ conn|qtIdent(data.conn_limit) }};
+{% endif %}
+{# The SQL generated below will change Security Label #}
+{% if data.seclabels and data.seclabels|length > 0 %}
+{% set seclabels = data.seclabels %}
+{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
+{% for r in seclabels.deleted %}
+{{ SECLABLE.DROP(conn, 'DATABASE', data.name, r.provider) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in seclabels and seclabels.added|length > 0 %}
+{% for r in seclabels.added %}
+{{ SECLABLE.APPLY(conn, 'DATABASE', data.name, r.provider, r.security_label) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
+{% for r in seclabels.changed %}
+{{ SECLABLE.APPLY(conn, 'DATABASE', data.name, r.provider, r.security_label) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{# The SQL generated below will change Variables #}
+{% if data.variables and data.variables|length > 0 %}
+{% set variables = data.variables %}
+{% if 'deleted' in variables and variables.deleted|length > 0 %}
+{% for var in variables.deleted %}
+{{ VARIABLE.RESET(conn, var.database, var.role, var.name) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in variables and variables.added|length > 0 %}
+{% for var in variables.added %}
+{% if var.value == True %}
+{{ VARIABLE.APPLY(conn, var.database, var.role, var.name, 'on') }}
+{% elif var.value == False %}
+{{ VARIABLE.APPLY(conn, var.database, var.role, var.name, 'off') }}
+{% else %}
+{{ VARIABLE.APPLY(conn, var.database, var.role, var.name, var.value) }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if 'changed' in variables and variables.changed|length > 0 %}
+{% for var in variables.changed %}
+{% if var.value == True %}
+{{ VARIABLE.APPLY(conn, var.database, var.role, var.name, 'on') }}
+{% elif var.value == False %}
+{{ VARIABLE.APPLY(conn, var.database, var.role, var.name, 'off') }}
+{% else %}
+{{ VARIABLE.APPLY(conn, var.database, var.role, var.name, var.value) }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{# The SQL generated below will change priviledges #}
+{% if data.datacl %}
+{% if 'deleted' in data.datacl %}
+{% for priv in data.datacl.deleted %}
+{{ PRIVILEGE.RESETALL(conn, 'DATABASE', priv.grantee, data.name) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.datacl %}
+{% for priv in data.datacl.changed %}
+{{ PRIVILEGE.RESETALL(conn, 'DATABASE', priv.grantee, data.name) }}
+{{ PRIVILEGE.APPLY(conn, 'DATABASE', priv.grantee, data.name, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.datacl %}
+{% for priv in data.datacl.added %}
+{{ PRIVILEGE.APPLY(conn, 'DATABASE', priv.grantee, data.name, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if data.deftblacl %}
+{% if 'deleted' in data.deftblacl %}
+{% for priv in data.deftblacl.deleted %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'TABLES', priv.grantee) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.deftblacl %}
+{% for priv in data.deftblacl.changed %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'TABLES', priv.grantee) }}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.deftblacl %}
+{% for priv in data.deftblacl.added %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TABLES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if data.defseqacl %}
+{% if 'deleted' in data.defseqacl %}
+{% for priv in data.defseqacl.deleted %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'SEQUENCES', priv.grantee) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.defseqacl %}
+{% for priv in data.defseqacl.changed %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'SEQUENCES', priv.grantee) }}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'SEQUENCES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.defseqacl %}
+{% for priv in data.defseqacl.added %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'SEQUENCES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if data.deffuncacl %}
+{% if 'deleted' in data.deffuncacl %}
+{% for priv in data.deffuncacl.deleted %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'FUNCTIONS', priv.grantee) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.deffuncacl %}
+{% for priv in data.deffuncacl.changed %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'FUNCTIONS', priv.grantee) }}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'FUNCTIONS', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.deffuncacl %}
+{% for priv in data.deffuncacl.added %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'FUNCTIONS', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% if data.deftypeacl %}
+{% if 'deleted' in data.deftypeacl %}
+{% for priv in data.deftypeacl.deleted %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'TYPES', priv.grantee) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.deftypeacl %}
+{% for priv in data.deftypeacl.changed %}
+{{ DEFAULT_PRIVILEGE.RESETALL(conn, 'TYPES', priv.grantee) }}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TYPES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.deftypeacl %}
+{% for priv in data.deftypeacl.added %}
+{{ DEFAULT_PRIVILEGE.APPLY(conn, 'TYPES', priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+{% endif %}
+{# We need database name #}
+{% if did %}
+SELECT db.datname as name FROM pg_database as db WHERE db.oid = {{did}}
+{% endif %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/variables.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/variables.sql
new file mode 100644
index 0000000..b316dbd
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/variables.sql
@@ -0,0 +1 @@
+SELECT name, vartype, min_val, max_val, enumvals FROM pg_settings WHERE context in ('user', 'superuser')
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/privilege.js b/web/pgadmin/browser/server_groups/servers/static/js/privilege.js
index e1d3b76..374419f 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/privilege.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/privilege.js
@@ -272,6 +272,10 @@
$(self.$el.find('input[type=checkbox]')).on('blur',function() {
self.$el.blur();
});
+
+ //Make row visible in when entering in edit mode.
+ $(self.$el).pgMakeVisible('backform-tab');
+
self.delegateEvents();
return this;
diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py
index 408003b..c8a4979 100644
--- a/web/pgadmin/browser/utils.py
+++ b/web/pgadmin/browser/utils.py
@@ -366,3 +366,30 @@ class PGChildNodeView(NodeView):
nodes.extend(module.get_nodes(**kwargs))
return make_json_response(data=nodes)
+
+
+def parse_privileges(db_privileges):
+ """
+ Common utility function to parse privileges retrieved from database.
+ """
+ acl = {'grantor':db_privileges['grantor'],
+ 'grantee':db_privileges['grantee'],
+ 'privileges':[]
+ }
+
+ privileges = []
+ for idx, priv in enumerate(db_privileges['privileges']):
+ if db_privileges['grantable'][idx]:
+ privileges.append({"privilege_type": priv,
+ "privilege": True,
+ "with_grant": True
+ })
+ else:
+ privileges.append({"privilege_type": priv,
+ "privilege": True,
+ "with_grant": False
+ })
+
+ acl['privileges'] = privileges
+
+ return acl
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/privilege.js b/web/pgadmin/browser/server_groups/servers/static/js/privilege.js
index e1d3b76..374419f 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/privilege.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/privilege.js
@@ -272,6 +272,10 @@
$(self.$el.find('input[type=checkbox]')).on('blur',function() {
self.$el.blur();
});
+
+ //Make row visible in when entering in edit mode.
+ $(self.$el).pgMakeVisible('backform-tab');
+
self.delegateEvents();
return this;
diff --git a/web/pgadmin/browser/server_groups/servers/templates/macros/default_privilege.macros b/web/pgadmin/browser/server_groups/servers/templates/macros/default_privilege.macros
new file mode 100644
index 0000000..40a656c
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/templates/macros/default_privilege.macros
@@ -0,0 +1,14 @@
+{% macro APPLY(conn, type, role, priv, with_grant) -%}
+{% if priv %}
+ALTER DEFAULT PRIVILEGES
+GRANT {{ priv }} ON {{ type }} TO {{ conn|qtIdent(role) }};
+{% endif %}
+{% if with_grant %}
+ALTER DEFAULT PRIVILEGES
+GRANT {{ with_grant }} ON {{ type }} TO {{ conn|qtIdent(role) }} WITH GRANT OPTION;
+{% endif %}
+{%- endmacro %}
+{% macro RESETALL(conn, type, role) -%}
+ALTER DEFAULT PRIVILEGES
+ REVOKE ALL ON {{ type }} FROM {{ conn|qtIdent(role) }};
+{%- endmacro %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/templates/macros/privilege.macros b/web/pgadmin/browser/server_groups/servers/templates/macros/privilege.macros
new file mode 100644
index 0000000..1d6660c
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/templates/macros/privilege.macros
@@ -0,0 +1,11 @@
+{% macro APPLY(conn, type, role, param, priv, with_grant) -%}
+{% if priv %}
+GRANT {{ priv }} ON {{ type }} {{ conn|qtIdent(param) }} TO {{ conn|qtIdent(role) }};
+{% endif %}
+{% if with_grant %}
+GRANT {{ with_grant }} ON {{ type }} {{ conn|qtIdent(param) }} TO {{ conn|qtIdent(role) }} WITH GRANT OPTION;
+{% endif %}
+{%- endmacro %}
+{% macro RESETALL(conn, type, role, param) -%}
+REVOKE ALL ON {{ type }} {{ conn|qtIdent(param) }} FROM {{ conn|qtIdent(role) }};
+{%- endmacro %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/variable.js b/web/pgadmin/browser/server_groups/servers/static/js/variable.js
index 2ead1a0..eaf7038 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/variable.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/variable.js
@@ -198,13 +142,27 @@
),
initialize: function(opts) {
- var self = this;
+ var self = this,
+ uniqueCol = ['name'];
+
+ /*
+ * Read from field schema whether user wants to use database and role
+ * fields in Variable control.
+ */
+ self.hasDatabase = opts.field.get('hasDatabase');
+ self.hasRole = opts.field.get('hasRole');
+ // Update unique coll field based on above flag status.
+ if (self.hasDatabase) {
+ uniqueCol.push('database')
+ } else if (self.hasRole) {
+ uniqueCol.push('role')
+ }
// Overriding the uniqueCol in the field
if (opts && opts.field) {
if (opts.field instanceof Backform.Field) {
opts.field.set({
- uniqueCol: ['name', 'role', 'database'],
+ uniqueCol: uniqueCol || self.uniqueCol,
model: pgNode.VariableModel
},
{
@@ -212,7 +170,7 @@
});
} else {
opts.field.extend({
- uniqueCol: ['name', 'role', 'database'],
+ uniqueCol: uniqueCol || self.uniqueCol,
model: pgNode.VariableModel
});
}
@@ -222,8 +180,7 @@
self, arguments
);
- self.hasDatabase = self.field.get('hasDatabase');
- self.hasRole = self.field.get('hasRole');
+
self.availVariables = {};
var node = self.field.get('node').type,
@@ -566,7 +523,7 @@
checkVars.push('database');
}
- if (self.role) {
+ if (self.hasRole) {
checkVars.push('role');
}
--
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers