Fix PEP8 issues in the Tools module. Fixes #3063

pull/7/head
Murtuza Zabuawala 2018-01-26 16:54:21 +00:00 committed by Dave Page
parent de1c767e88
commit 393ce53d2d
15 changed files with 1003 additions and 497 deletions

View File

@ -371,4 +371,3 @@ try:
from config_local import * from config_local import *
except ImportError: except ImportError:
pass pass

View File

@ -36,7 +36,8 @@ from pgadmin import create_app
from pgadmin.utils import u, fs_encoding, file_quote from pgadmin.utils import u, fs_encoding, file_quote
if config.DEBUG: if config.DEBUG:
from pgadmin.utils.javascript.javascript_bundler import JavascriptBundler, JsState from pgadmin.utils.javascript.javascript_bundler import \
JavascriptBundler, JsState
# Get the config database schema version. We store this in pgadmin.model # Get the config database schema version. We store this in pgadmin.model
# as it turns out that putting it in the config files isn't a great idea # as it turns out that putting it in the config files isn't a great idea
@ -50,7 +51,8 @@ config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
# Check if the database exists. If it does not, create it. # Check if the database exists. If it does not, create it.
if not os.path.isfile(config.SQLITE_PATH): if not os.path.isfile(config.SQLITE_PATH):
setupfile = os.path.join( setupfile = os.path.join(
os.path.dirname(os.path.realpath(u(__file__, fs_encoding))), u'setup.py' os.path.dirname(os.path.realpath(u(__file__, fs_encoding))),
u'setup.py'
) )
exec(open(file_quote(setupfile), 'r').read()) exec(open(file_quote(setupfile), 'r').read())
@ -75,7 +77,9 @@ else:
if config.DEBUG: if config.DEBUG:
if javascriptBundler.report() == JsState.NONE: if javascriptBundler.report() == JsState.NONE:
app.logger.error("Unable to generate javascript") app.logger.error("Unable to generate javascript")
app.logger.error("To run the app ensure that yarn install command runs successfully") app.logger.error(
"To run the app ensure that yarn install command runs successfully"
)
raise Exception("No generated javascript, aborting") raise Exception("No generated javascript, aborting")
# Start the web server. The port number should have already been set by the # Start the web server. The port number should have already been set by the
@ -83,20 +87,24 @@ if config.DEBUG:
# Flask default. # Flask default.
PGADMIN_RUNTIME = False PGADMIN_RUNTIME = False
if 'PGADMIN_PORT' in globals(): if 'PGADMIN_PORT' in globals():
app.logger.debug('Running under the desktop runtime, port: %s', app.logger.debug(
globals()['PGADMIN_PORT']) 'Running under the desktop runtime, port: %s',
globals()['PGADMIN_PORT']
)
server_port = int(globals()['PGADMIN_PORT']) server_port = int(globals()['PGADMIN_PORT'])
PGADMIN_RUNTIME = True PGADMIN_RUNTIME = True
elif 'PGADMIN_PORT' in os.environ: elif 'PGADMIN_PORT' in os.environ:
port = os.environ['PGADMIN_PORT'] port = os.environ['PGADMIN_PORT']
app.logger.debug( app.logger.debug(
'Not running under the desktop runtime, port: %s', 'Not running under the desktop runtime, port: %s',
port) port
)
server_port = int(port) server_port = int(port)
else: else:
app.logger.debug( app.logger.debug(
'Not running under the desktop runtime, port: %s', 'Not running under the desktop runtime, port: %s',
config.DEFAULT_SERVER_PORT) config.DEFAULT_SERVER_PORT
)
server_port = config.DEFAULT_SERVER_PORT server_port = config.DEFAULT_SERVER_PORT
# Let the application save the status about the runtime for using it later. # Let the application save the status about the runtime for using it later.
@ -113,8 +121,10 @@ else:
# If we're under WSGI, we don't need to worry about this # If we're under WSGI, we don't need to worry about this
if __name__ == '__main__': if __name__ == '__main__':
if not PGADMIN_RUNTIME: if not PGADMIN_RUNTIME:
print("Starting %s. Please navigate to http://%s:%d in your browser." % print(
(config.APP_NAME, config.DEFAULT_SERVER, server_port)) "Starting %s. Please navigate to http://%s:%d in your browser." %
(config.APP_NAME, config.DEFAULT_SERVER, server_port)
)
sys.stdout.flush() sys.stdout.flush()
else: else:
# For unknown reason the Qt runtime does not pass the environment # For unknown reason the Qt runtime does not pass the environment

View File

@ -10,7 +10,8 @@
"""The main pgAdmin module. This handles the application initialisation tasks, """The main pgAdmin module. This handles the application initialisation tasks,
such as setup of logging, dynamic loading of modules etc.""" such as setup of logging, dynamic loading of modules etc."""
import logging import logging
import os, sys import os
import sys
from collections import defaultdict from collections import defaultdict
from importlib import import_module from importlib import import_module
@ -217,7 +218,7 @@ def create_app(app_name=None):
# Set SQLITE_PATH to TEST_SQLITE_PATH while running test cases # Set SQLITE_PATH to TEST_SQLITE_PATH while running test cases
if "PGADMIN_TESTING_MODE" in os. environ and \ if "PGADMIN_TESTING_MODE" in os. environ and \
os.environ["PGADMIN_TESTING_MODE"] == "1": os.environ["PGADMIN_TESTING_MODE"] == "1":
config.SQLITE_PATH = config.TEST_SQLITE_PATH config.SQLITE_PATH = config.TEST_SQLITE_PATH
# Ensure the various working directories exist # Ensure the various working directories exist
@ -280,7 +281,9 @@ def create_app(app_name=None):
elif hasattr(session, 'PGADMIN_LANGUAGE'): elif hasattr(session, 'PGADMIN_LANGUAGE'):
language = getattr(session, 'PGADMIN_LANGUAGE', language) language = getattr(session, 'PGADMIN_LANGUAGE', language)
elif hasattr(request.cookies, 'PGADMIN_LANGUAGE'): elif hasattr(request.cookies, 'PGADMIN_LANGUAGE'):
language = getattr(request.cookies, 'PGADMIN_LANGUAGE', language) language = getattr(
request.cookies, 'PGADMIN_LANGUAGE', language
)
return language return language
@ -332,15 +335,20 @@ def create_app(app_name=None):
# Setup security # Setup security
########################################################################## ##########################################################################
with app.app_context(): with app.app_context():
config.CSRF_SESSION_KEY = Keys.query.filter_by(name = 'CSRF_SESSION_KEY').first().value config.CSRF_SESSION_KEY = Keys.query.filter_by(
config.SECRET_KEY = Keys.query.filter_by(name = 'SECRET_KEY').first().value name='CSRF_SESSION_KEY').first().value
config.SECURITY_PASSWORD_SALT = Keys.query.filter_by(name = 'SECURITY_PASSWORD_SALT').first().value config.SECRET_KEY = Keys.query.filter_by(
name='SECRET_KEY').first().value
config.SECURITY_PASSWORD_SALT = Keys.query.filter_by(
name='SECURITY_PASSWORD_SALT').first().value
# Update the app.config with proper security keyes for signing CSRF data, # Update the app.config with proper security keyes for signing CSRF data,
# signing cookies, and the SALT for hashing the passwords. # signing cookies, and the SALT for hashing the passwords.
app.config.update(dict(CSRF_SESSION_KEY=config.CSRF_SESSION_KEY)) app.config.update(dict({
app.config.update(dict(SECRET_KEY=config.SECRET_KEY)) 'CSRF_SESSION_KEY': config.CSRF_SESSION_KEY,
app.config.update(dict(SECURITY_PASSWORD_SALT=config.SECURITY_PASSWORD_SALT)) 'SECRET_KEY': config.SECRET_KEY,
'SECURITY_PASSWORD_SALT': config.SECURITY_PASSWORD_SALT
}))
security.init_app(app, user_datastore) security.init_app(app, user_datastore)
@ -376,7 +384,6 @@ def create_app(app_name=None):
if user_languages and language: if user_languages and language:
language = user_languages.set(language) language = user_languages.set(language)
########################################################################## ##########################################################################
# Register any local servers we can discover # Register any local servers we can discover
########################################################################## ##########################################################################
@ -397,25 +404,25 @@ def create_app(app_name=None):
'''Add a server to the config database''' '''Add a server to the config database'''
def add_server(user_id, servergroup_id, name, superuser, port, discovery_id, comment): def add_server(user_id, servergroup_id, name, superuser, port, discovery_id, comment):
# Create a server object if needed, and store it. # Create a server object if needed, and store it.
servers = Server.query.filter_by( servers = Server.query.filter_by(
user_id=user_id, user_id=user_id,
discovery_id=svr_discovery_id discovery_id=svr_discovery_id
).order_by("id") ).order_by("id")
if servers.count() > 0: if servers.count() > 0:
return; return
svr = Server(user_id=user_id, svr = Server(user_id=user_id,
servergroup_id=servergroup_id, servergroup_id=servergroup_id,
name=name, name=name,
host='localhost', host='localhost',
port=port, port=port,
maintenance_db='postgres', maintenance_db='postgres',
username=superuser, username=superuser,
ssl_mode='prefer', ssl_mode='prefer',
comment=svr_comment, comment=svr_comment,
discovery_id=discovery_id) discovery_id=discovery_id)
db.session.add(svr) db.session.add(svr)
db.session.commit() db.session.commit()
@ -505,7 +512,8 @@ def create_app(app_name=None):
description, description,
data_directory data_directory
)) ))
add_server(user_id, servergroup_id, svr_name, svr_superuser, svr_port, svr_discovery_id, svr_comment) add_server(user_id, servergroup_id, svr_name,
svr_superuser, svr_port, svr_discovery_id, svr_comment)
except: except:
pass pass
@ -564,7 +572,7 @@ def create_app(app_name=None):
# Minify output # Minify output
########################################################################## ##########################################################################
# HTMLMIN doesn't work with Python 2.6. # HTMLMIN doesn't work with Python 2.6.
if not config.DEBUG and sys.version_info >= (2,7): if not config.DEBUG and sys.version_info >= (2, 7):
from flask_htmlmin import HTMLMIN from flask_htmlmin import HTMLMIN
HTMLMIN(app) HTMLMIN(app)

