Handling the bad/lost connection of a database server.

Made backend changes for:
* Taking care of the connection status in the psycopg2 driver. And, when
  the connection is lost, it throws a exception with 503 http status
  message, and connection lost information in it.
* Allowing the flask application to propagate the exceptions even in the
  release mode.
* Utilising the existing password (while reconnection, if not
  disconnected explicitly).
* Introduced a new ajax response message 'service_unavailable' (http
  status code: 503), which suggests temporary service unavailable.

Client (front-end) changes:
* To handle the connection lost of a database server for different
  operations by generating proper events, and handle them properly.

Removed the connection status check code from different nodes, so that
- it generates the proper exception, when accessing the non-alive
  connection.

Fixes #1387
pull/3/head
Ashesh Vashi 2016-08-29 11:52:50 +05:30
parent 1b05464a04
commit f12d981a9d
51 changed files with 1235 additions and 970 deletions

View File

@ -124,6 +124,7 @@ def create_app(app_name=config.APP_NAME):
# Removes unwanted whitespace from render_template function # Removes unwanted whitespace from render_template function
app.jinja_env.trim_blocks = True app.jinja_env.trim_blocks = True
app.config.from_object(config) app.config.from_object(config)
app.config.update(dict(PROPAGATE_EXCEPTIONS=True))
########################################################################## ##########################################################################
# Setup session management # Setup session management

View File

@ -85,7 +85,8 @@ class CollectionNodeModule(PgAdminModule, PGChildModule):
"_type": 'coll-%s' % (self.node_type), "_type": 'coll-%s' % (self.node_type),
"_id": parent_id, "_id": parent_id,
"_pid": parent_id, "_pid": parent_id,
"module": 'pgadmin.node.%s' % self.node_type "module": 'pgadmin.node.%s' % self.node_type,
"subnodes": sorted([m.node_type for m in self.submodules])
} }
for key in kwargs: for key in kwargs:

View File

