public inbox for [email protected]  
help / color / mirror / Atom feed
From: Murtuza Zabuawala <[email protected]>
To: Dave Page <[email protected]>
Cc: pgadmin-hackers <[email protected]>
Subject: Re: [pgAdmin4][RM#3140] Add service parameter
Date: Mon, 12 Mar 2018 13:01:24 +0530
Message-ID: <CAKKotZT5AikN+70CnVwcyDApeSPZ6Awx8YTNKoMWxHRmoVctHw@mail.gmail.com> (raw)
In-Reply-To: <CAKKotZSt4is3xjhRbroRkuzBvGtbruGERQ2EX4dTTSvDX+3KnQ@mail.gmail.com>
References: <CAKKotZSrYHCypG0rfsD9DHCoE8-c+XAvBnU3vS8LMDfPqSrC1Q@mail.gmail.com>
	<CA+OCxoy7R6TU5Z3+b-D6Oz80yBafYVMe-6AtJ3QXoK6HC3jFXw@mail.gmail.com>
	<CAKKotZSt4is3xjhRbroRkuzBvGtbruGERQ2EX4dTTSvDX+3KnQ@mail.gmail.com>

Hi Dave,

PFA updated patch.

--
Regards,
Murtuza Zabuawala
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


On Fri, Mar 9, 2018 at 9:29 PM, Murtuza Zabuawala <
[email protected]> wrote:

> Hi Dave,
>
> I'll change the name and send you updated patch.
>
>
> On Fri, Mar 9, 2018 at 9:25 PM, Dave Page <[email protected]> wrote:
>
>> HI
>>
>> On Fri, Mar 9, 2018 at 11:47 AM, Murtuza Zabuawala <
>> [email protected]> wrote:
>>
>>> Hi,
>>>
>>> PFA patch to add service parameter in server dialog.
>>> - Docs updated
>>> - Test case added for Service ID parameter
>>>
>>> Please note,
>>> I have extracted Connection class and Server manager class from our own
>>> custom Psycopg2 driver module.
>>>
>>> Patch also covers RM#3120
>>>
>>
>>  This patch seems a little confused. The "Service" and "Service ID"
>> fields from pgAdmin 3 are very different things. The Redmine ticket seems
>> to be asking for the Service field (the pg_service.conf service name),
>> *not* Service ID (the operating system's service ID, used to start/stop the
>> database server service).
>>
>> --
>> Dave Page
>> Blog: http://pgsnake.blogspot.com
>> Twitter: @pgsnake
>>
>> EnterpriseDB UK: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>
>


Attachments:

  [application/octet-stream] RM_3140_v1.diff (280.4K, 3-RM_3140_v1.diff)
  download | inline diff:
diff --git a/docs/en_US/images/server_connection.png b/docs/en_US/images/server_connection.png
index 7ebf6b58b7bd260bcb3c1223907c3a22375fcd94..dd18376e5884effefabf45fc1bf6332f5522a73e 100644
GIT binary patch
literal 66243
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

literal 39678
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

diff --git a/docs/en_US/server_dialog.rst b/docs/en_US/server_dialog.rst
index 24a726b..b1159c5 100644
--- a/docs/en_US/server_dialog.rst
+++ b/docs/en_US/server_dialog.rst
@@ -32,6 +32,7 @@ Use the fields in the *Connection* tab to configure a connection:
 * Use the *Password* field to provide a password that will be supplied when authenticating with the server.
 * Check the box next to *Save password?* to instruct pgAdmin to save the password for future use.
 * Use the *Role* field to specify the name of a role that has privileges that will be conveyed to the client after authentication with the server. This selection allows you to connect as one role, and then assume the permissions of this specified role after the connection is established. Note that the connecting role must be a member of the role specified.
+* Use the *Service* field to specify the service name. For more information, see `Section 33.16 of the Postgres documentation <https://www.postgresql.org/docs/10/static/libpq-pgservice.html>`_.
 
 Click the *SSL* tab to continue.
 
diff --git a/web/migrations/versions/50aad68f99c2_.py b/web/migrations/versions/50aad68f99c2_.py
new file mode 100644
index 0000000..4cda56b
--- /dev/null
+++ b/web/migrations/versions/50aad68f99c2_.py
@@ -0,0 +1,82 @@
+
+"""Added service field option in server table (RM#3140)
+
+Revision ID: 50aad68f99c2
+Revises: 02b9dccdcfcb
+Create Date: 2018-03-07 11:53:57.584280
+
+"""
+from pgadmin.model import db
+
+
+# revision identifiers, used by Alembic.
+revision = '50aad68f99c2'
+down_revision = '02b9dccdcfcb'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+        # To Save previous data
+        db.engine.execute("ALTER TABLE server RENAME TO server_old")
+
+        # With service file some fields won't be mandatory as user can provide
+        # them using service file. Removed NOT NULL constraint from few columns
+        db.engine.execute("""
+            CREATE TABLE server (
+                id	INTEGER NOT NULL,
+                user_id	INTEGER NOT NULL,
+                servergroup_id	INTEGER NOT NULL,
+                name	VARCHAR(128) NOT NULL,
+                host	VARCHAR(128),
+                port	INTEGER NOT NULL CHECK(port >= 1024 AND port <= 65534),
+                maintenance_db	VARCHAR(64),
+                username	VARCHAR(64) NOT NULL,
+                password	VARCHAR(64),
+                role	VARCHAR(64),
+                ssl_mode	VARCHAR(16) NOT NULL CHECK(ssl_mode IN
+                    ( 'allow' , 'prefer' , 'require' , 'disable' ,
+                      'verify-ca' , 'verify-full' )
+                ),
+                comment	VARCHAR(1024),
+                discovery_id	VARCHAR(128),
+                hostaddr	TEXT(1024),
+                db_res	TEXT,
+                passfile	TEXT,
+                sslcert	TEXT,
+                sslkey	TEXT,
+                sslrootcert	TEXT,
+                sslcrl	TEXT,
+                sslcompression	INTEGER DEFAULT 0,
+                bgcolor TEXT(10),
+                fgcolor TEXT(10),
+                PRIMARY KEY(id),
+                FOREIGN KEY(user_id) REFERENCES user(id),
+                FOREIGN KEY(servergroup_id) REFERENCES servergroup(id)
+            )
+        """)
+
+        # Copy old data again into table
+        db.engine.execute("""
+        INSERT INTO server (
+            id,user_id, servergroup_id, name, host, port, maintenance_db,
+            username, ssl_mode, comment, password, role, discovery_id,
+            hostaddr, db_res, passfile, sslcert, sslkey, sslrootcert, sslcrl,
+            bgcolor, fgcolor
+        ) SELECT
+            id,user_id, servergroup_id, name, host, port, maintenance_db,
+            username, ssl_mode, comment, password, role, discovery_id,
+            hostaddr, db_res, passfile, sslcert, sslkey, sslrootcert, sslcrl,
+            bgcolor, fgcolor
+        FROM server_old""")
+
+        # Remove old data
+        db.engine.execute("DROP TABLE server_old")
+
+        # Add column for Service
+        db.engine.execute(
+            'ALTER TABLE server ADD COLUMN service 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 dfa9d62..fecb66d 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -478,7 +478,8 @@ class ServerNode(PGChildNodeView):
             'sslcrl': 'sslcrl',
             'sslcompression': 'sslcompression',
             'bgcolor': 'bgcolor',
-            'fgcolor': 'fgcolor'
+            'fgcolor': 'fgcolor',
+            'service': 'service'
         }
 
         disp_lbl = {
@@ -515,7 +516,7 @@ class ServerNode(PGChildNodeView):
         if connected:
             for arg in (
                     'host', 'hostaddr', 'port', 'db', 'username', 'sslmode',
-                    'role'
+                    'role', 'service'
             ):
                 if arg in data:
                     return forbidden(
@@ -663,7 +664,8 @@ class ServerNode(PGChildNodeView):
                 'sslrootcert': server.sslrootcert if is_ssl else None,
                 'sslcrl': server.sslcrl if is_ssl else None,
                 'sslcompression': True if is_ssl and server.sslcompression
-                else False
+                else False,
+                'service': server.service if server.service else None
             }
         )
 
@@ -672,18 +674,22 @@ class ServerNode(PGChildNodeView):
         """Add a server node to the settings database"""
         required_args = [
             u'name',
-            u'host',
             u'port',
-            u'db',
-            u'username',
             u'sslmode',
-            u'role'
+            u'username'
         ]
 
         data = request.form if request.form else json.loads(
             request.data, encoding='utf-8'
         )
 
+        # Some fields can be provided with service file so they are optional
+        if 'service' in data and not data['service']:
+            required_args.extend([
+                u'host',
+                u'db',
+                u'role'
+            ])
         for arg in required_args:
             if arg not in data:
                 return make_json_response(
@@ -711,29 +717,26 @@ class ServerNode(PGChildNodeView):
         try:
             server = Server(
                 user_id=current_user.id,
-                servergroup_id=data[u'gid'] if u'gid' in data else gid,
-                name=data[u'name'],
-                host=data[u'host'],
-                hostaddr=data[u'hostaddr'] if u'hostaddr' in data else None,
-                port=data[u'port'],
-                maintenance_db=data[u'db'],
-                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,
+                servergroup_id=data.get('gid', gid),
+                name=data.get('name'),
+                host=data.get('host', None),
+                hostaddr=data.get('hostaddr', None),
+                port=data.get('port'),
+                maintenance_db=data.get('db', None),
+                username=data.get('username'),
+                ssl_mode=data.get('sslmode'),
+                comment=data.get('comment', None),
+                role=data.get('role', None),
                 db_res=','.join(data[u'db_res'])
-                if u'db_res' in data
-                else None,
-                sslcert=data['sslcert'] if is_ssl else None,
-                sslkey=data['sslkey'] if is_ssl else None,
-                sslrootcert=data['sslrootcert'] if is_ssl else None,
-                sslcrl=data['sslcrl'] if is_ssl else None,
+                if u'db_res' in data else None,
+                sslcert=data.get('sslcert', None),
+                sslkey=data.get('sslkey', None),
+                sslrootcert=data.get('sslrootcert', None),
+                sslcrl=data.get('sslcrl', None),
                 sslcompression=1 if is_ssl and data['sslcompression'] else 0,
-                bgcolor=data['bgcolor'] if u'bgcolor' in data
-                else None,
-                fgcolor=data['fgcolor'] if u'fgcolor' in data
-                else None
-
+                bgcolor=data.get('bgcolor', None),
+                fgcolor=data.get('fgcolor', None),
+                service=data.get('service', None)
             )
             db.session.add(server)
             db.session.commit()
@@ -930,7 +933,7 @@ class ServerNode(PGChildNodeView):
         if 'password' not in data:
             conn_passwd = getattr(conn, 'password', None)
             if conn_passwd is None and server.password is None and \
-                    server.passfile is None:
+                    server.passfile is None and server.service is None:
                 # Return the password template in case password is not
                 # provided, or password has not been saved earlier.
                 return make_json_response(
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 9932808..53be225 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/server.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js
@@ -665,6 +665,7 @@ define('pgadmin.node.server', [
           sslkey: undefined,
           sslrootcert: undefined,
           sslcrl: undefined,
+          service: undefined,
         },
         // Default values!
         initialize: function(attrs, args) {
@@ -841,12 +842,18 @@ define('pgadmin.node.server', [
             var passfile = m.get('passfile');
             return !_.isUndefined(passfile) && !_.isNull(passfile);
           },
+        },{
+          id: 'service', label: gettext('Service'), type: 'text',
+          mode: ['properties', 'edit', 'create'], disabled: 'isConnected',
+          group: gettext('Connection'),
         }],
         validate: function() {
           var err = {},
             errmsg,
             self = this;
 
+          var service_id = this.get('service');
+
           var check_for_empty = function(id, msg) {
             var v = self.get(id);
             if (
@@ -903,26 +910,41 @@ define('pgadmin.node.server', [
           }
           check_for_empty('name', gettext('Name must be specified.'));
 
-          if (check_for_empty(
-            'host', gettext('Either Host name or Host address must be specified.')
-          ) && check_for_empty('hostaddr', gettext('Either Host name or Host address must be specified.'))){
-            errmsg = errmsg || gettext('Either Host name or Host address must be specified');
+          // If no service id then only check
+          if (
+              _.isUndefined(service_id) || _.isNull(service_id) ||
+              String(service_id).replace(/^\s+|\s+$/g, '') == ''
+            ) {
+            if (check_for_empty(
+              'host', gettext('Either Host name or Host address must be specified.')
+            ) && check_for_empty('hostaddr', gettext('Either Host name or Host address must be specified.'))){
+              errmsg = errmsg || gettext('Either Host name or Host address must be specified');
+            } else {
+              errmsg = undefined;
+              delete err['host'];
+              delete err['hostaddr'];
+            }
+
+            check_for_empty(
+              'db', gettext('Maintenance database must be specified.')
+            );
+            check_for_valid_ip(
+              'hostaddr', gettext('Host address must be valid IPv4 or IPv6 address.')
+            );
+            check_for_valid_ip(
+              'hostaddr', gettext('Host address must be valid IPv4 or IPv6 address.')
+            );
           } else {
-            errmsg = undefined;
-            delete err['host'];
-            delete err['hostaddr'];
+            _.each(['host', 'hostaddr', 'db'], (item) => {
+              self.errorModel.unset(item);
+            });
           }
 
           check_for_empty(
-            'db', gettext('Maintenance database must be specified.')
-          );
-          check_for_empty(
             'username', gettext('Username must be specified.')
           );
           check_for_empty('port', gettext('Port must be specified.'));
-          check_for_valid_ip(
-            'hostaddr', gettext('Host address must be valid IPv4 or IPv6 address.')
-          );
+
           this.errorModel.set(err);
 
           if (_.size(err)) {
diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_add_server_with_service_id.py b/web/pgadmin/browser/server_groups/servers/tests/test_add_server_with_service_id.py
new file mode 100644
index 0000000..3b03d49
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/tests/test_add_server_with_service_id.py
@@ -0,0 +1,47 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression.python_test_utils import test_utils as utils
+
+
+class ServersWithServiceIDAddTestCase(BaseTestGenerator):
+    """ This class will add the servers under default server group. """
+
+    scenarios = [
+        # Fetch the default url for server object
+        (
+            'Default Server Node url', dict(
+                url='/browser/server/obj/'
+            )
+        )
+    ]
+
+    def setUp(self):
+        pass
+
+    def runTest(self):
+        """ This function will add the server under default server group."""
+        url = "{0}{1}/".format(self.url, utils.SERVER_GROUP)
+        # Add service name in the config
+        self.server['service'] = "TestDB"
+        response = self.tester.post(
+            url,
+            data=json.dumps(self.server),
+            content_type='html/json'
+        )
+        self.assertEquals(response.status_code, 200)
+        response_data = json.loads(response.data.decode('utf-8'))
+        self.server_id = response_data['node']['_id']
+
+    def tearDown(self):
+        """This function delete the server from SQLite """
+        utils.delete_server_with_api(self.tester, self.server_id)
diff --git a/web/pgadmin/model/__init__.py b/web/pgadmin/model/__init__.py
index 674f945..11bc9f0 100644
--- a/web/pgadmin/model/__init__.py
+++ b/web/pgadmin/model/__init__.py
@@ -107,13 +107,13 @@ class Server(db.Model):
         nullable=False
     )
     name = db.Column(db.String(128), nullable=False)
-    host = db.Column(db.String(128), nullable=False)
+    host = db.Column(db.String(128), nullable=True)
     hostaddr = db.Column(db.String(128), nullable=True)
     port = db.Column(
         db.Integer(),
         db.CheckConstraint('port >= 1024 AND port <= 65534'),
         nullable=False)
-    maintenance_db = db.Column(db.String(64), nullable=False)
+    maintenance_db = db.Column(db.String(64), nullable=True)
     username = db.Column(db.String(64), nullable=False)
     password = db.Column(db.String(64), nullable=True)
     role = db.Column(db.String(64), nullable=True)
@@ -144,6 +144,7 @@ class Server(db.Model):
     )
     bgcolor = db.Column(db.Text(10), nullable=True)
     fgcolor = db.Column(db.Text(10), nullable=True)
+    service = db.Column(db.Text(), nullable=True)
 
 
 class ModulePreference(db.Model):
diff --git a/web/pgadmin/utils/driver/psycopg2/__init__.py b/web/pgadmin/utils/driver/psycopg2/__init__.py
index 941a694..95a49fb 100644
--- a/web/pgadmin/utils/driver/psycopg2/__init__.py
+++ b/web/pgadmin/utils/driver/psycopg2/__init__.py
@@ -8,1985 +8,23 @@
 ##########################################################################
 
 """
-Implementation of Connection, ServerManager and Driver classes using the
-psycopg2. It is a wrapper around the actual psycopg2 driver, and connection
+Implementation of Driver class
+It is a wrapper around the actual psycopg2 driver, and connection
 object.
-"""
 
+"""
 import datetime
-import os
-import random
-import select
-import sys
-
-import simplejson as json
-import psycopg2
-from flask import g, current_app, session
+from flask import session
 from flask_babel import gettext
-from flask_security import current_user
-from pgadmin.utils.crypto import decrypt
-from psycopg2.extensions import adapt, encodings
+import psycopg2
+from psycopg2.extensions import adapt
 
 import config
 from pgadmin.model import Server, User
-from pgadmin.utils.exception import ConnectionLost
-from pgadmin.utils import get_complete_file_path
 from .keywords import ScanKeyword
-from ..abstract import BaseDriver, BaseConnection
-from .cursor import DictCursor
-from .typecast import register_global_typecasters, \
-    register_string_typecasters, register_binary_typecasters, \
-    register_array_to_string_typecasters, ALL_JSON_TYPES
-from collections import deque
-
-
-if sys.version_info < (3,):
-    # Python2 in-built csv module do not handle unicode
-    # backports.csv module ported from PY3 csv module for unicode handling
-    from backports import csv
-    from StringIO import StringIO
-    IS_PY2 = True
-else:
-    from io import StringIO
-    import csv
-    IS_PY2 = False
-
-_ = gettext
-
-
-# Register global type caster which will be applicable to all connections.
-register_global_typecasters()
-
-
-class Connection(BaseConnection):
-    """
-    class Connection(object)
-
-        A wrapper class, which wraps the psycopg2 connection object, and
-        delegate the execution to the actual connection object, when required.
-
-    Methods:
-    -------
-    * connect(**kwargs)
-      - Connect the PostgreSQL/EDB Postgres Advanced Server using the psycopg2
-      driver
-
-    * execute_scalar(query, params, formatted_exception_msg)
-      - Execute the given query and returns single datum result
-
-    * execute_async(query, params, formatted_exception_msg)
-      - Execute the given query asynchronously and returns result.
-
-    * execute_void(query, params, formatted_exception_msg)
-      - Execute the given query with no result.
-
-    * execute_2darray(query, params, formatted_exception_msg)
-      - Execute the given query and returns the result as a 2 dimensional
-        array.
-
-    * execute_dict(query, params, formatted_exception_msg)
-      - Execute the given query and returns the result as an array of dict
-        (column name -> value) format.
-
-    * connected()
-      - Get the status of the connection.
-        Returns True if connected, otherwise False.
-
-    * reset()
-      - Reconnect the database server (if possible)
-
-    * transaction_status()
-      - Transaction Status
-
-    * ping()
-      - Ping the server.
-
-    * _release()
-      - Release the connection object of psycopg2
-
-    * _reconnect()
-      - Attempt to reconnect to the database
-
-    * _wait(conn)
-      - This method is used to wait for asynchronous connection. This is a
-        blocking call.
-
-    * _wait_timeout(conn)
-      - This method is used to wait for asynchronous connection with timeout.
-        This is a non blocking call.
-
-    * poll(formatted_exception_msg)
-      - This method is used to poll the data of query running on asynchronous
-        connection.
-
-    * status_message()
-      - Returns the status message returned by the last command executed on
-      the server.
-
-    * rows_affected()
-      - Returns the no of rows affected by the last command executed on
-      the server.
-
-    * cancel_transaction(conn_id, did=None)
-      - This method is used to cancel the transaction for the
-        specified connection id and database id.
-
-    * messages()
-      - Returns the list of messages/notices sends from the PostgreSQL database
-        server.
-
-    * _formatted_exception_msg(exception_obj, formatted_msg)
-      - This method is used to parse the psycopg2.Error object and returns the
-        formatted error message if flag is set to true else return
-        normal error message.
-
-    """
-
-    def __init__(self, manager, conn_id, db, auto_reconnect=True, async=0,
-                 use_binary_placeholder=False, array_to_string=False):
-        assert (manager is not None)
-        assert (conn_id is not None)
-
-        self.conn_id = conn_id
-        self.manager = manager
-        self.db = db if db is not None else manager.db
-        self.conn = None
-        self.auto_reconnect = auto_reconnect
-        self.async = async
-        self.__async_cursor = None
-        self.__async_query_id = None
-        self.__backend_pid = None
-        self.execution_aborted = False
-        self.row_count = 0
-        self.__notices = None
-        self.password = None
-        # This flag indicates the connection status (connected/disconnected).
-        self.wasConnected = False
-        # This flag indicates the connection reconnecting status.
-        self.reconnecting = False
-        self.use_binary_placeholder = use_binary_placeholder
-        self.array_to_string = array_to_string
-
-        super(Connection, self).__init__()
-
-    def as_dict(self):
-        """
-        Returns the dictionary object representing this object.
-        """
-        # In case, it cannot be auto reconnectable, or already been released,
-        # then we will return None.
-        if not self.auto_reconnect and not self.conn:
-            return None
-
-        res = dict()
-        res['conn_id'] = self.conn_id
-        res['database'] = self.db
-        res['async'] = self.async
-        res['wasConnected'] = self.wasConnected
-        res['auto_reconnect'] = self.auto_reconnect
-        res['use_binary_placeholder'] = self.use_binary_placeholder
-        res['array_to_string'] = self.array_to_string
-
-        return res
-
-    def __repr__(self):
-        return "PG Connection: {0} ({1}) -> {2} (ajax:{3})".format(
-            self.conn_id, self.db,
-            'Connected' if self.conn and not self.conn.closed else
-            "Disconnected",
-            self.async
-        )
-
-    def __str__(self):
-        return "PG Connection: {0} ({1}) -> {2} (ajax:{3})".format(
-            self.conn_id, self.db,
-            'Connected' if self.conn and not self.conn.closed else
-            "Disconnected",
-            self.async
-        )
-
-    def connect(self, **kwargs):
-        if self.conn:
-            if self.conn.closed:
-                self.conn = None
-            else:
-                return True, None
-
-        pg_conn = None
-        password = None
-        passfile = None
-        mgr = self.manager
-
-        encpass = kwargs['password'] if 'password' in kwargs else None
-        passfile = kwargs['passfile'] if 'passfile' in kwargs else None
-
-        if encpass is None:
-            encpass = self.password or getattr(mgr, 'password', None)
-
-        # Reset the existing connection password
-        if self.reconnecting is not False:
-            self.password = None
-
-        if encpass:
-            # Fetch Logged in User Details.
-            user = User.query.filter_by(id=current_user.id).first()
-
-            if user is None:
-                return False, gettext("Unauthorized request.")
-
-            try:
-                password = decrypt(encpass, user.password)
-                # Handling of non ascii password (Python2)
-                if hasattr(str, 'decode'):
-                    password = password.decode('utf-8').encode('utf-8')
-                # password is in bytes, for python3 we need it in string
-                elif isinstance(password, bytes):
-                    password = password.decode()
-
-            except Exception as e:
-                current_app.logger.exception(e)
-                return False, \
-                    _(
-                        "Failed to decrypt the saved password.\nError: {0}"
-                    ).format(str(e))
-
-        # If no password credential is found then connect request might
-        # come from Query tool, ViewData grid, debugger etc tools.
-        # we will check for pgpass file availability from connection manager
-        # if it's present then we will use it
-        if not password and not encpass and not passfile:
-            passfile = mgr.passfile if mgr.passfile else None
-
-        try:
-            if hasattr(str, 'decode'):
-                database = self.db.encode('utf-8')
-                user = mgr.user.encode('utf-8')
-                conn_id = self.conn_id.encode('utf-8')
-            else:
-                database = self.db
-                user = mgr.user
-                conn_id = self.conn_id
-
-            import os
-            os.environ['PGAPPNAME'] = '{0} - {1}'.format(
-                config.APP_NAME, conn_id)
-
-            pg_conn = psycopg2.connect(
-                host=mgr.host,
-                hostaddr=mgr.hostaddr,
-                port=mgr.port,
-                database=database,
-                user=user,
-                password=password,
-                async=self.async,
-                passfile=get_complete_file_path(passfile),
-                sslmode=mgr.ssl_mode,
-                sslcert=get_complete_file_path(mgr.sslcert),
-                sslkey=get_complete_file_path(mgr.sslkey),
-                sslrootcert=get_complete_file_path(mgr.sslrootcert),
-                sslcrl=get_complete_file_path(mgr.sslcrl),
-                sslcompression=True if mgr.sslcompression else False
-            )
-
-            # If connection is asynchronous then we will have to wait
-            # until the connection is ready to use.
-            if self.async == 1:
-                self._wait(pg_conn)
-
-        except psycopg2.Error as e:
-            if e.pgerror:
-                msg = e.pgerror
-            elif e.diag.message_detail:
-                msg = e.diag.message_detail
-            else:
-                msg = str(e)
-            current_app.logger.info(
-                u"Failed to connect to the database server(#{server_id}) for "
-                u"connection ({conn_id}) with error message as below"
-                u":{msg}".format(
-                    server_id=self.manager.sid,
-                    conn_id=conn_id,
-                    msg=msg.decode('utf-8') if hasattr(str, 'decode') else msg
-                )
-            )
-            return False, msg
-
-        # Overwrite connection notice attr to support
-        # more than 50 notices at a time
-        pg_conn.notices = deque([], self.ASYNC_NOTICE_MAXLENGTH)
-        self.conn = pg_conn
-        self.wasConnected = True
-        try:
-            status, msg = self._initialize(conn_id, **kwargs)
-        except Exception as e:
-            current_app.logger.exception(e)
-            self.conn = None
-            if not self.reconnecting:
-                self.wasConnected = False
-            raise e
-
-        if status:
-            mgr._update_password(encpass)
-        else:
-            if not self.reconnecting:
-                self.wasConnected = False
-
-        return status, msg
-
-    def _initialize(self, conn_id, **kwargs):
-        self.execution_aborted = False
-        self.__backend_pid = self.conn.get_backend_pid()
-
-        setattr(g, "{0}#{1}".format(
-            self.manager.sid,
-            self.conn_id.encode('utf-8')
-        ), None)
-
-        status, cur = self.__cursor()
-        formatted_exception_msg = self._formatted_exception_msg
-        mgr = self.manager
-
-        def _execute(cur, query, params=None):
-            try:
-                self.__internal_blocking_execute(cur, query, params)
-            except psycopg2.Error as pe:
-                cur.close()
-                return formatted_exception_msg(pe, False)
-            return None
-
-        # autocommit flag does not work with asynchronous connections.
-        # By default asynchronous connection runs in autocommit mode.
-        if self.async == 0:
-            if 'autocommit' in kwargs and kwargs['autocommit'] is False:
-                self.conn.autocommit = False
-            else:
-                self.conn.autocommit = True
-
-        register_string_typecasters(self.conn)
-
-        if self.array_to_string:
-            register_array_to_string_typecasters(self.conn)
-
-        # Register type casters for binary data only after registering array to
-        # string type casters.
-        if self.use_binary_placeholder:
-            register_binary_typecasters(self.conn)
-
-        status = _execute(cur, "SET DateStyle=ISO;"
-                               "SET client_min_messages=notice;"
-                               "SET bytea_output=escape;"
-                               "SET client_encoding='UNICODE';")
-
-        if status is not None:
-            self.conn.close()
-            self.conn = None
-
-            return False, status
-
-        if mgr.role:
-            status = _execute(cur, u"SET ROLE TO %s", [mgr.role])
-
-            if status is not None:
-                self.conn.close()
-                self.conn = None
-                current_app.logger.error(
-                    "Connect to the database server (#{server_id}) for "
-                    "connection ({conn_id}), but - failed to setup the role "
-                    "with error message as below:{msg}".format(
-                        server_id=self.manager.sid,
-                        conn_id=conn_id,
-                        msg=status
-                    )
-                )
-                return False, \
-                    _(
-                        "Failed to setup the role with error message:\n{0}"
-                    ).format(status)
-
-        if mgr.ver is None:
-            status = _execute(cur, "SELECT version()")
-
-            if status is not None:
-                self.conn.close()
-                self.conn = None
-                self.wasConnected = False
-                current_app.logger.error(
-                    "Failed to fetch the version information on the "
-                    "established connection to the database server "
-                    "(#{server_id}) for '{conn_id}' with below error "
-                    "message:{msg}".format(
-                        server_id=self.manager.sid,
-                        conn_id=conn_id,
-                        msg=status)
-                )
-                return False, status
-
-            if cur.rowcount > 0:
-                row = cur.fetchmany(1)[0]
-                mgr.ver = row['version']
-                mgr.sversion = self.conn.server_version
-
-        status = _execute(cur, """
-SELECT
-    db.oid as did, db.datname, db.datallowconn,
-    pg_encoding_to_char(db.encoding) AS serverencoding,
-    has_database_privilege(db.oid, 'CREATE') as cancreate, datlastsysoid
-FROM
-    pg_database db
-WHERE db.datname = current_database()""")
-
-        if status is None:
-            mgr.db_info = mgr.db_info or dict()
-            if cur.rowcount > 0:
-                res = cur.fetchmany(1)[0]
-                mgr.db_info[res['did']] = res.copy()
-
-                # We do not have database oid for the maintenance database.
-                if len(mgr.db_info) == 1:
-                    mgr.did = res['did']
-
-        status = _execute(cur, """
-SELECT
-    oid as id, rolname as name, rolsuper as is_superuser,
-    rolcreaterole as can_create_role, rolcreatedb as can_create_db
-FROM
-    pg_catalog.pg_roles
-WHERE
-    rolname = current_user""")
-
-        if status is None:
-            mgr.user_info = dict()
-            if cur.rowcount > 0:
-                mgr.user_info = cur.fetchmany(1)[0]
-
-        if 'password' in kwargs:
-            mgr.password = kwargs['password']
-
-        server_types = None
-        if 'server_types' in kwargs and isinstance(
-                kwargs['server_types'], list):
-            server_types = mgr.server_types = kwargs['server_types']
-
-        if server_types is None:
-            from pgadmin.browser.server_groups.servers.types import ServerType
-            server_types = ServerType.types()
-
-        for st in server_types:
-            if st.instanceOf(mgr.ver):
-                mgr.server_type = st.stype
-                mgr.server_cls = st
-                break
-
-        mgr.update_session()
-
-        return True, None
-
-    def __cursor(self, server_cursor=False):
-        if self.wasConnected is False:
-            raise ConnectionLost(
-                self.manager.sid,
-                self.db,
-                None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
-            )
-        cur = getattr(g, "{0}#{1}".format(
-            self.manager.sid,
-            self.conn_id.encode('utf-8')
-        ), None)
-
-        if self.connected() and cur and not cur.closed:
-            if not server_cursor or (server_cursor and cur.name):
-                return True, cur
-
-        if not self.connected():
-            errmsg = ""
-
-            current_app.logger.warning(
-                "Connection to database server (#{server_id}) for the "
-                "connection - '{conn_id}' has been lost.".format(
-                    server_id=self.manager.sid,
-                    conn_id=self.conn_id
-                )
-            )
-
-            if self.auto_reconnect and not self.reconnecting:
-                self.__attempt_execution_reconnect(None)
-            else:
-                raise ConnectionLost(
-                    self.manager.sid,
-                    self.db,
-                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
-                )
-
-        try:
-            if server_cursor:
-                # Providing name to cursor will create server side cursor.
-                cursor_name = "CURSOR:{0}".format(self.conn_id)
-                cur = self.conn.cursor(
-                    name=cursor_name, cursor_factory=DictCursor
-                )
-            else:
-                cur = self.conn.cursor(cursor_factory=DictCursor)
-        except psycopg2.Error as pe:
-            current_app.logger.exception(pe)
-            errmsg = gettext(
-                "Failed to create cursor for psycopg2 connection with error "
-                "message for the server#{1}:{2}:\n{0}"
-            ).format(
-                str(pe), self.manager.sid, self.db
-            )
-
-            current_app.logger.error(errmsg)
-            if self.conn.closed:
-                self.conn = None
-                if self.auto_reconnect and not self.reconnecting:
-                    current_app.logger.info(
-                        gettext(
-                            "Attempting to reconnect to the database server "
-                            "(#{server_id}) for the connection - '{conn_id}'."
-                        ).format(
-                            server_id=self.manager.sid,
-                            conn_id=self.conn_id
-                        )
-                    )
-                    return self.__attempt_execution_reconnect(
-                        self.__cursor, server_cursor
-                    )
-                else:
-                    raise ConnectionLost(
-                        self.manager.sid,
-                        self.db,
-                        None if self.conn_id[0:3] == u'DB:'
-                        else self.conn_id[5:]
-                    )
-
-        setattr(
-            g, "{0}#{1}".format(
-                self.manager.sid, self.conn_id.encode('utf-8')
-            ), cur
-        )
-
-        return True, cur
-
-    def __internal_blocking_execute(self, cur, query, params):
-        """
-        This function executes the query using cursor's execute function,
-        but in case of asynchronous connection we need to wait for the
-        transaction to be completed. If self.async is 1 then it is a
-        blocking call.
-
-        Args:
-            cur: Cursor object
-            query: SQL query to run.
-            params: Extra parameters
-        """
-
-        if sys.version_info < (3,):
-            if type(query) == unicode:
-                query = query.encode('utf-8')
-        else:
-            query = query.encode('utf-8')
-
-        cur.execute(query, params)
-        if self.async == 1:
-            self._wait(cur.connection)
-
-    def execute_on_server_as_csv(self,
-                                 query, params=None,
-                                 formatted_exception_msg=False,
-                                 records=2000):
-        """
-        To fetch query result and generate CSV output
-
-        Args:
-            query: SQL
-            params: Additional parameters
-            formatted_exception_msg: For exception
-            records: Number of initial records
-        Returns:
-            Generator response
-        """
-        status, cur = self.__cursor(server_cursor=True)
-        self.row_count = 0
-
-        if not status:
-            return False, str(cur)
-        query_id = random.randint(1, 9999999)
-
-        if IS_PY2 and type(query) == unicode:
-            query = query.encode('utf-8')
-
-        current_app.logger.log(
-            25,
-            u"Execute (with server cursor) for server #{server_id} - "
-            u"{conn_id} (Query-id: {query_id}):\n{query}".format(
-                server_id=self.manager.sid,
-                conn_id=self.conn_id,
-                query=query.decode('utf-8') if
-                sys.version_info < (3,) else query,
-                query_id=query_id
-            )
-        )
-        try:
-            self.__internal_blocking_execute(cur, query, params)
-        except psycopg2.Error as pe:
-            cur.close()
-            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
-            current_app.logger.error(
-                u"failed to execute query ((with server cursor) "
-                u"for the server #{server_id} - {conn_id} "
-                u"(query-id: {query_id}):\nerror message:{errmsg}".format(
-                    server_id=self.manager.sid,
-                    conn_id=self.conn_id,
-                    query=query,
-                    errmsg=errmsg,
-                    query_id=query_id
-                )
-            )
-            return False, errmsg
-
-        def handle_json_data(json_columns, results):
-            """
-            [ This is only for Python2.x]
-            This function will be useful to handle json data types.
-            We will dump json data as proper json instead of unicode values
-
-            Args:
-                json_columns: Columns which contains json data
-                results: Query result
-
-            Returns:
-                results
-            """
-            # Only if Python2 and there are columns with JSON type
-            if IS_PY2 and len(json_columns) > 0:
-                temp_results = []
-                for row in results:
-                    res = dict()
-                    for k, v in row.items():
-                        if k in json_columns:
-                            res[k] = json.dumps(v)
-                        else:
-                            res[k] = v
-                    temp_results.append(res)
-                results = temp_results
-            return results
-
-        def convert_keys_to_unicode(results, conn_encoding):
-            """
-            [ This is only for Python2.x]
-            We need to convert all keys to unicode as psycopg2
-            sends them as string
-
-            Args:
-                res: Query result set from psycopg2
-                conn_encoding: Connection encoding
-
-            Returns:
-                Result set (With all the keys converted to unicode)
-            """
-            new_results = []
-            for row in results:
-                new_results.append(
-                    dict([(k.decode(conn_encoding), v)
-                          for k, v in row.items()])
-                )
-            return new_results
-
-        def gen(quote='strings', quote_char="'", field_separator=','):
-
-            results = cur.fetchmany(records)
-            if not results:
-                if not cur.closed:
-                    cur.close()
-                yield gettext('The query executed did not return any data.')
-                return
-
-            header = []
-            json_columns = []
-            conn_encoding = cur.connection.encoding
-
-            for c in cur.ordered_description():
-                # This is to handle the case in which column name is non-ascii
-                column_name = c.to_dict()['name']
-                if IS_PY2:
-                    column_name = column_name.decode(conn_encoding)
-                header.append(column_name)
-                if c.to_dict()['type_code'] in ALL_JSON_TYPES:
-                    json_columns.append(column_name)
-
-            if IS_PY2:
-                results = convert_keys_to_unicode(results, conn_encoding)
-
-            res_io = StringIO()
-
-            if quote == 'strings':
-                quote = csv.QUOTE_NONNUMERIC
-            elif quote == 'all':
-                quote = csv.QUOTE_ALL
-            else:
-                quote = csv.QUOTE_NONE
-
-            if hasattr(str, 'decode'):
-                # Decode the field_separator
-                try:
-                    field_separator = field_separator.decode('utf-8')
-                except Exception as e:
-                    current_app.logger.error(e)
-
-                # Decode the quote_char
-                try:
-                    quote_char = quote_char.decode('utf-8')
-                except Exception as e:
-                    current_app.logger.error(e)
-
-            csv_writer = csv.DictWriter(
-                res_io, fieldnames=header, delimiter=field_separator,
-                quoting=quote,
-                quotechar=quote_char
-            )
-
-            csv_writer.writeheader()
-            results = handle_json_data(json_columns, results)
-            csv_writer.writerows(results)
-
-            yield res_io.getvalue()
-
-            while True:
-                results = cur.fetchmany(records)
-
-                if not results:
-                    if not cur.closed:
-                        cur.close()
-                    break
-                res_io = StringIO()
-
-                csv_writer = csv.DictWriter(
-                    res_io, fieldnames=header, delimiter=field_separator,
-                    quoting=quote,
-                    quotechar=quote_char
-                )
-
-                if IS_PY2:
-                    results = convert_keys_to_unicode(results, conn_encoding)
-
-                results = handle_json_data(json_columns, results)
-                csv_writer.writerows(results)
-                yield res_io.getvalue()
-
-        return True, gen
-
-    def execute_scalar(self, query, params=None,
-                       formatted_exception_msg=False):
-        status, cur = self.__cursor()
-        self.row_count = 0
-
-        if not status:
-            return False, str(cur)
-        query_id = random.randint(1, 9999999)
-
-        current_app.logger.log(
-            25,
-            u"Execute (scalar) for server #{server_id} - {conn_id} (Query-id: "
-            u"{query_id}):\n{query}".format(
-                server_id=self.manager.sid,
-                conn_id=self.conn_id,
-                query=query,
-                query_id=query_id
-            )
-        )
-        try:
-            self.__internal_blocking_execute(cur, query, params)
-        except psycopg2.Error as pe:
-            cur.close()
-            if not self.connected():
-                if self.auto_reconnect and not self.reconnecting:
-                    return self.__attempt_execution_reconnect(
-                        self.execute_dict, query, params,
-                        formatted_exception_msg
-                    )
-                raise ConnectionLost(
-                    self.manager.sid,
-                    self.db,
-                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
-                )
-            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
-            current_app.logger.error(
-                u"Failed to execute query (execute_scalar) for the server "
-                u"#{server_id} - {conn_id} (Query-id: {query_id}):\n"
-                u"Error Message:{errmsg}".format(
-                    server_id=self.manager.sid,
-                    conn_id=self.conn_id,
-                    query=query,
-                    errmsg=errmsg,
-                    query_id=query_id
-                )
-            )
-            return False, errmsg
-
-        self.row_count = cur.rowcount
-        if cur.rowcount > 0:
-            res = cur.fetchone()
-            if len(res) > 0:
-                return True, res[0]
-
-        return True, None
-
-    def execute_async(self, query, params=None, formatted_exception_msg=True):
-        """
-        This function executes the given query asynchronously and returns
-        result.
-
-        Args:
-            query: SQL query to run.
-            params: extra parameters to the function
-            formatted_exception_msg: if True then function return the
-            formatted exception message
-        """
-
-        if sys.version_info < (3,):
-            if type(query) == unicode:
-                query = query.encode('utf-8')
-        else:
-            query = query.encode('utf-8')
-
-        self.__async_cursor = None
-        status, cur = self.__cursor()
-
-        if not status:
-            return False, str(cur)
-        query_id = random.randint(1, 9999999)
-
-        current_app.logger.log(
-            25,
-            u"Execute (async) for server #{server_id} - {conn_id} (Query-id: "
-            u"{query_id}):\n{query}".format(
-                server_id=self.manager.sid,
-                conn_id=self.conn_id,
-                query=query.decode('utf-8'),
-                query_id=query_id
-            )
-        )
-
-        try:
-            self.__notices = []
-            self.execution_aborted = False
-            cur.execute(query, params)
-            res = self._wait_timeout(cur.connection)
-        except psycopg2.Error as pe:
-            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
-            current_app.logger.error(
-                u"Failed to execute query (execute_async) for the server "
-                u"#{server_id} - {conn_id}(Query-id: {query_id}):\n"
-                u"Error Message:{errmsg}".format(
-                    server_id=self.manager.sid,
-                    conn_id=self.conn_id,
-                    query=query.decode('utf-8'),
-                    errmsg=errmsg,
-                    query_id=query_id
-                )
-            )
-
-            if self.is_disconnected(pe):
-                raise ConnectionLost(
-                    self.manager.sid,
-                    self.db,
-                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
-                )
-            return False, errmsg
-
-        self.__async_cursor = cur
-        self.__async_query_id = query_id
-
-        return True, res
-
-    def execute_void(self, query, params=None, formatted_exception_msg=False):
-        """
-        This function executes the given query with no result.
-
-        Args:
-            query: SQL query to run.
-            params: extra parameters to the function
-            formatted_exception_msg: if True then function return the
-            formatted exception message
-        """
-        status, cur = self.__cursor()
-        self.row_count = 0
-
-        if not status:
-            return False, str(cur)
-        query_id = random.randint(1, 9999999)
-
-        current_app.logger.log(
-            25,
-            u"Execute (void) for server #{server_id} - {conn_id} (Query-id: "
-            u"{query_id}):\n{query}".format(
-                server_id=self.manager.sid,
-                conn_id=self.conn_id,
-                query=query,
-                query_id=query_id
-            )
-        )
-
-        try:
-            self.__internal_blocking_execute(cur, query, params)
-        except psycopg2.Error as pe:
-            cur.close()
-            if not self.connected():
-                if self.auto_reconnect and not self.reconnecting:
-                    return self.__attempt_execution_reconnect(
-                        self.execute_void, query, params,
-                        formatted_exception_msg
-                    )
-                raise ConnectionLost(
-                    self.manager.sid,
-                    self.db,
-                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
-                )
-            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
-            current_app.logger.error(
-                u"Failed to execute query (execute_void) for the server "
-                u"#{server_id} - {conn_id}(Query-id: {query_id}):\n"
-                u"Error Message:{errmsg}".format(
-                    server_id=self.manager.sid,
-                    conn_id=self.conn_id,
-                    query=query,
-                    errmsg=errmsg,
-                    query_id=query_id
-                )
-            )
-            return False, errmsg
-
-        self.row_count = cur.rowcount
-
-        return True, None
-
-    def __attempt_execution_reconnect(self, fn, *args, **kwargs):
-        self.reconnecting = True
-        setattr(g, "{0}#{1}".format(
-            self.manager.sid,
-            self.conn_id.encode('utf-8')
-        ), None)
-        try:
-            status, res = self.connect()
-            if status:
-                if fn:
-                    status, res = fn(*args, **kwargs)
-                    self.reconnecting = False
-                return status, res
-        except Exception as e:
-            current_app.logger.exception(e)
-            self.reconnecting = False
-
-            current_app.warning(
-                "Failed to reconnect the database server "
-                "(#{server_id})".format(
-                    server_id=self.manager.sid,
-                    conn_id=self.conn_id
-                )
-            )
-        self.reconnecting = False
-        raise ConnectionLost(
-            self.manager.sid,
-            self.db,
-            None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
-        )
-
-    def execute_2darray(self, query, params=None,
-                        formatted_exception_msg=False):
-        status, cur = self.__cursor()
-        self.row_count = 0
-
-        if not status:
-            return False, str(cur)
-
-        query_id = random.randint(1, 9999999)
-        current_app.logger.log(
-            25,
-            u"Execute (2darray) for server #{server_id} - {conn_id} "
-            u"(Query-id: {query_id}):\n{query}".format(
-                server_id=self.manager.sid,
-                conn_id=self.conn_id,
-                query=query,
-                query_id=query_id
-            )
-        )
-        try:
-            self.__internal_blocking_execute(cur, query, params)
-        except psycopg2.Error as pe:
-            cur.close()
-            if not self.connected():
-                if self.auto_reconnect and \
-                        not self.reconnecting:
-                    return self.__attempt_execution_reconnect(
-                        self.execute_2darray, query, params,
-                        formatted_exception_msg
-                    )
-            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
-            current_app.logger.error(
-                u"Failed to execute query (execute_2darray) for the server "
-                u"#{server_id} - {conn_id} (Query-id: {query_id}):\n"
-                u"Error Message:{errmsg}".format(
-                    server_id=self.manager.sid,
-                    conn_id=self.conn_id,
-                    query=query,
-                    errmsg=errmsg,
-                    query_id=query_id
-                )
-            )
-            return False, errmsg
-
-        # Get Resultset Column Name, Type and size
-        columns = cur.description and [
-            desc.to_dict() for desc in cur.ordered_description()
-        ] or []
-
-        rows = []
-        self.row_count = cur.rowcount
-        if cur.rowcount > 0:
-            for row in cur:
-                rows.append(row)
-
-        return True, {'columns': columns, 'rows': rows}
-
-    def execute_dict(self, query, params=None, formatted_exception_msg=False):
-        status, cur = self.__cursor()
-        self.row_count = 0
-
-        if not status:
-            return False, str(cur)
-        query_id = random.randint(1, 9999999)
-        current_app.logger.log(
-            25,
-            u"Execute (dict) for server #{server_id} - {conn_id} (Query-id: "
-            u"{query_id}):\n{query}".format(
-                server_id=self.manager.sid,
-                conn_id=self.conn_id,
-                query=query,
-                query_id=query_id
-            )
-        )
-        try:
-            self.__internal_blocking_execute(cur, query, params)
-        except psycopg2.Error as pe:
-            cur.close()
-            if not self.connected():
-                if self.auto_reconnect and not self.reconnecting:
-                    return self.__attempt_execution_reconnect(
-                        self.execute_dict, query, params,
-                        formatted_exception_msg
-                    )
-                raise ConnectionLost(
-                    self.manager.sid,
-                    self.db,
-                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
-                )
-            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
-            current_app.logger.error(
-                u"Failed to execute query (execute_dict) for the server "
-                u"#{server_id}- {conn_id} (Query-id: {query_id}):\n"
-                u"Error Message:{errmsg}".format(
-                    server_id=self.manager.sid,
-                    conn_id=self.conn_id,
-                    query_id=query_id,
-                    errmsg=errmsg
-                )
-            )
-            return False, errmsg
-
-        # Get Resultset Column Name, Type and size
-        columns = cur.description and [
-            desc.to_dict() for desc in cur.ordered_description()
-        ] or []
-
-        rows = []
-        self.row_count = cur.rowcount
-        if cur.rowcount > 0:
-            for row in cur:
-                rows.append(dict(row))
-
-        return True, {'columns': columns, 'rows': rows}
-
-    def async_fetchmany_2darray(self, records=2000,
-                                formatted_exception_msg=False):
-        """
-        User should poll and check if status is ASYNC_OK before calling this
-        function
-        Args:
-          records: no of records to fetch. use -1 to fetchall.
-          formatted_exception_msg:
-
-        Returns:
-
-        """
-        cur = self.__async_cursor
-        if not cur:
-            return False, gettext(
-                "Cursor could not be found for the async connection."
-            )
-
-        if self.conn.isexecuting():
-            return False, gettext(
-                "Asynchronous query execution/operation underway."
-            )
-
-        if self.row_count > 0:
-            result = []
-            # For DDL operation, we may not have result.
-            #
-            # Because - there is not direct way to differentiate DML and
-            # DDL operations, we need to rely on exception to figure
-            # that out at the moment.
-            try:
-                if records == -1:
-                    res = cur.fetchall()
-                else:
-                    res = cur.fetchmany(records)
-                for row in res:
-                    new_row = []
-                    for col in self.column_info:
-                        new_row.append(row[col['name']])
-                    result.append(new_row)
-            except psycopg2.ProgrammingError as e:
-                result = None
-        else:
-            # User performed operation which dose not produce record/s as
-            # result.
-            # for eg. DDL operations.
-            return True, None
-
-        return True, result
-
-    def connected(self):
-        if self.conn:
-            if not self.conn.closed:
-                return True
-            self.conn = None
-        return False
-
-    def reset(self):
-        if self.conn:
-            if self.conn.closed:
-                self.conn = None
-        pg_conn = None
-        mgr = self.manager
-
-        password = getattr(mgr, 'password', None)
-
-        if password:
-            # Fetch Logged in User Details.
-            user = User.query.filter_by(id=current_user.id).first()
-
-            if user is None:
-                return False, gettext("Unauthorized request.")
-
-            password = decrypt(password, user.password).decode()
-
-        try:
-            pg_conn = psycopg2.connect(
-                host=mgr.host,
-                hostaddr=mgr.hostaddr,
-                port=mgr.port,
-                database=self.db,
-                user=mgr.user,
-                password=password,
-                passfile=get_complete_file_path(mgr.passfile),
-                sslmode=mgr.ssl_mode,
-                sslcert=get_complete_file_path(mgr.sslcert),
-                sslkey=get_complete_file_path(mgr.sslkey),
-                sslrootcert=get_complete_file_path(mgr.sslrootcert),
-                sslcrl=get_complete_file_path(mgr.sslcrl),
-                sslcompression=True if mgr.sslcompression else False
-            )
-
-        except psycopg2.Error as e:
-            msg = e.pgerror if e.pgerror else e.message \
-                if e.message else e.diag.message_detail \
-                if e.diag.message_detail else str(e)
-
-            current_app.logger.error(
-                gettext(
-                    """
-Failed to reset the connection to the server due to following error:
-{0}"""
-                ).Format(msg)
-            )
-            return False, msg
-
-        pg_conn.notices = deque([], self.ASYNC_NOTICE_MAXLENGTH)
-        self.conn = pg_conn
-        self.__backend_pid = pg_conn.get_backend_pid()
-
-        return True, None
-
-    def transaction_status(self):
-        if self.conn:
-            return self.conn.get_transaction_status()
-        return None
-
-    def ping(self):
-        return self.execute_scalar('SELECT 1')
-
-    def _release(self):
-        if self.wasConnected:
-            if self.conn:
-                self.conn.close()
-                self.conn = None
-            self.password = None
-            self.wasConnected = False
-
-    def _wait(self, conn):
-        """
-        This function is used for the asynchronous connection,
-        it will call poll method in a infinite loop till poll
-        returns psycopg2.extensions.POLL_OK. This is a blocking
-        call.
-
-        Args:
-            conn: connection object
-        """
-
-        while 1:
-            state = conn.poll()
-            if state == psycopg2.extensions.POLL_OK:
-                break
-            elif state == psycopg2.extensions.POLL_WRITE:
-                select.select([], [conn.fileno()], [])
-            elif state == psycopg2.extensions.POLL_READ:
-                select.select([conn.fileno()], [], [])
-            else:
-                raise psycopg2.OperationalError(
-                    "poll() returned %s from _wait function" % state)
-
-    def _wait_timeout(self, conn):
-        """
-        This function is used for the asynchronous connection,
-        it will call poll method and return the status. If state is
-        psycopg2.extensions.POLL_WRITE and psycopg2.extensions.POLL_READ
-        function will wait for the given timeout.This is not a blocking call.
-
-        Args:
-            conn: connection object
-        """
-        while 1:
-            state = conn.poll()
-            if state == psycopg2.extensions.POLL_OK:
-                return self.ASYNC_OK
-            elif state == psycopg2.extensions.POLL_WRITE:
-                # Wait for the given time and then check the return status
-                # If three empty lists are returned then the time-out is
-                # reached.
-                timeout_status = select.select([], [conn.fileno()], [],
-                                               self.ASYNC_TIMEOUT)
-                if timeout_status == ([], [], []):
-                    return self.ASYNC_WRITE_TIMEOUT
-            elif state == psycopg2.extensions.POLL_READ:
-                # Wait for the given time and then check the return status
-                # If three empty lists are returned then the time-out is
-                # reached.
-                timeout_status = select.select([conn.fileno()], [], [],
-                                               self.ASYNC_TIMEOUT)
-                if timeout_status == ([], [], []):
-                    return self.ASYNC_READ_TIMEOUT
-            else:
-                raise psycopg2.OperationalError(
-                    "poll() returned %s from _wait_timeout function" % state
-                )
-
-    def poll(self, formatted_exception_msg=False, no_result=False):
-        """
-        This function is a wrapper around connection's poll function.
-        It internally uses the _wait_timeout method to poll the
-        result on the connection object. In case of success it
-        returns the result of the query.
-
-        Args:
-            formatted_exception_msg: if True then function return the formatted
-                                     exception message, otherwise error string.
-            no_result: If True then only poll status will be returned.
-        """
-
-        cur = self.__async_cursor
-        if not cur:
-            return False, gettext(
-                "Cursor could not be found for the async connection."
-            )
-
-        current_app.logger.log(
-            25,
-            "Polling result for (Query-id: {query_id})".format(
-                query_id=self.__async_query_id
-            )
-        )
-
-        is_error = False
-        try:
-            status = self._wait_timeout(self.conn)
-        except psycopg2.Error as pe:
-            if self.conn.closed:
-                raise ConnectionLost(
-                    self.manager.sid,
-                    self.db,
-                    self.conn_id[5:]
-                )
-            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
-            is_error = True
-
-        if self.conn.notices and self.__notices is not None:
-            self.__notices.extend(self.conn.notices)
-            self.conn.notices.clear()
-
-        # We also need to fetch notices before we return from function in case
-        # of any Exception, To avoid code duplication we will return after
-        # fetching the notices in case of any Exception
-        if is_error:
-            return False, errmsg
-
-        result = None
-        self.row_count = 0
-        self.column_info = None
-
-        if status == self.ASYNC_OK:
-
-            # if user has cancelled the transaction then changed the status
-            if self.execution_aborted:
-                status = self.ASYNC_EXECUTION_ABORTED
-                self.execution_aborted = False
-                return status, result
-
-            # Fetch the column information
-            if cur.description is not None:
-                self.column_info = [
-                    desc.to_dict() for desc in cur.ordered_description()
-                ]
-
-                pos = 0
-                for col in self.column_info:
-                    col['pos'] = pos
-                    pos += 1
-
-            self.row_count = cur.rowcount
-            if not no_result:
-                if cur.rowcount > 0:
-                    result = []
-                    # For DDL operation, we may not have result.
-                    #
-                    # Because - there is not direct way to differentiate DML
-                    # and DDL operations, we need to rely on exception to
-                    # figure that out at the moment.
-                    try:
-                        for row in cur:
-                            new_row = []
-                            for col in self.column_info:
-                                new_row.append(row[col['name']])
-                            result.append(new_row)
-
-                    except psycopg2.ProgrammingError:
-                        result = None
-
-        return status, result
-
-    def status_message(self):
-        """
-        This function will return the status message returned by the last
-        command executed on the server.
-        """
-        cur = self.__async_cursor
-        if not cur:
-            return gettext(
-                "Cursor could not be found for the async connection."
-            )
-
-        current_app.logger.log(
-            25,
-            "Status message for (Query-id: {query_id})".format(
-                query_id=self.__async_query_id
-            )
-        )
-
-        return cur.statusmessage
-
-    def rows_affected(self):
-        """
-        This function will return the no of rows affected by the last command
-        executed on the server.
-        """
-
-        return self.row_count
-
-    def get_column_info(self):
-        """
-        This function will returns list of columns for last async sql command
-        executed on the server.
-        """
-
-        return self.column_info
-
-    def cancel_transaction(self, conn_id, did=None):
-        """
-        This function is used to cancel the running transaction
-        of the given connection id and database id using
-        PostgreSQL's pg_cancel_backend.
-
-        Args:
-            conn_id: Connection id
-            did: Database id (optional)
-        """
-        cancel_conn = self.manager.connection(did=did, conn_id=conn_id)
-        query = """SELECT pg_cancel_backend({0});""".format(
-            cancel_conn.__backend_pid)
-
-        status = True
-        msg = ''
-
-        # if backend pid is same then create a new connection
-        # to cancel the query and release it.
-        if cancel_conn.__backend_pid == self.__backend_pid:
-            password = getattr(self.manager, 'password', None)
-            if password:
-                # Fetch Logged in User Details.
-                user = User.query.filter_by(id=current_user.id).first()
-                if user is None:
-                    return False, gettext("Unauthorized request.")
-
-                password = decrypt(password, user.password).decode()
-
-            try:
-                pg_conn = psycopg2.connect(
-                    host=self.manager.host,
-                    hostaddr=self.manager.hostaddr,
-                    port=self.manager.port,
-                    database=self.db,
-                    user=self.manager.user,
-                    password=password,
-                    passfile=get_complete_file_path(self.manager.passfile),
-                    sslmode=self.manager.ssl_mode,
-                    sslcert=get_complete_file_path(self.manager.sslcert),
-                    sslkey=get_complete_file_path(self.manager.sslkey),
-                    sslrootcert=get_complete_file_path(
-                        self.manager.sslrootcert
-                    ),
-                    sslcrl=get_complete_file_path(self.manager.sslcrl),
-                    sslcompression=True if self.manager.sslcompression
-                    else False
-                )
-
-                # Get the cursor and run the query
-                cur = pg_conn.cursor()
-                cur.execute(query)
-
-                # Close the connection
-                pg_conn.close()
-                pg_conn = None
-
-            except psycopg2.Error as e:
-                status = False
-                if e.pgerror:
-                    msg = e.pgerror
-                elif e.diag.message_detail:
-                    msg = e.diag.message_detail
-                else:
-                    msg = str(e)
-                return status, msg
-        else:
-            if self.connected():
-                status, msg = self.execute_void(query)
-
-                if status:
-                    cancel_conn.execution_aborted = True
-            else:
-                status = False
-                msg = gettext("Not connected to the database server.")
-
-        return status, msg
-
-    def messages(self):
-        """
-        Returns the list of the messages/notices send from the database server.
-        """
-        resp = []
-        while self.__notices:
-            resp.append(self.__notices.pop(0))
-        return resp
-
-    def decode_to_utf8(self, value):
-        """
-        This method will decode values to utf-8
-        Args:
-            value: String to be decode
-
-        Returns:
-            Decoded string
-        """
-        is_error = False
-        if hasattr(str, 'decode'):
-            try:
-                value = value.decode('utf-8')
-            except UnicodeDecodeError:
-                # Let's try with python's preferred encoding
-                # On Windows lc_messages mostly has environment dependent
-                # encoding like 'French_France.1252'
-                try:
-                    import locale
-                    pref_encoding = locale.getpreferredencoding()
-                    value = value.decode(pref_encoding)\
-                        .encode('utf-8')\
-                        .decode('utf-8')
-                except Exception:
-                    is_error = True
-            except Exception:
-                is_error = True
-
-        # If still not able to decode then
-        if is_error:
-            value = value.decode('ascii', 'ignore')
-
-        return value
-
-    def _formatted_exception_msg(self, exception_obj, formatted_msg):
-        """
-        This method is used to parse the psycopg2.Error object and returns the
-        formatted error message if flag is set to true else return
-        normal error message.
-
-        Args:
-            exception_obj: exception object
-            formatted_msg: if True then function return the formatted exception
-            message
-
-        """
-        if exception_obj.pgerror:
-            errmsg = exception_obj.pgerror
-        elif exception_obj.diag.message_detail:
-            errmsg = exception_obj.diag.message_detail
-        else:
-            errmsg = str(exception_obj)
-        # errmsg might contains encoded value, lets decode it
-        errmsg = self.decode_to_utf8(errmsg)
-
-        # if formatted_msg is false then return from the function
-        if not formatted_msg:
-            return errmsg
-
-        # Do not append if error starts with `ERROR:` as most pg related
-        # error starts with `ERROR:`
-        if not errmsg.startswith(u'ERROR:'):
-            errmsg = u'ERROR:  ' + errmsg + u'\n\n'
-
-        if exception_obj.diag.severity is not None \
-                and exception_obj.diag.message_primary is not None:
-            ex_diag_message = u"{0}:  {1}".format(
-                exception_obj.diag.severity,
-                self.decode_to_utf8(exception_obj.diag.message_primary)
-            )
-            # If both errors are different then only append it
-            if errmsg and ex_diag_message and \
-                ex_diag_message.strip().strip('\n').lower() not in \
-                    errmsg.strip().strip('\n').lower():
-                errmsg += ex_diag_message
-        elif exception_obj.diag.message_primary is not None:
-            message_primary = self.decode_to_utf8(
-                exception_obj.diag.message_primary
-            )
-            if message_primary.lower() not in errmsg.lower():
-                errmsg += message_primary
-
-        if exception_obj.diag.sqlstate is not None:
-            if not errmsg.endswith('\n'):
-                errmsg += '\n'
-            errmsg += gettext('SQL state: ')
-            errmsg += self.decode_to_utf8(exception_obj.diag.sqlstate)
-
-        if exception_obj.diag.message_detail is not None:
-            if 'Detail:'.lower() not in errmsg.lower():
-                if not errmsg.endswith('\n'):
-                    errmsg += '\n'
-                errmsg += gettext('Detail: ')
-                errmsg += self.decode_to_utf8(
-                    exception_obj.diag.message_detail
-                )
-
-        if exception_obj.diag.message_hint is not None:
-            if 'Hint:'.lower() not in errmsg.lower():
-                if not errmsg.endswith('\n'):
-                    errmsg += '\n'
-                errmsg += gettext('Hint: ')
-                errmsg += self.decode_to_utf8(exception_obj.diag.message_hint)
-
-        if exception_obj.diag.statement_position is not None:
-            if 'Character:'.lower() not in errmsg.lower():
-                if not errmsg.endswith('\n'):
-                    errmsg += '\n'
-                errmsg += gettext('Character: ')
-                errmsg += self.decode_to_utf8(
-                    exception_obj.diag.statement_position
-                )
-
-        if exception_obj.diag.context is not None:
-            if 'Context:'.lower() not in errmsg.lower():
-                if not errmsg.endswith('\n'):
-                    errmsg += '\n'
-                errmsg += gettext('Context: ')
-                errmsg += self.decode_to_utf8(exception_obj.diag.context)
-
-        return errmsg
-
-    #####
-    # As per issue reported on pgsycopg2 github repository link is shared below
-    # conn.closed is not reliable enough to identify the disconnection from the
-    # database server for some unknown reasons.
-    #
-    # (https://github.com/psycopg/psycopg2/issues/263)
-    #
-    # In order to resolve the issue, sqlalchamey follows the below logic to
-    # identify the disconnection. It relies on exception message to identify
-    # the error.
-    #
-    # Reference (MIT license):
-    # https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/dialects/postgresql/psycopg2.py
-    #
-    def is_disconnected(self, err):
-        if not self.conn.closed:
-            # checks based on strings.  in the case that .closed
-            # didn't cut it, fall back onto these.
-            str_e = str(err).partition("\n")[0]
-            for msg in [
-                # these error messages from libpq: interfaces/libpq/fe-misc.c
-                # and interfaces/libpq/fe-secure.c.
-                'terminating connection',
-                'closed the connection',
-                'connection not open',
-                'could not receive data from server',
-                'could not send data to server',
-                # psycopg2 client errors, psycopg2/conenction.h,
-                # psycopg2/cursor.h
-                'connection already closed',
-                'cursor already closed',
-                # not sure where this path is originally from, it may
-                # be obsolete.   It really says "losed", not "closed".
-                'losed the connection unexpectedly',
-                # these can occur in newer SSL
-                'connection has been closed unexpectedly',
-                'SSL SYSCALL error: Bad file descriptor',
-                'SSL SYSCALL error: EOF detected',
-            ]:
-                idx = str_e.find(msg)
-                if idx >= 0 and '"' not in str_e[:idx]:
-                    return True
-
-            return False
-        return True
-
-
-class ServerManager(object):
-    """
-    class ServerManager
-
-    This class contains the information about the given server.
-    And, acts as connection manager for that particular session.
-    """
-
-    def __init__(self, server):
-        self.connections = dict()
-
-        self.update(server)
-
-    def update(self, server):
-        assert (server is not None)
-        assert (isinstance(server, Server))
-
-        self.ver = None
-        self.sversion = None
-        self.server_type = None
-        self.server_cls = None
-        self.password = None
-
-        self.sid = server.id
-        self.host = server.host
-        self.hostaddr = server.hostaddr
-        self.port = server.port
-        self.db = server.maintenance_db
-        self.did = None
-        self.user = server.username
-        self.password = server.password
-        self.role = server.role
-        self.ssl_mode = server.ssl_mode
-        self.pinged = datetime.datetime.now()
-        self.db_info = dict()
-        self.server_types = None
-        self.db_res = server.db_res
-        self.passfile = server.passfile
-        self.sslcert = server.sslcert
-        self.sslkey = server.sslkey
-        self.sslrootcert = server.sslrootcert
-        self.sslcrl = server.sslcrl
-        self.sslcompression = True if server.sslcompression else False
-
-        for con in self.connections:
-            self.connections[con]._release()
-
-        self.update_session()
-
-        self.connections = dict()
-
-    def as_dict(self):
-        """
-        Returns a dictionary object representing the server manager.
-        """
-        if self.ver is None or len(self.connections) == 0:
-            return None
-
-        res = dict()
-        res['sid'] = self.sid
-        res['ver'] = self.ver
-        res['sversion'] = self.sversion
-        if hasattr(self, 'password') and self.password:
-            # If running under PY2
-            if hasattr(self.password, 'decode'):
-                res['password'] = self.password.decode('utf-8')
-            else:
-                res['password'] = str(self.password)
-        else:
-            res['password'] = self.password
-
-        connections = res['connections'] = dict()
-
-        for conn_id in self.connections:
-            conn = self.connections[conn_id].as_dict()
-
-            if conn is not None:
-                connections[conn_id] = conn
-
-        return res
-
-    def ServerVersion(self):
-        return self.ver
-
-    @property
-    def version(self):
-        return self.sversion
-
-    def MajorVersion(self):
-        if self.sversion is not None:
-            return int(self.sversion / 10000)
-        raise Exception("Information is not available.")
-
-    def MinorVersion(self):
-        if self.sversion:
-            return int(int(self.sversion / 100) % 100)
-        raise Exception("Information is not available.")
-
-    def PatchVersion(self):
-        if self.sversion:
-            return int(int(self.sversion / 100) / 100)
-        raise Exception("Information is not available.")
-
-    def connection(
-            self, database=None, conn_id=None, auto_reconnect=True, did=None,
-            async=None, use_binary_placeholder=False, array_to_string=False
-    ):
-        if database is not None:
-            if hasattr(str, 'decode') and \
-                    not isinstance(database, unicode):
-                database = database.decode('utf-8')
-            if did is not None:
-                if did in self.db_info:
-                    self.db_info[did]['datname'] = database
-        else:
-            if did is None:
-                database = self.db
-            elif did in self.db_info:
-                database = self.db_info[did]['datname']
-            else:
-                maintenance_db_id = u'DB:{0}'.format(self.db)
-                if maintenance_db_id in self.connections:
-                    conn = self.connections[maintenance_db_id]
-                    if conn.connected():
-                        status, res = conn.execute_dict(u"""
-SELECT
-    db.oid as did, db.datname, db.datallowconn,
-    pg_encoding_to_char(db.encoding) AS serverencoding,
-    has_database_privilege(db.oid, 'CREATE') as cancreate, datlastsysoid
-FROM
-    pg_database db
-WHERE db.oid = {0}""".format(did))
-
-                        if status and len(res['rows']) > 0:
-                            for row in res['rows']:
-                                self.db_info[did] = row
-                                database = self.db_info[did]['datname']
-
-                        if did not in self.db_info:
-                            raise Exception(gettext(
-                                "Could not find the specified database."
-                            ))
-
-        if database is None:
-            raise ConnectionLost(self.sid, None, None)
-
-        my_id = (u'CONN:{0}'.format(conn_id)) if conn_id is not None else \
-            (u'DB:{0}'.format(database))
-
-        self.pinged = datetime.datetime.now()
-
-        if my_id in self.connections:
-            return self.connections[my_id]
-        else:
-            if async is None:
-                async = 1 if conn_id is not None else 0
-            else:
-                async = 1 if async is True else 0
-            self.connections[my_id] = Connection(
-                self, my_id, database, auto_reconnect, async,
-                use_binary_placeholder=use_binary_placeholder,
-                array_to_string=array_to_string
-            )
-
-            return self.connections[my_id]
-
-    def _restore(self, data):
-        """
-        Helps restoring to reconnect the auto-connect connections smoothly on
-        reload/restart of the app server..
-        """
-        # restore server version from flask session if flask server was
-        # restarted. As we need server version to resolve sql template paths.
-
-        self.ver = data.get('ver', None)
-        self.sversion = data.get('sversion', None)
-
-        if self.ver and not self.server_type:
-            from pgadmin.browser.server_groups.servers.types import ServerType
-            for st in ServerType.types():
-                if st.instanceOf(self.ver):
-                    self.server_type = st.stype
-                    self.server_cls = st
-                    break
-
-        # Hmm.. we will not honour this request, when I already have
-        # connections
-        if len(self.connections) != 0:
-            return
-
-        # We need to know about the existing server variant supports during
-        # first connection for identifications.
-        from pgadmin.browser.server_groups.servers.types import ServerType
-        self.pinged = datetime.datetime.now()
-        try:
-            if 'password' in data and data['password']:
-                data['password'] = data['password'].encode('utf-8')
-        except Exception as e:
-            current_app.logger.exception(e)
-
-        connections = data['connections']
-        for conn_id in connections:
-            conn_info = connections[conn_id]
-            conn = self.connections[conn_info['conn_id']] = Connection(
-                self, conn_info['conn_id'], conn_info['database'],
-                conn_info['auto_reconnect'], conn_info['async'],
-                use_binary_placeholder=conn_info['use_binary_placeholder'],
-                array_to_string=conn_info['array_to_string']
-            )
-
-            # only try to reconnect if connection was connected previously and
-            # auto_reconnect is true.
-            if conn_info['wasConnected'] and conn_info['auto_reconnect']:
-                try:
-                    conn.connect(
-                        password=data['password'],
-                        server_types=ServerType.types()
-                    )
-                    # This will also update wasConnected flag in connection so
-                    # no need to update the flag manually.
-                except Exception as e:
-                    current_app.logger.exception(e)
-                    self.connections.pop(conn_info['conn_id'])
-
-    def release(self, database=None, conn_id=None, did=None):
-        if did is not None:
-            if did in self.db_info and 'datname' in self.db_info[did]:
-                database = self.db_info[did]['datname']
-                if hasattr(str, 'decode') and \
-                        not isinstance(database, unicode):
-                    database = database.decode('utf-8')
-                if database is None:
-                    return False
-            else:
-                return False
-
-        my_id = (u'CONN:{0}'.format(conn_id)) if conn_id is not None else \
-            (u'DB:{0}'.format(database)) if database is not None else None
-
-        if my_id is not None:
-            if my_id in self.connections:
-                self.connections[my_id]._release()
-                del self.connections[my_id]
-                if did is not None:
-                    del self.db_info[did]
-
-                if len(self.connections) == 0:
-                    self.ver = None
-                    self.sversion = None
-                    self.server_type = None
-                    self.server_cls = None
-                    self.password = None
-
-                self.update_session()
-
-                return True
-            else:
-                return False
-
-        for con in self.connections:
-            self.connections[con]._release()
-
-        self.connections = dict()
-        self.ver = None
-        self.sversion = None
-        self.server_type = None
-        self.server_cls = None
-        self.password = None
-
-        self.update_session()
-
-        return True
-
-    def _update_password(self, passwd):
-        self.password = passwd
-        for conn_id in self.connections:
-            conn = self.connections[conn_id]
-            if conn.conn is not None or conn.wasConnected is True:
-                conn.password = passwd
-
-    def update_session(self):
-        managers = session['__pgsql_server_managers'] \
-            if '__pgsql_server_managers' in session else dict()
-        updated_mgr = self.as_dict()
-
-        if not updated_mgr:
-            if self.sid in managers:
-                managers.pop(self.sid)
-        else:
-            managers[self.sid] = updated_mgr
-        session['__pgsql_server_managers'] = managers
-        session.force_write = True
-
-    def utility(self, operation):
-        """
-        utility(operation)
-
-        Returns: name of the utility which used for the operation
-        """
-        if self.server_cls is not None:
-            return self.server_cls.utility(operation, self.sversion)
-
-        return None
-
-    def export_password_env(self, env):
-        if self.password:
-            password = decrypt(
-                self.password, current_user.password
-            ).decode()
-            os.environ[str(env)] = password
+from ..abstract import BaseDriver
+from .connection import Connection
+from .server_manager import ServerManager
 
 
 class Driver(BaseDriver):
@@ -2164,8 +202,9 @@ class Driver(BaseDriver):
                 continue
 
             if curr_time - sess_mgr['pinged'] >= session_idle_timeout:
-                for mgr in [m for m in sess_mgr if isinstance(m,
-                                                              ServerManager)]:
+                for mgr in [
+                        m for m in sess_mgr if isinstance(m, ServerManager)
+                ]:
                     mgr.release()
 
     @staticmethod
diff --git a/web/pgadmin/utils/driver/psycopg2/connection.py b/web/pgadmin/utils/driver/psycopg2/connection.py
new file mode 100644
index 0000000..d4c9573
--- /dev/null
+++ b/web/pgadmin/utils/driver/psycopg2/connection.py
@@ -0,0 +1,1682 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""
+Implementation of Connection.
+It is a wrapper around the actual psycopg2 driver, and connection
+object.
+"""
+
+import random
+import select
+import sys
+from collections import deque
+import simplejson as json
+import psycopg2
+from flask import g, current_app
+from flask_babel import gettext
+from flask_security import current_user
+from pgadmin.utils.crypto import decrypt
+from psycopg2.extensions import adapt, encodings
+
+import config
+from pgadmin.model import Server, User
+from pgadmin.utils.exception import ConnectionLost
+from pgadmin.utils import get_complete_file_path
+from ..abstract import BaseDriver, BaseConnection
+from .cursor import DictCursor
+from .typecast import register_global_typecasters, \
+    register_string_typecasters, register_binary_typecasters, \
+    register_array_to_string_typecasters, ALL_JSON_TYPES
+
+
+if sys.version_info < (3,):
+    # Python2 in-built csv module do not handle unicode
+    # backports.csv module ported from PY3 csv module for unicode handling
+    from backports import csv
+    from StringIO import StringIO
+    IS_PY2 = True
+else:
+    from io import StringIO
+    import csv
+    IS_PY2 = False
+
+_ = gettext
+
+
+# Register global type caster which will be applicable to all connections.
+register_global_typecasters()
+
+
+class Connection(BaseConnection):
+    """
+    class Connection(object)
+
+        A wrapper class, which wraps the psycopg2 connection object, and
+        delegate the execution to the actual connection object, when required.
+
+    Methods:
+    -------
+    * connect(**kwargs)
+      - Connect the PostgreSQL/EDB Postgres Advanced Server using the psycopg2
+      driver
+
+    * execute_scalar(query, params, formatted_exception_msg)
+      - Execute the given query and returns single datum result
+
+    * execute_async(query, params, formatted_exception_msg)
+      - Execute the given query asynchronously and returns result.
+
+    * execute_void(query, params, formatted_exception_msg)
+      - Execute the given query with no result.
+
+    * execute_2darray(query, params, formatted_exception_msg)
+      - Execute the given query and returns the result as a 2 dimensional
+        array.
+
+    * execute_dict(query, params, formatted_exception_msg)
+      - Execute the given query and returns the result as an array of dict
+        (column name -> value) format.
+
+    * connected()
+      - Get the status of the connection.
+        Returns True if connected, otherwise False.
+
+    * reset()
+      - Reconnect the database server (if possible)
+
+    * transaction_status()
+      - Transaction Status
+
+    * ping()
+      - Ping the server.
+
+    * _release()
+      - Release the connection object of psycopg2
+
+    * _reconnect()
+      - Attempt to reconnect to the database
+
+    * _wait(conn)
+      - This method is used to wait for asynchronous connection. This is a
+        blocking call.
+
+    * _wait_timeout(conn)
+      - This method is used to wait for asynchronous connection with timeout.
+        This is a non blocking call.
+
+    * poll(formatted_exception_msg)
+      - This method is used to poll the data of query running on asynchronous
+        connection.
+
+    * status_message()
+      - Returns the status message returned by the last command executed on
+      the server.
+
+    * rows_affected()
+      - Returns the no of rows affected by the last command executed on
+      the server.
+
+    * cancel_transaction(conn_id, did=None)
+      - This method is used to cancel the transaction for the
+        specified connection id and database id.
+
+    * messages()
+      - Returns the list of messages/notices sends from the PostgreSQL database
+        server.
+
+    * _formatted_exception_msg(exception_obj, formatted_msg)
+      - This method is used to parse the psycopg2.Error object and returns the
+        formatted error message if flag is set to true else return
+        normal error message.
+
+    """
+
+    def __init__(self, manager, conn_id, db, auto_reconnect=True, async=0,
+                 use_binary_placeholder=False, array_to_string=False):
+        assert (manager is not None)
+        assert (conn_id is not None)
+
+        self.conn_id = conn_id
+        self.manager = manager
+        self.db = db if db is not None else manager.db
+        self.conn = None
+        self.auto_reconnect = auto_reconnect
+        self.async = async
+        self.__async_cursor = None
+        self.__async_query_id = None
+        self.__backend_pid = None
+        self.execution_aborted = False
+        self.row_count = 0
+        self.__notices = None
+        self.password = None
+        # This flag indicates the connection status (connected/disconnected).
+        self.wasConnected = False
+        # This flag indicates the connection reconnecting status.
+        self.reconnecting = False
+        self.use_binary_placeholder = use_binary_placeholder
+        self.array_to_string = array_to_string
+
+        super(Connection, self).__init__()
+
+    def as_dict(self):
+        """
+        Returns the dictionary object representing this object.
+        """
+        # In case, it cannot be auto reconnectable, or already been released,
+        # then we will return None.
+        if not self.auto_reconnect and not self.conn:
+            return None
+
+        res = dict()
+        res['conn_id'] = self.conn_id
+        res['database'] = self.db
+        res['async'] = self.async
+        res['wasConnected'] = self.wasConnected
+        res['auto_reconnect'] = self.auto_reconnect
+        res['use_binary_placeholder'] = self.use_binary_placeholder
+        res['array_to_string'] = self.array_to_string
+
+        return res
+
+    def __repr__(self):
+        return "PG Connection: {0} ({1}) -> {2} (ajax:{3})".format(
+            self.conn_id, self.db,
+            'Connected' if self.conn and not self.conn.closed else
+            "Disconnected",
+            self.async
+        )
+
+    def __str__(self):
+        return "PG Connection: {0} ({1}) -> {2} (ajax:{3})".format(
+            self.conn_id, self.db,
+            'Connected' if self.conn and not self.conn.closed else
+            "Disconnected",
+            self.async
+        )
+
+    def connect(self, **kwargs):
+        if self.conn:
+            if self.conn.closed:
+                self.conn = None
+            else:
+                return True, None
+
+        pg_conn = None
+        password = None
+        passfile = None
+        mgr = self.manager
+
+        encpass = kwargs['password'] if 'password' in kwargs else None
+        passfile = kwargs['passfile'] if 'passfile' in kwargs else None
+
+        if encpass is None:
+            encpass = self.password or getattr(mgr, 'password', None)
+
+        # Reset the existing connection password
+        if self.reconnecting is not False:
+            self.password = None
+
+        if encpass:
+            # Fetch Logged in User Details.
+            user = User.query.filter_by(id=current_user.id).first()
+
+            if user is None:
+                return False, gettext("Unauthorized request.")
+
+            try:
+                password = decrypt(encpass, user.password)
+                # Handling of non ascii password (Python2)
+                if hasattr(str, 'decode'):
+                    password = password.decode('utf-8').encode('utf-8')
+                # password is in bytes, for python3 we need it in string
+                elif isinstance(password, bytes):
+                    password = password.decode()
+
+            except Exception as e:
+                current_app.logger.exception(e)
+                return False, \
+                    _(
+                        "Failed to decrypt the saved password.\nError: {0}"
+                    ).format(str(e))
+
+        # If no password credential is found then connect request might
+        # come from Query tool, ViewData grid, debugger etc tools.
+        # we will check for pgpass file availability from connection manager
+        # if it's present then we will use it
+        if not password and not encpass and not passfile:
+            passfile = mgr.passfile if mgr.passfile else None
+
+        try:
+            if hasattr(str, 'decode'):
+                database = self.db.encode('utf-8')
+                user = mgr.user.encode('utf-8')
+                conn_id = self.conn_id.encode('utf-8')
+            else:
+                database = self.db
+                user = mgr.user
+                conn_id = self.conn_id
+
+            import os
+            os.environ['PGAPPNAME'] = '{0} - {1}'.format(
+                config.APP_NAME, conn_id)
+
+            pg_conn = psycopg2.connect(
+                host=mgr.host,
+                hostaddr=mgr.hostaddr,
+                port=mgr.port,
+                database=database,
+                user=user,
+                password=password,
+                async=self.async,
+                passfile=get_complete_file_path(passfile),
+                sslmode=mgr.ssl_mode,
+                sslcert=get_complete_file_path(mgr.sslcert),
+                sslkey=get_complete_file_path(mgr.sslkey),
+                sslrootcert=get_complete_file_path(mgr.sslrootcert),
+                sslcrl=get_complete_file_path(mgr.sslcrl),
+                sslcompression=True if mgr.sslcompression else False,
+                service=mgr.service
+            )
+
+            # If connection is asynchronous then we will have to wait
+            # until the connection is ready to use.
+            if self.async == 1:
+                self._wait(pg_conn)
+
+        except psycopg2.Error as e:
+            if e.pgerror:
+                msg = e.pgerror
+            elif e.diag.message_detail:
+                msg = e.diag.message_detail
+            else:
+                msg = str(e)
+            current_app.logger.info(
+                u"Failed to connect to the database server(#{server_id}) for "
+                u"connection ({conn_id}) with error message as below"
+                u":{msg}".format(
+                    server_id=self.manager.sid,
+                    conn_id=conn_id,
+                    msg=msg.decode('utf-8') if hasattr(str, 'decode') else msg
+                )
+            )
+            return False, msg
+
+        # Overwrite connection notice attr to support
+        # more than 50 notices at a time
+        pg_conn.notices = deque([], self.ASYNC_NOTICE_MAXLENGTH)
+
+        self.conn = pg_conn
+        self.wasConnected = True
+        try:
+            status, msg = self._initialize(conn_id, **kwargs)
+        except Exception as e:
+            current_app.logger.exception(e)
+            self.conn = None
+            if not self.reconnecting:
+                self.wasConnected = False
+            raise e
+
+        if status:
+            mgr._update_password(encpass)
+        else:
+            if not self.reconnecting:
+                self.wasConnected = False
+
+        return status, msg
+
+    def _initialize(self, conn_id, **kwargs):
+        self.execution_aborted = False
+        self.__backend_pid = self.conn.get_backend_pid()
+
+        setattr(g, "{0}#{1}".format(
+            self.manager.sid,
+            self.conn_id.encode('utf-8')
+        ), None)
+
+        status, cur = self.__cursor()
+        formatted_exception_msg = self._formatted_exception_msg
+        mgr = self.manager
+
+        def _execute(cur, query, params=None):
+            try:
+                self.__internal_blocking_execute(cur, query, params)
+            except psycopg2.Error as pe:
+                cur.close()
+                return formatted_exception_msg(pe, False)
+            return None
+
+        # autocommit flag does not work with asynchronous connections.
+        # By default asynchronous connection runs in autocommit mode.
+        if self.async == 0:
+            if 'autocommit' in kwargs and kwargs['autocommit'] is False:
+                self.conn.autocommit = False
+            else:
+                self.conn.autocommit = True
+
+        register_string_typecasters(self.conn)
+
+        if self.array_to_string:
+            register_array_to_string_typecasters(self.conn)
+
+        # Register type casters for binary data only after registering array to
+        # string type casters.
+        if self.use_binary_placeholder:
+            register_binary_typecasters(self.conn)
+
+        status = _execute(cur, "SET DateStyle=ISO;"
+                               "SET client_min_messages=notice;"
+                               "SET bytea_output=escape;"
+                               "SET client_encoding='UNICODE';")
+
+        if status is not None:
+            self.conn.close()
+            self.conn = None
+
+            return False, status
+
+        if mgr.role:
+            status = _execute(cur, u"SET ROLE TO %s", [mgr.role])
+
+            if status is not None:
+                self.conn.close()
+                self.conn = None
+                current_app.logger.error(
+                    "Connect to the database server (#{server_id}) for "
+                    "connection ({conn_id}), but - failed to setup the role "
+                    "with error message as below:{msg}".format(
+                        server_id=self.manager.sid,
+                        conn_id=conn_id,
+                        msg=status
+                    )
+                )
+                return False, \
+                    _(
+                        "Failed to setup the role with error message:\n{0}"
+                    ).format(status)
+
+        if mgr.ver is None:
+            status = _execute(cur, "SELECT version()")
+
+            if status is not None:
+                self.conn.close()
+                self.conn = None
+                self.wasConnected = False
+                current_app.logger.error(
+                    "Failed to fetch the version information on the "
+                    "established connection to the database server "
+                    "(#{server_id}) for '{conn_id}' with below error "
+                    "message:{msg}".format(
+                        server_id=self.manager.sid,
+                        conn_id=conn_id,
+                        msg=status)
+                )
+                return False, status
+
+            if cur.rowcount > 0:
+                row = cur.fetchmany(1)[0]
+                mgr.ver = row['version']
+                mgr.sversion = self.conn.server_version
+
+        status = _execute(cur, """
+SELECT
+    db.oid as did, db.datname, db.datallowconn,
+    pg_encoding_to_char(db.encoding) AS serverencoding,
+    has_database_privilege(db.oid, 'CREATE') as cancreate, datlastsysoid
+FROM
+    pg_database db
+WHERE db.datname = current_database()""")
+
+        if status is None:
+            mgr.db_info = mgr.db_info or dict()
+            if cur.rowcount > 0:
+                res = cur.fetchmany(1)[0]
+                mgr.db_info[res['did']] = res.copy()
+
+                # We do not have database oid for the maintenance database.
+                if len(mgr.db_info) == 1:
+                    mgr.did = res['did']
+
+        status = _execute(cur, """
+SELECT
+    oid as id, rolname as name, rolsuper as is_superuser,
+    rolcreaterole as can_create_role, rolcreatedb as can_create_db
+FROM
+    pg_catalog.pg_roles
+WHERE
+    rolname = current_user""")
+
+        if status is None:
+            mgr.user_info = dict()
+            if cur.rowcount > 0:
+                mgr.user_info = cur.fetchmany(1)[0]
+
+        if 'password' in kwargs:
+            mgr.password = kwargs['password']
+
+        server_types = None
+        if 'server_types' in kwargs and isinstance(
+                kwargs['server_types'], list):
+            server_types = mgr.server_types = kwargs['server_types']
+
+        if server_types is None:
+            from pgadmin.browser.server_groups.servers.types import ServerType
+            server_types = ServerType.types()
+
+        for st in server_types:
+            if st.instanceOf(mgr.ver):
+                mgr.server_type = st.stype
+                mgr.server_cls = st
+                break
+
+        mgr.update_session()
+
+        return True, None
+
+    def __cursor(self, server_cursor=False):
+        if self.wasConnected is False:
+            raise ConnectionLost(
+                self.manager.sid,
+                self.db,
+                None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
+            )
+        cur = getattr(g, "{0}#{1}".format(
+            self.manager.sid,
+            self.conn_id.encode('utf-8')
+        ), None)
+
+        if self.connected() and cur and not cur.closed:
+            if not server_cursor or (server_cursor and cur.name):
+                return True, cur
+
+        if not self.connected():
+            errmsg = ""
+
+            current_app.logger.warning(
+                "Connection to database server (#{server_id}) for the "
+                "connection - '{conn_id}' has been lost.".format(
+                    server_id=self.manager.sid,
+                    conn_id=self.conn_id
+                )
+            )
+
+            if self.auto_reconnect and not self.reconnecting:
+                self.__attempt_execution_reconnect(None)
+            else:
+                raise ConnectionLost(
+                    self.manager.sid,
+                    self.db,
+                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
+                )
+
+        try:
+            if server_cursor:
+                # Providing name to cursor will create server side cursor.
+                cursor_name = "CURSOR:{0}".format(self.conn_id)
+                cur = self.conn.cursor(
+                    name=cursor_name, cursor_factory=DictCursor
+                )
+            else:
+                cur = self.conn.cursor(cursor_factory=DictCursor)
+        except psycopg2.Error as pe:
+            current_app.logger.exception(pe)
+            errmsg = gettext(
+                "Failed to create cursor for psycopg2 connection with error "
+                "message for the server#{1}:{2}:\n{0}"
+            ).format(
+                str(pe), self.manager.sid, self.db
+            )
+
+            current_app.logger.error(errmsg)
+            if self.conn.closed:
+                self.conn = None
+                if self.auto_reconnect and not self.reconnecting:
+                    current_app.logger.info(
+                        gettext(
+                            "Attempting to reconnect to the database server "
+                            "(#{server_id}) for the connection - '{conn_id}'."
+                        ).format(
+                            server_id=self.manager.sid,
+                            conn_id=self.conn_id
+                        )
+                    )
+                    return self.__attempt_execution_reconnect(
+                        self.__cursor, server_cursor
+                    )
+                else:
+                    raise ConnectionLost(
+                        self.manager.sid,
+                        self.db,
+                        None if self.conn_id[0:3] == u'DB:'
+                        else self.conn_id[5:]
+                    )
+
+        setattr(
+            g, "{0}#{1}".format(
+                self.manager.sid, self.conn_id.encode('utf-8')
+            ), cur
+        )
+
+        return True, cur
+
+    def __internal_blocking_execute(self, cur, query, params):
+        """
+        This function executes the query using cursor's execute function,
+        but in case of asynchronous connection we need to wait for the
+        transaction to be completed. If self.async is 1 then it is a
+        blocking call.
+
+        Args:
+            cur: Cursor object
+            query: SQL query to run.
+            params: Extra parameters
+        """
+
+        if sys.version_info < (3,):
+            if type(query) == unicode:
+                query = query.encode('utf-8')
+        else:
+            query = query.encode('utf-8')
+
+        cur.execute(query, params)
+        if self.async == 1:
+            self._wait(cur.connection)
+
+    def execute_on_server_as_csv(self,
+                                 query, params=None,
+                                 formatted_exception_msg=False,
+                                 records=2000):
+        """
+        To fetch query result and generate CSV output
+
+        Args:
+            query: SQL
+            params: Additional parameters
+            formatted_exception_msg: For exception
+            records: Number of initial records
+        Returns:
+            Generator response
+        """
+        status, cur = self.__cursor(server_cursor=True)
+        self.row_count = 0
+
+        if not status:
+            return False, str(cur)
+        query_id = random.randint(1, 9999999)
+
+        if IS_PY2 and type(query) == unicode:
+            query = query.encode('utf-8')
+
+        current_app.logger.log(
+            25,
+            u"Execute (with server cursor) for server #{server_id} - "
+            u"{conn_id} (Query-id: {query_id}):\n{query}".format(
+                server_id=self.manager.sid,
+                conn_id=self.conn_id,
+                query=query.decode('utf-8') if
+                sys.version_info < (3,) else query,
+                query_id=query_id
+            )
+        )
+        try:
+            self.__internal_blocking_execute(cur, query, params)
+        except psycopg2.Error as pe:
+            cur.close()
+            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
+            current_app.logger.error(
+                u"failed to execute query ((with server cursor) "
+                u"for the server #{server_id} - {conn_id} "
+                u"(query-id: {query_id}):\nerror message:{errmsg}".format(
+                    server_id=self.manager.sid,
+                    conn_id=self.conn_id,
+                    query=query,
+                    errmsg=errmsg,
+                    query_id=query_id
+                )
+            )
+            return False, errmsg
+
+        def handle_json_data(json_columns, results):
+            """
+            [ This is only for Python2.x]
+            This function will be useful to handle json data types.
+            We will dump json data as proper json instead of unicode values
+
+            Args:
+                json_columns: Columns which contains json data
+                results: Query result
+
+            Returns:
+                results
+            """
+            # Only if Python2 and there are columns with JSON type
+            if IS_PY2 and len(json_columns) > 0:
+                temp_results = []
+                for row in results:
+                    res = dict()
+                    for k, v in row.items():
+                        if k in json_columns:
+                            res[k] = json.dumps(v)
+                        else:
+                            res[k] = v
+                    temp_results.append(res)
+                results = temp_results
+            return results
+
+        def convert_keys_to_unicode(results, conn_encoding):
+            """
+            [ This is only for Python2.x]
+            We need to convert all keys to unicode as psycopg2
+            sends them as string
+
+            Args:
+                res: Query result set from psycopg2
+                conn_encoding: Connection encoding
+
+            Returns:
+                Result set (With all the keys converted to unicode)
+            """
+            new_results = []
+            for row in results:
+                new_results.append(
+                    dict([(k.decode(conn_encoding), v)
+                          for k, v in row.items()])
+                )
+            return new_results
+
+        def gen(quote='strings', quote_char="'", field_separator=','):
+
+            results = cur.fetchmany(records)
+            if not results:
+                if not cur.closed:
+                    cur.close()
+                yield gettext('The query executed did not return any data.')
+                return
+
+            header = []
+            json_columns = []
+            conn_encoding = cur.connection.encoding
+
+            for c in cur.ordered_description():
+                # This is to handle the case in which column name is non-ascii
+                column_name = c.to_dict()['name']
+                if IS_PY2:
+                    column_name = column_name.decode(conn_encoding)
+                header.append(column_name)
+                if c.to_dict()['type_code'] in ALL_JSON_TYPES:
+                    json_columns.append(column_name)
+
+            if IS_PY2:
+                results = convert_keys_to_unicode(results, conn_encoding)
+
+            res_io = StringIO()
+
+            if quote == 'strings':
+                quote = csv.QUOTE_NONNUMERIC
+            elif quote == 'all':
+                quote = csv.QUOTE_ALL
+            else:
+                quote = csv.QUOTE_NONE
+
+            if hasattr(str, 'decode'):
+                # Decode the field_separator
+                try:
+                    field_separator = field_separator.decode('utf-8')
+                except Exception as e:
+                    current_app.logger.error(e)
+
+                # Decode the quote_char
+                try:
+                    quote_char = quote_char.decode('utf-8')
+                except Exception as e:
+                    current_app.logger.error(e)
+
+            csv_writer = csv.DictWriter(
+                res_io, fieldnames=header, delimiter=field_separator,
+                quoting=quote,
+                quotechar=quote_char
+            )
+
+            csv_writer.writeheader()
+            results = handle_json_data(json_columns, results)
+            csv_writer.writerows(results)
+
+            yield res_io.getvalue()
+
+            while True:
+                results = cur.fetchmany(records)
+
+                if not results:
+                    if not cur.closed:
+                        cur.close()
+                    break
+                res_io = StringIO()
+
+                csv_writer = csv.DictWriter(
+                    res_io, fieldnames=header, delimiter=field_separator,
+                    quoting=quote,
+                    quotechar=quote_char
+                )
+
+                if IS_PY2:
+                    results = convert_keys_to_unicode(results, conn_encoding)
+
+                results = handle_json_data(json_columns, results)
+                csv_writer.writerows(results)
+                yield res_io.getvalue()
+
+        return True, gen
+
+    def execute_scalar(self, query, params=None,
+                       formatted_exception_msg=False):
+        status, cur = self.__cursor()
+        self.row_count = 0
+
+        if not status:
+            return False, str(cur)
+        query_id = random.randint(1, 9999999)
+
+        current_app.logger.log(
+            25,
+            u"Execute (scalar) for server #{server_id} - {conn_id} (Query-id: "
+            u"{query_id}):\n{query}".format(
+                server_id=self.manager.sid,
+                conn_id=self.conn_id,
+                query=query,
+                query_id=query_id
+            )
+        )
+        try:
+            self.__internal_blocking_execute(cur, query, params)
+        except psycopg2.Error as pe:
+            cur.close()
+            if not self.connected():
+                if self.auto_reconnect and not self.reconnecting:
+                    return self.__attempt_execution_reconnect(
+                        self.execute_dict, query, params,
+                        formatted_exception_msg
+                    )
+                raise ConnectionLost(
+                    self.manager.sid,
+                    self.db,
+                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
+                )
+            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
+            current_app.logger.error(
+                u"Failed to execute query (execute_scalar) for the server "
+                u"#{server_id} - {conn_id} (Query-id: {query_id}):\n"
+                u"Error Message:{errmsg}".format(
+                    server_id=self.manager.sid,
+                    conn_id=self.conn_id,
+                    query=query,
+                    errmsg=errmsg,
+                    query_id=query_id
+                )
+            )
+            return False, errmsg
+
+        self.row_count = cur.rowcount
+        if cur.rowcount > 0:
+            res = cur.fetchone()
+            if len(res) > 0:
+                return True, res[0]
+
+        return True, None
+
+    def execute_async(self, query, params=None, formatted_exception_msg=True):
+        """
+        This function executes the given query asynchronously and returns
+        result.
+
+        Args:
+            query: SQL query to run.
+            params: extra parameters to the function
+            formatted_exception_msg: if True then function return the
+            formatted exception message
+        """
+
+        if sys.version_info < (3,):
+            if type(query) == unicode:
+                query = query.encode('utf-8')
+        else:
+            query = query.encode('utf-8')
+
+        self.__async_cursor = None
+        status, cur = self.__cursor()
+
+        if not status:
+            return False, str(cur)
+        query_id = random.randint(1, 9999999)
+
+        current_app.logger.log(
+            25,
+            u"Execute (async) for server #{server_id} - {conn_id} (Query-id: "
+            u"{query_id}):\n{query}".format(
+                server_id=self.manager.sid,
+                conn_id=self.conn_id,
+                query=query.decode('utf-8'),
+                query_id=query_id
+            )
+        )
+
+        try:
+            self.__notices = []
+            self.execution_aborted = False
+            cur.execute(query, params)
+            res = self._wait_timeout(cur.connection)
+        except psycopg2.Error as pe:
+            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
+            current_app.logger.error(
+                u"Failed to execute query (execute_async) for the server "
+                u"#{server_id} - {conn_id}(Query-id: {query_id}):\n"
+                u"Error Message:{errmsg}".format(
+                    server_id=self.manager.sid,
+                    conn_id=self.conn_id,
+                    query=query.decode('utf-8'),
+                    errmsg=errmsg,
+                    query_id=query_id
+                )
+            )
+
+            if self.is_disconnected(pe):
+                raise ConnectionLost(
+                    self.manager.sid,
+                    self.db,
+                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
+                )
+            return False, errmsg
+
+        self.__async_cursor = cur
+        self.__async_query_id = query_id
+
+        return True, res
+
+    def execute_void(self, query, params=None, formatted_exception_msg=False):
+        """
+        This function executes the given query with no result.
+
+        Args:
+            query: SQL query to run.
+            params: extra parameters to the function
+            formatted_exception_msg: if True then function return the
+            formatted exception message
+        """
+        status, cur = self.__cursor()
+        self.row_count = 0
+
+        if not status:
+            return False, str(cur)
+        query_id = random.randint(1, 9999999)
+
+        current_app.logger.log(
+            25,
+            u"Execute (void) for server #{server_id} - {conn_id} (Query-id: "
+            u"{query_id}):\n{query}".format(
+                server_id=self.manager.sid,
+                conn_id=self.conn_id,
+                query=query,
+                query_id=query_id
+            )
+        )
+
+        try:
+            self.__internal_blocking_execute(cur, query, params)
+        except psycopg2.Error as pe:
+            cur.close()
+            if not self.connected():
+                if self.auto_reconnect and not self.reconnecting:
+                    return self.__attempt_execution_reconnect(
+                        self.execute_void, query, params,
+                        formatted_exception_msg
+                    )
+                raise ConnectionLost(
+                    self.manager.sid,
+                    self.db,
+                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
+                )
+            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
+            current_app.logger.error(
+                u"Failed to execute query (execute_void) for the server "
+                u"#{server_id} - {conn_id}(Query-id: {query_id}):\n"
+                u"Error Message:{errmsg}".format(
+                    server_id=self.manager.sid,
+                    conn_id=self.conn_id,
+                    query=query,
+                    errmsg=errmsg,
+                    query_id=query_id
+                )
+            )
+            return False, errmsg
+
+        self.row_count = cur.rowcount
+
+        return True, None
+
+    def __attempt_execution_reconnect(self, fn, *args, **kwargs):
+        self.reconnecting = True
+        setattr(g, "{0}#{1}".format(
+            self.manager.sid,
+            self.conn_id.encode('utf-8')
+        ), None)
+        try:
+            status, res = self.connect()
+            if status:
+                if fn:
+                    status, res = fn(*args, **kwargs)
+                    self.reconnecting = False
+                return status, res
+        except Exception as e:
+            current_app.logger.exception(e)
+            self.reconnecting = False
+
+            current_app.warning(
+                "Failed to reconnect the database server "
+                "(#{server_id})".format(
+                    server_id=self.manager.sid,
+                    conn_id=self.conn_id
+                )
+            )
+        self.reconnecting = False
+        raise ConnectionLost(
+            self.manager.sid,
+            self.db,
+            None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
+        )
+
+    def execute_2darray(self, query, params=None,
+                        formatted_exception_msg=False):
+        status, cur = self.__cursor()
+        self.row_count = 0
+
+        if not status:
+            return False, str(cur)
+
+        query_id = random.randint(1, 9999999)
+        current_app.logger.log(
+            25,
+            u"Execute (2darray) for server #{server_id} - {conn_id} "
+            u"(Query-id: {query_id}):\n{query}".format(
+                server_id=self.manager.sid,
+                conn_id=self.conn_id,
+                query=query,
+                query_id=query_id
+            )
+        )
+        try:
+            self.__internal_blocking_execute(cur, query, params)
+        except psycopg2.Error as pe:
+            cur.close()
+            if not self.connected():
+                if self.auto_reconnect and \
+                        not self.reconnecting:
+                    return self.__attempt_execution_reconnect(
+                        self.execute_2darray, query, params,
+                        formatted_exception_msg
+                    )
+            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
+            current_app.logger.error(
+                u"Failed to execute query (execute_2darray) for the server "
+                u"#{server_id} - {conn_id} (Query-id: {query_id}):\n"
+                u"Error Message:{errmsg}".format(
+                    server_id=self.manager.sid,
+                    conn_id=self.conn_id,
+                    query=query,
+                    errmsg=errmsg,
+                    query_id=query_id
+                )
+            )
+            return False, errmsg
+
+        # Get Resultset Column Name, Type and size
+        columns = cur.description and [
+            desc.to_dict() for desc in cur.ordered_description()
+        ] or []
+
+        rows = []
+        self.row_count = cur.rowcount
+        if cur.rowcount > 0:
+            for row in cur:
+                rows.append(row)
+
+        return True, {'columns': columns, 'rows': rows}
+
+    def execute_dict(self, query, params=None, formatted_exception_msg=False):
+        status, cur = self.__cursor()
+        self.row_count = 0
+
+        if not status:
+            return False, str(cur)
+        query_id = random.randint(1, 9999999)
+        current_app.logger.log(
+            25,
+            u"Execute (dict) for server #{server_id} - {conn_id} (Query-id: "
+            u"{query_id}):\n{query}".format(
+                server_id=self.manager.sid,
+                conn_id=self.conn_id,
+                query=query,
+                query_id=query_id
+            )
+        )
+        try:
+            self.__internal_blocking_execute(cur, query, params)
+        except psycopg2.Error as pe:
+            cur.close()
+            if not self.connected():
+                if self.auto_reconnect and not self.reconnecting:
+                    return self.__attempt_execution_reconnect(
+                        self.execute_dict, query, params,
+                        formatted_exception_msg
+                    )
+                raise ConnectionLost(
+                    self.manager.sid,
+                    self.db,
+                    None if self.conn_id[0:3] == u'DB:' else self.conn_id[5:]
+                )
+            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
+            current_app.logger.error(
+                u"Failed to execute query (execute_dict) for the server "
+                u"#{server_id}- {conn_id} (Query-id: {query_id}):\n"
+                u"Error Message:{errmsg}".format(
+                    server_id=self.manager.sid,
+                    conn_id=self.conn_id,
+                    query_id=query_id,
+                    errmsg=errmsg
+                )
+            )
+            return False, errmsg
+
+        # Get Resultset Column Name, Type and size
+        columns = cur.description and [
+            desc.to_dict() for desc in cur.ordered_description()
+        ] or []
+
+        rows = []
+        self.row_count = cur.rowcount
+        if cur.rowcount > 0:
+            for row in cur:
+                rows.append(dict(row))
+
+        return True, {'columns': columns, 'rows': rows}
+
+    def async_fetchmany_2darray(self, records=2000,
+                                formatted_exception_msg=False):
+        """
+        User should poll and check if status is ASYNC_OK before calling this
+        function
+        Args:
+          records: no of records to fetch. use -1 to fetchall.
+          formatted_exception_msg:
+
+        Returns:
+
+        """
+        cur = self.__async_cursor
+        if not cur:
+            return False, gettext(
+                "Cursor could not be found for the async connection."
+            )
+
+        if self.conn.isexecuting():
+            return False, gettext(
+                "Asynchronous query execution/operation underway."
+            )
+
+        if self.row_count > 0:
+            result = []
+            # For DDL operation, we may not have result.
+            #
+            # Because - there is not direct way to differentiate DML and
+            # DDL operations, we need to rely on exception to figure
+            # that out at the moment.
+            try:
+                if records == -1:
+                    res = cur.fetchall()
+                else:
+                    res = cur.fetchmany(records)
+                for row in res:
+                    new_row = []
+                    for col in self.column_info:
+                        new_row.append(row[col['name']])
+                    result.append(new_row)
+            except psycopg2.ProgrammingError as e:
+                result = None
+        else:
+            # User performed operation which dose not produce record/s as
+            # result.
+            # for eg. DDL operations.
+            return True, None
+
+        return True, result
+
+    def connected(self):
+        if self.conn:
+            if not self.conn.closed:
+                return True
+            self.conn = None
+        return False
+
+    def reset(self):
+        if self.conn:
+            if self.conn.closed:
+                self.conn = None
+        pg_conn = None
+        mgr = self.manager
+
+        password = getattr(mgr, 'password', None)
+
+        if password:
+            # Fetch Logged in User Details.
+            user = User.query.filter_by(id=current_user.id).first()
+
+            if user is None:
+                return False, gettext("Unauthorized request.")
+
+            password = decrypt(password, user.password).decode()
+
+        try:
+            pg_conn = psycopg2.connect(
+                host=mgr.host,
+                hostaddr=mgr.hostaddr,
+                port=mgr.port,
+                database=self.db,
+                user=mgr.user,
+                password=password,
+                passfile=get_complete_file_path(mgr.passfile),
+                sslmode=mgr.ssl_mode,
+                sslcert=get_complete_file_path(mgr.sslcert),
+                sslkey=get_complete_file_path(mgr.sslkey),
+                sslrootcert=get_complete_file_path(mgr.sslrootcert),
+                sslcrl=get_complete_file_path(mgr.sslcrl),
+                sslcompression=True if mgr.sslcompression else False,
+                service=mgr.service
+            )
+
+        except psycopg2.Error as e:
+            msg = e.pgerror if e.pgerror else e.message \
+                if e.message else e.diag.message_detail \
+                if e.diag.message_detail else str(e)
+
+            current_app.logger.error(
+                gettext(
+                    """
+Failed to reset the connection to the server due to following error:
+{0}"""
+                ).Format(msg)
+            )
+            return False, msg
+
+        pg_conn.notices = deque([], self.ASYNC_NOTICE_MAXLENGTH)
+        self.conn = pg_conn
+        self.__backend_pid = pg_conn.get_backend_pid()
+
+        return True, None
+
+    def transaction_status(self):
+        if self.conn:
+            return self.conn.get_transaction_status()
+        return None
+
+    def ping(self):
+        return self.execute_scalar('SELECT 1')
+
+    def _release(self):
+        if self.wasConnected:
+            if self.conn:
+                self.conn.close()
+                self.conn = None
+            self.password = None
+            self.wasConnected = False
+
+    def _wait(self, conn):
+        """
+        This function is used for the asynchronous connection,
+        it will call poll method in a infinite loop till poll
+        returns psycopg2.extensions.POLL_OK. This is a blocking
+        call.
+
+        Args:
+            conn: connection object
+        """
+
+        while 1:
+            state = conn.poll()
+            if state == psycopg2.extensions.POLL_OK:
+                break
+            elif state == psycopg2.extensions.POLL_WRITE:
+                select.select([], [conn.fileno()], [])
+            elif state == psycopg2.extensions.POLL_READ:
+                select.select([conn.fileno()], [], [])
+            else:
+                raise psycopg2.OperationalError(
+                    "poll() returned %s from _wait function" % state)
+
+    def _wait_timeout(self, conn):
+        """
+        This function is used for the asynchronous connection,
+        it will call poll method and return the status. If state is
+        psycopg2.extensions.POLL_WRITE and psycopg2.extensions.POLL_READ
+        function will wait for the given timeout.This is not a blocking call.
+
+        Args:
+            conn: connection object
+            time: wait time
+        """
+
+        while 1:
+            state = conn.poll()
+
+            if state == psycopg2.extensions.POLL_OK:
+                return self.ASYNC_OK
+            elif state == psycopg2.extensions.POLL_WRITE:
+                # Wait for the given time and then check the return status
+                # If three empty lists are returned then the time-out is
+                # reached.
+                timeout_status = select.select(
+                    [], [conn.fileno()], [], self.ASYNC_TIMEOUT
+                )
+                if timeout_status == ([], [], []):
+                    return self.ASYNC_WRITE_TIMEOUT
+            elif state == psycopg2.extensions.POLL_READ:
+                # Wait for the given time and then check the return status
+                # If three empty lists are returned then the time-out is
+                # reached.
+                timeout_status = select.select(
+                    [conn.fileno()], [], [], self.ASYNC_TIMEOUT
+                )
+                if timeout_status == ([], [], []):
+                    return self.ASYNC_READ_TIMEOUT
+            else:
+                raise psycopg2.OperationalError(
+                    "poll() returned %s from _wait_timeout function" % state
+                )
+
+    def poll(self, formatted_exception_msg=False, no_result=False):
+        """
+        This function is a wrapper around connection's poll function.
+        It internally uses the _wait_timeout method to poll the
+        result on the connection object. In case of success it
+        returns the result of the query.
+
+        Args:
+            formatted_exception_msg: if True then function return the formatted
+                                     exception message, otherwise error string.
+            no_result: If True then only poll status will be returned.
+        """
+
+        cur = self.__async_cursor
+        if not cur:
+            return False, gettext(
+                "Cursor could not be found for the async connection."
+            )
+
+        current_app.logger.log(
+            25,
+            "Polling result for (Query-id: {query_id})".format(
+                query_id=self.__async_query_id
+            )
+        )
+
+        is_error = False
+        try:
+            status = self._wait_timeout(self.conn)
+        except psycopg2.Error as pe:
+            if self.conn.closed:
+                raise ConnectionLost(
+                    self.manager.sid,
+                    self.db,
+                    self.conn_id[5:]
+                )
+            errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
+            is_error = True
+
+        if self.conn.notices and self.__notices is not None:
+            self.__notices.extend(self.conn.notices)
+            self.conn.notices.clear()
+
+        # We also need to fetch notices before we return from function in case
+        # of any Exception, To avoid code duplication we will return after
+        # fetching the notices in case of any Exception
+        if is_error:
+            return False, errmsg
+
+        result = None
+        self.row_count = 0
+        self.column_info = None
+
+        if status == self.ASYNC_OK:
+
+            # if user has cancelled the transaction then changed the status
+            if self.execution_aborted:
+                status = self.ASYNC_EXECUTION_ABORTED
+                self.execution_aborted = False
+                return status, result
+
+            # Fetch the column information
+            if cur.description is not None:
+                self.column_info = [
+                    desc.to_dict() for desc in cur.ordered_description()
+                ]
+
+                pos = 0
+                for col in self.column_info:
+                    col['pos'] = pos
+                    pos += 1
+
+            self.row_count = cur.rowcount
+            if not no_result:
+                if cur.rowcount > 0:
+                    result = []
+                    # For DDL operation, we may not have result.
+                    #
+                    # Because - there is not direct way to differentiate DML
+                    # and DDL operations, we need to rely on exception to
+                    # figure that out at the moment.
+                    try:
+                        for row in cur:
+                            new_row = []
+                            for col in self.column_info:
+                                new_row.append(row[col['name']])
+                            result.append(new_row)
+
+                    except psycopg2.ProgrammingError:
+                        result = None
+
+        return status, result
+
+    def status_message(self):
+        """
+        This function will return the status message returned by the last
+        command executed on the server.
+        """
+        cur = self.__async_cursor
+        if not cur:
+            return gettext(
+                "Cursor could not be found for the async connection."
+            )
+
+        current_app.logger.log(
+            25,
+            "Status message for (Query-id: {query_id})".format(
+                query_id=self.__async_query_id
+            )
+        )
+
+        return cur.statusmessage
+
+    def rows_affected(self):
+        """
+        This function will return the no of rows affected by the last command
+        executed on the server.
+        """
+
+        return self.row_count
+
+    def get_column_info(self):
+        """
+        This function will returns list of columns for last async sql command
+        executed on the server.
+        """
+
+        return self.column_info
+
+    def cancel_transaction(self, conn_id, did=None):
+        """
+        This function is used to cancel the running transaction
+        of the given connection id and database id using
+        PostgreSQL's pg_cancel_backend.
+
+        Args:
+            conn_id: Connection id
+            did: Database id (optional)
+        """
+        cancel_conn = self.manager.connection(did=did, conn_id=conn_id)
+        query = """SELECT pg_cancel_backend({0});""".format(
+            cancel_conn.__backend_pid)
+
+        status = True
+        msg = ''
+
+        # if backend pid is same then create a new connection
+        # to cancel the query and release it.
+        if cancel_conn.__backend_pid == self.__backend_pid:
+            password = getattr(self.manager, 'password', None)
+            if password:
+                # Fetch Logged in User Details.
+                user = User.query.filter_by(id=current_user.id).first()
+                if user is None:
+                    return False, gettext("Unauthorized request.")
+
+                password = decrypt(password, user.password).decode()
+
+            try:
+                pg_conn = psycopg2.connect(
+                    host=self.manager.host,
+                    hostaddr=self.manager.hostaddr,
+                    port=self.manager.port,
+                    database=self.db,
+                    user=self.manager.user,
+                    password=password,
+                    passfile=get_complete_file_path(self.manager.passfile),
+                    sslmode=self.manager.ssl_mode,
+                    sslcert=get_complete_file_path(self.manager.sslcert),
+                    sslkey=get_complete_file_path(self.manager.sslkey),
+                    sslrootcert=get_complete_file_path(
+                        self.manager.sslrootcert
+                    ),
+                    sslcrl=get_complete_file_path(self.manager.sslcrl),
+                    sslcompression=True if self.manager.sslcompression
+                    else False,
+                    service=self.manager.service
+                )
+
+                # Get the cursor and run the query
+                cur = pg_conn.cursor()
+                cur.execute(query)
+
+                # Close the connection
+                pg_conn.close()
+                pg_conn = None
+
+            except psycopg2.Error as e:
+                status = False
+                if e.pgerror:
+                    msg = e.pgerror
+                elif e.diag.message_detail:
+                    msg = e.diag.message_detail
+                else:
+                    msg = str(e)
+                return status, msg
+        else:
+            if self.connected():
+                status, msg = self.execute_void(query)
+
+                if status:
+                    cancel_conn.execution_aborted = True
+            else:
+                status = False
+                msg = gettext("Not connected to the database server.")
+
+        return status, msg
+
+    def messages(self):
+        """
+        Returns the list of the messages/notices send from the database server.
+        """
+        resp = []
+        while self.__notices:
+            resp.append(self.__notices.pop(0))
+        return resp
+
+    def decode_to_utf8(self, value):
+        """
+        This method will decode values to utf-8
+        Args:
+            value: String to be decode
+
+        Returns:
+            Decoded string
+        """
+        is_error = False
+        if hasattr(str, 'decode'):
+            try:
+                value = value.decode('utf-8')
+            except UnicodeDecodeError:
+                # Let's try with python's preferred encoding
+                # On Windows lc_messages mostly has environment dependent
+                # encoding like 'French_France.1252'
+                try:
+                    import locale
+                    pref_encoding = locale.getpreferredencoding()
+                    value = value.decode(pref_encoding)\
+                        .encode('utf-8')\
+                        .decode('utf-8')
+                except Exception:
+                    is_error = True
+            except Exception:
+                is_error = True
+
+        # If still not able to decode then
+        if is_error:
+            value = value.decode('ascii', 'ignore')
+
+        return value
+
+    def _formatted_exception_msg(self, exception_obj, formatted_msg):
+        """
+        This method is used to parse the psycopg2.Error object and returns the
+        formatted error message if flag is set to true else return
+        normal error message.
+
+        Args:
+            exception_obj: exception object
+            formatted_msg: if True then function return the formatted exception
+            message
+
+        """
+        if exception_obj.pgerror:
+            errmsg = exception_obj.pgerror
+        elif exception_obj.diag.message_detail:
+            errmsg = exception_obj.diag.message_detail
+        else:
+            errmsg = str(exception_obj)
+        # errmsg might contains encoded value, lets decode it
+        errmsg = self.decode_to_utf8(errmsg)
+
+        # if formatted_msg is false then return from the function
+        if not formatted_msg:
+            return errmsg
+
+        # Do not append if error starts with `ERROR:` as most pg related
+        # error starts with `ERROR:`
+        if not errmsg.startswith(u'ERROR:'):
+            errmsg = u'ERROR:  ' + errmsg + u'\n\n'
+
+        if exception_obj.diag.severity is not None \
+                and exception_obj.diag.message_primary is not None:
+            ex_diag_message = u"{0}:  {1}".format(
+                exception_obj.diag.severity,
+                self.decode_to_utf8(exception_obj.diag.message_primary)
+            )
+            # If both errors are different then only append it
+            if errmsg and ex_diag_message and \
+                ex_diag_message.strip().strip('\n').lower() not in \
+                    errmsg.strip().strip('\n').lower():
+                errmsg += ex_diag_message
+        elif exception_obj.diag.message_primary is not None:
+            message_primary = self.decode_to_utf8(
+                exception_obj.diag.message_primary
+            )
+            if message_primary.lower() not in errmsg.lower():
+                errmsg += message_primary
+
+        if exception_obj.diag.sqlstate is not None:
+            if not errmsg.endswith('\n'):
+                errmsg += '\n'
+            errmsg += gettext('SQL state: ')
+            errmsg += self.decode_to_utf8(exception_obj.diag.sqlstate)
+
+        if exception_obj.diag.message_detail is not None:
+            if 'Detail:'.lower() not in errmsg.lower():
+                if not errmsg.endswith('\n'):
+                    errmsg += '\n'
+                errmsg += gettext('Detail: ')
+                errmsg += self.decode_to_utf8(
+                    exception_obj.diag.message_detail
+                )
+
+        if exception_obj.diag.message_hint is not None:
+            if 'Hint:'.lower() not in errmsg.lower():
+                if not errmsg.endswith('\n'):
+                    errmsg += '\n'
+                errmsg += gettext('Hint: ')
+                errmsg += self.decode_to_utf8(exception_obj.diag.message_hint)
+
+        if exception_obj.diag.statement_position is not None:
+            if 'Character:'.lower() not in errmsg.lower():
+                if not errmsg.endswith('\n'):
+                    errmsg += '\n'
+                errmsg += gettext('Character: ')
+                errmsg += self.decode_to_utf8(
+                    exception_obj.diag.statement_position
+                )
+
+        if exception_obj.diag.context is not None:
+            if 'Context:'.lower() not in errmsg.lower():
+                if not errmsg.endswith('\n'):
+                    errmsg += '\n'
+                errmsg += gettext('Context: ')
+                errmsg += self.decode_to_utf8(exception_obj.diag.context)
+
+        return errmsg
+
+    #####
+    # As per issue reported on pgsycopg2 github repository link is shared below
+    # conn.closed is not reliable enough to identify the disconnection from the
+    # database server for some unknown reasons.
+    #
+    # (https://github.com/psycopg/psycopg2/issues/263)
+    #
+    # In order to resolve the issue, sqlalchamey follows the below logic to
+    # identify the disconnection. It relies on exception message to identify
+    # the error.
+    #
+    # Reference (MIT license):
+    # https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/dialects/postgresql/psycopg2.py
+    #
+    def is_disconnected(self, err):
+        if not self.conn.closed:
+            # checks based on strings.  in the case that .closed
+            # didn't cut it, fall back onto these.
+            str_e = str(err).partition("\n")[0]
+            for msg in [
+                # these error messages from libpq: interfaces/libpq/fe-misc.c
+                # and interfaces/libpq/fe-secure.c.
+                'terminating connection',
+                'closed the connection',
+                'connection not open',
+                'could not receive data from server',
+                'could not send data to server',
+                # psycopg2 client errors, psycopg2/conenction.h,
+                # psycopg2/cursor.h
+                'connection already closed',
+                'cursor already closed',
+                # not sure where this path is originally from, it may
+                # be obsolete.   It really says "losed", not "closed".
+                'losed the connection unexpectedly',
+                # these can occur in newer SSL
+                'connection has been closed unexpectedly',
+                'SSL SYSCALL error: Bad file descriptor',
+                'SSL SYSCALL error: EOF detected',
+            ]:
+                idx = str_e.find(msg)
+                if idx >= 0 and '"' not in str_e[:idx]:
+                    return True
+
+            return False
+        return True
diff --git a/web/pgadmin/utils/driver/psycopg2/server_manager.py b/web/pgadmin/utils/driver/psycopg2/server_manager.py
new file mode 100644
index 0000000..2299e28
--- /dev/null
+++ b/web/pgadmin/utils/driver/psycopg2/server_manager.py
@@ -0,0 +1,333 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""
+Implementation of ServerManager
+"""
+import os
+import datetime
+from flask import current_app, session
+from flask_security import current_user
+from flask_babel import gettext
+
+from pgadmin.utils.crypto import decrypt
+from .connection import Connection
+from pgadmin.model import Server
+
+
+class ServerManager(object):
+    """
+    class ServerManager
+
+    This class contains the information about the given server.
+    And, acts as connection manager for that particular session.
+    """
+
+    def __init__(self, server):
+        self.connections = dict()
+
+        self.update(server)
+
+    def update(self, server):
+        assert (server is not None)
+        assert (isinstance(server, Server))
+
+        self.ver = None
+        self.sversion = None
+        self.server_type = None
+        self.server_cls = None
+        self.password = None
+
+        self.sid = server.id
+        self.host = server.host
+        self.hostaddr = server.hostaddr
+        self.port = server.port
+        self.db = server.maintenance_db
+        self.did = None
+        self.user = server.username
+        self.password = server.password
+        self.role = server.role
+        self.ssl_mode = server.ssl_mode
+        self.pinged = datetime.datetime.now()
+        self.db_info = dict()
+        self.server_types = None
+        self.db_res = server.db_res
+        self.passfile = server.passfile
+        self.sslcert = server.sslcert
+        self.sslkey = server.sslkey
+        self.sslrootcert = server.sslrootcert
+        self.sslcrl = server.sslcrl
+        self.sslcompression = True if server.sslcompression else False
+        self.service = server.service
+
+        for con in self.connections:
+            self.connections[con]._release()
+
+        self.update_session()
+
+        self.connections = dict()
+
+    def as_dict(self):
+        """
+        Returns a dictionary object representing the server manager.
+        """
+        if self.ver is None or len(self.connections) == 0:
+            return None
+
+        res = dict()
+        res['sid'] = self.sid
+        res['ver'] = self.ver
+        res['sversion'] = self.sversion
+        if hasattr(self, 'password') and self.password:
+            # If running under PY2
+            if hasattr(self.password, 'decode'):
+                res['password'] = self.password.decode('utf-8')
+            else:
+                res['password'] = str(self.password)
+        else:
+            res['password'] = self.password
+
+        connections = res['connections'] = dict()
+
+        for conn_id in self.connections:
+            conn = self.connections[conn_id].as_dict()
+
+            if conn is not None:
+                connections[conn_id] = conn
+
+        return res
+
+    def ServerVersion(self):
+        return self.ver
+
+    @property
+    def version(self):
+        return self.sversion
+
+    def MajorVersion(self):
+        if self.sversion is not None:
+            return int(self.sversion / 10000)
+        raise Exception("Information is not available.")
+
+    def MinorVersion(self):
+        if self.sversion:
+            return int(int(self.sversion / 100) % 100)
+        raise Exception("Information is not available.")
+
+    def PatchVersion(self):
+        if self.sversion:
+            return int(int(self.sversion / 100) / 100)
+        raise Exception("Information is not available.")
+
+    def connection(
+            self, database=None, conn_id=None, auto_reconnect=True, did=None,
+            async=None, use_binary_placeholder=False, array_to_string=False
+    ):
+        if database is not None:
+            if hasattr(str, 'decode') and \
+                    not isinstance(database, unicode):
+                database = database.decode('utf-8')
+            if did is not None:
+                if did in self.db_info:
+                    self.db_info[did]['datname'] = database
+        else:
+            if did is None:
+                database = self.db
+            elif did in self.db_info:
+                database = self.db_info[did]['datname']
+            else:
+                maintenance_db_id = u'DB:{0}'.format(self.db)
+                if maintenance_db_id in self.connections:
+                    conn = self.connections[maintenance_db_id]
+                    if conn.connected():
+                        status, res = conn.execute_dict(u"""
+SELECT
+    db.oid as did, db.datname, db.datallowconn,
+    pg_encoding_to_char(db.encoding) AS serverencoding,
+    has_database_privilege(db.oid, 'CREATE') as cancreate, datlastsysoid
+FROM
+    pg_database db
+WHERE db.oid = {0}""".format(did))
+
+                        if status and len(res['rows']) > 0:
+                            for row in res['rows']:
+                                self.db_info[did] = row
+                                database = self.db_info[did]['datname']
+
+                        if did not in self.db_info:
+                            raise Exception(gettext(
+                                "Could not find the specified database."
+                            ))
+
+        if database is None:
+            raise ConnectionLost(self.sid, None, None)
+
+        my_id = (u'CONN:{0}'.format(conn_id)) if conn_id is not None else \
+            (u'DB:{0}'.format(database))
+
+        self.pinged = datetime.datetime.now()
+
+        if my_id in self.connections:
+            return self.connections[my_id]
+        else:
+            if async is None:
+                async = 1 if conn_id is not None else 0
+            else:
+                async = 1 if async is True else 0
+            self.connections[my_id] = Connection(
+                self, my_id, database, auto_reconnect, async,
+                use_binary_placeholder=use_binary_placeholder,
+                array_to_string=array_to_string
+            )
+
+            return self.connections[my_id]
+
+    def _restore(self, data):
+        """
+        Helps restoring to reconnect the auto-connect connections smoothly on
+        reload/restart of the app server..
+        """
+        # restore server version from flask session if flask server was
+        # restarted. As we need server version to resolve sql template paths.
+        from pgadmin.browser.server_groups.servers.types import ServerType
+
+        self.ver = data.get('ver', None)
+        self.sversion = data.get('sversion', None)
+
+        if self.ver and not self.server_type:
+            for st in ServerType.types():
+                if st.instanceOf(self.ver):
+                    self.server_type = st.stype
+                    self.server_cls = st
+                    break
+
+        # Hmm.. we will not honour this request, when I already have
+        # connections
+        if len(self.connections) != 0:
+            return
+
+        # We need to know about the existing server variant supports during
+        # first connection for identifications.
+        self.pinged = datetime.datetime.now()
+        try:
+            if 'password' in data and data['password']:
+                data['password'] = data['password'].encode('utf-8')
+        except Exception as e:
+            current_app.logger.exception(e)
+
+        connections = data['connections']
+        for conn_id in connections:
+            conn_info = connections[conn_id]
+            conn = self.connections[conn_info['conn_id']] = Connection(
+                self, conn_info['conn_id'], conn_info['database'],
+                conn_info['auto_reconnect'], conn_info['async'],
+                use_binary_placeholder=conn_info['use_binary_placeholder'],
+                array_to_string=conn_info['array_to_string']
+            )
+
+            # only try to reconnect if connection was connected previously and
+            # auto_reconnect is true.
+            if conn_info['wasConnected'] and conn_info['auto_reconnect']:
+                try:
+                    conn.connect(
+                        password=data['password'],
+                        server_types=ServerType.types()
+                    )
+                    # This will also update wasConnected flag in connection so
+                    # no need to update the flag manually.
+                except Exception as e:
+                    current_app.logger.exception(e)
+                    self.connections.pop(conn_info['conn_id'])
+
+    def release(self, database=None, conn_id=None, did=None):
+        if did is not None:
+            if did in self.db_info and 'datname' in self.db_info[did]:
+                database = self.db_info[did]['datname']
+                if hasattr(str, 'decode') and \
+                        not isinstance(database, unicode):
+                    database = database.decode('utf-8')
+                if database is None:
+                    return False
+            else:
+                return False
+
+        my_id = (u'CONN:{0}'.format(conn_id)) if conn_id is not None else \
+            (u'DB:{0}'.format(database)) if database is not None else None
+
+        if my_id is not None:
+            if my_id in self.connections:
+                self.connections[my_id]._release()
+                del self.connections[my_id]
+                if did is not None:
+                    del self.db_info[did]
+
+                if len(self.connections) == 0:
+                    self.ver = None
+                    self.sversion = None
+                    self.server_type = None
+                    self.server_cls = None
+                    self.password = None
+
+                self.update_session()
+
+                return True
+            else:
+                return False
+
+        for con in self.connections:
+            self.connections[con]._release()
+
+        self.connections = dict()
+        self.ver = None
+        self.sversion = None
+        self.server_type = None
+        self.server_cls = None
+        self.password = None
+
+        self.update_session()
+
+        return True
+
+    def _update_password(self, passwd):
+        self.password = passwd
+        for conn_id in self.connections:
+            conn = self.connections[conn_id]
+            if conn.conn is not None or conn.wasConnected is True:
+                conn.password = passwd
+
+    def update_session(self):
+        managers = session['__pgsql_server_managers'] \
+            if '__pgsql_server_managers' in session else dict()
+        updated_mgr = self.as_dict()
+
+        if not updated_mgr:
+            if self.sid in managers:
+                managers.pop(self.sid)
+        else:
+            managers[self.sid] = updated_mgr
+        session['__pgsql_server_managers'] = managers
+        session.force_write = True
+
+    def utility(self, operation):
+        """
+        utility(operation)
+
+        Returns: name of the utility which used for the operation
+        """
+        if self.server_cls is not None:
+            return self.server_cls.utility(operation, self.sversion)
+
+        return None
+
+    def export_password_env(self, env):
+        if self.password:
+            password = decrypt(
+                self.password, current_user.password
+            ).decode()
+            os.environ[str(env)] = password


view thread (14+ messages)  latest in thread

reply

Reply instructions:

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

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

  To: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re: [pgAdmin4][RM#3140] Add service parameter
  In-Reply-To: <CAKKotZT5AikN+70CnVwcyDApeSPZ6Awx8YTNKoMWxHRmoVctHw@mail.gmail.com>

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

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