View File

@ -18,27 +18,28 @@ from pgadmin.utils.ajax import bad_request
MODULE_NAME = 'tools' MODULE_NAME = 'tools'
class ToolsModule(PgAdminModule): class ToolsModule(PgAdminModule):
def get_own_javascripts(self): def get_own_javascripts(self):
return [{ return [{
'name': 'translations', 'name': 'translations',
'path': url_for('tools.index') + "translations", 'path': url_for('tools.index') + "translations",
'when': None 'when': None
},{ }, {
'name': 'pgadmin-sqlfoldcode', 'name': 'pgadmin-sqlfoldcode',
'path': url_for( 'path': url_for(
'static', 'static',
filename='js/codemirror/addon/fold/pgadmin-sqlfoldcode' filename='js/codemirror/addon/fold/pgadmin-sqlfoldcode'
), ),
'when': 'debugger' 'when': 'debugger'
},{ }, {
'name': 'slick.pgadmin.editors', 'name': 'slick.pgadmin.editors',
'path': url_for( 'path': url_for(
'static', 'static',
filename='js/slickgrid/slick.pgadmin.editors' filename='js/slickgrid/slick.pgadmin.editors'
), ),
'when': 'debugger' 'when': 'debugger'
},{ }, {
'name': 'slick.pgadmin.formatters', 'name': 'slick.pgadmin.formatters',
'path': url_for( 'path': url_for(
'static', 'static',
@ -47,6 +48,7 @@ class ToolsModule(PgAdminModule):
'when': 'debugger' 'when': 'debugger'
}] }]
# Initialise the module # Initialise the module
blueprint = ToolsModule(MODULE_NAME, __name__) blueprint = ToolsModule(MODULE_NAME, __name__)
@ -56,10 +58,16 @@ def index():
"""Calling tools index URL directly is not allowed.""" """Calling tools index URL directly is not allowed."""
return bad_request(gettext('This URL cannot be requested directly.')) return bad_request(gettext('This URL cannot be requested directly.'))
@blueprint.route("/translations.js") @blueprint.route("/translations.js")
def translations(): def translations():
"""Return a js file that will handle translations so Flask interpolation can be isolated""" """Return a js file that will handle translations so Flask interpolation
template = render_template("js/translations.js", translations=get_translations()._catalog) can be isolated
"""
template = render_template(
"js/translations.js",
translations=get_translations()._catalog
)
return Response( return Response(
response=template, response=template,
status=200, status=200,

View File

@ -194,6 +194,7 @@ class BackupMessage(IProcessDesc):
return res return res
@blueprint.route("/") @blueprint.route("/")
@login_required @login_required
def index(): def index():
@ -348,7 +349,8 @@ def create_backup_objects_job(sid):
Args: Args:
sid: Server ID sid: Server ID
Creates a new job for backup task (Backup Database(s)/Schema(s)/Table(s)) Creates a new job for backup task
(Backup Database(s)/Schema(s)/Table(s))
Returns: Returns:
None None

View File

@ -28,6 +28,7 @@ from config import PG_DEFAULT_DRIVER
from pgadmin.utils.preferences import Preferences from pgadmin.utils.preferences import Preferences
from pgadmin.model import Server from pgadmin.model import Server
class DataGridModule(PgAdminModule): class DataGridModule(PgAdminModule):
""" """
class DataGridModule(PgAdminModule) class DataGridModule(PgAdminModule)
@ -72,7 +73,9 @@ blueprint = DataGridModule(MODULE_NAME, __name__, static_url_path='/static')
@blueprint.route("/") @blueprint.route("/")
@login_required @login_required
def index(): def index():
return bad_request(errormsg=gettext('This URL cannot be requested directly.')) return bad_request(
errormsg=gettext('This URL cannot be requested directly.')
)
@blueprint.route("/css/datagrid.css") @blueprint.route("/css/datagrid.css")
@ -90,8 +93,10 @@ def show_filter():
@blueprint.route( @blueprint.route(
'/initialize/datagrid/<int:cmd_type>/<obj_type>/<int:sid>/<int:did>/<int:obj_id>', '/initialize/datagrid/<int:cmd_type>/<obj_type>/<int:sid>/<int:did>/'
methods=["PUT", "POST"], endpoint="initialize_datagrid" '<int:obj_id>',
methods=["PUT", "POST"],
endpoint="initialize_datagrid"
) )
@login_required @login_required
def initialize_datagrid(cmd_type, obj_type, sid, did, obj_id): def initialize_datagrid(cmd_type, obj_type, sid, did, obj_id):
@ -103,7 +108,9 @@ def initialize_datagrid(cmd_type, obj_type, sid, did, obj_id):
Args: Args:
cmd_type: Contains value for which menu item is clicked. cmd_type: Contains value for which menu item is clicked.
obj_type: Contains type of selected object for which data grid to be render obj_type: Contains type of selected object for which data grid to
be render
sid: Server Id sid: Server Id
did: Database Id did: Database Id
obj_id: Id of currently selected object obj_id: Id of currently selected object
@ -135,9 +142,11 @@ def initialize_datagrid(cmd_type, obj_type, sid, did, obj_id):
obj_type = 'table' obj_type = 'table'
# Get the object as per the object type # Get the object as per the object type
command_obj = ObjectRegistry.get_object(obj_type, conn_id=conn_id, sid=sid, command_obj = ObjectRegistry.get_object(
did=did, obj_id=obj_id, cmd_type=cmd_type, obj_type, conn_id=conn_id, sid=sid,
sql_filter=filter_sql) did=did, obj_id=obj_id, cmd_type=cmd_type,
sql_filter=filter_sql
)
except Exception as e: except Exception as e:
return internal_server_error(errormsg=str(e)) return internal_server_error(errormsg=str(e))
@ -162,8 +171,12 @@ def initialize_datagrid(cmd_type, obj_type, sid, did, obj_id):
pref = Preferences.module('sqleditor') pref = Preferences.module('sqleditor')
new_browser_tab = pref.preference('new_browser_tab').get() new_browser_tab = pref.preference('new_browser_tab').get()
return make_json_response(data={'gridTransId': trans_id, return make_json_response(
'newBrowserTab': new_browser_tab}) data={
'gridTransId': trans_id,
'newBrowserTab': new_browser_tab
}
)
@blueprint.route( @blueprint.route(
@ -199,9 +212,9 @@ def panel(trans_id, is_query_tool, editor_title):
Animations and transitions are not automatically GPU accelerated and by Animations and transitions are not automatically GPU accelerated and by
default use browser's slow rendering engine. We need to set 'translate3d' default use browser's slow rendering engine. We need to set 'translate3d'
value of '-webkit-transform' property in order to use GPU. After applying value of '-webkit-transform' property in order to use GPU. After applying
this property under linux, Webkit calculates wrong position of the elements this property under linux, Webkit calculates wrong position of the
so panel contents are not visible. To make it work, we need to explicitly elements so panel contents are not visible. To make it work, we need to
set '-webkit-transform' property to 'none' for .ajs-notifier, explicitly set '-webkit-transform' property to 'none' for .ajs-notifier,
.ajs-message, .ajs-modal classes. .ajs-message, .ajs-modal classes.
This issue is only with linux runtime application and observed in Query This issue is only with linux runtime application and observed in Query
@ -228,7 +241,9 @@ def panel(trans_id, is_query_tool, editor_title):
'prompt_save_query_changes' 'prompt_save_query_changes'
).get() ).get()
else: else:
prompt_save_changes = pref.preference('prompt_save_data_changes').get() prompt_save_changes = pref.preference(
'prompt_save_data_changes'
).get()
display_connection_status = pref.preference('connection_status').get() display_connection_status = pref.preference('connection_status').get()
@ -242,8 +257,9 @@ def panel(trans_id, is_query_tool, editor_title):
trans_obj = pickle.loads(session_obj['command_obj']) trans_obj = pickle.loads(session_obj['command_obj'])
s = Server.query.filter_by(id=trans_obj.sid).first() s = Server.query.filter_by(id=trans_obj.sid).first()
if s and s.bgcolor: if s and s.bgcolor:
# If background is set to white means we do not have to change the # If background is set to white means we do not have to change
# title background else change it as per user specified background # the title background else change it as per user specified
# background
if s.bgcolor != '#ffffff': if s.bgcolor != '#ffffff':
bgcolor = s.bgcolor bgcolor = s.bgcolor
fgcolor = s.fgcolor or 'black' fgcolor = s.fgcolor or 'black'
@ -262,8 +278,8 @@ def panel(trans_id, is_query_tool, editor_title):
client_platform=user_agent.platform, client_platform=user_agent.platform,
bgcolor=bgcolor, bgcolor=bgcolor,
fgcolor=fgcolor, fgcolor=fgcolor,
# convert python boolean value to equivalent js boolean literal before # convert python boolean value to equivalent js boolean literal
# passing it to html template. # before passing it to html template.
prompt_save_changes='true' if prompt_save_changes else 'false', prompt_save_changes='true' if prompt_save_changes else 'false',
display_connection_status=display_connection_status display_connection_status=display_connection_status
) )
@ -305,7 +321,9 @@ def initialize_query_tool(sid, did=None):
) )
try: try:
command_obj = ObjectRegistry.get_object('query_tool', sid=sid, did=did) command_obj = ObjectRegistry.get_object(
'query_tool', sid=sid, did=did
)
except Exception as e: except Exception as e:
return internal_server_error(errormsg=str(e)) return internal_server_error(errormsg=str(e))
@ -320,7 +338,8 @@ def initialize_query_tool(sid, did=None):
# Use pickle to store the command object which will be used # Use pickle to store the command object which will be used
# later by the sql grid module. # later by the sql grid module.
sql_grid_data[trans_id] = { sql_grid_data[trans_id] = {
'command_obj': pickle.dumps(command_obj, -1) # -1 specify the highest protocol version available # -1 specify the highest protocol version available
'command_obj': pickle.dumps(command_obj, -1)
} }
# Store the grid dictionary into the session variable # Store the grid dictionary into the session variable
@ -329,8 +348,12 @@ def initialize_query_tool(sid, did=None):
pref = Preferences.module('sqleditor') pref = Preferences.module('sqleditor')
new_browser_tab = pref.preference('new_browser_tab').get() new_browser_tab = pref.preference('new_browser_tab').get()
return make_json_response(data={'gridTransId': trans_id, return make_json_response(
'newBrowserTab': new_browser_tab}) data={
'gridTransId': trans_id,
'newBrowserTab': new_browser_tab
}
)
@blueprint.route('/close/<int:trans_id>', methods=["GET"], endpoint='close') @blueprint.route('/close/<int:trans_id>', methods=["GET"], endpoint='close')
@ -356,8 +379,10 @@ def close(trans_id):
# if connection id is None then no need to release the connection # if connection id is None then no need to release the connection
if cmd_obj.conn_id is not None: if cmd_obj.conn_id is not None:
try: try:
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(cmd_obj.sid) manager = get_driver(
conn = manager.connection(did=cmd_obj.did, conn_id=cmd_obj.conn_id) PG_DEFAULT_DRIVER).connection_manager(cmd_obj.sid)
conn = manager.connection(
did=cmd_obj.did, conn_id=cmd_obj.conn_id)
except Exception as e: except Exception as e:
return internal_server_error(errormsg=str(e)) return internal_server_error(errormsg=str(e))
@ -365,16 +390,18 @@ def close(trans_id):
if conn.connected(): if conn.connected():
manager.release(did=cmd_obj.did, conn_id=cmd_obj.conn_id) manager.release(did=cmd_obj.did, conn_id=cmd_obj.conn_id)
# Remove the information of unique transaction id from the session variable. # Remove the information of unique transaction id from the
# session variable.
grid_data.pop(str(trans_id), None) grid_data.pop(str(trans_id), None)
session['gridData'] = grid_data session['gridData'] = grid_data
return make_json_response(data={'status': True}) return make_json_response(data={'status': True})
@blueprint.route('/filter/validate/<int:sid>/<int:did>/<int:obj_id>', @blueprint.route(
methods=["PUT", "POST"], endpoint='filter_validate' '/filter/validate/<int:sid>/<int:did>/<int:obj_id>',
) methods=["PUT", "POST"], endpoint='filter_validate'
)
@login_required @login_required
def validate_filter(sid, did, obj_id): def validate_filter(sid, did, obj_id):
""" """
@ -408,6 +435,6 @@ def script():
"""render the required javascript""" """render the required javascript"""
return Response( return Response(
response=render_template("datagrid/js/datagrid.js", _=gettext), response=render_template("datagrid/js/datagrid.js", _=gettext),
status=200, mimetype="application/javascript" status=200,
mimetype="application/javascript"
) )

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@ from config import PG_DEFAULT_DRIVER
try: try:
from urllib import unquote from urllib import unquote
except: except ImportError:
from urllib.parse import unquote from urllib.parse import unquote
from pgadmin.utils.ajax import precondition_required from pgadmin.utils.ajax import precondition_required
from functools import wraps from functools import wraps
@ -136,9 +136,11 @@ def check_precondition(f):
server_info['server_type'] = server_info['manager'].server_type server_info['server_type'] = server_info['manager'].server_type
server_info['version'] = server_info['manager'].version server_info['version'] = server_info['manager'].version
if server_info['server_type'] == 'pg': if server_info['server_type'] == 'pg':
server_info['template_path'] = 'grant_wizard/pg/#{0}#'.format(server_info['version']) server_info['template_path'] = 'grant_wizard/pg/#{0}#'.format(
server_info['version'])
elif server_info['server_type'] == 'ppas': elif server_info['server_type'] == 'ppas':
server_info['template_path'] = 'grant_wizard/ppas/#{0}#'.format(server_info['version']) server_info['template_path'] = 'grant_wizard/ppas/#{0}#'.format(
server_info['version'])
return f(*args, **kwargs) return f(*args, **kwargs)
@ -240,8 +242,8 @@ def properties(sid, did, node_id, node_type):
# Fetch procedures only if server type is ppas # Fetch procedures only if server type is ppas
if (len(server_prop) > 0 and if (len(server_prop) > 0 and
server_prop['server_type'] == 'ppas' and server_prop['server_type'] == 'ppas' and
ntype in ['schema', 'procedure']): ntype in ['schema', 'procedure']):
SQL = render_template("/".join( SQL = render_template("/".join(
[server_prop['template_path'], '/sql/function.sql']), [server_prop['template_path'], '/sql/function.sql']),
node_id=node_id, type='procedure') node_id=node_id, type='procedure')