@ -712,8 +712,16 @@ class ServerNode(PGChildNodeView):
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
conn = manager.connection() conn = manager.connection()
res = conn.connected()
return make_json_response(data={'connected': conn.connected()}) if res:
from pgadmin.utils.exception import ConnectionLost
try:
conn.execute_scalar('SELECT 1')
except ConnectionLost:
res = False
return make_json_response(data={'connected': res})
def connect(self, gid, sid): def connect(self, gid, sid):
""" """
@ -752,8 +760,14 @@ class ServerNode(PGChildNodeView):
password = None password = None
save_password = False save_password = False
# Connect the Server
from pgadmin.utils.driver import get_driver
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
conn = manager.connection()
if 'password' not in data: if 'password' not in data:
if server.password is None: conn_passwd = getattr(conn, 'password', None)
if conn_passwd is None and server.password is None:
# Return the password template in case password is not # Return the password template in case password is not
# provided, or password has not been saved earlier. # provided, or password has not been saved earlier.
return make_json_response( return make_json_response(
@ -772,19 +786,15 @@ class ServerNode(PGChildNodeView):
data['save_password'] if password and \ data['save_password'] if password and \
'save_password' in data else False 'save_password' in data else False
# Encrypt the password before saving with user's login password key. # Encrypt the password before saving with user's login password key.
try: try:
password = encrypt(password, user.password) \ password = encrypt(password, user.password) \
if password is not None else server.password if password is not None else server.password
except Exception as e: except Exception as e:
current_app.logger.exception(e) current_app.logger.exception(e)
return internal_server_error(errormsg=e.message) return internal_server_error(errormsg=e.message)
# Connect the Server
from pgadmin.utils.driver import get_driver
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
conn = manager.connection()
status = True
try: try:
status, errmsg = conn.connect( status, errmsg = conn.connect(
password=password, password=password,
@ -792,13 +802,18 @@ class ServerNode(PGChildNodeView):
) )
except Exception as e: except Exception as e:
current_app.logger.exception(e) current_app.logger.exception(e)
# TODO::
# Ask the password again (if existing password couldn't be return make_json_response(
# descrypted) success=0,
if e.message: status=401,
return internal_server_error(errormsg=e.message) result=render_template(
else: 'servers/password.html',
return internal_server_error(errormsg=str(e)) server_label=server.name,
username=server.username,
errmsg=e.message if e.message else str(e),
_=gettext
)
)
if not status: if not status:
current_app.logger.error( current_app.logger.error(

View File

@ -24,7 +24,7 @@ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, \
make_response as ajax_response, internal_server_error, unauthorized make_response as ajax_response, internal_server_error, unauthorized
from pgadmin.utils.ajax import precondition_required, gone from pgadmin.utils.ajax import gone
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -133,11 +133,6 @@ class DatabaseView(PGChildNodeView):
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
else: else:
self.conn = self.manager.connection() self.conn = self.manager.connection()
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
_("Connection to the server has been lost!")
)
ver = self.manager.version ver = self.manager.version
# we will set template path for sql scripts # we will set template path for sql scripts
@ -147,6 +142,7 @@ class DatabaseView(PGChildNodeView):
self.template_path = 'databases/sql/9.2_plus' self.template_path = 'databases/sql/9.2_plus'
else: else:
self.template_path = 'databases/sql/9.1_plus' self.template_path = 'databases/sql/9.1_plus'
return f(self, *args, **kwargs) return f(self, *args, **kwargs)
return wrapped return wrapped
@ -156,7 +152,9 @@ class DatabaseView(PGChildNodeView):
@check_precondition(action="list") @check_precondition(action="list")
def list(self, gid, sid): def list(self, gid, sid):
last_system_oid = 0 if self.blueprint.show_system_objects else \ last_system_oid = 0 if self.blueprint.show_system_objects else \
(self.manager.db_info[self.manager.did])['datlastsysoid'] (self.manager.db_info[self.manager.did])['datlastsysoid'] \
if self.manager.db_info is not None and \
self.manager.did in self.manager.db_info else 0
SQL = render_template( SQL = render_template(
"/".join([self.template_path, 'properties.sql']), "/".join([self.template_path, 'properties.sql']),
conn=self.conn, last_system_oid=last_system_oid conn=self.conn, last_system_oid=last_system_oid
@ -175,8 +173,10 @@ class DatabaseView(PGChildNodeView):
res = [] res = []
last_system_oid = 0 if self.blueprint.show_system_objects or \ last_system_oid = 0 if self.blueprint.show_system_objects or \
show_system_templates else ( show_system_templates else (
self.manager.db_info[self.manager.did] (self.manager.db_info[self.manager.did])['datlastsysoid'] \
)['datlastsysoid'] if self.manager.db_info is not None and \
self.manager.did in self.manager.db_info else 0
)
SQL = render_template( SQL = render_template(
"/".join([self.template_path, 'nodes.sql']), "/".join([self.template_path, 'nodes.sql']),
@ -403,26 +403,22 @@ class DatabaseView(PGChildNodeView):
This function to return list of avialable encodings This function to return list of avialable encodings
""" """
res = [{'label': '', 'value': ''}] res = [{'label': '', 'value': ''}]
try: SQL = render_template(
SQL = render_template( "/".join([self.template_path, 'get_encodings.sql'])
"/".join([self.template_path, 'get_encodings.sql']) )
) status, rset = self.conn.execute_dict(SQL)
status, rset = self.conn.execute_dict(SQL) if not status:
if not status: return internal_server_error(errormsg=rset)
return internal_server_error(errormsg=res)
for row in rset['rows']: for row in rset['rows']:
res.append( res.append(
{'label': row['encoding'], 'value': row['encoding']} {'label': row['encoding'], 'value': row['encoding']}
)
return make_json_response(
data=res,
status=200
) )
except Exception as e: return make_json_response(
return internal_server_error(errormsg=str(e)) data=res,
status=200
)
@check_precondition(action="get_ctypes") @check_precondition(action="get_ctypes")
def get_ctypes(self, gid, sid, did=None): def get_ctypes(self, gid, sid, did=None):
@ -435,25 +431,21 @@ class DatabaseView(PGChildNodeView):
res.append( res.append(
{'label': val, 'value': val} {'label': val, 'value': val}
) )
try: SQL = render_template(
SQL = render_template( "/".join([self.template_path, 'get_ctypes.sql'])
"/".join([self.template_path, 'get_ctypes.sql']) )
) status, rset = self.conn.execute_dict(SQL)
status, rset = self.conn.execute_dict(SQL) if not status:
if not status: return internal_server_error(errormsg=rset)
return internal_server_error(errormsg=res)
for row in rset['rows']: for row in rset['rows']:
if row['cname'] not in default_list: if row['cname'] not in default_list:
res.append({'label': row['cname'], 'value': row['cname']}) res.append({'label': row['cname'], 'value': row['cname']})
return make_json_response( return make_json_response(
data=res, data=res,
status=200 status=200
) )
except Exception as e:
return internal_server_error(errormsg=str(e))
@check_precondition(action="create") @check_precondition(action="create")
def create(self, gid, sid): def create(self, gid, sid):
@ -475,64 +467,56 @@ class DatabaseView(PGChildNodeView):
"Could not find the required parameter (%s)." % arg "Could not find the required parameter (%s)." % arg
) )
) )
try: # The below SQL will execute CREATE DDL only
# The below SQL will execute CREATE DDL only SQL = render_template(
SQL = render_template( "/".join([self.template_path, 'create.sql']),
"/".join([self.template_path, 'create.sql']), data=data, conn=self.conn
data=data, conn=self.conn )
) status, msg = self.conn.execute_scalar(SQL)
if not status:
return internal_server_error(errormsg=msg)
if 'datacl' in data:
data['datacl'] = parse_priv_to_db(data['datacl'], 'DATABASE')
# The below SQL will execute rest DMLs because we can not execute CREATE with any other
SQL = render_template(
"/".join([self.template_path, 'grant.sql']),
data=data, conn=self.conn
)
SQL = SQL.strip('\n').strip(' ')
if SQL and SQL != "":
status, msg = self.conn.execute_scalar(SQL) status, msg = self.conn.execute_scalar(SQL)
if not status: if not status:
return internal_server_error(errormsg=msg) return internal_server_error(errormsg=msg)
if 'datacl' in data: # We need oid of newly created database
data['datacl'] = parse_priv_to_db(data['datacl'], 'DATABASE') SQL = render_template(
"/".join([self.template_path, 'properties.sql']),
name=data['name'], conn=self.conn, last_system_oid=0
)
SQL = SQL.strip('\n').strip(' ')
if SQL and SQL != "":
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
# The below SQL will execute rest DMLs because we can not execute CREATE with any other response = res['rows'][0]
SQL = render_template(
"/".join([self.template_path, 'grant.sql']), return jsonify(
data=data, conn=self.conn node=self.blueprint.generate_browser_node(
) response['did'],
SQL = SQL.strip('\n').strip(' ') sid,
if SQL and SQL != "": response['name'],
status, msg = self.conn.execute_scalar(SQL) icon="icon-database-not-connected",
if not status: connected=False,
return internal_server_error(errormsg=msg) tablespace=response['default_tablespace'],
allowConn=True,
# We need oid of newly created database canCreate=response['cancreate'],
SQL = render_template( canDisconn=True,
"/".join([self.template_path, 'properties.sql']), canDrop=True
name=data['name'], conn=self.conn, last_system_oid=0
)
SQL = SQL.strip('\n').strip(' ')
if SQL and SQL != "":
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
response = res['rows'][0]
return jsonify(
node=self.blueprint.generate_browser_node(
response['did'],
sid,
response['name'],
icon="icon-database-not-connected",
connected=False,
tablespace=response['default_tablespace'],
allowConn=True,
canCreate=response['cancreate'],
canDisconn=True,
canDrop=True
)
)
except Exception as e:
return make_json_response(
status=410,
success=0,
errormsg=e.message
) )
)
@check_precondition(action="update") @check_precondition(action="update")
def update(self, gid, sid, did): def update(self, gid, sid, did):
@ -563,91 +547,79 @@ class DatabaseView(PGChildNodeView):
if 'name' not in data: if 'name' not in data:
data['name'] = data['old_name'] data['name'] = data['old_name']
try: status = self.manager.release(did=did)
status = self.manager.release(did=did) conn = self.manager.connection()
conn = self.manager.connection() for action in ["rename_database", "tablespace"]:
for action in ["rename_database", "tablespace"]: SQL = self.get_offline_sql(gid, sid, data, did, action)
SQL = self.get_offline_sql(gid, sid, data, did, action)
SQL = SQL.strip('\n').strip(' ')
if SQL and SQL != "":
status, msg = conn.execute_scalar(SQL)
if not status:
return internal_server_error(errormsg=msg)
info = "Database updated."
self.conn = self.manager.connection(database=data['name'], auto_reconnect=True)
status, errmsg = self.conn.connect()
SQL = self.get_online_sql(gid, sid, data, did)
SQL = SQL.strip('\n').strip(' ') SQL = SQL.strip('\n').strip(' ')
if SQL and SQL != "": if SQL and SQL != "":
status, msg = self.conn.execute_scalar(SQL) status, msg = conn.execute_scalar(SQL)
if not status: if not status:
return internal_server_error(errormsg=msg) return internal_server_error(errormsg=msg)
info = "Database updated." info = "Database updated."
return make_json_response( self.conn = self.manager.connection(database=data['name'], auto_reconnect=True)
success=1, status, errmsg = self.conn.connect()
info=info,
data={
'id': did,
'sid': sid,
'gid': gid,
}
)
except Exception as e: SQL = self.get_online_sql(gid, sid, data, did)
return make_json_response( SQL = SQL.strip('\n').strip(' ')
status=410, if SQL and SQL != "":
success=0, status, msg = self.conn.execute_scalar(SQL)
errormsg=str(e) if not status:
) return internal_server_error(errormsg=msg)
info = "Database updated."
return make_json_response(
success=1,
info=info,
data={
'id': did,
'sid': sid,
'gid': gid,
}
)
@check_precondition(action="drop") @check_precondition(action="drop")
def delete(self, gid, sid, did): def delete(self, gid, sid, did):
"""Delete the database.""" """Delete the database."""
try: default_conn = self.manager.connection()
default_conn = self.manager.connection() SQL = render_template(
SQL = render_template( "/".join([self.template_path, 'delete.sql']),
"/".join([self.template_path, 'delete.sql']), did=did, conn=self.conn
did=did, conn=self.conn )
) status, res = default_conn.execute_scalar(SQL)
status, res = default_conn.execute_scalar(SQL) if not status:
if not status: return internal_server_error(errormsg=res)
return internal_server_error(errormsg=res)
if res is None: if res is None:
return make_json_response(
success=0,
errormsg=_(
'Error: Object not found.'
),
info=_(
'The specified database could not be found.\n'
)
)
else:
status = self.manager.release(did=did)
SQL = render_template(
"/".join([self.template_path, 'delete.sql']),
datname=res, conn=self.conn
)
status, msg = default_conn.execute_scalar(SQL)
if not status:
# reconnect if database drop failed.
conn = self.manager.connection(did=did, auto_reconnect=True)
status, errmsg = conn.connect()
return internal_server_error(errormsg=msg)
except Exception as e:
return make_json_response( return make_json_response(
success=0, success=0,
errormsg=str(e)) errormsg=_(
'Error: Object not found.'
),
info=_(
'The specified database could not be found.\n'
)
)
else:
status = self.manager.release(did=did)
SQL = render_template(
"/".join([self.template_path, 'delete.sql']),
datname=res, conn=self.conn
)
status, msg = default_conn.execute_scalar(SQL)
if not status:
# reconnect if database drop failed.
conn = self.manager.connection(did=did, auto_reconnect=True)
status, errmsg = conn.connect()
return internal_server_error(errormsg=msg)
return make_json_response(success=1) return make_json_response(success=1)
@ -662,25 +634,18 @@ class DatabaseView(PGChildNodeView):
data[k] = json.loads(v, encoding='utf-8') data[k] = json.loads(v, encoding='utf-8')
except ValueError: except ValueError:
data[k] = v data[k] = v
try: status, res = self.get_sql(gid, sid, data, did)
status, res = self.get_sql(gid, sid, data, did)
if not status: if not status:
return res return res
res = re.sub('\n{2,}', '\n\n', res) res = re.sub('\n{2,}', '\n\n', res)
SQL = res.strip('\n').strip(' ') SQL = res.strip('\n').strip(' ')
return make_json_response( return make_json_response(
data=SQL, data=SQL,
status=200 status=200
) )
except Exception as e:
current_app.logger.exception(e)
return make_json_response(
data=_("-- modified SQL"),
status=200
)
def get_sql(self, gid, sid, data, did=None): def get_sql(self, gid, sid, data, did=None):
SQL = '' SQL = ''
@ -819,7 +784,10 @@ class DatabaseView(PGChildNodeView):
server. server.
""" """
last_system_oid = 0 if self.blueprint.show_system_objects else \ last_system_oid = 0 if self.blueprint.show_system_objects else \
(self.manager.db_info[self.manager.did])['datlastsysoid'] (self.manager.db_info[self.manager.did])['datlastsysoid'] \
if self.manager.db_info is not None and \
self.manager.did in self.manager.db_info else 0
status, res = self.conn.execute_dict( status, res = self.conn.execute_dict(
render_template( render_template(
"/".join([self.template_path, 'stats.sql']), "/".join([self.template_path, 'stats.sql']),

View File

@ -17,9 +17,8 @@ from flask import render_template, make_response, request, jsonify
from flask_babel import gettext from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response, gone
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -201,17 +200,8 @@ class CastView(PGChildNodeView):
self = args[0] self = args[0]
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid']) self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser # Set template path for the SQL scripts
if not self.conn.connected(): self.template_path = 'cast/sql/9.1_plus'
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
ver = self.manager.version
# we will set template path for sql scripts
if ver >= 90100:
self.template_path = 'cast/sql/9.1_plus'
return f(*args, **kwargs) return f(*args, **kwargs)
@ -226,9 +216,13 @@ class CastView(PGChildNodeView):
:param did: database id :param did: database id
:return: :return:
""" """
last_system_oid = 0 if self.blueprint.show_system_objects else \
(self.manager.db_info[did])['datlastsysoid'] \
if self.manager.db_info is not None and \
did in self.manager.db_info else 0
sql = render_template( sql = render_template(
"/".join([self.template_path, 'properties.sql']), "/".join([self.template_path, 'properties.sql']),
datlastsysoid=self.manager.db_info[did]['datlastsysoid'], datlastsysoid=last_system_oid,
showsysobj=self.blueprint.show_system_objects showsysobj=self.blueprint.show_system_objects
) )
status, res = self.conn.execute_dict(sql) status, res = self.conn.execute_dict(sql)
@ -255,9 +249,13 @@ class CastView(PGChildNodeView):
:return: :return:
""" """
res = [] res = []
last_system_oid = 0 if self.blueprint.show_system_objects else \
(self.manager.db_info[did])['datlastsysoid'] \
if self.manager.db_info is not None and \
did in self.manager.db_info else 0
sql = render_template( sql = render_template(
"/".join([self.template_path, 'nodes.sql']), "/".join([self.template_path, 'nodes.sql']),
datlastsysoid=self.manager.db_info[did]['datlastsysoid'], datlastsysoid=last_system_oid,
showsysobj=self.blueprint.show_system_objects showsysobj=self.blueprint.show_system_objects
) )
status, rset = self.conn.execute_2darray(sql) status, rset = self.conn.execute_2darray(sql)
@ -313,17 +311,19 @@ class CastView(PGChildNodeView):
:param cid: cast id :param cid: cast id
:return: :return:
""" """
last_system_oid = (self.manager.db_info[did])['datlastsysoid'] if \
self.manager.db_info is not None and \
did in self.manager.db_info else 0
sql = render_template( sql = render_template(
"/".join([self.template_path, 'properties.sql']), "/".join([self.template_path, 'properties.sql']),
cid=cid, cid=cid,
datlastsysoid=self.manager.db_info[did]['datlastsysoid'], datlastsysoid=last_system_oid,
showsysobj=self.blueprint.show_system_objects showsysobj=self.blueprint.show_system_objects
) )
status, res = self.conn.execute_dict(sql) status, res = self.conn.execute_dict(sql)
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
result = res['rows'][0]
return ajax_response( return ajax_response(
response=res['rows'][0], response=res['rows'][0],
@ -367,10 +367,14 @@ class CastView(PGChildNodeView):
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
# we need oid to to add object in tree at browser, below sql will gives the same # we need oid to to add object in tree at browser, below sql will gives the same
last_system_oid = 0 if self.blueprint.show_system_objects else \
(self.manager.db_info[did])['datlastsysoid'] \
if self.manager.db_info is not None and \
did in self.manager.db_info else 0
sql = render_template("/".join([self.template_path, 'properties.sql']), sql = render_template("/".join([self.template_path, 'properties.sql']),
srctyp=data['srctyp'], srctyp=data['srctyp'],
trgtyp=data['trgtyp'], trgtyp=data['trgtyp'],
datlastsysoid=self.manager.db_info[did]['datlastsysoid'], datlastsysoid=last_system_oid,
showsysobj=self.blueprint.show_system_objects showsysobj=self.blueprint.show_system_objects
) )
status, cid = self.conn.execute_scalar(sql) status, cid = self.conn.execute_scalar(sql)
@ -529,9 +533,13 @@ class CastView(PGChildNodeView):
""" """
try: try:
if cid is not None: if cid is not None:
last_system_oid = 0 if self.blueprint.show_system_objects else \
(self.manager.db_info[did])['datlastsysoid'] \
if self.manager.db_info is not none and \
did in self.manager.db_info else 0
sql = render_template("/".join([self.template_path, 'properties.sql']), sql = render_template("/".join([self.template_path, 'properties.sql']),
cid=cid, cid=cid,
datlastsysoid=self.manager.db_info[did]['datlastsysoid'], datlastsysoid=last_system_oid,
showsysobj=self.blueprint.show_system_objects) showsysobj=self.blueprint.show_system_objects)
status, res = self.conn.execute_dict(sql) status, res = self.conn.execute_dict(sql)

View File

@ -16,9 +16,8 @@ from flask import render_template, make_response, request, jsonify
from flask_babel import gettext from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -188,22 +187,12 @@ class EventTriggerView(PGChildNodeView):
@wraps(f) @wraps(f)
def wrap(*args, **kwargs): def wrap(*args, **kwargs):
# Here args[0] will hold self & kwargs will hold gid,sid,did
# Here - args[0] will always hold self & kwargs will hold gid, sid, did
self = args[0] self = args[0]
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid']) self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.template_path = 'event_triggers/sql/9.3_plus'
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
ver = self.manager.version
if ver >= 90300:
self.template_path = 'event_triggers/sql/9.3_plus'
return f(*args, **kwargs) return f(*args, **kwargs)

View File

@ -19,9 +19,8 @@ from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -211,17 +210,8 @@ class ForeignDataWrapperView(PGChildNodeView):
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid']) self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser # Set the template path for the SQL scripts
if not self.conn.connected(): if self.manager.version >= 90300:
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
ver = self.manager.version
# we will set template path for sql scripts
if ver >= 90300:
self.template_path = 'foreign_data_wrappers/sql/9.3_plus' self.template_path = 'foreign_data_wrappers/sql/9.3_plus'
else: else:
self.template_path = 'foreign_data_wrappers/sql/9.1_plus' self.template_path = 'foreign_data_wrappers/sql/9.1_plus'

View File

@ -19,9 +19,8 @@ from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -204,18 +203,8 @@ class ForeignServerView(PGChildNodeView):
self = args[0] self = args[0]
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid']) self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# Set the template path for the SQL scripts
# If DB not connected then return error to browser if self.manager.version >= 90300:
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
ver = self.manager.version
# we will set template path for sql scripts
if ver >= 90300:
self.template_path = 'foreign_servers/sql/9.3_plus' self.template_path = 'foreign_servers/sql/9.3_plus'
else: else:
self.template_path = 'foreign_servers/sql/9.1_plus' self.template_path = 'foreign_servers/sql/9.1_plus'

View File

@ -17,9 +17,8 @@ from flask import render_template, make_response, request, jsonify
from flask_babel import gettext from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -219,21 +218,9 @@ class UserMappingView(PGChildNodeView):
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid']) self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser # Set the template path for the SQL scripts
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
self.template_path = 'user_mappings/sql/9.1_plus' self.template_path = 'user_mappings/sql/9.1_plus'
ver = self.manager.version
# we will set template path for sql scripts
if ver >= 90100:
self.template_path = 'user_mappings/sql/9.1_plus'
return f(*args, **kwargs) return f(*args, **kwargs)
return wrap return wrap

View File

@ -19,9 +19,8 @@ from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -229,18 +228,8 @@ class LanguageView(PGChildNodeView):
self.driver = get_driver(PG_DEFAULT_DRIVER) self.driver = get_driver(PG_DEFAULT_DRIVER)
self.manager = self.driver.connection_manager(kwargs['sid']) self.manager = self.driver.connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# Set the template path for the SQL scripts
# If DB not connected then return error to browser if self.manager.version >= 90300:
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
ver = self.manager.version
# we will set template path for sql scripts
if ver >= 90300:
self.template_path = 'languages/sql/9.3_plus' self.template_path = 'languages/sql/9.3_plus'
else: else:
self.template_path = 'languages/sql/9.1_plus' self.template_path = 'languages/sql/9.1_plus'

View File

@ -18,10 +18,8 @@ from pgadmin.browser.collection import CollectionNodeModule, PGChildModule
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error, gone, \ make_response as ajax_response, gone, bad_request
bad_request
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -129,13 +127,7 @@ def check_precondition(f):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser # Set the template path for the SQL scripts
if not self.conn.connected():
return precondition_required(
gettext("Connection to the server has been lost!")
)
# Set template path for sql scripts
self.template_path = self.template_initial + '/' + ( self.template_path = self.template_initial + '/' + (
self.ppas_template_path(self.manager.version) self.ppas_template_path(self.manager.version)
if self.manager.server_type == 'ppas' else if self.manager.server_type == 'ppas' else

View File

@ -17,9 +17,8 @@ from flask_babel import gettext
from pgadmin.browser.server_groups.servers.databases.schemas.utils \ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
import SchemaChildModule import SchemaChildModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -146,14 +145,6 @@ class CatalogObjectView(PGChildNodeView):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
self.template_path = 'catalog_object/sql/{0}/9.1_plus'.format( self.template_path = 'catalog_object/sql/{0}/9.1_plus'.format(
'ppas' if self.manager.server_type == 'ppas' else 'pg' 'ppas' if self.manager.server_type == 'ppas' else 'pg'
) )

View File

@ -16,9 +16,8 @@ from flask import render_template
from flask_babel import gettext from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from pgadmin.utils.preferences import Preferences from pgadmin.utils.preferences import Preferences
@ -166,14 +165,6 @@ class CatalogObjectColumnsView(PGChildNodeView):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
self.template_path = 'catalog_object_column/sql/9.1_plus' self.template_path = 'catalog_object_column/sql/9.1_plus'
return f(*args, **kwargs) return f(*args, **kwargs)

View File

@ -18,9 +18,8 @@ from flask_babel import gettext
from pgadmin.browser.server_groups.servers.databases.schemas.utils \ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
import SchemaChildModule import SchemaChildModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -185,18 +184,10 @@ class CollationView(PGChildNodeView):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser # Set the template path for the SQL scripts
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
# we will set template path for sql scripts
self.template_path = 'collation/sql/9.1_plus' self.template_path = 'collation/sql/9.1_plus'
return f(*args, **kwargs)
return f(*args, **kwargs)
return wrap return wrap
@check_precondition @check_precondition

View File

@ -20,9 +20,8 @@ from pgadmin.browser.server_groups.servers.databases.schemas.utils import \
from pgadmin.browser.server_groups.servers.databases.utils import \ from pgadmin.browser.server_groups.servers.databases.utils import \
parse_sec_labels_from_db parse_sec_labels_from_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error, gone make_response as ajax_response, gone
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -263,18 +262,10 @@ class DomainView(PGChildNodeView, DataTypeReader):
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.qtIdent = driver.qtIdent self.qtIdent = driver.qtIdent
if not self.conn.connected():
return precondition_required(
gettext("Connection to the server has been lost!")
)
ver = self.manager.version
server_type = self.manager.server_type
# we will set template path for sql scripts # we will set template path for sql scripts
if ver >= 90200: if self.manager.version >= 90200:
self.template_path = 'domains/sql/9.2_plus' self.template_path = 'domains/sql/9.2_plus'
elif ver >= 90100: else:
self.template_path = 'domains/sql/9.1_plus' self.template_path = 'domains/sql/9.1_plus'
return f(*args, **kwargs) return f(*args, **kwargs)

View File

@ -18,9 +18,8 @@ from flask import render_template, make_response, request, jsonify
from flask_babel import gettext from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -256,22 +255,13 @@ class DomainConstraintView(PGChildNodeView):
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.qtIdent = driver.qtIdent self.qtIdent = driver.qtIdent
# If DB not connected then return error to browser # Set the template path for the SQL scripts
if not self.conn.connected(): if self.manager.version >= 90200:
return precondition_required(
gettext("Connection to the server has been lost!")
)
ver = self.manager.version
# we will set template path for sql scripts
if ver >= 90200:
self.template_path = 'domain_constraints/sql/9.2_plus' self.template_path = 'domain_constraints/sql/9.2_plus'
elif ver >= 90100: else:
self.template_path = 'domain_constraints/sql/9.1_plus' self.template_path = 'domain_constraints/sql/9.1_plus'
return f(*args, **kwargs) return f(*args, **kwargs)
return wrap return wrap
@check_precondition @check_precondition

View File

@ -25,9 +25,8 @@ from pgadmin.browser.server_groups.servers.databases.utils import \
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error, gone make_response as ajax_response, gone
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -338,16 +337,8 @@ class ForeignTableView(PGChildNodeView, DataTypeReader):
# Get database connection # Get database connection
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.qtIdent = driver.qtIdent self.qtIdent = driver.qtIdent
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
ver = self.manager.version ver = self.manager.version
# Set template path for sql scripts depending # Set template path for sql scripts depending
# on the server version. # on the server version.
@ -360,7 +351,6 @@ class ForeignTableView(PGChildNodeView, DataTypeReader):
self.template_path = 'foreign_tables/sql/9.1_plus' self.template_path = 'foreign_tables/sql/9.1_plus'
return f(*args, **kwargs) return f(*args, **kwargs)
return wrap return wrap
@check_precondition @check_precondition

View File

@ -18,9 +18,8 @@ from flask_babel import gettext as _
from pgadmin.browser.server_groups.servers.databases.schemas.utils \ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
import SchemaChildModule import SchemaChildModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error, gone make_response as ajax_response, gone
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -230,17 +229,10 @@ class FtsConfigurationView(PGChildNodeView):
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager( self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
kwargs['sid']) kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser # Set the template path for the SQL scripts
if not self.conn.connected(): self.template_path = 'fts_configuration/sql/9.1_plus'
return precondition_required(
_("Connection to the server has been lost!")
)
# we will set template path for sql scripts depending upon server version
ver = self.manager.version
if ver >= 90100:
self.template_path = 'fts_configuration/sql/9.1_plus'
return f(*args, **kwargs)
return f(*args, **kwargs)
return wrap return wrap
@check_precondition @check_precondition
@ -741,7 +733,6 @@ class FtsConfigurationView(PGChildNodeView):
:param scid: schema id :param scid: schema id
""" """
# Fetch last system oid # Fetch last system oid
datlastsysoid = self.manager.db_info[did]['datlastsysoid']
sql = render_template( sql = render_template(
"/".join([self.template_path, 'parser.sql']), "/".join([self.template_path, 'parser.sql']),
@ -752,6 +743,8 @@ class FtsConfigurationView(PGChildNodeView):
if not status: if not status:
return internal_server_error(errormsg=rset) return internal_server_error(errormsg=rset)
datlastsysoid = self.manager.db_info[did]['datlastsysoid']
# Empty set is added before actual list as initially it will be visible # Empty set is added before actual list as initially it will be visible
# at parser control while creating a new FTS Configuration # at parser control while creating a new FTS Configuration
res = [{'label': '', 'value': ''}] res = [{'label': '', 'value': ''}]
@ -776,8 +769,6 @@ class FtsConfigurationView(PGChildNodeView):
:param scid: schema id :param scid: schema id
""" """
# Fetch last system oid # Fetch last system oid
datlastsysoid = self.manager.db_info[did]['datlastsysoid']
sql = render_template( sql = render_template(
"/".join([self.template_path, 'copy_config.sql']), "/".join([self.template_path, 'copy_config.sql']),
copy_config=True copy_config=True
@ -787,6 +778,8 @@ class FtsConfigurationView(PGChildNodeView):
if not status: if not status:
return internal_server_error(errormsg=rset) return internal_server_error(errormsg=rset)
datlastsysoid = self.manager.db_info[did]['datlastsysoid']
# Empty set is added before actual list as initially it will be visible # Empty set is added before actual list as initially it will be visible
# at copy_config control while creating a new FTS Configuration # at copy_config control while creating a new FTS Configuration
res = [{'label': '', 'value': ''}] res = [{'label': '', 'value': ''}]

View File

@ -18,9 +18,8 @@ from flask_babel import gettext as _
from pgadmin.browser.server_groups.servers.databases.schemas.utils \ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
import SchemaChildModule import SchemaChildModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error, gone make_response as ajax_response, gone
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -222,17 +221,10 @@ class FtsDictionaryView(PGChildNodeView):
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager( self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
kwargs['sid']) kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser # Set the template path for the SQL scripts
if not self.conn.connected(): self.template_path = 'fts_dictionary/sql/9.1_plus'
return precondition_required(
_("Connection to the server has been lost!")
)
# we will set template path for sql scripts depending upon server version
ver = self.manager.version
if ver >= 90100:
self.template_path = 'fts_dictionary/sql/9.1_plus'
return f(*args, **kwargs)
return f(*args, **kwargs)
return wrap return wrap
def tokenize_options(self, option_value): def tokenize_options(self, option_value):
@ -725,8 +717,6 @@ class FtsDictionaryView(PGChildNodeView):
:param scid: schema id :param scid: schema id
""" """
# Fetch last system oid # Fetch last system oid
datlastsysoid = self.manager.db_info[did]['datlastsysoid']
sql = render_template("/".join([self.template_path, 'templates.sql']), sql = render_template("/".join([self.template_path, 'templates.sql']),
template=True) template=True)
status, rset = self.conn.execute_dict(sql) status, rset = self.conn.execute_dict(sql)
@ -734,6 +724,7 @@ class FtsDictionaryView(PGChildNodeView):
if not status: if not status:
return internal_server_error(errormsg=rset) return internal_server_error(errormsg=rset)
datlastsysoid = self.manager.db_info[did]['datlastsysoid']
# Empty set is added before actual list as initially it will be visible # Empty set is added before actual list as initially it will be visible
# at template control while creating a new FTS Dictionary # at template control while creating a new FTS Dictionary
res = [{'label': '', 'value': ''}] res = [{'label': '', 'value': ''}]

View File

@ -17,9 +17,8 @@ from flask_babel import gettext as _
from pgadmin.browser.server_groups.servers.databases import DatabaseModule from pgadmin.browser.server_groups.servers.databases import DatabaseModule
from pgadmin.browser.server_groups.servers.databases.schemas.utils import SchemaChildModule from pgadmin.browser.server_groups.servers.databases.schemas.utils import SchemaChildModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response, gone
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -220,19 +219,10 @@ class FtsParserView(PGChildNodeView):
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager( self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
kwargs['sid']) kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser # Set the template path for the SQL scripts
if not self.conn.connected(): self.template_path = 'fts_parser/sql/9.1_plus'
return precondition_required(
_(
"Connection to the server has been lost!"
)
)
# we will set template path for sql scripts depending upon server version
ver = self.manager.version
if ver >= 90100:
self.template_path = 'fts_parser/sql/9.1_plus'
return f(*args, **kwargs)
return f(*args, **kwargs)
return wrap return wrap
@check_precondition @check_precondition

View File

@ -17,9 +17,8 @@ from flask_babel import gettext
from pgadmin.browser.server_groups.servers.databases import DatabaseModule from pgadmin.browser.server_groups.servers.databases import DatabaseModule
from pgadmin.browser.server_groups.servers.databases.schemas.utils import SchemaChildModule from pgadmin.browser.server_groups.servers.databases.schemas.utils import SchemaChildModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response, gone
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -209,19 +208,9 @@ class FtsTemplateView(PGChildNodeView):
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager( self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
kwargs['sid']) kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser self.template_path = 'fts_template/sql/9.1_plus'
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
# we will set template path for sql scripts depending upon server version
ver = self.manager.version
if ver >= 90100:
self.template_path = 'fts_template/sql/9.1_plus'
return f(*args, **kwargs)
return f(*args, **kwargs)
return wrap return wrap
@check_precondition @check_precondition
@ -267,7 +256,6 @@ class FtsTemplateView(PGChildNodeView):
@check_precondition @check_precondition
def node(self, gid, sid, did, scid, tid): def node(self, gid, sid, did, scid, tid):
res = []
sql = render_template( sql = render_template(
"/".join([self.template_path, 'nodes.sql']), "/".join([self.template_path, 'nodes.sql']),
tid=tid tid=tid
@ -286,6 +274,9 @@ class FtsTemplateView(PGChildNodeView):
), ),
status=200 status=200
) )
return gone(
_("Could not the requested FTS template.")
)
@check_precondition @check_precondition
def properties(self, gid, sid, did, scid, tid): def properties(self, gid, sid, did, scid, tid):
@ -609,9 +600,9 @@ class FtsTemplateView(PGChildNodeView):
:param scid: schema id :param scid: schema id
:param tid: fts tempate id :param tid: fts tempate id
""" """
data = request.args sql = render_template(
sql = render_template("/".join([self.template_path, 'functions.sql']), "/".join([self.template_path, 'functions.sql']), lexize=True
lexize=True) )
status, rset = self.conn.execute_dict(sql) status, rset = self.conn.execute_dict(sql)
if not status: if not status:
@ -638,9 +629,9 @@ class FtsTemplateView(PGChildNodeView):
:param scid: schema id :param scid: schema id
:param tid: fts tempate id :param tid: fts tempate id
""" """
data = request.args sql = render_template(
sql = render_template("/".join([self.template_path, 'functions.sql']), "/".join([self.template_path, 'functions.sql']), init=True
init=True) )
status, rset = self.conn.execute_dict(sql) status, rset = self.conn.execute_dict(sql)
if not status: if not status:

View File

@ -27,9 +27,8 @@ from pgadmin.browser.server_groups.servers.databases.utils import \
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error, gone make_response as ajax_response, gone
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -329,21 +328,12 @@ class FunctionView(PGChildNodeView, DataTypeReader):
# Get database connection # Get database connection
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.qtIdent = driver.qtIdent self.qtIdent = driver.qtIdent
self.qtLiteral = driver.qtLiteral self.qtLiteral = driver.qtLiteral
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
ver = self.manager.version ver = self.manager.version
# Set template path for sql scripts depending # Set the template path for the SQL scripts
# on the server version.
self.template_path = "/".join([ self.template_path = "/".join([
self.node_type self.node_type
]) ])
@ -469,10 +459,9 @@ class FunctionView(PGChildNodeView, DataTypeReader):
proallargtypes = data['proallargtypes'] \ proallargtypes = data['proallargtypes'] \
if data['proallargtypes'] else [] if data['proallargtypes'] else []
proargout = [] proargmodenames = {
proargid = [] 'i': 'IN', 'o': 'OUT', 'b': 'INOUT', 'v': 'VARIADIC', 't': 'TABLE'
proargmodenames = {'i': 'IN', 'o': 'OUT', 'b': 'INOUT', }
'v': 'VARIADIC', 't': 'TABLE'}
# The proargtypes doesn't give OUT params, so we need to fetch # The proargtypes doesn't give OUT params, so we need to fetch
# those from database explicitly, below code is written for this # those from database explicitly, below code is written for this
@ -1325,7 +1314,6 @@ It may have been removed by another user or moved to another schema.
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
func_def = res['rows'][0]['func_def']
name = res['rows'][0]['name'] name = res['rows'][0]['name']
# Fetch only arguments # Fetch only arguments

View File

@ -20,9 +20,8 @@ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -145,20 +144,11 @@ class SequenceView(PGChildNodeView):
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
else: else:
self.conn = self.manager.connection() self.conn = self.manager.connection()
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
_(
"Connection to the server has been lost!"
)
)
self.template_path = 'sequence/sql/9.1_plus' self.template_path = 'sequence/sql/9.1_plus'
self.acl = ['r', 'w', 'U'] self.acl = ['r', 'w', 'U']
return f(self, *args, **kwargs) return f(self, *args, **kwargs)
return wrapped return wrapped
return wrap return wrap
@check_precondition(action='list') @check_precondition(action='list')
@ -336,10 +326,10 @@ class SequenceView(PGChildNodeView):
# We need oid of newly created sequence. # We need oid of newly created sequence.
SQL = render_template("/".join([self.template_path, 'get_oid.sql']), name=data['name'], scid=scid) SQL = render_template("/".join([self.template_path, 'get_oid.sql']), name=data['name'], scid=scid)
SQL = SQL.strip('\n').strip(' ') SQL = SQL.strip('\n').strip(' ')
if SQL and SQL != "":
status, seid = self.conn.execute_scalar(SQL) status, seid = self.conn.execute_scalar(SQL)
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=seid)
return jsonify( return jsonify(
node=self.blueprint.generate_browser_node( node=self.blueprint.generate_browser_node(
@ -504,18 +494,13 @@ class SequenceView(PGChildNodeView):
"Could not find the required parameter (%s)." % arg "Could not find the required parameter (%s)." % arg
) )
) )
try: SQL = self.getSQL(gid, sid, did, data, scid, seid)
SQL = self.getSQL(gid, sid, did, data, scid, seid) SQL = SQL.strip('\n').strip(' ')
SQL = SQL.strip('\n').strip(' ')
return make_json_response( return make_json_response(
data=SQL, data=SQL,
status=200 status=200
) )
except Exception as e:
return make_json_response(
data="-- modified SQL",
status=200
)
def getSQL(self, gid, sid, did, data, scid, seid=None): def getSQL(self, gid, sid, did, data, scid, seid=None):
""" """

View File

@ -22,9 +22,8 @@ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -272,22 +271,18 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
# Here args[0] will hold self & kwargs will hold gid,sid,did # Here args[0] will hold self & kwargs will hold gid,sid,did
self = args[0] self = args[0]
driver = get_driver(PG_DEFAULT_DRIVER) driver = get_driver(PG_DEFAULT_DRIVER)
did = kwargs['did']
self.manager = driver.connection_manager(kwargs['sid']) self.manager = driver.connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.qtIdent = driver.qtIdent self.qtIdent = driver.qtIdent
# We need datlastsysoid to check if current table is system table # We need datlastsysoid to check if current table is system table
self.datlastsysoid = self.manager.db_info[kwargs['did']]['datlastsysoid'] self.datlastsysoid = self.manager.db_info[
self.server_type = self.manager.server_type did
# If DB not connected then return error to browser ]['datlastsysoid'] if self.manager.db_info is not None and \
if not self.conn.connected(): did in self.manager.db_info else 0
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
# we will set template path for sql scripts
ver = self.manager.version ver = self.manager.version
# Template for Column node # Set the template path for the SQL scripts
if ver >= 90500: if ver >= 90500:
self.template_path = 'table/sql/9.5_plus' self.template_path = 'table/sql/9.5_plus'
else: else:
@ -1193,7 +1188,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
try: try:
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'get_oftype.sql']), scid=scid, 'get_oftype.sql']), scid=scid,
server_type=self.server_type, server_type=self.manager.server_type,
show_sys_objects=self.blueprint.show_system_objects) show_sys_objects=self.blueprint.show_system_objects)
status, rset = self.conn.execute_2darray(SQL) status, rset = self.conn.execute_2darray(SQL)
if not status: if not status:
@ -1224,7 +1219,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
SQL = render_template("/".join([self.template_path, 'get_inherits.sql']), SQL = render_template("/".join([self.template_path, 'get_inherits.sql']),
show_system_objects=self.blueprint.show_system_objects, show_system_objects=self.blueprint.show_system_objects,
tid=tid, tid=tid,
server_type=self.server_type) server_type=self.manager.server_type)
status, rset = self.conn.execute_2darray(SQL) status, rset = self.conn.execute_2darray(SQL)
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
@ -1253,7 +1248,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
try: try:
SQL = render_template("/".join([self.template_path, 'get_relations.sql']), SQL = render_template("/".join([self.template_path, 'get_relations.sql']),
show_sys_objects=self.blueprint.show_system_objects, show_sys_objects=self.blueprint.show_system_objects,
server_type=self.server_type) server_type=self.manager.server_type)
status, rset = self.conn.execute_2darray(SQL) status, rset = self.conn.execute_2darray(SQL)
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)

View File

@ -21,9 +21,8 @@ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -199,17 +198,9 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.qtIdent = driver.qtIdent self.qtIdent = driver.qtIdent
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
ver = self.manager.version # Set the template path for the SQL scripts
# we will set template path for sql scripts if self.manager.version >= 90200:
if ver >= 90200:
self.template_path = 'column/sql/9.2_plus' self.template_path = 'column/sql/9.2_plus'
else: else:
self.template_path = 'column/sql/9.1_plus' self.template_path = 'column/sql/9.1_plus'

View File

@ -19,9 +19,8 @@ from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.server_groups.servers.databases.schemas.tables.constraints.type \ from pgadmin.browser.server_groups.servers.databases.schemas.tables.constraints.type \
import ConstraintRegistry import ConstraintRegistry
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -208,15 +207,8 @@ class CheckConstraintView(PGChildNodeView):
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.qtIdent = driver.qtIdent self.qtIdent = driver.qtIdent
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
_("Connection to the server has been lost!")
)
ver = self.manager.version ver = self.manager.version
# Set the template path for the SQL scripts
# we will set template path for sql scripts
if ver >= 90200: if ver >= 90200:
self.template_path = 'check_constraint/sql/9.2_plus' self.template_path = 'check_constraint/sql/9.2_plus'
elif ver >= 90100: elif ver >= 90100:

View File

@ -18,9 +18,8 @@ from flask_babel import gettext as _
from pgadmin.browser.server_groups.servers.databases.schemas.tables.constraints.type \ from pgadmin.browser.server_groups.servers.databases.schemas.tables.constraints.type \
import ConstraintRegistry, ConstraintTypeModule import ConstraintRegistry, ConstraintTypeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -216,16 +215,7 @@ class ExclusionConstraintView(PGChildNodeView):
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
_(
"Connection to the server has been lost!"
)
)
ver = self.manager.version ver = self.manager.version
if ver >= 90200: if ver >= 90200:
self.template_path = 'exclusion_constraint/sql/9.2_plus' self.template_path = 'exclusion_constraint/sql/9.2_plus'
elif ver >= 90100: elif ver >= 90100:
@ -242,8 +232,8 @@ class ExclusionConstraintView(PGChildNodeView):
for row in rset['rows']: for row in rset['rows']:
self.schema = row['schema'] self.schema = row['schema']
self.table = row['table'] self.table = row['table']
return f(*args, **kwargs)
return f(*args, **kwargs)
return wrap return wrap
def end_transaction(self): def end_transaction(self):

View File

@ -18,9 +18,8 @@ from flask_babel import gettext as _
from pgadmin.browser.server_groups.servers.databases.schemas.tables.constraints.type \ from pgadmin.browser.server_groups.servers.databases.schemas.tables.constraints.type \
import ConstraintRegistry, ConstraintTypeModule import ConstraintRegistry, ConstraintTypeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -194,7 +193,7 @@ class ForeignKeyConstraintView(PGChildNodeView):
], ],
'delete': [{'delete': 'delete'}], 'delete': [{'delete': 'delete'}],
'children': [{'get': 'children'}], 'children': [{'get': 'children'}],
'nodes': [{'get': 'node'}, {'get': 'nodes'}], 'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
'sql': [{'get': 'sql'}], 'sql': [{'get': 'sql'}],
'msql': [{'get': 'msql'}, {'get': 'msql'}], 'msql': [{'get': 'msql'}, {'get': 'msql'}],
'stats': [{'get': 'statistics'}], 'stats': [{'get': 'statistics'}],
@ -234,16 +233,8 @@ class ForeignKeyConstraintView(PGChildNodeView):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
_(
"Connection to the server has been lost!"
)
)
self.template_path = 'foreign_key/sql' self.template_path = 'foreign_key/sql'
# We need parent's name eg table name and schema name # We need parent's name eg table name and schema name
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'get_parent.sql']), 'get_parent.sql']),
@ -255,8 +246,8 @@ class ForeignKeyConstraintView(PGChildNodeView):
for row in rset['rows']: for row in rset['rows']:
self.schema = row['schema'] self.schema = row['schema']
self.table = row['table'] self.table = row['table']
return f(*args, **kwargs)
return f(*args, **kwargs)
return wrap return wrap
def end_transaction(self): def end_transaction(self):
@ -398,31 +389,8 @@ class ForeignKeyConstraintView(PGChildNodeView):
Returns: Returns:
""" """
try: res = self.get_nodes(gid, sid, did, scid, tid, fkid)
res = self.get_nodes(gid, sid, did, scid, tid, fkid)
return make_json_response(
data=res,
status=200
)
except Exception as e:
return internal_server_error(errormsg=str(e))
@check_precondition
def get_nodes(self, gid, sid, did, scid, tid, fkid=None):
"""
This function returns all event trigger nodes as a list.
Args:
gid: Server Group ID
sid: Server ID
did: Database ID
scid: Schema ID
tid: Table ID
fkid: Foreign key constraint ID
Returns:
"""
res = [] res = []
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'nodes.sql']), 'nodes.sql']),
@ -444,7 +412,11 @@ class ForeignKeyConstraintView(PGChildNodeView):
icon=icon, icon=icon,
valid=valid valid=valid
)) ))
return res
return make_json_response(
data=res,
status=200
)
@check_precondition @check_precondition
def create(self, gid, sid, did, scid, tid, fkid=None): def create(self, gid, sid, did, scid, tid, fkid=None):