View File

@ -88,7 +88,7 @@ class IEMessage(IProcessDesc):
x = x.replace('"', '\\"') x = x.replace('"', '\\"')
x = x.replace('""', '\\"') x = x.replace('""', '\\"')
return ' "' + x + '"' return ' "' + x + '"'
return '' return ''
replace_next = False replace_next = False
@ -219,7 +219,6 @@ def create_import_export_job(sid):
if server is None: if server is None:
return bad_request(errormsg=_("Could not find the given server")) return bad_request(errormsg=_("Could not find the given server"))
# To fetch MetaData for the server # To fetch MetaData for the server
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
driver = get_driver(PG_DEFAULT_DRIVER) driver = get_driver(PG_DEFAULT_DRIVER)
@ -238,7 +237,8 @@ def create_import_export_job(sid):
if 'filename' in data: if 'filename' in data:
try: try:
_file = filename_with_file_manager_path(data['filename'], data['is_import']) _file = filename_with_file_manager_path(
data['filename'], data['is_import'])
except Exception as e: except Exception as e:
return bad_request(errormsg=str(e)) return bad_request(errormsg=str(e))
@ -306,6 +306,7 @@ def create_import_export_job(sid):
cmd=utility, args=args cmd=utility, args=args
) )
manager.export_password_env(p.id) manager.export_password_env(p.id)
def export_pg_env(env): def export_pg_env(env):
env['PGHOST'] = server.host env['PGHOST'] = server.host
env['PGPORT'] = str(server.port) env['PGPORT'] = str(server.port)