View File

@ -18,9 +18,8 @@ from flask_babel import gettext as _
from pgadmin.browser.server_groups.servers.databases.schemas.tables.constraints.type \ from pgadmin.browser.server_groups.servers.databases.schemas.tables.constraints.type \
import ConstraintRegistry, ConstraintTypeModule import ConstraintRegistry, ConstraintTypeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -237,16 +236,8 @@ class IndexConstraintView(PGChildNodeView):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
_(
"Connection to the server has been lost!"
)
)
self.template_path = 'index_constraint/sql' self.template_path = 'index_constraint/sql'
# We need parent's name eg table name and schema name # We need parent's name eg table name and schema name
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'get_parent.sql']), 'get_parent.sql']),

View File

@ -1,7 +1,7 @@
define( define(
[ [
'jquery', 'underscore', 'underscore.string', 'pgadmin', 'pgadmin.browser', 'jquery', 'underscore', 'underscore.string', 'pgadmin', 'pgadmin.browser',
'pgadmin.browser.collection'{% for c in constraints %}, 'pgadmin.node.{{ c|safe }}'{%endfor%} 'pgadmin.browser.collection'{% for c in constraints %}, 'pgadmin.node.{{ c }}'{%endfor%}
], ],
function($, _, S, pgAdmin, pgBrowser) { function($, _, S, pgAdmin, pgBrowser) {
@ -51,4 +51,4 @@ function($, _, S, pgAdmin, pgBrowser) {
} }
return pgBrowser.Nodes['constraints']; return pgBrowser.Nodes['constraints'];
}); });

View File

@ -17,9 +17,8 @@ from flask import render_template, request, jsonify
from flask_babel import gettext from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -69,13 +68,6 @@ class IndexesModule(CollectionNodeModule):
""" """
if super(IndexesModule, self).BackendSupported(manager, **kwargs): if super(IndexesModule, self).BackendSupported(manager, **kwargs):
conn = manager.connection(did=kwargs['did']) conn = manager.connection(did=kwargs['did'])
# If DB is not connected then return error to browser
if not conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
if 'vid' not in kwargs: if 'vid' not in kwargs:
return True return True
@ -228,16 +220,11 @@ class IndexesView(PGChildNodeView):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
# We need datlastsysoid to check if current index is system index # We need datlastsysoid to check if current index is system index
self.datlastsysoid = self.manager.db_info[kwargs['did']]['datlastsysoid'] self.datlastsysoid = self.manager.db_info[
kwargs['did']
]['datlastsysoid'] if self.manager.db_info is not None and \
kwargs['did'] in self.manager.db_info else 0
# we will set template path for sql scripts # we will set template path for sql scripts
self.template_path = 'index/sql/9.1_plus' self.template_path = 'index/sql/9.1_plus'
@ -440,7 +427,6 @@ class IndexesView(PGChildNodeView):
# 'options' we need true/false to render switch ASC(false)/DESC(true) # 'options' we need true/false to render switch ASC(false)/DESC(true)
columns = [] columns = []
cols = [] cols = []
cnt = 1
for row in rset['rows']: for row in rset['rows']:
# We need all data as collection for ColumnsModel # We need all data as collection for ColumnsModel
cols_data = { cols_data = {

View File

@ -19,9 +19,8 @@ from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.server_groups.servers.databases.schemas.utils import \ from pgadmin.browser.server_groups.servers.databases.schemas.utils import \
parse_rule_definition parse_rule_definition
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -53,13 +52,6 @@ class RuleModule(CollectionNodeModule):
""" """
if super(RuleModule, self).BackendSupported(manager, **kwargs): if super(RuleModule, self).BackendSupported(manager, **kwargs):
conn = manager.connection(did=kwargs['did']) conn = manager.connection(did=kwargs['did'])
# If DB is not connected then return error to browser
if not conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
if 'vid' not in kwargs: if 'vid' not in kwargs:
return True return True
@ -202,16 +194,10 @@ class RuleView(PGChildNodeView):
self.manager = get_driver( self.manager = get_driver(
PG_DEFAULT_DRIVER).connection_manager(kwargs['sid']) PG_DEFAULT_DRIVER).connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
self.datlastsysoid = self.manager.db_info[
# If DB not connected then return error to browser kwargs['did']
if not self.conn.connected(): ]['datlastsysoid'] if self.manager.db_info is not None and \
return precondition_required( kwargs['did'] in self.manager.db_info else 0
gettext(
"Connection to the server has been lost!"
)
)
self.datlastsysoid = self.manager.db_info[kwargs['did']]['datlastsysoid']
self.template_path = 'rules/sql' self.template_path = 'rules/sql'
return f(*args, **kwargs) return f(*args, **kwargs)

View File

@ -4,4 +4,4 @@ SELECT ct.oid,
FROM pg_constraint ct FROM pg_constraint ct
WHERE contype='f' AND WHERE contype='f' AND
conrelid = {{tid}}::oid conrelid = {{tid}}::oid
ORDER BY conname ORDER BY conname

View File

@ -17,9 +17,8 @@ from flask import render_template, request, jsonify
from flask_babel import gettext from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -69,24 +68,21 @@ class TriggerModule(CollectionNodeModule):
""" """
if super(TriggerModule, self).BackendSupported(manager, **kwargs): if super(TriggerModule, self).BackendSupported(manager, **kwargs):
conn = manager.connection(did=kwargs['did']) conn = manager.connection(did=kwargs['did'])
# If DB is not connected then return error to browser
if not conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
if 'vid' not in kwargs: if 'vid' not in kwargs:
return True return True
template_path = 'trigger/sql/9.1_plus' template_path = 'trigger/sql/9.1_plus'
SQL = render_template("/".join( SQL = render_template("/".join(
[template_path, 'backend_support.sql']), vid=kwargs['vid']) [template_path, 'backend_support.sql']), vid=kwargs['vid']
)
status, res = conn.execute_scalar(SQL) status, res = conn.execute_scalar(SQL)
# check if any errors # check if any errors
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
# Check vid is view not material view # Check vid is view not material view
# then true, othewise false # then true, othewise false
return res return res
@ -255,16 +251,11 @@ class TriggerView(PGChildNodeView):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
# We need datlastsysoid to check if current trigger is system trigger # We need datlastsysoid to check if current trigger is system trigger
self.datlastsysoid = self.manager.db_info[kwargs['did']]['datlastsysoid'] self.datlastsysoid = self.manager.db_info[
kwargs['did']
]['datlastsysoid'] if self.manager.db_info is not None and \
kwargs['did'] in self.manager.db_info else 0
# we will set template path for sql scripts # we will set template path for sql scripts
self.template_path = 'trigger/sql/9.1_plus' self.template_path = 'trigger/sql/9.1_plus'

View File

@ -20,9 +20,8 @@ from pgadmin.browser.server_groups.servers.databases.schemas.utils \
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
parse_priv_to_db parse_priv_to_db
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error make_response as ajax_response
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -223,15 +222,10 @@ class TypeView(PGChildNodeView, DataTypeReader):
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# We need datlastsysoid to check if current type is system type # We need datlastsysoid to check if current type is system type
self.datlastsysoid = self.manager.db_info[kwargs['did']]['datlastsysoid'] self.datlastsysoid = self.manager.db_info[
kwargs['did']
# If DB not connected then return error to browser ]['datlastsysoid'] if self.manager.db_info is not None and \
if not self.conn.connected(): kwargs['did'] in self.manager.db_info else 0
return precondition_required(
gettext(
"Connection to the server has been lost!"
)
)
# Declare allows acl on type # Declare allows acl on type
self.acl = ['U'] self.acl = ['U']
@ -240,7 +234,6 @@ class TypeView(PGChildNodeView, DataTypeReader):
self.template_path = 'type/sql/9.1_plus' self.template_path = 'type/sql/9.1_plus'
return f(*args, **kwargs) return f(*args, **kwargs)
return wrap return wrap
@check_precondition @check_precondition

View File

@ -18,10 +18,8 @@ from flask_babel import gettext
from pgadmin.browser.server_groups.servers.databases.schemas.utils import \ from pgadmin.browser.server_groups.servers.databases.schemas.utils import \
SchemaChildModule, parse_rule_definition, VacuumSettings SchemaChildModule, parse_rule_definition, VacuumSettings
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
make_response as ajax_response, internal_server_error, \ make_response as ajax_response, bad_request
bad_request
from pgadmin.utils.ajax import precondition_required
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
@ -171,13 +169,10 @@ def check_precondition(f):
kwargs['sid'] kwargs['sid']
) )
self.conn = self.manager.connection(did=kwargs['did']) self.conn = self.manager.connection(did=kwargs['did'])
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
gettext("Connection to the server has been lost!")
)
self.datlastsysoid = self.manager.db_info[ self.datlastsysoid = self.manager.db_info[
kwargs['did']]['datlastsysoid'] kwargs['did']
]['datlastsysoid'] if self.manager.db_info is not None and \
kwargs['did'] in self.manager.db_info else 0
# Set template path for sql scripts # Set template path for sql scripts
self.template_path = self.template_initial + '/' + ( self.template_path = self.template_initial + '/' + (

View File

@ -69,6 +69,11 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
category: 'drop', priority: 5, label: '{{ _('Disconnect Database...') }}', category: 'drop', priority: 5, label: '{{ _('Disconnect Database...') }}',
icon: 'fa fa-chain-broken', enable : 'is_connected' icon: 'fa fa-chain-broken', enable : 'is_connected'
}]); }]);
_.bindAll(this, 'connection_lost');
pgBrowser.Events.on(
'pgadmin:database:connection:lost', this.connection_lost
);
}, },
can_create_database: function(node, item) { can_create_database: function(node, item) {
var treeData = this.getTreeNodeHierarchy(item), var treeData = this.getTreeNodeHierarchy(item),
@ -82,6 +87,67 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
is_connected: function(node) { is_connected: function(node) {
return (node && node.connected == true && node.canDisconn == true); return (node && node.connected == true && node.canDisconn == true);
}, },
connection_lost: function(i, resp, server_connected) {
if (pgBrowser.tree) {
var t = pgBrowser.tree,
info = i && this.getTreeNodeHierarchy(i),
s = null,
d = i && t.itemData(i),
self = this,
_i = i;
while (d && d._type != 'database') {
i = t.parent(i);
d = i && t.itemData(i);
}
if (i && d) {
if (_.isUndefined(d.is_connecting) || !d.is_connecting) {
d.is_connecting = true;
var disconnect = function(_i, _d) {
if (_d._id == this._id) {
d.is_connecting = false;
pgBrowser.Events.off(
'pgadmin:database:connect:cancelled', disconnect
);
_i = _i && t.parent(_i);
_d = _i && t.itemData(_i);
if (_i && _d) {
pgBrowser.Events.trigger(
'pgadmin:server:disconnect',
{item: _i, data: _d}, false
);
}
}
};
pgBrowser.Events.on(
'pgadmin:database:connect:cancelled', disconnect
);
if (server_connected) {
connect(self, d, t, i, true);
return;
}
Alertify.confirm(
'{{ _('Connection lost') }}',
'{{ _('Would you like to reconnect to the database?') }}',
function() {
connect(self, d, t, i, true);
},
function() {
d.is_connecting = false;
t.unload(i);
t.setInode(i);
t.addIcon(i, {icon: 'icon-database-not-connected'});
pgBrowser.Events.trigger(
'pgadmin:database:connect:cancelled', i, d, self
);
});
}
}
}
},
callbacks: { callbacks: {
/* Connect the database */ /* Connect the database */
connect_database: function(args){ connect_database: function(args){
@ -374,58 +440,91 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
return null; return null;
} }
}) })
}); });
function connect_to_database(obj, data, tree, item, interactive) {
connect(obj, data, tree, item)
};
function connect(obj, data, tree, item) {
var onFailure = function(xhr, status, error, _model, _data, _tree, _item) {
tree.setInode(_item); function connect_to_database(obj, data, tree, item, interactive) {
tree.addIcon(_item, {icon: 'icon-database-not-connected'}); connect(obj, data, tree, item)
}
Alertify.pgNotifier('error', xhr, error, function(msg) { function connect(obj, data, tree, item, _wasConnected) {
setTimeout(function() { var wasConnected = _wasConnected || data.connected,
Alertify.dlgServerPass( onFailure = function(
'{{ _('Connect to database') }}', xhr, status, error, _model, _data, _tree, _item, _status
msg, _model, _data, _tree, _item ) {
).resizeTo(); if (!_status) {
}, 100); tree.setInode(_item);
}); tree.addIcon(_item, {icon: 'icon-database-not-connected'});
},
onSuccess = function(res, model, data, tree, item) {
tree.deselect(item);
tree.setInode(item);
if (res && res.data) {
if(typeof res.data.connected == 'boolean') {
data.connected = res.data.connected;
}
if (typeof res.data.icon == 'string') {
tree.removeIcon(item);
data.icon = res.data.icon;
tree.addIcon(item, {icon: data.icon});
}
Alertify.success(res.info);
setTimeout(function() {tree.select(item);}, 10);
setTimeout(function() {tree.open(item);}, 100);
}
},
url = obj.generate_url(item, "connect", data, true);
$.post(url)
.done(
function(res) {
if (res.success == 1) {
return onSuccess(res, obj, data, tree, item);
} }
})
.fail(
function(xhr, status, error) {
return onFailure(xhr, status, error, obj, data, tree, item);
});
}
Alertify.pgNotifier('error', xhr, error, function(msg) {
setTimeout(function() {
Alertify.dlgServerPass(
'{{ _('Connect to database') }}',
msg, _model, _data, _tree, _item, _status,
onSuccess, onFailure, onCancel
).resizeTo();
}, 100);
});
},
onSuccess = function(
res, model, data, tree, item, connected
) {
data.is_connecting = false;
if (!connected) {
tree.deselect(item);
tree.setInode(item);
}
if (res && res.data) {
if(typeof res.data.connected == 'boolean') {
data.connected = res.data.connected;
}
if (typeof res.data.icon == 'string') {
tree.removeIcon(item);
data.icon = res.data.icon;
tree.addIcon(item, {icon: data.icon});
}
Alertify.success(res.info);
obj.trigger('connected', obj, item, data);
pgBrowser.Events.trigger(
'pgadmin:database:connected', item, data
);
if (!connected) {
setTimeout(function() {
tree.select(item);
tree.open(item);
}, 10);
}
}
},
onCancel = function(_tree, _item, _data, _status) {
_data.is_connecting = false;
var server = _tree.parent(_item);
_tree.unload(_item);
_tree.setInode(_item);
_tree.removeIcon(_item);
_tree.addIcon(_item, {icon: 'icon-database-not-connected'});
obj.trigger('connect:cancelled', obj, _item, _data);
pgBrowser.Events.trigger(
'pgadmin:database:connect:cancelled', _item, _data, obj
);
_tree.select(server);
};
$.post(
obj.generate_url(item, "connect", data, true)
).done(function(res) {
if (res.success == 1) {
return onSuccess(res, obj, data, tree, item, wasConnected);
}
}).fail(function(xhr, status, error) {
return onFailure(
xhr, status, error, obj, data, tree, item, wasConnected
);
});
}
} }
return pgBrowser.Nodes['coll-database']; return pgBrowser.Nodes['coll-database'];