View File

@ -120,8 +120,8 @@ class Message(IProcessDesc):
if self.data['op'] == "REINDEX": if self.data['op'] == "REINDEX":
if 'schema' in self.data and self.data['schema']: if 'schema' in self.data and self.data['schema']:
if 'primary_key' in self.data or\ if 'primary_key' in self.data or\
'unique_constraint' in self.data or\ 'unique_constraint' in self.data or\
'index' in self.data: 'index' in self.data:
return _('REINDEX INDEX') return _('REINDEX INDEX')
else: else:
return _('REINDEX TABLE') return _('REINDEX TABLE')
@ -248,5 +248,6 @@ def create_maintenance_job(sid, did):
# Return response # Return response
return make_json_response( return make_json_response(
data={'job_id': jid, 'status': True, 'info': 'Maintenance job created.'} data={'job_id': jid, 'status': True,
'info': 'Maintenance job created.'}
) )

View File

@ -58,6 +58,7 @@ class RestoreModule(PgAdminModule):
""" """
return ['restore.create_job'] return ['restore.create_job']
# Create blueprint for RestoreModule class # Create blueprint for RestoreModule class
blueprint = RestoreModule( blueprint = RestoreModule(
MODULE_NAME, __name__, static_url_path='' MODULE_NAME, __name__, static_url_path=''
@ -76,7 +77,7 @@ class RestoreMessage(IProcessDesc):
x = x.replace('\\', '\\\\') x = x.replace('\\', '\\\\')
x = x.replace('"', '\\"') x = x.replace('"', '\\"')
x = x.replace('""', '\\"') x = x.replace('""', '\\"')
return ' "' + x + '"' return ' "' + x + '"'
return '' return ''
for arg in _args: for arg in _args:
@ -85,7 +86,6 @@ class RestoreMessage(IProcessDesc):
else: else:
self.cmd += cmdArg(arg) self.cmd += cmdArg(arg)
@property @property
def message(self): def message(self):
# Fetch the server details like hostname, port, roles etc # Fetch the server details like hostname, port, roles etc
@ -324,7 +324,7 @@ def create_restore_job(sid):
data['file'].encode('utf-8') if hasattr( data['file'].encode('utf-8') if hasattr(
data['file'], 'encode' data['file'], 'encode'
) else data['file'], ) else data['file'],
*args *args
), ),
cmd=utility, args=args cmd=utility, args=args
) )

View File