View File

@ -102,6 +102,18 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
'{{ _('A grantee must be selected.') }}'; '{{ _('A grantee must be selected.') }}';
pgBrowser.messages['NO_PRIV_SELECTED'] = pgBrowser.messages['NO_PRIV_SELECTED'] =
'{{ _('At least one privilege should be selected.') }}'; '{{ _('At least one privilege should be selected.') }}';
pgBrowser.Events.on(
'pgadmin:server:disconnect', this.callbacks.disconnect_server
);
pgBrowser.Events.on(
'pgadmin:server:connect', this.callbacks.connect_server
);
_.bindAll(this, 'connection_lost');
pgBrowser.Events.on(
'pgadmin:server:connection:lost', this.connection_lost
);
}, },
is_not_connected: function(node) { is_not_connected: function(node) {
return (node && node.connected != true); return (node && node.connected != true);
@ -158,11 +170,11 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
if (!d) if (!d)
return false; return false;
connect_to_server(obj, d, t, i); connect_to_server(obj, d, t, i, false);
return false; return false;
}, },
/* Disconnect the server */ /* Disconnect the server */
disconnect_server: function(args) { disconnect_server: function(args, notify) {
var input = args || {}, var input = args || {},
obj = this, obj = this,
t = pgBrowser.tree, t = pgBrowser.tree,
@ -172,48 +184,60 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
if (!d) if (!d)
return false; return false;
alertify.confirm( notify = notify || _.isUndefined(notify) || _.isNull(notify);
'{{ _('Disconnect server') }}',
S('{{ _('Are you sure you want to disconnect the server %s?') }}').sprintf(d.label).value(), var disconnect = function() {
function(evt) { $.ajax({
$.ajax({ url: obj.generate_url(i, 'connect', d, true),
url: obj.generate_url(i, 'connect', d, true), type:'DELETE',
type:'DELETE', success: function(res) {
success: function(res) { if (res.success == 1) {
if (res.success == 1) { alertify.success(res.info);
alertify.success(res.info); d = t.itemData(i);
d = t.itemData(i); t.removeIcon(i);
t.removeIcon(i); d.connected = false;
d.connected = false; d.icon = 'icon-server-not-connected';
d.icon = 'icon-server-not-connected'; t.addIcon(i, {icon: d.icon});
t.addIcon(i, {icon: d.icon}); obj.callbacks.refresh.apply(obj, [null, i]);
obj.callbacks.refresh.apply(obj, [null, i]); if (pgBrowser.serverInfo && d._id in pgBrowser.serverInfo) {
if (pgBrowser.serverInfo && d._id in pgBrowser.serverInfo) { delete pgBrowser.serverInfo[d._id]
delete pgBrowser.serverInfo[d._id]
}
obj.trigger('server-disconnected', obj, i, d);
} }
else { obj.trigger('server-disconnected', obj, i, d);
try { }
alertify.error(res.errormsg); else {
} catch (e) {}
t.unload(i);
}
},
error: function(xhr, status, error) {
try { try {
var err = $.parseJSON(xhr.responseText); alertify.error(res.errormsg);
if (err.success == 0) {
alertify.error(err.errormsg);
}
} catch (e) {} } catch (e) {}
t.unload(i); t.unload(i);
} }
},
error: function(xhr, status, error) {
try {
var err = $.parseJSON(xhr.responseText);
if (err.success == 0) {
alertify.error(err.errormsg);
}
} catch (e) {}
t.unload(i);
}
});
};
if (notify) {
alertify.confirm(
'{{ _('Disconnect server') }}',
S('{{ _('Are you sure you want to disconnect the server %s?') }}').sprintf(
d.label
).value(),
function(evt) {
disconnect();
},
function(evt) {
return true;
}); });
}, } else {
function(evt) { disconnect();
return true; }
});
return false; return false;
}, },
@ -226,7 +250,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
pgBrowser.tree.addIcon(item, {icon: data.icon}); pgBrowser.tree.addIcon(item, {icon: data.icon});
if (!data.connected) { if (!data.connected) {
connect_to_server(this, data, pgBrowser.tree, item); connect_to_server(this, data, pgBrowser.tree, item, false);
return false; return false;
} }
@ -409,7 +433,6 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
} }
}, },
prepare: function() { prepare: function() {
//console.log(this.get('server').user.name);
var self = this; var self = this;
// Disable Backup button until user provides Filename // Disable Backup button until user provides Filename
this.__internal.buttons[0].element.disabled = true; this.__internal.buttons[0].element.disabled = true;
@ -487,13 +510,14 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
alertify.changeServerPassword(d).resizeTo('40%','52%'); alertify.changeServerPassword(d).resizeTo('40%','52%');
return false; return false;
}, },
/* Pause WAL Replay */ /* Pause WAL Replay */
pause_wal_replay: function(args) { pause_wal_replay: function(args) {
var input = args || {}; var input = args || {},
obj = this, obj = this,
t = pgBrowser.tree, t = pgBrowser.tree,
i = input.item || t.selected(), i = input.item || t.selected(),
d = i && i.length == 1 ? t.itemData(i) : undefined; d = i && i.length == 1 ? t.itemData(i) : undefined;
if (!d) if (!d)
return false; return false;
@ -528,13 +552,14 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
} }
}) })
}, },
/* Resume WAL Replay */ /* Resume WAL Replay */
resume_wal_replay: function(args) { resume_wal_replay: function(args) {
var input = args || {}; var input = args || {},
obj = this, obj = this,
t = pgBrowser.tree, t = pgBrowser.tree,
i = input.item || t.selected(), i = input.item || t.selected(),
d = i && i.length == 1 ? t.itemData(i) : undefined; d = i && i.length == 1 ? t.itemData(i) : undefined;
if (!d) if (!d)
return false; return false;
@ -709,66 +734,157 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
isConnected: function(model) { isConnected: function(model) {
return model.get('connected'); return model.get('connected');
} }
}) }),
}); connection_lost: function(i, resp) {
function connect_to_server(obj, data, tree, item) { if (pgBrowser.tree) {
var onFailure = function(xhr, status, error, _model, _data, _tree, _item) { var t = pgBrowser.tree,
info = i && this.getTreeNodeHierarchy(i),
s = null,
d = i && t.itemData(i),
self = this;
tree.setInode(_item); while (d && d._type != 'server') {
tree.addIcon(_item, {icon: 'icon-server-not-connected'}); i = t.parent(i);
d = i && t.itemData(i);
alertify.pgNotifier('error', xhr, error, function(msg) {
setTimeout(function() {
alertify.dlgServerPass(
'{{ _('Connect to Server') }}',
msg, _model, _data, _tree, _item
).resizeTo();
}, 100);
});
},
onSuccess = function(res, model, data, tree, item) {
tree.deselect(item);
tree.setInode(item);
if (res && res.data) {
if (typeof res.data.icon == 'string') {
tree.removeIcon(item);
data.icon = res.data.icon;
tree.addIcon(item, {icon: data.icon});
} }
// Update 'in_recovery' and 'wal_pause' options at server node if (i && d && d._type == 'server') {
tree.itemData(item).in_recovery=res.data.in_recovery; if (_.isUndefined(d.is_connecting) || !d.is_connecting) {
tree.itemData(item).wal_pause=res.data.wal_pause; d.is_connecting = true;
_.extend(data, res.data); var disconnect = function(_sid) {
if (d._id == _sid) {
d.is_connecting = false;
// Stop listening to the connection cancellation event
pgBrowser.Events.off(
'pgadmin:server:connect:cancelled', disconnect
);
var serverInfo = pgBrowser.serverInfo = pgBrowser.serverInfo || {}; // Connection to the database will also be cancelled
serverInfo[data._id] = _.extend({}, data); pgBrowser.Events.trigger(
'pgadmin:database:connect:cancelled',_sid,
resp.data.database || d.db
);
alertify.success(res.info); // Make sure - the server is disconnected properly
obj.trigger('server-connected', obj, item, data); pgBrowser.Events.trigger(
'pgadmin:server:disconnect',
setTimeout(function() { {item: _i, data: _d}, false
tree.select(item); );
tree.open(item); }
}, 10); };
// Listen for the server connection cancellation event
pgBrowser.Events.on(
'pgadmin:server:connect:cancelled', disconnect
);
alertify.confirm(
'{{ _('Connection lost') }}',
'{{ _('Would you like to reconnect to the database?') }}',
function() {
connect_to_server(self, d, t, i, true);
},
function() {
d.is_connecting = false;
t.unload(i);
t.setInode(i);
t.addIcon(i, {icon: 'icon-database-not-connected'});
pgBrowser.Events.trigger(
'pgadmin:server:connect:cancelled', i, d, self
);
t.select(i);
});
}
}
} }
}; }
});
function connect_to_server(obj, data, tree, item, reconnect) {
var wasConnected = reconnect || data.connected,
onFailure = function(
xhr, status, error, _node, _data, _tree, _item, _wasConnected
) {
data.connected = false;
// It should be attempt to reconnect.
// Let's not change the status of the tree node now.
if (!_wasConnected) {
tree.setInode(_item);
tree.addIcon(_item, {icon: 'icon-server-not-connected'});
}
alertify.pgNotifier('error', xhr, error, function(msg) {
setTimeout(function() {
alertify.dlgServerPass(
'{{ _('Connect to Server') }}',
msg, _node, _data, _tree, _item, _wasConnected
).resizeTo();
}, 100);
});
},
onSuccess = function(res, node, data, tree, item, _wasConnected) {
if (res && res.data) {
if (typeof res.data.icon == 'string') {
tree.removeIcon(item);
data.icon = res.data.icon;
tree.addIcon(item, {icon: data.icon});
}
_.extend(data, res.data);
data.is_connecting = false;
var serverInfo = pgBrowser.serverInfo =
pgBrowser.serverInfo || {};
serverInfo[data._id] = _.extend({}, data);
alertify.success(res.info);
obj.trigger('connected', obj, item, data);
// Generate the event that server is connected
pgBrowser.Events.trigger(
'pgadmin:server:connected', data._id, item, data
);
// Generate the event that database is connected
pgBrowser.Events.trigger(
'pgadmin:database:connected', data._id, data.db, item, data
);
// We're not reconnecting
if (!_wasConnected) {
tree.setInode(item);
tree.deselect(item);
setTimeout(function() {
tree.select(item);
tree.open(item);
}, 10);
} else {
// We just need to refresh the tree now.
setTimeout(function() {
node.callbacks.refresh.apply(node, [true]);
}, 10);
}
}
};
// Ask Password and send it back to the connect server // Ask Password and send it back to the connect server
if (!alertify.dlgServerPass) { if (!alertify.dlgServerPass) {
alertify.dialog('dlgServerPass', function factory() { alertify.dialog('dlgServerPass', function factory() {
return { return {
main: function(title, message, model, data, tree, item) { main: function(
title, message, node, data, tree, item,
_status, _onSuccess, _onFailure, _onCancel
) {
this.set('title', title); this.set('title', title);
this.message = message; this.message = message;
this.tree = tree; this.tree = tree;
this.nodeData = data; this.nodeData = data;
this.nodeItem = item; this.nodeItem = item;
this.nodeModel = model; this.node= node;
this.connected = _status;
this.onSuccess = _onSuccess || onSuccess;
this.onFailure = _onFailure || onFailure;
this.onCancel = _onCancel || onCancel;
}, },
setup:function() { setup:function() {
return { return {
@ -791,18 +907,24 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
this.setContent(this.message); this.setContent(this.message);
}, },
callback: function(closeEvent) { callback: function(closeEvent) {
var _sdata = this.nodeData, var _tree = this.tree,
_tree = this.tree,
_item = this.nodeItem, _item = this.nodeItem,
_model = this.nodeModel; _node = this.node,
_data = this.nodeData,
_status = this.connected,
_onSuccess = this.onSuccess,
_onFailure = this.onFailure,
_onCancel = this.onCancel;
if (closeEvent.button.text == "{{ _('OK') }}") { if (closeEvent.button.text == "{{ _('OK') }}") {
var _url = _model.generate_url(_item, 'connect', _sdata, true); var _url = _node.generate_url(_item, 'connect', _data, true);
_tree.setLeaf(_item); if (!_status) {
_tree.removeIcon(_item); _tree.setLeaf(_item);
_tree.addIcon(_item, {icon: 'icon-server-connecting'}); _tree.removeIcon(_item);
_tree.addIcon(_item, {icon: 'icon-server-connecting'});
}
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
@ -810,38 +932,58 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
url: _url, url: _url,
data: $('#frmPassword').serialize(), data: $('#frmPassword').serialize(),
success: function(res) { success: function(res) {
return onSuccess( return _onSuccess(
res, _model, _sdata, _tree, _item res, _node, _data, _tree, _item, _status
); );
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
return onFailure( return _onFailure(
xhr, status, error, _model, _sdata, _tree, _item xhr, status, error, _node, _data, _tree, _item, _status
); );
} }
}); });
} else { } else {
_tree.setInode(_item); this.onCancel && typeof(this.onCancel) == 'function' &&
_tree.removeIcon(_item); this.onCancel(_tree, _item, _data, _status);
_tree.addIcon(_item, {icon: 'icon-server-not-connected'});
} }
} }
}; };
}); });
} }
var onCancel = function(_tree, _item, _data, _status) {
_data.is_connecting = false;
_tree.unload(_item);
_tree.setInode(_item);
_tree.removeIcon(_item);
_tree.addIcon(_item, {icon: 'icon-server-not-connected'});
obj.trigger('connect:cancelled', data._id, data.db, obj, _item, _data);
pgBrowser.Events.trigger(
'pgadmin:server:connect:cancelled', data._id, _item, _data, obj
);
pgBrowser.Events.trigger(
'pgadmin:database:connect:cancelled', data._id, data.db, _item, _data, obj
);
if (_status) {
_tree.select(_item);
}
};
data.is_connecting = true;
url = obj.generate_url(item, "connect", data, true); url = obj.generate_url(item, "connect", data, true);
$.post(url) $.post(url)
.done( .done(function(res) {
function(res) { if (res.success == 1) {
if (res.success == 1) { return onSuccess(
return onSuccess(res, obj, data, tree, item); res, obj, data, tree, item, wasConnected
} );
}) }
.fail( })
function(xhr, status, error) { .fail(function(xhr, status, error) {
return onFailure(xhr, status, error, obj, data, tree, item); return onFailure(
}); xhr, status, error, obj, data, tree, item, wasConnected
);
});
} }
/* Send PING to indicate that session is alive */ /* Send PING to indicate that session is alive */