@ -59,6 +59,7 @@ CONNECTION_STATUS_MESSAGE_MAPPING = dict({
4: 'The connection with the server is bad.' 4: 'The connection with the server is bad.'
}) })
class SqlEditorModule(PgAdminModule): class SqlEditorModule(PgAdminModule):
""" """
class SqlEditorModule(PgAdminModule) class SqlEditorModule(PgAdminModule)
@ -85,7 +86,6 @@ class SqlEditorModule(PgAdminModule):
'when': None 'when': None
}] }]
def get_panels(self): def get_panels(self):
return [] return []
@ -128,10 +128,10 @@ class SqlEditorModule(PgAdminModule):
max_val=999999, max_val=999999,
help_str=gettext( help_str=gettext(
'The length of time to display the query info notifier after ' 'The length of time to display the query info notifier after '
'execution has completed. A value of -1 disables the notifier ' 'execution has completed. A value of -1 disables the notifier'
'and a value of 0 displays it until clicked. Values greater ' ' and a value of 0 displays it until clicked. Values greater'
'than 0 display the notifier for the number of seconds ' ' than 0 display the notifier for the number of seconds'
'specified.' ' specified.'
) )
) )
@ -356,10 +356,13 @@ class SqlEditorModule(PgAdminModule):
gettext("Connection status refresh rate"), 'integer', 2, gettext("Connection status refresh rate"), 'integer', 2,
min_val=1, max_val=600, min_val=1, max_val=600,
category_label=gettext('Display'), category_label=gettext('Display'),
help_str=gettext('The number of seconds between connection/transaction ' help_str=gettext(
'status polls.') 'The number of seconds between connection/transaction '
'status polls.'
)
) )
blueprint = SqlEditorModule(MODULE_NAME, __name__, static_url_path='/static') blueprint = SqlEditorModule(MODULE_NAME, __name__, static_url_path='/static')
@ -392,7 +395,7 @@ def check_transaction_status(trans_id):
""" """
if 'gridData' not in session: if 'gridData' not in session:
return False, unauthorized(gettext("Unauthorized request.")), \ return False, unauthorized(gettext("Unauthorized request.")), \
None, None, None None, None, None
grid_data = session['gridData'] grid_data = session['gridData']
@ -408,23 +411,28 @@ def check_transaction_status(trans_id):
trans_obj = pickle.loads(session_obj['command_obj']) trans_obj = pickle.loads(session_obj['command_obj'])
try: try:
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid) manager = get_driver(
conn = manager.connection(did=trans_obj.did, conn_id=trans_obj.conn_id, PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid)
use_binary_placeholder=True, conn = manager.connection(
array_to_string=True) did=trans_obj.did,
conn_id=trans_obj.conn_id,
use_binary_placeholder=True,
array_to_string=True
)
except Exception as e: except Exception as e:
return False, internal_server_error(errormsg=str(e)), None, None, None return False, internal_server_error(errormsg=str(e)), None, None, None
if conn.connected(): if conn.connected():
return True, None, conn, trans_obj, session_obj return True, None, conn, trans_obj, session_obj
else: else:
return False, gettext('Not connected to server or connection with the server has been closed.'), \ return False, gettext('Not connected to server or connection with '
None, trans_obj, session_obj 'the server has been closed.'), \
None, trans_obj, session_obj
@blueprint.route( @blueprint.route(
'/view_data/start/<int:trans_id>', '/view_data/start/<int:trans_id>',
methods=["GET"], endpoint='view_data_start' methods=["GET"], endpoint='view_data_start'
) )
@login_required @login_required
def start_view_data(trans_id): def start_view_data(trans_id):
@ -437,7 +445,8 @@ def start_view_data(trans_id):
limit = -1 limit = -1
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
# get the default connection as current connection which is attached to # get the default connection as current connection which is attached to
# trans id holds the cursor which has query result so we cannot use that # trans id holds the cursor which has query result so we cannot use that
@ -568,7 +577,8 @@ def start_query_tool(trans_id):
conn_id = str(random.randint(1, 9999999)) conn_id = str(random.randint(1, 9999999))
try: try:
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid) manager = get_driver(
PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid)
conn = manager.connection(did=trans_obj.did, conn_id=conn_id, conn = manager.connection(did=trans_obj.did, conn_id=conn_id,
use_binary_placeholder=True, use_binary_placeholder=True,
array_to_string=True) array_to_string=True)
@ -611,14 +621,17 @@ def start_query_tool(trans_id):
conn.execute_void("ROLLBACK;") conn.execute_void("ROLLBACK;")
else: else:
status = False status = False
result = gettext('Not connected to server or connection with the server has been closed.') result = gettext(
'Not connected to server or connection with the server has '
'been closed.')
can_edit = trans_obj.can_edit() can_edit = trans_obj.can_edit()
can_filter = trans_obj.can_filter() can_filter = trans_obj.can_filter()
else: else:
status = False status = False
result = gettext('Either transaction object or session object not found.') result = gettext(
'Either transaction object or session object not found.')
return make_json_response( return make_json_response(
data={ data={
@ -644,10 +657,12 @@ def preferences(trans_id):
if request.method == 'GET': if request.method == 'GET':
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
# Call the set_auto_commit and set_auto_rollback method of transaction object # Call the set_auto_commit and set_auto_rollback method of
# transaction object
trans_obj.set_auto_commit(blueprint.auto_commit.get()) trans_obj.set_auto_commit(blueprint.auto_commit.get())
trans_obj.set_auto_rollback(blueprint.auto_rollback.get()) trans_obj.set_auto_rollback(blueprint.auto_rollback.get())
@ -690,7 +705,8 @@ def preferences(trans_id):
@login_required @login_required
def poll(trans_id): def poll(trans_id):
""" """
This method polls the result of the asynchronous query and returns the result. This method polls the result of the asynchronous query and returns
the result.
Args: Args:
trans_id: unique transaction id trans_id: unique transaction id
@ -710,9 +726,11 @@ def poll(trans_id):
oids = None oids = None
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None and session_obj is not None: if status and conn is not None and session_obj is not None:
status, result = conn.poll(formatted_exception_msg=True, no_result=True) status, result = conn.poll(
formatted_exception_msg=True, no_result=True)
if not status: if not status:
return internal_server_error(result) return internal_server_error(result)
elif status == ASYNC_OK: elif status == ASYNC_OK:
@ -821,10 +839,12 @@ def poll(trans_id):
if res_len > 0: if res_len > 0:
rows_fetched_from = trans_obj.get_fetched_row_cnt() rows_fetched_from = trans_obj.get_fetched_row_cnt()
trans_obj.update_fetched_row_cnt(rows_fetched_from + res_len) trans_obj.update_fetched_row_cnt(
rows_fetched_from + res_len)
rows_fetched_from += 1 rows_fetched_from += 1
rows_fetched_to = trans_obj.get_fetched_row_cnt() rows_fetched_to = trans_obj.get_fetched_row_cnt()
session_obj['command_obj'] = pickle.dumps(trans_obj, -1) session_obj['command_obj'] = pickle.dumps(
trans_obj, -1)
# As we changed the transaction object we need to # As we changed the transaction object we need to
# restore it and update the session variable. # restore it and update the session variable.
@ -856,7 +876,7 @@ def poll(trans_id):
if status == 'Success' and result is None: if status == 'Success' and result is None:
result = conn.status_message() result = conn.status_message()
if (result != 'SELECT 1' or result != 'SELECT 0') \ if (result != 'SELECT 1' or result != 'SELECT 0') \
and result is not None and additional_messages: and result is not None and additional_messages:
result = additional_messages + result result = additional_messages + result
return make_json_response( return make_json_response(
@ -877,8 +897,13 @@ def poll(trans_id):
) )
@blueprint.route('/fetch/<int:trans_id>', methods=["GET"], endpoint='fetch') @blueprint.route(
@blueprint.route('/fetch/<int:trans_id>/<int:fetch_all>', methods=["GET"], endpoint='fetch_all') '/fetch/<int:trans_id>', methods=["GET"], endpoint='fetch'
)
@blueprint.route(
'/fetch/<int:trans_id>/<int:fetch_all>', methods=["GET"],
endpoint='fetch_all'
)
@login_required @login_required
def fetch(trans_id, fetch_all=None): def fetch(trans_id, fetch_all=None):
result = None result = None
@ -888,7 +913,8 @@ def fetch(trans_id, fetch_all=None):
fetch_row_cnt = -1 if fetch_all == 1 else ON_DEMAND_RECORD_COUNT fetch_row_cnt = -1 if fetch_all == 1 else ON_DEMAND_RECORD_COUNT
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None and session_obj is not None: if status and conn is not None and session_obj is not None:
status, result = conn.async_fetchmany_2darray(fetch_row_cnt) status, result = conn.async_fetchmany_2darray(fetch_row_cnt)
if not status: if not status:
@ -947,8 +973,9 @@ def fetch_pg_types(columns_info, trans_obj):
if oids: if oids:
status, res = default_conn.execute_dict( status, res = default_conn.execute_dict(
u"""SELECT oid, format_type(oid,null) as typname FROM pg_type WHERE oid IN %s ORDER BY oid; u"SELECT oid, format_type(oid,null) as typname FROM pg_type "
""", [tuple(oids)]) u"WHERE oid IN %s ORDER BY oid;", [tuple(oids)]
)
if not status: if not status:
return False, res return False, res
@ -1001,20 +1028,24 @@ def save(trans_id):
changed_data = request.args or request.form changed_data = request.args or request.form
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
# If there is no primary key found then return from the function. # If there is no primary key found then return from the function.
if (len(session_obj['primary_keys']) <= 0 or len(changed_data) <= 0) and 'has_oids' not in session_obj: if (len(session_obj['primary_keys']) <= 0 or len(changed_data) <= 0) \
and 'has_oids' not in session_obj:
return make_json_response( return make_json_response(
data={ data={
'status': False, 'status': False,
'result': gettext('No primary key found for this object, so unable to save records.') 'result': gettext('No primary key found for this object, '
'so unable to save records.')
} }
) )
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid) manager = get_driver(
PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid)
default_conn = manager.connection(did=trans_obj.did) default_conn = manager.connection(did=trans_obj.did)
# Connect to the Server if not connected. # Connect to the Server if not connected.
@ -1059,7 +1090,8 @@ def get_filter(trans_id):
""" """
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
@ -1089,7 +1121,8 @@ def apply_filter(trans_id):
filter_sql = request.args or request.form filter_sql = request.args or request.form
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
@ -1124,7 +1157,8 @@ def append_filter_inclusive(trans_id):
filter_data = request.args or request.form filter_data = request.args or request.form
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
@ -1137,7 +1171,9 @@ def append_filter_inclusive(trans_id):
if column_value is None: if column_value is None:
filter_sql = driver.qtIdent(conn, column_name) + ' IS NULL ' filter_sql = driver.qtIdent(conn, column_name) + ' IS NULL '
else: else:
filter_sql = driver.qtIdent(conn, column_name) + ' = ' + driver.qtLiteral(column_value) filter_sql = driver.qtIdent(
conn, column_name
) + ' = ' + driver.qtLiteral(column_value)
trans_obj.append_filter(filter_sql) trans_obj.append_filter(filter_sql)
@ -1170,7 +1206,8 @@ def append_filter_exclusive(trans_id):
filter_data = request.args or request.form filter_data = request.args or request.form
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
@ -1181,9 +1218,12 @@ def append_filter_exclusive(trans_id):
for column_name in filter_data: for column_name in filter_data:
column_value = filter_data[column_name] column_value = filter_data[column_name]
if column_value is None: if column_value is None:
filter_sql = driver.qtIdent(conn, column_name) + ' IS NOT NULL ' filter_sql = driver.qtIdent(
conn, column_name) + ' IS NOT NULL '
else: else:
filter_sql = driver.qtIdent(conn, column_name) + ' IS DISTINCT FROM ' + driver.qtLiteral(column_value) filter_sql = driver.qtIdent(
conn, column_name
) + ' IS DISTINCT FROM ' + driver.qtLiteral(column_value)
# Call the append_filter method of transaction object # Call the append_filter method of transaction object
trans_obj.append_filter(filter_sql) trans_obj.append_filter(filter_sql)
@ -1213,7 +1253,8 @@ def remove_filter(trans_id):
""" """
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
@ -1250,7 +1291,8 @@ def set_limit(trans_id):
limit = request.args or request.form limit = request.args or request.form
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
@ -1289,7 +1331,8 @@ def cancel_transaction(trans_id):
if str(trans_id) not in grid_data: if str(trans_id) not in grid_data:
return make_json_response( return make_json_response(
data={ data={
'status': False, 'result': gettext('Transaction ID not found in the session.') 'status': False,
'result': gettext('Transaction ID not found in the session.')
} }
) )
@ -1302,7 +1345,8 @@ def cancel_transaction(trans_id):
# Fetch the main connection object for the database. # Fetch the main connection object for the database.
try: try:
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid) manager = get_driver(
PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid)
conn = manager.connection(did=trans_obj.did) conn = manager.connection(did=trans_obj.did)
except Exception as e: except Exception as e:
return internal_server_error(errormsg=str(e)) return internal_server_error(errormsg=str(e))
@ -1318,7 +1362,8 @@ def cancel_transaction(trans_id):
if conn.connected(): if conn.connected():
# on successful connection cancel the running transaction # on successful connection cancel the running transaction
status, result = conn.cancel_transaction(trans_obj.conn_id, trans_obj.did) status, result = conn.cancel_transaction(
trans_obj.conn_id, trans_obj.did)
# Delete connection if we have created it to # Delete connection if we have created it to
# cancel the transaction # cancel the transaction
@ -1326,10 +1371,14 @@ def cancel_transaction(trans_id):
manager.release(did=trans_obj.did) manager.release(did=trans_obj.did)
else: else:
status = False status = False
result = gettext('Not connected to server or connection with the server has been closed.') result = gettext(
'Not connected to server or connection with the server has '
'been closed.'
)
else: else:
status = False status = False
result = gettext('Either transaction object or session object not found.') result = gettext(
'Either transaction object or session object not found.')
return make_json_response( return make_json_response(
data={ data={
@ -1352,10 +1401,10 @@ def get_object_name(trans_id):
""" """
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
res = trans_obj.object_name res = trans_obj.object_name
else: else:
status = False status = False
@ -1382,7 +1431,8 @@ def set_auto_commit(trans_id):
auto_commit = request.args or request.form auto_commit = request.args or request.form
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
@ -1423,7 +1473,8 @@ def set_auto_rollback(trans_id):
auto_rollback = request.args or request.form auto_rollback = request.args or request.form
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
@ -1471,12 +1522,14 @@ def auto_complete(trans_id):
text_before_cursor = data[1] text_before_cursor = data[1]
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = \
check_transaction_status(trans_id)
if status and conn is not None \ if status and conn is not None \
and trans_obj is not None and session_obj is not None: and trans_obj is not None and session_obj is not None:
# Create object of SQLAutoComplete class and pass connection object # Create object of SQLAutoComplete class and pass connection object
auto_complete_obj = SQLAutoComplete(sid=trans_obj.sid, did=trans_obj.did, conn=conn) auto_complete_obj = SQLAutoComplete(
sid=trans_obj.sid, did=trans_obj.did, conn=conn)
# Get the auto completion suggestions. # Get the auto completion suggestions.
res = auto_complete_obj.get_completions(full_sql, text_before_cursor) res = auto_complete_obj.get_completions(full_sql, text_before_cursor)
@ -1491,13 +1544,16 @@ def auto_complete(trans_id):
@login_required @login_required
def script(): def script():
"""render the required javascript""" """render the required javascript"""
return Response(response=render_template("sqleditor/js/sqleditor.js", return Response(
tab_size=blueprint.tab_size.get(), response=render_template(
use_spaces=blueprint.use_spaces.get(), "sqleditor/js/sqleditor.js",
_=gettext), tab_size=blueprint.tab_size.get(),
status=200, use_spaces=blueprint.use_spaces.get(),
mimetype="application/javascript" _=gettext
) ),
status=200,
mimetype="application/javascript"
)
def is_begin_required(query): def is_begin_required(query):
@ -1702,7 +1758,8 @@ def load_file():
def gen(): def gen():
with codecs.open(file_path, 'r', encoding=enc) as fileObj: with codecs.open(file_path, 'r', encoding=enc) as fileObj:
while True: while True:
data = fileObj.read(4194304) # 4MB chunk (4 * 1024 * 1024 Bytes) # 4MB chunk (4 * 1024 * 1024 Bytes)
data = fileObj.read(4194304)
if not data: if not data:
break break
yield data yield data
@ -1815,9 +1872,14 @@ def start_query_download_tool(trans_id):
r.call_on_close(cleanup) r.call_on_close(cleanup)
return r return r
r = Response(gen(quote=blueprint.csv_quoting.get(), r = Response(
quote_char=blueprint.csv_quote_char.get(), gen(
field_separator=blueprint.csv_field_separator.get()), mimetype='text/csv') quote=blueprint.csv_quoting.get(),
quote_char=blueprint.csv_quote_char.get(),
field_separator=blueprint.csv_field_separator.get()
),
mimetype='text/csv'
)
if 'filename' in data and data['filename'] != "": if 'filename' in data and data['filename'] != "":
filename = data['filename'] filename = data['filename']
@ -1851,6 +1913,7 @@ def start_query_download_tool(trans_id):
errormsg=gettext("Transaction status check failed.") errormsg=gettext("Transaction status check failed.")
) )
@blueprint.route( @blueprint.route(
'/status/<int:trans_id>', '/status/<int:trans_id>',
methods=["GET"], methods=["GET"],

View File

@ -67,7 +67,8 @@ class ObjectRegistry(ABCMeta):
return (ObjectRegistry.registry[name])(**kwargs) return (ObjectRegistry.registry[name])(**kwargs)
raise NotImplementedError( raise NotImplementedError(
gettext("This feature has not been implemented for object type '{0}'.").format(name) gettext("This feature has not been implemented for object "
"type '{0}'.").format(name)
) )
@ -157,7 +158,8 @@ class SQLFilter(object):
self.sid = kwargs['sid'] self.sid = kwargs['sid']
self.did = kwargs['did'] self.did = kwargs['did']
self.obj_id = kwargs['obj_id'] self.obj_id = kwargs['obj_id']
self.__row_filter = kwargs['sql_filter'] if 'sql_filter' in kwargs else None self.__row_filter = kwargs['sql_filter'] if 'sql_filter' in kwargs \
else None
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(self.sid) manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(self.sid)
conn = manager.connection(did=self.did) conn = manager.connection(did=self.did)
@ -167,7 +169,10 @@ class SQLFilter(object):
if conn.connected(): if conn.connected():
# Fetch the Namespace Name and object Name # Fetch the Namespace Name and object Name
query = render_template("/".join([self.sql_path, 'objectname.sql']), obj_id=self.obj_id) query = render_template(
"/".join([self.sql_path, 'objectname.sql']),
obj_id=self.obj_id
)
status, result = conn.execute_dict(query) status, result = conn.execute_dict(query)
if not status: if not status:
@ -176,7 +181,10 @@ class SQLFilter(object):
self.nsp_name = result['rows'][0]['nspname'] self.nsp_name = result['rows'][0]['nspname']
self.object_name = result['rows'][0]['relname'] self.object_name = result['rows'][0]['relname']
else: else:
raise Exception(gettext('Not connected to server or connection with the server has been closed.')) raise Exception(gettext(
'Not connected to server or connection with the server '
'has been closed.')
)
def get_filter(self): def get_filter(self):
""" """
@ -248,8 +256,10 @@ class SQLFilter(object):
conn = manager.connection(did=self.did) conn = manager.connection(did=self.did)
if conn.connected(): if conn.connected():
sql = render_template("/".join([self.sql_path, 'validate.sql']), sql = render_template(
nsp_name=self.nsp_name, object_name=self.object_name, row_filter=row_filter) "/".join([self.sql_path, 'validate.sql']),
nsp_name=self.nsp_name, object_name=self.object_name,
row_filter=row_filter)
status, result = conn.execute_scalar(sql) status, result = conn.execute_scalar(sql)
if not status: if not status:
@ -262,6 +272,7 @@ class FetchedRowTracker(object):
""" """
Keeps track of fetched row count. Keeps track of fetched row count.
""" """
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.fetched_rows = 0 self.fetched_rows = 0
@ -285,7 +296,8 @@ class GridCommand(BaseCommand, SQLFilter, FetchedRowTracker):
- Derived class can implement there own logic to get the primary keys. - Derived class can implement there own logic to get the primary keys.
* save() * save()
- Derived class can implement there own logic to save the data into the database. - Derived class can implement there own logic to save the data into the
database.
* set_limit(limit) * set_limit(limit)
- This method sets the limit for SQL query - This method sets the limit for SQL query
@ -311,14 +323,17 @@ class GridCommand(BaseCommand, SQLFilter, FetchedRowTracker):
self.cmd_type = kwargs['cmd_type'] if 'cmd_type' in kwargs else None self.cmd_type = kwargs['cmd_type'] if 'cmd_type' in kwargs else None
self.limit = -1 self.limit = -1
if self.cmd_type == VIEW_FIRST_100_ROWS or self.cmd_type == VIEW_LAST_100_ROWS: if self.cmd_type == VIEW_FIRST_100_ROWS or \
self.cmd_type == VIEW_LAST_100_ROWS:
self.limit = 100 self.limit = 100
def get_primary_keys(self, *args, **kwargs): def get_primary_keys(self, *args, **kwargs):
return None, None return None, None
def save(self, changed_data, default_conn=None): def save(self, changed_data, default_conn=None):
return forbidden(errmsg=gettext("Data cannot be saved for the current object.")) return forbidden(
errmsg=gettext("Data cannot be saved for the current object.")
)
def get_limit(self): def get_limit(self):
""" """
@ -370,14 +385,22 @@ class TableCommand(GridCommand):
sql_filter = self.get_filter() sql_filter = self.get_filter()
if sql_filter is None: if sql_filter is None:
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name, sql = render_template(
nsp_name=self.nsp_name, pk_names=pk_names, cmd_type=self.cmd_type, "/".join([self.sql_path, 'objectquery.sql']),
limit=self.limit, primary_keys=primary_keys, has_oids=has_oids) object_name=self.object_name,
nsp_name=self.nsp_name, pk_names=pk_names,
cmd_type=self.cmd_type, limit=self.limit,
primary_keys=primary_keys, has_oids=has_oids
)
else: else:
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name, sql = render_template(
nsp_name=self.nsp_name, pk_names=pk_names, cmd_type=self.cmd_type, "/".join([self.sql_path, 'objectquery.sql']),
sql_filter=sql_filter, limit=self.limit, primary_keys=primary_keys, object_name=self.object_name,
has_oids=has_oids) nsp_name=self.nsp_name, pk_names=pk_names,
cmd_type=self.cmd_type, sql_filter=sql_filter,
limit=self.limit, primary_keys=primary_keys,
has_oids=has_oids
)
return sql return sql
@ -398,7 +421,10 @@ class TableCommand(GridCommand):
if conn.connected(): if conn.connected():
# Fetch the primary key column names # Fetch the primary key column names
query = render_template("/".join([self.sql_path, 'primary_keys.sql']), obj_id=self.obj_id) query = render_template(
"/".join([self.sql_path, 'primary_keys.sql']),
obj_id=self.obj_id
)
status, result = conn.execute_dict(query) status, result = conn.execute_dict(query)
if not status: if not status:
@ -412,7 +438,10 @@ class TableCommand(GridCommand):
# Remove last character from the string # Remove last character from the string
pk_names = pk_names[:-1] pk_names = pk_names[:-1]
else: else:
raise Exception(gettext('Not connected to server or connection with the server has been closed.')) raise Exception(
gettext('Not connected to server or connection with the '
'server has been closed.')
)
return pk_names, primary_keys return pk_names, primary_keys
@ -436,14 +465,18 @@ class TableCommand(GridCommand):
if conn.connected(): if conn.connected():
# Fetch the table oids status # Fetch the table oids status
query = render_template("/".join([self.sql_path, 'has_oids.sql']), obj_id=self.obj_id) query = render_template(
"/".join([self.sql_path, 'has_oids.sql']), obj_id=self.obj_id)
status, has_oids = conn.execute_scalar(query) status, has_oids = conn.execute_scalar(query)
if not status: if not status:
raise Exception(has_oids) raise Exception(has_oids)
else: else:
raise Exception(gettext('Not connected to server or connection with the server has been closed.')) raise Exception(
gettext('Not connected to server or connection with the '
'server has been closed.')
)
return has_oids return has_oids
@ -493,7 +526,6 @@ class TableCommand(GridCommand):
if len(changed_data[of_type]) < 1: if len(changed_data[of_type]) < 1:
continue continue
column_type = {} column_type = {}
column_data = {} column_data = {}
for each_col in columns_info: for each_col in columns_info:
@ -512,11 +544,16 @@ class TableCommand(GridCommand):
# For newly added rows # For newly added rows
if of_type == 'added': if of_type == 'added':
# Python dict does not honour the inserted item order # Python dict does not honour the inserted item order
# So to insert data in the order, we need to make ordered list of added index # So to insert data in the order, we need to make ordered
# We don't need this mechanism in updated/deleted rows as # list of added index We don't need this mechanism in
# it does not matter in those operations # updated/deleted rows as it does not matter in
added_index = OrderedDict(sorted(changed_data['added_index'].items(), # those operations
key=lambda x: int(x[0]))) added_index = OrderedDict(
sorted(
changed_data['added_index'].items(),
key=lambda x: int(x[0])
)
)
list_of_sql[of_type] = [] list_of_sql[of_type] = []
# When new rows are added, only changed columns data is # When new rows are added, only changed columns data is
@ -528,7 +565,8 @@ class TableCommand(GridCommand):
has_oids = 'oid' in column_type has_oids = 'oid' in column_type
for each_row in added_index: for each_row in added_index:
# Get the row index to match with the added rows dict key # Get the row index to match with the added rows
# dict key
tmp_row_index = added_index[each_row] tmp_row_index = added_index[each_row]
data = changed_data[of_type][tmp_row_index]['data'] data = changed_data[of_type][tmp_row_index]['data']
# Remove our unique tracking key # Remove our unique tracking key
@ -540,22 +578,31 @@ class TableCommand(GridCommand):
# not_null=False and has no default value # not_null=False and has no default value
column_data.update(data) column_data.update(data)
sql = render_template("/".join([self.sql_path, 'insert.sql']), sql = render_template(
data_to_be_saved=column_data, "/".join([self.sql_path, 'insert.sql']),
primary_keys=None, data_to_be_saved=column_data,
object_name=self.object_name, primary_keys=None,
nsp_name=self.nsp_name, object_name=self.object_name,
data_type=column_type, nsp_name=self.nsp_name,
pk_names=pk_names, data_type=column_type,
has_oids=has_oids) pk_names=pk_names,
select_sql = render_template("/".join([self.sql_path, 'select.sql']), has_oids=has_oids
object_name=self.object_name, )
nsp_name=self.nsp_name,
pk_names=pk_names.split(",") if pk_names else None, select_sql = render_template(
has_oids=has_oids) "/".join([self.sql_path, 'select.sql']),
list_of_sql[of_type].append({'sql': sql, 'data': data, object_name=self.object_name,
'client_row': tmp_row_index, nsp_name=self.nsp_name,
'select_sql': select_sql}) pk_names=pk_names.split(",") if pk_names
else None,
has_oids=has_oids
)
list_of_sql[of_type].append({
'sql': sql, 'data': data,
'client_row': tmp_row_index,
'select_sql': select_sql
})
# Reset column data # Reset column data
column_data = {} column_data = {}
@ -565,12 +612,14 @@ class TableCommand(GridCommand):
for each_row in changed_data[of_type]: for each_row in changed_data[of_type]:
data = changed_data[of_type][each_row]['data'] data = changed_data[of_type][each_row]['data']
pk = changed_data[of_type][each_row]['primary_keys'] pk = changed_data[of_type][each_row]['primary_keys']
sql = render_template("/".join([self.sql_path, 'update.sql']), sql = render_template(
data_to_be_saved=data, "/".join([self.sql_path, 'update.sql']),
primary_keys=pk, data_to_be_saved=data,
object_name=self.object_name, primary_keys=pk,
nsp_name=self.nsp_name, object_name=self.object_name,
data_type=column_type) nsp_name=self.nsp_name,
data_type=column_type
)
list_of_sql[of_type].append({'sql': sql, 'data': data}) list_of_sql[of_type].append({'sql': sql, 'data': data})
list_of_rowid.append(data.get(client_primary_key)) list_of_rowid.append(data.get(client_primary_key))
@ -589,8 +638,9 @@ class TableCommand(GridCommand):
# Python3 # Python3
# In Python2, it's already a list & We will also # In Python2, it's already a list & We will also
# fetch column names using index # fetch column names using index
keys = list(changed_data[of_type][each_row].keys()) keys = list(
changed_data[of_type][each_row].keys()
)
no_of_keys = len(keys) no_of_keys = len(keys)
is_first = False is_first = False
# Map index with column name for each row # Map index with column name for each row
@ -599,17 +649,20 @@ class TableCommand(GridCommand):
# Set primary key with label & delete index based # Set primary key with label & delete index based
# mapped key # mapped key
try: try:
row[changed_data['columns'][int(k)]['name']] = v row[changed_data['columns']
[int(k)]['name']] = v
except ValueError: except ValueError:
continue continue
del row[k] del row[k]
sql = render_template("/".join([self.sql_path, 'delete.sql']), sql = render_template(
data=rows_to_delete, "/".join([self.sql_path, 'delete.sql']),
primary_key_labels=keys, data=rows_to_delete,
no_of_keys=no_of_keys, primary_key_labels=keys,
object_name=self.object_name, no_of_keys=no_of_keys,
nsp_name=self.nsp_name) object_name=self.object_name,
nsp_name=self.nsp_name
)
list_of_sql[of_type].append({'sql': sql, 'data': {}}) list_of_sql[of_type].append({'sql': sql, 'data': {}})
for opr, sqls in list_of_sql.items(): for opr, sqls in list_of_sql.items():
@ -627,15 +680,19 @@ class TableCommand(GridCommand):
if not status: if not status:
conn.execute_void('ROLLBACK;') conn.execute_void('ROLLBACK;')
# If we roll backed every thing then update the message for # If we roll backed every thing then update the
# each sql query. # message for each sql query.
for val in query_res: for val in query_res:
if query_res[val]['status']: if query_res[val]['status']:
query_res[val]['result'] = 'Transaction ROLLBACK' query_res[val]['result'] = \
'Transaction ROLLBACK'
# If list is empty set rowid to 1 # If list is empty set rowid to 1
try: try:
_rowid = list_of_rowid[count] if list_of_rowid else 1 if list_of_rowid:
_rowid = list_of_rowid[count]
else:
_rowid = 1
except Exception: except Exception:
_rowid = 0 _rowid = 0
@ -648,29 +705,37 @@ class TableCommand(GridCommand):
if not status: if not status:
conn.execute_void('ROLLBACK;') conn.execute_void('ROLLBACK;')
# If we roll backed every thing then update the message for # If we roll backed every thing then update
# each sql query. # the message for each sql query.
for val in query_res: for val in query_res:
if query_res[val]['status']: if query_res[val]['status']:
query_res[val]['result'] = 'Transaction ROLLBACK' query_res[val]['result'] = \
'Transaction ROLLBACK'
# If list is empty set rowid to 1 # If list is empty set rowid to 1
try: try:
_rowid = list_of_rowid[count] if list_of_rowid else 1 if list_of_rowid:
_rowid = list_of_rowid[count]
else:
_rowid = 1
except Exception: except Exception:
_rowid = 0 _rowid = 0
return status, sel_res, query_res, _rowid return status, sel_res, query_res, _rowid
if 'rows' in sel_res and len(sel_res['rows']) > 0: if 'rows' in sel_res and len(sel_res['rows']) > 0:
row_added = {item['client_row']: sel_res['rows'][0]} row_added = {
item['client_row']: sel_res['rows'][0]}
rows_affected = conn.rows_affected() rows_affected = conn.rows_affected()
# store the result of each query in dictionary # store the result of each query in dictionary
query_res[count] = {'status': status, 'result': None if row_added else res, query_res[count] = {
'sql': sql, 'rows_affected': rows_affected, 'status': status,
'row_added': row_added} 'result': None if row_added else res,
'sql': sql, 'rows_affected': rows_affected,
'row_added': row_added
}
count += 1 count += 1
@ -708,13 +773,19 @@ class ViewCommand(GridCommand):
sql_filter = self.get_filter() sql_filter = self.get_filter()
if sql_filter is None: if sql_filter is None:
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name, sql = render_template(
nsp_name=self.nsp_name, cmd_type=self.cmd_type, "/".join([self.sql_path, 'objectquery.sql']),
limit=self.limit) object_name=self.object_name,
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
limit=self.limit
)
else: else:
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name, sql = render_template(
nsp_name=self.nsp_name, cmd_type=self.cmd_type, "/".join([self.sql_path, 'objectquery.sql']),
sql_filter=sql_filter, limit=self.limit) object_name=self.object_name,
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
sql_filter=sql_filter, limit=self.limit
)
return sql return sql
@ -763,13 +834,19 @@ class ForeignTableCommand(GridCommand):
sql_filter = self.get_filter() sql_filter = self.get_filter()
if sql_filter is None: if sql_filter is None:
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name, sql = render_template(
nsp_name=self.nsp_name, cmd_type=self.cmd_type, "/".join([self.sql_path, 'objectquery.sql']),
limit=self.limit) object_name=self.object_name,
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
limit=self.limit
)
else: else:
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name, sql = render_template(
nsp_name=self.nsp_name, cmd_type=self.cmd_type, "/".join([self.sql_path, 'objectquery.sql']),
sql_filter=sql_filter, limit=self.limit) object_name=self.object_name,
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
sql_filter=sql_filter, limit=self.limit
)
return sql return sql
@ -808,13 +885,19 @@ class CatalogCommand(GridCommand):
sql_filter = self.get_filter() sql_filter = self.get_filter()
if sql_filter is None: if sql_filter is None:
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name, sql = render_template(
nsp_name=self.nsp_name, cmd_type=self.cmd_type, "/".join([self.sql_path, 'objectquery.sql']),
limit=self.limit) object_name=self.object_name,
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
limit=self.limit
)
else: else:
sql = render_template("/".join([self.sql_path, 'objectquery.sql']), object_name=self.object_name, sql = render_template(
nsp_name=self.nsp_name, cmd_type=self.cmd_type, "/".join([self.sql_path, 'objectquery.sql']),
sql_filter=sql_filter, limit=self.limit) object_name=self.object_name,
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
sql_filter=sql_filter, limit=self.limit
)
return sql return sql