View File

@ -1,8 +1,8 @@
SELECT SELECT
procpid AS "{{ conn|qtIdent('PID') }}, procpid AS {{ conn|qtIdent('PID') }},
usename AS "{{ conn|qtIdent(_('User')|safe) }}, usename AS {{ conn|qtIdent(_('User')) }},
datname AS "{{ conn|qtIdent(_('Database')|safe) }}, datname AS {{ conn|qtIdent(_('Database')) }},
backend_start AS "{{ conn|qtIdent(_('Backend start')|safe) }}, backend_start AS {{ conn|qtIdent(_('Backend start')) }},
CASE CASE
WHEN client_hostname IS NOT NULL AND client_hostname != '' THEN WHEN client_hostname IS NOT NULL AND client_hostname != '' THEN
client_hostname || ':' || client_port client_hostname || ':' || client_port
@ -12,22 +12,22 @@ SELECT
'local pipe' 'local pipe'
ELSE ELSE
'localhost:' || client_port 'localhost:' || client_port
END AS "{{ conn|qtIdent(_('Client')|safe) }}, END AS {{ conn|qtIdent(_('Client')) }},
application_name AS "{{ conn|qtIdent(_('Application')|safe) }}, application_name AS {{ conn|qtIdent(_('Application')) }},
waiting AS "{{ conn|qtIdent(_('Waiting?')|safe) }}, waiting AS {{ conn|qtIdent(_('Waiting?')) }},
current_query AS "{{ conn|qtIdent(_('Query')|safe) }}, current_query AS {{ conn|qtIdent(_('Query')) }},
query_start AS "{{ conn|qtIdent(_('Query start')|safe) }}, query_start AS {{ conn|qtIdent(_('Query start')) }},
xact_start AS "{{ conn|qtIdent(_('Xact start')|safe) }} xact_start AS {{ conn|qtIdent(_('Xact start')) }}
FROM FROM
pg_stat_activity sa pg_stat_activity sa
WHERE WHERE
(SELECT r.rolsuper OR r.oid = sa.usesysid FROM pg_roles r WHERE r.rolname = current_user) (SELECT r.rolsuper OR r.oid = sa.usesysid FROM pg_roles r WHERE r.rolname = current_user)
UNION UNION
SELECT SELECT
procpid AS "{{ conn|qtIdent('PID') }}, procpid AS "PID",
usename AS "{{ conn|qtIdent(_('User')|safe) }}, usename AS {{ conn|qtIdent(_('User')) }},
'' AS "{{ conn|qtIdent(_('Database')|safe) }}, datname AS {{ conn|qtIdent(_('Database')) }},
backend_start AS "{{ conn|qtIdent(_('Backend start')|safe) }}, backend_start AS {{ conn|qtIdent(_('Backend start')) }},
CASE CASE
WHEN client_hostname IS NOT NULL AND client_hostname != '' THEN WHEN client_hostname IS NOT NULL AND client_hostname != '' THEN
client_hostname || ':' || client_port client_hostname || ':' || client_port
@ -37,12 +37,12 @@ SELECT
'local pipe' 'local pipe'
ELSE ELSE
'localhost:' || client_port 'localhost:' || client_port
END AS "{{ conn|qtIdent(_('Client')|safe) }}, END AS {{ conn|qtIdent(_('Client')) }},
{{ _('Streaming Replication') }}|safe|qtLiteral AS "{{ conn|qtIdent(_('Application')|safe) }}, {{ _('Streaming Replication') }}|qtLiteral AS {{ conn|qtIdent(_('Application')) }},
null AS "{{ conn|qtIdent(_('Waiting?')|safe) }}, null AS {{ conn|qtIdent(_('Waiting?')) }},
state || ' [sync (state: ' || COALESCE(sync_state, '') || ', priority: ' || sync_priority::text || ')] (' || sent_location || ' sent, ' || write_location || ' written, ' || flush_location || ' flushed, ' || replay_location || ' applied)' AS "{{ conn|qtIdent(_('Query')|safe) }}, state || ' [sync (state: ' || COALESCE(sync_state, '') || ', priority: ' || sync_priority::text || ')] (' || sent_location || ' sent, ' || write_location || ' written, ' || flush_location || ' flushed, ' || replay_location || ' applied)' AS {{ conn|qtIdent(_('Query')) }},
null AS "{{ conn|qtIdent(_('Query start')|safe) }}, null AS {{ conn|qtIdent(_('Query start')) }},
null AS "{{ conn|qtIdent(_('Xact start')|safe) }} null AS {{ conn|qtIdent(_('Xact start')) }}
FROM FROM
pg_stat_replication sa pg_stat_replication sa
WHERE WHERE

View File

@ -1,8 +1,8 @@
SELECT SELECT
pid AS {{ conn|qtIdent('PID') }}, pid AS "PID",
usename AS {{ conn|qtIdent(_('User')|safe) }}, usename AS {{ conn|qtIdent(_('User')) }},
datname AS {{ conn|qtIdent(_('Database')|safe) }}, datname AS {{ conn|qtIdent(_('Database')) }},
backend_start AS {{ conn|qtIdent(_('Backend start')|safe) }}, backend_start AS {{ conn|qtIdent(_('Backend start')) }},
CASE CASE
WHEN client_hostname IS NOT NULL AND client_hostname != '' THEN WHEN client_hostname IS NOT NULL AND client_hostname != '' THEN
client_hostname || ':' || client_port client_hostname || ':' || client_port
@ -12,22 +12,22 @@ SELECT
'local pipe' 'local pipe'
ELSE ELSE
'localhost:' || client_port 'localhost:' || client_port
END AS {{ conn|qtIdent(_('Client')|safe) }}, END AS {{ conn|qtIdent(_('Client')) }},
application_name AS {{ conn|qtIdent(_('Application')|safe) }}, application_name AS {{ conn|qtIdent(_('Application')) }},
waiting AS {{ conn|qtIdent(_('Waiting?')|safe) }}, waiting AS {{ conn|qtIdent(_('Waiting?')) }},
query AS {{ conn|qtIdent(_('Query')|safe) }}, query AS {{ conn|qtIdent(_('Query')) }},
query_start AS {{ conn|qtIdent(_('Query start')|safe) }}, query_start AS {{ conn|qtIdent(_('Query start')) }},
xact_start AS {{ conn|qtIdent(_('Xact start')|safe) }} xact_start AS {{ conn|qtIdent(_('Xact start')) }}
FROM FROM
pg_stat_activity sa pg_stat_activity sa
WHERE WHERE
(SELECT r.rolsuper OR r.oid = sa.usesysid FROM pg_roles r WHERE r.rolname = current_user) (SELECT r.rolsuper OR r.oid = sa.usesysid FROM pg_roles r WHERE r.rolname = current_user)
UNION UNION
SELECT SELECT
pid AS {{ conn|qtIdent('PID') }}, pid AS "PID",
usename AS {{ conn|qtIdent(_('User')|safe) }}, usename AS {{ conn|qtIdent(_('User')) }},
'' AS {{ conn|qtIdent(_('Database')|safe) }}, '' AS {{ conn|qtIdent(_('Database')) }},
backend_start AS {{ conn|qtIdent(_('Backend start')|safe) }}, backend_start AS {{ conn|qtIdent(_('Backend start')) }},
CASE CASE
WHEN client_hostname IS NOT NULL AND client_hostname != '' THEN WHEN client_hostname IS NOT NULL AND client_hostname != '' THEN
client_hostname || ':' || client_port client_hostname || ':' || client_port
@ -37,12 +37,12 @@ SELECT
'local pipe' 'local pipe'
ELSE ELSE
'localhost:' || client_port 'localhost:' || client_port
END AS {{ conn|qtIdent(_('Client')|safe) }}, END AS {{ conn|qtIdent(_('Client')) }},
{{ _('Streaming Replication')|safe|qtLiteral }} AS {{ conn|qtIdent(_('Application')|safe) }}, {{ _('Streaming Replication')|qtLiteral }} AS {{ conn|qtIdent(_('Application')) }},
null AS {{ conn|qtIdent(_('Waiting?')|safe) }}, null AS {{ conn|qtIdent(_('Waiting?')) }},
state || ' [sync (state: ' || COALESCE(sync_state, '') || ', priority: ' || sync_priority::text || ')] (' || sent_location || ' sent, ' || write_location || ' written, ' || flush_location || ' flushed, ' || replay_location || ' applied)' AS {{ conn|qtIdent(_('Query')|safe) }}, state || ' [sync (state: ' || COALESCE(sync_state, '') || ', priority: ' || sync_priority::text || ')] (' || sent_location || ' sent, ' || write_location || ' written, ' || flush_location || ' flushed, ' || replay_location || ' applied)' AS {{ conn|qtIdent(_('Query')) }},
null AS {{ conn|qtIdent(_('Query start')|safe) }}, null AS {{ conn|qtIdent(_('Query start')) }},
null AS {{ conn|qtIdent(_('Xact start')|safe) }} null AS {{ conn|qtIdent(_('Xact start')) }}
FROM FROM
pg_stat_replication sa pg_stat_replication sa
WHERE WHERE

View File

@ -335,7 +335,11 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
url: '{{ url_for('browser.get_nodes') }}', url: '{{ url_for('browser.get_nodes') }}',
converters: { converters: {
'text json': function(payload) { 'text json': function(payload) {
data = JSON.parse(payload).data; data = JSON.parse(payload).data.sort(function(a, b) {
return (
(a.label === b.label) ? 0 : (a.label < b.label ? -1 : 1)
);
});
_.each(data, function(d){ _.each(data, function(d){
d.label = _.escape(d.label); d.label = _.escape(d.label);
}) })

View File

@ -114,14 +114,24 @@ function($, _, S, pgAdmin, Backbone, Alertify, Backform) {
// Fetch Data // Fetch Data
collection.fetch({reset: true}) collection.fetch({reset: true})
.error(function(jqxhr, error, message) { .error(function(xhr, error, message) {
pgBrowser.Events.trigger(
'pgadmin:collection:retrieval:error', 'properties', xhr, error, message, item, that
);
if (
!Alertify.pgHandleItemError(xhr, error, message, {item: item, info: info})
) {
Alertify.pgNotifier( Alertify.pgNotifier(
error, jqxhr, error, xhr,
S( S(
"{{ _("Error retrieving properties: %s.") }}" "{{ _("Error retrieving properties- %s") }}"
).sprintf(message).value() ).sprintf(message || that.label).value(),
); function() {
}); console.log(arguments);
}
);
}
});
}, },
generate_url: function(item, type, d) { generate_url: function(item, type, d) {
var url = pgAdmin.Browser.URL + '{TYPE}/{REDIRECT}{REF}', var url = pgAdmin.Browser.URL + '{TYPE}/{REDIRECT}{REF}',

View File

@ -14,8 +14,8 @@ function(_, S, pgAdmin) {
'SQL_TAB': '{{ _('SQL') }}', 'SQL_TAB': '{{ _('SQL') }}',
'SQL_INCOMPLETE': '{{ _('Incomplete definition') }}', 'SQL_INCOMPLETE': '{{ _('Incomplete definition') }}',
'SQL_NO_CHANGE': '{{ _('Nothing changed')|safe }}', 'SQL_NO_CHANGE': '{{ _('Nothing changed')|safe }}',
'MUST_BE_INT' : "{{ _("'%s' must be an integer.")|safe }}", 'MUST_BE_INT' : "{{ _("'%s' must be an integer.") }}",
'MUST_BE_NUM' : "{{ _("'%s' must be a numeric.")|safe }}", 'MUST_BE_NUM' : "{{ _("'%s' must be a numeric.") }}",
'MUST_GR_EQ' : "{{ _("'%s' must be greater than or equal to %d.")|safe }}", 'MUST_GR_EQ' : "{{ _("'%s' must be greater than or equal to %d.")|safe }}",
'MUST_LESS_EQ' : "{{ _("'%s' must be less than or equal to %d.")|safe }}", 'MUST_LESS_EQ' : "{{ _("'%s' must be less than or equal to %d.")|safe }}",
'STATISTICS_LABEL': "{{ _("Statistics") }}", 'STATISTICS_LABEL': "{{ _("Statistics") }}",
@ -24,12 +24,13 @@ function(_, S, pgAdmin) {
'NODE_HAS_NO_STATISTICS': "{{ _("No statistics are available for the selected object.") }}", 'NODE_HAS_NO_STATISTICS': "{{ _("No statistics are available for the selected object.") }}",
'TRUE': "{{ _("True") }}", 'TRUE': "{{ _("True") }}",
'FALSE': "{{ _("False") }}", 'FALSE': "{{ _("False") }}",
'NOTE_CTRL_LABEL': "{{ _("Note") }}" 'NOTE_CTRL_LABEL': "{{ _("Note") }}",
'ERR_RETRIEVAL_INFO': "{{ _("Error retrieving the information- %s") }}",
'CONNECTION_LOST': "{{ _("Connection to the server has been lost!") }}"
}; };
{% for key in current_app.messages.keys() %} {% for key in current_app.messages.keys() %}
messages['{{ key|safe }}'] = '{{ current_app.messages[key]|safe }}'; messages['{{ key }}'] = '{{ current_app.messages[key] }}';
{% endfor %} {% endfor %}
return pgBrowser.messages; return pgBrowser.messages;

View File

@ -36,6 +36,14 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) {
// Make sure - a child have all the callbacks of the parent. // Make sure - a child have all the callbacks of the parent.
child.callbacks = _.extend({}, parent.callbacks, props.callbacks); child.callbacks = _.extend({}, parent.callbacks, props.callbacks);
var bindToChild = function(cb) {
if (typeof(child.callbacks[cb]) == 'function') {
child.callbacks[cb] = child.callbacks[cb].bind(child);
}
},
callbacks = _.keys(child.callbacks);
for(var idx = 0; idx < callbacks.length; idx++) bindToChild(callbacks[idx]);
// Registering the node by calling child.Init(...) function // Registering the node by calling child.Init(...) function
child.Init.apply(child); child.Init.apply(child);
@ -174,7 +182,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) {
// //
// Used to generate view for the particular node properties, edit, // Used to generate view for the particular node properties, edit,
// creation. // creation.
getView: function(item, type, el, node, formType, callback, ctx) { getView: function(item, type, el, node, formType, callback, ctx, cancelFunc) {
var that = this; var that = this;
if (!this.type || this.type == '') if (!this.type || this.type == '')
@ -265,24 +273,43 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) {
if (!newModel.isNew()) { if (!newModel.isNew()) {
// This is definetely not in create mode // This is definetely not in create mode
newModel.fetch() newModel.fetch()
.success(function(res, msg, xhr) { .success(function(res, msg, xhr) {
// We got the latest attributes of the // We got the latest attributes of the
// object. Render the view now. // object. Render the view now.
view.render(); view.render();
if (type != 'properties') { if (type != 'properties') {
$(el).focus(); $(el).focus();
} }
newModel.startNewSession(); newModel.startNewSession();
}) })
.error(function(jqxhr, error, message) { .error(function(xhr, error, message) {
// TODO:: We may not want to continue from here var _label = that && item ?
that.getTreeNodeHierarchy(item)[that.type].label :
'';
pgBrowser.Events.trigger(
'pgadmin:node:retrieval:error', 'properties',
xhr, error, message, item
);
if (
!Alertify.pgHandleItemError(
xhr, error, message, {item: item, info: info}
)
) {
Alertify.pgNotifier( Alertify.pgNotifier(
error, jqxhr, error, xhr,
S( S(
"{{ _("Error retrieving properties: %s.") }}" "{{ _("Error retrieving properties- %s") }}"
).sprintf(message).value() ).sprintf(message || _label).value(),
); function() {
}); console.log(arguments);
}
);
}
// Close the panel (if couldn't fetch properties)
if (cancelFunc) {
cancelFunc();
}
});
} else { } else {
// Yay - render the view now! // Yay - render the view now!
$(el).focus(); $(el).focus();
@ -1039,7 +1066,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform) {
}; };
// Create a view to edit/create the properties in fieldsets // Create a view to edit/create the properties in fieldsets
view = that.getView(item, action, content, data, 'dialog', updateButtons, j); view = that.getView(item, action, content, data, 'dialog', updateButtons, j, onCancelFunc);
if (view) { if (view) {
// Save it to release it later // Save it to release it later
j.data('obj-view', view); j.data('obj-view', view);

View File

@ -1,6 +1,7 @@
define( define([
['underscore', 'underscore.string', 'jquery', 'pgadmin.browser'], 'underscore', 'underscore.string', 'jquery', 'pgadmin.browser',
function(_, S, $, pgBrowser) { 'alertify', 'pgadmin.alertifyjs'
], function(_, S, $, pgBrowser, Alertify) {
if (pgBrowser.ShowNodeDepends) if (pgBrowser.ShowNodeDepends)
return pgBrowser.ShowNodeDepends; return pgBrowser.ShowNodeDepends;
@ -226,7 +227,30 @@ define(
$gridContainer.removeClass('hidden'); $gridContainer.removeClass('hidden');
// Set the url, fetch the data and update the collection // Set the url, fetch the data and update the collection
collection.url = url; collection.url = url;
collection.fetch({ reset: true }); collection.fetch({
reset: true,
error: function(coll, xhr, error, message) {
var _label = treeHierarchy[n_type].label;
pgBrowser.Events.trigger(
'pgadmin:node:retrieval:error', 'depends', xhr, status, error
);
if (
!Alertify.pgHandleItemError(xhr, error, message, {
item: item, info: treeHierarchy
})
) {
Alertify.pgNotifier(
status, xhr,
S(
pgBrowser.messages['ERR_RETRIEVAL_INFO']
).sprintf(message || _label).value(),
function() {
console.log(arguments);
}
);
}
}
});
} }
} }
if (msg != '') { if (msg != '') {

View File

@ -1,6 +1,7 @@
define( define([
['underscore', 'jquery', 'pgadmin.browser'], 'underscore', 'underscore.string', 'jquery', 'pgadmin.browser',
function(_, $, pgBrowser) { 'alertify', 'pgadmin.alertifyjs'
], function(_, S, $, pgBrowser, Alertify) {
pgBrowser.ShowNodeSQL = pgBrowser.ShowNodeSQL || {}; pgBrowser.ShowNodeSQL = pgBrowser.ShowNodeSQL || {};
@ -84,8 +85,26 @@ function(_, $, pgBrowser) {
pgAdmin.Browser.editor.setValue(res); pgAdmin.Browser.editor.setValue(res);
} }
}, },
error: function() { error: function(xhr, error, message) {
// TODO:: Report this var _label = treeHierarchy[n_type].label;
pgBrowser.Events.trigger(
'pgadmin:node:retrieval:error', 'sql', xhr, status, error, item
);
if (
!Alertify.pgHandleItemError(xhr, error, message, {
item: item, info: treeHierarchy
})
) {
Alertify.pgNotifier(
status, xhr,
S(
pgBrowser.messages['ERR_RETRIEVAL_INFO']
).sprintf(message || _label).value(),
function() {
console.log(arguments);
}
);
}
} }
}); });
} }

View File

@ -1,6 +1,7 @@
define( define([
['underscore', 'jquery', 'pgadmin.browser', 'backgrid', 'wcdocker', 'pgadmin.backgrid'], 'underscore', 'underscore.string', 'jquery', 'pgadmin.browser', 'backgrid',
function(_, $, pgBrowser, Backgrid) { 'alertify', 'wcdocker', 'pgadmin.backgrid', 'pgadmin.alertifyjs'
], function(_, S, $, pgBrowser, Backgrid, Alertify) {
if (pgBrowser.NodeStatistics) if (pgBrowser.NodeStatistics)
return pgBrowser.NodeStatistics; return pgBrowser.NodeStatistics;
@ -210,8 +211,26 @@ function(_, $, pgBrowser, Backgrid) {
$msgContainer.removeClass('hidden'); $msgContainer.removeClass('hidden');
} }
}, },
error: function() { error: function(xhr, error, message) {
// TODO:: Report this error. var _label = treeHierarchy[n_type].label;
pgBrowser.Events.trigger(
'pgadmin:node:retrieval:error', 'statistics', xhr, status, error, item
);
if (
!Alertify.pgHandleItemError(xhr, error, message, {
item: item, info: treeHierarchy
})
) {
Alertify.pgNotifier(
status, xhr,
S(
pgBrowser.messages['ERR_RETRIEVAL_INFO']
).sprintf(message || _label).value(),
function() {
console.log(arguments);
}
);
}
} }
}); });
} }

View File

@ -95,7 +95,7 @@ function(alertify, S) {
if (contentType) { if (contentType) {
try { try {
if (contentType.indexOf('text/json') == 0) { if (contentType.indexOf('application/json') == 0) {
resp = $.parseJSON(msg); resp = $.parseJSON(msg);
if (resp.result != null && (!resp.errormsg || resp.errormsg == '') && if (resp.result != null && (!resp.errormsg || resp.errormsg == '') &&
@ -104,17 +104,19 @@ function(alertify, S) {
} }
msg = _.escape(resp.result) || _.escape(resp.errormsg) || "Unknown error"; msg = _.escape(resp.result) || _.escape(resp.errormsg) || "Unknown error";
} }
} catch (exc) { if (contentType.indexOf('text/html') == 0) {
} alertify.notify(
if (contentType.indexOf('text/html') == 0) {
alertify.notify(
S( S(
'%s<br><br>' + window.pgAdmin.Browser.messages.CLICK_FOR_DETAILED_MSG '%s<br><br>' +
).sprintf(promptmsg).value(), type, 0, function() { window.pgAdmin.Browser.messages.CLICK_FOR_DETAILED_MSG
alertify.pgIframeDialog().show().set({ frameless: false }).set('pg_msg', msg); ).sprintf(promptmsg).value(), type, 0, function() {
alertify.pgIframeDialog().show().set({frameless: false}).set(
'pg_msg', msg
);
}); });
return; return;
}
} catch (exc) {
} }
} }
alertify.alert().show().set( alertify.alert().show().set(
@ -185,4 +187,125 @@ function(alertify, S) {
this.set('onrestored', alertifyDialogResized); this.set('onrestored', alertifyDialogResized);
}; };
alertify.pgHandleItemError = function(xhr, error, message, args) {
var pgBrowser = window.pgAdmin.Browser;
if (!xhr || !pgBrowser) {
return;
}
var msg = xhr.responseText,
contentType = xhr.getResponseHeader('Content-Type'),
msg = xhr.responseText,
jsonResp = contentType &&
contentType.indexOf('application/json') == 0 &&
$.parseJSON(xhr.responseText);
if (
jsonResp && (
xhr.status == 503 ? (
jsonResp.info == 'CONNECTION_LOST' &&
'server' in args.info && jsonResp.data.sid >= 0 &&
jsonResp.data.sid == args.info.server._id
) : (
xhr.status == 428 &&
jsonResp.errormsg &&
jsonResp.errormsg == pgBrowser.messages.CONNECTION_LOST
)
)
) {
if (
args.preHandleConnectionLost &&
typeof(args.preHandleConnectionLost) == 'function'
) {
args.preHandleConnectionLost.apply(this, arguments);
}
// Check the status of the maintenance server connection.
var server = pgBrowser.Nodes['server'],
ctx = {
resp: jsonResp,
xhr: xhr,
args: args
},
reconnectServer = function() {
var ctx = this,
onServerConnect = function(_sid, _i, _d) {
// Yay - server is reconnected.
if (this.args.info.server._id == _sid) {
pgBrowser.Events.off(
'pgadmin:server:connected', onServerConnect
);
pgBrowser.Events.off(
'pgadmin:server:connect:cancelled', onConnectCancel
);
// Do we need to connect the disconnected server now?
if (
this.resp.data.database &&
this.resp.data.database != _d.db
) {
// Server is connected now, we will need to inform the
// database to connect it now.
pgBrowser.Events.trigger(
'pgadmin:database:connection:lost', this.args.item,
this.resp, true
);
}
}
}.bind(ctx),
onConnectCancel = function(_sid, _item, _data) {
// User has cancelled the operation in between.
if (_sid == this.args.info.server.id) {
pgBrowser.Events.off('pgadmin:server:connected', onServerConnect);
pgBrowser.Events.off('pgadmin:server:connect:cancelled', onConnectCancel);
// Connection to the database will also be cancelled
pgBrowser.Events.trigger(
'pgadmin:database:connect:cancelled', _sid,
this.resp.data.database || _data.db, _item, _data
);
}
}.bind(ctx);
pgBrowser.Events.on('pgadmin:server:connected', onServerConnect);
pgBrowser.Events.on('pgadmin:server:connect:cancelled', onConnectCancel);
// Connection to the server has been lost, we need to inform the
// server first to take the action first.
pgBrowser.Events.trigger(
'pgadmin:server:connection:lost', this.args.item, this.resp
);
}.bind(ctx);
$.ajax({
url: server.generate_url(
null, 'connect', args.info.server, true, args.info
),
dataType: 'json',
success: function(res) {
if (res.success && 'connected' in res.data) {
if (res.data.connected) {
// Server is connected, but - the connection with the
// particular database has been lost.
pgBrowser.Events.trigger(
'pgadmin:database:connection:lost', args.item, jsonResp
);
return;
}
}
// Serever was not connected, we should first try to connect
// the server.
reconnectServer();
},
error: function() {
reconnectServer();
}
});
return true;
}
return false;
};
}); });

View File

@ -30,8 +30,9 @@ class DataTypeJSONEncoder(json.JSONEncoder):
return json.JSONEncoder.default(self, obj) return json.JSONEncoder.default(self, obj)
def make_json_response(success=1, errormsg='', info='', result=None, def make_json_response(
data=None, status=200): success=1, errormsg='', info='', result=None, data=None, status=200
):
"""Create a HTML response document describing the results of a request and """Create a HTML response document describing the results of a request and
containing the data.""" containing the data."""
doc = dict() doc = dict()
@ -44,7 +45,7 @@ def make_json_response(success=1, errormsg='', info='', result=None,
return Response( return Response(
response=json.dumps(doc, cls=DataTypeJSONEncoder), response=json.dumps(doc, cls=DataTypeJSONEncoder),
status=status, status=status,
mimetype="text/json" mimetype="application/json"
) )
@ -53,7 +54,7 @@ def make_response(response=None, status=200):
return Response( return Response(
response=json.dumps(response, cls=DataTypeJSONEncoder), response=json.dumps(response, cls=DataTypeJSONEncoder),
status=status, status=status,
mimetype="text/json" mimetype="application/json"
) )
@ -120,10 +121,25 @@ def gone(errormsg=''):
) )
def not_implemented(errormsg=_('Not implemented.')): def not_implemented(errormsg=_('Not implemented.'), info='', result=None, data=None):
"""Create a response with HTTP status code 501 - Not Implemented.""" """Create a response with HTTP status code 501 - Not Implemented."""
return make_json_response( return make_json_response(
status=501, status=501,
success=0, success=0,
errormsg=errormsg errormsg=errormsg,
info=info,
result=result,
data=data
)
def service_unavailable(errormsg=_("Service Unavailable"), info='', result=None, data=None):
"""Create a response with HTTP status code 503 - Server Unavailable."""
return make_json_response(
status=503,
success=0,
errormsg=errormsg,
info=info,
result=result,
data=data
) )