View File

@ -51,7 +51,7 @@ class UserManagementModule(PgAdminModule):
'name': 'pgadmin.tools.user_management', 'name': 'pgadmin.tools.user_management',
'path': url_for('user_management.index') + 'user_management', 'path': url_for('user_management.index') + 'user_management',
'when': None 'when': None
},{ }, {
'name': 'pgadmin.user_management.current_user', 'name': 'pgadmin.user_management.current_user',
'path': url_for('user_management.index') + 'current_user', 'path': url_for('user_management.index') + 'current_user',
'when': None, 'when': None,
@ -85,12 +85,14 @@ blueprint = UserManagementModule(
def validate_user(data): def validate_user(data):
new_data = dict() new_data = dict()
email_filter = re.compile("^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9]" email_filter = re.compile(
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9]" "^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9]"
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") "(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9]"
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
)
if ('newPassword' in data and data['newPassword'] != "" and if ('newPassword' in data and data['newPassword'] != "" and
'confirmPassword' in data and data['confirmPassword'] != ""): 'confirmPassword' in data and data['confirmPassword'] != ""):
if data['newPassword'] == data['confirmPassword']: if data['newPassword'] == data['confirmPassword']:
new_data['password'] = encrypt_password(data['newPassword']) new_data['password'] = encrypt_password(data['newPassword'])
@ -132,20 +134,23 @@ def script():
mimetype="application/javascript" mimetype="application/javascript"
) )
@blueprint.route("/current_user.js") @blueprint.route("/current_user.js")
@login_required @login_required
def current_user_info(): def current_user_info():
return Response( return Response(
response=render_template( response=render_template(
"user_management/js/current_user.js", "user_management/js/current_user.js",
is_admin='true' if current_user.has_role("Administrator") else 'false', is_admin='true' if current_user.has_role(
"Administrator") else 'false',
user_id=current_user.id, user_id=current_user.id,
email=current_user.email, email=current_user.email,
name=( name=(
current_user.email.split('@')[0] if config.SERVER_MODE is True current_user.email.split('@')[0] if config.SERVER_MODE is True
else 'postgres' else 'postgres'
), ),
allow_save_password='true' if config.ALLOW_SAVE_PASSWORD else 'false' allow_save_password='true' if config.ALLOW_SAVE_PASSWORD
else 'false'
), ),
status=200, status=200,
mimetype="application/javascript" mimetype="application/javascript"
@ -247,7 +252,9 @@ def create():
) )
@blueprint.route('/user/<int:uid>', methods=['DELETE'], endpoint='delete_user') @blueprint.route(
'/user/<int:uid>', methods=['DELETE'], endpoint='delete_user'
)
@roles_required('Administrator') @roles_required('Administrator')
def delete(uid): def delete(uid):
""" """

View File

@ -41,8 +41,9 @@ if __name__ == '__main__':
config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
if "PGADMIN_TESTING_MODE" in os. environ and \ if "PGADMIN_TESTING_MODE" in os. environ and \
os.environ["PGADMIN_TESTING_MODE"] == "1": os.environ["PGADMIN_TESTING_MODE"] == "1":
config.SQLITE_PATH = config.TEST_SQLITE_PATH config.SQLITE_PATH = config.TEST_SQLITE_PATH
create_app_data_directory(config) create_app_data_directory(config)
app = create_app() app = create_app()