View File

@ -30,6 +30,7 @@ from psycopg2.extensions import adapt
import config import config
from pgadmin.model import Server, User from pgadmin.model import Server, User
from pgadmin.utils.exception import ConnectionLost
from .keywords import ScanKeyword from .keywords import ScanKeyword
from ..abstract import BaseDriver, BaseConnection from ..abstract import BaseDriver, BaseConnection
from .cursor import DictCursor from .cursor import DictCursor
@ -179,6 +180,7 @@ class Connection(BaseConnection):
self.execution_aborted = False self.execution_aborted = False
self.row_count = 0 self.row_count = 0
self.__notices = None self.__notices = None
self.password = None
super(Connection, self).__init__() super(Connection, self).__init__()
@ -225,10 +227,13 @@ class Connection(BaseConnection):
password = None password = None
mgr = self.manager mgr = self.manager
if 'password' in kwargs: encpass = kwargs['password'] if 'password' in kwargs else None
encpass = kwargs['password']
else: if encpass is None:
encpass = getattr(mgr, 'password', None) encpass = self.password or getattr(mgr, 'password', None)
# Reset the existing connection password
self.password = None
if encpass: if encpass:
# Fetch Logged in User Details. # Fetch Logged in User Details.
@ -239,6 +244,10 @@ class Connection(BaseConnection):
try: try:
password = decrypt(encpass, user.password) password = decrypt(encpass, user.password)
# password is in bytes, for python3 we need it in string
if isinstance(password, bytes):
password = password.decode()
except Exception as e: except Exception as e:
current_app.logger.exception(e) current_app.logger.exception(e)
return False, \ return False, \
@ -246,10 +255,6 @@ class Connection(BaseConnection):
str(e) str(e)
) )
# password is in bytes, for python3 we need it in string
if isinstance(password, bytes):
password = password.decode()
try: try:
if hasattr(str, 'decode'): if hasattr(str, 'decode'):
database = self.db.encode('utf-8') database = self.db.encode('utf-8')
@ -401,11 +406,18 @@ WHERE
mgr.server_cls = st mgr.server_cls = st
break break
mgr._update_password(encpass)
mgr.update_session() mgr.update_session()
return True, None return True, None
def __cursor(self, server_cursor=False): def __cursor(self, server_cursor=False):
if not self.conn:
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( cur = getattr(g, "{0}#{1}".format(
self.manager.sid, self.manager.sid,
self.conn_id.encode('utf-8') self.conn_id.encode('utf-8')
@ -475,7 +487,7 @@ Attempting to reconnect to the database server (#{server_id}) for the connection
Connection for server#{0} with database "{1}" was lost. Connection for server#{0} with database "{1}" was lost.
Attempt to reconnect it failed with the error: Attempt to reconnect it failed with the error:
{2}""" {2}"""
).format(self.driver.server_id, self.database, cur) ).format(self.driver.server_id, self.db, cur)
current_app.logger.error(msg) current_app.logger.error(msg)
return False, cur return False, cur
@ -593,6 +605,12 @@ Attempt to reconnect it failed with the error:
self.__internal_blocking_execute(cur, query, params) self.__internal_blocking_execute(cur, query, params)
except psycopg2.Error as pe: except psycopg2.Error as pe:
cur.close() cur.close()
if not self.connected():
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) errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
current_app.logger.error( current_app.logger.error(
u"Failed to execute query (execute_scalar) for the server #{server_id} - {conn_id} (Query-id: {query_id}):\nError Message:{errmsg}".format( u"Failed to execute query (execute_scalar) for the server #{server_id} - {conn_id} (Query-id: {query_id}):\nError Message:{errmsg}".format(
@ -694,6 +712,12 @@ Failed to execute query (execute_async) for the server #{server_id} - {conn_id}
self.__internal_blocking_execute(cur, query, params) self.__internal_blocking_execute(cur, query, params)
except psycopg2.Error as pe: except psycopg2.Error as pe:
cur.close() cur.close()
if not self.connected():
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) errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
current_app.logger.error(u""" current_app.logger.error(u"""
Failed to execute query (execute_void) for the server #{server_id} - {conn_id} Failed to execute query (execute_void) for the server #{server_id} - {conn_id}
@ -733,6 +757,12 @@ Failed to execute query (execute_void) for the server #{server_id} - {conn_id}
self.__internal_blocking_execute(cur, query, params) self.__internal_blocking_execute(cur, query, params)
except psycopg2.Error as pe: except psycopg2.Error as pe:
cur.close() cur.close()
if not self.connected():
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) errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
current_app.logger.error( current_app.logger.error(
u"Failed to execute query (execute_2darray) for the server #{server_id} - {conn_id} (Query-id: {query_id}):\nError Message:{errmsg}".format( u"Failed to execute query (execute_2darray) for the server #{server_id} - {conn_id} (Query-id: {query_id}):\nError Message:{errmsg}".format(
@ -778,6 +808,12 @@ Failed to execute query (execute_void) for the server #{server_id} - {conn_id}
self.__internal_blocking_execute(cur, query, params) self.__internal_blocking_execute(cur, query, params)
except psycopg2.Error as pe: except psycopg2.Error as pe:
cur.close() cur.close()
if not self.connected():
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) errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
current_app.logger.error( current_app.logger.error(
u"Failed to execute query (execute_dict) for the server #{server_id}- {conn_id} (Query-id: {query_id}):\nError Message:{errmsg}".format( u"Failed to execute query (execute_dict) for the server #{server_id}- {conn_id} (Query-id: {query_id}):\nError Message:{errmsg}".format(
@ -867,6 +903,7 @@ Failed to reset the connection to the server due to following error:
if self.conn: if self.conn:
self.conn.close() self.conn.close()
self.conn = None self.conn = None
self.password = None
def _wait(self, conn): def _wait(self, conn):
""" """
@ -942,6 +979,12 @@ Failed to reset the connection to the server due to following error:
try: try:
status = self._wait_timeout(self.conn, ASYNC_WAIT_TIMEOUT) status = self._wait_timeout(self.conn, ASYNC_WAIT_TIMEOUT)
except psycopg2.Error as pe: except psycopg2.Error as pe:
if cur.closed:
raise ConnectionLost(
self.manager.sid,
self.db,
self.conn_id[5:]
)
errmsg = self._formatted_exception_msg(pe, formatted_exception_msg) errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
return False, errmsg, None return False, errmsg, None
@ -1242,10 +1285,6 @@ class ServerManager(object):
self, database=None, conn_id=None, auto_reconnect=True, did=None, self, database=None, conn_id=None, auto_reconnect=True, did=None,
async=None async=None
): ):
msg_active_conn = gettext(
"Server has no active connection. Please connect to the server."
)
if database is not None: if database is not None:
if hasattr(str, 'decode') and \ if hasattr(str, 'decode') and \
not isinstance(database, unicode): not isinstance(database, unicode):
@ -1285,7 +1324,7 @@ WHERE db.oid = {0}""".format(did))
)) ))
if database is None: if database is None:
raise Exception(msg_active_conn) raise ConnectionLost(self.sid, None, None)
my_id = (u'CONN:{0}'.format(conn_id)) if conn_id is not None else \ my_id = (u'CONN:{0}'.format(conn_id)) if conn_id is not None else \
(u'DB:{0}'.format(database)) (u'DB:{0}'.format(database))
@ -1387,6 +1426,13 @@ WHERE db.oid = {0}""".format(did))
return True 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:
conn.password = passwd
def update_session(self): def update_session(self):
managers = session['__pgsql_server_managers'] \ managers = session['__pgsql_server_managers'] \
if '__pgsql_server_managers' in session else dict() if '__pgsql_server_managers' in session else dict()

View File

@ -0,0 +1,42 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
from werkzeug.exceptions import HTTPException
from werkzeug.http import HTTP_STATUS_CODES
from flask_babel import gettext as _
from flask import request
from pgadmin.utils.ajax import service_unavailable
class ConnectionLost(HTTPException):
"""
Exception
"""
def __init__(self, _server_id, _database_name, _conn_id):
self.sid = _server_id
self.db = _database_name
self.conn_id = _conn_id
HTTPException.__init__(self)
@property
def name(self):
return HTTP_STATUS_CODES.get(505, 'Service Unavailable')
def get_response(self, environ=None):
return service_unavailable(
_("Connection to the server has been lost!"),
info="CONNECTION_LOST",
data={
'sid': self.sid,
'database': self.db,
'conn_id': self.conn_id
}
)