public inbox for [email protected]help / color / mirror / Atom feed
[pgAdmin][RM-2341]: Add menu option for starting PSQL 54+ messages / 4 participants [nested] [flat]
* [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-10 12:45 Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-05-10 12:45 UTC (permalink / raw) To: pgadmin-hackers Hi Hackers, Please find the attached patch for RM-2341 <https://redmine.postgresql.org/issues/2341;: Add Menu option for starting PSQL. 1. Added new Option PSQL Tool in Tools menu. 2. Added the same option for Server and Database nodes from the tree view. -- *Thanks & Regards,* *Nikhil Mohite* *Software Engineer.* *EDB Postgres* <https://www.enterprisedb.com/; *Mob.No: +91-7798364578.* Attachments: [application/octet-stream] RM_2341.patch (111.9K, 3-RM_2341.patch) download | inline diff: diff --git a/docs/en_US/developer_tools.rst b/docs/en_US/developer_tools.rst index 1ff442cc..bb67e33a 100644 --- a/docs/en_US/developer_tools.rst +++ b/docs/en_US/developer_tools.rst @@ -16,3 +16,4 @@ PL/SQL code. editgrid schema_diff erd_tool + psql_tool diff --git a/docs/en_US/images/psql_tool.png b/docs/en_US/images/psql_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f88ba5a573aa60bf7e08b8a38526dc73e8fcd5 GIT binary patch literal 23736 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 P=p;Q)S3j3^P6<r_JTn~) literal 0 HcmV?d00001 diff --git a/docs/en_US/psql_tool.rst b/docs/en_US/psql_tool.rst new file mode 100644 index 00000000..e0b3287e --- /dev/null +++ b/docs/en_US/psql_tool.rst @@ -0,0 +1,18 @@ +.. _psql_tool: + +****************** +`PSQL Tool`:index: +****************** + +PSQL tool allows user to connect to PostgreSQL server using psql terminal. + +* Login to PostgreSQL server through terminal in pgAdmin. +* execute all type of commands. + +.. image:: images/psql_tool.png + :alt: PSQL tool window + :align: center + +You can open multiple instance of the PSQL tool in individual tabs simultaneously. +To close the PSQL tool, click the *X* in the upper-right hand corner of the tab bar. + diff --git a/requirements.txt b/requirements.txt index edd7000b..fb8f25cd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,3 +36,6 @@ sshtunnel==0.* ldap3==2.* Flask-BabelEx==0.* gssapi==1.6.* + +flask-socketio>=5.0.1 +eventlet==0.30.2 diff --git a/web/config.py b/web/config.py index 2643ef19..002a9951 100644 --- a/web/config.py +++ b/web/config.py @@ -156,8 +156,8 @@ X_FRAME_OPTIONS = "SAMEORIGIN" # such as JavaScript, CSS, or pretty much anything that the browser loads. # see https://content-security-policy.com/#source_list for more info # e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';" -CONTENT_SECURITY_POLICY = "default-src http: data: blob: 'unsafe-inline' " \ - "'unsafe-eval';" +CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \ + " 'unsafe-eval';" # STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the # Strict-Transport-Security header @@ -636,6 +636,19 @@ KRB_AUTO_CREATE_USER = True KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache') +# PSQL tool settings +# This will enable PSQL tool in pgAdmin. So user can execute the commands using +# PSQL terminal in pgAdmin. +ENABLE_PSQL = True + +# ALLOW_PSQL_SHELL_COMMAND = True will disable the execution of os level +# commands using meta command \! from PSQL terminal. +# As PSQL allow user to execute the os level commands from the PSQL terminal +# user can execute any system level command as per the system login user +# privileges. Default this setting is set to False but if it set to True +# User will able to execute the system level commands through PSQL terminal in +# pgAdmin. +ALLOW_PSQL_SHELL_COMMANDS = False ########################################################################## # Local config settings diff --git a/web/package.json b/web/package.json index cc1e15ab..0d0f79b9 100644 --- a/web/package.json +++ b/web/package.json @@ -103,6 +103,7 @@ "json-bignumber": "^1.0.1", "karma-coverage": "^2.0.3", "leaflet": "^1.5.1", + "lodash": "4.*", "ml-matrix": "^6.5.0", "moment": "^2.24.0", @@ -118,13 +119,18 @@ "shim-loader": "^1.0.1", "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16", "snapsvg-cjs": "^0.0.6", + "socket.io-client": "^4.0.0", "split.js": "^1.5.10", "tablesorter": "^2.31.2", "tempusdominus-bootstrap-4": "^5.1.2", "tempusdominus-core": "^5.0.3", "underscore": "^1.9.1", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36", - "wkx": "^0.5.0" + "wkx": "^0.5.0", + "xterm": "^4.11.0", + "xterm-addon-fit": "^0.5.0", + "xterm-addon-search": "^0.8.0", + "xterm-addon-web-links": "^0.4.0", }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index d2bd1af6..6e1e4ea6 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -15,6 +15,7 @@ to start a web server.""" import sys from cheroot.wsgi import Server as CherootServer + if sys.version_info < (3, 4): raise RuntimeError('This application must be run under Python 3.4 ' 'or later.') @@ -37,7 +38,7 @@ else: builtins.SERVER_MODE = None import config -from pgadmin import create_app +from pgadmin import create_app, socketio from pgadmin.utils import u_encode, fs_encoding, file_quote from pgadmin.utils.constants import INTERNAL # Get the config database schema version. We store this in pgadmin.model @@ -97,6 +98,8 @@ if not os.path.isfile(config.SQLITE_PATH): ########################################################################## app = create_app() app.debug = False +app.config['sessions'] = dict() + if config.SERVER_MODE: app.wsgi_app = ReverseProxied(app.wsgi_app) @@ -206,17 +209,16 @@ def main(): else: # Can use cheroot instead of flask dev server when not in debug # 10 is default thread count in CherootServer - num_threads = 10 if config.THREADED_MODE else 1 - prod_server = CherootServer( - (config.DEFAULT_SERVER, config.EFFECTIVE_SERVER_PORT), - wsgi_app=app, - numthreads=num_threads, - server_name=config.APP_NAME) + # num_threads = 10 if config.THREADED_MODE else 1 try: - print("Using production server...") - prod_server.start() + socketio.run( + app, + host=config.DEFAULT_SERVER, + port=config.EFFECTIVE_SERVER_PORT, + ) except KeyboardInterrupt: - prod_server.stop() + print("CLOSE SERVER") + socketio.stop() except IOError: app.logger.error("Error starting the app server: %s", sys.exc_info()) diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index a7333537..a641ea66 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -19,6 +19,7 @@ from collections import defaultdict from importlib import import_module from flask import Flask, abort, request, current_app, session, url_for +from flask_socketio import SocketIO from werkzeug.exceptions import HTTPException from flask_babelex import Babel, gettext from flask_babelex import gettext as _ @@ -52,10 +53,15 @@ import mimetypes mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('text/css', '.css') + winreg = None if os.name == 'nt': import winreg +socketio = SocketIO(manage_session=False, async_mode='eventlet', + logger=True, engineio_logger=True, debug=False, + ping_interval=25, ping_timeout=120) + class PgAdmin(Flask): def __init__(self, *args, **kwargs): @@ -811,4 +817,5 @@ def create_app(app_name=None): ########################################################################## # All done! ########################################################################## + socketio.init_app(app) return app diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 235db027..b093e3a4 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -10,6 +10,7 @@ from flask_babelex import gettext from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\ PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \ PREF_LABEL_OPTIONS +from flask_security import current_user import config LOCK_LAYOUT_LEVEL = { @@ -511,10 +512,12 @@ def register_browser_preferences(self): options=[{'label': gettext('Query Tool'), 'value': 'qt'}, {'label': gettext('Debugger'), 'value': 'debugger'}, {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], - help_str=gettext('Select Query Tool, Debugger, or Schema Diff from ' - 'the drop-down to set open in new browser tab for ' - 'that particular module.'), + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext('Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), select2={ 'multiple': True, 'allowClear': False, 'tags': True, 'first_empty': False, diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 01ab89c5..c4784d51 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -91,6 +91,11 @@ define('pgadmin.node.database', [ name: 'generate_erd', node: 'database', module: this, applies: ['object', 'context'], callback: 'generate_erd', category: 'erd', priority: 5, label: gettext('Generate ERD (Beta)'), + },{ + name: 'psql_tool', node: 'database', module: this, + applies: ['object', 'context'], callback: 'db_psql_tool', + category: 'psql_tool', priority: 5, label: gettext('PSQL Tool (Beta)'), + enable: 'is_psql_enabled' }]); _.bindAll(this, 'connection_lost'); @@ -122,6 +127,9 @@ define('pgadmin.node.database', [ is_connected: function(node) { return (node && node.connected == true && node.canDisconn == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, is_conn_allow: function(node) { return (node && node.allowConn == true); }, @@ -266,6 +274,15 @@ define('pgadmin.node.database', [ pgBrowser.erd.showErdTool(d, i, true); }, + /* Open psql tool for db*/ + db_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, + /* Connect the database (if not connected), before opening this node */ beforeopen: function(item, data) { if(!data || data._type != 'database' || data.label == 'template0') { diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index b21cba43..1a7a0cef 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -102,6 +102,12 @@ define('pgadmin.node.server', [ data_disabled: gettext('Database is already disconnected.'), }, },{ + name: 'server_psql', node: 'server', module: this, + applies: ['object', 'context'], callback: 'server_psql_tool', + category: 'psql_tool', priority: 5, label: gettext('PSQL Tool (Beta)'), + enable : 'is_psql_enabled', + }, + { name: 'reload_configuration', node: 'server', module: this, applies: ['tools', 'context'], callback: 'reload_configuration', category: 'reload', priority: 6, label: gettext('Reload Configuration'), @@ -183,6 +189,9 @@ define('pgadmin.node.server', [ is_connected: function(node) { return (node && node.connected == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, enable_reload_config: function(node) { // Must be connected & is Super user if (node && node._type == 'server' && @@ -728,6 +737,14 @@ define('pgadmin.node.server', [ return false; }, + /* Open psql tool for server*/ + server_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + } }, model: pgAdmin.Browser.Node.Model.extend({ defaults: { diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js index c9e64132..3068aabe 100644 --- a/web/pgadmin/browser/static/js/panel.js +++ b/web/pgadmin/browser/static/js/panel.js @@ -122,10 +122,30 @@ define( myPanel.on(ev, that.handleVisibility.bind(myPanel, ev)); }); } + + // Listen on detach panel event + myPanel.on(wcDocker.EVENT.DETACHED, function(obj) { + that.setCodeMirrorHeight(obj); + }); }, }); } }, + setCodeMirrorHeight: function() { + // Fix for mac os code-mirror showing black screen. + var txtArea = $('.pg-panel-content .sql_textarea > textarea').first(); + txtArea.css('z-index', -1); + var $tabContent = $('.pg-panel-content > .sql_textarea').first(); + var $sqlPane = $tabContent.find('.CodeMirror > div > textarea'); + for(let i=0; i<$sqlPane.length; i++) {$($sqlPane[i]).css('z-index', -1);} + + $tabContent = $('.pg-panel-content > .sql_textarea').first(); + $sqlPane = $tabContent.find('.pg-panel-content'); + $sqlPane.find('.CodeMirror').css( + 'cssText', + 'height: ' + ($tabContent.height()) + 'px !important;' + ); + }, eventFunc: function(eventName) { var name = $(this).data('pgAdminName'); diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 8597df48..b0a317a5 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -52,6 +52,10 @@ define('pgadmin.browser.utils', pgAdmin['user_inactivity_timeout'] = {{ current_app.config.get('USER_INACTIVITY_TIMEOUT') }}; pgAdmin['override_user_inactivity_timeout'] = '{{ current_app.config.get('OVERRIDE_USER_INACTIVITY_TIMEOUT') }}' == 'True'; + /* GET PSQL Tool related config */ + pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; + // Define list of nodes on which Query tool option doesn't appears var unsupported_nodes = pgAdmin.unsupported_nodes = [ 'server_group', 'server', 'coll-tablespace', 'tablespace', diff --git a/web/pgadmin/static/bundle/browser.js b/web/pgadmin/static/bundle/browser.js index 14140a2f..0b3ad81b 100644 --- a/web/pgadmin/static/bundle/browser.js +++ b/web/pgadmin/static/bundle/browser.js @@ -11,6 +11,7 @@ define('bundled_browser',[ 'pgadmin.browser', 'sources/browser/index', 'top/tools/erd/static/js/index', + 'top/tools/psql/static/js/index', ], function(pgBrowser) { pgBrowser.init(); }); diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css index c2a776c8..5b4a9f2d 100644 --- a/web/pgadmin/static/css/style.css +++ b/web/pgadmin/static/css/style.css @@ -21,3 +21,5 @@ @import '../vendor/backgrid/backgrid.css'; @import '../vendor/backgrid/backgrid-select-all.css'; + +@import 'node_modules/xterm/css/xterm.css'; diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py new file mode 100644 index 00000000..27ae7e2a --- /dev/null +++ b/web/pgadmin/tools/psql/__init__.py @@ -0,0 +1,503 @@ +#!/usr/bin/env python3 +import os +import re +import select +import signal +import termios +import struct +import fcntl +import pty +import config +import eventlet.green.subprocess as subprocess +from flask import Response, session, url_for, request +from pgadmin.browser.utils import underscore_unescape +from flask import render_template, copy_current_request_context, \ + current_app as app +from flask_babelex import gettext +from pgadmin.utils import PgAdminModule +from flask_security import login_required, current_user +from pgadmin.utils.constants import PREF_LABEL_DISPLAY, MIMETYPE_APP_JS, \ + ERROR_MSG_TRANS_ID_NOT_FOUND +from pgadmin.utils.driver import get_driver +from config import PG_DEFAULT_DRIVER +from pgadmin.model import Server +from pgadmin.utils import get_complete_file_path + +from ... import socketio as sio + +session_input = dict() +session_input_cursor = dict() +session_last_cmd = dict() +pdata = dict() +cdata = dict() + + +class PSQLModule(PgAdminModule): + """ + class PSQLModule(PgAdminModule) + A module class for PSQL derived from PgAdminModule. + """ + + LABEL = gettext("PSQL") + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.psql', + 'path': url_for('psql.index') + "psql", + 'when': None + }] + + def get_panels(self): + return [] + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints for PSQL module + """ + return [ + 'psql.panel', + ] + + +blueprint = PSQLModule('psql', __name__, static_url_path='/static') + + [email protected]("/psql.js") +@login_required +def script(): + """render the required javascript""" + return Response( + response=render_template("psql/js/psql.js", _=gettext), + status=200, + mimetype=MIMETYPE_APP_JS + ) + + [email protected]('/panel/<int:trans_id>', + methods=["POST"], + endpoint="panel") +@login_required +def panel(trans_id): + """ + Return panel template for PSQL tools. + :param trans_id: + """ + params = { + 'trans_id': trans_id, + 'title': request.form['title'] + } + if request.args: + params.update({k: v for k, v in request.args.items()}) + + return render_template('editor_template.html', + sid=params['sid'], + db=params['db'], + server_type=params['server_type'], + is_enable=config.ENABLE_PSQL, + title=underscore_unescape(params['title'])) + + +def set_term_size(fd, row, col, xpix=0, ypix=0): + """ + Set the terminal size as per UI xterm size. + :param fd: + :param row: + :param col: + :param xpix: + :param ypix: + """ + term_size = struct.pack('HHHH', row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) + + [email protected]('connect', namespace='/pty') +def connect(): + """ + Connect to the server through socket. + :return: + :rtype: + """ + if config.ENABLE_PSQL: + sio.emit('connected', {'sid': request.sid}, namespace='/pty', + to=request.sid) + if request.sid in session_last_cmd: + session_last_cmd[request.sid]['is_new_connection'] = False + else: + session_last_cmd[request.sid] = {'cmd': '', 'arrow_up': False, + 'invalid_cmd': False, + 'is_new_connection': True} + else: + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + [email protected]('start_process', namespace='/pty') +@login_required +def start_process(data): + """ + Start the pty terminal and execute psql command and emit results to user. + :param data: + :return: + """ + + @copy_current_request_context + def read_and_forward_pty_output(sid, data): + max_read_bytes = 1024 * 20 + # Create the pty terminal process, parent and fd are file descriptors + # for parent and child. + parent, fd = pty.openpty() + p = None + if parent is not None: + # Child process + p = subprocess.Popen(connection_data, + preexec_fn=os.setsid, + stdin=fd, + stdout=fd, + stderr=fd, + universal_newlines=True + ) + + app.config['sessions'][request.sid] = parent + pdata[request.sid] = p + cdata[request.sid] = fd + else: + app.config['sessions'][request.sid] = parent + cdata[request.sid] = fd + set_term_size(fd, 50, 50) + + while p and p.poll() is None: + if request.sid in app.config['sessions']: + # This code is added to make this unit testable. + if "is_test" not in data: + sio.sleep(0.01) + else: + data['count'] += 1 + if data['count'] == 5: + break + + timeout = 0 + # module provides access to platform-specific I/O + # monitoring functions + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) + + if parent in data_ready: + # Read the output from parent fd (terminal). + output = os.read(parent, max_read_bytes) + emit_output = True + + if sid in session_last_cmd and session_last_cmd[sid][ + 'arrow_up'] and not session_last_cmd[request.sid][ + 'arrow_left_right']: + session_last_cmd[sid]['cmd'] = output.decode() + session_input_cursor[request.sid] = len( + session_last_cmd[sid]['cmd']) + session_last_cmd[sid]['arrow_up'] = True + + if sid in session_last_cmd: + # If command is invalid then emit error to user. + if session_last_cmd[sid]['invalid_cmd']: + emit_output = False + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security;\r\n"), + 'error': True + }, + namespace='/pty', room=sid) + # If command is valid then emit output to user. + if emit_output: + sio.emit('pty-output', + {'result': output.decode(), + 'error': False}, + namespace='/pty', room=sid) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + + # Check user is authenticated and PSQL is enabled in config. + if current_user.is_authenticated and config.ENABLE_PSQL: + connection_data = [] + try: + db = '' + if data['db']: + db = data['db'] + # driver = get_driver(PG_DEFAULT_DRIVER) + # manager = driver.connection_manager(int(data['sid'])) + # conn = manager.connection() + conn, manager = _get_connection(int(data['sid']), data) + psql_utility = manager.utility('sql') + print("psql_utility: ", psql_utility) + connection_data = get_connection_str(psql_utility, conn, db, + manager) + except Exception as e: + # If any error raised during the start the PSQL emit error to UI. + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + + try: + sio.start_background_task(read_and_forward_pty_output, + request.sid, data) + except Exception as e: + print(e) + else: + # Show error if user is not authenticated. + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def _get_connection(sid, data): + """ + Get the connection object of ERD. + :param sid: + :param did: + :param trans_id: + :return: + """ + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + try: + conn = manager.connection() + if 'pwd' in data: + kwargs = {'password': data['pwd'], "user": data['user']} + status, msg = conn.connect(**kwargs) + else: + status, msg = conn.connect() + if not status: + app.logger.error(msg) + # raise ConnectionLost(sid, conn.db, trans_id) + + return conn, manager + except Exception as e: + app.logger.error(e) + raise + + +def get_connection_str(psql_utility, conn, db, manager): + """ + Get connection string(through connection dsn) + :param psql_utility: PostgreSQL binary path. + :param conn: Connection data + :param db: database name to connect specific db. + :return: connection attribute list for PSQL connection. + """ + + conn_attr = conn.conn.dsn + if 'password=xxx' in conn_attr: + conn_attr = conn_attr.replace('password=xxx', '') + + if db != '': + conn_attr = conn_attr.replace('dbname=postgres', + 'dbname={0}'.format(db)) + # Add application name to new created psql terminal instance + # through pgAdmin 4. + conn_attr = "{0} {1}".format(conn_attr, + " application_name='pgAdmin4: psql'") + + conn_attr_list = list() + conn_attr_list.append(psql_utility) + conn_attr_list.append(conn_attr) + return conn_attr_list + + [email protected]('socket_input', namespace='/pty') +def socket_input(data): + """ + This get the user input through socket. + :param data: User input from socket. + """ + try: + # Check PSQL enabled setting from config. + enable_psql = True if config.ENABLE_PSQL else False + + if request.sid in app.config['sessions']: + if data['key_name'] == 'Enter' and enable_psql: + # If user get previous executed command from history then set + # current command as previous executed command. + if session_last_cmd[request.sid]['cmd'] \ + and session_last_cmd[request.sid]['arrow_up']: + user_input = str( + session_last_cmd[request.sid]['cmd']).strip() + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + else: + user_input = str(session_input[request.sid]).strip() + session_input_cursor[request.sid] = 0 + + # If ALLOW_PSQL_SHELL_COMMANDS is False then user can't execute + # \! meta command to run shell commands through PSQL terminal. + # Check before executing the user entered command does not + # contains \! in input. + is_new_connection = session_last_cmd[request.sid][ + 'is_new_connection'] + if user_input.startswith('\\!') and \ + re.match("^\\\!$", user_input) and \ + len(user_input) == 2 and \ + not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not is_new_connection: + + session_last_cmd[request.sid]['invalid_cmd'] = True + + for i in range(len(session_input[request.sid])): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + session_input[request.sid] = '' + elif re.search("\\\!", user_input) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + stop_execution = True + # Check \! is passed as string or not. + double_quote_strs = re.findall('"([^"]*)"', user_input) + + if double_quote_strs: + for sub_str in double_quote_strs: + if re.search("\\\!", sub_str): + stop_execution = False + # break + + if stop_execution: + session_last_cmd[request.sid]['invalid_cmd'] = True + # Remove already added command from terminal. + for i in range(len(user_input)): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + # Add Enter event to execute the command. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + elif user_input == '\q': + # If user enter \q to terminate the PSQL, emit the msg to + # notify user connection is terminated. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + sio.emit('pty-output', + { + 'result': gettext( + 'Connection terminated, TO create new ' + 'connection please open another psql' + ' tool.'), + 'error': True}, + namespace='/pty', room=request.sid) + else: + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + session_input[request.sid] = '' + session_last_cmd[request.sid]['is_new_connection'] = False + else: + if data['key_name'] == 'ArrowLeft': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] > 0: + session_input_cursor[request.sid] -= 1 + + elif data['key_name'] == 'ArrowRight': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] < len( + session_input[request.sid]): + session_input_cursor[request.sid] += 1 + + elif data['key_name'] == 'ArrowUp': + session_last_cmd[request.sid]['arrow_up'] = True + session_last_cmd[request.sid]['arrow_left_right'] = False + session_input[request.sid] = session_last_cmd[request.sid][ + 'cmd'] + session_input_cursor[request.sid] = len( + session_last_cmd[request.sid]['cmd']) + + elif request.sid in session_input and data[ + 'key_name'] == 'Backspace' and ( + len(session_input[request.sid]) or len( + session_last_cmd[request.sid])): + + session_last_cmd[request.sid]['arrow_left_right'] = True + + if session_last_cmd[request.sid]['cmd']: + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + + user_input = list(session_input[request.sid]) + + if session_input_cursor[request.sid] == 1: + index = 0 + session_input_cursor[request.sid] -= 1 + else: + if session_input_cursor[request.sid] > 0: + index = (session_input_cursor[request.sid]) - 1 + session_input_cursor[request.sid] -= 1 + else: + index = session_input_cursor[request.sid] + session_input_cursor[request.sid] = 0 + + if len(user_input): + del user_input[index] + session_input[request.sid] = "".join(user_input) + + if len(session_input[request.sid]) == 0: + session_input_cursor[request.sid] = 0 + session_last_cmd[request.sid]['cmd'] = '' + elif request.sid in session_input: + if session_last_cmd[request.sid]['cmd'] and session_input[ + request.sid] == '': + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + session_input_cursor[request.sid] = len( + session_input[request.sid]) + else: + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + user_input = list(session_input[request.sid]) + user_input.insert(session_input_cursor[request.sid], + data['input']) + session_input[request.sid] = ''.join(user_input) + session_input_cursor[request.sid] += 1 + session_last_cmd[request.sid]['arrow_left_right'] = False + else: + session_input_cursor[request.sid] = 0 + session_input[request.sid] = data['input'] + session_input_cursor[request.sid] += 1 + + # Write user input to terminal parent fd. + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + except Exception as e: + # Delete socket id from sessions. + del app.config['sessions'][request.sid] + + [email protected]('resize', namespace='/pty') +def resize(data): + """ + Resize the pty terminal as per the UI terminal. + :param data: UI terminal rows and cols data + """ + if request.sid in app.config['sessions']: + set_term_size(app.config['sessions'][request.sid], data['rows'], + data['cols']) + + [email protected]('disconnect', namespace='/pty') +def disconnect(): + """ + Disconnect the socket and terminate the process + """ + if request.sid in pdata: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + os.write(app.config['sessions'][request.sid], '\q\n'.encode()) + sio.sleep(1) + os.close(app.config['sessions'][request.sid]) + os.close(cdata[request.sid]) + del app.config['sessions'][request.sid] + os.kill(pdata[request.sid].pid, signal.SIGSTOP) diff --git a/web/pgadmin/tools/psql/static/js/index.js b/web/pgadmin/tools/psql/static/js/index.js new file mode 100644 index 00000000..59ae8b4b --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/index.js @@ -0,0 +1,22 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import $ from 'jquery'; +import _ from 'underscore'; +import pgAdmin from 'sources/pgadmin'; +import * as csrfToken from 'sources/csrf'; +import {initialize} from './psql_module'; + +let pgBrowserOut = initialize(gettext, url_for, $, _, pgAdmin, csrfToken); + +module.exports = { + pgBrowser: pgBrowserOut, +}; diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js new file mode 100644 index 00000000..eca623cd --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -0,0 +1,334 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import { Terminal } from 'xterm'; +import LocalEchoController from 'local-echo-controller'; +import { FitAddon } from 'xterm-addon-fit'; +import { WebLinksAddon } from 'xterm-addon-web-links'; +import { SearchAddon } from 'xterm-addon-search'; +import { io } from 'socketio'; +import Alertify from 'pgadmin.alertifyjs'; +import clipboard from 'sources/selection/clipboard'; + +import 'wcdocker'; +import {getRandomInt} from 'sources/utils'; +import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; + + +export function setPanelTitle(psqlToolPanel, panelTitle) { + psqlToolPanel.title('<span title="'+panelTitle+'">'+panelTitle+'</span>'); +} + +var wcDocker = window.wcDocker; + +export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken) { + var pgBrowser = pgAdmin.Browser; + var terminal = Terminal; + var parentData = null; + var localControl = LocalEchoController; + /* Return back, this has been called more than once */ + if (pgBrowser.psql) + return pgBrowser.psql; + + // Create an Object Restore of pgBrowser class + pgBrowser.psql = { + init: function() { + this.initialized = true; + + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'psql', + module: this, + applies: ['tools'], + callback: 'psql_tool', + priority: 1, + label: gettext('PSQL Tool (Beta)'), + enable: this.psqlToolEnabled, + }]; + + this.enable_psql_tool = pgAdmin['enable_psql']; + if(pgAdmin['enable_psql']) { + pgBrowser.add_menus(menus); + } + + // Creating a new pgBrowser frame to show the data. + var psqlFrameType = new pgBrowser.Frame({ + name: 'frm_psqltool', + showTitle: true, + isCloseable: true, + isPrivate: true, + url: 'about:blank', + }); + + let self = this; + /* Cache may take time to load for the first time + * Keep trying till available + */ + let cacheIntervalId = setInterval(function() { + if(pgBrowser.preference_version() > 0) { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + clearInterval(cacheIntervalId); + } + },0); + + pgBrowser.onPreferencesChange('psql', function() { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + }); + + // Load the newly created frame + psqlFrameType.load(pgBrowser.docker); + return this; + }, + + psqlToolEnabled: function(obj) { + //Same as query tool + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj)) { + if ((this.enable_psql_tool == true) && ((obj._type == 'server' && obj.connected == true )|| obj._type == 'database')) { + return true; + } else { + return false; + } + } else { + return false; + } + })(); + return isEnabled; + }, + retrieveAncestorOfTypeServer: function(item) { + let serverInformation = null; + // let aciTreeItem = item || pgBrowser.treeMenu.selected(); + let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); + + if (treeNode) { + let nodeData; + let databaseNode = treeNode.ancestorNode( + (node) => { + nodeData = node.getData(); + return (nodeData._type === 'database'); + } + ); + let isServerNode = (node) => { + nodeData = node.getData(); + return nodeData._type === 'server'; + }; + + if (databaseNode !== null) { + if (nodeData._label.indexOf('=') >= 0) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext( + 'Databases with = symbols in the name cannot be backed up or restored using this utility.' + ) + ); + } else { + if (databaseNode.anyParent(isServerNode)) + serverInformation = nodeData; + } + } else { + if (treeNode.anyFamilyMember(isServerNode)) + serverInformation = nodeData; + } + } + + if (serverInformation === null) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext('Please select server or child node from the browser tree.') + ); + } + return serverInformation; + }, + psql_tool: function(data, aciTreeIdentifier, gen=false) { + const module = 'paths'; + let preference_name = 'pg_bin_dir'; + let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.'); + const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeIdentifier); + + // const node1 = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if ((serverInformation.type && serverInformation.type === 'ppas') || + serverInformation.server_type === 'ppas') { + preference_name = 'ppas_bin_dir'; + msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'); + } + const preference = pgBrowser.get_preference(module, preference_name); + + if (preference) { + if (!preference.value) { + Alertify.alert(gettext('Configuration required'), msg); + return false; + } + } else { + Alertify.alert( + gettext(this.errorAlertTitle), + gettext('Failed to load preference %s of module %s', preference_name, module) + ); + return false; + } + const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if (node === undefined || !node.getData()) { + Alertify.alert( + gettext('PSQL Error'), + gettext('No object selected.') + ); + return; + } + + parentData = getTreeNodeHierarchyFromIdentifier.call( + pgBrowser, + aciTreeIdentifier + ); + + if(_.isUndefined(parentData.server)) { + Alertify.alert( + gettext('PSQL Error'), + gettext('Please select a server/database object.') + ); + return; + } + + const transId = getRandomInt(1, 9999999); + + var panelTitle = ''; + if (parentData.database) { + panelTitle = parentData.database.label + '/' + parentData.server.user_name + '@' + parentData.server.label; + } else { + panelTitle = parentData.server.user_name + '@' + parentData.server.label; + } + const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + + let psqlToolForm = ` + <form id="psqlToolForm" action="${panelUrl}" method="post"> + <input id="title" name="title" hidden /> + <input name="close_url" value="${panelCloseUrl}" hidden /> + </form> + <script> + document.getElementById("title").value = "${_.escape(panelTitle)}"; + document.getElementById("psqlToolForm").submit(); + </script> + `; + + var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; + if (open_new_tab && open_new_tab.includes('psql_tool')) { + var newWin = window.open('', '_blank'); + newWin.document.write(psqlToolForm); + newWin.document.title = panelTitle; + } else { + /* On successfully initialization find the properties panel, + * create new panel and add it to the dashboard panel. + */ + var propertiesPanel = pgBrowser.docker.findPanels('properties'); + var psqlToolPanel = pgBrowser.docker.addPanel('frm_psqltool', wcDocker.DOCK.STACKED, propertiesPanel[0]); + + // Set panel title and icon + setPanelTitle(psqlToolPanel, panelTitle); + psqlToolPanel.icon('fas fa-terminal'); + psqlToolPanel.focus(); + + // Listen on the panel closed event. + /*psqlToolPanel.on(wcDocker.EVENT.CLOSED, function() { + $.ajax({ + url: panelCloseUrl, + method: 'DELETE', + }); + });*/ + + var openPSQLToolURL = function(j) { + // add spinner element + let $spinner_el = + $(`<div class="pg-sp-container"> + <div class="pg-sp-content"> + <div class="row"> + <div class="col-12 pg-sp-icon"></div> + </div> + </div> + </div>`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { + var frameInitialized = $(j).data('frameInitialized'); + if (frameInitialized) { + clearInterval(init_poller_id); + var frame = $(j).data('embeddedFrame'); + if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); + frame.openHTML(psqlToolForm); + } + } + }, 100); + }; + + openPSQLToolURL(psqlToolPanel); + + } + + // var url_params = { + // 'sid': parentData.server._id, + // }; + // var baseUrl = url_for('psql.initialize', url_params); + // + // window.open(baseUrl, '_blank'); + }, + getPanelUrls: function(transId, panelTitle, parentData) { + let openUrl = url_for('psql.panel', { + trans_id: transId, + }); + + openUrl += `?sgid=${parentData.server_group._id}` + +`&sid=${parentData.server._id}` + +`&server_type=${parentData.server.server_type}`; + + if(parentData.database && parentData.database._id) { + openUrl += `&db=${parentData.database._label}`; + } else { + openUrl += `&db=${''}`; + } + + let closeUrl = url_for('psql.close', { + trans_id: transId, + // sgid: parentData.server_group._id, + // sid: parentData.server._id, + // did: parentData.database._id, + }); + return [openUrl, closeUrl]; + }, + psql_terminal: function() { + return new terminal({ + cursorBlink: true, + macOptionIsMeta: true, + scrollback: 10000, + }); + }, + psql_local_controller: function() { + return new localControl(); + }, + psql_fit_screen: function() { + return new FitAddon(); + }, + psql_web_link: function() { + return new WebLinksAddon(); + }, + psql_search: function() { + return new SearchAddon(); + }, + psql_socket: function() { + return io('/pty', {pingTimeout: 120000, pingInterval: 25000}); + }, + get_parent_db: function(){ + return parentData.server; + }, + _clipboard: function() { + return clipboard; + } + }; + + return pgBrowser.psql; +} + diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html new file mode 100644 index 00000000..e5f50a29 --- /dev/null +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -0,0 +1,137 @@ +{% extends "base.html" %} +{% block title %}{{title}}{% endblock %} + +{% block css_link %} +<link type="text/css" rel="stylesheet" href="{{ url_for('browser.browser_css')}}"/> +{% endblock %} +{% block body %} +<style> + body {padding: 0px;} + {% if is_desktop_mode and is_linux %} + .alertify .ajs-dimmer,.alertify .ajs-modal{-webkit-transform: none;} + .alertify-notifier{-webkit-transform: none;} + .alertify-notifier .ajs-message{-webkit-transform: none;} + .alertify .ajs-dialog.ajs-shake{-webkit-animation-name: none;} + .sql-editor-busy-icon.fa-pulse{-webkit-animation: none;} + {% endif %} +</style> +<div style="width: 100%; height: 100%;" id="psql-terminal" class="psql_terminal"></div> +{% endblock %} + + +{% block init_script %} +require( + ['sources/generated/psql_tool'], + function(pgBrowser) { + const term = self.pgAdmin.Browser.psql.psql_terminal(); + + const fitAddon = self.pgAdmin.Browser.psql.psql_fit_screen(); + term.loadAddon(fitAddon); + let clipboard = self.pgAdmin.Browser.psql._clipboard(); + + const webLinksAddon = self.pgAdmin.Browser.psql.psql_web_link(); + term.loadAddon(webLinksAddon); + + const searchAddon = self.pgAdmin.Browser.psql.psql_search(); + term.loadAddon(searchAddon); + + term.open(document.getElementById('psql-terminal')); + fitAddon.fit() + term.resize(15, 50) + fitAddon.fit() + let selected_text = ''; + let user_input = ''; + let is_pwd = true; + let cursor_position = 0; + + term.attachCustomKeyEventHandler(e => { + e.stopPropagation(); + if(e.type=='keydown' && e.metaKey &&(e.key == 'v' || e.key == 'V')) { + if(selected_text != '') { + if (selected_text.length > 0) { + socket.emit("socket_input", {"input": selected_text, 'key_name': e.code}); + selected_text = ''; + } + } else { + navigator.clipboard.readText().then( clipText => { + selected_text = clipText; + if (selected_text.length > 0) { + socket.emit("socket_input", {"input": selected_text, 'key_name': e.code}); + selected_text = ''; + } + }); + } + + }else if(e.type=='keydown' && e.metaKey && (e.key == 'c' || e.key == 'C')) { + if (term.hasSelection()) { + selected_text = term.getSelection(); + } else { + selected_text = clipboard.readText(); + } + } +<!-- else if (e.type=='keydown' && e.keyCode == 32) {--> +<!-- user_input += e.key;--> +<!-- console.log('SPACEBAR');--> +<!-- socket.emit("socket_input", {"input": e.key, 'key_name': e.code});--> +<!-- }--> + return true; + }); + + term.onKey(function (ev) { + if (pgAdmin['allow_psql_shell_commands']) { + socket.emit("socket_input", {"input": ev.key, 'key_name': ev.domEvent.code}); + } else { + console.log("socket_input" + ev.key); + socket.emit("socket_input", {"input": ev.key, 'key_name': ev.domEvent.code}); + } + }); + + const socket = self.pgAdmin.Browser.psql.psql_socket(); + + socket.on("pty-output", function(data){ + if(data.error) { + term.write('\r\n'); + } + term.write(data.result); + if(data.error) { + term.write('\r\n'); + } + }) + + socket.on("connect", () => { + if('{{is_enable}}' == 'True'){ + socket.emit('start_process', {"sid": {{sid}}, "db": '{{db}}', 'stype': '{{server_type}}' }); + } + fitToscreen(); + }); + + socket.on("conn_error", (response) => { + term.write(response.error); + fitToscreen(); + }); + + socket.on("conn_not_allow", () => { + term.write('PSQL connection not allowed'); + fitToscreen(); + }); + + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } + + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) + } + } + + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) + }); +{% endblock %} + + diff --git a/web/pgadmin/tools/psql/tests/__init__.py b/web/pgadmin/tools/psql/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web/pgadmin/tools/psql/tests/psql_test_data.json b/web/pgadmin/tools/psql/tests/psql_test_data.json new file mode 100644 index 00000000..9b2cfaf5 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/psql_test_data.json @@ -0,0 +1,174 @@ +{ + "psql_user_input": [ + { + "name": "Enter Select 1;", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "move_cursor_up": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "is_history": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowLeft", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowLeft": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowRight", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Read previous executed command", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "move_cursor_right": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\!", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! with other cmd not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\! ls", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Valid commands", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select \"\\!\"", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Exist psql terminal by using \\q", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\q", + "mock_data": { + + }, + "expected_data": { + } + } + ], + "resize_terminal": [ + { + "name": "Resize psql terminal as per UI.", + "is_positive_test": true, + "mocking_required": false, + "input_data": { + "cols": 141, + "rows": 39 + }, + "mock_data": { + + }, + "expected_data": { + } + } + ], + "backend_task": [ + { + "name": "Backend Task", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "Select 1;", + "is_backend_task": true, + "mock_data": { + "is_test": true + }, + "expected_data": { + } + } + ] +} diff --git a/web/pgadmin/tools/psql/tests/test_backend_task.py b/web/pgadmin/tools/psql/tests/test_backend_task.py new file mode 100644 index 00000000..99073c0a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_backend_task.py @@ -0,0 +1,88 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLBackend(BaseTestGenerator): + scenarios = utils.generate_scenarios('backend_task', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'], + 'is_test': True, + 'count': 0 + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_panel.py b/web/pgadmin/tools/psql/tests/test_panel.py new file mode 100644 index 00000000..83480681 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_panel.py @@ -0,0 +1,35 @@ +import uuid +import random +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data + + +class PSQLPanel(BaseTestGenerator): + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + + def runTest(self): + trans_id = random.randint(1, 9999999) + url = '/psql/panel/{trans_id}?sgid={sgid}&sid={sid}&server_type=pg' \ + '&db={db_name}'.\ + format(trans_id=trans_id, sgid=self.sgid, sid=self.sid, + db_name=self.db_name) + + response = self.tester.post( + url, data={"title": "panel_title"}, + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_disabled.py b/web/pgadmin/tools/psql/tests/test_psql_disabled.py new file mode 100644 index 00000000..32eaa623 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_disabled.py @@ -0,0 +1,36 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +# from flask import current_app as app + +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisabled(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = False + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + print("received:", received) + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_input.py b/web/pgadmin/tools/psql/tests/test_psql_input.py new file mode 100644 index 00000000..8fe0b47a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_input.py @@ -0,0 +1,159 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLInput(BaseTestGenerator): + scenarios = utils.generate_scenarios('psql_user_input', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + print("received values: ", received) + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + received = self.test_client.get_received('/pty') + print("user I/P:: ", received) + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + received = self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_backspace') and self.is_backspace: + if hasattr(self, 'move_cursor_up') and self.move_cursor_up: + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Backspace' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowUp') and self.is_arrowUp: + if hasattr(self, 'is_history') and self.is_history: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowLeft') and self.is_arrowLeft: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowRight') and self.is_arrowRight: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'move_cursor_right') and self.is_arrowRight: + for i in range(2): + input_data = { + 'input': '', + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + input_data = { + 'input': '', + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + received = self.test_client.get_received('/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_resize_terminal.py b/web/pgadmin/tools/psql/tests/test_resize_terminal.py new file mode 100644 index 00000000..9ce7d004 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_resize_terminal.py @@ -0,0 +1,60 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLResizeTerminal(BaseTestGenerator): + scenarios = utils.generate_scenarios('resize_terminal', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + + self.test_client.emit('resize', self.input_data, namespace='/pty') + + # self.test_client.disconnect(namespace='/pty') + # self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_connect.py b/web/pgadmin/tools/psql/tests/test_socket_connect.py new file mode 100644 index 00000000..7b8031bd --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_connect.py @@ -0,0 +1,36 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +# from flask import current_app as app +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketConnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + print("received:", received) + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py new file mode 100644 index 00000000..cd2cf5ac --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py @@ -0,0 +1,35 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +# from flask import current_app as app +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisconnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + print("received:", received) + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process.py b/web/pgadmin/tools/psql/tests/test_start_process.py new file mode 100644 index 00000000..055f7ce3 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process.py @@ -0,0 +1,63 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils.driver import get_driver +from config import PG_DEFAULT_DRIVER +from .... import socketio + + +class PSQLStartProcess(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + self.server_con = server_utils.connect_server(self, self.sid) + print(self.server_con) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + import random + trans_id = random.randint(1, 9999999) + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + print("received values: ", received) + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process_fail.py b/web/pgadmin/tools/psql/tests/test_start_process_fail.py new file mode 100644 index 00000000..895fc533 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process_fail.py @@ -0,0 +1,60 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from .... import socketio + + +class PSQLStartProcessFail(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + db_con = database_utils.connect_database(self, + self.sgid, + self.sid, + self.did) + print("DB connection") + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + print("received:", received) + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + import random + trans_id = random.randint(1, 9999999) + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + config.ENABLE_PSQL = False + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/utils.py b/web/pgadmin/tools/psql/tests/utils.py new file mode 100644 index 00000000..85bd5373 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/utils.py @@ -0,0 +1,6 @@ +import os +import json + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/psql_test_data.json") as data_file: + test_cases = json.load(data_file) diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss index 0bb40802..5ffc8241 100644 --- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss +++ b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss @@ -374,3 +374,9 @@ div.strikeout:after { /* Setting it to hardcoded white as the SVG generated is having white bg * Need to check what can be done. */ + +/* Css for psql */ +.psql_terminal .terminal { + padding-top: 1%; + padding-left: 0.5%; +} diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py index 23abfffa..71ae82ea 100644 --- a/web/pgadmin/utils/csrf.py +++ b/web/pgadmin/utils/csrf.py @@ -38,6 +38,7 @@ class _PGCSRFProtect(CSRFProtect): 'pgadmin.tools.schema_diff.ddl_compare', 'pgadmin.authenticate.login', 'pgadmin.tools.erd.panel', + 'pgadmin.tools.psql.panel', ] for exempt in exempt_views: diff --git a/web/pgadmin/utils/preferences.py b/web/pgadmin/utils/preferences.py index 15ceeb1a..e9efe479 100644 --- a/web/pgadmin/utils/preferences.py +++ b/web/pgadmin/utils/preferences.py @@ -72,6 +72,7 @@ class _Preference(object): self.select2 = kwargs.get('select2', None) self.fields = kwargs.get('fields', None) self.allow_blanks = kwargs.get('allow_blanks', None) + self.disabled = kwargs.get('disabled', False) # Look into the configuration table to find out the id of the specific # preference. @@ -252,6 +253,7 @@ class _Preference(object): 'select2': self.select2, 'value': self.get(), 'fields': self.fields, + 'disabled': self.disabled, } return res @@ -414,6 +416,7 @@ class Preferences(object): :param fields: field schema (if preference has more than one field to take input from user e.g. keyboardshortcut preference) :param allow_blanks: Flag specify whether to allow blank value. + :param disabled: Flag specify whether to disable the setting or not. """ min_val = kwargs.get('min_val', None) max_val = kwargs.get('max_val', None) @@ -423,6 +426,7 @@ class Preferences(object): select2 = kwargs.get('select2', None) fields = kwargs.get('fields', None) allow_blanks = kwargs.get('allow_blanks', None) + disabled = kwargs.get('disabled', False) cat = self.__category(category, category_label) if name in cat['preferences']: @@ -439,7 +443,8 @@ class Preferences(object): (cat['preferences'])[name] = res = _Preference( cat['id'], name, label, _type, default, help_str=help_str, min_val=min_val, max_val=max_val, options=options, - select2=select2, fields=fields, allow_blanks=allow_blanks + select2=select2, fields=fields, allow_blanks=allow_blanks, + disabled=disabled ) return res diff --git a/web/webpack.config.js b/web/webpack.config.js index e906a567..104a3b20 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -355,6 +355,7 @@ module.exports = [{ debugger_direct: './pgadmin/tools/debugger/static/js/direct.js', schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js', erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js', + psql_tool: './pgadmin/tools/psql/static/js/index.js', file_utils: './pgadmin/misc/file_manager/static/js/utility.js', 'pgadmin.style': pgadminCssStyles, pgadmin: pgadminScssStyles, @@ -493,7 +494,7 @@ module.exports = [{ ], }, }, - }, { + },{ test: require.resolve('./node_modules/acitree/js/jquery.aciTree.min'), use: { loader: 'imports-loader', @@ -532,6 +533,7 @@ module.exports = [{ 'pure|pgadmin.tools.storage_manager', 'pure|pgadmin.tools.search_objects', 'pure|pgadmin.tools.erd_module', + 'pure|pgadmin.tools.psql_module', ], }, }, diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 074b2580..b860d21f 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -159,6 +159,16 @@ var webpackShimConfig = { 'jquery.acisortable': path.join(__dirname, './node_modules/acitree/js/jquery.aciSortable.min'), 'jquery.acifragment': path.join(__dirname, './node_modules/acitree/js/jquery.aciFragment.min'), + //xterm + 'xterm': path.join(__dirname, './node_modules/xterm/lib/xterm.js'), + 'xterm-addon-fit': path.join(__dirname, './node_modules/xterm-addon-fit/lib/xterm-addon-fit.js'), + 'xterm-addon-web-links': path.join(__dirname, './node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js'), + 'xterm-addon-search': path.join(__dirname, './node_modules/xterm-addon-search/lib/xterm-addon-search.js'), + 'local-echo-controller': path.join(__dirname, './node_modules/local-echo'), + + //socket + 'socketio': path.join(__dirname, './node_modules/socket.io-client/dist/socket.io.js'), + // Backbone and Backgrid 'backbone': path.join(__dirname, './node_modules/backbone/backbone'), 'backbone.undo': path.join(__dirname, './node_modules/backbone-undo/Backbone.Undo'), @@ -288,6 +298,8 @@ var webpackShimConfig = { 'pgadmin.tools.storage_manager': path.join(__dirname, './pgadmin/tools/storage_manager/static/js/storage_manager'), 'pgadmin.tools.erd_module': path.join(__dirname, './pgadmin/tools/erd/static/js/erd_module'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index e0b6fd69..3cc079f9 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -177,6 +177,7 @@ module.exports = { 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), 'tools': path.join(__dirname, './pgadmin/tools/'), 'pgadmin.user_management.current_user': regressionDir + '/javascript/fake_current_user', ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-10 13:40 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-05-10 13:40 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers Hi On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < [email protected]> wrote: > Hi Hackers, > > Please find the attached patch for RM-2341 > <https://redmine.postgresql.org/issues/2341;: Add Menu option for > starting PSQL. > 1. Added new Option PSQL Tool in Tools menu. > 2. Added the same option for Server and Database nodes from the tree view. > Unfortunately there's a trailing comma in package.json that makes it invalid. If I fix that, then I get the error below, so I'm guessing the intention was to actually include another package there? ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 Module not found: Error: Can't resolve 'local-echo-controller' in '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' resolve 'local-echo-controller' in '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' Parsed request is a module using description file: /Users/dpage/git/pgadmin4/web/package.json (relative path: ./pgadmin/tools/psql/static/js) aliased with mapping 'local-echo-controller': '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' using description file: /Users/dpage/git/pgadmin4/web/package.json (relative path: ./pgadmin/tools/psql/static/js) Field 'browser' doesn't contain a valid alias configuration root path /Users/dpage/git/pgadmin4/web using description file: /Users/dpage/git/pgadmin4/web/package.json (relative path: ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) no extension Field 'browser' doesn't contain a valid alias configuration /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist .js Field 'browser' doesn't contain a valid alias configuration /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist .jsx Field 'browser' doesn't contain a valid alias configuration /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist as directory /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist using description file: /Users/dpage/git/pgadmin4/web/package.json (relative path: ./node_modules/local-echo) no extension Field 'browser' doesn't contain a valid alias configuration /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist .js Field 'browser' doesn't contain a valid alias configuration /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist .jsx Field 'browser' doesn't contain a valid alias configuration /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist as directory /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 ms -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-10 14:01 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-05-10 14:01 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: pgadmin-hackers Hi Dave/ Team, PFA updated patch, sorry for the inconvenience, while cleanup I removed the unwanted libraries but forgot to remove the code related to them. On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> wrote: > Hi > > On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Hackers, >> >> Please find the attached patch for RM-2341 >> <https://redmine.postgresql.org/issues/2341;: Add Menu option for >> starting PSQL. >> 1. Added new Option PSQL Tool in Tools menu. >> 2. Added the same option for Server and Database nodes from the tree view. >> > > Unfortunately there's a trailing comma in package.json that makes it > invalid. If I fix that, then I get the error below, so I'm guessing the > intention was to actually include another package there? > > ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 > Module not found: Error: Can't resolve 'local-echo-controller' in > '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' > resolve 'local-echo-controller' in > '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' > Parsed request is a module > using description file: /Users/dpage/git/pgadmin4/web/package.json > (relative path: ./pgadmin/tools/psql/static/js) > aliased with mapping 'local-echo-controller': > '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to > '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' > using description file: /Users/dpage/git/pgadmin4/web/package.json > (relative path: ./pgadmin/tools/psql/static/js) > Field 'browser' doesn't contain a valid alias configuration > root path /Users/dpage/git/pgadmin4/web > using description file: > /Users/dpage/git/pgadmin4/web/package.json (relative path: > ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) > no extension > Field 'browser' doesn't contain a valid alias configuration > > /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo > doesn't exist > .js > Field 'browser' doesn't contain a valid alias configuration > > /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js > doesn't exist > .jsx > Field 'browser' doesn't contain a valid alias configuration > > /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx > doesn't exist > as directory > > /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo > doesn't exist > using description file: /Users/dpage/git/pgadmin4/web/package.json > (relative path: ./node_modules/local-echo) > no extension > Field 'browser' doesn't contain a valid alias configuration > /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't > exist > .js > Field 'browser' doesn't contain a valid alias configuration > /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js > doesn't exist > .jsx > Field 'browser' doesn't contain a valid alias configuration > /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx > doesn't exist > as directory > /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't > exist > @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 > > 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 ms > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > Regards, Nikhil Mohite Attachments: [application/octet-stream] RM_2341_V2.patch (111.7K, 3-RM_2341_V2.patch) download | inline diff: diff --git a/docs/en_US/developer_tools.rst b/docs/en_US/developer_tools.rst index 1ff442cc..bb67e33a 100644 --- a/docs/en_US/developer_tools.rst +++ b/docs/en_US/developer_tools.rst @@ -16,3 +16,4 @@ PL/SQL code. editgrid schema_diff erd_tool + psql_tool diff --git a/docs/en_US/images/psql_tool.png b/docs/en_US/images/psql_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f88ba5a573aa60bf7e08b8a38526dc73e8fcd5 GIT binary patch literal 23736 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 P=p;Q)S3j3^P6<r_JTn~) literal 0 HcmV?d00001 diff --git a/docs/en_US/psql_tool.rst b/docs/en_US/psql_tool.rst new file mode 100644 index 00000000..e0b3287e --- /dev/null +++ b/docs/en_US/psql_tool.rst @@ -0,0 +1,18 @@ +.. _psql_tool: + +****************** +`PSQL Tool`:index: +****************** + +PSQL tool allows user to connect to PostgreSQL server using psql terminal. + +* Login to PostgreSQL server through terminal in pgAdmin. +* execute all type of commands. + +.. image:: images/psql_tool.png + :alt: PSQL tool window + :align: center + +You can open multiple instance of the PSQL tool in individual tabs simultaneously. +To close the PSQL tool, click the *X* in the upper-right hand corner of the tab bar. + diff --git a/requirements.txt b/requirements.txt index edd7000b..fb8f25cd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,3 +36,6 @@ sshtunnel==0.* ldap3==2.* Flask-BabelEx==0.* gssapi==1.6.* + +flask-socketio>=5.0.1 +eventlet==0.30.2 diff --git a/web/config.py b/web/config.py index 2643ef19..002a9951 100644 --- a/web/config.py +++ b/web/config.py @@ -156,8 +156,8 @@ X_FRAME_OPTIONS = "SAMEORIGIN" # such as JavaScript, CSS, or pretty much anything that the browser loads. # see https://content-security-policy.com/#source_list for more info # e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';" -CONTENT_SECURITY_POLICY = "default-src http: data: blob: 'unsafe-inline' " \ - "'unsafe-eval';" +CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \ + " 'unsafe-eval';" # STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the # Strict-Transport-Security header @@ -636,6 +636,19 @@ KRB_AUTO_CREATE_USER = True KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache') +# PSQL tool settings +# This will enable PSQL tool in pgAdmin. So user can execute the commands using +# PSQL terminal in pgAdmin. +ENABLE_PSQL = True + +# ALLOW_PSQL_SHELL_COMMAND = True will disable the execution of os level +# commands using meta command \! from PSQL terminal. +# As PSQL allow user to execute the os level commands from the PSQL terminal +# user can execute any system level command as per the system login user +# privileges. Default this setting is set to False but if it set to True +# User will able to execute the system level commands through PSQL terminal in +# pgAdmin. +ALLOW_PSQL_SHELL_COMMANDS = False ########################################################################## # Local config settings diff --git a/web/package.json b/web/package.json index cc1e15ab..fc2e8193 100644 --- a/web/package.json +++ b/web/package.json @@ -103,6 +103,7 @@ "json-bignumber": "^1.0.1", "karma-coverage": "^2.0.3", "leaflet": "^1.5.1", + "lodash": "4.*", "ml-matrix": "^6.5.0", "moment": "^2.24.0", @@ -118,13 +119,18 @@ "shim-loader": "^1.0.1", "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16", "snapsvg-cjs": "^0.0.6", + "socket.io-client": "^4.0.0", "split.js": "^1.5.10", "tablesorter": "^2.31.2", "tempusdominus-bootstrap-4": "^5.1.2", "tempusdominus-core": "^5.0.3", "underscore": "^1.9.1", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36", - "wkx": "^0.5.0" + "wkx": "^0.5.0", + "xterm": "^4.11.0", + "xterm-addon-fit": "^0.5.0", + "xterm-addon-search": "^0.8.0", + "xterm-addon-web-links": "^0.4.0" }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index d2bd1af6..6e1e4ea6 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -15,6 +15,7 @@ to start a web server.""" import sys from cheroot.wsgi import Server as CherootServer + if sys.version_info < (3, 4): raise RuntimeError('This application must be run under Python 3.4 ' 'or later.') @@ -37,7 +38,7 @@ else: builtins.SERVER_MODE = None import config -from pgadmin import create_app +from pgadmin import create_app, socketio from pgadmin.utils import u_encode, fs_encoding, file_quote from pgadmin.utils.constants import INTERNAL # Get the config database schema version. We store this in pgadmin.model @@ -97,6 +98,8 @@ if not os.path.isfile(config.SQLITE_PATH): ########################################################################## app = create_app() app.debug = False +app.config['sessions'] = dict() + if config.SERVER_MODE: app.wsgi_app = ReverseProxied(app.wsgi_app) @@ -206,17 +209,16 @@ def main(): else: # Can use cheroot instead of flask dev server when not in debug # 10 is default thread count in CherootServer - num_threads = 10 if config.THREADED_MODE else 1 - prod_server = CherootServer( - (config.DEFAULT_SERVER, config.EFFECTIVE_SERVER_PORT), - wsgi_app=app, - numthreads=num_threads, - server_name=config.APP_NAME) + # num_threads = 10 if config.THREADED_MODE else 1 try: - print("Using production server...") - prod_server.start() + socketio.run( + app, + host=config.DEFAULT_SERVER, + port=config.EFFECTIVE_SERVER_PORT, + ) except KeyboardInterrupt: - prod_server.stop() + print("CLOSE SERVER") + socketio.stop() except IOError: app.logger.error("Error starting the app server: %s", sys.exc_info()) diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index a7333537..a641ea66 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -19,6 +19,7 @@ from collections import defaultdict from importlib import import_module from flask import Flask, abort, request, current_app, session, url_for +from flask_socketio import SocketIO from werkzeug.exceptions import HTTPException from flask_babelex import Babel, gettext from flask_babelex import gettext as _ @@ -52,10 +53,15 @@ import mimetypes mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('text/css', '.css') + winreg = None if os.name == 'nt': import winreg +socketio = SocketIO(manage_session=False, async_mode='eventlet', + logger=True, engineio_logger=True, debug=False, + ping_interval=25, ping_timeout=120) + class PgAdmin(Flask): def __init__(self, *args, **kwargs): @@ -811,4 +817,5 @@ def create_app(app_name=None): ########################################################################## # All done! ########################################################################## + socketio.init_app(app) return app diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 235db027..b093e3a4 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -10,6 +10,7 @@ from flask_babelex import gettext from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\ PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \ PREF_LABEL_OPTIONS +from flask_security import current_user import config LOCK_LAYOUT_LEVEL = { @@ -511,10 +512,12 @@ def register_browser_preferences(self): options=[{'label': gettext('Query Tool'), 'value': 'qt'}, {'label': gettext('Debugger'), 'value': 'debugger'}, {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], - help_str=gettext('Select Query Tool, Debugger, or Schema Diff from ' - 'the drop-down to set open in new browser tab for ' - 'that particular module.'), + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext('Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), select2={ 'multiple': True, 'allowClear': False, 'tags': True, 'first_empty': False, diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 01ab89c5..c4784d51 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -91,6 +91,11 @@ define('pgadmin.node.database', [ name: 'generate_erd', node: 'database', module: this, applies: ['object', 'context'], callback: 'generate_erd', category: 'erd', priority: 5, label: gettext('Generate ERD (Beta)'), + },{ + name: 'psql_tool', node: 'database', module: this, + applies: ['object', 'context'], callback: 'db_psql_tool', + category: 'psql_tool', priority: 5, label: gettext('PSQL Tool (Beta)'), + enable: 'is_psql_enabled' }]); _.bindAll(this, 'connection_lost'); @@ -122,6 +127,9 @@ define('pgadmin.node.database', [ is_connected: function(node) { return (node && node.connected == true && node.canDisconn == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, is_conn_allow: function(node) { return (node && node.allowConn == true); }, @@ -266,6 +274,15 @@ define('pgadmin.node.database', [ pgBrowser.erd.showErdTool(d, i, true); }, + /* Open psql tool for db*/ + db_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, + /* Connect the database (if not connected), before opening this node */ beforeopen: function(item, data) { if(!data || data._type != 'database' || data.label == 'template0') { diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index b21cba43..1a7a0cef 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -102,6 +102,12 @@ define('pgadmin.node.server', [ data_disabled: gettext('Database is already disconnected.'), }, },{ + name: 'server_psql', node: 'server', module: this, + applies: ['object', 'context'], callback: 'server_psql_tool', + category: 'psql_tool', priority: 5, label: gettext('PSQL Tool (Beta)'), + enable : 'is_psql_enabled', + }, + { name: 'reload_configuration', node: 'server', module: this, applies: ['tools', 'context'], callback: 'reload_configuration', category: 'reload', priority: 6, label: gettext('Reload Configuration'), @@ -183,6 +189,9 @@ define('pgadmin.node.server', [ is_connected: function(node) { return (node && node.connected == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, enable_reload_config: function(node) { // Must be connected & is Super user if (node && node._type == 'server' && @@ -728,6 +737,14 @@ define('pgadmin.node.server', [ return false; }, + /* Open psql tool for server*/ + server_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + } }, model: pgAdmin.Browser.Node.Model.extend({ defaults: { diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js index c9e64132..3068aabe 100644 --- a/web/pgadmin/browser/static/js/panel.js +++ b/web/pgadmin/browser/static/js/panel.js @@ -122,10 +122,30 @@ define( myPanel.on(ev, that.handleVisibility.bind(myPanel, ev)); }); } + + // Listen on detach panel event + myPanel.on(wcDocker.EVENT.DETACHED, function(obj) { + that.setCodeMirrorHeight(obj); + }); }, }); } }, + setCodeMirrorHeight: function() { + // Fix for mac os code-mirror showing black screen. + var txtArea = $('.pg-panel-content .sql_textarea > textarea').first(); + txtArea.css('z-index', -1); + var $tabContent = $('.pg-panel-content > .sql_textarea').first(); + var $sqlPane = $tabContent.find('.CodeMirror > div > textarea'); + for(let i=0; i<$sqlPane.length; i++) {$($sqlPane[i]).css('z-index', -1);} + + $tabContent = $('.pg-panel-content > .sql_textarea').first(); + $sqlPane = $tabContent.find('.pg-panel-content'); + $sqlPane.find('.CodeMirror').css( + 'cssText', + 'height: ' + ($tabContent.height()) + 'px !important;' + ); + }, eventFunc: function(eventName) { var name = $(this).data('pgAdminName'); diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 8597df48..b0a317a5 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -52,6 +52,10 @@ define('pgadmin.browser.utils', pgAdmin['user_inactivity_timeout'] = {{ current_app.config.get('USER_INACTIVITY_TIMEOUT') }}; pgAdmin['override_user_inactivity_timeout'] = '{{ current_app.config.get('OVERRIDE_USER_INACTIVITY_TIMEOUT') }}' == 'True'; + /* GET PSQL Tool related config */ + pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; + // Define list of nodes on which Query tool option doesn't appears var unsupported_nodes = pgAdmin.unsupported_nodes = [ 'server_group', 'server', 'coll-tablespace', 'tablespace', diff --git a/web/pgadmin/static/bundle/browser.js b/web/pgadmin/static/bundle/browser.js index 14140a2f..0b3ad81b 100644 --- a/web/pgadmin/static/bundle/browser.js +++ b/web/pgadmin/static/bundle/browser.js @@ -11,6 +11,7 @@ define('bundled_browser',[ 'pgadmin.browser', 'sources/browser/index', 'top/tools/erd/static/js/index', + 'top/tools/psql/static/js/index', ], function(pgBrowser) { pgBrowser.init(); }); diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css index c2a776c8..5b4a9f2d 100644 --- a/web/pgadmin/static/css/style.css +++ b/web/pgadmin/static/css/style.css @@ -21,3 +21,5 @@ @import '../vendor/backgrid/backgrid.css'; @import '../vendor/backgrid/backgrid-select-all.css'; + +@import 'node_modules/xterm/css/xterm.css'; diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py new file mode 100644 index 00000000..27ae7e2a --- /dev/null +++ b/web/pgadmin/tools/psql/__init__.py @@ -0,0 +1,503 @@ +#!/usr/bin/env python3 +import os +import re +import select +import signal +import termios +import struct +import fcntl +import pty +import config +import eventlet.green.subprocess as subprocess +from flask import Response, session, url_for, request +from pgadmin.browser.utils import underscore_unescape +from flask import render_template, copy_current_request_context, \ + current_app as app +from flask_babelex import gettext +from pgadmin.utils import PgAdminModule +from flask_security import login_required, current_user +from pgadmin.utils.constants import PREF_LABEL_DISPLAY, MIMETYPE_APP_JS, \ + ERROR_MSG_TRANS_ID_NOT_FOUND +from pgadmin.utils.driver import get_driver +from config import PG_DEFAULT_DRIVER +from pgadmin.model import Server +from pgadmin.utils import get_complete_file_path + +from ... import socketio as sio + +session_input = dict() +session_input_cursor = dict() +session_last_cmd = dict() +pdata = dict() +cdata = dict() + + +class PSQLModule(PgAdminModule): + """ + class PSQLModule(PgAdminModule) + A module class for PSQL derived from PgAdminModule. + """ + + LABEL = gettext("PSQL") + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.psql', + 'path': url_for('psql.index') + "psql", + 'when': None + }] + + def get_panels(self): + return [] + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints for PSQL module + """ + return [ + 'psql.panel', + ] + + +blueprint = PSQLModule('psql', __name__, static_url_path='/static') + + [email protected]("/psql.js") +@login_required +def script(): + """render the required javascript""" + return Response( + response=render_template("psql/js/psql.js", _=gettext), + status=200, + mimetype=MIMETYPE_APP_JS + ) + + [email protected]('/panel/<int:trans_id>', + methods=["POST"], + endpoint="panel") +@login_required +def panel(trans_id): + """ + Return panel template for PSQL tools. + :param trans_id: + """ + params = { + 'trans_id': trans_id, + 'title': request.form['title'] + } + if request.args: + params.update({k: v for k, v in request.args.items()}) + + return render_template('editor_template.html', + sid=params['sid'], + db=params['db'], + server_type=params['server_type'], + is_enable=config.ENABLE_PSQL, + title=underscore_unescape(params['title'])) + + +def set_term_size(fd, row, col, xpix=0, ypix=0): + """ + Set the terminal size as per UI xterm size. + :param fd: + :param row: + :param col: + :param xpix: + :param ypix: + """ + term_size = struct.pack('HHHH', row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) + + [email protected]('connect', namespace='/pty') +def connect(): + """ + Connect to the server through socket. + :return: + :rtype: + """ + if config.ENABLE_PSQL: + sio.emit('connected', {'sid': request.sid}, namespace='/pty', + to=request.sid) + if request.sid in session_last_cmd: + session_last_cmd[request.sid]['is_new_connection'] = False + else: + session_last_cmd[request.sid] = {'cmd': '', 'arrow_up': False, + 'invalid_cmd': False, + 'is_new_connection': True} + else: + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + [email protected]('start_process', namespace='/pty') +@login_required +def start_process(data): + """ + Start the pty terminal and execute psql command and emit results to user. + :param data: + :return: + """ + + @copy_current_request_context + def read_and_forward_pty_output(sid, data): + max_read_bytes = 1024 * 20 + # Create the pty terminal process, parent and fd are file descriptors + # for parent and child. + parent, fd = pty.openpty() + p = None + if parent is not None: + # Child process + p = subprocess.Popen(connection_data, + preexec_fn=os.setsid, + stdin=fd, + stdout=fd, + stderr=fd, + universal_newlines=True + ) + + app.config['sessions'][request.sid] = parent + pdata[request.sid] = p + cdata[request.sid] = fd + else: + app.config['sessions'][request.sid] = parent + cdata[request.sid] = fd + set_term_size(fd, 50, 50) + + while p and p.poll() is None: + if request.sid in app.config['sessions']: + # This code is added to make this unit testable. + if "is_test" not in data: + sio.sleep(0.01) + else: + data['count'] += 1 + if data['count'] == 5: + break + + timeout = 0 + # module provides access to platform-specific I/O + # monitoring functions + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) + + if parent in data_ready: + # Read the output from parent fd (terminal). + output = os.read(parent, max_read_bytes) + emit_output = True + + if sid in session_last_cmd and session_last_cmd[sid][ + 'arrow_up'] and not session_last_cmd[request.sid][ + 'arrow_left_right']: + session_last_cmd[sid]['cmd'] = output.decode() + session_input_cursor[request.sid] = len( + session_last_cmd[sid]['cmd']) + session_last_cmd[sid]['arrow_up'] = True + + if sid in session_last_cmd: + # If command is invalid then emit error to user. + if session_last_cmd[sid]['invalid_cmd']: + emit_output = False + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security;\r\n"), + 'error': True + }, + namespace='/pty', room=sid) + # If command is valid then emit output to user. + if emit_output: + sio.emit('pty-output', + {'result': output.decode(), + 'error': False}, + namespace='/pty', room=sid) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + + # Check user is authenticated and PSQL is enabled in config. + if current_user.is_authenticated and config.ENABLE_PSQL: + connection_data = [] + try: + db = '' + if data['db']: + db = data['db'] + # driver = get_driver(PG_DEFAULT_DRIVER) + # manager = driver.connection_manager(int(data['sid'])) + # conn = manager.connection() + conn, manager = _get_connection(int(data['sid']), data) + psql_utility = manager.utility('sql') + print("psql_utility: ", psql_utility) + connection_data = get_connection_str(psql_utility, conn, db, + manager) + except Exception as e: + # If any error raised during the start the PSQL emit error to UI. + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + + try: + sio.start_background_task(read_and_forward_pty_output, + request.sid, data) + except Exception as e: + print(e) + else: + # Show error if user is not authenticated. + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def _get_connection(sid, data): + """ + Get the connection object of ERD. + :param sid: + :param did: + :param trans_id: + :return: + """ + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + try: + conn = manager.connection() + if 'pwd' in data: + kwargs = {'password': data['pwd'], "user": data['user']} + status, msg = conn.connect(**kwargs) + else: + status, msg = conn.connect() + if not status: + app.logger.error(msg) + # raise ConnectionLost(sid, conn.db, trans_id) + + return conn, manager + except Exception as e: + app.logger.error(e) + raise + + +def get_connection_str(psql_utility, conn, db, manager): + """ + Get connection string(through connection dsn) + :param psql_utility: PostgreSQL binary path. + :param conn: Connection data + :param db: database name to connect specific db. + :return: connection attribute list for PSQL connection. + """ + + conn_attr = conn.conn.dsn + if 'password=xxx' in conn_attr: + conn_attr = conn_attr.replace('password=xxx', '') + + if db != '': + conn_attr = conn_attr.replace('dbname=postgres', + 'dbname={0}'.format(db)) + # Add application name to new created psql terminal instance + # through pgAdmin 4. + conn_attr = "{0} {1}".format(conn_attr, + " application_name='pgAdmin4: psql'") + + conn_attr_list = list() + conn_attr_list.append(psql_utility) + conn_attr_list.append(conn_attr) + return conn_attr_list + + [email protected]('socket_input', namespace='/pty') +def socket_input(data): + """ + This get the user input through socket. + :param data: User input from socket. + """ + try: + # Check PSQL enabled setting from config. + enable_psql = True if config.ENABLE_PSQL else False + + if request.sid in app.config['sessions']: + if data['key_name'] == 'Enter' and enable_psql: + # If user get previous executed command from history then set + # current command as previous executed command. + if session_last_cmd[request.sid]['cmd'] \ + and session_last_cmd[request.sid]['arrow_up']: + user_input = str( + session_last_cmd[request.sid]['cmd']).strip() + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + else: + user_input = str(session_input[request.sid]).strip() + session_input_cursor[request.sid] = 0 + + # If ALLOW_PSQL_SHELL_COMMANDS is False then user can't execute + # \! meta command to run shell commands through PSQL terminal. + # Check before executing the user entered command does not + # contains \! in input. + is_new_connection = session_last_cmd[request.sid][ + 'is_new_connection'] + if user_input.startswith('\\!') and \ + re.match("^\\\!$", user_input) and \ + len(user_input) == 2 and \ + not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not is_new_connection: + + session_last_cmd[request.sid]['invalid_cmd'] = True + + for i in range(len(session_input[request.sid])): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + session_input[request.sid] = '' + elif re.search("\\\!", user_input) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + stop_execution = True + # Check \! is passed as string or not. + double_quote_strs = re.findall('"([^"]*)"', user_input) + + if double_quote_strs: + for sub_str in double_quote_strs: + if re.search("\\\!", sub_str): + stop_execution = False + # break + + if stop_execution: + session_last_cmd[request.sid]['invalid_cmd'] = True + # Remove already added command from terminal. + for i in range(len(user_input)): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + # Add Enter event to execute the command. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + elif user_input == '\q': + # If user enter \q to terminate the PSQL, emit the msg to + # notify user connection is terminated. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + sio.emit('pty-output', + { + 'result': gettext( + 'Connection terminated, TO create new ' + 'connection please open another psql' + ' tool.'), + 'error': True}, + namespace='/pty', room=request.sid) + else: + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + session_input[request.sid] = '' + session_last_cmd[request.sid]['is_new_connection'] = False + else: + if data['key_name'] == 'ArrowLeft': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] > 0: + session_input_cursor[request.sid] -= 1 + + elif data['key_name'] == 'ArrowRight': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] < len( + session_input[request.sid]): + session_input_cursor[request.sid] += 1 + + elif data['key_name'] == 'ArrowUp': + session_last_cmd[request.sid]['arrow_up'] = True + session_last_cmd[request.sid]['arrow_left_right'] = False + session_input[request.sid] = session_last_cmd[request.sid][ + 'cmd'] + session_input_cursor[request.sid] = len( + session_last_cmd[request.sid]['cmd']) + + elif request.sid in session_input and data[ + 'key_name'] == 'Backspace' and ( + len(session_input[request.sid]) or len( + session_last_cmd[request.sid])): + + session_last_cmd[request.sid]['arrow_left_right'] = True + + if session_last_cmd[request.sid]['cmd']: + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + + user_input = list(session_input[request.sid]) + + if session_input_cursor[request.sid] == 1: + index = 0 + session_input_cursor[request.sid] -= 1 + else: + if session_input_cursor[request.sid] > 0: + index = (session_input_cursor[request.sid]) - 1 + session_input_cursor[request.sid] -= 1 + else: + index = session_input_cursor[request.sid] + session_input_cursor[request.sid] = 0 + + if len(user_input): + del user_input[index] + session_input[request.sid] = "".join(user_input) + + if len(session_input[request.sid]) == 0: + session_input_cursor[request.sid] = 0 + session_last_cmd[request.sid]['cmd'] = '' + elif request.sid in session_input: + if session_last_cmd[request.sid]['cmd'] and session_input[ + request.sid] == '': + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + session_input_cursor[request.sid] = len( + session_input[request.sid]) + else: + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + user_input = list(session_input[request.sid]) + user_input.insert(session_input_cursor[request.sid], + data['input']) + session_input[request.sid] = ''.join(user_input) + session_input_cursor[request.sid] += 1 + session_last_cmd[request.sid]['arrow_left_right'] = False + else: + session_input_cursor[request.sid] = 0 + session_input[request.sid] = data['input'] + session_input_cursor[request.sid] += 1 + + # Write user input to terminal parent fd. + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + except Exception as e: + # Delete socket id from sessions. + del app.config['sessions'][request.sid] + + [email protected]('resize', namespace='/pty') +def resize(data): + """ + Resize the pty terminal as per the UI terminal. + :param data: UI terminal rows and cols data + """ + if request.sid in app.config['sessions']: + set_term_size(app.config['sessions'][request.sid], data['rows'], + data['cols']) + + [email protected]('disconnect', namespace='/pty') +def disconnect(): + """ + Disconnect the socket and terminate the process + """ + if request.sid in pdata: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + os.write(app.config['sessions'][request.sid], '\q\n'.encode()) + sio.sleep(1) + os.close(app.config['sessions'][request.sid]) + os.close(cdata[request.sid]) + del app.config['sessions'][request.sid] + os.kill(pdata[request.sid].pid, signal.SIGSTOP) diff --git a/web/pgadmin/tools/psql/static/js/index.js b/web/pgadmin/tools/psql/static/js/index.js new file mode 100644 index 00000000..4d88ba04 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/index.js @@ -0,0 +1,23 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import $ from 'jquery'; +import _ from 'underscore'; +import pgAdmin from 'sources/pgadmin'; +import pgBrowser from 'top/browser/static/js/browser'; +import * as csrfToken from 'sources/csrf'; +import {initialize} from './psql_module'; + +let pgBrowserOut = initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser); + +module.exports = { + pgBrowser: pgBrowserOut, +}; diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js new file mode 100644 index 00000000..a9bdd90b --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -0,0 +1,329 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import { Terminal } from 'xterm'; +import { FitAddon } from 'xterm-addon-fit'; +import { WebLinksAddon } from 'xterm-addon-web-links'; +import { SearchAddon } from 'xterm-addon-search'; +import { io } from 'socketio'; +import Alertify from 'pgadmin.alertifyjs'; +import clipboard from 'sources/selection/clipboard'; + +import 'wcdocker'; +import {getRandomInt} from 'sources/utils'; +import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; + + +export function setPanelTitle(psqlToolPanel, panelTitle) { + psqlToolPanel.title('<span title="'+panelTitle+'">'+panelTitle+'</span>'); +} + +var wcDocker = window.wcDocker; + +export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) { + var pgBrowser = Browser; + var terminal = Terminal; + var parentData = null; + /* Return back, this has been called more than once */ + if (pgBrowser.psql) + return pgBrowser.psql; + + // Create an Object Restore of pgBrowser class + pgBrowser.psql = { + init: function() { + this.initialized = true; + + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'psql', + module: this, + applies: ['tools'], + callback: 'psql_tool', + priority: 1, + label: gettext('PSQL Tool (Beta)'), + enable: this.psqlToolEnabled, + }]; + + this.enable_psql_tool = pgAdmin['enable_psql']; + if(pgAdmin['enable_psql']) { + pgBrowser.add_menus(menus); + } + + // Creating a new pgBrowser frame to show the data. + var psqlFrameType = new pgBrowser.Frame({ + name: 'frm_psqltool', + showTitle: true, + isCloseable: true, + isPrivate: true, + url: 'about:blank', + }); + + let self = this; + /* Cache may take time to load for the first time + * Keep trying till available + */ + let cacheIntervalId = setInterval(function() { + if(pgBrowser.preference_version() > 0) { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + clearInterval(cacheIntervalId); + } + },0); + + pgBrowser.onPreferencesChange('psql', function() { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + }); + + // Load the newly created frame + psqlFrameType.load(pgBrowser.docker); + return this; + }, + + psqlToolEnabled: function(obj) { + //Same as query tool + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj)) { + if ((this.enable_psql_tool == true) && ((obj._type == 'server' && obj.connected == true )|| obj._type == 'database')) { + return true; + } else { + return false; + } + } else { + return false; + } + })(); + return isEnabled; + }, + retrieveAncestorOfTypeServer: function(item) { + let serverInformation = null; + // let aciTreeItem = item || pgBrowser.treeMenu.selected(); + let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); + + if (treeNode) { + let nodeData; + let databaseNode = treeNode.ancestorNode( + (node) => { + nodeData = node.getData(); + return (nodeData._type === 'database'); + } + ); + let isServerNode = (node) => { + nodeData = node.getData(); + return nodeData._type === 'server'; + }; + + if (databaseNode !== null) { + if (nodeData._label.indexOf('=') >= 0) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext( + 'Databases with = symbols in the name cannot be backed up or restored using this utility.' + ) + ); + } else { + if (databaseNode.anyParent(isServerNode)) + serverInformation = nodeData; + } + } else { + if (treeNode.anyFamilyMember(isServerNode)) + serverInformation = nodeData; + } + } + + if (serverInformation === null) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext('Please select server or child node from the browser tree.') + ); + } + return serverInformation; + }, + psql_tool: function(data, aciTreeIdentifier, gen=false) { + const module = 'paths'; + let preference_name = 'pg_bin_dir'; + let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.'); + const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeIdentifier); + + // const node1 = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if ((serverInformation.type && serverInformation.type === 'ppas') || + serverInformation.server_type === 'ppas') { + preference_name = 'ppas_bin_dir'; + msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'); + } + const preference = pgBrowser.get_preference(module, preference_name); + + if (preference) { + if (!preference.value) { + Alertify.alert(gettext('Configuration required'), msg); + return false; + } + } else { + Alertify.alert( + gettext(this.errorAlertTitle), + gettext('Failed to load preference %s of module %s', preference_name, module) + ); + return false; + } + const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if (node === undefined || !node.getData()) { + Alertify.alert( + gettext('PSQL Error'), + gettext('No object selected.') + ); + return; + } + + parentData = getTreeNodeHierarchyFromIdentifier.call( + pgBrowser, + aciTreeIdentifier + ); + + if(_.isUndefined(parentData.server)) { + Alertify.alert( + gettext('PSQL Error'), + gettext('Please select a server/database object.') + ); + return; + } + + const transId = getRandomInt(1, 9999999); + + var panelTitle = ''; + if (parentData.database) { + panelTitle = parentData.database.label + '/' + parentData.server.user_name + '@' + parentData.server.label; + } else { + panelTitle = parentData.server.user_name + '@' + parentData.server.label; + } + const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + + let psqlToolForm = ` + <form id="psqlToolForm" action="${panelUrl}" method="post"> + <input id="title" name="title" hidden /> + <input name="close_url" value="${panelCloseUrl}" hidden /> + </form> + <script> + document.getElementById("title").value = "${_.escape(panelTitle)}"; + document.getElementById("psqlToolForm").submit(); + </script> + `; + + var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; + if (open_new_tab && open_new_tab.includes('psql_tool')) { + var newWin = window.open('', '_blank'); + newWin.document.write(psqlToolForm); + newWin.document.title = panelTitle; + } else { + /* On successfully initialization find the properties panel, + * create new panel and add it to the dashboard panel. + */ + var propertiesPanel = pgBrowser.docker.findPanels('properties'); + var psqlToolPanel = pgBrowser.docker.addPanel('frm_psqltool', wcDocker.DOCK.STACKED, propertiesPanel[0]); + + // Set panel title and icon + setPanelTitle(psqlToolPanel, panelTitle); + psqlToolPanel.icon('fas fa-terminal'); + psqlToolPanel.focus(); + + // Listen on the panel closed event. + /*psqlToolPanel.on(wcDocker.EVENT.CLOSED, function() { + $.ajax({ + url: panelCloseUrl, + method: 'DELETE', + }); + });*/ + + var openPSQLToolURL = function(j) { + // add spinner element + let $spinner_el = + $(`<div class="pg-sp-container"> + <div class="pg-sp-content"> + <div class="row"> + <div class="col-12 pg-sp-icon"></div> + </div> + </div> + </div>`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { + var frameInitialized = $(j).data('frameInitialized'); + if (frameInitialized) { + clearInterval(init_poller_id); + var frame = $(j).data('embeddedFrame'); + if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); + frame.openHTML(psqlToolForm); + } + } + }, 100); + }; + + openPSQLToolURL(psqlToolPanel); + + } + + // var url_params = { + // 'sid': parentData.server._id, + // }; + // var baseUrl = url_for('psql.initialize', url_params); + // + // window.open(baseUrl, '_blank'); + }, + getPanelUrls: function(transId, panelTitle, parentData) { + let openUrl = url_for('psql.panel', { + trans_id: transId, + }); + + openUrl += `?sgid=${parentData.server_group._id}` + +`&sid=${parentData.server._id}` + +`&server_type=${parentData.server.server_type}`; + + if(parentData.database && parentData.database._id) { + openUrl += `&db=${parentData.database._label}`; + } else { + openUrl += `&db=${''}`; + } + + let closeUrl = url_for('psql.close', { + trans_id: transId, + // sgid: parentData.server_group._id, + // sid: parentData.server._id, + // did: parentData.database._id, + }); + return [openUrl, closeUrl]; + }, + psql_terminal: function() { + return new terminal({ + cursorBlink: true, + macOptionIsMeta: true, + scrollback: 10000, + }); + }, + psql_fit_screen: function() { + return new FitAddon(); + }, + psql_web_link: function() { + return new WebLinksAddon(); + }, + psql_search: function() { + return new SearchAddon(); + }, + psql_socket: function() { + return io('/pty', {pingTimeout: 120000, pingInterval: 25000}); + }, + get_parent_db: function(){ + return parentData.server; + }, + _clipboard: function() { + return clipboard; + } + }; + + return pgBrowser.psql; +} + diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html new file mode 100644 index 00000000..e5f50a29 --- /dev/null +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -0,0 +1,137 @@ +{% extends "base.html" %} +{% block title %}{{title}}{% endblock %} + +{% block css_link %} +<link type="text/css" rel="stylesheet" href="{{ url_for('browser.browser_css')}}"/> +{% endblock %} +{% block body %} +<style> + body {padding: 0px;} + {% if is_desktop_mode and is_linux %} + .alertify .ajs-dimmer,.alertify .ajs-modal{-webkit-transform: none;} + .alertify-notifier{-webkit-transform: none;} + .alertify-notifier .ajs-message{-webkit-transform: none;} + .alertify .ajs-dialog.ajs-shake{-webkit-animation-name: none;} + .sql-editor-busy-icon.fa-pulse{-webkit-animation: none;} + {% endif %} +</style> +<div style="width: 100%; height: 100%;" id="psql-terminal" class="psql_terminal"></div> +{% endblock %} + + +{% block init_script %} +require( + ['sources/generated/psql_tool'], + function(pgBrowser) { + const term = self.pgAdmin.Browser.psql.psql_terminal(); + + const fitAddon = self.pgAdmin.Browser.psql.psql_fit_screen(); + term.loadAddon(fitAddon); + let clipboard = self.pgAdmin.Browser.psql._clipboard(); + + const webLinksAddon = self.pgAdmin.Browser.psql.psql_web_link(); + term.loadAddon(webLinksAddon); + + const searchAddon = self.pgAdmin.Browser.psql.psql_search(); + term.loadAddon(searchAddon); + + term.open(document.getElementById('psql-terminal')); + fitAddon.fit() + term.resize(15, 50) + fitAddon.fit() + let selected_text = ''; + let user_input = ''; + let is_pwd = true; + let cursor_position = 0; + + term.attachCustomKeyEventHandler(e => { + e.stopPropagation(); + if(e.type=='keydown' && e.metaKey &&(e.key == 'v' || e.key == 'V')) { + if(selected_text != '') { + if (selected_text.length > 0) { + socket.emit("socket_input", {"input": selected_text, 'key_name': e.code}); + selected_text = ''; + } + } else { + navigator.clipboard.readText().then( clipText => { + selected_text = clipText; + if (selected_text.length > 0) { + socket.emit("socket_input", {"input": selected_text, 'key_name': e.code}); + selected_text = ''; + } + }); + } + + }else if(e.type=='keydown' && e.metaKey && (e.key == 'c' || e.key == 'C')) { + if (term.hasSelection()) { + selected_text = term.getSelection(); + } else { + selected_text = clipboard.readText(); + } + } +<!-- else if (e.type=='keydown' && e.keyCode == 32) {--> +<!-- user_input += e.key;--> +<!-- console.log('SPACEBAR');--> +<!-- socket.emit("socket_input", {"input": e.key, 'key_name': e.code});--> +<!-- }--> + return true; + }); + + term.onKey(function (ev) { + if (pgAdmin['allow_psql_shell_commands']) { + socket.emit("socket_input", {"input": ev.key, 'key_name': ev.domEvent.code}); + } else { + console.log("socket_input" + ev.key); + socket.emit("socket_input", {"input": ev.key, 'key_name': ev.domEvent.code}); + } + }); + + const socket = self.pgAdmin.Browser.psql.psql_socket(); + + socket.on("pty-output", function(data){ + if(data.error) { + term.write('\r\n'); + } + term.write(data.result); + if(data.error) { + term.write('\r\n'); + } + }) + + socket.on("connect", () => { + if('{{is_enable}}' == 'True'){ + socket.emit('start_process', {"sid": {{sid}}, "db": '{{db}}', 'stype': '{{server_type}}' }); + } + fitToscreen(); + }); + + socket.on("conn_error", (response) => { + term.write(response.error); + fitToscreen(); + }); + + socket.on("conn_not_allow", () => { + term.write('PSQL connection not allowed'); + fitToscreen(); + }); + + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } + + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) + } + } + + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) + }); +{% endblock %} + + diff --git a/web/pgadmin/tools/psql/tests/__init__.py b/web/pgadmin/tools/psql/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web/pgadmin/tools/psql/tests/psql_test_data.json b/web/pgadmin/tools/psql/tests/psql_test_data.json new file mode 100644 index 00000000..9b2cfaf5 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/psql_test_data.json @@ -0,0 +1,174 @@ +{ + "psql_user_input": [ + { + "name": "Enter Select 1;", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "move_cursor_up": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "is_history": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowLeft", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowLeft": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowRight", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Read previous executed command", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "move_cursor_right": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\!", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! with other cmd not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\! ls", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Valid commands", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select \"\\!\"", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Exist psql terminal by using \\q", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\q", + "mock_data": { + + }, + "expected_data": { + } + } + ], + "resize_terminal": [ + { + "name": "Resize psql terminal as per UI.", + "is_positive_test": true, + "mocking_required": false, + "input_data": { + "cols": 141, + "rows": 39 + }, + "mock_data": { + + }, + "expected_data": { + } + } + ], + "backend_task": [ + { + "name": "Backend Task", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "Select 1;", + "is_backend_task": true, + "mock_data": { + "is_test": true + }, + "expected_data": { + } + } + ] +} diff --git a/web/pgadmin/tools/psql/tests/test_backend_task.py b/web/pgadmin/tools/psql/tests/test_backend_task.py new file mode 100644 index 00000000..99073c0a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_backend_task.py @@ -0,0 +1,88 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLBackend(BaseTestGenerator): + scenarios = utils.generate_scenarios('backend_task', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'], + 'is_test': True, + 'count': 0 + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_panel.py b/web/pgadmin/tools/psql/tests/test_panel.py new file mode 100644 index 00000000..83480681 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_panel.py @@ -0,0 +1,35 @@ +import uuid +import random +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data + + +class PSQLPanel(BaseTestGenerator): + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + + def runTest(self): + trans_id = random.randint(1, 9999999) + url = '/psql/panel/{trans_id}?sgid={sgid}&sid={sid}&server_type=pg' \ + '&db={db_name}'.\ + format(trans_id=trans_id, sgid=self.sgid, sid=self.sid, + db_name=self.db_name) + + response = self.tester.post( + url, data={"title": "panel_title"}, + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_disabled.py b/web/pgadmin/tools/psql/tests/test_psql_disabled.py new file mode 100644 index 00000000..32eaa623 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_disabled.py @@ -0,0 +1,36 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +# from flask import current_app as app + +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisabled(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = False + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + print("received:", received) + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_input.py b/web/pgadmin/tools/psql/tests/test_psql_input.py new file mode 100644 index 00000000..8fe0b47a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_input.py @@ -0,0 +1,159 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLInput(BaseTestGenerator): + scenarios = utils.generate_scenarios('psql_user_input', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + print("received values: ", received) + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + received = self.test_client.get_received('/pty') + print("user I/P:: ", received) + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + received = self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_backspace') and self.is_backspace: + if hasattr(self, 'move_cursor_up') and self.move_cursor_up: + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Backspace' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowUp') and self.is_arrowUp: + if hasattr(self, 'is_history') and self.is_history: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowLeft') and self.is_arrowLeft: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowRight') and self.is_arrowRight: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'move_cursor_right') and self.is_arrowRight: + for i in range(2): + input_data = { + 'input': '', + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + input_data = { + 'input': '', + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + received = self.test_client.get_received('/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_resize_terminal.py b/web/pgadmin/tools/psql/tests/test_resize_terminal.py new file mode 100644 index 00000000..9ce7d004 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_resize_terminal.py @@ -0,0 +1,60 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLResizeTerminal(BaseTestGenerator): + scenarios = utils.generate_scenarios('resize_terminal', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + + self.test_client.emit('resize', self.input_data, namespace='/pty') + + # self.test_client.disconnect(namespace='/pty') + # self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_connect.py b/web/pgadmin/tools/psql/tests/test_socket_connect.py new file mode 100644 index 00000000..7b8031bd --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_connect.py @@ -0,0 +1,36 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +# from flask import current_app as app +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketConnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + print("received:", received) + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py new file mode 100644 index 00000000..cd2cf5ac --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py @@ -0,0 +1,35 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +# from flask import current_app as app +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisconnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + print("received:", received) + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process.py b/web/pgadmin/tools/psql/tests/test_start_process.py new file mode 100644 index 00000000..055f7ce3 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process.py @@ -0,0 +1,63 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils.driver import get_driver +from config import PG_DEFAULT_DRIVER +from .... import socketio + + +class PSQLStartProcess(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + self.server_con = server_utils.connect_server(self, self.sid) + print(self.server_con) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + import random + trans_id = random.randint(1, 9999999) + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + print("received values: ", received) + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process_fail.py b/web/pgadmin/tools/psql/tests/test_start_process_fail.py new file mode 100644 index 00000000..895fc533 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process_fail.py @@ -0,0 +1,60 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from .... import socketio + + +class PSQLStartProcessFail(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + db_con = database_utils.connect_database(self, + self.sgid, + self.sid, + self.did) + print("DB connection") + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/session') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + print("received:", received) + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + import random + trans_id = random.randint(1, 9999999) + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + config.ENABLE_PSQL = False + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/utils.py b/web/pgadmin/tools/psql/tests/utils.py new file mode 100644 index 00000000..85bd5373 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/utils.py @@ -0,0 +1,6 @@ +import os +import json + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/psql_test_data.json") as data_file: + test_cases = json.load(data_file) diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss index 0bb40802..5ffc8241 100644 --- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss +++ b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss @@ -374,3 +374,9 @@ div.strikeout:after { /* Setting it to hardcoded white as the SVG generated is having white bg * Need to check what can be done. */ + +/* Css for psql */ +.psql_terminal .terminal { + padding-top: 1%; + padding-left: 0.5%; +} diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py index 23abfffa..71ae82ea 100644 --- a/web/pgadmin/utils/csrf.py +++ b/web/pgadmin/utils/csrf.py @@ -38,6 +38,7 @@ class _PGCSRFProtect(CSRFProtect): 'pgadmin.tools.schema_diff.ddl_compare', 'pgadmin.authenticate.login', 'pgadmin.tools.erd.panel', + 'pgadmin.tools.psql.panel', ] for exempt in exempt_views: diff --git a/web/pgadmin/utils/preferences.py b/web/pgadmin/utils/preferences.py index 15ceeb1a..e9efe479 100644 --- a/web/pgadmin/utils/preferences.py +++ b/web/pgadmin/utils/preferences.py @@ -72,6 +72,7 @@ class _Preference(object): self.select2 = kwargs.get('select2', None) self.fields = kwargs.get('fields', None) self.allow_blanks = kwargs.get('allow_blanks', None) + self.disabled = kwargs.get('disabled', False) # Look into the configuration table to find out the id of the specific # preference. @@ -252,6 +253,7 @@ class _Preference(object): 'select2': self.select2, 'value': self.get(), 'fields': self.fields, + 'disabled': self.disabled, } return res @@ -414,6 +416,7 @@ class Preferences(object): :param fields: field schema (if preference has more than one field to take input from user e.g. keyboardshortcut preference) :param allow_blanks: Flag specify whether to allow blank value. + :param disabled: Flag specify whether to disable the setting or not. """ min_val = kwargs.get('min_val', None) max_val = kwargs.get('max_val', None) @@ -423,6 +426,7 @@ class Preferences(object): select2 = kwargs.get('select2', None) fields = kwargs.get('fields', None) allow_blanks = kwargs.get('allow_blanks', None) + disabled = kwargs.get('disabled', False) cat = self.__category(category, category_label) if name in cat['preferences']: @@ -439,7 +443,8 @@ class Preferences(object): (cat['preferences'])[name] = res = _Preference( cat['id'], name, label, _type, default, help_str=help_str, min_val=min_val, max_val=max_val, options=options, - select2=select2, fields=fields, allow_blanks=allow_blanks + select2=select2, fields=fields, allow_blanks=allow_blanks, + disabled=disabled ) return res diff --git a/web/webpack.config.js b/web/webpack.config.js index e906a567..104a3b20 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -355,6 +355,7 @@ module.exports = [{ debugger_direct: './pgadmin/tools/debugger/static/js/direct.js', schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js', erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js', + psql_tool: './pgadmin/tools/psql/static/js/index.js', file_utils: './pgadmin/misc/file_manager/static/js/utility.js', 'pgadmin.style': pgadminCssStyles, pgadmin: pgadminScssStyles, @@ -493,7 +494,7 @@ module.exports = [{ ], }, }, - }, { + },{ test: require.resolve('./node_modules/acitree/js/jquery.aciTree.min'), use: { loader: 'imports-loader', @@ -532,6 +533,7 @@ module.exports = [{ 'pure|pgadmin.tools.storage_manager', 'pure|pgadmin.tools.search_objects', 'pure|pgadmin.tools.erd_module', + 'pure|pgadmin.tools.psql_module', ], }, }, diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 074b2580..e0b28091 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -159,6 +159,15 @@ var webpackShimConfig = { 'jquery.acisortable': path.join(__dirname, './node_modules/acitree/js/jquery.aciSortable.min'), 'jquery.acifragment': path.join(__dirname, './node_modules/acitree/js/jquery.aciFragment.min'), + //xterm + 'xterm': path.join(__dirname, './node_modules/xterm/lib/xterm.js'), + 'xterm-addon-fit': path.join(__dirname, './node_modules/xterm-addon-fit/lib/xterm-addon-fit.js'), + 'xterm-addon-web-links': path.join(__dirname, './node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js'), + 'xterm-addon-search': path.join(__dirname, './node_modules/xterm-addon-search/lib/xterm-addon-search.js'), + + //socket + 'socketio': path.join(__dirname, './node_modules/socket.io-client/dist/socket.io.js'), + // Backbone and Backgrid 'backbone': path.join(__dirname, './node_modules/backbone/backbone'), 'backbone.undo': path.join(__dirname, './node_modules/backbone-undo/Backbone.Undo'), @@ -288,6 +297,8 @@ var webpackShimConfig = { 'pgadmin.tools.storage_manager': path.join(__dirname, './pgadmin/tools/storage_manager/static/js/storage_manager'), 'pgadmin.tools.erd_module': path.join(__dirname, './pgadmin/tools/erd/static/js/erd_module'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index e0b6fd69..3cc079f9 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -177,6 +177,7 @@ module.exports = { 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), 'tools': path.join(__dirname, './pgadmin/tools/'), 'pgadmin.user_management.current_user': regressionDir + '/javascript/fake_current_user', ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-11 08:02 Akshay Joshi <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Akshay Joshi @ 2021-05-11 08:02 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: Dave Page <[email protected]>; pgadmin-hackers Hi Nikhil Following are the review comments: *GUI specific*: - We need a panel icon for PSQL like query tool, we can also add that on the browser tree toolbar. - PSQL Tool menu should be visible for all the child nodes of the database node. Follow the same as Query Tool. - PSQL tab title should be only database server name as the user can change the database/user from PSQL command, so it's been difficult to update the tab title. - PSQL connection is still open even if we disconnect the database server from the browser tree. *Code specific:* - Remove an extra space from requirements.txt and package.json - Documentation needs to be updated to let the user know from where the PSQL tool will open and on which node it is applicable. - psql/__init__.py check there are so many unused imports please remove them. - We are not using cheroot so it should be removed from requirements.txt and also remove the import statement from pgAdmin4.py - Test cases are showing successful but actually, there are some routing errors please check. On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < [email protected]> wrote: > Hi Dave/ Team, > > PFA updated patch, sorry for the inconvenience, while cleanup I removed > the unwanted libraries but forgot to remove the code related to them. > > On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Hackers, >>> >>> Please find the attached patch for RM-2341 >>> <https://redmine.postgresql.org/issues/2341;: Add Menu option for >>> starting PSQL. >>> 1. Added new Option PSQL Tool in Tools menu. >>> 2. Added the same option for Server and Database nodes from the tree >>> view. >>> >> >> Unfortunately there's a trailing comma in package.json that makes it >> invalid. If I fix that, then I get the error below, so I'm guessing the >> intention was to actually include another package there? >> >> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >> Module not found: Error: Can't resolve 'local-echo-controller' in >> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >> resolve 'local-echo-controller' in >> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >> Parsed request is a module >> using description file: /Users/dpage/git/pgadmin4/web/package.json >> (relative path: ./pgadmin/tools/psql/static/js) >> aliased with mapping 'local-echo-controller': >> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >> using description file: /Users/dpage/git/pgadmin4/web/package.json >> (relative path: ./pgadmin/tools/psql/static/js) >> Field 'browser' doesn't contain a valid alias configuration >> root path /Users/dpage/git/pgadmin4/web >> using description file: >> /Users/dpage/git/pgadmin4/web/package.json (relative path: >> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >> no extension >> Field 'browser' doesn't contain a valid alias configuration >> >> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >> doesn't exist >> .js >> Field 'browser' doesn't contain a valid alias configuration >> >> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >> doesn't exist >> .jsx >> Field 'browser' doesn't contain a valid alias configuration >> >> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >> doesn't exist >> as directory >> >> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >> doesn't exist >> using description file: >> /Users/dpage/git/pgadmin4/web/package.json (relative path: >> ./node_modules/local-echo) >> no extension >> Field 'browser' doesn't contain a valid alias configuration >> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't >> exist >> .js >> Field 'browser' doesn't contain a valid alias configuration >> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >> doesn't exist >> .jsx >> Field 'browser' doesn't contain a valid alias configuration >> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >> doesn't exist >> as directory >> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't >> exist >> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >> >> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 ms >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> > > Regards, > Nikhil Mohite > -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-11 10:10 Dave Page <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-05-11 10:10 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers Hi On Tue, May 11, 2021 at 9:02 AM Akshay Joshi <[email protected]> wrote: > Hi Nikhil > > Following are the review comments: > > *GUI specific*: > > - We need a panel icon for PSQL like query tool, we can also add that > on the browser tree toolbar. > - PSQL Tool menu should be visible for all the child nodes of the > database node. Follow the same as Query Tool. > - PSQL tab title should be only database server name as the user can > change the database/user from PSQL command, so it's been difficult to > update the tab title. > - PSQL connection is still open even if we disconnect the database > server from the browser tree. > > *Code specific:* > > - Remove an extra space from requirements.txt and package.json > - Documentation needs to be updated to let the user know from where > the PSQL tool will open and on which node it is applicable. > - psql/__init__.py check there are so many unused imports please > remove them. > - We are not using cheroot so it should be removed from > requirements.txt and also remove the import statement from pgAdmin4.py > - Test cases are showing successful but actually, there are some > routing errors please check. > > A few other things I noticed: - I was prompted to enter a password. This should be passed in the environment to psql as it is for pg_dump etc. - There seems to be an issue with terminal compatibility (which I didn't have on my prototype): ml=# select * from pg_class; WARNING: terminal is not fully functional -[ RECORD 1 ]-------+---------------------------------------------- oid | 79354 relname | housing ... - The panel should honour the styleguide. I'm running in dark mode, and see a jet black background. I would expect to see the same background/foreground colours as the treeview. - I spotted at least one print() statement that shouldn't be there (debug output should go through the logger) - psql/__init__.py:235 - This seems suspect - why would there be a password in a connection string we've built? And why would it be xxx? if 'password=xxx' in conn_attr: conn_attr = conn_attr.replace('password=xxx', '') - There's a thick white line at the bottom of the panel, where a horizontal scrollbar might be if there was one. - The trailing semi-colon should be removed from: "ERROR: Shell commands are disabled in psql for security;" Once we're happy with the patch in general, I'll do a string review before committing. In particular, I want to be sure the text in config.py is appropriately worded. This is shaping up nicely! Good work. > > On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Dave/ Team, >> >> PFA updated patch, sorry for the inconvenience, while cleanup I removed >> the unwanted libraries but forgot to remove the code related to them. >> >> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Hackers, >>>> >>>> Please find the attached patch for RM-2341 >>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option for >>>> starting PSQL. >>>> 1. Added new Option PSQL Tool in Tools menu. >>>> 2. Added the same option for Server and Database nodes from the tree >>>> view. >>>> >>> >>> Unfortunately there's a trailing comma in package.json that makes it >>> invalid. If I fix that, then I get the error below, so I'm guessing the >>> intention was to actually include another package there? >>> >>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>> Module not found: Error: Can't resolve 'local-echo-controller' in >>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>> resolve 'local-echo-controller' in >>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>> Parsed request is a module >>> using description file: /Users/dpage/git/pgadmin4/web/package.json >>> (relative path: ./pgadmin/tools/psql/static/js) >>> aliased with mapping 'local-echo-controller': >>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>> using description file: /Users/dpage/git/pgadmin4/web/package.json >>> (relative path: ./pgadmin/tools/psql/static/js) >>> Field 'browser' doesn't contain a valid alias configuration >>> root path /Users/dpage/git/pgadmin4/web >>> using description file: >>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>> no extension >>> Field 'browser' doesn't contain a valid alias configuration >>> >>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>> doesn't exist >>> .js >>> Field 'browser' doesn't contain a valid alias configuration >>> >>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>> doesn't exist >>> .jsx >>> Field 'browser' doesn't contain a valid alias configuration >>> >>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>> doesn't exist >>> as directory >>> >>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>> doesn't exist >>> using description file: >>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>> ./node_modules/local-echo) >>> no extension >>> Field 'browser' doesn't contain a valid alias configuration >>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>> doesn't exist >>> .js >>> Field 'browser' doesn't contain a valid alias configuration >>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>> doesn't exist >>> .jsx >>> Field 'browser' doesn't contain a valid alias configuration >>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>> doesn't exist >>> as directory >>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>> doesn't exist >>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>> >>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 ms >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >> >> Regards, >> Nikhil Mohite >> > > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-17 10:01 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-05-17 10:01 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: pgadmin-hackers; Dave Page <[email protected]> Hi Akshay/ Team, Please find the attached updated patch for the psql tool. On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> wrote: > Hi > > On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < > [email protected]> wrote: > >> Hi Nikhil >> >> Following are the review comments: >> >> *GUI specific*: >> >> - We need a panel icon for PSQL like query tool, we can also add that >> on the browser tree toolbar. >> - PSQL Tool menu should be visible for all the child nodes of the >> database node. Follow the same as Query Tool. >> - PSQL tab title should be only database server name as the user can >> change the database/user from PSQL command, so it's been difficult to >> update the tab title. >> - PSQL connection is still open even if we disconnect the database >> server from the browser tree. >> >> *Code specific:* >> >> - Remove an extra space from requirements.txt and package.json >> - Documentation needs to be updated to let the user know from where >> the PSQL tool will open and on which node it is applicable. >> - psql/__init__.py check there are so many unused imports please >> remove them. >> - We are not using cheroot so it should be removed from >> requirements.txt and also remove the import statement from pgAdmin4.py >> - Test cases are showing successful but actually, there are some >> routing errors please check. >> >> A few other things I noticed: > > - I was prompted to enter a password. This should be passed in the > environment to psql as it is for pg_dump etc. > - There seems to be an issue with terminal compatibility (which I didn't > have on my prototype): > > ml=# select * from pg_class; > WARNING: terminal is not fully functional > -[ RECORD 1 ]-------+---------------------------------------------- > oid | 79354 > relname | housing > ... > > - The panel should honour the styleguide. I'm running in dark mode, and > see a jet black background. I would expect to see the same > background/foreground colours as the treeview. > - I spotted at least one print() statement that shouldn't be there (debug > output should go through the logger) - psql/__init__.py:235 > - This seems suspect - why would there be a password in a connection > string we've built? And why would it be xxx? > > if 'password=xxx' in conn_attr: > conn_attr = conn_attr.replace('password=xxx', '') > > - There's a thick white line at the bottom of the panel, where a > horizontal scrollbar might be if there was one. > - The trailing semi-colon should be removed from: "ERROR: Shell commands > are disabled in psql for security;" > > Once we're happy with the patch in general, I'll do a string review before > committing. In particular, I want to be sure the text in config.py is > appropriately worded. > > This is shaping up nicely! Good work. > > >> >> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Dave/ Team, >>> >>> PFA updated patch, sorry for the inconvenience, while cleanup I removed >>> the unwanted libraries but forgot to remove the code related to them. >>> >>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Hackers, >>>>> >>>>> Please find the attached patch for RM-2341 >>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option for >>>>> starting PSQL. >>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>> 2. Added the same option for Server and Database nodes from the tree >>>>> view. >>>>> >>>> >>>> Unfortunately there's a trailing comma in package.json that makes it >>>> invalid. If I fix that, then I get the error below, so I'm guessing the >>>> intention was to actually include another package there? >>>> >>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>> Module not found: Error: Can't resolve 'local-echo-controller' in >>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>> resolve 'local-echo-controller' in >>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>> Parsed request is a module >>>> using description file: /Users/dpage/git/pgadmin4/web/package.json >>>> (relative path: ./pgadmin/tools/psql/static/js) >>>> aliased with mapping 'local-echo-controller': >>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>> using description file: >>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>> ./pgadmin/tools/psql/static/js) >>>> Field 'browser' doesn't contain a valid alias configuration >>>> root path /Users/dpage/git/pgadmin4/web >>>> using description file: >>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>> no extension >>>> Field 'browser' doesn't contain a valid alias >>>> configuration >>>> >>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>> doesn't exist >>>> .js >>>> Field 'browser' doesn't contain a valid alias >>>> configuration >>>> >>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>> doesn't exist >>>> .jsx >>>> Field 'browser' doesn't contain a valid alias >>>> configuration >>>> >>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>> doesn't exist >>>> as directory >>>> >>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>> doesn't exist >>>> using description file: >>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>> ./node_modules/local-echo) >>>> no extension >>>> Field 'browser' doesn't contain a valid alias configuration >>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>> doesn't exist >>>> .js >>>> Field 'browser' doesn't contain a valid alias configuration >>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>> doesn't exist >>>> .jsx >>>> Field 'browser' doesn't contain a valid alias configuration >>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>> doesn't exist >>>> as directory >>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>> doesn't exist >>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>> >>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 ms >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>> >>> Regards, >>> Nikhil Mohite >>> >> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > Regards, Nikhil Mohite Attachments: [application/octet-stream] RM_2341_V3.patch (351.1K, 3-RM_2341_V3.patch) download | inline diff: diff --git a/docs/en_US/developer_tools.rst b/docs/en_US/developer_tools.rst index 1ff442cc..bb67e33a 100644 --- a/docs/en_US/developer_tools.rst +++ b/docs/en_US/developer_tools.rst @@ -16,3 +16,4 @@ PL/SQL code. editgrid schema_diff erd_tool + psql_tool diff --git a/docs/en_US/images/psql_tool.png b/docs/en_US/images/psql_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f88ba5a573aa60bf7e08b8a38526dc73e8fcd5 GIT binary patch literal 23736 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 P=p;Q)S3j3^P6<r_JTn~) literal 0 HcmV?d00001 diff --git a/docs/en_US/images/psql_tool_menu.png b/docs/en_US/images/psql_tool_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..c219a0787868bd9427cfc056ce18c9ab562e52bd GIT binary patch literal 187181 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 literal 0 HcmV?d00001 diff --git a/docs/en_US/psql_tool.rst b/docs/en_US/psql_tool.rst new file mode 100644 index 00000000..8791648a --- /dev/null +++ b/docs/en_US/psql_tool.rst @@ -0,0 +1,23 @@ +.. _psql_tool: + +****************** +`PSQL Tool`:index: +****************** + +PSQL tool allows user to connect to PostgreSQL server using psql terminal. + +* Open PSQL Tool from Tools menu or context menu PSQL Tool from tree view. + +.. image:: images/psql_tool_menu.png + :alt: PSQL tool menu + :align: center + +* execute all type of commands. + +.. image:: images/psql_tool.png + :alt: PSQL tool window + :align: center + +You can open multiple instance of the PSQL tool in individual tabs simultaneously. +To close the PSQL tool, click the *X* in the upper-right hand corner of the tab bar. + diff --git a/requirements.txt b/requirements.txt index edd7000b..8227a4c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,6 @@ # ############################################################################### -cheroot==8.* Flask==1.* Flask-Gravatar==0.* Flask-Login==0.* @@ -36,3 +35,5 @@ sshtunnel==0.* ldap3==2.* Flask-BabelEx==0.* gssapi==1.6.* +flask-socketio>=5.0.1 +eventlet==0.30.2 diff --git a/web/config.py b/web/config.py index 2643ef19..002a9951 100644 --- a/web/config.py +++ b/web/config.py @@ -156,8 +156,8 @@ X_FRAME_OPTIONS = "SAMEORIGIN" # such as JavaScript, CSS, or pretty much anything that the browser loads. # see https://content-security-policy.com/#source_list for more info # e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';" -CONTENT_SECURITY_POLICY = "default-src http: data: blob: 'unsafe-inline' " \ - "'unsafe-eval';" +CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \ + " 'unsafe-eval';" # STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the # Strict-Transport-Security header @@ -636,6 +636,19 @@ KRB_AUTO_CREATE_USER = True KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache') +# PSQL tool settings +# This will enable PSQL tool in pgAdmin. So user can execute the commands using +# PSQL terminal in pgAdmin. +ENABLE_PSQL = True + +# ALLOW_PSQL_SHELL_COMMAND = True will disable the execution of os level +# commands using meta command \! from PSQL terminal. +# As PSQL allow user to execute the os level commands from the PSQL terminal +# user can execute any system level command as per the system login user +# privileges. Default this setting is set to False but if it set to True +# User will able to execute the system level commands through PSQL terminal in +# pgAdmin. +ALLOW_PSQL_SHELL_COMMANDS = False ########################################################################## # Local config settings diff --git a/web/package.json b/web/package.json index 8ed32df9..19110fda 100644 --- a/web/package.json +++ b/web/package.json @@ -117,13 +117,18 @@ "shim-loader": "^1.0.1", "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16", "snapsvg-cjs": "^0.0.6", + "socket.io-client": "^4.0.0", "split.js": "^1.5.10", "tablesorter": "^2.31.2", "tempusdominus-bootstrap-4": "^5.1.2", "tempusdominus-core": "^5.0.3", "underscore": "^1.13.1", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36", - "wkx": "^0.5.0" + "wkx": "^0.5.0", + "xterm": "^4.11.0", + "xterm-addon-fit": "^0.5.0", + "xterm-addon-search": "^0.8.0", + "xterm-addon-web-links": "^0.4.0" }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index d2bd1af6..dc1924cb 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -13,7 +13,7 @@ to start a web server.""" import sys -from cheroot.wsgi import Server as CherootServer + if sys.version_info < (3, 4): raise RuntimeError('This application must be run under Python 3.4 ' @@ -37,7 +37,7 @@ else: builtins.SERVER_MODE = None import config -from pgadmin import create_app +from pgadmin import create_app, socketio from pgadmin.utils import u_encode, fs_encoding, file_quote from pgadmin.utils.constants import INTERNAL # Get the config database schema version. We store this in pgadmin.model @@ -97,6 +97,8 @@ if not os.path.isfile(config.SQLITE_PATH): ########################################################################## app = create_app() app.debug = False +app.config['sessions'] = dict() + if config.SERVER_MODE: app.wsgi_app = ReverseProxied(app.wsgi_app) @@ -206,17 +208,16 @@ def main(): else: # Can use cheroot instead of flask dev server when not in debug # 10 is default thread count in CherootServer - num_threads = 10 if config.THREADED_MODE else 1 - prod_server = CherootServer( - (config.DEFAULT_SERVER, config.EFFECTIVE_SERVER_PORT), - wsgi_app=app, - numthreads=num_threads, - server_name=config.APP_NAME) + # num_threads = 10 if config.THREADED_MODE else 1 try: - print("Using production server...") - prod_server.start() + socketio.run( + app, + host=config.DEFAULT_SERVER, + port=config.EFFECTIVE_SERVER_PORT, + ) except KeyboardInterrupt: - prod_server.stop() + print("CLOSE SERVER") + socketio.stop() except IOError: app.logger.error("Error starting the app server: %s", sys.exc_info()) diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index a7333537..fad91082 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -19,6 +19,7 @@ from collections import defaultdict from importlib import import_module from flask import Flask, abort, request, current_app, session, url_for +from flask_socketio import SocketIO from werkzeug.exceptions import HTTPException from flask_babelex import Babel, gettext from flask_babelex import gettext as _ @@ -52,10 +53,15 @@ import mimetypes mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('text/css', '.css') + winreg = None if os.name == 'nt': import winreg +socketio = SocketIO(manage_session=False, async_mode='eventlet', + logger=False, engineio_logger=False, debug=False, + ping_interval=25, ping_timeout=120) + class PgAdmin(Flask): def __init__(self, *args, **kwargs): @@ -811,4 +817,5 @@ def create_app(app_name=None): ########################################################################## # All done! ########################################################################## + socketio.init_app(app) return app diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 235db027..d835ca82 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -10,6 +10,7 @@ from flask_babelex import gettext from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\ PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \ PREF_LABEL_OPTIONS +from flask_security import current_user import config LOCK_LAYOUT_LEVEL = { @@ -511,10 +512,12 @@ def register_browser_preferences(self): options=[{'label': gettext('Query Tool'), 'value': 'qt'}, {'label': gettext('Debugger'), 'value': 'debugger'}, {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], - help_str=gettext('Select Query Tool, Debugger, or Schema Diff from ' - 'the drop-down to set open in new browser tab for ' - 'that particular module.'), + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext('Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), select2={ 'multiple': True, 'allowClear': False, 'tags': True, 'first_empty': False, @@ -523,3 +526,16 @@ def register_browser_preferences(self): 'placeholder': gettext('Select open new tab...') } ) + + self.psql_tab_title = self.preference.register( + 'tab_settings', 'psql_tab_title_placeholder', + gettext("PSQL tool tab title"), + 'text', '%DATABASE%/%USERNAME%@%SERVER%', + category_label=PREF_LABEL_DISPLAY, + help_str=gettext( + 'Supported placeholders are %DATABASE%, %USERNAME%, and %SERVER%. ' + 'Users can provide any string with or without placeholders of' + ' their choice. The blank title will be revert back to the' + ' default title with placeholders.' + ) + ) diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index f4165c32..01f83b11 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -34,6 +34,7 @@ from pgadmin.utils.constants import UNAUTH_REQ, MIMETYPE_APP_JS, \ SERVER_CONNECTION_CLOSED from sqlalchemy import or_ from pgadmin.utils.preferences import Preferences +from .... import socketio as sio def has_any(data, keys): @@ -1499,6 +1500,13 @@ class ServerNode(PGChildNodeView): # Release Connection manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + # Check if any psql terminal is running for the current disconnecting + # server. If any terminate the psql tool connection. + if 'sid_soid_mapping' in current_app.config and sid in \ + current_app.config['sid_soid_mapping']: + if sid in current_app.config['sid_soid_mapping']: + for i in current_app.config['sid_soid_mapping'][sid]: + sio.emit('disconnect-psql', namespace='/pty', to=i) status = manager.release() diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 01ab89c5..eb20cac5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -122,6 +122,9 @@ define('pgadmin.node.database', [ is_connected: function(node) { return (node && node.connected == true && node.canDisconn == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, is_conn_allow: function(node) { return (node && node.allowConn == true); }, diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 45dea090..3fb1e7d7 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -102,6 +102,12 @@ define('pgadmin.node.server', [ data_disabled: gettext('Database is already disconnected.'), }, },{ + name: 'server_psql', node: 'server', module: this, + applies: ['object', 'context'], callback: 'server_psql_tool', + category: 'psql_tool', priority: 5, label: gettext('PSQL Tool (Beta)'), + enable : 'is_psql_enabled', + }, + { name: 'reload_configuration', node: 'server', module: this, applies: ['tools', 'context'], callback: 'reload_configuration', category: 'reload', priority: 6, label: gettext('Reload Configuration'), @@ -183,6 +189,9 @@ define('pgadmin.node.server', [ is_connected: function(node) { return (node && node.connected == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, enable_reload_config: function(node) { // Must be connected & is Super user if (node && node._type == 'server' && @@ -728,6 +737,14 @@ define('pgadmin.node.server', [ return false; }, + /* Open psql tool for server*/ + server_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + } }, model: pgAdmin.Browser.Node.Model.extend({ defaults: { diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index 3823ef35..e763aa11 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -64,6 +64,14 @@ define([ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', }]); + + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); } } }, @@ -498,6 +506,13 @@ define([ pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); } }, + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, }); return pgBrowser.Collection; diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index 1c5af3f5..23585dbe 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -209,6 +209,14 @@ define('pgadmin.browser.node', [ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', enable: enable, }]); + + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); } // This will add options of scripts eg:'CREATE Script' @@ -902,6 +910,15 @@ define('pgadmin.browser.node', [ pgAdmin.DataGrid.show_query_tool('', i); }, + // Callback to render psql tool. + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, + // Logic to change the server background colour // There is no way of applying CSS to parent element so we have to // do it via JS code only diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js index c9e64132..3068aabe 100644 --- a/web/pgadmin/browser/static/js/panel.js +++ b/web/pgadmin/browser/static/js/panel.js @@ -122,10 +122,30 @@ define( myPanel.on(ev, that.handleVisibility.bind(myPanel, ev)); }); } + + // Listen on detach panel event + myPanel.on(wcDocker.EVENT.DETACHED, function(obj) { + that.setCodeMirrorHeight(obj); + }); }, }); } }, + setCodeMirrorHeight: function() { + // Fix for mac os code-mirror showing black screen. + var txtArea = $('.pg-panel-content .sql_textarea > textarea').first(); + txtArea.css('z-index', -1); + var $tabContent = $('.pg-panel-content > .sql_textarea').first(); + var $sqlPane = $tabContent.find('.CodeMirror > div > textarea'); + for(let i=0; i<$sqlPane.length; i++) {$($sqlPane[i]).css('z-index', -1);} + + $tabContent = $('.pg-panel-content > .sql_textarea').first(); + $sqlPane = $tabContent.find('.pg-panel-content'); + $sqlPane.find('.CodeMirror').css( + 'cssText', + 'height: ' + ($tabContent.height()) + 'px !important;' + ); + }, eventFunc: function(eventName) { var name = $(this).data('pgAdminName'); diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index 09baaf22..90d2d007 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -56,6 +56,15 @@ let _defaultToolBarButtons = [ toggleClass: '', parentClass: 'pg-toolbar-btn btn-primary-icon', enabled: false, + },{ + label: gettext('PSQL Tool'), + ariaLabel: gettext('PSQL Tool'), + btnClass: 'fas fa-terminal', + text: '', + toggled: false, + toggleClass: '', + parentClass: 'pg-toolbar-btn btn-primary-icon pg-toolbar-psql', + enabled: false, }, ]; @@ -105,6 +114,13 @@ export function initializeToolbar(panel, wcDocker) { pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected()); else if ('name' in data && data.name === gettext('Search objects')) pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); + else if ('name' in data && data.name === gettext('PSQL Tool')){ + var input = {}, + t = pgAdmin.Browser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgAdmin.Browser.psql.psql_tool(d, i, true); + } }); } diff --git a/web/pgadmin/browser/static/scss/_browser.scss b/web/pgadmin/browser/static/scss/_browser.scss index 0d157384..ae72f0e6 100644 --- a/web/pgadmin/browser/static/scss/_browser.scss +++ b/web/pgadmin/browser/static/scss/_browser.scss @@ -53,3 +53,9 @@ samp, border-width: 1px; font-size: 1.15em; } + +.pg-toolbar-psql { + padding-top: 0em; + font-size: inherit; + align-items: center; +} diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 8597df48..b0a317a5 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -52,6 +52,10 @@ define('pgadmin.browser.utils', pgAdmin['user_inactivity_timeout'] = {{ current_app.config.get('USER_INACTIVITY_TIMEOUT') }}; pgAdmin['override_user_inactivity_timeout'] = '{{ current_app.config.get('OVERRIDE_USER_INACTIVITY_TIMEOUT') }}' == 'True'; + /* GET PSQL Tool related config */ + pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; + // Define list of nodes on which Query tool option doesn't appears var unsupported_nodes = pgAdmin.unsupported_nodes = [ 'server_group', 'server', 'coll-tablespace', 'tablespace', diff --git a/web/pgadmin/static/bundle/browser.js b/web/pgadmin/static/bundle/browser.js index 14140a2f..0b3ad81b 100644 --- a/web/pgadmin/static/bundle/browser.js +++ b/web/pgadmin/static/bundle/browser.js @@ -11,6 +11,7 @@ define('bundled_browser',[ 'pgadmin.browser', 'sources/browser/index', 'top/tools/erd/static/js/index', + 'top/tools/psql/static/js/index', ], function(pgBrowser) { pgBrowser.init(); }); diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css index c2a776c8..5b4a9f2d 100644 --- a/web/pgadmin/static/css/style.css +++ b/web/pgadmin/static/css/style.css @@ -21,3 +21,5 @@ @import '../vendor/backgrid/backgrid.css'; @import '../vendor/backgrid/backgrid-select-all.css'; + +@import 'node_modules/xterm/css/xterm.css'; diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js index 1348cc45..42efc04d 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js @@ -100,6 +100,10 @@ export function generateTitle(title_placeholder, title_data) { title_placeholder = title_placeholder.replace(new RegExp('%ARGS%'), _.unescape(title_data.args)); title_placeholder = title_placeholder.replace(new RegExp('%SCHEMA%'), _.unescape(title_data.schema)); title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + } else if(title_data.type == 'psql_tool') { + title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + title_placeholder = title_placeholder.replace(new RegExp('%USERNAME%'), _.unescape(title_data.username)); + title_placeholder = title_placeholder.replace(new RegExp('%SERVER%'), _.unescape(title_data.server)); } return _.escape(title_placeholder); diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py new file mode 100644 index 00000000..e479f627 --- /dev/null +++ b/web/pgadmin/tools/psql/__init__.py @@ -0,0 +1,599 @@ +#!/usr/bin/env python3 +import fcntl +import os +import pty +import re +import select +import struct +import termios +import config +import eventlet.green.subprocess as subprocess + +from config import PG_DEFAULT_DRIVER +from flask import Response, url_for, request +from flask import render_template, copy_current_request_context, \ + current_app as app +from flask_babelex import gettext +from flask_security import login_required, current_user +from pgadmin.browser.utils import underscore_unescape +from pgadmin.utils import PgAdminModule +from pgadmin.utils.constants import MIMETYPE_APP_JS +from pgadmin.utils.driver import get_driver +from ... import socketio as sio +from pgadmin.utils import get_complete_file_path + + +session_input = dict() +session_input_cursor = dict() +session_last_cmd = dict() +pdata = dict() +cdata = dict() + + +class PSQLModule(PgAdminModule): + """ + class PSQLModule(PgAdminModule) + A module class for PSQL derived from PgAdminModule. + """ + + LABEL = gettext("PSQL") + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.psql', + 'path': url_for('psql.index') + "psql", + 'when': None + }] + + def get_panels(self): + return [] + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints for PSQL module + """ + return [ + 'psql.panel' + ] + + +blueprint = PSQLModule('psql', __name__, static_url_path='/static') + + [email protected]("/psql.js") +@login_required +def script(): + """render the required javascript""" + return Response( + response=render_template("psql/js/psql.js", _=gettext), + status=200, + mimetype=MIMETYPE_APP_JS + ) + + [email protected]('/panel/<int:trans_id>', + methods=["POST"], + endpoint="panel") +@login_required +def panel(trans_id): + """ + Return panel template for PSQL tools. + :param trans_id: + """ + params = { + 'trans_id': trans_id, + 'title': request.form['title'] + } + if 'sid_soid_mapping' not in app.config: + app.config['sid_soid_mapping'] = dict() + if request.args: + params.update({k: v for k, v in request.args.items()}) + + return render_template('editor_template.html', + sid=params['sid'], + db=params['db'] if params['db'] else 'postgres', + server_type=params['server_type'], + is_enable=config.ENABLE_PSQL, + title=underscore_unescape(params['title']), + theme=params['theme'] + ) + + +def set_term_size(fd, row, col, xpix=0, ypix=0): + """ + Set the terminal size as per UI xterm size. + :param fd: + :param row: + :param col: + :param xpix: + :param ypix: + """ + term_size = struct.pack('HHHH', row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) + + [email protected]('connect', namespace='/pty') +def connect(): + """ + Connect to the server through socket. + :return: + :rtype: + """ + if config.ENABLE_PSQL: + sio.emit('connected', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + if request.sid in session_last_cmd: + session_last_cmd[request.sid]['is_new_connection'] = False + else: + session_last_cmd[request.sid] = {'cmd': '', 'arrow_up': False, + 'invalid_cmd': False, + 'is_new_connection': False} + else: + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + [email protected]('start_process', namespace='/pty') +def start_process(data): + """ + Start the pty terminal and execute psql command and emit results to user. + :param data: + :return: + """ + + @copy_current_request_context + def read_and_forward_pty_output(sid, data): + max_read_bytes = 1024 * 20 + # Create the pty terminal process, parent and fd are file descriptors + # for parent and child. + parent, fd = pty.openpty() + p = None + if parent is not None: + # Child process + p = subprocess.Popen(connection_data, + preexec_fn=os.setsid, + stdin=fd, + stdout=fd, + stderr=fd, + universal_newlines=True + ) + + app.config['sessions'][request.sid] = parent + pdata[request.sid] = p + cdata[request.sid] = fd + else: + app.config['sessions'][request.sid] = parent + cdata[request.sid] = fd + set_term_size(fd, 50, 50) + + while p and p.poll() is None: + if request.sid in app.config['sessions']: + # This code is added to make this unit testable. + if "is_test" not in data: + sio.sleep(0.01) + else: + data['count'] += 1 + if data['count'] == 5: + break + + timeout = 0 + # module provides access to platform-specific I/O + # monitoring functions + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) + + if parent in data_ready: + # Read the output from parent fd (terminal). + output = os.read(parent, max_read_bytes) + emit_output = True + + if sid in session_last_cmd and session_last_cmd[sid][ + 'arrow_up'] and not session_last_cmd[request.sid][ + 'arrow_left_right']: + session_last_cmd[sid]['cmd'] = output.decode() + session_input_cursor[request.sid] = len( + session_last_cmd[sid]['cmd']) + session_last_cmd[sid]['arrow_up'] = True + + if sid in session_last_cmd: + # If command is invalid then emit error to user. + if session_last_cmd[sid]['invalid_cmd']: + emit_output = False + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security\r\n"), + 'error': True + }, + namespace='/pty', room=sid) + # If command is valid then emit output to user. + if emit_output: + sio.emit('pty-output', + {'result': output.decode(), + 'error': False}, + namespace='/pty', room=sid) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + + # Check user is authenticated and PSQL is enabled in config. + if current_user.is_authenticated and config.ENABLE_PSQL: + connection_data = [] + try: + db = '' + if data['db']: + db = data['db'].replace('\\', "\\\\") + + conn, manager = _get_connection(int(data['sid']), data) + psql_utility = manager.utility('sql') + connection_data = get_connection_str(psql_utility, db, + manager) + except Exception as e: + # If any error raised during the start the PSQL emit error to UI. + # request.sid: This sid is socket id. + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + + try: + if int(data['sid']) not in app.config['sid_soid_mapping']: + # request.sid: refer request.sid as socket id. + app.config['sid_soid_mapping'][data['sid']] = list() + app.config['sid_soid_mapping'][data['sid']].append(request.sid) + else: + app.config['sid_soid_mapping'][data['sid']].append(request.sid) + + sio.start_background_task(read_and_forward_pty_output, + request.sid, data) + except Exception as e: + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + else: + # Show error if user is not authenticated. + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def _get_connection(sid, data): + """ + Get the connection object of ERD. + :param sid: + :param did: + :param trans_id: + :return: + """ + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + try: + conn = manager.connection() + # This is added for unit test only, no use in normal execution. + if 'pwd' in data: + kwargs = {'password': data['pwd'], "user": data['user']} + status, msg = conn.connect(**kwargs) + else: + status, msg = conn.connect() + if not status: + app.logger.error(msg) + sio.emit(sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}' + ''.format('Server connection not present.'), + }, namespace='/pty', room=request.sid)) + raise Exception('Server is not connected.') + + return conn, manager + except Exception as e: + app.logger.error(e) + raise + + +def get_connection_str(psql_utility, db, manager): + """ + Get connection string(through connection dsn) + :param psql_utility: PostgreSQL binary path. + :param db: database name to connect specific db. + :return: connection attribute list for PSQL connection. + """ + conn_attr = get_conn_str(manager, db) + conn_attr_list = list() + conn_attr_list.append(psql_utility) + conn_attr_list.append(conn_attr) + return conn_attr_list + + +def get_conn_str(manager, db): + """ + Get connection attributes for psql connection. + :param manager: + :param db: + :return: + """ + pwd = manager.extract_password() + conn_attr =\ + "host={0} port={1} dbname={2} user={3} sslmode={4} " \ + "sslcompression={5} password={6} " \ + "".format( + manager.local_bind_host if manager.use_ssh_tunnel else + manager.host, + manager.local_bind_port if manager.use_ssh_tunnel else + manager.port, + db if db != '' else 'postgres', + manager.user if manager.user else 'postgres', + manager.ssl_mode, + True if manager.sslcompression else False, + pwd + ) + + if manager.hostaddr: + conn_attr = " {0} hostaddr={1}".format(conn_attr, manager.hostaddr) + + if manager.passfile: + conn_attr = " {0} passfile={1}".format(conn_attr, + get_complete_file_path( + manager.passfile)) + + if get_complete_file_path(manager.sslcert): + conn_attr = " {0} sslcert={1}".format( + conn_attr, get_complete_file_path(manager.sslcert)) + + if get_complete_file_path(manager.sslkey): + conn_attr = " {0} sslkey={1}".format( + conn_attr, get_complete_file_path(manager.sslkey)) + + if get_complete_file_path(manager.sslrootcert): + conn_attr = " {0} sslrootcert={1}".format( + conn_attr, get_complete_file_path(manager.sslrootcert)) + + if get_complete_file_path(manager.sslcrl): + conn_attr = " {0} sslcrl={1}".format( + conn_attr, get_complete_file_path(manager.sslcrl)) + + if manager.service: + conn_attr = " {0} service={1}".format( + conn_attr, get_complete_file_path(manager.service)) + + return conn_attr + + [email protected]('socket_input', namespace='/pty') +def socket_input(data): + """ + This get the user input through socket. + :param data: User input from socket. + """ + try: + # request.sid: refer request.sid as socket id. + # Check PSQL enabled setting from config. + enable_psql = True if config.ENABLE_PSQL else False + + if request.sid in app.config['sessions']: + if data['key_name'] == 'Enter' and enable_psql: + # If user get previous executed command from history then set + # current command as previous executed command. + if session_last_cmd[request.sid]['cmd'] \ + and session_last_cmd[request.sid]['arrow_up']: + user_input = str( + session_last_cmd[request.sid]['cmd']).strip() + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + else: + if request.sid not in session_input: + session_input[request.sid] = data['input'] + user_input = str(session_input[request.sid]).strip() + else: + user_input = str(session_input[request.sid]).strip() + session_input_cursor[request.sid] = 0 + + # If ALLOW_PSQL_SHELL_COMMANDS is False then user can't execute + # \! meta command to run shell commands through PSQL terminal. + # Check before executing the user entered command does not + # contains \! in input. + is_new_connection = session_last_cmd[request.sid][ + 'is_new_connection'] + if user_input.startswith('\\!') and \ + re.match("^\\\!$", user_input) and \ + len(user_input) == 2 and \ + not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not is_new_connection: + + session_last_cmd[request.sid]['invalid_cmd'] = True + + for i in range(len(session_input[request.sid])): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + session_input[request.sid] = '' + elif re.search("\\\!", user_input) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + stop_execution = True + # Check \! is passed as string or not. + double_quote_strs = re.findall('"([^"]*)"', user_input) + + if double_quote_strs: + for sub_str in double_quote_strs: + if re.search("\\\!", sub_str): + stop_execution = False + # break + + if stop_execution: + session_last_cmd[request.sid]['invalid_cmd'] = True + # Remove already added command from terminal. + for i in range(len(user_input)): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + # Add Enter event to execute the command. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + elif user_input == '\q': + # If user enter \q to terminate the PSQL, emit the msg to + # notify user connection is terminated. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + sio.emit('pty-output', + { + 'result': gettext( + 'Connection terminated, TO create new ' + 'connection please open another psql' + ' tool.'), + 'error': True}, + namespace='/pty', room=request.sid) + else: + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + session_input[request.sid] = '' + session_last_cmd[request.sid]['is_new_connection'] = False + else: + if data['key_name'] == 'ArrowLeft': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] > 0: + session_input_cursor[request.sid] -= 1 + + elif data['key_name'] == 'ArrowRight': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] < len( + session_input[request.sid]): + session_input_cursor[request.sid] += 1 + + elif data['key_name'] == 'ArrowUp': + session_last_cmd[request.sid]['arrow_up'] = True + session_last_cmd[request.sid]['arrow_left_right'] = False + session_input[request.sid] = session_last_cmd[request.sid][ + 'cmd'] + session_input_cursor[request.sid] = len( + session_last_cmd[request.sid]['cmd']) + + elif request.sid in session_input and data[ + 'key_name'] == 'Backspace' and ( + len(session_input[request.sid]) or len( + session_last_cmd[request.sid])): + + session_last_cmd[request.sid]['arrow_left_right'] = True + + if session_last_cmd[request.sid]['cmd']: + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + + user_input = list(session_input[request.sid]) + + if session_input_cursor[request.sid] == 1: + index = 0 + session_input_cursor[request.sid] -= 1 + else: + if session_input_cursor[request.sid] > 0: + index = (session_input_cursor[request.sid]) - 1 + session_input_cursor[request.sid] -= 1 + else: + index = session_input_cursor[request.sid] + session_input_cursor[request.sid] = 0 + + if len(user_input): + del user_input[index] + session_input[request.sid] = "".join(user_input) + + if len(session_input[request.sid]) == 0: + session_input_cursor[request.sid] = 0 + session_last_cmd[request.sid]['cmd'] = '' + elif request.sid in session_input: + if session_last_cmd[request.sid]['cmd'] and session_input[ + request.sid] == '': + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + session_input_cursor[request.sid] = len( + session_input[request.sid]) + else: + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + user_input = list(session_input[request.sid]) + user_input.insert(session_input_cursor[request.sid], + data['input']) + session_input[request.sid] = ''.join(user_input) + session_input_cursor[request.sid] += 1 + session_last_cmd[request.sid]['arrow_left_right'] = False + else: + session_input_cursor[request.sid] = 0 + session_input[request.sid] = data['input'] + session_input_cursor[request.sid] += 1 + + # Write user input to terminal parent fd. + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + except Exception as e: + # Delete socket id from sessions. + # request.sid: refer request.sid as socket id. + sio.emit('pty-output', + { + 'result': gettext('Invalid session.\r\n'), + 'error': True + }, + namespace='/pty', room=request.sid) + del app.config['sessions'][request.sid] + + [email protected]('resize', namespace='/pty') +def resize(data): + """ + Resize the pty terminal as per the UI terminal. + :param data: UI terminal rows and cols data + """ + # request.sid: refer request.sid as socket id. + if request.sid in app.config['sessions']: + set_term_size(app.config['sessions'][request.sid], data['rows'], + data['cols']) + + [email protected]('disconnect', namespace='/pty') +def disconnect(): + """ + Disconnect the socket and terminate the process + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + disconnect_socket() + + [email protected]('server-disconnect', namespace='/pty') +def server_disconnect(data): + """ + Disconnect the socket and terminate the process after user disconnect + the server. we can't use disconnect event name as it is reserved for socket + internal use. + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata and request.sid in app.config['sid_soid_mapping'][ + data['sid']]: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + app.config['sid_soid_mapping'][data['sid']] = [soid for soid in + app.config[ + 'sid_soid_mapping'][ + data['sid']] if + soid != request.sid] + disconnect_socket() + + +def disconnect_socket(): + os.write(app.config['sessions'][request.sid], '\q\n'.encode()) + sio.sleep(1) + os.close(app.config['sessions'][request.sid]) + os.close(cdata[request.sid]) + del app.config['sessions'][request.sid] diff --git a/web/pgadmin/tools/psql/static/js/index.js b/web/pgadmin/tools/psql/static/js/index.js new file mode 100644 index 00000000..4d88ba04 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/index.js @@ -0,0 +1,23 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import $ from 'jquery'; +import _ from 'underscore'; +import pgAdmin from 'sources/pgadmin'; +import pgBrowser from 'top/browser/static/js/browser'; +import * as csrfToken from 'sources/csrf'; +import {initialize} from './psql_module'; + +let pgBrowserOut = initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser); + +module.exports = { + pgBrowser: pgBrowserOut, +}; diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js new file mode 100644 index 00000000..6223c697 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -0,0 +1,331 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import { Terminal } from 'xterm'; +import { FitAddon } from 'xterm-addon-fit'; +import { WebLinksAddon } from 'xterm-addon-web-links'; +import { SearchAddon } from 'xterm-addon-search'; +import { io } from 'socketio'; +import Alertify from 'pgadmin.alertifyjs'; +import {enable} from 'pgadmin.browser.toolbar'; +import clipboard from 'sources/selection/clipboard'; +import 'wcdocker'; +import {getRandomInt} from 'sources/utils'; + +import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; +import {generateTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; + + +export function setPanelTitle(psqlToolPanel, panelTitle) { + psqlToolPanel.title('<span title="'+panelTitle+'">'+panelTitle+'</span>'); +} + +var wcDocker = window.wcDocker; + +export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) { + var pgBrowser = Browser; + var terminal = Terminal; + var parentData = null; + /* Return back, this has been called more than once */ + if (pgBrowser.psql) + return pgBrowser.psql; + + + // Create an Object Restore of pgBrowser class + pgBrowser.psql = { + init: function() { + this.initialized = true; + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'psql', + module: this, + applies: ['tools'], + callback: 'psql_tool', + priority: 1, + label: gettext('PSQL Tool (Beta)'), + enable: this.psqlToolEnabled, + }]; + + this.enable_psql_tool = pgAdmin['enable_psql']; + if(pgAdmin['enable_psql']) { + pgBrowser.add_menus(menus); + } + + // Creating a new pgBrowser frame to show the data. + var psqlFrameType = new pgBrowser.Frame({ + name: 'frm_psqltool', + showTitle: true, + isCloseable: true, + isPrivate: true, + url: 'about:blank', + }); + + var self = this; + /* Cache may take time to load for the first time + * Keep trying till available + */ + let cacheIntervalId = setInterval(function() { + if(pgBrowser.preference_version() > 0) { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + clearInterval(cacheIntervalId); + } + },0); + + pgBrowser.onPreferencesChange('psql', function() { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + }); + + // Load the newly created frame + psqlFrameType.load(pgBrowser.docker); + return this; + }, + /* Enable/disable PSQL tool menu in tools based + * on node selected. if selected node is present + * in unsupported_nodes, menu will be disabled + * otherwise enabled. + */ + psqlToolEnabled: function(obj) { + + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj)) { + if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1 || (obj._type == 'server' && obj.connected)) { + if (obj._type == 'database' && obj.allowConn) { + return true; + } else if (obj._type != 'database') { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + })(); + + enable(gettext('PSQL Tool'), isEnabled); + return isEnabled; + }, + retrieveAncestorOfTypeServer: function(item) { + let serverInformation = null; + // let aciTreeItem = item || pgBrowser.treeMenu.selected(); + let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); + + if (treeNode) { + let nodeData; + let databaseNode = treeNode.ancestorNode( + (node) => { + nodeData = node.getData(); + return (nodeData._type === 'database'); + } + ); + let isServerNode = (node) => { + nodeData = node.getData(); + return nodeData._type === 'server'; + }; + + if (databaseNode !== null) { + if (nodeData._label.indexOf('=') >= 0) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext( + 'Databases with = symbols in the name cannot be backed up or restored using this utility.' + ) + ); + } else { + if (databaseNode.anyParent(isServerNode)) + serverInformation = nodeData; + } + } else { + if (treeNode.anyFamilyMember(isServerNode)) + serverInformation = nodeData; + } + } + + if (serverInformation === null) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext('Please select server or child node from the browser tree.') + ); + } + return serverInformation; + }, + psql_tool: function(data, aciTreeIdentifier, gen=false) { + const module = 'paths'; + let preference_name = 'pg_bin_dir'; + let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.'); + const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeIdentifier); + + if ((serverInformation.type && serverInformation.type === 'ppas') || + serverInformation.server_type === 'ppas') { + preference_name = 'ppas_bin_dir'; + msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'); + } + const preference = pgBrowser.get_preference(module, preference_name); + if (preference) { + if (!preference.value) { + Alertify.alert(gettext('Configuration required'), msg); + return false; + } + } else { + Alertify.alert( + gettext(this.errorAlertTitle), + gettext('Failed to load preference %s of module %s', preference_name, module) + ); + return false; + } + const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if (node === undefined || !node.getData()) { + Alertify.alert( + gettext('PSQL Error'), + gettext('No object selected.') + ); + return; + } + + parentData = getTreeNodeHierarchyFromIdentifier.call( + pgBrowser, + aciTreeIdentifier + ); + + if(_.isUndefined(parentData.server)) { + Alertify.alert( + gettext('PSQL Error'), + gettext('Please select a server/database object.') + ); + return; + } + + const transId = getRandomInt(1, 9999999); + + var panelTitle = ''; + // Set psql tab title as per prefrences setting. + var title_data = { + 'database': parentData.database ? parentData.database.label : 'postgres' , + 'username': parentData.server.user_name, + 'server': parentData.server.label, + 'type': 'psql_tool', + }; + var tab_title_placeholder = pgBrowser.get_preferences_for_module('browser').psql_tab_title_placeholder; + panelTitle = generateTitle(tab_title_placeholder, title_data); + + const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + + let psqlToolForm = ` + <form id="psqlToolForm" action="${panelUrl}" method="post"> + <input id="title" name="title" hidden /> + <input name="close_url" value="${panelCloseUrl}" hidden /> + </form> + <script> + document.getElementById("title").value = "${_.escape(panelTitle)}"; + document.getElementById("psqlToolForm").submit(); + </script> + `; + var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; + if (open_new_tab && open_new_tab.includes('psql_tool')) { + var newWin = window.open('', '_blank'); + newWin.document.write(psqlToolForm); + newWin.document.title = panelTitle; + } else { + /* On successfully initialization find the properties panel, + * create new panel and add it to the dashboard panel. + */ + var propertiesPanel = pgBrowser.docker.findPanels('properties'); + var psqlToolPanel = pgBrowser.docker.addPanel('frm_psqltool', wcDocker.DOCK.STACKED, propertiesPanel[0]); + + // Set panel title and icon + setPanelTitle(psqlToolPanel, panelTitle); + psqlToolPanel.icon('fas fa-terminal psql-tab-style'); + psqlToolPanel.focus(); + + var openPSQLToolURL = function(j) { + // add spinner element + let $spinner_el = + $(`<div class="pg-sp-container"> + <div class="pg-sp-content"> + <div class="row"> + <div class="col-12 pg-sp-icon"></div> + </div> + </div> + </div>`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { + var frameInitialized = $(j).data('frameInitialized'); + if (frameInitialized) { + clearInterval(init_poller_id); + var frame = $(j).data('embeddedFrame'); + if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); + frame.openHTML(psqlToolForm); + } + } + }, 100); + }; + + openPSQLToolURL(psqlToolPanel); + + } + + }, + getPanelUrls: function(transId, panelTitle, parentData) { + let openUrl = url_for('psql.panel', { + trans_id: transId, + }); + const misc_preferences = pgBrowser.get_preferences_for_module('misc'); + var theme = misc_preferences.theme; + + openUrl += `?sgid=${parentData.server_group._id}` + +`&sid=${parentData.server._id}` + +`&server_type=${parentData.server.server_type}` + + `&theme=${theme}`; + + if(parentData.database && parentData.database._id) { + let db_label = parentData.database._label.replace('\\', '\\\\'); + openUrl += `&db=${_.escape(db_label)}`; + } else { + openUrl += `&db=${''}`; + } + + let closeUrl = url_for('psql.close', { + trans_id: transId, + }); + return [openUrl, closeUrl]; + }, + psql_terminal: function() { + // theme colors + var term = new terminal({ + cursorBlink: true, + macOptionIsMeta: true, + scrollback: 10000, + }); + return term; + }, + psql_fit_screen: function() { + return new FitAddon(); + }, + psql_web_link: function() { + return new WebLinksAddon(); + }, + psql_search: function() { + return new SearchAddon(); + }, + psql_socket: function() { + return io('/pty', {pingTimeout: 120000, pingInterval: 25000}); + }, + _clipboard: function() { + return clipboard; + } + }; + + return pgBrowser.psql; +} + diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html new file mode 100644 index 00000000..3c550c97 --- /dev/null +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -0,0 +1,161 @@ +{% extends "base.html" %} +{% block title %}{{title}}{% endblock %} + +{% block css_link %} +<link type="text/css" rel="stylesheet" href="{{ url_for('browser.browser_css')}}"/> +{% endblock %} +{% block body %} +<style> + body {padding: 0px;} + {% if is_desktop_mode and is_linux %} + .alertify .ajs-dimmer,.alertify .ajs-modal{-webkit-transform: none;} + .alertify-notifier{-webkit-transform: none;} + .alertify-notifier .ajs-message{-webkit-transform: none;} + .alertify .ajs-dialog.ajs-shake{-webkit-animation-name: none;} + .sql-editor-busy-icon.fa-pulse{-webkit-animation: none;} + {% endif %} +</style> +<div style="width: 100%; height: 100%;" id="psql-terminal" class="psql_terminal"></div> +{% endblock %} + + +{% block init_script %} +require( + ['sources/generated/psql_tool'], + function(pgBrowser) { + var theme_colors = { + 'standard': { + background: '#FFF', + foreground: '#000', + cursor: '#000', + cursorAccent: '#000', + selection: '#DDD', + }, + 'dark': { + background: '#212121', + foreground: '#d4d4d4', + cursor: '#d4d4d4', + cursorAccent: '#d4d4d4', + selection: '#323e43', + }, + 'high_contrast': { + background: '#010b15', + foreground: '#fff', + cursor: '#fff', + cursorAccent: '#fff', + selection: '#84d6ff', + } + } + const term = self.pgAdmin.Browser.psql.psql_terminal(); + term.setOption('theme', theme_colors['{{theme}}']); + const fitAddon = self.pgAdmin.Browser.psql.psql_fit_screen(); + term.loadAddon(fitAddon); + let clipboard = self.pgAdmin.Browser.psql._clipboard(); + + const webLinksAddon = self.pgAdmin.Browser.psql.psql_web_link(); + term.loadAddon(webLinksAddon); + + const searchAddon = self.pgAdmin.Browser.psql.psql_search(); + term.loadAddon(searchAddon); + + term.open(document.getElementById('psql-terminal')); + fitAddon.fit() + term.resize(15, 50) + fitAddon.fit() + let selected_text = ''; + let user_input = ''; + let is_pwd = true; + let cursor_position = 0; + + term.attachCustomKeyEventHandler(e => { + e.stopPropagation(); + if(e.type=='keydown' && e.metaKey &&(e.key == 'v' || e.key == 'V')) { + if(selected_text != '') { + if (selected_text.length > 0) { + socket.emit("socket_input", {"input": selected_text, 'key_name': e.code}); + selected_text = ''; + } + } else { + navigator.clipboard.readText().then( clipText => { + selected_text = clipText; + if (selected_text.length > 0) { + socket.emit("socket_input", {"input": selected_text, 'key_name': e.code}); + selected_text = ''; + } + }); + } + + }else if(e.type=='keydown' && e.metaKey && (e.key == 'c' || e.key == 'C')) { + if (term.hasSelection()) { + selected_text = term.getSelection(); + } else { + selected_text = clipboard.readText(); + } + } + + return true; + }); + + term.onKey(function (ev) { + if (pgAdmin['allow_psql_shell_commands']) { + socket.emit("socket_input", {"input": ev.key, 'key_name': ev.domEvent.code}); + } else { + socket.emit("socket_input", {"input": ev.key, 'key_name': ev.domEvent.code}); + } + }); + + const socket = self.pgAdmin.Browser.psql.psql_socket(); + + socket.on("pty-output", function(data){ + if(data.error) { + term.write('\r\n'); + } + term.write(data.result); + if(data.error) { + term.write('\r\n'); + } + }) + + socket.on("connect", () => { + if('{{is_enable}}' == 'True'){ + socket.emit('start_process', {"sid": {{sid}}, "db": '{{db}}', 'stype': '{{server_type}}' }); + } + fitToscreen(); + }); + + socket.on("conn_error", (response) => { + term.write(response.error); + fitToscreen(); + }); + + socket.on("conn_not_allow", () => { + term.write('PSQL connection not allowed'); + fitToscreen(); + }); + + socket.on("disconnect-psql", () => { + socket.emit("server-disconnect", {'sid': {{sid}}}); + term.write('\r\nServer disconnected, Connection terminated, + TO create new connection please open another psql tool.'); + }); + + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } + + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) + } + } + + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) + }); +{% endblock %} + + diff --git a/web/pgadmin/tools/psql/tests/__init__.py b/web/pgadmin/tools/psql/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web/pgadmin/tools/psql/tests/psql_test_data.json b/web/pgadmin/tools/psql/tests/psql_test_data.json new file mode 100644 index 00000000..4148c75b --- /dev/null +++ b/web/pgadmin/tools/psql/tests/psql_test_data.json @@ -0,0 +1,184 @@ +{ + "psql_user_input": [ + { + "name": "Enter Select 1;", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "move_cursor_up": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "is_history": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowLeft", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowLeft": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowRight", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Read previous executed command", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "move_cursor_right": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\!", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! with other cmd not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\! ls", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Valid commands", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select \"\\!\"", + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "First command as enter", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Exist psql terminal by using \\q", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\q", + "mock_data": { + + }, + "expected_data": { + } + } + ], + "resize_terminal": [ + { + "name": "Resize psql terminal as per UI.", + "is_positive_test": true, + "mocking_required": false, + "input_data": { + "cols": 141, + "rows": 39 + }, + "mock_data": { + + }, + "expected_data": { + } + } + ], + "backend_task": [ + { + "name": "Backend Task", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "Select 1;", + "is_backend_task": true, + "mock_data": { + "is_test": true + }, + "expected_data": { + } + } + ] +} diff --git a/web/pgadmin/tools/psql/tests/test_backend_task.py b/web/pgadmin/tools/psql/tests/test_backend_task.py new file mode 100644 index 00000000..a4f14ee4 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_backend_task.py @@ -0,0 +1,87 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLBackend(BaseTestGenerator): + scenarios = utils.generate_scenarios('backend_task', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'], + 'is_test': True, + 'count': 0 + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_panel.py b/web/pgadmin/tools/psql/tests/test_panel.py new file mode 100644 index 00000000..6f93c8c2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_panel.py @@ -0,0 +1,36 @@ +import uuid +import random +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data + + +class PSQLPanel(BaseTestGenerator): + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + self.theme = 'standard' + + def runTest(self): + trans_id = random.randint(1, 9999999) + url = '/psql/panel/{trans_id}?sgid={sgid}&sid={sid}&server_type=pg' \ + '&db={db_name}&theme={theme}'.\ + format(trans_id=trans_id, sgid=self.sgid, sid=self.sid, + db_name=self.db_name, theme=self.theme) + + response = self.tester.post( + url, data={"title": "panel_title"}, + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_disabled.py b/web/pgadmin/tools/psql/tests/test_psql_disabled.py new file mode 100644 index 00000000..7dc52498 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_disabled.py @@ -0,0 +1,34 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisabled(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = False + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_input.py b/web/pgadmin/tools/psql/tests/test_psql_input.py new file mode 100644 index 00000000..6f6eabe7 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_input.py @@ -0,0 +1,148 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLInput(BaseTestGenerator): + scenarios = utils.generate_scenarios('psql_user_input', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_backspace') and self.is_backspace: + if hasattr(self, 'move_cursor_up') and self.move_cursor_up: + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Backspace' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowUp') and self.is_arrowUp: + if hasattr(self, 'is_history') and self.is_history: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowLeft') and self.is_arrowLeft: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowRight') and self.is_arrowRight: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'move_cursor_right') and self.is_arrowRight: + for i in range(2): + input_data = { + 'input': '', + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + input_data = { + 'input': '', + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_resize_terminal.py b/web/pgadmin/tools/psql/tests/test_resize_terminal.py new file mode 100644 index 00000000..d305c2d0 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_resize_terminal.py @@ -0,0 +1,58 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLResizeTerminal(BaseTestGenerator): + scenarios = utils.generate_scenarios('resize_terminal', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.emit('resize', self.input_data, namespace='/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_connect.py b/web/pgadmin/tools/psql/tests/test_socket_connect.py new file mode 100644 index 00000000..3791525a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_connect.py @@ -0,0 +1,35 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketConnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py new file mode 100644 index 00000000..0619eb30 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py @@ -0,0 +1,52 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisconnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_test_client = app.test_client() + flask_test_client.get('/') + + self.test_client = socketio.test_client( + app, + flask_test_client=flask_test_client, + namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process.py b/web/pgadmin/tools/psql/tests/test_start_process.py new file mode 100644 index 00000000..1245de3f --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process.py @@ -0,0 +1,57 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcess(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + import random + trans_id = random.randint(1, 9999999) + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process_fail.py b/web/pgadmin/tools/psql/tests/test_start_process_fail.py new file mode 100644 index 00000000..0acc7be2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process_fail.py @@ -0,0 +1,48 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcessFail(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + config.ENABLE_PSQL = False + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/utils.py b/web/pgadmin/tools/psql/tests/utils.py new file mode 100644 index 00000000..85bd5373 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/utils.py @@ -0,0 +1,6 @@ +import os +import json + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/psql_test_data.json") as data_file: + test_cases = json.load(data_file) diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss index 0bb40802..a58eb7e9 100644 --- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss +++ b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss @@ -374,3 +374,20 @@ div.strikeout:after { /* Setting it to hardcoded white as the SVG generated is having white bg * Need to check what can be done. */ + +/* Css for psql */ +.psql_terminal .terminal { + padding-top: 1%; + padding-left: 0.5%; + height: 100%; +} + +.psql-icon-style { + font-size: inherit; + padding-left: 0em; +} + +.psql-tab-style { + font-size: small; + padding-left: 0em; +} diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py index 23abfffa..71ae82ea 100644 --- a/web/pgadmin/utils/csrf.py +++ b/web/pgadmin/utils/csrf.py @@ -38,6 +38,7 @@ class _PGCSRFProtect(CSRFProtect): 'pgadmin.tools.schema_diff.ddl_compare', 'pgadmin.authenticate.login', 'pgadmin.tools.erd.panel', + 'pgadmin.tools.psql.panel', ] for exempt in exempt_views: diff --git a/web/pgadmin/utils/driver/psycopg2/server_manager.py b/web/pgadmin/utils/driver/psycopg2/server_manager.py index 2a951b6e..3be5d833 100644 --- a/web/pgadmin/utils/driver/psycopg2/server_manager.py +++ b/web/pgadmin/utils/driver/psycopg2/server_manager.py @@ -527,6 +527,15 @@ WHERE db.oid = {0}""".format(did)) return None + def extract_password(self): + if self.password: + crypt_key_present, crypt_key = get_crypt_key() + if not crypt_key_present: + return False, crypt_key + + password = decrypt(self.password, crypt_key).decode() + return password + def export_password_env(self, env): if self.password: crypt_key_present, crypt_key = get_crypt_key() diff --git a/web/pgadmin/utils/preferences.py b/web/pgadmin/utils/preferences.py index 15ceeb1a..e9efe479 100644 --- a/web/pgadmin/utils/preferences.py +++ b/web/pgadmin/utils/preferences.py @@ -72,6 +72,7 @@ class _Preference(object): self.select2 = kwargs.get('select2', None) self.fields = kwargs.get('fields', None) self.allow_blanks = kwargs.get('allow_blanks', None) + self.disabled = kwargs.get('disabled', False) # Look into the configuration table to find out the id of the specific # preference. @@ -252,6 +253,7 @@ class _Preference(object): 'select2': self.select2, 'value': self.get(), 'fields': self.fields, + 'disabled': self.disabled, } return res @@ -414,6 +416,7 @@ class Preferences(object): :param fields: field schema (if preference has more than one field to take input from user e.g. keyboardshortcut preference) :param allow_blanks: Flag specify whether to allow blank value. + :param disabled: Flag specify whether to disable the setting or not. """ min_val = kwargs.get('min_val', None) max_val = kwargs.get('max_val', None) @@ -423,6 +426,7 @@ class Preferences(object): select2 = kwargs.get('select2', None) fields = kwargs.get('fields', None) allow_blanks = kwargs.get('allow_blanks', None) + disabled = kwargs.get('disabled', False) cat = self.__category(category, category_label) if name in cat['preferences']: @@ -439,7 +443,8 @@ class Preferences(object): (cat['preferences'])[name] = res = _Preference( cat['id'], name, label, _type, default, help_str=help_str, min_val=min_val, max_val=max_val, options=options, - select2=select2, fields=fields, allow_blanks=allow_blanks + select2=select2, fields=fields, allow_blanks=allow_blanks, + disabled=disabled ) return res diff --git a/web/webpack.config.js b/web/webpack.config.js index 779f2faa..f631178b 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -355,6 +355,7 @@ module.exports = [{ debugger_direct: './pgadmin/tools/debugger/static/js/direct.js', schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js', erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js', + psql_tool: './pgadmin/tools/psql/static/js/index.js', file_utils: './pgadmin/misc/file_manager/static/js/utility.js', 'pgadmin.style': pgadminCssStyles, pgadmin: pgadminScssStyles, @@ -493,7 +494,7 @@ module.exports = [{ ], }, }, - }, { + },{ test: require.resolve('./node_modules/acitree/js/jquery.aciTree.min'), use: { loader: 'imports-loader', @@ -532,6 +533,7 @@ module.exports = [{ 'pure|pgadmin.tools.storage_manager', 'pure|pgadmin.tools.search_objects', 'pure|pgadmin.tools.erd_module', + 'pure|pgadmin.tools.psql_module', ], }, }, diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 074b2580..e0b28091 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -159,6 +159,15 @@ var webpackShimConfig = { 'jquery.acisortable': path.join(__dirname, './node_modules/acitree/js/jquery.aciSortable.min'), 'jquery.acifragment': path.join(__dirname, './node_modules/acitree/js/jquery.aciFragment.min'), + //xterm + 'xterm': path.join(__dirname, './node_modules/xterm/lib/xterm.js'), + 'xterm-addon-fit': path.join(__dirname, './node_modules/xterm-addon-fit/lib/xterm-addon-fit.js'), + 'xterm-addon-web-links': path.join(__dirname, './node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js'), + 'xterm-addon-search': path.join(__dirname, './node_modules/xterm-addon-search/lib/xterm-addon-search.js'), + + //socket + 'socketio': path.join(__dirname, './node_modules/socket.io-client/dist/socket.io.js'), + // Backbone and Backgrid 'backbone': path.join(__dirname, './node_modules/backbone/backbone'), 'backbone.undo': path.join(__dirname, './node_modules/backbone-undo/Backbone.Undo'), @@ -288,6 +297,8 @@ var webpackShimConfig = { 'pgadmin.tools.storage_manager': path.join(__dirname, './pgadmin/tools/storage_manager/static/js/storage_manager'), 'pgadmin.tools.erd_module': path.join(__dirname, './pgadmin/tools/erd/static/js/erd_module'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index e0b6fd69..3cc079f9 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -177,6 +177,7 @@ module.exports = { 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), 'tools': path.join(__dirname, './pgadmin/tools/'), 'pgadmin.user_management.current_user': regressionDir + '/javascript/fake_current_user', ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-17 13:17 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-05-17 13:17 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers Hi On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < [email protected]> wrote: > Hi Akshay/ Team, > > Please find the attached updated patch for the psql tool. > Hmm, this version is also broken. There's a typo in editor_template.html on line 138 - it splits a string across two lines which throws an error. Having fixed that... I also note there's a lot of Javascript in that HTML file. That should be pushed into the webpacked bundle I think, and not included inline in HTML. A couple of other things I noticed: - The button is enabled if the treeview has a Server selected. It could be argued that the query tool should do the same (defaulting to the maintenance database), however, that would be a separate change, and psql should be consistent with the query tool. - If I do a "select * from pg_class;" I still get: postgres=# select * from pg_class; WARNING: terminal is not fully functional - I'm sure using \q in the previous version displayed a message saying the session exited (the one on line 138 of editor_template.html). It no longer seems to do so. > > > On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >> [email protected]> wrote: >> >>> Hi Nikhil >>> >>> Following are the review comments: >>> >>> *GUI specific*: >>> >>> - We need a panel icon for PSQL like query tool, we can also add >>> that on the browser tree toolbar. >>> - PSQL Tool menu should be visible for all the child nodes of the >>> database node. Follow the same as Query Tool. >>> - PSQL tab title should be only database server name as the user can >>> change the database/user from PSQL command, so it's been difficult to >>> update the tab title. >>> - PSQL connection is still open even if we disconnect the database >>> server from the browser tree. >>> >>> *Code specific:* >>> >>> - Remove an extra space from requirements.txt and package.json >>> - Documentation needs to be updated to let the user know from where >>> the PSQL tool will open and on which node it is applicable. >>> - psql/__init__.py check there are so many unused imports please >>> remove them. >>> - We are not using cheroot so it should be removed from >>> requirements.txt and also remove the import statement from pgAdmin4.py >>> - Test cases are showing successful but actually, there are some >>> routing errors please check. >>> >>> A few other things I noticed: >> >> - I was prompted to enter a password. This should be passed in the >> environment to psql as it is for pg_dump etc. >> - There seems to be an issue with terminal compatibility (which I didn't >> have on my prototype): >> >> ml=# select * from pg_class; >> WARNING: terminal is not fully functional >> -[ RECORD 1 ]-------+---------------------------------------------- >> oid | 79354 >> relname | housing >> ... >> >> - The panel should honour the styleguide. I'm running in dark mode, and >> see a jet black background. I would expect to see the same >> background/foreground colours as the treeview. >> - I spotted at least one print() statement that shouldn't be there (debug >> output should go through the logger) - psql/__init__.py:235 >> - This seems suspect - why would there be a password in a connection >> string we've built? And why would it be xxx? >> >> if 'password=xxx' in conn_attr: >> conn_attr = conn_attr.replace('password=xxx', '') >> >> - There's a thick white line at the bottom of the panel, where a >> horizontal scrollbar might be if there was one. >> - The trailing semi-colon should be removed from: "ERROR: Shell commands >> are disabled in psql for security;" >> >> Once we're happy with the patch in general, I'll do a string review >> before committing. In particular, I want to be sure the text in config.py >> is appropriately worded. >> >> This is shaping up nicely! Good work. >> >> >>> >>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Dave/ Team, >>>> >>>> PFA updated patch, sorry for the inconvenience, while cleanup I removed >>>> the unwanted libraries but forgot to remove the code related to them. >>>> >>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Hackers, >>>>>> >>>>>> Please find the attached patch for RM-2341 >>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option for >>>>>> starting PSQL. >>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>> 2. Added the same option for Server and Database nodes from the tree >>>>>> view. >>>>>> >>>>> >>>>> Unfortunately there's a trailing comma in package.json that makes it >>>>> invalid. If I fix that, then I get the error below, so I'm guessing the >>>>> intention was to actually include another package there? >>>>> >>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>> Module not found: Error: Can't resolve 'local-echo-controller' in >>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>> resolve 'local-echo-controller' in >>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>> Parsed request is a module >>>>> using description file: /Users/dpage/git/pgadmin4/web/package.json >>>>> (relative path: ./pgadmin/tools/psql/static/js) >>>>> aliased with mapping 'local-echo-controller': >>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>> using description file: >>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>> ./pgadmin/tools/psql/static/js) >>>>> Field 'browser' doesn't contain a valid alias configuration >>>>> root path /Users/dpage/git/pgadmin4/web >>>>> using description file: >>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>> no extension >>>>> Field 'browser' doesn't contain a valid alias >>>>> configuration >>>>> >>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>> doesn't exist >>>>> .js >>>>> Field 'browser' doesn't contain a valid alias >>>>> configuration >>>>> >>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>> doesn't exist >>>>> .jsx >>>>> Field 'browser' doesn't contain a valid alias >>>>> configuration >>>>> >>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>> doesn't exist >>>>> as directory >>>>> >>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>> doesn't exist >>>>> using description file: >>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>> ./node_modules/local-echo) >>>>> no extension >>>>> Field 'browser' doesn't contain a valid alias configuration >>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>> doesn't exist >>>>> .js >>>>> Field 'browser' doesn't contain a valid alias configuration >>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>> doesn't exist >>>>> .jsx >>>>> Field 'browser' doesn't contain a valid alias configuration >>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>> doesn't exist >>>>> as directory >>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>> doesn't exist >>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>> >>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 ms >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>> >>>> Regards, >>>> Nikhil Mohite >>>> >>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> *pgAdmin Hacker | Principal Software Architect* >>> *EDB Postgres <http://edbpostgres.com>* >>> >>> *Mobile: +91 976-788-8246* >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> Regards, > Nikhil Mohite > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-18 11:12 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-05-18 11:12 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers Hi Dave/Team, On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: > Hi > > On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < > [email protected]> wrote: > >> Hi Akshay/ Team, >> >> Please find the attached updated patch for the psql tool. >> > > Hmm, this version is also broken. There's a typo in editor_template.html > on line 138 - it splits a string across two lines which throws an error. > Having fixed that... > > I also note there's a lot of Javascript in that HTML file. That should be > pushed into the webpacked bundle I think, and not included inline in HTML. > I have moved most of the code in the js file, few things are still in HTML. > > A couple of other things I noticed: > > - The button is enabled if the treeview has a Server selected. It could be > argued that the query tool should do the same (defaulting to the > maintenance database), however, that would be a separate change, and psql > should be consistent with the query tool. > It is now consistent with the query tool. > > - If I do a "select * from pg_class;" I still get: > > postgres=# select * from pg_class; > WARNING: terminal is not fully functional > I am not able to reproduce the warning for the terminal (I am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, Safari) and also checked on local nwjs runtime but still not able to reproduce the warning. but found one limitation: if we try to load data from the table containing millions of records, UI gets very slow. > > - I'm sure using \q in the previous version displayed a message saying the > session exited (the one on line 138 of editor_template.html). It no longer > seems to do so. > > >> >> >> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> Hi Nikhil >>>> >>>> Following are the review comments: >>>> >>>> *GUI specific*: >>>> >>>> - We need a panel icon for PSQL like query tool, we can also add >>>> that on the browser tree toolbar. >>>> - PSQL Tool menu should be visible for all the child nodes of the >>>> database node. Follow the same as Query Tool. >>>> - PSQL tab title should be only database server name as the user >>>> can change the database/user from PSQL command, so it's been difficult to >>>> update the tab title. >>>> - PSQL connection is still open even if we disconnect the database >>>> server from the browser tree. >>>> >>>> *Code specific:* >>>> >>>> - Remove an extra space from requirements.txt and package.json >>>> - Documentation needs to be updated to let the user know from where >>>> the PSQL tool will open and on which node it is applicable. >>>> - psql/__init__.py check there are so many unused imports please >>>> remove them. >>>> - We are not using cheroot so it should be removed from >>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>> - Test cases are showing successful but actually, there are some >>>> routing errors please check. >>>> >>>> A few other things I noticed: >>> >>> - I was prompted to enter a password. This should be passed in the >>> environment to psql as it is for pg_dump etc. >>> - There seems to be an issue with terminal compatibility (which I didn't >>> have on my prototype): >>> >>> ml=# select * from pg_class; >>> WARNING: terminal is not fully functional >>> -[ RECORD 1 ]-------+---------------------------------------------- >>> oid | 79354 >>> relname | housing >>> ... >>> >>> - The panel should honour the styleguide. I'm running in dark mode, and >>> see a jet black background. I would expect to see the same >>> background/foreground colours as the treeview. >>> - I spotted at least one print() statement that shouldn't be there >>> (debug output should go through the logger) - psql/__init__.py:235 >>> - This seems suspect - why would there be a password in a connection >>> string we've built? And why would it be xxx? >>> >>> if 'password=xxx' in conn_attr: >>> conn_attr = conn_attr.replace('password=xxx', '') >>> >>> - There's a thick white line at the bottom of the panel, where a >>> horizontal scrollbar might be if there was one. >>> - The trailing semi-colon should be removed from: "ERROR: Shell commands >>> are disabled in psql for security;" >>> >>> Once we're happy with the patch in general, I'll do a string review >>> before committing. In particular, I want to be sure the text in config.py >>> is appropriately worded. >>> >>> This is shaping up nicely! Good work. >>> >>> >>>> >>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave/ Team, >>>>> >>>>> PFA updated patch, sorry for the inconvenience, while cleanup I >>>>> removed the unwanted libraries but forgot to remove the code related to >>>>> them. >>>>> >>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Hackers, >>>>>>> >>>>>>> Please find the attached patch for RM-2341 >>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option for >>>>>>> starting PSQL. >>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>> 2. Added the same option for Server and Database nodes from the tree >>>>>>> view. >>>>>>> >>>>>> >>>>>> Unfortunately there's a trailing comma in package.json that makes it >>>>>> invalid. If I fix that, then I get the error below, so I'm guessing the >>>>>> intention was to actually include another package there? >>>>>> >>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>> Module not found: Error: Can't resolve 'local-echo-controller' in >>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>> resolve 'local-echo-controller' in >>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>> Parsed request is a module >>>>>> using description file: /Users/dpage/git/pgadmin4/web/package.json >>>>>> (relative path: ./pgadmin/tools/psql/static/js) >>>>>> aliased with mapping 'local-echo-controller': >>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>> using description file: >>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>> ./pgadmin/tools/psql/static/js) >>>>>> Field 'browser' doesn't contain a valid alias configuration >>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>> using description file: >>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>> no extension >>>>>> Field 'browser' doesn't contain a valid alias >>>>>> configuration >>>>>> >>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>> doesn't exist >>>>>> .js >>>>>> Field 'browser' doesn't contain a valid alias >>>>>> configuration >>>>>> >>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>> doesn't exist >>>>>> .jsx >>>>>> Field 'browser' doesn't contain a valid alias >>>>>> configuration >>>>>> >>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>> doesn't exist >>>>>> as directory >>>>>> >>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>> doesn't exist >>>>>> using description file: >>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>> ./node_modules/local-echo) >>>>>> no extension >>>>>> Field 'browser' doesn't contain a valid alias >>>>>> configuration >>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>> doesn't exist >>>>>> .js >>>>>> Field 'browser' doesn't contain a valid alias >>>>>> configuration >>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>> doesn't exist >>>>>> .jsx >>>>>> Field 'browser' doesn't contain a valid alias >>>>>> configuration >>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>> doesn't exist >>>>>> as directory >>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>> doesn't exist >>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>> >>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 ms >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>> >>>>> Regards, >>>>> Nikhil Mohite >>>>> >>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> *pgAdmin Hacker | Principal Software Architect* >>>> *EDB Postgres <http://edbpostgres.com>* >>>> >>>> *Mobile: +91 976-788-8246* >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> Regards, >> Nikhil Mohite >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > Regards, Nikhil Mohite Attachments: [application/octet-stream] RM_2341_V4.patch (351.0K, 3-RM_2341_V4.patch) download | inline diff: diff --git a/docs/en_US/developer_tools.rst b/docs/en_US/developer_tools.rst index 1ff442cc..bb67e33a 100644 --- a/docs/en_US/developer_tools.rst +++ b/docs/en_US/developer_tools.rst @@ -16,3 +16,4 @@ PL/SQL code. editgrid schema_diff erd_tool + psql_tool diff --git a/docs/en_US/images/psql_tool.png b/docs/en_US/images/psql_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f88ba5a573aa60bf7e08b8a38526dc73e8fcd5 GIT binary patch literal 23736 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 P=p;Q)S3j3^P6<r_JTn~) literal 0 HcmV?d00001 diff --git a/docs/en_US/images/psql_tool_menu.png b/docs/en_US/images/psql_tool_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..c219a0787868bd9427cfc056ce18c9ab562e52bd GIT binary patch literal 187181 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 literal 0 HcmV?d00001 diff --git a/docs/en_US/psql_tool.rst b/docs/en_US/psql_tool.rst new file mode 100644 index 00000000..8791648a --- /dev/null +++ b/docs/en_US/psql_tool.rst @@ -0,0 +1,23 @@ +.. _psql_tool: + +****************** +`PSQL Tool`:index: +****************** + +PSQL tool allows user to connect to PostgreSQL server using psql terminal. + +* Open PSQL Tool from Tools menu or context menu PSQL Tool from tree view. + +.. image:: images/psql_tool_menu.png + :alt: PSQL tool menu + :align: center + +* execute all type of commands. + +.. image:: images/psql_tool.png + :alt: PSQL tool window + :align: center + +You can open multiple instance of the PSQL tool in individual tabs simultaneously. +To close the PSQL tool, click the *X* in the upper-right hand corner of the tab bar. + diff --git a/requirements.txt b/requirements.txt index edd7000b..8227a4c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,6 @@ # ############################################################################### -cheroot==8.* Flask==1.* Flask-Gravatar==0.* Flask-Login==0.* @@ -36,3 +35,5 @@ sshtunnel==0.* ldap3==2.* Flask-BabelEx==0.* gssapi==1.6.* +flask-socketio>=5.0.1 +eventlet==0.30.2 diff --git a/web/config.py b/web/config.py index 2643ef19..002a9951 100644 --- a/web/config.py +++ b/web/config.py @@ -156,8 +156,8 @@ X_FRAME_OPTIONS = "SAMEORIGIN" # such as JavaScript, CSS, or pretty much anything that the browser loads. # see https://content-security-policy.com/#source_list for more info # e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';" -CONTENT_SECURITY_POLICY = "default-src http: data: blob: 'unsafe-inline' " \ - "'unsafe-eval';" +CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \ + " 'unsafe-eval';" # STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the # Strict-Transport-Security header @@ -636,6 +636,19 @@ KRB_AUTO_CREATE_USER = True KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache') +# PSQL tool settings +# This will enable PSQL tool in pgAdmin. So user can execute the commands using +# PSQL terminal in pgAdmin. +ENABLE_PSQL = True + +# ALLOW_PSQL_SHELL_COMMAND = True will disable the execution of os level +# commands using meta command \! from PSQL terminal. +# As PSQL allow user to execute the os level commands from the PSQL terminal +# user can execute any system level command as per the system login user +# privileges. Default this setting is set to False but if it set to True +# User will able to execute the system level commands through PSQL terminal in +# pgAdmin. +ALLOW_PSQL_SHELL_COMMANDS = False ########################################################################## # Local config settings diff --git a/web/package.json b/web/package.json index 8ed32df9..19110fda 100644 --- a/web/package.json +++ b/web/package.json @@ -117,13 +117,18 @@ "shim-loader": "^1.0.1", "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16", "snapsvg-cjs": "^0.0.6", + "socket.io-client": "^4.0.0", "split.js": "^1.5.10", "tablesorter": "^2.31.2", "tempusdominus-bootstrap-4": "^5.1.2", "tempusdominus-core": "^5.0.3", "underscore": "^1.13.1", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36", - "wkx": "^0.5.0" + "wkx": "^0.5.0", + "xterm": "^4.11.0", + "xterm-addon-fit": "^0.5.0", + "xterm-addon-search": "^0.8.0", + "xterm-addon-web-links": "^0.4.0" }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index d2bd1af6..dc1924cb 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -13,7 +13,7 @@ to start a web server.""" import sys -from cheroot.wsgi import Server as CherootServer + if sys.version_info < (3, 4): raise RuntimeError('This application must be run under Python 3.4 ' @@ -37,7 +37,7 @@ else: builtins.SERVER_MODE = None import config -from pgadmin import create_app +from pgadmin import create_app, socketio from pgadmin.utils import u_encode, fs_encoding, file_quote from pgadmin.utils.constants import INTERNAL # Get the config database schema version. We store this in pgadmin.model @@ -97,6 +97,8 @@ if not os.path.isfile(config.SQLITE_PATH): ########################################################################## app = create_app() app.debug = False +app.config['sessions'] = dict() + if config.SERVER_MODE: app.wsgi_app = ReverseProxied(app.wsgi_app) @@ -206,17 +208,16 @@ def main(): else: # Can use cheroot instead of flask dev server when not in debug # 10 is default thread count in CherootServer - num_threads = 10 if config.THREADED_MODE else 1 - prod_server = CherootServer( - (config.DEFAULT_SERVER, config.EFFECTIVE_SERVER_PORT), - wsgi_app=app, - numthreads=num_threads, - server_name=config.APP_NAME) + # num_threads = 10 if config.THREADED_MODE else 1 try: - print("Using production server...") - prod_server.start() + socketio.run( + app, + host=config.DEFAULT_SERVER, + port=config.EFFECTIVE_SERVER_PORT, + ) except KeyboardInterrupt: - prod_server.stop() + print("CLOSE SERVER") + socketio.stop() except IOError: app.logger.error("Error starting the app server: %s", sys.exc_info()) diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index a7333537..fad91082 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -19,6 +19,7 @@ from collections import defaultdict from importlib import import_module from flask import Flask, abort, request, current_app, session, url_for +from flask_socketio import SocketIO from werkzeug.exceptions import HTTPException from flask_babelex import Babel, gettext from flask_babelex import gettext as _ @@ -52,10 +53,15 @@ import mimetypes mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('text/css', '.css') + winreg = None if os.name == 'nt': import winreg +socketio = SocketIO(manage_session=False, async_mode='eventlet', + logger=False, engineio_logger=False, debug=False, + ping_interval=25, ping_timeout=120) + class PgAdmin(Flask): def __init__(self, *args, **kwargs): @@ -811,4 +817,5 @@ def create_app(app_name=None): ########################################################################## # All done! ########################################################################## + socketio.init_app(app) return app diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 235db027..d835ca82 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -10,6 +10,7 @@ from flask_babelex import gettext from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\ PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \ PREF_LABEL_OPTIONS +from flask_security import current_user import config LOCK_LAYOUT_LEVEL = { @@ -511,10 +512,12 @@ def register_browser_preferences(self): options=[{'label': gettext('Query Tool'), 'value': 'qt'}, {'label': gettext('Debugger'), 'value': 'debugger'}, {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], - help_str=gettext('Select Query Tool, Debugger, or Schema Diff from ' - 'the drop-down to set open in new browser tab for ' - 'that particular module.'), + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext('Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), select2={ 'multiple': True, 'allowClear': False, 'tags': True, 'first_empty': False, @@ -523,3 +526,16 @@ def register_browser_preferences(self): 'placeholder': gettext('Select open new tab...') } ) + + self.psql_tab_title = self.preference.register( + 'tab_settings', 'psql_tab_title_placeholder', + gettext("PSQL tool tab title"), + 'text', '%DATABASE%/%USERNAME%@%SERVER%', + category_label=PREF_LABEL_DISPLAY, + help_str=gettext( + 'Supported placeholders are %DATABASE%, %USERNAME%, and %SERVER%. ' + 'Users can provide any string with or without placeholders of' + ' their choice. The blank title will be revert back to the' + ' default title with placeholders.' + ) + ) diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index f4165c32..fb7ff12c 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -34,6 +34,7 @@ from pgadmin.utils.constants import UNAUTH_REQ, MIMETYPE_APP_JS, \ SERVER_CONNECTION_CLOSED from sqlalchemy import or_ from pgadmin.utils.preferences import Preferences +from .... import socketio as sio def has_any(data, keys): @@ -1499,6 +1500,13 @@ class ServerNode(PGChildNodeView): # Release Connection manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + # Check if any psql terminal is running for the current disconnecting + # server. If any terminate the psql tool connection. + if 'sid_soid_mapping' in current_app.config and str(sid) in \ + current_app.config['sid_soid_mapping']: + if str(sid) in current_app.config['sid_soid_mapping']: + for i in current_app.config['sid_soid_mapping'][str(sid)]: + sio.emit('disconnect-psql', namespace='/pty', to=i) status = manager.release() diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 01ab89c5..eb20cac5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -122,6 +122,9 @@ define('pgadmin.node.database', [ is_connected: function(node) { return (node && node.connected == true && node.canDisconn == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, is_conn_allow: function(node) { return (node && node.allowConn == true); }, diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 45dea090..ffd715f8 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -101,7 +101,8 @@ define('pgadmin.node.server', [ icon: 'fa fa-unlink', enable : 'is_connected',data: { data_disabled: gettext('Database is already disconnected.'), }, - },{ + }, + { name: 'reload_configuration', node: 'server', module: this, applies: ['tools', 'context'], callback: 'reload_configuration', category: 'reload', priority: 6, label: gettext('Reload Configuration'), @@ -728,6 +729,14 @@ define('pgadmin.node.server', [ return false; }, + /* Open psql tool for server*/ + server_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + } }, model: pgAdmin.Browser.Node.Model.extend({ defaults: { diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index 3823ef35..e763aa11 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -64,6 +64,14 @@ define([ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', }]); + + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); } } }, @@ -498,6 +506,13 @@ define([ pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); } }, + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, }); return pgBrowser.Collection; diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index 1c5af3f5..23585dbe 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -209,6 +209,14 @@ define('pgadmin.browser.node', [ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', enable: enable, }]); + + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); } // This will add options of scripts eg:'CREATE Script' @@ -902,6 +910,15 @@ define('pgadmin.browser.node', [ pgAdmin.DataGrid.show_query_tool('', i); }, + // Callback to render psql tool. + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, + // Logic to change the server background colour // There is no way of applying CSS to parent element so we have to // do it via JS code only diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js index c9e64132..3068aabe 100644 --- a/web/pgadmin/browser/static/js/panel.js +++ b/web/pgadmin/browser/static/js/panel.js @@ -122,10 +122,30 @@ define( myPanel.on(ev, that.handleVisibility.bind(myPanel, ev)); }); } + + // Listen on detach panel event + myPanel.on(wcDocker.EVENT.DETACHED, function(obj) { + that.setCodeMirrorHeight(obj); + }); }, }); } }, + setCodeMirrorHeight: function() { + // Fix for mac os code-mirror showing black screen. + var txtArea = $('.pg-panel-content .sql_textarea > textarea').first(); + txtArea.css('z-index', -1); + var $tabContent = $('.pg-panel-content > .sql_textarea').first(); + var $sqlPane = $tabContent.find('.CodeMirror > div > textarea'); + for(let i=0; i<$sqlPane.length; i++) {$($sqlPane[i]).css('z-index', -1);} + + $tabContent = $('.pg-panel-content > .sql_textarea').first(); + $sqlPane = $tabContent.find('.pg-panel-content'); + $sqlPane.find('.CodeMirror').css( + 'cssText', + 'height: ' + ($tabContent.height()) + 'px !important;' + ); + }, eventFunc: function(eventName) { var name = $(this).data('pgAdminName'); diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index 09baaf22..90d2d007 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -56,6 +56,15 @@ let _defaultToolBarButtons = [ toggleClass: '', parentClass: 'pg-toolbar-btn btn-primary-icon', enabled: false, + },{ + label: gettext('PSQL Tool'), + ariaLabel: gettext('PSQL Tool'), + btnClass: 'fas fa-terminal', + text: '', + toggled: false, + toggleClass: '', + parentClass: 'pg-toolbar-btn btn-primary-icon pg-toolbar-psql', + enabled: false, }, ]; @@ -105,6 +114,13 @@ export function initializeToolbar(panel, wcDocker) { pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected()); else if ('name' in data && data.name === gettext('Search objects')) pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); + else if ('name' in data && data.name === gettext('PSQL Tool')){ + var input = {}, + t = pgAdmin.Browser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgAdmin.Browser.psql.psql_tool(d, i, true); + } }); } diff --git a/web/pgadmin/browser/static/scss/_browser.scss b/web/pgadmin/browser/static/scss/_browser.scss index 0d157384..ae72f0e6 100644 --- a/web/pgadmin/browser/static/scss/_browser.scss +++ b/web/pgadmin/browser/static/scss/_browser.scss @@ -53,3 +53,9 @@ samp, border-width: 1px; font-size: 1.15em; } + +.pg-toolbar-psql { + padding-top: 0em; + font-size: inherit; + align-items: center; +} diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 8597df48..b0a317a5 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -52,6 +52,10 @@ define('pgadmin.browser.utils', pgAdmin['user_inactivity_timeout'] = {{ current_app.config.get('USER_INACTIVITY_TIMEOUT') }}; pgAdmin['override_user_inactivity_timeout'] = '{{ current_app.config.get('OVERRIDE_USER_INACTIVITY_TIMEOUT') }}' == 'True'; + /* GET PSQL Tool related config */ + pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; + // Define list of nodes on which Query tool option doesn't appears var unsupported_nodes = pgAdmin.unsupported_nodes = [ 'server_group', 'server', 'coll-tablespace', 'tablespace', diff --git a/web/pgadmin/static/bundle/browser.js b/web/pgadmin/static/bundle/browser.js index 14140a2f..0b3ad81b 100644 --- a/web/pgadmin/static/bundle/browser.js +++ b/web/pgadmin/static/bundle/browser.js @@ -11,6 +11,7 @@ define('bundled_browser',[ 'pgadmin.browser', 'sources/browser/index', 'top/tools/erd/static/js/index', + 'top/tools/psql/static/js/index', ], function(pgBrowser) { pgBrowser.init(); }); diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css index c2a776c8..5b4a9f2d 100644 --- a/web/pgadmin/static/css/style.css +++ b/web/pgadmin/static/css/style.css @@ -21,3 +21,5 @@ @import '../vendor/backgrid/backgrid.css'; @import '../vendor/backgrid/backgrid-select-all.css'; + +@import 'node_modules/xterm/css/xterm.css'; diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js index 1348cc45..42efc04d 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js @@ -100,6 +100,10 @@ export function generateTitle(title_placeholder, title_data) { title_placeholder = title_placeholder.replace(new RegExp('%ARGS%'), _.unescape(title_data.args)); title_placeholder = title_placeholder.replace(new RegExp('%SCHEMA%'), _.unescape(title_data.schema)); title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + } else if(title_data.type == 'psql_tool') { + title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + title_placeholder = title_placeholder.replace(new RegExp('%USERNAME%'), _.unescape(title_data.username)); + title_placeholder = title_placeholder.replace(new RegExp('%SERVER%'), _.unescape(title_data.server)); } return _.escape(title_placeholder); diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py new file mode 100644 index 00000000..e36f561f --- /dev/null +++ b/web/pgadmin/tools/psql/__init__.py @@ -0,0 +1,602 @@ +#!/usr/bin/env python3 +import fcntl +import os +import pty +import re +import select +import struct +import termios +import config +import eventlet.green.subprocess as subprocess + +from config import PG_DEFAULT_DRIVER +from flask import Response, url_for, request +from flask import render_template, copy_current_request_context, \ + current_app as app +from flask_babelex import gettext +from flask_security import login_required, current_user +from pgadmin.browser.utils import underscore_unescape +from pgadmin.utils import PgAdminModule +from pgadmin.utils.constants import MIMETYPE_APP_JS +from pgadmin.utils.driver import get_driver +from ... import socketio as sio +from pgadmin.utils import get_complete_file_path + + +session_input = dict() +session_input_cursor = dict() +session_last_cmd = dict() +pdata = dict() +cdata = dict() + + +class PSQLModule(PgAdminModule): + """ + class PSQLModule(PgAdminModule) + A module class for PSQL derived from PgAdminModule. + """ + + LABEL = gettext("PSQL") + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.psql', + 'path': url_for('psql.index') + "psql", + 'when': None + }] + + def get_panels(self): + return [] + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints for PSQL module + """ + return [ + 'psql.panel' + ] + + +blueprint = PSQLModule('psql', __name__, static_url_path='/static') + + [email protected]("/psql.js") +@login_required +def script(): + """render the required javascript""" + return Response( + response=render_template("psql/js/psql.js", _=gettext), + status=200, + mimetype=MIMETYPE_APP_JS + ) + + [email protected]('/panel/<int:trans_id>', + methods=["POST"], + endpoint="panel") +@login_required +def panel(trans_id): + """ + Return panel template for PSQL tools. + :param trans_id: + """ + params = { + 'trans_id': trans_id, + 'title': request.form['title'] + } + if 'sid_soid_mapping' not in app.config: + app.config['sid_soid_mapping'] = dict() + if request.args: + params.update({k: v for k, v in request.args.items()}) + + return render_template('editor_template.html', + sid=params['sid'], + db=params['db'] if params['db'] else 'postgres', + server_type=params['server_type'], + is_enable=config.ENABLE_PSQL, + title=underscore_unescape(params['title']), + theme=params['theme'] + ) + + +def set_term_size(fd, row, col, xpix=0, ypix=0): + """ + Set the terminal size as per UI xterm size. + :param fd: + :param row: + :param col: + :param xpix: + :param ypix: + """ + term_size = struct.pack('HHHH', row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) + + [email protected]('connect', namespace='/pty') +def connect(): + """ + Connect to the server through socket. + :return: + :rtype: + """ + if config.ENABLE_PSQL: + sio.emit('connected', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + if request.sid in session_last_cmd: + session_last_cmd[request.sid]['is_new_connection'] = False + else: + session_last_cmd[request.sid] = {'cmd': '', 'arrow_up': False, + 'invalid_cmd': False, + 'is_new_connection': False} + else: + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + [email protected]('start_process', namespace='/pty') +def start_process(data): + """ + Start the pty terminal and execute psql command and emit results to user. + :param data: + :return: + """ + + @copy_current_request_context + def read_and_forward_pty_output(sid, data): + max_read_bytes = 1024 * 20 + # Create the pty terminal process, parent and fd are file descriptors + # for parent and child. + parent, fd = pty.openpty() + p = None + if parent is not None: + # Child process + p = subprocess.Popen(connection_data, + preexec_fn=os.setsid, + stdin=fd, + stdout=fd, + stderr=fd, + universal_newlines=True + ) + + app.config['sessions'][request.sid] = parent + pdata[request.sid] = p + cdata[request.sid] = fd + else: + app.config['sessions'][request.sid] = parent + cdata[request.sid] = fd + set_term_size(fd, 50, 50) + + while p and p.poll() is None: + if request.sid in app.config['sessions']: + # This code is added to make this unit testable. + if "is_test" not in data: + sio.sleep(0.01) + else: + data['count'] += 1 + if data['count'] == 5: + break + + timeout = 0 + # module provides access to platform-specific I/O + # monitoring functions + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) + + if parent in data_ready: + # Read the output from parent fd (terminal). + output = os.read(parent, max_read_bytes) + emit_output = True + + if sid in session_last_cmd and session_last_cmd[sid][ + 'arrow_up'] and not session_last_cmd[request.sid][ + 'arrow_left_right']: + session_last_cmd[sid]['cmd'] = output.decode() + session_input_cursor[request.sid] = len( + session_last_cmd[sid]['cmd']) + session_last_cmd[sid]['arrow_up'] = True + + if sid in session_last_cmd: + # If command is invalid then emit error to user. + if session_last_cmd[sid]['invalid_cmd']: + emit_output = False + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security\r\n"), + 'error': True + }, + namespace='/pty', room=sid) + # If command is valid then emit output to user. + if emit_output: + sio.emit('pty-output', + {'result': output.decode(), + 'error': False}, + namespace='/pty', room=sid) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + + # Check user is authenticated and PSQL is enabled in config. + if current_user.is_authenticated and config.ENABLE_PSQL: + connection_data = [] + try: + db = '' + if data['db']: + db = data['db'].replace('\\', "\\\\") + + conn, manager = _get_connection(int(data['sid']), data) + psql_utility = manager.utility('sql') + connection_data = get_connection_str(psql_utility, db, + manager) + except Exception as e: + # If any error raised during the start the PSQL emit error to UI. + # request.sid: This sid is socket id. + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + + try: + if str(data['sid']) not in app.config['sid_soid_mapping']: + # request.sid: refer request.sid as socket id. + app.config['sid_soid_mapping'][str(data['sid'])] = list() + app.config['sid_soid_mapping'][str(data['sid'])].append( + request.sid) + else: + app.config['sid_soid_mapping'][str(data['sid'])].append( + request.sid) + + sio.start_background_task(read_and_forward_pty_output, + request.sid, data) + except Exception as e: + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + else: + # Show error if user is not authenticated. + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def _get_connection(sid, data): + """ + Get the connection object of ERD. + :param sid: + :param did: + :param trans_id: + :return: + """ + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + try: + conn = manager.connection() + # This is added for unit test only, no use in normal execution. + if 'pwd' in data: + kwargs = {'password': data['pwd'], "user": data['user']} + status, msg = conn.connect(**kwargs) + else: + status, msg = conn.connect() + if not status: + app.logger.error(msg) + sio.emit(sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}' + ''.format('Server connection not present.'), + }, namespace='/pty', room=request.sid)) + raise Exception('Server is not connected.') + + return conn, manager + except Exception as e: + app.logger.error(e) + raise + + +def get_connection_str(psql_utility, db, manager): + """ + Get connection string(through connection dsn) + :param psql_utility: PostgreSQL binary path. + :param db: database name to connect specific db. + :return: connection attribute list for PSQL connection. + """ + conn_attr = get_conn_str(manager, db) + conn_attr_list = list() + conn_attr_list.append(psql_utility) + conn_attr_list.append(conn_attr) + return conn_attr_list + + +def get_conn_str(manager, db): + """ + Get connection attributes for psql connection. + :param manager: + :param db: + :return: + """ + pwd = manager.extract_password() + conn_attr =\ + "host={0} port={1} dbname={2} user={3} sslmode={4} " \ + "sslcompression={5} password={6} " \ + "".format( + manager.local_bind_host if manager.use_ssh_tunnel else + manager.host, + manager.local_bind_port if manager.use_ssh_tunnel else + manager.port, + db if db != '' else 'postgres', + manager.user if manager.user else 'postgres', + manager.ssl_mode, + True if manager.sslcompression else False, + pwd + ) + + if manager.hostaddr: + conn_attr = " {0} hostaddr={1}".format(conn_attr, manager.hostaddr) + + if manager.passfile: + conn_attr = " {0} passfile={1}".format(conn_attr, + get_complete_file_path( + manager.passfile)) + + if get_complete_file_path(manager.sslcert): + conn_attr = " {0} sslcert={1}".format( + conn_attr, get_complete_file_path(manager.sslcert)) + + if get_complete_file_path(manager.sslkey): + conn_attr = " {0} sslkey={1}".format( + conn_attr, get_complete_file_path(manager.sslkey)) + + if get_complete_file_path(manager.sslrootcert): + conn_attr = " {0} sslrootcert={1}".format( + conn_attr, get_complete_file_path(manager.sslrootcert)) + + if get_complete_file_path(manager.sslcrl): + conn_attr = " {0} sslcrl={1}".format( + conn_attr, get_complete_file_path(manager.sslcrl)) + + if manager.service: + conn_attr = " {0} service={1}".format( + conn_attr, get_complete_file_path(manager.service)) + + return conn_attr + + [email protected]('socket_input', namespace='/pty') +def socket_input(data): + """ + This get the user input through socket. + :param data: User input from socket. + """ + try: + # request.sid: refer request.sid as socket id. + # Check PSQL enabled setting from config. + enable_psql = True if config.ENABLE_PSQL else False + + if request.sid in app.config['sessions']: + if data['key_name'] == 'Enter' and enable_psql: + # If user get previous executed command from history then set + # current command as previous executed command. + if session_last_cmd[request.sid]['cmd'] \ + and session_last_cmd[request.sid]['arrow_up']: + user_input = str( + session_last_cmd[request.sid]['cmd']).strip() + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + else: + if request.sid not in session_input: + session_input[request.sid] = data['input'] + user_input = str(session_input[request.sid]).strip() + else: + user_input = str(session_input[request.sid]).strip() + session_input_cursor[request.sid] = 0 + + # If ALLOW_PSQL_SHELL_COMMANDS is False then user can't execute + # \! meta command to run shell commands through PSQL terminal. + # Check before executing the user entered command does not + # contains \! in input. + is_new_connection = session_last_cmd[request.sid][ + 'is_new_connection'] + if user_input.startswith('\\!') and \ + re.match("^\\\!$", user_input) and \ + len(user_input) == 2 and \ + not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not is_new_connection: + + session_last_cmd[request.sid]['invalid_cmd'] = True + + for i in range(len(session_input[request.sid])): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + session_input[request.sid] = '' + elif re.search("\\\!", user_input) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + stop_execution = True + # Check \! is passed as string or not. + double_quote_strs = re.findall('"([^"]*)"', user_input) + + if double_quote_strs: + for sub_str in double_quote_strs: + if re.search("\\\!", sub_str): + stop_execution = False + # break + + if stop_execution: + session_last_cmd[request.sid]['invalid_cmd'] = True + # Remove already added command from terminal. + for i in range(len(user_input)): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + # Add Enter event to execute the command. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + elif user_input == '\q' or user_input == 'q\\q': + # If user enter \q to terminate the PSQL, emit the msg to + # notify user connection is terminated. + sio.emit('pty-output', + { + 'result': gettext( + 'Connection terminated, To create new ' + 'connection please open another psql' + ' tool.'), + 'error': True}, + namespace='/pty', room=request.sid) + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + + else: + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + session_input[request.sid] = '' + session_last_cmd[request.sid]['is_new_connection'] = False + else: + if data['key_name'] == 'ArrowLeft': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] > 0: + session_input_cursor[request.sid] -= 1 + + elif data['key_name'] == 'ArrowRight': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] < len( + session_input[request.sid]): + session_input_cursor[request.sid] += 1 + + elif data['key_name'] == 'ArrowUp': + session_last_cmd[request.sid]['arrow_up'] = True + session_last_cmd[request.sid]['arrow_left_right'] = False + session_input[request.sid] = session_last_cmd[request.sid][ + 'cmd'] + session_input_cursor[request.sid] = len( + session_last_cmd[request.sid]['cmd']) + + elif request.sid in session_input and data[ + 'key_name'] == 'Backspace' and ( + len(session_input[request.sid]) or len( + session_last_cmd[request.sid])): + + session_last_cmd[request.sid]['arrow_left_right'] = True + + if session_last_cmd[request.sid]['cmd']: + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + + user_input = list(session_input[request.sid]) + + if session_input_cursor[request.sid] == 1: + index = 0 + session_input_cursor[request.sid] -= 1 + else: + if session_input_cursor[request.sid] > 0: + index = (session_input_cursor[request.sid]) - 1 + session_input_cursor[request.sid] -= 1 + else: + index = session_input_cursor[request.sid] + session_input_cursor[request.sid] = 0 + + if len(user_input): + del user_input[index] + session_input[request.sid] = "".join(user_input) + + if len(session_input[request.sid]) == 0: + session_input_cursor[request.sid] = 0 + session_last_cmd[request.sid]['cmd'] = '' + elif request.sid in session_input: + if session_last_cmd[request.sid]['cmd'] and session_input[ + request.sid] == '': + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + session_input_cursor[request.sid] = len( + session_input[request.sid]) + else: + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + user_input = list(session_input[request.sid]) + user_input.insert(session_input_cursor[request.sid], + data['input']) + session_input[request.sid] = ''.join(user_input) + session_input_cursor[request.sid] += 1 + session_last_cmd[request.sid]['arrow_left_right'] = False + else: + session_input_cursor[request.sid] = 0 + session_input[request.sid] = data['input'] + session_input_cursor[request.sid] += 1 + + # Write user input to terminal parent fd. + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + except Exception as e: + # Delete socket id from sessions. + # request.sid: refer request.sid as socket id. + sio.emit('pty-output', + { + 'result': gettext('Invalid session.\r\n'), + 'error': True + }, + namespace='/pty', room=request.sid) + del app.config['sessions'][request.sid] + + [email protected]('resize', namespace='/pty') +def resize(data): + """ + Resize the pty terminal as per the UI terminal. + :param data: UI terminal rows and cols data + """ + # request.sid: refer request.sid as socket id. + if request.sid in app.config['sessions']: + set_term_size(app.config['sessions'][request.sid], data['rows'], + data['cols']) + + [email protected]('disconnect', namespace='/pty') +def disconnect(): + """ + Disconnect the socket and terminate the process + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + disconnect_socket() + + [email protected]('server-disconnect', namespace='/pty') +def server_disconnect(data): + """ + Disconnect the socket and terminate the process after user disconnect + the server. we can't use disconnect event name as it is reserved for socket + internal use. + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata and request.sid in app.config['sid_soid_mapping'][ + data['sid']]: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + app.config['sid_soid_mapping'][data['sid']] = [soid for soid in + app.config[ + 'sid_soid_mapping'][ + data['sid']] if + soid != request.sid] + disconnect_socket() + + +def disconnect_socket(): + os.write(app.config['sessions'][request.sid], '\q\n'.encode()) + sio.sleep(1) + os.close(app.config['sessions'][request.sid]) + os.close(cdata[request.sid]) + del app.config['sessions'][request.sid] diff --git a/web/pgadmin/tools/psql/static/js/index.js b/web/pgadmin/tools/psql/static/js/index.js new file mode 100644 index 00000000..4d88ba04 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/index.js @@ -0,0 +1,23 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import $ from 'jquery'; +import _ from 'underscore'; +import pgAdmin from 'sources/pgadmin'; +import pgBrowser from 'top/browser/static/js/browser'; +import * as csrfToken from 'sources/csrf'; +import {initialize} from './psql_module'; + +let pgBrowserOut = initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser); + +module.exports = { + pgBrowser: pgBrowserOut, +}; diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js new file mode 100644 index 00000000..2610a60f --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -0,0 +1,419 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import { Terminal } from 'xterm'; +import { FitAddon } from 'xterm-addon-fit'; +import { WebLinksAddon } from 'xterm-addon-web-links'; +import { SearchAddon } from 'xterm-addon-search'; +import { io } from 'socketio'; +import Alertify from 'pgadmin.alertifyjs'; +import {enable} from 'pgadmin.browser.toolbar'; +import clipboard from 'sources/selection/clipboard'; +import 'wcdocker'; +import {getRandomInt} from 'sources/utils'; + +import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; +import {generateTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; + + +export function setPanelTitle(psqlToolPanel, panelTitle) { + psqlToolPanel.title('<span title="'+panelTitle+'">'+panelTitle+'</span>'); +} + +var wcDocker = window.wcDocker; + +export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) { + var pgBrowser = Browser; + var terminal = Terminal; + var parentData = null; + /* Return back, this has been called more than once */ + if (pgBrowser.psql) + return pgBrowser.psql; + + + // Create an Object Restore of pgBrowser class + pgBrowser.psql = { + init: function() { + this.initialized = true; + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'psql', + module: this, + applies: ['tools'], + callback: 'psql_tool', + priority: 1, + label: gettext('PSQL Tool (Beta)'), + enable: this.psqlToolEnabled, + }]; + + this.enable_psql_tool = pgAdmin['enable_psql']; + if(pgAdmin['enable_psql']) { + pgBrowser.add_menus(menus); + } + + // Creating a new pgBrowser frame to show the data. + var psqlFrameType = new pgBrowser.Frame({ + name: 'frm_psqltool', + showTitle: true, + isCloseable: true, + isPrivate: true, + url: 'about:blank', + }); + + var self = this; + /* Cache may take time to load for the first time + * Keep trying till available + */ + let cacheIntervalId = setInterval(function() { + if(pgBrowser.preference_version() > 0) { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + clearInterval(cacheIntervalId); + } + },0); + + pgBrowser.onPreferencesChange('psql', function() { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + }); + + // Load the newly created frame + psqlFrameType.load(pgBrowser.docker); + return this; + }, + /* Enable/disable PSQL tool menu in tools based + * on node selected. if selected node is present + * in unsupported_nodes, menu will be disabled + * otherwise enabled. + */ + psqlToolEnabled: function(obj) { + + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj)) { + if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) { + if (obj._type == 'database' && obj.allowConn) { + return true; + } else if (obj._type != 'database') { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + })(); + + enable(gettext('PSQL Tool'), isEnabled); + return isEnabled; + }, + retrieveAncestorOfTypeServer: function(item) { + let serverInformation = null; + // let aciTreeItem = item || pgBrowser.treeMenu.selected(); + let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); + + if (treeNode) { + let nodeData; + let databaseNode = treeNode.ancestorNode( + (node) => { + nodeData = node.getData(); + return (nodeData._type === 'database'); + } + ); + let isServerNode = (node) => { + nodeData = node.getData(); + return nodeData._type === 'server'; + }; + + if (databaseNode !== null) { + if (nodeData._label.indexOf('=') >= 0) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext( + 'Databases with = symbols in the name cannot be backed up or restored using this utility.' + ) + ); + } else { + if (databaseNode.anyParent(isServerNode)) + serverInformation = nodeData; + } + } else { + if (treeNode.anyFamilyMember(isServerNode)) + serverInformation = nodeData; + } + } + + if (serverInformation === null) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext('Please select server or child node from the browser tree.') + ); + } + return serverInformation; + }, + psql_tool: function(data, aciTreeIdentifier, gen=false) { + const module = 'paths'; + let preference_name = 'pg_bin_dir'; + let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.'); + const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeIdentifier); + + if ((serverInformation.type && serverInformation.type === 'ppas') || + serverInformation.server_type === 'ppas') { + preference_name = 'ppas_bin_dir'; + msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'); + } + const preference = pgBrowser.get_preference(module, preference_name); + if (preference) { + if (!preference.value) { + Alertify.alert(gettext('Configuration required'), msg); + return false; + } + } else { + Alertify.alert( + gettext(this.errorAlertTitle), + gettext('Failed to load preference %s of module %s', preference_name, module) + ); + return false; + } + const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if (node === undefined || !node.getData()) { + Alertify.alert( + gettext('PSQL Error'), + gettext('No object selected.') + ); + return; + } + + parentData = getTreeNodeHierarchyFromIdentifier.call( + pgBrowser, + aciTreeIdentifier + ); + + if(_.isUndefined(parentData.server)) { + Alertify.alert( + gettext('PSQL Error'), + gettext('Please select a server/database object.') + ); + return; + } + + const transId = getRandomInt(1, 9999999); + + var panelTitle = ''; + // Set psql tab title as per prefrences setting. + var title_data = { + 'database': parentData.database ? parentData.database.label : 'postgres' , + 'username': parentData.server.user_name, + 'server': parentData.server.label, + 'type': 'psql_tool', + }; + var tab_title_placeholder = pgBrowser.get_preferences_for_module('browser').psql_tab_title_placeholder; + panelTitle = generateTitle(tab_title_placeholder, title_data); + + const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + + let psqlToolForm = ` + <form id="psqlToolForm" action="${panelUrl}" method="post"> + <input id="title" name="title" hidden /> + <input name="close_url" value="${panelCloseUrl}" hidden /> + </form> + <script> + document.getElementById("title").value = "${_.escape(panelTitle)}"; + document.getElementById("psqlToolForm").submit(); + </script> + `; + var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; + if (open_new_tab && open_new_tab.includes('psql_tool')) { + var newWin = window.open('', '_blank'); + newWin.document.write(psqlToolForm); + newWin.document.title = panelTitle; + } else { + /* On successfully initialization find the properties panel, + * create new panel and add it to the dashboard panel. + */ + var propertiesPanel = pgBrowser.docker.findPanels('properties'); + var psqlToolPanel = pgBrowser.docker.addPanel('frm_psqltool', wcDocker.DOCK.STACKED, propertiesPanel[0]); + + // Set panel title and icon + setPanelTitle(psqlToolPanel, panelTitle); + psqlToolPanel.icon('fas fa-terminal psql-tab-style'); + psqlToolPanel.focus(); + + var openPSQLToolURL = function(j) { + // add spinner element + let $spinner_el = + $(`<div class="pg-sp-container"> + <div class="pg-sp-content"> + <div class="row"> + <div class="col-12 pg-sp-icon"></div> + </div> + </div> + </div>`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { + var frameInitialized = $(j).data('frameInitialized'); + if (frameInitialized) { + clearInterval(init_poller_id); + var frame = $(j).data('embeddedFrame'); + if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); + frame.openHTML(psqlToolForm); + } + } + }, 100); + }; + + openPSQLToolURL(psqlToolPanel); + + } + + }, + getPanelUrls: function(transId, panelTitle, parentData) { + let openUrl = url_for('psql.panel', { + trans_id: transId, + }); + const misc_preferences = pgBrowser.get_preferences_for_module('misc'); + var theme = misc_preferences.theme; + + openUrl += `?sgid=${parentData.server_group._id}` + +`&sid=${parentData.server._id}` + +`&server_type=${parentData.server.server_type}` + + `&theme=${theme}`; + + if(parentData.database && parentData.database._id) { + let db_label = parentData.database._label.replace('\\', '\\\\'); + openUrl += `&db=${_.escape(db_label)}`; + } else { + openUrl += `&db=${''}`; + } + + let closeUrl = url_for('psql.close', { + trans_id: transId, + }); + return [openUrl, closeUrl]; + }, + psql_terminal: function() { + // theme colors + var term = new terminal({ + cursorBlink: true, + macOptionIsMeta: true, + scrollback: 10000, + }); + + return term; + }, + psql_Addon: function(term) { + const fitAddon = this.psql_fit_screen(); + term.loadAddon(fitAddon); + + const webLinksAddon = this.psql_web_link(); + term.loadAddon(webLinksAddon); + + const searchAddon = this.psql_search(); + term.loadAddon(searchAddon); + + fitAddon.fit(); + term.resize(15, 50); + fitAddon.fit(); + return fitAddon; + }, + psql_fit_screen: function() { + return new FitAddon(); + }, + psql_web_link: function() { + return new WebLinksAddon(); + }, + psql_search: function() { + return new SearchAddon(); + }, + psql_socket: function() { + return io('/pty', {pingTimeout: 120000, pingInterval: 25000}); + }, + psql_socket_io: function(socket, is_enable, sid, db, server_type, fitAddon, term) { + // Listen all the socket events emit from server. + socket.on('pty-output', function(data){ + if(data.error) { + term.write('\r\n'); + } + term.write(data.result); + if(data.error) { + term.write('\r\n'); + } + }); + // Connect socket + socket.on('connect', () => { + if(is_enable == 'True'){ + socket.emit('start_process', {'sid': sid, 'db': db, 'stype': server_type }); + } + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('conn_error', (response) => { + term.write(response.error); + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('conn_not_allow', () => { + term.write('PSQL connection not allowed'); + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('disconnect-psql', () => { + socket.emit('server-disconnect', {'sid': sid}); + term.write('\r\nServer disconnected, Connection terminated, To create new connection please open another psql tool.'); + }); + }, + psql_terminal_io: function(term, socket) { + // Listen key press event from terminal and emit socket event. + let selected_text = ''; + term.attachCustomKeyEventHandler(e => { + e.stopPropagation(); + if(e.type=='keydown' && e.metaKey &&(e.key == 'v' || e.key == 'V')) { + if(selected_text != '') { + if (selected_text.length > 0) { + socket.emit('socket_input', {'input': selected_text, 'key_name': e.code}); + selected_text = ''; + } + } else { + navigator.clipboard.readText().then( clipText => { + selected_text = clipText; + if (selected_text.length > 0) { + socket.emit('socket_input', {'input': selected_text, 'key_name': e.code}); + selected_text = ''; + } + }); + } + }else if(e.type=='keydown' && e.metaKey && (e.key == 'c' || e.key == 'C')) { + if (term.hasSelection()) { + selected_text = term.getSelection(); + } else { + selected_text = clipboard.readText(); + } + } + return true; + }); + + term.onKey(function (ev) { + if (pgAdmin['allow_psql_shell_commands']) { + socket.emit('socket_input', {'input': ev.key, 'key_name': ev.domEvent.code}); + } else { + socket.emit('socket_input', {'input': ev.key, 'key_name': ev.domEvent.code}); + } + }); + } + }; + + return pgBrowser.psql; +} + diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html new file mode 100644 index 00000000..86812c79 --- /dev/null +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -0,0 +1,83 @@ +{% extends "base.html" %} +{% block title %}{{title}}{% endblock %} + +{% block css_link %} +<link type="text/css" rel="stylesheet" href="{{ url_for('browser.browser_css')}}"/> +{% endblock %} +{% block body %} +<style> + body {padding: 0px;} + {% if is_desktop_mode and is_linux %} + .alertify .ajs-dimmer,.alertify .ajs-modal{-webkit-transform: none;} + .alertify-notifier{-webkit-transform: none;} + .alertify-notifier .ajs-message{-webkit-transform: none;} + .alertify .ajs-dialog.ajs-shake{-webkit-animation-name: none;} + .sql-editor-busy-icon.fa-pulse{-webkit-animation: none;} + {% endif %} +</style> +<div style="width: 100%; height: 100%;" id="psql-terminal" class="psql_terminal"></div> +{% endblock %} + + +{% block init_script %} +require( + ['sources/generated/psql_tool'], + function(pgBrowser) { + <!--Theme colors--> + var theme_colors = { + 'standard': { + background: '#FFF', + foreground: '#000', + cursor: '#000', + cursorAccent: '#000', + selection: '#DDD', + }, + 'dark': { + background: '#212121', + foreground: '#d4d4d4', + cursor: '#d4d4d4', + cursorAccent: '#d4d4d4', + selection: '#323e43', + }, + 'high_contrast': { + background: '#010b15', + foreground: '#fff', + cursor: '#fff', + cursorAccent: '#fff', + selection: '#84d6ff', + } + } + + const term = self.pgAdmin.Browser.psql.psql_terminal(); + <!--Addon for fitAddon, webLinkAddon, SearchAddon --> + const fitAddon = self.pgAdmin.Browser.psql.psql_Addon(term); + <!-- Update the theme for terminal--> + term.setOption('theme', theme_colors['{{theme}}']); + <!-- Open the terminal --> + term.open(document.getElementById('psql-terminal')); + <!-- Socket--> + const socket = self.pgAdmin.Browser.psql.psql_socket(); + self.pgAdmin.Browser.psql.psql_socket_io(socket, '{{is_enable}}', '{{sid}}', '{{db}}', '{{server_type}}', fitAddon, term); + self.pgAdmin.Browser.psql.psql_terminal_io(term, socket); + + <!-- Resize the terminal --> + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } + + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) + } + } + + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) + }); +{% endblock %} + + diff --git a/web/pgadmin/tools/psql/tests/__init__.py b/web/pgadmin/tools/psql/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web/pgadmin/tools/psql/tests/psql_test_data.json b/web/pgadmin/tools/psql/tests/psql_test_data.json new file mode 100644 index 00000000..4148c75b --- /dev/null +++ b/web/pgadmin/tools/psql/tests/psql_test_data.json @@ -0,0 +1,184 @@ +{ + "psql_user_input": [ + { + "name": "Enter Select 1;", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "move_cursor_up": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "is_history": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowLeft", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowLeft": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowRight", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Read previous executed command", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "move_cursor_right": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\!", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! with other cmd not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\! ls", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Valid commands", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select \"\\!\"", + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "First command as enter", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Exist psql terminal by using \\q", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\q", + "mock_data": { + + }, + "expected_data": { + } + } + ], + "resize_terminal": [ + { + "name": "Resize psql terminal as per UI.", + "is_positive_test": true, + "mocking_required": false, + "input_data": { + "cols": 141, + "rows": 39 + }, + "mock_data": { + + }, + "expected_data": { + } + } + ], + "backend_task": [ + { + "name": "Backend Task", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "Select 1;", + "is_backend_task": true, + "mock_data": { + "is_test": true + }, + "expected_data": { + } + } + ] +} diff --git a/web/pgadmin/tools/psql/tests/test_backend_task.py b/web/pgadmin/tools/psql/tests/test_backend_task.py new file mode 100644 index 00000000..a4f14ee4 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_backend_task.py @@ -0,0 +1,87 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLBackend(BaseTestGenerator): + scenarios = utils.generate_scenarios('backend_task', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'], + 'is_test': True, + 'count': 0 + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_panel.py b/web/pgadmin/tools/psql/tests/test_panel.py new file mode 100644 index 00000000..6f93c8c2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_panel.py @@ -0,0 +1,36 @@ +import uuid +import random +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data + + +class PSQLPanel(BaseTestGenerator): + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + self.theme = 'standard' + + def runTest(self): + trans_id = random.randint(1, 9999999) + url = '/psql/panel/{trans_id}?sgid={sgid}&sid={sid}&server_type=pg' \ + '&db={db_name}&theme={theme}'.\ + format(trans_id=trans_id, sgid=self.sgid, sid=self.sid, + db_name=self.db_name, theme=self.theme) + + response = self.tester.post( + url, data={"title": "panel_title"}, + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_disabled.py b/web/pgadmin/tools/psql/tests/test_psql_disabled.py new file mode 100644 index 00000000..7dc52498 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_disabled.py @@ -0,0 +1,34 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisabled(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = False + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_input.py b/web/pgadmin/tools/psql/tests/test_psql_input.py new file mode 100644 index 00000000..6f6eabe7 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_input.py @@ -0,0 +1,148 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLInput(BaseTestGenerator): + scenarios = utils.generate_scenarios('psql_user_input', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_backspace') and self.is_backspace: + if hasattr(self, 'move_cursor_up') and self.move_cursor_up: + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Backspace' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowUp') and self.is_arrowUp: + if hasattr(self, 'is_history') and self.is_history: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowLeft') and self.is_arrowLeft: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowRight') and self.is_arrowRight: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'move_cursor_right') and self.is_arrowRight: + for i in range(2): + input_data = { + 'input': '', + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + input_data = { + 'input': '', + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_resize_terminal.py b/web/pgadmin/tools/psql/tests/test_resize_terminal.py new file mode 100644 index 00000000..d305c2d0 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_resize_terminal.py @@ -0,0 +1,58 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLResizeTerminal(BaseTestGenerator): + scenarios = utils.generate_scenarios('resize_terminal', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.emit('resize', self.input_data, namespace='/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_connect.py b/web/pgadmin/tools/psql/tests/test_socket_connect.py new file mode 100644 index 00000000..3791525a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_connect.py @@ -0,0 +1,35 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketConnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py new file mode 100644 index 00000000..0619eb30 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py @@ -0,0 +1,52 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisconnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_test_client = app.test_client() + flask_test_client.get('/') + + self.test_client = socketio.test_client( + app, + flask_test_client=flask_test_client, + namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process.py b/web/pgadmin/tools/psql/tests/test_start_process.py new file mode 100644 index 00000000..1245de3f --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process.py @@ -0,0 +1,57 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcess(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + import random + trans_id = random.randint(1, 9999999) + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process_fail.py b/web/pgadmin/tools/psql/tests/test_start_process_fail.py new file mode 100644 index 00000000..0acc7be2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process_fail.py @@ -0,0 +1,48 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcessFail(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + config.ENABLE_PSQL = False + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/utils.py b/web/pgadmin/tools/psql/tests/utils.py new file mode 100644 index 00000000..85bd5373 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/utils.py @@ -0,0 +1,6 @@ +import os +import json + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/psql_test_data.json") as data_file: + test_cases = json.load(data_file) diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss index 0bb40802..a58eb7e9 100644 --- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss +++ b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss @@ -374,3 +374,20 @@ div.strikeout:after { /* Setting it to hardcoded white as the SVG generated is having white bg * Need to check what can be done. */ + +/* Css for psql */ +.psql_terminal .terminal { + padding-top: 1%; + padding-left: 0.5%; + height: 100%; +} + +.psql-icon-style { + font-size: inherit; + padding-left: 0em; +} + +.psql-tab-style { + font-size: small; + padding-left: 0em; +} diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py index 23abfffa..71ae82ea 100644 --- a/web/pgadmin/utils/csrf.py +++ b/web/pgadmin/utils/csrf.py @@ -38,6 +38,7 @@ class _PGCSRFProtect(CSRFProtect): 'pgadmin.tools.schema_diff.ddl_compare', 'pgadmin.authenticate.login', 'pgadmin.tools.erd.panel', + 'pgadmin.tools.psql.panel', ] for exempt in exempt_views: diff --git a/web/pgadmin/utils/driver/psycopg2/server_manager.py b/web/pgadmin/utils/driver/psycopg2/server_manager.py index 2a951b6e..3be5d833 100644 --- a/web/pgadmin/utils/driver/psycopg2/server_manager.py +++ b/web/pgadmin/utils/driver/psycopg2/server_manager.py @@ -527,6 +527,15 @@ WHERE db.oid = {0}""".format(did)) return None + def extract_password(self): + if self.password: + crypt_key_present, crypt_key = get_crypt_key() + if not crypt_key_present: + return False, crypt_key + + password = decrypt(self.password, crypt_key).decode() + return password + def export_password_env(self, env): if self.password: crypt_key_present, crypt_key = get_crypt_key() diff --git a/web/pgadmin/utils/preferences.py b/web/pgadmin/utils/preferences.py index 15ceeb1a..e9efe479 100644 --- a/web/pgadmin/utils/preferences.py +++ b/web/pgadmin/utils/preferences.py @@ -72,6 +72,7 @@ class _Preference(object): self.select2 = kwargs.get('select2', None) self.fields = kwargs.get('fields', None) self.allow_blanks = kwargs.get('allow_blanks', None) + self.disabled = kwargs.get('disabled', False) # Look into the configuration table to find out the id of the specific # preference. @@ -252,6 +253,7 @@ class _Preference(object): 'select2': self.select2, 'value': self.get(), 'fields': self.fields, + 'disabled': self.disabled, } return res @@ -414,6 +416,7 @@ class Preferences(object): :param fields: field schema (if preference has more than one field to take input from user e.g. keyboardshortcut preference) :param allow_blanks: Flag specify whether to allow blank value. + :param disabled: Flag specify whether to disable the setting or not. """ min_val = kwargs.get('min_val', None) max_val = kwargs.get('max_val', None) @@ -423,6 +426,7 @@ class Preferences(object): select2 = kwargs.get('select2', None) fields = kwargs.get('fields', None) allow_blanks = kwargs.get('allow_blanks', None) + disabled = kwargs.get('disabled', False) cat = self.__category(category, category_label) if name in cat['preferences']: @@ -439,7 +443,8 @@ class Preferences(object): (cat['preferences'])[name] = res = _Preference( cat['id'], name, label, _type, default, help_str=help_str, min_val=min_val, max_val=max_val, options=options, - select2=select2, fields=fields, allow_blanks=allow_blanks + select2=select2, fields=fields, allow_blanks=allow_blanks, + disabled=disabled ) return res diff --git a/web/webpack.config.js b/web/webpack.config.js index 779f2faa..f631178b 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -355,6 +355,7 @@ module.exports = [{ debugger_direct: './pgadmin/tools/debugger/static/js/direct.js', schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js', erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js', + psql_tool: './pgadmin/tools/psql/static/js/index.js', file_utils: './pgadmin/misc/file_manager/static/js/utility.js', 'pgadmin.style': pgadminCssStyles, pgadmin: pgadminScssStyles, @@ -493,7 +494,7 @@ module.exports = [{ ], }, }, - }, { + },{ test: require.resolve('./node_modules/acitree/js/jquery.aciTree.min'), use: { loader: 'imports-loader', @@ -532,6 +533,7 @@ module.exports = [{ 'pure|pgadmin.tools.storage_manager', 'pure|pgadmin.tools.search_objects', 'pure|pgadmin.tools.erd_module', + 'pure|pgadmin.tools.psql_module', ], }, }, diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 074b2580..e0b28091 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -159,6 +159,15 @@ var webpackShimConfig = { 'jquery.acisortable': path.join(__dirname, './node_modules/acitree/js/jquery.aciSortable.min'), 'jquery.acifragment': path.join(__dirname, './node_modules/acitree/js/jquery.aciFragment.min'), + //xterm + 'xterm': path.join(__dirname, './node_modules/xterm/lib/xterm.js'), + 'xterm-addon-fit': path.join(__dirname, './node_modules/xterm-addon-fit/lib/xterm-addon-fit.js'), + 'xterm-addon-web-links': path.join(__dirname, './node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js'), + 'xterm-addon-search': path.join(__dirname, './node_modules/xterm-addon-search/lib/xterm-addon-search.js'), + + //socket + 'socketio': path.join(__dirname, './node_modules/socket.io-client/dist/socket.io.js'), + // Backbone and Backgrid 'backbone': path.join(__dirname, './node_modules/backbone/backbone'), 'backbone.undo': path.join(__dirname, './node_modules/backbone-undo/Backbone.Undo'), @@ -288,6 +297,8 @@ var webpackShimConfig = { 'pgadmin.tools.storage_manager': path.join(__dirname, './pgadmin/tools/storage_manager/static/js/storage_manager'), 'pgadmin.tools.erd_module': path.join(__dirname, './pgadmin/tools/erd/static/js/erd_module'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index e0b6fd69..3cc079f9 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -177,6 +177,7 @@ module.exports = { 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), 'tools': path.join(__dirname, './pgadmin/tools/'), 'pgadmin.user_management.current_user': regressionDir + '/javascript/fake_current_user', ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-18 15:11 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-05-18 15:11 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers Hi On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < [email protected]> wrote: > Hi Dave/Team, > > > On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Akshay/ Team, >>> >>> Please find the attached updated patch for the psql tool. >>> >> >> Hmm, this version is also broken. There's a typo in editor_template.html >> on line 138 - it splits a string across two lines which throws an error. >> Having fixed that... >> >> I also note there's a lot of Javascript in that HTML file. That should be >> pushed into the webpacked bundle I think, and not included inline in HTML. >> > I have moved most of the code in the js file, few things are still in HTML. > Hmm, yes - in particular, colours for the different themes. Please move them into the css for the themes. You have a mix of style, layout and code in this file which needs to be cleaned up. Speaking of themes, the background colour for selected text doesn't seem right (it's barely visible) in the dark theme. Can you fix that to match the colouring in the SQL text boxes please? > >> A couple of other things I noticed: >> >> - The button is enabled if the treeview has a Server selected. It could >> be argued that the query tool should do the same (defaulting to the >> maintenance database), however, that would be a separate change, and psql >> should be consistent with the query tool. >> > It is now consistent with the query tool. > >> >> - If I do a "select * from pg_class;" I still get: >> >> postgres=# select * from pg_class; >> WARNING: terminal is not fully functional >> > I am not able to reproduce the warning for the terminal (I am working on > Catalina 10.15.7), I checked on browsers (chrome, firefox, Safari) and also > checked on local nwjs runtime but still not able to reproduce the warning. > but found one limitation: > It looks like that can be fixed by adding: env={'TERM': 'xterm'} to the subprocess.Popen() call. I noticed while I was playing with that, that you are passing the password as part of the connection string. As I've mentioned in the past, that is absolutely not acceptable; it will expose the password to all manner of tools (such as ps -ef). You *must* pass the password to psql using the PGPASSWORD environment variable. > if we try to load data from the table containing millions of records, UI > gets very slow. > Is xtermjs discarding the older buffer contents when it fills up? Can you tell where the memory usage is? > >> - I'm sure using \q in the previous version displayed a message saying >> the session exited (the one on line 138 of editor_template.html). It no >> longer seems to do so. >> > In addition to the issue above, it looks like the \! blocking may have lost it's ability to ignore quoted strings: pgweb=# select '\!'; ERROR: Shell commands are disabled in psql for security > >> >>> >>> >>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> Hi Nikhil >>>>> >>>>> Following are the review comments: >>>>> >>>>> *GUI specific*: >>>>> >>>>> - We need a panel icon for PSQL like query tool, we can also add >>>>> that on the browser tree toolbar. >>>>> - PSQL Tool menu should be visible for all the child nodes of the >>>>> database node. Follow the same as Query Tool. >>>>> - PSQL tab title should be only database server name as the user >>>>> can change the database/user from PSQL command, so it's been difficult to >>>>> update the tab title. >>>>> - PSQL connection is still open even if we disconnect the database >>>>> server from the browser tree. >>>>> >>>>> *Code specific:* >>>>> >>>>> - Remove an extra space from requirements.txt and package.json >>>>> - Documentation needs to be updated to let the user know from >>>>> where the PSQL tool will open and on which node it is applicable. >>>>> - psql/__init__.py check there are so many unused imports please >>>>> remove them. >>>>> - We are not using cheroot so it should be removed from >>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>> - Test cases are showing successful but actually, there are some >>>>> routing errors please check. >>>>> >>>>> A few other things I noticed: >>>> >>>> - I was prompted to enter a password. This should be passed in the >>>> environment to psql as it is for pg_dump etc. >>>> - There seems to be an issue with terminal compatibility (which I >>>> didn't have on my prototype): >>>> >>>> ml=# select * from pg_class; >>>> WARNING: terminal is not fully functional >>>> -[ RECORD 1 ]-------+---------------------------------------------- >>>> oid | 79354 >>>> relname | housing >>>> ... >>>> >>>> - The panel should honour the styleguide. I'm running in dark mode, and >>>> see a jet black background. I would expect to see the same >>>> background/foreground colours as the treeview. >>>> - I spotted at least one print() statement that shouldn't be there >>>> (debug output should go through the logger) - psql/__init__.py:235 >>>> - This seems suspect - why would there be a password in a connection >>>> string we've built? And why would it be xxx? >>>> >>>> if 'password=xxx' in conn_attr: >>>> conn_attr = conn_attr.replace('password=xxx', '') >>>> >>>> - There's a thick white line at the bottom of the panel, where a >>>> horizontal scrollbar might be if there was one. >>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>> commands are disabled in psql for security;" >>>> >>>> Once we're happy with the patch in general, I'll do a string review >>>> before committing. In particular, I want to be sure the text in config.py >>>> is appropriately worded. >>>> >>>> This is shaping up nicely! Good work. >>>> >>>> >>>>> >>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave/ Team, >>>>>> >>>>>> PFA updated patch, sorry for the inconvenience, while cleanup I >>>>>> removed the unwanted libraries but forgot to remove the code related to >>>>>> them. >>>>>> >>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Hackers, >>>>>>>> >>>>>>>> Please find the attached patch for RM-2341 >>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option for >>>>>>>> starting PSQL. >>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>> 2. Added the same option for Server and Database nodes from the >>>>>>>> tree view. >>>>>>>> >>>>>>> >>>>>>> Unfortunately there's a trailing comma in package.json that makes it >>>>>>> invalid. If I fix that, then I get the error below, so I'm guessing the >>>>>>> intention was to actually include another package there? >>>>>>> >>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>> Module not found: Error: Can't resolve 'local-echo-controller' in >>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>> resolve 'local-echo-controller' in >>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>> Parsed request is a module >>>>>>> using description file: /Users/dpage/git/pgadmin4/web/package.json >>>>>>> (relative path: ./pgadmin/tools/psql/static/js) >>>>>>> aliased with mapping 'local-echo-controller': >>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>> using description file: >>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>> Field 'browser' doesn't contain a valid alias configuration >>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>> using description file: >>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>> no extension >>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>> configuration >>>>>>> >>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>> doesn't exist >>>>>>> .js >>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>> configuration >>>>>>> >>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>> doesn't exist >>>>>>> .jsx >>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>> configuration >>>>>>> >>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>> doesn't exist >>>>>>> as directory >>>>>>> >>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>> doesn't exist >>>>>>> using description file: >>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>> ./node_modules/local-echo) >>>>>>> no extension >>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>> configuration >>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>> doesn't exist >>>>>>> .js >>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>> configuration >>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>> doesn't exist >>>>>>> .jsx >>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>> configuration >>>>>>> >>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>> as directory >>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>> doesn't exist >>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>> >>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 ms >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>> >>>>>> Regards, >>>>>> Nikhil Mohite >>>>>> >>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> *pgAdmin Hacker | Principal Software Architect* >>>>> *EDB Postgres <http://edbpostgres.com>* >>>>> >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> Regards, >>> Nikhil Mohite >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> > > Regards, > Nikhil Mohite > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-19 07:58 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-05-19 07:58 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers Hi Dave/ Team, On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> wrote: > Hi > > On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < [email protected]> wrote: > Hi Dave/Team, > > > On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Akshay/ Team, >>> >>> Please find the attached updated patch for the psql tool. >>> >> >> Hmm, this version is also broken. There's a typo in editor_template.html >> on line 138 - it splits a string across two lines which throws an error. >> Having fixed that... >> >> I also note there's a lot of Javascript in that HTML file. That should be >> pushed into the webpacked bundle I think, and not included inline in HTML. >> > I have moved most of the code in the js file, few things are still in HTML. > Hmm, yes - in particular, colours for the different themes. Please move them into the css for the themes. You have a mix of style, layout and code in this file which needs to be cleaned up. xterm V3 onwards they have provided the API to set the theme and other settings, earlier I tried with CSS to override the theme but couldn’t able to apply the theme properly as some style get applied as in-line style for the HTML, so used the API to set the theme. > Speaking of themes, the background colour for selected text doesn't seem > right (it's barely visible) in the dark theme. Can you fix that to match > the colouring in the SQL text boxes please? > > >> >>> A couple of other things I noticed: >>> >>> - The button is enabled if the treeview has a Server selected. It could >>> be argued that the query tool should do the same (defaulting to the >>> maintenance database), however, that would be a separate change, and psql >>> should be consistent with the query tool. >>> >> It is now consistent with the query tool. >> >>> >>> - If I do a "select * from pg_class;" I still get: >>> >>> postgres=# select * from pg_class; >>> WARNING: terminal is not fully functional >>> >> I am not able to reproduce the warning for the terminal (I am working on >> Catalina 10.15.7), I checked on browsers (chrome, firefox, Safari) and also >> checked on local nwjs runtime but still not able to reproduce the warning. >> but found one limitation: >> > > It looks like that can be fixed by adding: > > env={'TERM': 'xterm'} > > to the subprocess.Popen() call. > > I noticed while I was playing with that, that you are passing the password > as part of the connection string. As I've mentioned in the past, that is > absolutely not acceptable; it will expose the password to all manner of > tools (such as ps -ef). You *must* pass the password to psql using the > PGPASSWORD environment variable. > > >> if we try to load data from the table containing millions of records, UI >> gets very slow. >> > > Is xtermjs discarding the older buffer contents when it fills up? Can you > tell where the memory usage is? > I checked the psql memory consumption in terminal and pgAdmin psql tool memory consumption is the similar. Also tested the performance and query execution timing is also similar. > > > >> >>> - I'm sure using \q in the previous version displayed a message saying >>> the session exited (the one on line 138 of editor_template.html). It no >>> longer seems to do so. >>> >> > In addition to the issue above, it looks like the \! blocking may have > lost it's ability to ignore quoted strings: > > pgweb=# select '\!'; > ERROR: Shell commands are disabled in psql for security > > >>> >>>> >>>> >>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Nikhil >>>>>> >>>>>> Following are the review comments: >>>>>> >>>>>> *GUI specific*: >>>>>> >>>>>> - We need a panel icon for PSQL like query tool, we can also add >>>>>> that on the browser tree toolbar. >>>>>> - PSQL Tool menu should be visible for all the child nodes of the >>>>>> database node. Follow the same as Query Tool. >>>>>> - PSQL tab title should be only database server name as the user >>>>>> can change the database/user from PSQL command, so it's been difficult to >>>>>> update the tab title. >>>>>> - PSQL connection is still open even if we disconnect the >>>>>> database server from the browser tree. >>>>>> >>>>>> *Code specific:* >>>>>> >>>>>> - Remove an extra space from requirements.txt and package.json >>>>>> - Documentation needs to be updated to let the user know from >>>>>> where the PSQL tool will open and on which node it is applicable. >>>>>> - psql/__init__.py check there are so many unused imports please >>>>>> remove them. >>>>>> - We are not using cheroot so it should be removed from >>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>> - Test cases are showing successful but actually, there are some >>>>>> routing errors please check. >>>>>> >>>>>> A few other things I noticed: >>>>> >>>>> - I was prompted to enter a password. This should be passed in the >>>>> environment to psql as it is for pg_dump etc. >>>>> - There seems to be an issue with terminal compatibility (which I >>>>> didn't have on my prototype): >>>>> >>>>> ml=# select * from pg_class; >>>>> WARNING: terminal is not fully functional >>>>> -[ RECORD 1 ]-------+---------------------------------------------- >>>>> oid | 79354 >>>>> relname | housing >>>>> ... >>>>> >>>>> - The panel should honour the styleguide. I'm running in dark mode, >>>>> and see a jet black background. I would expect to see the same >>>>> background/foreground colours as the treeview. >>>>> - I spotted at least one print() statement that shouldn't be there >>>>> (debug output should go through the logger) - psql/__init__.py:235 >>>>> - This seems suspect - why would there be a password in a connection >>>>> string we've built? And why would it be xxx? >>>>> >>>>> if 'password=xxx' in conn_attr: >>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>> >>>>> - There's a thick white line at the bottom of the panel, where a >>>>> horizontal scrollbar might be if there was one. >>>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>>> commands are disabled in psql for security;" >>>>> >>>>> Once we're happy with the patch in general, I'll do a string review >>>>> before committing. In particular, I want to be sure the text in config.py >>>>> is appropriately worded. >>>>> >>>>> This is shaping up nicely! Good work. >>>>> >>>>> >>>>>> >>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave/ Team, >>>>>>> >>>>>>> PFA updated patch, sorry for the inconvenience, while cleanup I >>>>>>> removed the unwanted libraries but forgot to remove the code related to >>>>>>> them. >>>>>>> >>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Hackers, >>>>>>>>> >>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option for >>>>>>>>> starting PSQL. >>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>> 2. Added the same option for Server and Database nodes from the >>>>>>>>> tree view. >>>>>>>>> >>>>>>>> >>>>>>>> Unfortunately there's a trailing comma in package.json that makes >>>>>>>> it invalid. If I fix that, then I get the error below, so I'm guessing the >>>>>>>> intention was to actually include another package there? >>>>>>>> >>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>> Module not found: Error: Can't resolve 'local-echo-controller' in >>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>> resolve 'local-echo-controller' in >>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>> Parsed request is a module >>>>>>>> using description file: >>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>> using description file: >>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>> Field 'browser' doesn't contain a valid alias configuration >>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>> using description file: >>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>> no extension >>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>> configuration >>>>>>>> >>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>> doesn't exist >>>>>>>> .js >>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>> configuration >>>>>>>> >>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>> doesn't exist >>>>>>>> .jsx >>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>> configuration >>>>>>>> >>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>> doesn't exist >>>>>>>> as directory >>>>>>>> >>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>> doesn't exist >>>>>>>> using description file: >>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>> ./node_modules/local-echo) >>>>>>>> no extension >>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>> configuration >>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>> doesn't exist >>>>>>>> .js >>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>> configuration >>>>>>>> >>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>> .jsx >>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>> configuration >>>>>>>> >>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>> as directory >>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>> doesn't exist >>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>> >>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 >>>>>>>> ms >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>> >>>>>>> Regards, >>>>>>> Nikhil Mohite >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> *Thanks & Regards* >>>>>> *Akshay Joshi* >>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>> >>>>>> *Mobile: +91 976-788-8246* >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> Regards, >>>> Nikhil Mohite >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >> >> Regards, >> Nikhil Mohite >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > Regards, Nikhil Mohite > <https://www.enterprisedb.com; > > -- *Thanks & Regards,* *Nikhil Mohite* *Software Engineer.* *EDB Postgres* <https://www.enterprisedb.com/; *Mob.No: +91-7798364578.* ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-19 08:13 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-05-19 08:13 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers Hi On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < [email protected]> wrote: > Hi Dave/ Team, > > On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Dave/Team, >> >> >> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Akshay/ Team, >>>> >>>> Please find the attached updated patch for the psql tool. >>>> >>> >>> Hmm, this version is also broken. There's a typo in editor_template.html >>> on line 138 - it splits a string across two lines which throws an error. >>> Having fixed that... >>> >>> I also note there's a lot of Javascript in that HTML file. That should >>> be pushed into the webpacked bundle I think, and not included inline in >>> HTML. >>> >> I have moved most of the code in the js file, few things are still in >> HTML. >> > > Hmm, yes - in particular, colours for the different themes. Please move > them into the css for the themes. You have a mix of style, layout and code > in this file which needs to be cleaned up. > xterm V3 onwards they have provided the API to set the theme and other > settings, earlier I tried with CSS to override the theme but couldn’t able > to apply the theme properly as some style get applied as in-line style for > the HTML, so used the API to set the theme. > OK, but either way we can't hard-code styles from themes in HTML templates for individual features; that way leads to madness. Perhaps Aditya or one of the other team members can give some assistance? > > >> Speaking of themes, the background colour for selected text doesn't seem >> right (it's barely visible) in the dark theme. Can you fix that to match >> the colouring in the SQL text boxes please? >> > >> >>> >>>> A couple of other things I noticed: >>>> >>>> - The button is enabled if the treeview has a Server selected. It could >>>> be argued that the query tool should do the same (defaulting to the >>>> maintenance database), however, that would be a separate change, and psql >>>> should be consistent with the query tool. >>>> >>> It is now consistent with the query tool. >>> >>>> >>>> - If I do a "select * from pg_class;" I still get: >>>> >>>> postgres=# select * from pg_class; >>>> WARNING: terminal is not fully functional >>>> >>> I am not able to reproduce the warning for the terminal (I am working on >>> Catalina 10.15.7), I checked on browsers (chrome, firefox, Safari) and also >>> checked on local nwjs runtime but still not able to reproduce the warning. >>> but found one limitation: >>> >> >> It looks like that can be fixed by adding: >> >> env={'TERM': 'xterm'} >> >> to the subprocess.Popen() call. >> >> I noticed while I was playing with that, that you are passing the >> password as part of the connection string. As I've mentioned in the past, >> that is absolutely not acceptable; it will expose the password to all >> manner of tools (such as ps -ef). You *must* pass the password to psql >> using the PGPASSWORD environment variable. >> >> >>> if we try to load data from the table containing millions of records, UI >>> gets very slow. >>> >> >> Is xtermjs discarding the older buffer contents when it fills up? Can you >> tell where the memory usage is? >> > I checked the psql memory consumption in terminal and pgAdmin psql tool > memory consumption is the similar. Also tested the performance and query > execution timing is also similar. > OK, so there's probably not much we can do here. > >> >> >>> >>>> - I'm sure using \q in the previous version displayed a message saying >>>> the session exited (the one on line 138 of editor_template.html). It no >>>> longer seems to do so. >>>> >>> >> In addition to the issue above, it looks like the \! blocking may have >> lost it's ability to ignore quoted strings: >> >> pgweb=# select '\!'; >> ERROR: Shell commands are disabled in psql for security >> > >> > >>>> >>>>> >>>>> >>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Nikhil >>>>>>> >>>>>>> Following are the review comments: >>>>>>> >>>>>>> *GUI specific*: >>>>>>> >>>>>>> - We need a panel icon for PSQL like query tool, we can also add >>>>>>> that on the browser tree toolbar. >>>>>>> - PSQL Tool menu should be visible for all the child nodes of >>>>>>> the database node. Follow the same as Query Tool. >>>>>>> - PSQL tab title should be only database server name as the user >>>>>>> can change the database/user from PSQL command, so it's been difficult to >>>>>>> update the tab title. >>>>>>> - PSQL connection is still open even if we disconnect the >>>>>>> database server from the browser tree. >>>>>>> >>>>>>> *Code specific:* >>>>>>> >>>>>>> - Remove an extra space from requirements.txt and package.json >>>>>>> - Documentation needs to be updated to let the user know from >>>>>>> where the PSQL tool will open and on which node it is applicable. >>>>>>> - psql/__init__.py check there are so many unused imports please >>>>>>> remove them. >>>>>>> - We are not using cheroot so it should be removed from >>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>> - Test cases are showing successful but actually, there are some >>>>>>> routing errors please check. >>>>>>> >>>>>>> A few other things I noticed: >>>>>> >>>>>> - I was prompted to enter a password. This should be passed in the >>>>>> environment to psql as it is for pg_dump etc. >>>>>> - There seems to be an issue with terminal compatibility (which I >>>>>> didn't have on my prototype): >>>>>> >>>>>> ml=# select * from pg_class; >>>>>> WARNING: terminal is not fully functional >>>>>> -[ RECORD 1 ]-------+---------------------------------------------- >>>>>> oid | 79354 >>>>>> relname | housing >>>>>> ... >>>>>> >>>>>> - The panel should honour the styleguide. I'm running in dark mode, >>>>>> and see a jet black background. I would expect to see the same >>>>>> background/foreground colours as the treeview. >>>>>> - I spotted at least one print() statement that shouldn't be there >>>>>> (debug output should go through the logger) - psql/__init__.py:235 >>>>>> - This seems suspect - why would there be a password in a connection >>>>>> string we've built? And why would it be xxx? >>>>>> >>>>>> if 'password=xxx' in conn_attr: >>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>> >>>>>> - There's a thick white line at the bottom of the panel, where a >>>>>> horizontal scrollbar might be if there was one. >>>>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>>>> commands are disabled in psql for security;" >>>>>> >>>>>> Once we're happy with the patch in general, I'll do a string review >>>>>> before committing. In particular, I want to be sure the text in config.py >>>>>> is appropriately worded. >>>>>> >>>>>> This is shaping up nicely! Good work. >>>>>> >>>>>> >>>>>>> >>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave/ Team, >>>>>>>> >>>>>>>> PFA updated patch, sorry for the inconvenience, while cleanup I >>>>>>>> removed the unwanted libraries but forgot to remove the code related to >>>>>>>> them. >>>>>>>> >>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Hackers, >>>>>>>>>> >>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option >>>>>>>>>> for starting PSQL. >>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>> 2. Added the same option for Server and Database nodes from the >>>>>>>>>> tree view. >>>>>>>>>> >>>>>>>>> >>>>>>>>> Unfortunately there's a trailing comma in package.json that makes >>>>>>>>> it invalid. If I fix that, then I get the error below, so I'm guessing the >>>>>>>>> intention was to actually include another package there? >>>>>>>>> >>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>> Module not found: Error: Can't resolve 'local-echo-controller' in >>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>> Parsed request is a module >>>>>>>>> using description file: >>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>> using description file: >>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>> Field 'browser' doesn't contain a valid alias configuration >>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>> using description file: >>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>> no extension >>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>> configuration >>>>>>>>> >>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>> doesn't exist >>>>>>>>> .js >>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>> configuration >>>>>>>>> >>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>> doesn't exist >>>>>>>>> .jsx >>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>> configuration >>>>>>>>> >>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>> doesn't exist >>>>>>>>> as directory >>>>>>>>> >>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>> doesn't exist >>>>>>>>> using description file: >>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>> ./node_modules/local-echo) >>>>>>>>> no extension >>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>> configuration >>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>> doesn't exist >>>>>>>>> .js >>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>> configuration >>>>>>>>> >>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>> .jsx >>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>> configuration >>>>>>>>> >>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>> as directory >>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>> doesn't exist >>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>> >>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in 60041 >>>>>>>>> ms >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>> >>>>>>>> Regards, >>>>>>>> Nikhil Mohite >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Thanks & Regards* >>>>>>> *Akshay Joshi* >>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>> >>>>>>> *Mobile: +91 976-788-8246* >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> Regards, >>>>> Nikhil Mohite >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>> >>> Regards, >>> Nikhil Mohite >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> > > > Regards, > Nikhil Mohite > >> <https://www.enterprisedb.com; >> >> -- > *Thanks & Regards,* > *Nikhil Mohite* > *Software Engineer.* > *EDB Postgres* <https://www.enterprisedb.com/; > *Mob.No: +91-7798364578.* > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-19 13:42 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-05-19 13:42 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers Hi Dave/ Team, On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> wrote: > Hi > > On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < > [email protected]> wrote: > >> Hi Dave/ Team, >> >> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Dave/Team, >>> >>> >>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Akshay/ Team, >>>>> >>>>> Please find the attached updated patch for the psql tool. >>>>> >>>> >>>> Hmm, this version is also broken. There's a typo in >>>> editor_template.html on line 138 - it splits a string across two lines >>>> which throws an error. Having fixed that... >>>> >>>> I also note there's a lot of Javascript in that HTML file. That should >>>> be pushed into the webpacked bundle I think, and not included inline in >>>> HTML. >>>> >>> I have moved most of the code in the js file, few things are still in >>> HTML. >>> >> >> Hmm, yes - in particular, colours for the different themes. Please move >> them into the css for the themes. You have a mix of style, layout and code >> in this file which needs to be cleaned up. >> xterm V3 onwards they have provided the API to set the theme and other >> settings, earlier I tried with CSS to override the theme but couldn’t able >> to apply the theme properly as some style get applied as in-line style for >> the HTML, so used the API to set the theme. >> > > OK, but either way we can't hard-code styles from themes in HTML templates > for individual features; that way leads to madness. > > Perhaps Aditya or one of the other team members can give some assistance? > I have moved the color settings to the respective theme files. Aditya helped in this. > > >> >> >>> Speaking of themes, the background colour for selected text doesn't seem >>> right (it's barely visible) in the dark theme. Can you fix that to match >>> the colouring in the SQL text boxes please? >>> >> I tried the default selection color from SQL for the dark and standard themes but still, it was not readable so just updated the color code with another color as follows. 1. Dark Theme: [image: Screenshot 2021-05-19 at 6.29.43 PM.png] 2. High Contrast: (using default SQL selection color) [image: Screenshot 2021-05-19 at 6.59.52 PM.png] 3. Standard: [image: image.png] can we go with the colors or should we update it? > >>> >>>> >>>>> A couple of other things I noticed: >>>>> >>>>> - The button is enabled if the treeview has a Server selected. It >>>>> could be argued that the query tool should do the same (defaulting to the >>>>> maintenance database), however, that would be a separate change, and psql >>>>> should be consistent with the query tool. >>>>> >>>> It is now consistent with the query tool. >>>> >>>>> >>>>> - If I do a "select * from pg_class;" I still get: >>>>> >>>>> postgres=# select * from pg_class; >>>>> WARNING: terminal is not fully functional >>>>> >>>> I am not able to reproduce the warning for the terminal (I am working >>>> on Catalina 10.15.7), I checked on browsers (chrome, firefox, Safari) and >>>> also checked on local nwjs runtime but still not able to reproduce the >>>> warning. but found one limitation: >>>> >>> >>> It looks like that can be fixed by adding: >>> >>> env={'TERM': 'xterm'} >>> >> Added this in the environment when opening the psql panel. > >>> to the subprocess.Popen() call. >>> >>> I noticed while I was playing with that, that you are passing the >>> password as part of the connection string. As I've mentioned in the past, >>> that is absolutely not acceptable; it will expose the password to all >>> manner of tools (such as ps -ef). You *must* pass the password to psql >>> using the PGPASSWORD environment variable. >>> >>> >>>> if we try to load data from the table containing millions of records, >>>> UI gets very slow. >>>> >>> Removed the password from the connection string and added 'PGPASSWORD' in the environment. > >>> Is xtermjs discarding the older buffer contents when it fills up? Can >>> you tell where the memory usage is? >>> >> I checked the psql memory consumption in terminal and pgAdmin psql tool >> memory consumption is the similar. Also tested the performance and query >> execution timing is also similar. >> > > OK, so there's probably not much we can do here. > > >> >>> >>> >>>> >>>>> - I'm sure using \q in the previous version displayed a message saying >>>>> the session exited (the one on line 138 of editor_template.html). It no >>>>> longer seems to do so. >>>>> >>>> >>> In addition to the issue above, it looks like the \! blocking may have >>> lost it's ability to ignore quoted strings: >>> >>> pgweb=# select '\!'; >>> ERROR: Shell commands are disabled in psql for security >>> >> Fixed the issue now it is consistent with the psql terminal. > >>> >> >>>>> >>>>>> >>>>>> >>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Nikhil >>>>>>>> >>>>>>>> Following are the review comments: >>>>>>>> >>>>>>>> *GUI specific*: >>>>>>>> >>>>>>>> - We need a panel icon for PSQL like query tool, we can also >>>>>>>> add that on the browser tree toolbar. >>>>>>>> - PSQL Tool menu should be visible for all the child nodes of >>>>>>>> the database node. Follow the same as Query Tool. >>>>>>>> - PSQL tab title should be only database server name as the >>>>>>>> user can change the database/user from PSQL command, so it's been difficult >>>>>>>> to update the tab title. >>>>>>>> - PSQL connection is still open even if we disconnect the >>>>>>>> database server from the browser tree. >>>>>>>> >>>>>>>> *Code specific:* >>>>>>>> >>>>>>>> - Remove an extra space from requirements.txt and package.json >>>>>>>> - Documentation needs to be updated to let the user know from >>>>>>>> where the PSQL tool will open and on which node it is applicable. >>>>>>>> - psql/__init__.py check there are so many unused imports >>>>>>>> please remove them. >>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>> - Test cases are showing successful but actually, there are >>>>>>>> some routing errors please check. >>>>>>>> >>>>>>>> A few other things I noticed: >>>>>>> >>>>>>> - I was prompted to enter a password. This should be passed in the >>>>>>> environment to psql as it is for pg_dump etc. >>>>>>> - There seems to be an issue with terminal compatibility (which I >>>>>>> didn't have on my prototype): >>>>>>> >>>>>>> ml=# select * from pg_class; >>>>>>> WARNING: terminal is not fully functional >>>>>>> -[ RECORD 1 ]-------+---------------------------------------------- >>>>>>> oid | 79354 >>>>>>> relname | housing >>>>>>> ... >>>>>>> >>>>>>> - The panel should honour the styleguide. I'm running in dark mode, >>>>>>> and see a jet black background. I would expect to see the same >>>>>>> background/foreground colours as the treeview. >>>>>>> - I spotted at least one print() statement that shouldn't be there >>>>>>> (debug output should go through the logger) - psql/__init__.py:235 >>>>>>> - This seems suspect - why would there be a password in a connection >>>>>>> string we've built? And why would it be xxx? >>>>>>> >>>>>>> if 'password=xxx' in conn_attr: >>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>> >>>>>>> - There's a thick white line at the bottom of the panel, where a >>>>>>> horizontal scrollbar might be if there was one. >>>>>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>>>>> commands are disabled in psql for security;" >>>>>>> >>>>>>> Once we're happy with the patch in general, I'll do a string review >>>>>>> before committing. In particular, I want to be sure the text in config.py >>>>>>> is appropriately worded. >>>>>>> >>>>>>> This is shaping up nicely! Good work. >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Dave/ Team, >>>>>>>>> >>>>>>>>> PFA updated patch, sorry for the inconvenience, while cleanup I >>>>>>>>> removed the unwanted libraries but forgot to remove the code related to >>>>>>>>> them. >>>>>>>>> >>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Hackers, >>>>>>>>>>> >>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option >>>>>>>>>>> for starting PSQL. >>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>> 2. Added the same option for Server and Database nodes from the >>>>>>>>>>> tree view. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Unfortunately there's a trailing comma in package.json that makes >>>>>>>>>> it invalid. If I fix that, then I get the error below, so I'm guessing the >>>>>>>>>> intention was to actually include another package there? >>>>>>>>>> >>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>> Module not found: Error: Can't resolve 'local-echo-controller' in >>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>> Parsed request is a module >>>>>>>>>> using description file: >>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>> using description file: >>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>> configuration >>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>> using description file: >>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>> no extension >>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>> configuration >>>>>>>>>> >>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>> doesn't exist >>>>>>>>>> .js >>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>> configuration >>>>>>>>>> >>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>> doesn't exist >>>>>>>>>> .jsx >>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>> configuration >>>>>>>>>> >>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>> doesn't exist >>>>>>>>>> as directory >>>>>>>>>> >>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>> doesn't exist >>>>>>>>>> using description file: >>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>> no extension >>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>> configuration >>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>> doesn't exist >>>>>>>>>> .js >>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>> configuration >>>>>>>>>> >>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>> .jsx >>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>> configuration >>>>>>>>>> >>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>> as directory >>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>> doesn't exist >>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>> >>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in >>>>>>>>>> 60041 ms >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> Nikhil Mohite >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> *Thanks & Regards* >>>>>>>> *Akshay Joshi* >>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>> >>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> Regards, >>>>>> Nikhil Mohite >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>> >>>> Regards, >>>> Nikhil Mohite >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >> >> >> Regards, >> Nikhil Mohite >> >>> <https://www.enterprisedb.com; >>> >>> -- >> *Thanks & Regards,* >> *Nikhil Mohite* >> *Software Engineer.* >> *EDB Postgres* <https://www.enterprisedb.com/; >> *Mob.No: +91-7798364578.* >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > Regards, Nikhil Mohite Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [application/octet-stream] RM_2341_V5.patch (354.0K, 6-RM_2341_V5.patch) download | inline diff: diff --git a/docs/en_US/developer_tools.rst b/docs/en_US/developer_tools.rst index 1ff442cc..bb67e33a 100644 --- a/docs/en_US/developer_tools.rst +++ b/docs/en_US/developer_tools.rst @@ -16,3 +16,4 @@ PL/SQL code. editgrid schema_diff erd_tool + psql_tool diff --git a/docs/en_US/images/psql_tool.png b/docs/en_US/images/psql_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f88ba5a573aa60bf7e08b8a38526dc73e8fcd5 GIT binary patch literal 23736 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 P=p;Q)S3j3^P6<r_JTn~) literal 0 HcmV?d00001 diff --git a/docs/en_US/images/psql_tool_menu.png b/docs/en_US/images/psql_tool_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..c219a0787868bd9427cfc056ce18c9ab562e52bd GIT binary patch literal 187181 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 literal 0 HcmV?d00001 diff --git a/docs/en_US/psql_tool.rst b/docs/en_US/psql_tool.rst new file mode 100644 index 00000000..8791648a --- /dev/null +++ b/docs/en_US/psql_tool.rst @@ -0,0 +1,23 @@ +.. _psql_tool: + +****************** +`PSQL Tool`:index: +****************** + +PSQL tool allows user to connect to PostgreSQL server using psql terminal. + +* Open PSQL Tool from Tools menu or context menu PSQL Tool from tree view. + +.. image:: images/psql_tool_menu.png + :alt: PSQL tool menu + :align: center + +* execute all type of commands. + +.. image:: images/psql_tool.png + :alt: PSQL tool window + :align: center + +You can open multiple instance of the PSQL tool in individual tabs simultaneously. +To close the PSQL tool, click the *X* in the upper-right hand corner of the tab bar. + diff --git a/requirements.txt b/requirements.txt index edd7000b..8227a4c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,6 @@ # ############################################################################### -cheroot==8.* Flask==1.* Flask-Gravatar==0.* Flask-Login==0.* @@ -36,3 +35,5 @@ sshtunnel==0.* ldap3==2.* Flask-BabelEx==0.* gssapi==1.6.* +flask-socketio>=5.0.1 +eventlet==0.30.2 diff --git a/web/config.py b/web/config.py index 2643ef19..002a9951 100644 --- a/web/config.py +++ b/web/config.py @@ -156,8 +156,8 @@ X_FRAME_OPTIONS = "SAMEORIGIN" # such as JavaScript, CSS, or pretty much anything that the browser loads. # see https://content-security-policy.com/#source_list for more info # e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';" -CONTENT_SECURITY_POLICY = "default-src http: data: blob: 'unsafe-inline' " \ - "'unsafe-eval';" +CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \ + " 'unsafe-eval';" # STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the # Strict-Transport-Security header @@ -636,6 +636,19 @@ KRB_AUTO_CREATE_USER = True KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache') +# PSQL tool settings +# This will enable PSQL tool in pgAdmin. So user can execute the commands using +# PSQL terminal in pgAdmin. +ENABLE_PSQL = True + +# ALLOW_PSQL_SHELL_COMMAND = True will disable the execution of os level +# commands using meta command \! from PSQL terminal. +# As PSQL allow user to execute the os level commands from the PSQL terminal +# user can execute any system level command as per the system login user +# privileges. Default this setting is set to False but if it set to True +# User will able to execute the system level commands through PSQL terminal in +# pgAdmin. +ALLOW_PSQL_SHELL_COMMANDS = False ########################################################################## # Local config settings diff --git a/web/package.json b/web/package.json index 8ed32df9..19110fda 100644 --- a/web/package.json +++ b/web/package.json @@ -117,13 +117,18 @@ "shim-loader": "^1.0.1", "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16", "snapsvg-cjs": "^0.0.6", + "socket.io-client": "^4.0.0", "split.js": "^1.5.10", "tablesorter": "^2.31.2", "tempusdominus-bootstrap-4": "^5.1.2", "tempusdominus-core": "^5.0.3", "underscore": "^1.13.1", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36", - "wkx": "^0.5.0" + "wkx": "^0.5.0", + "xterm": "^4.11.0", + "xterm-addon-fit": "^0.5.0", + "xterm-addon-search": "^0.8.0", + "xterm-addon-web-links": "^0.4.0" }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index d2bd1af6..dc1924cb 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -13,7 +13,7 @@ to start a web server.""" import sys -from cheroot.wsgi import Server as CherootServer + if sys.version_info < (3, 4): raise RuntimeError('This application must be run under Python 3.4 ' @@ -37,7 +37,7 @@ else: builtins.SERVER_MODE = None import config -from pgadmin import create_app +from pgadmin import create_app, socketio from pgadmin.utils import u_encode, fs_encoding, file_quote from pgadmin.utils.constants import INTERNAL # Get the config database schema version. We store this in pgadmin.model @@ -97,6 +97,8 @@ if not os.path.isfile(config.SQLITE_PATH): ########################################################################## app = create_app() app.debug = False +app.config['sessions'] = dict() + if config.SERVER_MODE: app.wsgi_app = ReverseProxied(app.wsgi_app) @@ -206,17 +208,16 @@ def main(): else: # Can use cheroot instead of flask dev server when not in debug # 10 is default thread count in CherootServer - num_threads = 10 if config.THREADED_MODE else 1 - prod_server = CherootServer( - (config.DEFAULT_SERVER, config.EFFECTIVE_SERVER_PORT), - wsgi_app=app, - numthreads=num_threads, - server_name=config.APP_NAME) + # num_threads = 10 if config.THREADED_MODE else 1 try: - print("Using production server...") - prod_server.start() + socketio.run( + app, + host=config.DEFAULT_SERVER, + port=config.EFFECTIVE_SERVER_PORT, + ) except KeyboardInterrupt: - prod_server.stop() + print("CLOSE SERVER") + socketio.stop() except IOError: app.logger.error("Error starting the app server: %s", sys.exc_info()) diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index a7333537..fad91082 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -19,6 +19,7 @@ from collections import defaultdict from importlib import import_module from flask import Flask, abort, request, current_app, session, url_for +from flask_socketio import SocketIO from werkzeug.exceptions import HTTPException from flask_babelex import Babel, gettext from flask_babelex import gettext as _ @@ -52,10 +53,15 @@ import mimetypes mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('text/css', '.css') + winreg = None if os.name == 'nt': import winreg +socketio = SocketIO(manage_session=False, async_mode='eventlet', + logger=False, engineio_logger=False, debug=False, + ping_interval=25, ping_timeout=120) + class PgAdmin(Flask): def __init__(self, *args, **kwargs): @@ -811,4 +817,5 @@ def create_app(app_name=None): ########################################################################## # All done! ########################################################################## + socketio.init_app(app) return app diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 235db027..d835ca82 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -10,6 +10,7 @@ from flask_babelex import gettext from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\ PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \ PREF_LABEL_OPTIONS +from flask_security import current_user import config LOCK_LAYOUT_LEVEL = { @@ -511,10 +512,12 @@ def register_browser_preferences(self): options=[{'label': gettext('Query Tool'), 'value': 'qt'}, {'label': gettext('Debugger'), 'value': 'debugger'}, {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], - help_str=gettext('Select Query Tool, Debugger, or Schema Diff from ' - 'the drop-down to set open in new browser tab for ' - 'that particular module.'), + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext('Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), select2={ 'multiple': True, 'allowClear': False, 'tags': True, 'first_empty': False, @@ -523,3 +526,16 @@ def register_browser_preferences(self): 'placeholder': gettext('Select open new tab...') } ) + + self.psql_tab_title = self.preference.register( + 'tab_settings', 'psql_tab_title_placeholder', + gettext("PSQL tool tab title"), + 'text', '%DATABASE%/%USERNAME%@%SERVER%', + category_label=PREF_LABEL_DISPLAY, + help_str=gettext( + 'Supported placeholders are %DATABASE%, %USERNAME%, and %SERVER%. ' + 'Users can provide any string with or without placeholders of' + ' their choice. The blank title will be revert back to the' + ' default title with placeholders.' + ) + ) diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index f4165c32..fb7ff12c 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -34,6 +34,7 @@ from pgadmin.utils.constants import UNAUTH_REQ, MIMETYPE_APP_JS, \ SERVER_CONNECTION_CLOSED from sqlalchemy import or_ from pgadmin.utils.preferences import Preferences +from .... import socketio as sio def has_any(data, keys): @@ -1499,6 +1500,13 @@ class ServerNode(PGChildNodeView): # Release Connection manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + # Check if any psql terminal is running for the current disconnecting + # server. If any terminate the psql tool connection. + if 'sid_soid_mapping' in current_app.config and str(sid) in \ + current_app.config['sid_soid_mapping']: + if str(sid) in current_app.config['sid_soid_mapping']: + for i in current_app.config['sid_soid_mapping'][str(sid)]: + sio.emit('disconnect-psql', namespace='/pty', to=i) status = manager.release() diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 01ab89c5..eb20cac5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -122,6 +122,9 @@ define('pgadmin.node.database', [ is_connected: function(node) { return (node && node.connected == true && node.canDisconn == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, is_conn_allow: function(node) { return (node && node.allowConn == true); }, diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 45dea090..ffd715f8 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -101,7 +101,8 @@ define('pgadmin.node.server', [ icon: 'fa fa-unlink', enable : 'is_connected',data: { data_disabled: gettext('Database is already disconnected.'), }, - },{ + }, + { name: 'reload_configuration', node: 'server', module: this, applies: ['tools', 'context'], callback: 'reload_configuration', category: 'reload', priority: 6, label: gettext('Reload Configuration'), @@ -728,6 +729,14 @@ define('pgadmin.node.server', [ return false; }, + /* Open psql tool for server*/ + server_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + } }, model: pgAdmin.Browser.Node.Model.extend({ defaults: { diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index 3823ef35..e763aa11 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -64,6 +64,14 @@ define([ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', }]); + + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); } } }, @@ -498,6 +506,13 @@ define([ pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); } }, + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, }); return pgBrowser.Collection; diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index 1c5af3f5..23585dbe 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -209,6 +209,14 @@ define('pgadmin.browser.node', [ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', enable: enable, }]); + + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); } // This will add options of scripts eg:'CREATE Script' @@ -902,6 +910,15 @@ define('pgadmin.browser.node', [ pgAdmin.DataGrid.show_query_tool('', i); }, + // Callback to render psql tool. + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, + // Logic to change the server background colour // There is no way of applying CSS to parent element so we have to // do it via JS code only diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js index c9e64132..3068aabe 100644 --- a/web/pgadmin/browser/static/js/panel.js +++ b/web/pgadmin/browser/static/js/panel.js @@ -122,10 +122,30 @@ define( myPanel.on(ev, that.handleVisibility.bind(myPanel, ev)); }); } + + // Listen on detach panel event + myPanel.on(wcDocker.EVENT.DETACHED, function(obj) { + that.setCodeMirrorHeight(obj); + }); }, }); } }, + setCodeMirrorHeight: function() { + // Fix for mac os code-mirror showing black screen. + var txtArea = $('.pg-panel-content .sql_textarea > textarea').first(); + txtArea.css('z-index', -1); + var $tabContent = $('.pg-panel-content > .sql_textarea').first(); + var $sqlPane = $tabContent.find('.CodeMirror > div > textarea'); + for(let i=0; i<$sqlPane.length; i++) {$($sqlPane[i]).css('z-index', -1);} + + $tabContent = $('.pg-panel-content > .sql_textarea').first(); + $sqlPane = $tabContent.find('.pg-panel-content'); + $sqlPane.find('.CodeMirror').css( + 'cssText', + 'height: ' + ($tabContent.height()) + 'px !important;' + ); + }, eventFunc: function(eventName) { var name = $(this).data('pgAdminName'); diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index 09baaf22..90d2d007 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -56,6 +56,15 @@ let _defaultToolBarButtons = [ toggleClass: '', parentClass: 'pg-toolbar-btn btn-primary-icon', enabled: false, + },{ + label: gettext('PSQL Tool'), + ariaLabel: gettext('PSQL Tool'), + btnClass: 'fas fa-terminal', + text: '', + toggled: false, + toggleClass: '', + parentClass: 'pg-toolbar-btn btn-primary-icon pg-toolbar-psql', + enabled: false, }, ]; @@ -105,6 +114,13 @@ export function initializeToolbar(panel, wcDocker) { pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected()); else if ('name' in data && data.name === gettext('Search objects')) pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); + else if ('name' in data && data.name === gettext('PSQL Tool')){ + var input = {}, + t = pgAdmin.Browser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgAdmin.Browser.psql.psql_tool(d, i, true); + } }); } diff --git a/web/pgadmin/browser/static/scss/_browser.scss b/web/pgadmin/browser/static/scss/_browser.scss index 0d157384..ae72f0e6 100644 --- a/web/pgadmin/browser/static/scss/_browser.scss +++ b/web/pgadmin/browser/static/scss/_browser.scss @@ -53,3 +53,9 @@ samp, border-width: 1px; font-size: 1.15em; } + +.pg-toolbar-psql { + padding-top: 0em; + font-size: inherit; + align-items: center; +} diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 8597df48..b0a317a5 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -52,6 +52,10 @@ define('pgadmin.browser.utils', pgAdmin['user_inactivity_timeout'] = {{ current_app.config.get('USER_INACTIVITY_TIMEOUT') }}; pgAdmin['override_user_inactivity_timeout'] = '{{ current_app.config.get('OVERRIDE_USER_INACTIVITY_TIMEOUT') }}' == 'True'; + /* GET PSQL Tool related config */ + pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; + // Define list of nodes on which Query tool option doesn't appears var unsupported_nodes = pgAdmin.unsupported_nodes = [ 'server_group', 'server', 'coll-tablespace', 'tablespace', diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py index 312b0ee1..5e22f2d5 100644 --- a/web/pgadmin/browser/utils.py +++ b/web/pgadmin/browser/utils.py @@ -62,7 +62,8 @@ def underscore_unescape(text): ">": '>', """: '"', "`": '`', - "'": "'" + "'": "'", + "'": "'" } # always replace & first diff --git a/web/pgadmin/static/bundle/browser.js b/web/pgadmin/static/bundle/browser.js index 14140a2f..0b3ad81b 100644 --- a/web/pgadmin/static/bundle/browser.js +++ b/web/pgadmin/static/bundle/browser.js @@ -11,6 +11,7 @@ define('bundled_browser',[ 'pgadmin.browser', 'sources/browser/index', 'top/tools/erd/static/js/index', + 'top/tools/psql/static/js/index', ], function(pgBrowser) { pgBrowser.init(); }); diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css index c2a776c8..5b4a9f2d 100644 --- a/web/pgadmin/static/css/style.css +++ b/web/pgadmin/static/css/style.css @@ -21,3 +21,5 @@ @import '../vendor/backgrid/backgrid.css'; @import '../vendor/backgrid/backgrid-select-all.css'; + +@import 'node_modules/xterm/css/xterm.css'; diff --git a/web/pgadmin/static/scss/pgadmin.scss b/web/pgadmin/static/scss/pgadmin.scss index 6c38c6f7..2e5bc6d9 100644 --- a/web/pgadmin/static/scss/pgadmin.scss +++ b/web/pgadmin/static/scss/pgadmin.scss @@ -10,6 +10,11 @@ $theme-colors: ( --color-fg: #{$color-fg}; --color-bg: #{$color-bg}; --border-color: #{$border-color}; + --psql-background: #{$psql-background}; + --psql-foreground: #{$psql-foreground}; + --psql-cursor: #{$psql-cursor}; + --psql-cursorAccent: #{$psql-cursorAccent}; + --psql-selection: #{$psql-selection}; } @import "bootstrap/scss/bootstrap"; diff --git a/web/pgadmin/static/scss/resources/_default.variables.scss b/web/pgadmin/static/scss/resources/_default.variables.scss index ce33424e..d9fb6653 100644 --- a/web/pgadmin/static/scss/resources/_default.variables.scss +++ b/web/pgadmin/static/scss/resources/_default.variables.scss @@ -371,3 +371,10 @@ $erd-link-selected-color: $color-fg !default; $erd-bg-grid: url("data:image/svg+xml, %3Csvg width='100%25' viewBox='0 0 45 45' style='background-color:#{url-friendly-colour($erd-canvas-bg)}' height='100%25' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cpattern id='smallGrid' width='15' height='15' patternUnits='userSpaceOnUse'%3E%3Cpath d='M 15 0 L 0 0 0 15' fill='none' stroke='#{url-friendly-colour($erd-canvas-grid)}' stroke-width='0.5'/%3E%3C/pattern%3E%3Cpattern id='grid' width='45' height='45' patternUnits='userSpaceOnUse'%3E%3Crect width='100' height='100' fill='url(%23smallGrid)'/%3E%3Cpath d='M 100 0 L 0 0 0 100' fill='none' stroke='#{url-friendly-colour($erd-canvas-grid)}' stroke-width='1'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='100%25' height='100%25' fill='url(%23grid)' /%3E%3C/svg%3E%0A"); $select2-readonly: $color-gray-lighter !default; + +// psql tool variables +$psql-background: $color-bg !default; +$psql-foreground: $color-fg !default; +$psql-cursor: $color-fg !default; +$psql-cursorAccent: $color-fg !default; +$psql-selection: #326690 !default; diff --git a/web/pgadmin/static/scss/resources/dark/_theme.variables.scss b/web/pgadmin/static/scss/resources/dark/_theme.variables.scss index efa36df8..2fa907b8 100644 --- a/web/pgadmin/static/scss/resources/dark/_theme.variables.scss +++ b/web/pgadmin/static/scss/resources/dark/_theme.variables.scss @@ -136,3 +136,10 @@ $erd-link-color: $color-fg; $erd-link-selected-color: $color-fg; $select2-readonly: $color-bg; + +// psql tool variables +$psql-background: $color-bg; +$psql-foreground: $color-fg; +$psql-cursor: $color-fg; +$psql-cursorAccent: $color-fg; +$psql-selection: #d6effc; diff --git a/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss b/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss index 682f2622..b4783bce 100644 --- a/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss +++ b/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss @@ -207,3 +207,10 @@ $quick-search-a-text-color: $black !default; $quick-search-info-icon: #8A8A8A !default; $select2-readonly: $color-gray; + +// psql tool variables +$psql-background: $color-bg; +$psql-foreground: $color-fg; +$psql-cursor: $color-fg; +$psql-cursorAccent: $color-fg; +$psql-selection: $color-primary-light; diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js index 1348cc45..42efc04d 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js @@ -100,6 +100,10 @@ export function generateTitle(title_placeholder, title_data) { title_placeholder = title_placeholder.replace(new RegExp('%ARGS%'), _.unescape(title_data.args)); title_placeholder = title_placeholder.replace(new RegExp('%SCHEMA%'), _.unescape(title_data.schema)); title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + } else if(title_data.type == 'psql_tool') { + title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + title_placeholder = title_placeholder.replace(new RegExp('%USERNAME%'), _.unescape(title_data.username)); + title_placeholder = title_placeholder.replace(new RegExp('%SERVER%'), _.unescape(title_data.server)); } return _.escape(title_placeholder); diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py new file mode 100644 index 00000000..2dde39a7 --- /dev/null +++ b/web/pgadmin/tools/psql/__init__.py @@ -0,0 +1,606 @@ +#!/usr/bin/env python3 +import fcntl +import os +import pty +import re +import select +import struct +import termios +import config +import eventlet.green.subprocess as subprocess + +from config import PG_DEFAULT_DRIVER +from flask import Response, url_for, request +from flask import render_template, copy_current_request_context, \ + current_app as app +from flask_babelex import gettext +from flask_security import login_required, current_user +from pgadmin.browser.utils import underscore_unescape +from pgadmin.utils import PgAdminModule +from pgadmin.utils.constants import MIMETYPE_APP_JS +from pgadmin.utils.driver import get_driver +from ... import socketio as sio +from pgadmin.utils import get_complete_file_path + + +session_input = dict() +session_input_cursor = dict() +session_last_cmd = dict() +pdata = dict() +cdata = dict() + + +class PSQLModule(PgAdminModule): + """ + class PSQLModule(PgAdminModule) + A module class for PSQL derived from PgAdminModule. + """ + + LABEL = gettext("PSQL") + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.psql', + 'path': url_for('psql.index') + "psql", + 'when': None + }] + + def get_panels(self): + return [] + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints for PSQL module + """ + return [ + 'psql.panel' + ] + + +blueprint = PSQLModule('psql', __name__, static_url_path='/static') + + [email protected]("/psql.js") +@login_required +def script(): + """render the required javascript""" + return Response( + response=render_template("psql/js/psql.js", _=gettext), + status=200, + mimetype=MIMETYPE_APP_JS + ) + + [email protected]('/panel/<int:trans_id>', + methods=["POST"], + endpoint="panel") +@login_required +def panel(trans_id): + """ + Return panel template for PSQL tools. + :param trans_id: + """ + params = { + 'trans_id': trans_id, + 'title': request.form['title'] + } + if 'sid_soid_mapping' not in app.config: + app.config['sid_soid_mapping'] = dict() + if request.args: + params.update({k: v for k, v in request.args.items()}) + # Set TERM env for xterm. + os.environ['TERM'] = 'xterm' + + return render_template('editor_template.html', + sid=params['sid'], + db=underscore_unescape(params['db']) if params[ + 'db'] else 'postgres', + server_type=params['server_type'], + is_enable=config.ENABLE_PSQL, + title=underscore_unescape(params['title']), + theme=params['theme'] + ) + + +def set_term_size(fd, row, col, xpix=0, ypix=0): + """ + Set the terminal size as per UI xterm size. + :param fd: + :param row: + :param col: + :param xpix: + :param ypix: + """ + term_size = struct.pack('HHHH', row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) + + [email protected]('connect', namespace='/pty') +def connect(): + """ + Connect to the server through socket. + :return: + :rtype: + """ + if config.ENABLE_PSQL: + sio.emit('connected', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + if request.sid in session_last_cmd: + session_last_cmd[request.sid]['is_new_connection'] = False + else: + session_last_cmd[request.sid] = {'cmd': '', 'arrow_up': False, + 'invalid_cmd': False, + 'is_new_connection': False} + else: + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + [email protected]('start_process', namespace='/pty') +def start_process(data): + """ + Start the pty terminal and execute psql command and emit results to user. + :param data: + :return: + """ + + @copy_current_request_context + def read_and_forward_pty_output(sid, data): + max_read_bytes = 1024 * 20 + # Create the pty terminal process, parent and fd are file descriptors + # for parent and child. + parent, fd = pty.openpty() + p = None + if parent is not None: + # Child process + p = subprocess.Popen(connection_data, + preexec_fn=os.setsid, + stdin=fd, + stdout=fd, + stderr=fd, + universal_newlines=True + ) + + app.config['sessions'][request.sid] = parent + pdata[request.sid] = p + cdata[request.sid] = fd + else: + app.config['sessions'][request.sid] = parent + cdata[request.sid] = fd + set_term_size(fd, 50, 50) + + while p and p.poll() is None: + if request.sid in app.config['sessions']: + # This code is added to make this unit testable. + if "is_test" not in data: + sio.sleep(0.01) + else: + data['count'] += 1 + if data['count'] == 5: + break + + timeout = 0 + # module provides access to platform-specific I/O + # monitoring functions + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) + + if parent in data_ready: + # Read the output from parent fd (terminal). + output = os.read(parent, max_read_bytes) + emit_output = True + + if sid in session_last_cmd and session_last_cmd[sid][ + 'arrow_up'] and not session_last_cmd[request.sid][ + 'arrow_left_right']: + session_last_cmd[sid]['cmd'] = output.decode() + session_input_cursor[request.sid] = len( + session_last_cmd[sid]['cmd']) + session_last_cmd[sid]['arrow_up'] = True + + if sid in session_last_cmd: + # If command is invalid then emit error to user. + if session_last_cmd[sid]['invalid_cmd']: + emit_output = False + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security\r\n"), + 'error': True + }, + namespace='/pty', room=sid) + # If command is valid then emit output to user. + if emit_output: + sio.emit('pty-output', + {'result': output.decode(), + 'error': False}, + namespace='/pty', room=sid) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + + # Check user is authenticated and PSQL is enabled in config. + if current_user.is_authenticated and config.ENABLE_PSQL: + connection_data = [] + try: + db = '' + if data['db']: + db = underscore_unescape(data['db']).replace('\\', "\\\\") + + conn, manager = _get_connection(int(data['sid']), data) + psql_utility = manager.utility('sql') + connection_data = get_connection_str(psql_utility, db, + manager) + except Exception as e: + # If any error raised during the start the PSQL emit error to UI. + # request.sid: This sid is socket id. + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + + try: + if str(data['sid']) not in app.config['sid_soid_mapping']: + # request.sid: refer request.sid as socket id. + app.config['sid_soid_mapping'][str(data['sid'])] = list() + app.config['sid_soid_mapping'][str(data['sid'])].append( + request.sid) + else: + app.config['sid_soid_mapping'][str(data['sid'])].append( + request.sid) + + sio.start_background_task(read_and_forward_pty_output, + request.sid, data) + except Exception as e: + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + else: + # Show error if user is not authenticated. + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def _get_connection(sid, data): + """ + Get the connection object of ERD. + :param sid: + :param did: + :param trans_id: + :return: + """ + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + try: + conn = manager.connection() + # This is added for unit test only, no use in normal execution. + if 'pwd' in data: + kwargs = {'password': data['pwd'], "user": data['user']} + status, msg = conn.connect(**kwargs) + else: + status, msg = conn.connect() + if not status: + app.logger.error(msg) + sio.emit(sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}' + ''.format('Server connection not present.'), + }, namespace='/pty', room=request.sid)) + raise Exception('Server is not connected.') + + return conn, manager + except Exception as e: + app.logger.error(e) + raise + + +def get_connection_str(psql_utility, db, manager): + """ + Get connection string(through connection dsn) + :param psql_utility: PostgreSQL binary path. + :param db: database name to connect specific db. + :return: connection attribute list for PSQL connection. + """ + conn_attr = get_conn_str(manager, db) + conn_attr_list = list() + conn_attr_list.append(psql_utility) + conn_attr_list.append(conn_attr) + return conn_attr_list + + +def get_conn_str(manager, db): + """ + Get connection attributes for psql connection. + :param manager: + :param db: + :return: + """ + manager.export_password_env('PGPASSWORD') + conn_attr =\ + "host={0} port={1} dbname={2} user={3} sslmode={4} " \ + "sslcompression={5} " \ + "".format( + manager.local_bind_host if manager.use_ssh_tunnel else + manager.host, + manager.local_bind_port if manager.use_ssh_tunnel else + manager.port, + db if db != '' else 'postgres', + manager.user if manager.user else 'postgres', + manager.ssl_mode, + True if manager.sslcompression else False, + ) + + if manager.hostaddr: + conn_attr = " {0} hostaddr={1}".format(conn_attr, manager.hostaddr) + + if manager.passfile: + conn_attr = " {0} passfile={1}".format(conn_attr, + get_complete_file_path( + manager.passfile)) + + if get_complete_file_path(manager.sslcert): + conn_attr = " {0} sslcert={1}".format( + conn_attr, get_complete_file_path(manager.sslcert)) + + if get_complete_file_path(manager.sslkey): + conn_attr = " {0} sslkey={1}".format( + conn_attr, get_complete_file_path(manager.sslkey)) + + if get_complete_file_path(manager.sslrootcert): + conn_attr = " {0} sslrootcert={1}".format( + conn_attr, get_complete_file_path(manager.sslrootcert)) + + if get_complete_file_path(manager.sslcrl): + conn_attr = " {0} sslcrl={1}".format( + conn_attr, get_complete_file_path(manager.sslcrl)) + + if manager.service: + conn_attr = " {0} service={1}".format( + conn_attr, get_complete_file_path(manager.service)) + + return conn_attr + + [email protected]('socket_input', namespace='/pty') +def socket_input(data): + """ + This get the user input through socket. + :param data: User input from socket. + """ + try: + # request.sid: refer request.sid as socket id. + # Check PSQL enabled setting from config. + enable_psql = True if config.ENABLE_PSQL else False + + if request.sid in app.config['sessions']: + if data['key_name'] == 'Enter' and enable_psql: + # If user get previous executed command from history then set + # current command as previous executed command. + if session_last_cmd[request.sid]['cmd'] \ + and session_last_cmd[request.sid]['arrow_up']: + user_input = str( + session_last_cmd[request.sid]['cmd']).strip() + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + else: + if request.sid not in session_input: + session_input[request.sid] = data['input'] + user_input = str(session_input[request.sid]).strip() + else: + user_input = str(session_input[request.sid]).strip() + session_input_cursor[request.sid] = 0 + + # If ALLOW_PSQL_SHELL_COMMANDS is False then user can't execute + # \! meta command to run shell commands through PSQL terminal. + # Check before executing the user entered command does not + # contains \! in input. + is_new_connection = session_last_cmd[request.sid][ + 'is_new_connection'] + if user_input.startswith('\\!') and \ + re.match("^\\\!$", user_input) and \ + len(user_input) == 2 and \ + not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not is_new_connection: + + session_last_cmd[request.sid]['invalid_cmd'] = True + + for i in range(len(session_input[request.sid])): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + session_input[request.sid] = '' + elif re.search("\\\!", user_input) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + stop_execution = True + # Check \! is passed as string or not. + double_quote_strs = re.findall('"([^"]*)"', user_input) + if not double_quote_strs: + double_quote_strs = re.findall("'([^']*)'", user_input) + + if double_quote_strs: + for sub_str in double_quote_strs: + if re.search("\\\!", sub_str): + stop_execution = False + # break + + if stop_execution: + session_last_cmd[request.sid]['invalid_cmd'] = True + # Remove already added command from terminal. + for i in range(len(user_input)): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + # Add Enter event to execute the command. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + elif user_input == '\q' or user_input == 'q\\q': + # If user enter \q to terminate the PSQL, emit the msg to + # notify user connection is terminated. + sio.emit('pty-output', + { + 'result': gettext( + 'Connection terminated, To create new ' + 'connection please open another psql' + ' tool.'), + 'error': True}, + namespace='/pty', room=request.sid) + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + + else: + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + session_input[request.sid] = '' + session_last_cmd[request.sid]['is_new_connection'] = False + else: + if data['key_name'] == 'ArrowLeft': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] > 0: + session_input_cursor[request.sid] -= 1 + + elif data['key_name'] == 'ArrowRight': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] < len( + session_input[request.sid]): + session_input_cursor[request.sid] += 1 + + elif data['key_name'] == 'ArrowUp': + session_last_cmd[request.sid]['arrow_up'] = True + session_last_cmd[request.sid]['arrow_left_right'] = False + session_input[request.sid] = session_last_cmd[request.sid][ + 'cmd'] + session_input_cursor[request.sid] = len( + session_last_cmd[request.sid]['cmd']) + + elif request.sid in session_input and data[ + 'key_name'] == 'Backspace' and ( + len(session_input[request.sid]) or len( + session_last_cmd[request.sid])): + + session_last_cmd[request.sid]['arrow_left_right'] = True + + if session_last_cmd[request.sid]['cmd']: + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + + user_input = list(session_input[request.sid]) + + if session_input_cursor[request.sid] == 1: + index = 0 + session_input_cursor[request.sid] -= 1 + else: + if session_input_cursor[request.sid] > 0: + index = (session_input_cursor[request.sid]) - 1 + session_input_cursor[request.sid] -= 1 + else: + index = session_input_cursor[request.sid] + session_input_cursor[request.sid] = 0 + + if len(user_input): + del user_input[index] + session_input[request.sid] = "".join(user_input) + + if len(session_input[request.sid]) == 0: + session_input_cursor[request.sid] = 0 + session_last_cmd[request.sid]['cmd'] = '' + elif request.sid in session_input: + if session_last_cmd[request.sid]['cmd'] and session_input[ + request.sid] == '': + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + session_input_cursor[request.sid] = len( + session_input[request.sid]) + else: + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + user_input = list(session_input[request.sid]) + user_input.insert(session_input_cursor[request.sid], + data['input']) + session_input[request.sid] = ''.join(user_input) + session_input_cursor[request.sid] += 1 + session_last_cmd[request.sid]['arrow_left_right'] = False + else: + session_input_cursor[request.sid] = 0 + session_input[request.sid] = data['input'] + session_input_cursor[request.sid] += 1 + + # Write user input to terminal parent fd. + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + except Exception as e: + # Delete socket id from sessions. + # request.sid: refer request.sid as socket id. + sio.emit('pty-output', + { + 'result': gettext('Invalid session.\r\n'), + 'error': True + }, + namespace='/pty', room=request.sid) + del app.config['sessions'][request.sid] + + [email protected]('resize', namespace='/pty') +def resize(data): + """ + Resize the pty terminal as per the UI terminal. + :param data: UI terminal rows and cols data + """ + # request.sid: refer request.sid as socket id. + if request.sid in app.config['sessions']: + set_term_size(app.config['sessions'][request.sid], data['rows'], + data['cols']) + + [email protected]('disconnect', namespace='/pty') +def disconnect(): + """ + Disconnect the socket and terminate the process + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + disconnect_socket() + + [email protected]('server-disconnect', namespace='/pty') +def server_disconnect(data): + """ + Disconnect the socket and terminate the process after user disconnect + the server. we can't use disconnect event name as it is reserved for socket + internal use. + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata and request.sid in app.config['sid_soid_mapping'][ + data['sid']]: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + app.config['sid_soid_mapping'][data['sid']] = [soid for soid in + app.config[ + 'sid_soid_mapping'][ + data['sid']] if + soid != request.sid] + disconnect_socket() + + +def disconnect_socket(): + os.write(app.config['sessions'][request.sid], '\q\n'.encode()) + sio.sleep(1) + os.close(app.config['sessions'][request.sid]) + os.close(cdata[request.sid]) + del app.config['sessions'][request.sid] diff --git a/web/pgadmin/tools/psql/static/js/index.js b/web/pgadmin/tools/psql/static/js/index.js new file mode 100644 index 00000000..4d88ba04 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/index.js @@ -0,0 +1,23 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import $ from 'jquery'; +import _ from 'underscore'; +import pgAdmin from 'sources/pgadmin'; +import pgBrowser from 'top/browser/static/js/browser'; +import * as csrfToken from 'sources/csrf'; +import {initialize} from './psql_module'; + +let pgBrowserOut = initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser); + +module.exports = { + pgBrowser: pgBrowserOut, +}; diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js new file mode 100644 index 00000000..9f7cada3 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -0,0 +1,429 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import { Terminal } from 'xterm'; +import { FitAddon } from 'xterm-addon-fit'; +import { WebLinksAddon } from 'xterm-addon-web-links'; +import { SearchAddon } from 'xterm-addon-search'; +import { io } from 'socketio'; +import Alertify from 'pgadmin.alertifyjs'; +import {enable} from 'pgadmin.browser.toolbar'; +import clipboard from 'sources/selection/clipboard'; +import 'wcdocker'; +import {getRandomInt} from 'sources/utils'; + +import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; +import {generateTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; + + +export function setPanelTitle(psqlToolPanel, panelTitle) { + psqlToolPanel.title('<span title="'+panelTitle+'">'+panelTitle+'</span>'); +} + +var wcDocker = window.wcDocker; + +export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) { + var pgBrowser = Browser; + var terminal = Terminal; + var parentData = null; + /* Return back, this has been called more than once */ + if (pgBrowser.psql) + return pgBrowser.psql; + + + // Create an Object Restore of pgBrowser class + pgBrowser.psql = { + init: function() { + this.initialized = true; + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'psql', + module: this, + applies: ['tools'], + callback: 'psql_tool', + priority: 1, + label: gettext('PSQL Tool (Beta)'), + enable: this.psqlToolEnabled, + }]; + + this.enable_psql_tool = pgAdmin['enable_psql']; + if(pgAdmin['enable_psql']) { + pgBrowser.add_menus(menus); + } + + // Creating a new pgBrowser frame to show the data. + var psqlFrameType = new pgBrowser.Frame({ + name: 'frm_psqltool', + showTitle: true, + isCloseable: true, + isPrivate: true, + url: 'about:blank', + }); + + var self = this; + /* Cache may take time to load for the first time + * Keep trying till available + */ + let cacheIntervalId = setInterval(function() { + if(pgBrowser.preference_version() > 0) { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + clearInterval(cacheIntervalId); + } + },0); + + pgBrowser.onPreferencesChange('psql', function() { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + }); + + // Load the newly created frame + psqlFrameType.load(pgBrowser.docker); + return this; + }, + /* Enable/disable PSQL tool menu in tools based + * on node selected. if selected node is present + * in unsupported_nodes, menu will be disabled + * otherwise enabled. + */ + psqlToolEnabled: function(obj) { + + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj)) { + if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) { + if (obj._type == 'database' && obj.allowConn) { + return true; + } else if (obj._type != 'database') { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + })(); + + enable(gettext('PSQL Tool'), isEnabled); + return isEnabled; + }, + retrieveAncestorOfTypeServer: function(item) { + let serverInformation = null; + // let aciTreeItem = item || pgBrowser.treeMenu.selected(); + let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); + + if (treeNode) { + let nodeData; + let databaseNode = treeNode.ancestorNode( + (node) => { + nodeData = node.getData(); + return (nodeData._type === 'database'); + } + ); + let isServerNode = (node) => { + nodeData = node.getData(); + return nodeData._type === 'server'; + }; + + if (databaseNode !== null) { + if (nodeData._label.indexOf('=') >= 0) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext( + 'Databases with = symbols in the name cannot be backed up or restored using this utility.' + ) + ); + } else { + if (databaseNode.anyParent(isServerNode)) + serverInformation = nodeData; + } + } else { + if (treeNode.anyFamilyMember(isServerNode)) + serverInformation = nodeData; + } + } + + if (serverInformation === null) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext('Please select server or child node from the browser tree.') + ); + } + return serverInformation; + }, + psql_tool: function(data, aciTreeIdentifier, gen=false) { + const module = 'paths'; + let preference_name = 'pg_bin_dir'; + let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.'); + const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeIdentifier); + + if ((serverInformation.type && serverInformation.type === 'ppas') || + serverInformation.server_type === 'ppas') { + preference_name = 'ppas_bin_dir'; + msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'); + } + const preference = pgBrowser.get_preference(module, preference_name); + if (preference) { + if (!preference.value) { + Alertify.alert(gettext('Configuration required'), msg); + return false; + } + } else { + Alertify.alert( + gettext(this.errorAlertTitle), + gettext('Failed to load preference %s of module %s', preference_name, module) + ); + return false; + } + const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if (node === undefined || !node.getData()) { + Alertify.alert( + gettext('PSQL Error'), + gettext('No object selected.') + ); + return; + } + + parentData = getTreeNodeHierarchyFromIdentifier.call( + pgBrowser, + aciTreeIdentifier + ); + + if(_.isUndefined(parentData.server)) { + Alertify.alert( + gettext('PSQL Error'), + gettext('Please select a server/database object.') + ); + return; + } + + const transId = getRandomInt(1, 9999999); + + var panelTitle = ''; + // Set psql tab title as per prefrences setting. + var title_data = { + 'database': parentData.database ? parentData.database.label : 'postgres' , + 'username': parentData.server.user_name, + 'server': parentData.server.label, + 'type': 'psql_tool', + }; + var tab_title_placeholder = pgBrowser.get_preferences_for_module('browser').psql_tab_title_placeholder; + panelTitle = generateTitle(tab_title_placeholder, title_data); + + const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + + let psqlToolForm = ` + <form id="psqlToolForm" action="${panelUrl}" method="post"> + <input id="title" name="title" hidden /> + <input name="close_url" value="${panelCloseUrl}" hidden /> + </form> + <script> + document.getElementById("title").value = "${_.escape(panelTitle)}"; + document.getElementById("psqlToolForm").submit(); + </script> + `; + var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; + if (open_new_tab && open_new_tab.includes('psql_tool')) { + var newWin = window.open('', '_blank'); + newWin.document.write(psqlToolForm); + newWin.document.title = panelTitle; + } else { + /* On successfully initialization find the properties panel, + * create new panel and add it to the dashboard panel. + */ + var propertiesPanel = pgBrowser.docker.findPanels('properties'); + var psqlToolPanel = pgBrowser.docker.addPanel('frm_psqltool', wcDocker.DOCK.STACKED, propertiesPanel[0]); + + // Set panel title and icon + setPanelTitle(psqlToolPanel, panelTitle); + psqlToolPanel.icon('fas fa-terminal psql-tab-style'); + psqlToolPanel.focus(); + + var openPSQLToolURL = function(j) { + // add spinner element + let $spinner_el = + $(`<div class="pg-sp-container"> + <div class="pg-sp-content"> + <div class="row"> + <div class="col-12 pg-sp-icon"></div> + </div> + </div> + </div>`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { + var frameInitialized = $(j).data('frameInitialized'); + if (frameInitialized) { + clearInterval(init_poller_id); + var frame = $(j).data('embeddedFrame'); + if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); + frame.openHTML(psqlToolForm); + } + } + }, 100); + }; + + openPSQLToolURL(psqlToolPanel); + + } + + }, + getPanelUrls: function(transId, panelTitle, parentData) { + let openUrl = url_for('psql.panel', { + trans_id: transId, + }); + const misc_preferences = pgBrowser.get_preferences_for_module('misc'); + var theme = misc_preferences.theme; + + openUrl += `?sgid=${parentData.server_group._id}` + +`&sid=${parentData.server._id}` + +`&server_type=${parentData.server.server_type}` + + `&theme=${theme}`; + + if(parentData.database && parentData.database._id) { + let db_label = parentData.database._label.replace('\\', '\\\\'); + openUrl += `&db=${db_label}`; + } else { + openUrl += `&db=${''}`; + } + + let closeUrl = url_for('psql.close', { + trans_id: transId, + }); + return [openUrl, closeUrl]; + }, + psql_terminal: function() { + // theme colors + var term = new terminal({ + cursorBlink: true, + macOptionIsMeta: true, + scrollback: 5000, + }); + + return term; + }, + psql_Addon: function(term) { + const fitAddon = this.psql_fit_screen(); + term.loadAddon(fitAddon); + + const webLinksAddon = this.psql_web_link(); + term.loadAddon(webLinksAddon); + + const searchAddon = this.psql_search(); + term.loadAddon(searchAddon); + + fitAddon.fit(); + term.resize(15, 50); + fitAddon.fit(); + return fitAddon; + }, + psql_fit_screen: function() { + return new FitAddon(); + }, + psql_web_link: function() { + return new WebLinksAddon(); + }, + psql_search: function() { + return new SearchAddon(); + }, + psql_socket: function() { + return io('/pty', {pingTimeout: 120000, pingInterval: 25000}); + }, + set_theme: function(term) { + var theme = { + background: getComputedStyle(document.documentElement).getPropertyValue('--psql-background'), + foreground: getComputedStyle(document.documentElement).getPropertyValue('--psql-foreground'), + cursor: getComputedStyle(document.documentElement).getPropertyValue('--psql-cursor'), + cursorAccent: getComputedStyle(document.documentElement).getPropertyValue('--psql-cursorAccent'), + selection: getComputedStyle(document.documentElement).getPropertyValue('--psql-selection'), + }; + term.setOption('theme', theme); + }, + psql_socket_io: function(socket, is_enable, sid, db, server_type, fitAddon, term) { + // Listen all the socket events emit from server. + socket.on('pty-output', function(data){ + if(data.error) { + term.write('\r\n'); + } + term.write(data.result); + if(data.error) { + term.write('\r\n'); + } + }); + // Connect socket + socket.on('connect', () => { + if(is_enable == 'True'){ + socket.emit('start_process', {'sid': sid, 'db': db, 'stype': server_type }); + } + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('conn_error', (response) => { + term.write(response.error); + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('conn_not_allow', () => { + term.write('PSQL connection not allowed'); + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('disconnect-psql', () => { + socket.emit('server-disconnect', {'sid': sid}); + term.write('\r\nServer disconnected, Connection terminated, To create new connection please open another psql tool.'); + }); + }, + psql_terminal_io: function(term, socket) { + // Listen key press event from terminal and emit socket event. + let selected_text = ''; + term.attachCustomKeyEventHandler(e => { + e.stopPropagation(); + if(e.type=='keydown' && e.metaKey &&(e.key == 'v' || e.key == 'V')) { + if(selected_text != '') { + if (selected_text.length > 0) { + socket.emit('socket_input', {'input': selected_text, 'key_name': e.code}); + selected_text = ''; + } + } else { + navigator.clipboard.readText().then( clipText => { + selected_text = clipText; + if (selected_text.length > 0) { + socket.emit('socket_input', {'input': selected_text, 'key_name': e.code}); + selected_text = ''; + } + }); + } + }else if(e.type=='keydown' && e.metaKey && (e.key == 'c' || e.key == 'C')) { + if (term.hasSelection()) { + selected_text = term.getSelection(); + } else { + selected_text = clipboard.readText(); + } + } + return true; + }); + + term.onKey(function (ev) { + if (pgAdmin['allow_psql_shell_commands']) { + socket.emit('socket_input', {'input': ev.key, 'key_name': ev.domEvent.code}); + } else { + socket.emit('socket_input', {'input': ev.key, 'key_name': ev.domEvent.code}); + } + }); + } + }; + + return pgBrowser.psql; +} + diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html new file mode 100644 index 00000000..43b346b2 --- /dev/null +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -0,0 +1,58 @@ +{% extends "base.html" %} +{% block title %}{{title}}{% endblock %} + +{% block css_link %} +<link type="text/css" rel="stylesheet" href="{{ url_for('browser.browser_css')}}"/> +{% endblock %} +{% block body %} +<style> + body {padding: 0px;} + {% if is_desktop_mode and is_linux %} + .alertify .ajs-dimmer,.alertify .ajs-modal{-webkit-transform: none;} + .alertify-notifier{-webkit-transform: none;} + .alertify-notifier .ajs-message{-webkit-transform: none;} + .alertify .ajs-dialog.ajs-shake{-webkit-animation-name: none;} + .sql-editor-busy-icon.fa-pulse{-webkit-animation: none;} + {% endif %} +</style> +<div style="width: 100%; height: 100%;" id="psql-terminal" class="psql_terminal"></div> +{% endblock %} + + +{% block init_script %} +require( + ['sources/generated/psql_tool'], + function(pgBrowser) { + const term = self.pgAdmin.Browser.psql.psql_terminal(); + <!--Addon for fitAddon, webLinkAddon, SearchAddon --> + const fitAddon = self.pgAdmin.Browser.psql.psql_Addon(term); + <!-- Update the theme for terminal as per pgAdmin 4 theme.--> + self.pgAdmin.Browser.psql.set_theme(term); + <!-- Open the terminal --> + term.open(document.getElementById('psql-terminal')); + <!-- Socket--> + const socket = self.pgAdmin.Browser.psql.psql_socket(); + self.pgAdmin.Browser.psql.psql_socket_io(socket, '{{is_enable}}', '{{sid}}', '{{db}}', '{{server_type}}', fitAddon, term); + self.pgAdmin.Browser.psql.psql_terminal_io(term, socket); + + <!-- Resize the terminal --> + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } + + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) + } + } + + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) + }); +{% endblock %} + + diff --git a/web/pgadmin/tools/psql/tests/__init__.py b/web/pgadmin/tools/psql/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web/pgadmin/tools/psql/tests/psql_test_data.json b/web/pgadmin/tools/psql/tests/psql_test_data.json new file mode 100644 index 00000000..4148c75b --- /dev/null +++ b/web/pgadmin/tools/psql/tests/psql_test_data.json @@ -0,0 +1,184 @@ +{ + "psql_user_input": [ + { + "name": "Enter Select 1;", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "move_cursor_up": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "is_history": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowLeft", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowLeft": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowRight", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Read previous executed command", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "move_cursor_right": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\!", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! with other cmd not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\! ls", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Valid commands", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select \"\\!\"", + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "First command as enter", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Exist psql terminal by using \\q", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\q", + "mock_data": { + + }, + "expected_data": { + } + } + ], + "resize_terminal": [ + { + "name": "Resize psql terminal as per UI.", + "is_positive_test": true, + "mocking_required": false, + "input_data": { + "cols": 141, + "rows": 39 + }, + "mock_data": { + + }, + "expected_data": { + } + } + ], + "backend_task": [ + { + "name": "Backend Task", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "Select 1;", + "is_backend_task": true, + "mock_data": { + "is_test": true + }, + "expected_data": { + } + } + ] +} diff --git a/web/pgadmin/tools/psql/tests/test_backend_task.py b/web/pgadmin/tools/psql/tests/test_backend_task.py new file mode 100644 index 00000000..a4f14ee4 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_backend_task.py @@ -0,0 +1,87 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLBackend(BaseTestGenerator): + scenarios = utils.generate_scenarios('backend_task', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'], + 'is_test': True, + 'count': 0 + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_panel.py b/web/pgadmin/tools/psql/tests/test_panel.py new file mode 100644 index 00000000..6f93c8c2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_panel.py @@ -0,0 +1,36 @@ +import uuid +import random +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data + + +class PSQLPanel(BaseTestGenerator): + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + self.theme = 'standard' + + def runTest(self): + trans_id = random.randint(1, 9999999) + url = '/psql/panel/{trans_id}?sgid={sgid}&sid={sid}&server_type=pg' \ + '&db={db_name}&theme={theme}'.\ + format(trans_id=trans_id, sgid=self.sgid, sid=self.sid, + db_name=self.db_name, theme=self.theme) + + response = self.tester.post( + url, data={"title": "panel_title"}, + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_disabled.py b/web/pgadmin/tools/psql/tests/test_psql_disabled.py new file mode 100644 index 00000000..7dc52498 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_disabled.py @@ -0,0 +1,34 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisabled(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = False + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_input.py b/web/pgadmin/tools/psql/tests/test_psql_input.py new file mode 100644 index 00000000..6f6eabe7 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_input.py @@ -0,0 +1,148 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLInput(BaseTestGenerator): + scenarios = utils.generate_scenarios('psql_user_input', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_backspace') and self.is_backspace: + if hasattr(self, 'move_cursor_up') and self.move_cursor_up: + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Backspace' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowUp') and self.is_arrowUp: + if hasattr(self, 'is_history') and self.is_history: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowLeft') and self.is_arrowLeft: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowRight') and self.is_arrowRight: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'move_cursor_right') and self.is_arrowRight: + for i in range(2): + input_data = { + 'input': '', + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + input_data = { + 'input': '', + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_resize_terminal.py b/web/pgadmin/tools/psql/tests/test_resize_terminal.py new file mode 100644 index 00000000..d305c2d0 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_resize_terminal.py @@ -0,0 +1,58 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLResizeTerminal(BaseTestGenerator): + scenarios = utils.generate_scenarios('resize_terminal', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.emit('resize', self.input_data, namespace='/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_connect.py b/web/pgadmin/tools/psql/tests/test_socket_connect.py new file mode 100644 index 00000000..3791525a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_connect.py @@ -0,0 +1,35 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketConnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py new file mode 100644 index 00000000..0619eb30 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py @@ -0,0 +1,52 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisconnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_test_client = app.test_client() + flask_test_client.get('/') + + self.test_client = socketio.test_client( + app, + flask_test_client=flask_test_client, + namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process.py b/web/pgadmin/tools/psql/tests/test_start_process.py new file mode 100644 index 00000000..1245de3f --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process.py @@ -0,0 +1,57 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcess(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + import random + trans_id = random.randint(1, 9999999) + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process_fail.py b/web/pgadmin/tools/psql/tests/test_start_process_fail.py new file mode 100644 index 00000000..0acc7be2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process_fail.py @@ -0,0 +1,48 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcessFail(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + config.ENABLE_PSQL = False + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/utils.py b/web/pgadmin/tools/psql/tests/utils.py new file mode 100644 index 00000000..85bd5373 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/utils.py @@ -0,0 +1,6 @@ +import os +import json + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/psql_test_data.json") as data_file: + test_cases = json.load(data_file) diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss index 0bb40802..a58eb7e9 100644 --- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss +++ b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss @@ -374,3 +374,20 @@ div.strikeout:after { /* Setting it to hardcoded white as the SVG generated is having white bg * Need to check what can be done. */ + +/* Css for psql */ +.psql_terminal .terminal { + padding-top: 1%; + padding-left: 0.5%; + height: 100%; +} + +.psql-icon-style { + font-size: inherit; + padding-left: 0em; +} + +.psql-tab-style { + font-size: small; + padding-left: 0em; +} diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py index 23abfffa..71ae82ea 100644 --- a/web/pgadmin/utils/csrf.py +++ b/web/pgadmin/utils/csrf.py @@ -38,6 +38,7 @@ class _PGCSRFProtect(CSRFProtect): 'pgadmin.tools.schema_diff.ddl_compare', 'pgadmin.authenticate.login', 'pgadmin.tools.erd.panel', + 'pgadmin.tools.psql.panel', ] for exempt in exempt_views: diff --git a/web/pgadmin/utils/preferences.py b/web/pgadmin/utils/preferences.py index 15ceeb1a..e9efe479 100644 --- a/web/pgadmin/utils/preferences.py +++ b/web/pgadmin/utils/preferences.py @@ -72,6 +72,7 @@ class _Preference(object): self.select2 = kwargs.get('select2', None) self.fields = kwargs.get('fields', None) self.allow_blanks = kwargs.get('allow_blanks', None) + self.disabled = kwargs.get('disabled', False) # Look into the configuration table to find out the id of the specific # preference. @@ -252,6 +253,7 @@ class _Preference(object): 'select2': self.select2, 'value': self.get(), 'fields': self.fields, + 'disabled': self.disabled, } return res @@ -414,6 +416,7 @@ class Preferences(object): :param fields: field schema (if preference has more than one field to take input from user e.g. keyboardshortcut preference) :param allow_blanks: Flag specify whether to allow blank value. + :param disabled: Flag specify whether to disable the setting or not. """ min_val = kwargs.get('min_val', None) max_val = kwargs.get('max_val', None) @@ -423,6 +426,7 @@ class Preferences(object): select2 = kwargs.get('select2', None) fields = kwargs.get('fields', None) allow_blanks = kwargs.get('allow_blanks', None) + disabled = kwargs.get('disabled', False) cat = self.__category(category, category_label) if name in cat['preferences']: @@ -439,7 +443,8 @@ class Preferences(object): (cat['preferences'])[name] = res = _Preference( cat['id'], name, label, _type, default, help_str=help_str, min_val=min_val, max_val=max_val, options=options, - select2=select2, fields=fields, allow_blanks=allow_blanks + select2=select2, fields=fields, allow_blanks=allow_blanks, + disabled=disabled ) return res diff --git a/web/webpack.config.js b/web/webpack.config.js index 779f2faa..f631178b 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -355,6 +355,7 @@ module.exports = [{ debugger_direct: './pgadmin/tools/debugger/static/js/direct.js', schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js', erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js', + psql_tool: './pgadmin/tools/psql/static/js/index.js', file_utils: './pgadmin/misc/file_manager/static/js/utility.js', 'pgadmin.style': pgadminCssStyles, pgadmin: pgadminScssStyles, @@ -493,7 +494,7 @@ module.exports = [{ ], }, }, - }, { + },{ test: require.resolve('./node_modules/acitree/js/jquery.aciTree.min'), use: { loader: 'imports-loader', @@ -532,6 +533,7 @@ module.exports = [{ 'pure|pgadmin.tools.storage_manager', 'pure|pgadmin.tools.search_objects', 'pure|pgadmin.tools.erd_module', + 'pure|pgadmin.tools.psql_module', ], }, }, diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 074b2580..e0b28091 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -159,6 +159,15 @@ var webpackShimConfig = { 'jquery.acisortable': path.join(__dirname, './node_modules/acitree/js/jquery.aciSortable.min'), 'jquery.acifragment': path.join(__dirname, './node_modules/acitree/js/jquery.aciFragment.min'), + //xterm + 'xterm': path.join(__dirname, './node_modules/xterm/lib/xterm.js'), + 'xterm-addon-fit': path.join(__dirname, './node_modules/xterm-addon-fit/lib/xterm-addon-fit.js'), + 'xterm-addon-web-links': path.join(__dirname, './node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js'), + 'xterm-addon-search': path.join(__dirname, './node_modules/xterm-addon-search/lib/xterm-addon-search.js'), + + //socket + 'socketio': path.join(__dirname, './node_modules/socket.io-client/dist/socket.io.js'), + // Backbone and Backgrid 'backbone': path.join(__dirname, './node_modules/backbone/backbone'), 'backbone.undo': path.join(__dirname, './node_modules/backbone-undo/Backbone.Undo'), @@ -288,6 +297,8 @@ var webpackShimConfig = { 'pgadmin.tools.storage_manager': path.join(__dirname, './pgadmin/tools/storage_manager/static/js/storage_manager'), 'pgadmin.tools.erd_module': path.join(__dirname, './pgadmin/tools/erd/static/js/erd_module'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index e0b6fd69..3cc079f9 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -177,6 +177,7 @@ module.exports = { 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), 'tools': path.join(__dirname, './pgadmin/tools/'), 'pgadmin.user_management.current_user': regressionDir + '/javascript/fake_current_user', ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-20 09:22 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-05-20 09:22 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers Thanks Nikhil. Can someone else review this version please? On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < [email protected]> wrote: > Hi Dave/ Team, > > On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Dave/ Team, >>> >>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Dave/Team, >>>> >>>> >>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Akshay/ Team, >>>>>> >>>>>> Please find the attached updated patch for the psql tool. >>>>>> >>>>> >>>>> Hmm, this version is also broken. There's a typo in >>>>> editor_template.html on line 138 - it splits a string across two lines >>>>> which throws an error. Having fixed that... >>>>> >>>>> I also note there's a lot of Javascript in that HTML file. That should >>>>> be pushed into the webpacked bundle I think, and not included inline in >>>>> HTML. >>>>> >>>> I have moved most of the code in the js file, few things are still in >>>> HTML. >>>> >>> >>> Hmm, yes - in particular, colours for the different themes. Please move >>> them into the css for the themes. You have a mix of style, layout and code >>> in this file which needs to be cleaned up. >>> xterm V3 onwards they have provided the API to set the theme and other >>> settings, earlier I tried with CSS to override the theme but couldn’t able >>> to apply the theme properly as some style get applied as in-line style for >>> the HTML, so used the API to set the theme. >>> >> >> OK, but either way we can't hard-code styles from themes in HTML >> templates for individual features; that way leads to madness. >> >> Perhaps Aditya or one of the other team members can give some assistance? >> > I have moved the color settings to the respective theme files. Aditya > helped in this. > >> >> >>> >>> >>>> Speaking of themes, the background colour for selected text doesn't >>>> seem right (it's barely visible) in the dark theme. Can you fix that to >>>> match the colouring in the SQL text boxes please? >>>> >>> I tried the default selection color from SQL for the dark and standard > themes but still, it was not readable so just updated the color code with > another color as follows. > 1. Dark Theme: > [image: Screenshot 2021-05-19 at 6.29.43 PM.png] > 2. High Contrast: (using default SQL selection color) > [image: Screenshot 2021-05-19 at 6.59.52 PM.png] > 3. Standard: > [image: image.png] > can we go with the colors or should we update it? > >> >>>> >>>>> >>>>>> A couple of other things I noticed: >>>>>> >>>>>> - The button is enabled if the treeview has a Server selected. It >>>>>> could be argued that the query tool should do the same (defaulting to the >>>>>> maintenance database), however, that would be a separate change, and psql >>>>>> should be consistent with the query tool. >>>>>> >>>>> It is now consistent with the query tool. >>>>> >>>>>> >>>>>> - If I do a "select * from pg_class;" I still get: >>>>>> >>>>>> postgres=# select * from pg_class; >>>>>> WARNING: terminal is not fully functional >>>>>> >>>>> I am not able to reproduce the warning for the terminal (I am working >>>>> on Catalina 10.15.7), I checked on browsers (chrome, firefox, Safari) and >>>>> also checked on local nwjs runtime but still not able to reproduce the >>>>> warning. but found one limitation: >>>>> >>>> >>>> It looks like that can be fixed by adding: >>>> >>>> env={'TERM': 'xterm'} >>>> >>> Added this in the environment when opening the psql panel. > >> >>>> to the subprocess.Popen() call. >>>> >>>> I noticed while I was playing with that, that you are passing the >>>> password as part of the connection string. As I've mentioned in the past, >>>> that is absolutely not acceptable; it will expose the password to all >>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>> using the PGPASSWORD environment variable. >>>> >>>> >>>>> if we try to load data from the table containing millions of records, >>>>> UI gets very slow. >>>>> >>>> Removed the password from the connection string and added 'PGPASSWORD' > in the environment. > >> >>>> Is xtermjs discarding the older buffer contents when it fills up? Can >>>> you tell where the memory usage is? >>>> >>> I checked the psql memory consumption in terminal and pgAdmin psql tool >>> memory consumption is the similar. Also tested the performance and query >>> execution timing is also similar. >>> >> >> OK, so there's probably not much we can do here. >> >> >>> >>>> >>>> >>>>> >>>>>> - I'm sure using \q in the previous version displayed a message >>>>>> saying the session exited (the one on line 138 of editor_template.html). It >>>>>> no longer seems to do so. >>>>>> >>>>> >>>> In addition to the issue above, it looks like the \! blocking may have >>>> lost it's ability to ignore quoted strings: >>>> >>>> pgweb=# select '\!'; >>>> ERROR: Shell commands are disabled in psql for security >>>> >>> Fixed the issue now it is consistent with the psql terminal. > >> >>>> >>> >>>>>> >>>>>>> >>>>>>> >>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Nikhil >>>>>>>>> >>>>>>>>> Following are the review comments: >>>>>>>>> >>>>>>>>> *GUI specific*: >>>>>>>>> >>>>>>>>> - We need a panel icon for PSQL like query tool, we can also >>>>>>>>> add that on the browser tree toolbar. >>>>>>>>> - PSQL Tool menu should be visible for all the child nodes of >>>>>>>>> the database node. Follow the same as Query Tool. >>>>>>>>> - PSQL tab title should be only database server name as the >>>>>>>>> user can change the database/user from PSQL command, so it's been difficult >>>>>>>>> to update the tab title. >>>>>>>>> - PSQL connection is still open even if we disconnect the >>>>>>>>> database server from the browser tree. >>>>>>>>> >>>>>>>>> *Code specific:* >>>>>>>>> >>>>>>>>> - Remove an extra space from requirements.txt and package.json >>>>>>>>> - Documentation needs to be updated to let the user know from >>>>>>>>> where the PSQL tool will open and on which node it is applicable. >>>>>>>>> - psql/__init__.py check there are so many unused imports >>>>>>>>> please remove them. >>>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>> - Test cases are showing successful but actually, there are >>>>>>>>> some routing errors please check. >>>>>>>>> >>>>>>>>> A few other things I noticed: >>>>>>>> >>>>>>>> - I was prompted to enter a password. This should be passed in the >>>>>>>> environment to psql as it is for pg_dump etc. >>>>>>>> - There seems to be an issue with terminal compatibility (which I >>>>>>>> didn't have on my prototype): >>>>>>>> >>>>>>>> ml=# select * from pg_class; >>>>>>>> WARNING: terminal is not fully functional >>>>>>>> -[ RECORD 1 ]-------+---------------------------------------------- >>>>>>>> oid | 79354 >>>>>>>> relname | housing >>>>>>>> ... >>>>>>>> >>>>>>>> - The panel should honour the styleguide. I'm running in dark mode, >>>>>>>> and see a jet black background. I would expect to see the same >>>>>>>> background/foreground colours as the treeview. >>>>>>>> - I spotted at least one print() statement that shouldn't be there >>>>>>>> (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>> >>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>> >>>>>>>> - There's a thick white line at the bottom of the panel, where a >>>>>>>> horizontal scrollbar might be if there was one. >>>>>>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>>>>>> commands are disabled in psql for security;" >>>>>>>> >>>>>>>> Once we're happy with the patch in general, I'll do a string review >>>>>>>> before committing. In particular, I want to be sure the text in config.py >>>>>>>> is appropriately worded. >>>>>>>> >>>>>>>> This is shaping up nicely! Good work. >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave/ Team, >>>>>>>>>> >>>>>>>>>> PFA updated patch, sorry for the inconvenience, while cleanup I >>>>>>>>>> removed the unwanted libraries but forgot to remove the code related to >>>>>>>>>> them. >>>>>>>>>> >>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>> >>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option >>>>>>>>>>>> for starting PSQL. >>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>> 2. Added the same option for Server and Database nodes from the >>>>>>>>>>>> tree view. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Unfortunately there's a trailing comma in package.json that >>>>>>>>>>> makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>> >>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>> Module not found: Error: Can't resolve 'local-echo-controller' >>>>>>>>>>> in '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>> Parsed request is a module >>>>>>>>>>> using description file: >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>> using description file: >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>> configuration >>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>> using description file: >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>> no extension >>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>> configuration >>>>>>>>>>> >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>> doesn't exist >>>>>>>>>>> .js >>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>> configuration >>>>>>>>>>> >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>> doesn't exist >>>>>>>>>>> .jsx >>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>> configuration >>>>>>>>>>> >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>> doesn't exist >>>>>>>>>>> as directory >>>>>>>>>>> >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>> doesn't exist >>>>>>>>>>> using description file: >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>> no extension >>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>> configuration >>>>>>>>>>> >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>> .js >>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>> configuration >>>>>>>>>>> >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>> .jsx >>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>> configuration >>>>>>>>>>> >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>> as directory >>>>>>>>>>> >>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>> >>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in >>>>>>>>>>> 60041 ms >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>>> Nikhil Mohite >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> *Thanks & Regards* >>>>>>>>> *Akshay Joshi* >>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>> >>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> Regards, >>>>>>> Nikhil Mohite >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>> >>>>> Regards, >>>>> Nikhil Mohite >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>> >>> >>> Regards, >>> Nikhil Mohite >>> >>>> <https://www.enterprisedb.com; >>>> >>>> -- >>> *Thanks & Regards,* >>> *Nikhil Mohite* >>> *Software Engineer.* >>> *EDB Postgres* <https://www.enterprisedb.com/; >>> *Mob.No: +91-7798364578.* >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> Regards, > Nikhil Mohite > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-24 15:49 Akshay Joshi <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Akshay Joshi @ 2021-05-24 15:49 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Dave Page <[email protected]> Hi Nikhil Following are the review comments: - Set "ENABLE_PSQL = False", PSQL button from browser tree and context menu option should not be visible. - Documentation screenshot should be in standard theme for consistency, and check the size it's very large. Take the screenshot with the new PSQL button on the browser tree. - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. - Remove commented code (if any) - Check SonarQube (I haven't run) On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> wrote: > Thanks Nikhil. Can someone else review this version please? > > On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Dave/ Team, >> >> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Dave/ Team, >>>> >>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave/Team, >>>>> >>>>> >>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Akshay/ Team, >>>>>>> >>>>>>> Please find the attached updated patch for the psql tool. >>>>>>> >>>>>> >>>>>> Hmm, this version is also broken. There's a typo in >>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>> which throws an error. Having fixed that... >>>>>> >>>>>> I also note there's a lot of Javascript in that HTML file. That >>>>>> should be pushed into the webpacked bundle I think, and not included inline >>>>>> in HTML. >>>>>> >>>>> I have moved most of the code in the js file, few things are still in >>>>> HTML. >>>>> >>>> >>>> Hmm, yes - in particular, colours for the different themes. Please move >>>> them into the css for the themes. You have a mix of style, layout and code >>>> in this file which needs to be cleaned up. >>>> xterm V3 onwards they have provided the API to set the theme and other >>>> settings, earlier I tried with CSS to override the theme but couldn’t able >>>> to apply the theme properly as some style get applied as in-line style for >>>> the HTML, so used the API to set the theme. >>>> >>> >>> OK, but either way we can't hard-code styles from themes in HTML >>> templates for individual features; that way leads to madness. >>> >>> Perhaps Aditya or one of the other team members can give some assistance? >>> >> I have moved the color settings to the respective theme files. Aditya >> helped in this. >> >>> >>> >>>> >>>> >>>>> Speaking of themes, the background colour for selected text doesn't >>>>> seem right (it's barely visible) in the dark theme. Can you fix that to >>>>> match the colouring in the SQL text boxes please? >>>>> >>>> I tried the default selection color from SQL for the dark and standard >> themes but still, it was not readable so just updated the color code with >> another color as follows. >> 1. Dark Theme: >> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >> 2. High Contrast: (using default SQL selection color) >> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >> 3. Standard: >> [image: image.png] >> can we go with the colors or should we update it? >> >>> >>>>> >>>>>> >>>>>>> A couple of other things I noticed: >>>>>>> >>>>>>> - The button is enabled if the treeview has a Server selected. It >>>>>>> could be argued that the query tool should do the same (defaulting to the >>>>>>> maintenance database), however, that would be a separate change, and psql >>>>>>> should be consistent with the query tool. >>>>>>> >>>>>> It is now consistent with the query tool. >>>>>> >>>>>>> >>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>> >>>>>>> postgres=# select * from pg_class; >>>>>>> WARNING: terminal is not fully functional >>>>>>> >>>>>> I am not able to reproduce the warning for the terminal (I am working >>>>>> on Catalina 10.15.7), I checked on browsers (chrome, firefox, Safari) and >>>>>> also checked on local nwjs runtime but still not able to reproduce the >>>>>> warning. but found one limitation: >>>>>> >>>>> >>>>> It looks like that can be fixed by adding: >>>>> >>>>> env={'TERM': 'xterm'} >>>>> >>>> Added this in the environment when opening the psql panel. >> >>> >>>>> to the subprocess.Popen() call. >>>>> >>>>> I noticed while I was playing with that, that you are passing the >>>>> password as part of the connection string. As I've mentioned in the past, >>>>> that is absolutely not acceptable; it will expose the password to all >>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>> using the PGPASSWORD environment variable. >>>>> >>>>> >>>>>> if we try to load data from the table containing millions of records, >>>>>> UI gets very slow. >>>>>> >>>>> Removed the password from the connection string and added 'PGPASSWORD' >> in the environment. >> >>> >>>>> Is xtermjs discarding the older buffer contents when it fills up? Can >>>>> you tell where the memory usage is? >>>>> >>>> I checked the psql memory consumption in terminal and pgAdmin psql tool >>>> memory consumption is the similar. Also tested the performance and query >>>> execution timing is also similar. >>>> >>> >>> OK, so there's probably not much we can do here. >>> >>> >>>> >>>>> >>>>> >>>>>> >>>>>>> - I'm sure using \q in the previous version displayed a message >>>>>>> saying the session exited (the one on line 138 of editor_template.html). It >>>>>>> no longer seems to do so. >>>>>>> >>>>>> >>>>> In addition to the issue above, it looks like the \! blocking may have >>>>> lost it's ability to ignore quoted strings: >>>>> >>>>> pgweb=# select '\!'; >>>>> ERROR: Shell commands are disabled in psql for security >>>>> >>>> Fixed the issue now it is consistent with the psql terminal. >> >>> >>>>> >>>> >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Nikhil >>>>>>>>>> >>>>>>>>>> Following are the review comments: >>>>>>>>>> >>>>>>>>>> *GUI specific*: >>>>>>>>>> >>>>>>>>>> - We need a panel icon for PSQL like query tool, we can also >>>>>>>>>> add that on the browser tree toolbar. >>>>>>>>>> - PSQL Tool menu should be visible for all the child nodes of >>>>>>>>>> the database node. Follow the same as Query Tool. >>>>>>>>>> - PSQL tab title should be only database server name as the >>>>>>>>>> user can change the database/user from PSQL command, so it's been difficult >>>>>>>>>> to update the tab title. >>>>>>>>>> - PSQL connection is still open even if we disconnect the >>>>>>>>>> database server from the browser tree. >>>>>>>>>> >>>>>>>>>> *Code specific:* >>>>>>>>>> >>>>>>>>>> - Remove an extra space from requirements.txt and package.json >>>>>>>>>> - Documentation needs to be updated to let the user know from >>>>>>>>>> where the PSQL tool will open and on which node it is applicable. >>>>>>>>>> - psql/__init__.py check there are so many unused imports >>>>>>>>>> please remove them. >>>>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>> - Test cases are showing successful but actually, there are >>>>>>>>>> some routing errors please check. >>>>>>>>>> >>>>>>>>>> A few other things I noticed: >>>>>>>>> >>>>>>>>> - I was prompted to enter a password. This should be passed in the >>>>>>>>> environment to psql as it is for pg_dump etc. >>>>>>>>> - There seems to be an issue with terminal compatibility (which I >>>>>>>>> didn't have on my prototype): >>>>>>>>> >>>>>>>>> ml=# select * from pg_class; >>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>> -[ RECORD 1 ]-------+---------------------------------------------- >>>>>>>>> oid | 79354 >>>>>>>>> relname | housing >>>>>>>>> ... >>>>>>>>> >>>>>>>>> - The panel should honour the styleguide. I'm running in dark >>>>>>>>> mode, and see a jet black background. I would expect to see the same >>>>>>>>> background/foreground colours as the treeview. >>>>>>>>> - I spotted at least one print() statement that shouldn't be there >>>>>>>>> (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>> >>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>> >>>>>>>>> - There's a thick white line at the bottom of the panel, where a >>>>>>>>> horizontal scrollbar might be if there was one. >>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>>>>>>> commands are disabled in psql for security;" >>>>>>>>> >>>>>>>>> Once we're happy with the patch in general, I'll do a string >>>>>>>>> review before committing. In particular, I want to be sure the text in >>>>>>>>> config.py is appropriately worded. >>>>>>>>> >>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>> >>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while cleanup I >>>>>>>>>>> removed the unwanted libraries but forgot to remove the code related to >>>>>>>>>>> them. >>>>>>>>>>> >>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>> >>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu option >>>>>>>>>>>>> for starting PSQL. >>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>> 2. Added the same option for Server and Database nodes from >>>>>>>>>>>>> the tree view. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Unfortunately there's a trailing comma in package.json that >>>>>>>>>>>> makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>> >>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>> Module not found: Error: Can't resolve 'local-echo-controller' >>>>>>>>>>>> in '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>> using description file: >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>> using description file: >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>> configuration >>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>> using description file: >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>> no extension >>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>> configuration >>>>>>>>>>>> >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>> doesn't exist >>>>>>>>>>>> .js >>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>> configuration >>>>>>>>>>>> >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>> doesn't exist >>>>>>>>>>>> .jsx >>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>> configuration >>>>>>>>>>>> >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>> doesn't exist >>>>>>>>>>>> as directory >>>>>>>>>>>> >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>> doesn't exist >>>>>>>>>>>> using description file: >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>> no extension >>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>> configuration >>>>>>>>>>>> >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>> .js >>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>> configuration >>>>>>>>>>>> >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>> .jsx >>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>> configuration >>>>>>>>>>>> >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>> as directory >>>>>>>>>>>> >>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>> >>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in >>>>>>>>>>>> 60041 ms >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Regards, >>>>>>>>>>> Nikhil Mohite >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> *Thanks & Regards* >>>>>>>>>> *Akshay Joshi* >>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>> >>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> Regards, >>>>>>>> Nikhil Mohite >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>> >>>>>> Regards, >>>>>> Nikhil Mohite >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>> >>>> >>>> Regards, >>>> Nikhil Mohite >>>> >>>>> <https://www.enterprisedb.com; >>>>> >>>>> -- >>>> *Thanks & Regards,* >>>> *Nikhil Mohite* >>>> *Software Engineer.* >>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>> *Mob.No: +91-7798364578.* >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> Regards, >> Nikhil Mohite >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-25 09:22 Nikhil Mohite <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-05-25 09:22 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: pgadmin-hackers; Dave Page <[email protected]> Hi Akshay/ Team On Mon, May 24, 2021 at 9:19 PM Akshay Joshi <[email protected]> wrote: > Hi Nikhil > > Following are the review comments: > > - Set "ENABLE_PSQL = False", PSQL button from browser tree and context > menu option should not be visible. > - Documentation screenshot should be in standard theme for > consistency, and check the size it's very large. Take the screenshot with > the new PSQL button on the browser tree. > - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. > - Remove commented code (if any) > - Check SonarQube (I haven't run) > > Please find the updated patch, resolve all the review comments, and update the code to resolve the SonarQube issues. > > On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> wrote: > >> Thanks Nikhil. Can someone else review this version please? >> >> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Dave/ Team, >>> >>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave/ Team, >>>>> >>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave/Team, >>>>>> >>>>>> >>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Akshay/ Team, >>>>>>>> >>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>> >>>>>>> >>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>> which throws an error. Having fixed that... >>>>>>> >>>>>>> I also note there's a lot of Javascript in that HTML file. That >>>>>>> should be pushed into the webpacked bundle I think, and not included inline >>>>>>> in HTML. >>>>>>> >>>>>> I have moved most of the code in the js file, few things are still in >>>>>> HTML. >>>>>> >>>>> >>>>> Hmm, yes - in particular, colours for the different themes. Please >>>>> move them into the css for the themes. You have a mix of style, layout and >>>>> code in this file which needs to be cleaned up. >>>>> xterm V3 onwards they have provided the API to set the theme and other >>>>> settings, earlier I tried with CSS to override the theme but couldn’t able >>>>> to apply the theme properly as some style get applied as in-line style for >>>>> the HTML, so used the API to set the theme. >>>>> >>>> >>>> OK, but either way we can't hard-code styles from themes in HTML >>>> templates for individual features; that way leads to madness. >>>> >>>> Perhaps Aditya or one of the other team members can give some >>>> assistance? >>>> >>> I have moved the color settings to the respective theme files. Aditya >>> helped in this. >>> >>>> >>>> >>>>> >>>>> >>>>>> Speaking of themes, the background colour for selected text doesn't >>>>>> seem right (it's barely visible) in the dark theme. Can you fix that to >>>>>> match the colouring in the SQL text boxes please? >>>>>> >>>>> I tried the default selection color from SQL for the dark and standard >>> themes but still, it was not readable so just updated the color code with >>> another color as follows. >>> 1. Dark Theme: >>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>> 2. High Contrast: (using default SQL selection color) >>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>> 3. Standard: >>> [image: image.png] >>> can we go with the colors or should we update it? >>> >>>> >>>>>> >>>>>>> >>>>>>>> A couple of other things I noticed: >>>>>>>> >>>>>>>> - The button is enabled if the treeview has a Server selected. It >>>>>>>> could be argued that the query tool should do the same (defaulting to the >>>>>>>> maintenance database), however, that would be a separate change, and psql >>>>>>>> should be consistent with the query tool. >>>>>>>> >>>>>>> It is now consistent with the query tool. >>>>>>> >>>>>>>> >>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>> >>>>>>>> postgres=# select * from pg_class; >>>>>>>> WARNING: terminal is not fully functional >>>>>>>> >>>>>>> I am not able to reproduce the warning for the terminal (I am >>>>>>> working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>> reproduce the warning. but found one limitation: >>>>>>> >>>>>> >>>>>> It looks like that can be fixed by adding: >>>>>> >>>>>> env={'TERM': 'xterm'} >>>>>> >>>>> Added this in the environment when opening the psql panel. >>> >>>> >>>>>> to the subprocess.Popen() call. >>>>>> >>>>>> I noticed while I was playing with that, that you are passing the >>>>>> password as part of the connection string. As I've mentioned in the past, >>>>>> that is absolutely not acceptable; it will expose the password to all >>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>> using the PGPASSWORD environment variable. >>>>>> >>>>>> >>>>>>> if we try to load data from the table containing millions of >>>>>>> records, UI gets very slow. >>>>>>> >>>>>> Removed the password from the connection string and added >>> 'PGPASSWORD' in the environment. >>> >>>> >>>>>> Is xtermjs discarding the older buffer contents when it fills up? Can >>>>>> you tell where the memory usage is? >>>>>> >>>>> I checked the psql memory consumption in terminal and pgAdmin psql >>>>> tool memory consumption is the similar. Also tested the performance and >>>>> query execution timing is also similar. >>>>> >>>> >>>> OK, so there's probably not much we can do here. >>>> >>>> >>>>> >>>>>> >>>>>> >>>>>>> >>>>>>>> - I'm sure using \q in the previous version displayed a message >>>>>>>> saying the session exited (the one on line 138 of editor_template.html). It >>>>>>>> no longer seems to do so. >>>>>>>> >>>>>>> >>>>>> In addition to the issue above, it looks like the \! blocking may >>>>>> have lost it's ability to ignore quoted strings: >>>>>> >>>>>> pgweb=# select '\!'; >>>>>> ERROR: Shell commands are disabled in psql for security >>>>>> >>>>> Fixed the issue now it is consistent with the psql terminal. >>> >>>> >>>>>> >>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Nikhil >>>>>>>>>>> >>>>>>>>>>> Following are the review comments: >>>>>>>>>>> >>>>>>>>>>> *GUI specific*: >>>>>>>>>>> >>>>>>>>>>> - We need a panel icon for PSQL like query tool, we can also >>>>>>>>>>> add that on the browser tree toolbar. >>>>>>>>>>> - PSQL Tool menu should be visible for all the child nodes >>>>>>>>>>> of the database node. Follow the same as Query Tool. >>>>>>>>>>> - PSQL tab title should be only database server name as the >>>>>>>>>>> user can change the database/user from PSQL command, so it's been difficult >>>>>>>>>>> to update the tab title. >>>>>>>>>>> - PSQL connection is still open even if we disconnect the >>>>>>>>>>> database server from the browser tree. >>>>>>>>>>> >>>>>>>>>>> *Code specific:* >>>>>>>>>>> >>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>> package.json >>>>>>>>>>> - Documentation needs to be updated to let the user know >>>>>>>>>>> from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>> - psql/__init__.py check there are so many unused imports >>>>>>>>>>> please remove them. >>>>>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>> - Test cases are showing successful but actually, there are >>>>>>>>>>> some routing errors please check. >>>>>>>>>>> >>>>>>>>>>> A few other things I noticed: >>>>>>>>>> >>>>>>>>>> - I was prompted to enter a password. This should be passed in >>>>>>>>>> the environment to psql as it is for pg_dump etc. >>>>>>>>>> - There seems to be an issue with terminal compatibility (which I >>>>>>>>>> didn't have on my prototype): >>>>>>>>>> >>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>> -[ RECORD 1 >>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>> oid | 79354 >>>>>>>>>> relname | housing >>>>>>>>>> ... >>>>>>>>>> >>>>>>>>>> - The panel should honour the styleguide. I'm running in dark >>>>>>>>>> mode, and see a jet black background. I would expect to see the same >>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>> - I spotted at least one print() statement that shouldn't be >>>>>>>>>> there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>> >>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>> >>>>>>>>>> - There's a thick white line at the bottom of the panel, where a >>>>>>>>>> horizontal scrollbar might be if there was one. >>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>>>>>>>> commands are disabled in psql for security;" >>>>>>>>>> >>>>>>>>>> Once we're happy with the patch in general, I'll do a string >>>>>>>>>> review before committing. In particular, I want to be sure the text in >>>>>>>>>> config.py is appropriately worded. >>>>>>>>>> >>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>> >>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while cleanup I >>>>>>>>>>>> removed the unwanted libraries but forgot to remove the code related to >>>>>>>>>>>> them. >>>>>>>>>>>> >>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu >>>>>>>>>>>>>> option for starting PSQL. >>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>> 2. Added the same option for Server and Database nodes from >>>>>>>>>>>>>> the tree view. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json that >>>>>>>>>>>>> makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>> >>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>>> Module not found: Error: Can't resolve 'local-echo-controller' >>>>>>>>>>>>> in '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>> using description file: >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>> using description file: >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>> configuration >>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>> using description file: >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>> no extension >>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>> configuration >>>>>>>>>>>>> >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>> .js >>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>> configuration >>>>>>>>>>>>> >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>> .jsx >>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>> configuration >>>>>>>>>>>>> >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>> as directory >>>>>>>>>>>>> >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>> using description file: >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>> no extension >>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>> configuration >>>>>>>>>>>>> >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>> .js >>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>> configuration >>>>>>>>>>>>> >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>> .jsx >>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>> configuration >>>>>>>>>>>>> >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>> as directory >>>>>>>>>>>>> >>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>> >>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in >>>>>>>>>>>>> 60041 ms >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>> >>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>> Nikhil Mohite >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>> >>>>>>> Regards, >>>>>>> Nikhil Mohite >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>> >>>>> >>>>> Regards, >>>>> Nikhil Mohite >>>>> >>>>>> <https://www.enterprisedb.com; >>>>>> >>>>>> -- >>>>> *Thanks & Regards,* >>>>> *Nikhil Mohite* >>>>> *Software Engineer.* >>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>> *Mob.No: +91-7798364578.* >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> Regards, >>> Nikhil Mohite >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [application/octet-stream] RM_2341_V6.patch (511.5K, 6-RM_2341_V6.patch) download | inline diff: diff --git a/docs/en_US/developer_tools.rst b/docs/en_US/developer_tools.rst index 1ff442cc..bb67e33a 100644 --- a/docs/en_US/developer_tools.rst +++ b/docs/en_US/developer_tools.rst @@ -16,3 +16,4 @@ PL/SQL code. editgrid schema_diff erd_tool + psql_tool diff --git a/docs/en_US/images/psql_tool.png b/docs/en_US/images/psql_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..f92e120211f962d6409959c48428177f69ad2d24 GIT binary patch literal 43302 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 SWZO^RbJ)ntFz=xA_5T1GN0V6q literal 0 HcmV?d00001 diff --git a/docs/en_US/images/tool_menu.png b/docs/en_US/images/tool_menu.png index 7747b95503584d4164c55738fa66a0644e8c7dcc..cc85469699ecbfe37ecf0d8d123b944af4fb6a10 100644 GIT binary patch literal 94562 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 Jlu4O=_&+8=@vi^? literal 98642 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�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�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 Yhi{VLr!Tm=3kvuW7m*RJ6x8$oKlO0?Y5)KL diff --git a/docs/en_US/images/toolbar.png b/docs/en_US/images/toolbar.png index aac16b967b93b44576bf2a042b989aa296251648..30223d28acfa9d12d4cf7e9122675249045dfd36 100644 GIT binary patch literal 55279 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 CNuNOg literal 42931 zcmZ^~19&IjvMwCkwr$&(*tYFoY}>YtiEY~xPHZO=JGt}Ud!KvGz2E)1pVh0n>V2zf z^{RfJW~8FL1Uw853=j|yyp*JvG7u1m*k8F13gYjUkY=b72nbHzN>o%)N>r3c5#V5M zWorfmBpI2i0ja4nfsv=9EM*x8B?;XVNdg6yfFcr2M5Kn4ngE6(9Rn>q5=U3PtF4F( z?kcV!j;04oWHX|VF><Yq0ZT)Bu}{OHx?K`b+k4k@@9TV%&ua0d!ounf0n~%jE1MR6 z4w}G7pD-p7Qa@T=)*u-V1acYxkrM!IP>|rXzh4BL68J25^yq2{e-xD+b+PgFO#>m4 zC;|k80_jwyNIV|yK?vm0AVk3k6fhp<wP6L$f-WDvCW!zVqFFY$j-y*Nn2DoX+A0-u zBGL^C#1cD~ZUI`b0ryxVBFu5P&;#AjrAn0uQXmn=rATxPOB@&Cq3QR9h92hDPkj%Y zcj@nFjsUoOT@Thwj@BM8L<yyf7d-f;8~aZC;5!OHgj};U_B8FLvCwSG?ocUG&46%f zV`HVjFcyv2kq)u;j!>%7#Lg^fkeC67VW`126uD$L4F4f)i{RAG#z>)EJvW^ca!(Y- z3YN=2y-RLA#(+jWh|-+Hen)-V0LmpZdt^Dr@#o08kLDe9a+54B?Ym5K7<boSjZ9uP zFarkY2Ym|Jm{1LDLm~+$v9w9>I$C50GbjhZteeJ<H)5T{N-QFbP-ZSEe9Y#`>@_OT zr$M<P1haTV4SauCQqH&j3Z$3E4>bZ;Tv>h*C|;6Tz>5g8kcv$<nRkUEiNflB<az=| zWWUA4+tkxZ+dGGDGFtJ>j)+4AjlyzlzZiBmWa-brLSs<7m|Tv>4+MYN914PNBr#A1 zC~&%h5PDQuU~Zwsm8~Use=Dy+V8U@>4kTdCpXP>QQJoSn`OpPWAJB<VR1jmK72e_n zNaunG*6a$L38mNcs`2CC@x-%`N<@fX>Qxd_kUiwV5{jg+qg_CwS&-RPH#+!`)<rEi zM?j1+4*f}3Kj6rJpbSOMwqp}SydNz5!G_C*oE`OrEc&!n@Q}5n<Rj80bwRS1OGBIL zi!!4-4fxpm9mCo;jpZJYqwfJl0JKibIy*cQfGYs=wzn%h--NjYXmP3rSbS#lL9)IS z9c%MO@q(Aa6@sbc^b%BF6kV{77ge36KQ0Vsacinw8_unMbr>vZLG36R=orH`^sHH3 zV!2`PMz8~8xPjS>G8l%ddN?BRE6)`IJKUao0Epucas7RMDyWg8Uq4>!T@yC@76`HF zwFrV-qpibrkm>05@Au~#4DU;U4}~}IZSrpdEBZ>XZ7j)@y}bu8&H1j-2iR~6{odK} z|I@^9&JXlnv&VAtQsdkW*9O|Yny<y6I0?(nqx(qIza@lNOQm86ZM)|_3GV^qu!|TZ zjD-biEKDK^o@|&q;wUgRz{UhS4Ov=%M+aKnuU!vp3$oEKUk}L^7`%(c1wI=rvy0OX zf1*I?0pZneGapU_1zkuAH;mRGa*3=l3~EFgD2as<J4{+B36T^liA>G{s}+z!iaxGw zN~#?G5rZcbM{JSkc8CEWJQMl)v0aQMEgGu`y9A6M*r<en6G~Bpx?t-<qaBh~ATv+X zjIkBSQ8YGxf6Cqr>KpcC4D@RtBZK`otbv&UBf8W`D+4b(IMpaslYS+jrQiPzW+l+o z<i?R?wqL6qH)kl(1BIc#eBb%c$cwfQ?si0ef8Fl$Ex`wBpga?0JIV(X-=K#GhY?O; zilWq-$eIEdw1x`h9($ssDGGk1fFpYuigN^OWOU?3L|24F<kfKaus%wpsWgBbJi%DX zM;W*>r8%rQ*d@dzb4kieW`$TMk$-&ekgYLASGJbSfs&BIfI^V?S?PiL2~AL%PFylm zSW9|c)~Zmq#6|h70zy^78i+kHOEg#EXAy^@g7S@`!TIUw+Ud)A%&)}L>0gzL>pz`; zob=A}W)aVXj+U1GN@*r<{@GmItkazC!m|}fAgfS}IiEg%aXNPPeCpte-8tmy*(tKs z(Yf3i+nMf~f1&hn`N-v!{1Ej(^Z0bGw{)>me#(35{P_Cj{80Ufc)Bxx!)}Nb!xq6l z&Z%izzqMO4pdy-77;KbLIA1^Pn7rpS6b=_-G_}hD76TqL6O$YxPg;~%j66p*R<UVW zu9U45-%xl<bzpjMHo80-9>be~^(%0~<d`{~<(a9DbqBElYY>|Rr_oY!C}B!;I|Gg# zngcmACG(P{!~AYL#SF(h%cgU)dE%iK+y2;?W7aln-K#0td`mPo><tkejvlwu;?&`| zq9fX~`&IT{?ih30o1TuIgw7PhhAvLWMTdnxnBJLALz|%Wve8%*TwAI}T^qmQE!b>& zzy3~Btp>G*z{dGP(x&wB#|6iQ0IozfS+;Su9*4VKWvlH5-9~Eb&sKgnbvKhM^Y!J8 zPjiI^i;d_jjg9<P|AXDrg#AA~qRB%l5~vb+CW$6J2l$koDha<-%eBj^XT>a9oonxT zPGlG=qSK?-N`D^}(Vm}Q(KzXy{1%8|ns(1{(Y&h1wP)ju(<#*H+4$U>-dh-o4(EjT z7Z|h``yFvaDj)xHczu+2(!2ioBsr95@&hB@7W=g=JUYC;`1e5-<reFvbFD?wNwiXJ zu~_j+eCOH7ADoNF9*yc%2?s)l4)<X9^!QwbFooDT_*P`zxSkB((ez#1ecsjQf*W2z zhdz)#en0=$uGf<{hi8AD-%ibz5626Lptc|{z__41AX<Ugfr1cjU|Nv3!Pdb9U>gvy z!EIoIdtA-{E?%xV(M{1q;&;()$Iter4hhkQ`H1<(`BtW(`jYw<qvt`p!KR^$A#ajy z67wH;v1DRD#2Mnd2by-FJzTr<m<3GC<GGQ=qopIXaUY3(lWP-fv0&iynqNjWxEo)Z zlrYOR5T#*ukv!Swm~1Y!8;l~4jl@<HJahS(e$>4Df{qE9fZjmWrwk)wkn7GpOevAI zmRpgLSE!ZoOGe33PF!U68-7_om@CgJl~&IFC22KbrL*Wo86v02UdXyd+r#$xCN>uN zi!v|Ql!Mw~v2emG`8E039EnAlrPab`ckIsQwI{QCI%}E$SfgJ1k1Q6QF7+h}cm$1@ zLL*2cO=F%pq-ovwH40=T?Z_5Nt?AE0ae33(upG{gh7KL)_j~0#x1;2H);mN=_|lF= zR28~%+5ANY=hW0mp0YPNJ@ys}0`i?AAv9F<8So!}`u&8@N<QR0`<UwMJO5lYA6j{r z<I1MX_c0BbjTT`mL=8s!Wkt@RP21+0@!NdWyf<+-an1@Ko6cJ0+VHlS+Mjescy1i4 zoSe*lx2*NF7riV8rGV3uW02oV6Zm1?>iJgMS9U*)K7Z{vXhtxm(Anx7c3937DVPm5 zIv-shr5+Jtz+&XT8yzC52|h4RXfL)dd7r(R4Vx{Rt)@fL@2DFoDyiN&j;x`_(rVF8 zsrPELdoHg}Dy8D8t7y<_xT}h5u-7%{G}+FCx9qp9R*6=*FK4XMRe3haw_o4A?LNZe z(s86XczhQhj%DMLa&WBhEUDX**wbu2csSo3{}OEQui7wfE%lii`?>fNe`CKbx8lCC zdc(fg*NR`euIA=<V(-D??0oJFygfXwJF|Q04MbOJ*Y^we!O4Yp(Npua*^S+rMPHq{ zpoza0=^|HgL%G!E(n8MfO+Ulwz!i+|w9h`cZ?g;Gi{Rz(7({x0S$<tW`?usm;&yRk z@zz*lJil%3rq}z+%YlYM4DW&)%lToZ%3gU~{&9`~fMR!gpvlhyF~=m|hUdn&_cmxX z^s~?Fv$Joe>*sCJ+{m#^Z@Ttxi8jJsJeSwC)Op(S+Pm7kJ`CrdpI(cP*_?|GE}LlE zK3=ppE73bJ{uf>RHwb(3>w2GEsn63l%U{<Y@3jawaiY(nHwGRFe|Dcl2Zk)-(c%SM z()h{*YkiC#ORg)&eg*68>7{>V{E;|eU2p2WUKE7?s`0#j@YyjK@Yg%V-ud+^@>TSG zGr}lmVDHO*u4dz)d(*S}TKB%4(!=iCb%p=Fb@ohslm8(1F7&4OxbSK+RbHXs{&xTV zZsx;n;EUF8DB9Er^x{nm^q>lamA?CG6m*<djv?mEsYd!Izy6q^0>c3aXII8m_k;l4 zkkc07o`}=7s@ThzNr;~xGFu%@D~|w&0jK*GY5VE9uNf#{38Y`b)8Bum^Xn@<+o-+` zh>J(fxla`uc^lpjPOVUfmICgDFvTCZlgWR|Llao>?+r$pnWmJvoE#9%Ul|Gr92f-% z^sfZ`cLf5*0RsP*3<M+%jQhW3WnilRU_gL?!mWV7{)5r}+yAp9{B3{P|LH-K!hj(E z?xFl`Aq61+g$5BT0R1l+sPC^0NLWQwO6qT~VgfKTvv;<1aETa?u>Pxnc9hg|1_Ht$ z|EB><DU<#Adxzv~rK;(oDJRQg;$X*MWa?mS#^7P+_>UhTJ`bM1qMezG5s`<Tt-Ujk z2S3Tb5Ile7f7Fa5ME`=g*zl8R$|(|wIsnXw*csRum`DU*h=_>z0H)?V%3?qML;t(S zPh#of;>g3u=<e>$;Lgh60I*<W=H}*RWMW}tVWIzvpm+APcQNvyw|6G}x0C<!BWC7o z0<dy)v2w5{`p2)4v4g7%KMBb{f&TaM?>t?s%>O%*z4L#D^>=`b|5zBA8JHOVUo<lh ztN$O`KbC*f{xz<DhvWOl8IJ<M%It5#|D+|r%=fPV|A+3s)B87G+05C&*7YB_n!S~a z0Ly<U|CjoIu>OhtxA@Eeq7HU;e?tlU_q_5k{(p@BH&M~b!^~Dw%<3=G`JWUySpP=+ z7wiAF{6Cpm|IK7!;`*P=|6%zLlaKMAY55=1^zRz@m-cTF2*B_${_lbkfFZDUCItc# z0+JFFR`meB^o2A`TYh|=*!E5oM^Tqt!xdhKirA?7*|KbHSFLWN^BworvW)O^+1lo3 z)6XV(RmHMkdLr*IbSTrr9(R!!zrOcwPS3kLa}<&O6QOO3EzfJ7=b8(bvHTr@<#|VC zgtC*!?CPc*9&!v#ta>IxqyE8wP+(Y442WJeEJrs003{mYO}(W<P3s>W9o&CF2%xj& zbZH6r(lrwQQ@^_r25h0e2K`O<f4HK9^U+}j3W6eOQi<JJdDD4p{hxv8;3BG%_mN%W zF%q+*o7xZNma+LLS#mRMb*9Uodfm$cXNi9Ph=9M4->)lF@^A?JcY6O$<<He%K(%ml zvv`XO9Pze2gR-g?Z8mJRSkyUKiulH`;#d;@RH32+ijY173jR6u#K89A=_TDGC4Jnw z){pMg?*I06`ggdc%8!}nNS>Ws6L;Ox9sYo#4|`R?GeUHd*<F-Jw|n-xAVYIX@>KT5 zd&k!9Uh8<()HIp;x^j}J*&NwRH9I@>(f>Ml|72$g4qD6BbwfiN?zAQJc*xN?uF=;i zJ&H(3q_0l^@^;!CycdjW`ZY3ixEy+6Ht@R#<@$siJ{F_=wA)6qy8pkAb^$Dw<CO>= zdMI0bTXizs)X%i#Z}(JLe8CcG>e6u0Cs@$i-#P>80*fI8NU!3dkP~wbImF^e%Z=nm z?H-+7lTuM%bX>GpOzw#HpIQ^s(o6rHWpf~~XlW;`x_KTEQJPuG<P@iDf|N<J8b&O~ zexNZ`)O1#D_f4#SD}d%CrNEm?01o<3;=4l@F)l66Fe=QxZUz0RJ{;9PWIID0FLmnU zr~&qMWtZ7rm$#E$sri4^68=y?p{N*!6s2(FNENP`qHTM7;2L-2$TT?E@GFcM@MAS} zuYf+l#JJ?}5G|r9TBhy@C2`k<EH7k0x2`44M8O7VPZvVOQp}}3Mmi31j}E}bYM|T% zTZ**F&8U&CKclIdJN(x0pPCAUg#p!DBqot4ML5Y1m3R}i7@rc7Jh7_MkB}@zsU-?Z zG8R4BZNP(m3|*TZxT_K2sc538@+tzPwmdeL!eRL0XcC|qX4G|scyv&U3Vv2{>T2<! zh_Vx{5%fAm>2iAKv<JT|)ZZ(XeLT*f1BjXwLHM^0O%+H~Fb6xe|8oxYx1oSahgUSk zVRzIk@nBpY!y!ZspaX<(U9bwHn2Rw5k#sDQ)WccrNDEM9Z+iGQO9)cQPR0pRSh%-0 z2)zfr+5^l$-G3|wym3WX=c}gYSC*sWpEIt;Algu@W>ButOUS2;=hdK;9*nr1)Atvp zEOAcuq{k=U%w(?xMK42vKP3hmA8K&UB<=JxYQjua4Nu|c6zQveZ3jtI<Na4@&3|Gs zrBrpb18{9p5747wTlok2_gQHzknnU*B_o(yVe@8E#-!-t$attwcsK(Z+Y)c7Q*Ndf zd7uLbQX#^gg*@+V&P|*1yTH8Kalld$=3_OCOJPDrNZV$T8>F1dOS{bsvOYdu=Y(2T zK*MM0q2hmmJnu$pD@HYZ<*|598>UuwxUN%Dx#4HyQ5GKr9T{Xxo2G=fjgX%YJT){n z{%c12+ps}7Xj$(Um-tT=hh=fW;03v{?HdbaVZk>ht)0NzCc@3%$r6CF3P_xm2u|y1 z@CMrmi+`f0Mr&1~rjbUAmncP-SB?+|e+dZ^+thAR}0*tkzTJ&-^@xe405Nr*v5 z60hiZua+ry;fg7K_3E<_O)DT+97g9;LKn53|7P7;BN$Gl%}QJGhS9dtXm#fY$<e~a z(bDY09|Ibr+la_UhxLL0^|H5N_J5RJQD@izz-jv4JRlgNX1adEd7OI09iE`m$j48n zv4LXRBD!Pqmk?rDQA%;=5UZu8CZ(yA4D$)h<3_?fr3(9!lCjZ=?Z1IlR_LCl7E5&9 z(K4X*I_Z&z3xiT(p65FTSrp^$ovNHZkf)LK{n|NC(bmsYpic?(=W^)Q6|i%eiZ3g# zI@k8J+ri1aI@nYE9!G1QYO`(VeDgvwvsbL)u<k#K5%O6uj-H&{+G(VTmjABD<6A6k zE)#A9M3?xxROEyZWT_9AdxN43gO{o$>1fk8Af@l6f^WqD>u7Mto*Eh47PVt?)s?FE zg6EC`o#2ET6eu_-|CSEnavy6R@vMU2qWm43xT#)~wu9A1>e&)w#;=9dKZ@oX@0;d3 zmt_-6PzXgLN9|@osnvTH@UdSxXVe%<$JGZoB>b6>?SM`G-0n3#Kzata2+uCP)nrad z<Re>Hm8)8yIa5V(b4tyZlTBDZfS4>z4v(%&@7fPJ1ppvroU%!RY|Yh=mR*(O!PABn z>-*eM6NR?WNOhY$rh4<}^d%@rEDL1R?TU5T%|f&lGg`Tej_2VNt|>X;c!;bzM)pDV zN}AY>l<<zBmWE>xhgBRv@?15PRTv%UKYt{>OUO{^;#oS1^ES4_YS^bb#9>N<wcA+0 zI`GWhKb}J~6hQg}w5;}?*6u1QcY7)CB}JF>svB|ccH->Il#)V{)!(cVZCbZyo!%Ui zF%w*s`}Xc%+oo*b+bSSF*hTqtAUgraZRx=$dcyy?jCe10@`H+)8x3Mx_yrA%7LhHF zmM}){guoN(8Sv_2if|!zr#{cY)ZcIt$2{J!rq%7Nt1fy}7#Dnx2Xvx^a==TgAWabE zn8-Ox$PamR8mmRq^xiZe0Tot$vW`kR0vnuW>j6_}jUqZcc2?5eZW!z1dKw}d%${<S zAt^f@D_2xni1f(Co0~)r$$Hf1&3Yt^S9yCuIGqL*5%@4%gyAC#B4Je4^X=Gq7=)S% zSt}x^7p$#H3erv9>p+Oj+T14w_B#1hyx!<J=6CA|=>$>~jh~d;zOb%Vn<1e6VQ9WX zaMdqWThuCioyRUB0^+NNlhsv-i{V_9RS<?4k+$$TbQHX#n<-^em&_x!S_?tE##$6Z zVGJX_{9<3Xq-zO%6{*7&2^MhQL`kplb(c>LxQbC?VG@vzB$!~=ZXy>K(C?C95<vIc z(D`#UwY&gW8{;*|Q_BZeRzJ~@)Pv?k@c2cO^e1*hz!sD;%rlyDxJ#{GdK$%oTX&hL zIN%WIw1e3T*+<CNVxQ>sC5t*KE0OkFvtA!?FEb2pvI>y>?R8`5e=me<YJ9z}p-Kx} z=*Pmdqyeb5HoHkQhQ4(gXhLkaca$;y9dr+L*_=ev@w!je;Wdf{{cxXhvaL;=e>s~H z0yKwVq%)N(YX2Guz((1p6gNXp!m>QwXo%0D-NlnK%<oL#WUV3Obj&<*1=JUG#xkE) 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 K<4QTJ@c#j4GvEOL diff --git a/docs/en_US/psql_tool.rst b/docs/en_US/psql_tool.rst new file mode 100644 index 00000000..229a2c5a --- /dev/null +++ b/docs/en_US/psql_tool.rst @@ -0,0 +1,19 @@ +.. _psql_tool: + +****************** +`PSQL Tool`:index: +****************** + +PSQL tool allows user to connect to PostgreSQL server using psql terminal. + +* Open PSQL Tool from Tools menu or context menu PSQL Tool from tree view. + +* PSQL will connect to the selected database from browser tree. + +.. image:: images/psql_tool.png + :alt: PSQL tool window + :align: center + +You can open multiple instance of the PSQL tool in individual tabs simultaneously. +To close the PSQL tool, click the *X* in the upper-right hand corner of the tab bar. + diff --git a/docs/en_US/toolbar.rst b/docs/en_US/toolbar.rst index f4c685f2..60ddc247 100644 --- a/docs/en_US/toolbar.rst +++ b/docs/en_US/toolbar.rst @@ -20,4 +20,6 @@ the selected browser node. * Use the :ref:`Filtered Rows <viewdata_filter>` button to access the Data Filter popup to apply a filter to a set of data for viewing/editing. * Use the :ref:`Search objects <search_objects>` button to access the search objects - dialog. It helps you search any database object. \ No newline at end of file + dialog. It helps you search any database object. +* Use the :ref:`PSQL Tool <psql_tool>` button to open the PSQL Tool in the selected + database context. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index edd7000b..8227a4c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,6 @@ # ############################################################################### -cheroot==8.* Flask==1.* Flask-Gravatar==0.* Flask-Login==0.* @@ -36,3 +35,5 @@ sshtunnel==0.* ldap3==2.* Flask-BabelEx==0.* gssapi==1.6.* +flask-socketio>=5.0.1 +eventlet==0.30.2 diff --git a/web/config.py b/web/config.py index 2643ef19..002a9951 100644 --- a/web/config.py +++ b/web/config.py @@ -156,8 +156,8 @@ X_FRAME_OPTIONS = "SAMEORIGIN" # such as JavaScript, CSS, or pretty much anything that the browser loads. # see https://content-security-policy.com/#source_list for more info # e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';" -CONTENT_SECURITY_POLICY = "default-src http: data: blob: 'unsafe-inline' " \ - "'unsafe-eval';" +CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \ + " 'unsafe-eval';" # STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the # Strict-Transport-Security header @@ -636,6 +636,19 @@ KRB_AUTO_CREATE_USER = True KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache') +# PSQL tool settings +# This will enable PSQL tool in pgAdmin. So user can execute the commands using +# PSQL terminal in pgAdmin. +ENABLE_PSQL = True + +# ALLOW_PSQL_SHELL_COMMAND = True will disable the execution of os level +# commands using meta command \! from PSQL terminal. +# As PSQL allow user to execute the os level commands from the PSQL terminal +# user can execute any system level command as per the system login user +# privileges. Default this setting is set to False but if it set to True +# User will able to execute the system level commands through PSQL terminal in +# pgAdmin. +ALLOW_PSQL_SHELL_COMMANDS = False ########################################################################## # Local config settings diff --git a/web/package.json b/web/package.json index 8ed32df9..19110fda 100644 --- a/web/package.json +++ b/web/package.json @@ -117,13 +117,18 @@ "shim-loader": "^1.0.1", "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16", "snapsvg-cjs": "^0.0.6", + "socket.io-client": "^4.0.0", "split.js": "^1.5.10", "tablesorter": "^2.31.2", "tempusdominus-bootstrap-4": "^5.1.2", "tempusdominus-core": "^5.0.3", "underscore": "^1.13.1", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36", - "wkx": "^0.5.0" + "wkx": "^0.5.0", + "xterm": "^4.11.0", + "xterm-addon-fit": "^0.5.0", + "xterm-addon-search": "^0.8.0", + "xterm-addon-web-links": "^0.4.0" }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index d2bd1af6..dc1924cb 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -13,7 +13,7 @@ to start a web server.""" import sys -from cheroot.wsgi import Server as CherootServer + if sys.version_info < (3, 4): raise RuntimeError('This application must be run under Python 3.4 ' @@ -37,7 +37,7 @@ else: builtins.SERVER_MODE = None import config -from pgadmin import create_app +from pgadmin import create_app, socketio from pgadmin.utils import u_encode, fs_encoding, file_quote from pgadmin.utils.constants import INTERNAL # Get the config database schema version. We store this in pgadmin.model @@ -97,6 +97,8 @@ if not os.path.isfile(config.SQLITE_PATH): ########################################################################## app = create_app() app.debug = False +app.config['sessions'] = dict() + if config.SERVER_MODE: app.wsgi_app = ReverseProxied(app.wsgi_app) @@ -206,17 +208,16 @@ def main(): else: # Can use cheroot instead of flask dev server when not in debug # 10 is default thread count in CherootServer - num_threads = 10 if config.THREADED_MODE else 1 - prod_server = CherootServer( - (config.DEFAULT_SERVER, config.EFFECTIVE_SERVER_PORT), - wsgi_app=app, - numthreads=num_threads, - server_name=config.APP_NAME) + # num_threads = 10 if config.THREADED_MODE else 1 try: - print("Using production server...") - prod_server.start() + socketio.run( + app, + host=config.DEFAULT_SERVER, + port=config.EFFECTIVE_SERVER_PORT, + ) except KeyboardInterrupt: - prod_server.stop() + print("CLOSE SERVER") + socketio.stop() except IOError: app.logger.error("Error starting the app server: %s", sys.exc_info()) diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index a7333537..fad91082 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -19,6 +19,7 @@ from collections import defaultdict from importlib import import_module from flask import Flask, abort, request, current_app, session, url_for +from flask_socketio import SocketIO from werkzeug.exceptions import HTTPException from flask_babelex import Babel, gettext from flask_babelex import gettext as _ @@ -52,10 +53,15 @@ import mimetypes mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('text/css', '.css') + winreg = None if os.name == 'nt': import winreg +socketio = SocketIO(manage_session=False, async_mode='eventlet', + logger=False, engineio_logger=False, debug=False, + ping_interval=25, ping_timeout=120) + class PgAdmin(Flask): def __init__(self, *args, **kwargs): @@ -811,4 +817,5 @@ def create_app(app_name=None): ########################################################################## # All done! ########################################################################## + socketio.init_app(app) return app diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 235db027..d835ca82 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -10,6 +10,7 @@ from flask_babelex import gettext from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\ PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \ PREF_LABEL_OPTIONS +from flask_security import current_user import config LOCK_LAYOUT_LEVEL = { @@ -511,10 +512,12 @@ def register_browser_preferences(self): options=[{'label': gettext('Query Tool'), 'value': 'qt'}, {'label': gettext('Debugger'), 'value': 'debugger'}, {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], - help_str=gettext('Select Query Tool, Debugger, or Schema Diff from ' - 'the drop-down to set open in new browser tab for ' - 'that particular module.'), + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext('Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), select2={ 'multiple': True, 'allowClear': False, 'tags': True, 'first_empty': False, @@ -523,3 +526,16 @@ def register_browser_preferences(self): 'placeholder': gettext('Select open new tab...') } ) + + self.psql_tab_title = self.preference.register( + 'tab_settings', 'psql_tab_title_placeholder', + gettext("PSQL tool tab title"), + 'text', '%DATABASE%/%USERNAME%@%SERVER%', + category_label=PREF_LABEL_DISPLAY, + help_str=gettext( + 'Supported placeholders are %DATABASE%, %USERNAME%, and %SERVER%. ' + 'Users can provide any string with or without placeholders of' + ' their choice. The blank title will be revert back to the' + ' default title with placeholders.' + ) + ) diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index f4165c32..fb7ff12c 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -34,6 +34,7 @@ from pgadmin.utils.constants import UNAUTH_REQ, MIMETYPE_APP_JS, \ SERVER_CONNECTION_CLOSED from sqlalchemy import or_ from pgadmin.utils.preferences import Preferences +from .... import socketio as sio def has_any(data, keys): @@ -1499,6 +1500,13 @@ class ServerNode(PGChildNodeView): # Release Connection manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + # Check if any psql terminal is running for the current disconnecting + # server. If any terminate the psql tool connection. + if 'sid_soid_mapping' in current_app.config and str(sid) in \ + current_app.config['sid_soid_mapping']: + if str(sid) in current_app.config['sid_soid_mapping']: + for i in current_app.config['sid_soid_mapping'][str(sid)]: + sio.emit('disconnect-psql', namespace='/pty', to=i) status = manager.release() diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 01ab89c5..eb20cac5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -122,6 +122,9 @@ define('pgadmin.node.database', [ is_connected: function(node) { return (node && node.connected == true && node.canDisconn == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, is_conn_allow: function(node) { return (node && node.allowConn == true); }, diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 45dea090..ffd715f8 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -101,7 +101,8 @@ define('pgadmin.node.server', [ icon: 'fa fa-unlink', enable : 'is_connected',data: { data_disabled: gettext('Database is already disconnected.'), }, - },{ + }, + { name: 'reload_configuration', node: 'server', module: this, applies: ['tools', 'context'], callback: 'reload_configuration', category: 'reload', priority: 6, label: gettext('Reload Configuration'), @@ -728,6 +729,14 @@ define('pgadmin.node.server', [ return false; }, + /* Open psql tool for server*/ + server_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + } }, model: pgAdmin.Browser.Node.Model.extend({ defaults: { diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index 3823ef35..e763aa11 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -64,6 +64,14 @@ define([ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', }]); + + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); } } }, @@ -498,6 +506,13 @@ define([ pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); } }, + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, }); return pgBrowser.Collection; diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index 1c5af3f5..9680af2e 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -209,6 +209,16 @@ define('pgadmin.browser.node', [ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', enable: enable, }]); + + if(pgAdmin['enable_psql']) { + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); + } } // This will add options of scripts eg:'CREATE Script' @@ -902,6 +912,15 @@ define('pgadmin.browser.node', [ pgAdmin.DataGrid.show_query_tool('', i); }, + // Callback to render psql tool. + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, + // Logic to change the server background colour // There is no way of applying CSS to parent element so we have to // do it via JS code only diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js index c9e64132..3068aabe 100644 --- a/web/pgadmin/browser/static/js/panel.js +++ b/web/pgadmin/browser/static/js/panel.js @@ -122,10 +122,30 @@ define( myPanel.on(ev, that.handleVisibility.bind(myPanel, ev)); }); } + + // Listen on detach panel event + myPanel.on(wcDocker.EVENT.DETACHED, function(obj) { + that.setCodeMirrorHeight(obj); + }); }, }); } }, + setCodeMirrorHeight: function() { + // Fix for mac os code-mirror showing black screen. + var txtArea = $('.pg-panel-content .sql_textarea > textarea').first(); + txtArea.css('z-index', -1); + var $tabContent = $('.pg-panel-content > .sql_textarea').first(); + var $sqlPane = $tabContent.find('.CodeMirror > div > textarea'); + for(let i=0; i<$sqlPane.length; i++) {$($sqlPane[i]).css('z-index', -1);} + + $tabContent = $('.pg-panel-content > .sql_textarea').first(); + $sqlPane = $tabContent.find('.pg-panel-content'); + $sqlPane.find('.CodeMirror').css( + 'cssText', + 'height: ' + ($tabContent.height()) + 'px !important;' + ); + }, eventFunc: function(eventName) { var name = $(this).data('pgAdminName'); diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index 09baaf22..65e29c85 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -56,9 +56,23 @@ let _defaultToolBarButtons = [ toggleClass: '', parentClass: 'pg-toolbar-btn btn-primary-icon', enabled: false, - }, + } ]; +if(pgAdmin['enable_psql']) { + _defaultToolBarButtons.push({ + label: gettext('PSQL Tool'), + ariaLabel: gettext('PSQL Tool'), + btnClass: 'fas fa-terminal', + text: '', + toggled: false, + toggleClass: '', + parentClass: 'pg-toolbar-btn btn-primary-icon pg-toolbar-psql', + enabled: false, + }); +} + + // Place holder for non default tool bar buttons. let _otherToolbarButtons = []; @@ -105,6 +119,13 @@ export function initializeToolbar(panel, wcDocker) { pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected()); else if ('name' in data && data.name === gettext('Search objects')) pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); + else if ('name' in data && data.name === gettext('PSQL Tool')){ + var input = {}, + t = pgAdmin.Browser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgAdmin.Browser.psql.psql_tool(d, i, true); + } }); } diff --git a/web/pgadmin/browser/static/scss/_browser.scss b/web/pgadmin/browser/static/scss/_browser.scss index 0d157384..ae72f0e6 100644 --- a/web/pgadmin/browser/static/scss/_browser.scss +++ b/web/pgadmin/browser/static/scss/_browser.scss @@ -53,3 +53,9 @@ samp, border-width: 1px; font-size: 1.15em; } + +.pg-toolbar-psql { + padding-top: 0em; + font-size: inherit; + align-items: center; +} diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 8597df48..b0a317a5 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -52,6 +52,10 @@ define('pgadmin.browser.utils', pgAdmin['user_inactivity_timeout'] = {{ current_app.config.get('USER_INACTIVITY_TIMEOUT') }}; pgAdmin['override_user_inactivity_timeout'] = '{{ current_app.config.get('OVERRIDE_USER_INACTIVITY_TIMEOUT') }}' == 'True'; + /* GET PSQL Tool related config */ + pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; + // Define list of nodes on which Query tool option doesn't appears var unsupported_nodes = pgAdmin.unsupported_nodes = [ 'server_group', 'server', 'coll-tablespace', 'tablespace', diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py index 312b0ee1..5e22f2d5 100644 --- a/web/pgadmin/browser/utils.py +++ b/web/pgadmin/browser/utils.py @@ -62,7 +62,8 @@ def underscore_unescape(text): ">": '>', """: '"', "`": '`', - "'": "'" + "'": "'", + "'": "'" } # always replace & first diff --git a/web/pgadmin/static/bundle/browser.js b/web/pgadmin/static/bundle/browser.js index 14140a2f..0b3ad81b 100644 --- a/web/pgadmin/static/bundle/browser.js +++ b/web/pgadmin/static/bundle/browser.js @@ -11,6 +11,7 @@ define('bundled_browser',[ 'pgadmin.browser', 'sources/browser/index', 'top/tools/erd/static/js/index', + 'top/tools/psql/static/js/index', ], function(pgBrowser) { pgBrowser.init(); }); diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css index c2a776c8..5b4a9f2d 100644 --- a/web/pgadmin/static/css/style.css +++ b/web/pgadmin/static/css/style.css @@ -21,3 +21,5 @@ @import '../vendor/backgrid/backgrid.css'; @import '../vendor/backgrid/backgrid-select-all.css'; + +@import 'node_modules/xterm/css/xterm.css'; diff --git a/web/pgadmin/static/scss/pgadmin.scss b/web/pgadmin/static/scss/pgadmin.scss index 6c38c6f7..2e5bc6d9 100644 --- a/web/pgadmin/static/scss/pgadmin.scss +++ b/web/pgadmin/static/scss/pgadmin.scss @@ -10,6 +10,11 @@ $theme-colors: ( --color-fg: #{$color-fg}; --color-bg: #{$color-bg}; --border-color: #{$border-color}; + --psql-background: #{$psql-background}; + --psql-foreground: #{$psql-foreground}; + --psql-cursor: #{$psql-cursor}; + --psql-cursorAccent: #{$psql-cursorAccent}; + --psql-selection: #{$psql-selection}; } @import "bootstrap/scss/bootstrap"; diff --git a/web/pgadmin/static/scss/resources/_default.variables.scss b/web/pgadmin/static/scss/resources/_default.variables.scss index ce33424e..d9fb6653 100644 --- a/web/pgadmin/static/scss/resources/_default.variables.scss +++ b/web/pgadmin/static/scss/resources/_default.variables.scss @@ -371,3 +371,10 @@ $erd-link-selected-color: $color-fg !default; $erd-bg-grid: url("data:image/svg+xml, %3Csvg width='100%25' viewBox='0 0 45 45' style='background-color:#{url-friendly-colour($erd-canvas-bg)}' height='100%25' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cpattern id='smallGrid' width='15' height='15' patternUnits='userSpaceOnUse'%3E%3Cpath d='M 15 0 L 0 0 0 15' fill='none' stroke='#{url-friendly-colour($erd-canvas-grid)}' stroke-width='0.5'/%3E%3C/pattern%3E%3Cpattern id='grid' width='45' height='45' patternUnits='userSpaceOnUse'%3E%3Crect width='100' height='100' fill='url(%23smallGrid)'/%3E%3Cpath d='M 100 0 L 0 0 0 100' fill='none' stroke='#{url-friendly-colour($erd-canvas-grid)}' stroke-width='1'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='100%25' height='100%25' fill='url(%23grid)' /%3E%3C/svg%3E%0A"); $select2-readonly: $color-gray-lighter !default; + +// psql tool variables +$psql-background: $color-bg !default; +$psql-foreground: $color-fg !default; +$psql-cursor: $color-fg !default; +$psql-cursorAccent: $color-fg !default; +$psql-selection: #326690 !default; diff --git a/web/pgadmin/static/scss/resources/dark/_theme.variables.scss b/web/pgadmin/static/scss/resources/dark/_theme.variables.scss index efa36df8..2fa907b8 100644 --- a/web/pgadmin/static/scss/resources/dark/_theme.variables.scss +++ b/web/pgadmin/static/scss/resources/dark/_theme.variables.scss @@ -136,3 +136,10 @@ $erd-link-color: $color-fg; $erd-link-selected-color: $color-fg; $select2-readonly: $color-bg; + +// psql tool variables +$psql-background: $color-bg; +$psql-foreground: $color-fg; +$psql-cursor: $color-fg; +$psql-cursorAccent: $color-fg; +$psql-selection: #d6effc; diff --git a/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss b/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss index 682f2622..b4783bce 100644 --- a/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss +++ b/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss @@ -207,3 +207,10 @@ $quick-search-a-text-color: $black !default; $quick-search-info-icon: #8A8A8A !default; $select2-readonly: $color-gray; + +// psql tool variables +$psql-background: $color-bg; +$psql-foreground: $color-fg; +$psql-cursor: $color-fg; +$psql-cursorAccent: $color-fg; +$psql-selection: $color-primary-light; diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js index 1348cc45..42efc04d 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js @@ -100,6 +100,10 @@ export function generateTitle(title_placeholder, title_data) { title_placeholder = title_placeholder.replace(new RegExp('%ARGS%'), _.unescape(title_data.args)); title_placeholder = title_placeholder.replace(new RegExp('%SCHEMA%'), _.unescape(title_data.schema)); title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + } else if(title_data.type == 'psql_tool') { + title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + title_placeholder = title_placeholder.replace(new RegExp('%USERNAME%'), _.unescape(title_data.username)); + title_placeholder = title_placeholder.replace(new RegExp('%SERVER%'), _.unescape(title_data.server)); } return _.escape(title_placeholder); diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py new file mode 100644 index 00000000..30b5237c --- /dev/null +++ b/web/pgadmin/tools/psql/__init__.py @@ -0,0 +1,686 @@ +#!/usr/bin/env python3 +import fcntl +import os +import pty +import re +import select +import struct +import termios +import config +import eventlet.green.subprocess as subprocess + +from config import PG_DEFAULT_DRIVER +from flask import Response, url_for, request +from flask import render_template, copy_current_request_context, \ + current_app as app +from flask_babelex import gettext +from flask_security import login_required, current_user +from pgadmin.browser.utils import underscore_unescape +from pgadmin.utils import PgAdminModule +from pgadmin.utils.constants import MIMETYPE_APP_JS +from pgadmin.utils.driver import get_driver +from ... import socketio as sio +from pgadmin.utils import get_complete_file_path + + +session_input = dict() +session_input_cursor = dict() +session_last_cmd = dict() +pdata = dict() +cdata = dict() + + +class PSQLModule(PgAdminModule): + """ + class PSQLModule(PgAdminModule) + A module class for PSQL derived from PgAdminModule. + """ + + LABEL = gettext("PSQL") + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.psql', + 'path': url_for('psql.index') + "psql", + 'when': None + }] + + def get_panels(self): + return [] + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints for PSQL module + """ + return [ + 'psql.panel' + ] + + +blueprint = PSQLModule('psql', __name__, static_url_path='/static') + + [email protected]("/psql.js") +@login_required +def script(): + """render the required javascript""" + return Response( + response=render_template("psql/js/psql.js", _=gettext), + status=200, + mimetype=MIMETYPE_APP_JS + ) + + [email protected]('/panel/<int:trans_id>', + methods=["POST"], + endpoint="panel") +@login_required +def panel(trans_id): + """ + Return panel template for PSQL tools. + :param trans_id: + """ + params = { + 'trans_id': trans_id, + 'title': request.form['title'] + } + if 'sid_soid_mapping' not in app.config: + app.config['sid_soid_mapping'] = dict() + if request.args: + params.update({k: v for k, v in request.args.items()}) + # Set TERM env for xterm. + os.environ['TERM'] = 'xterm' + + return render_template('editor_template.html', + sid=params['sid'], + db=underscore_unescape(params['db']) if params[ + 'db'] else 'postgres', + server_type=params['server_type'], + is_enable=config.ENABLE_PSQL, + title=underscore_unescape(params['title']), + theme=params['theme'] + ) + + +def set_term_size(fd, row, col, xpix=0, ypix=0): + """ + Set the terminal size as per UI xterm size. + :param fd: + :param row: + :param col: + :param xpix: + :param ypix: + """ + term_size = struct.pack('HHHH', row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) + + [email protected]('connect', namespace='/pty') +def connect(): + """ + Connect to the server through socket. + :return: + :rtype: + """ + if config.ENABLE_PSQL: + sio.emit('connected', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + if request.sid in session_last_cmd: + session_last_cmd[request.sid]['is_new_connection'] = False + else: + session_last_cmd[request.sid] = {'cmd': '', 'arrow_up': False, + 'invalid_cmd': False, + 'is_new_connection': False} + else: + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def create_pty_terminal(connection_data): + # Create the pty terminal process, parent and fd are file descriptors + # for parent and child. + parent, fd = pty.openpty() + p = None + if parent is not None: + # Child process + p = subprocess.Popen(connection_data, + preexec_fn=os.setsid, + stdin=fd, + stdout=fd, + stderr=fd, + universal_newlines=True + ) + + app.config['sessions'][request.sid] = parent + pdata[request.sid] = p + cdata[request.sid] = fd + else: + app.config['sessions'][request.sid] = parent + cdata[request.sid] = fd + set_term_size(fd, 50, 50) + + return p, parent, fd + + +def read_terminal_data(parent, data_ready, max_read_bytes, sid): + """ + Read the terminal output. + :param parent: + :param data_ready: + :param max_read_bytes: + :param sid: + :return: + """ + if parent in data_ready: + # Read the output from parent fd (terminal). + output = os.read(parent, max_read_bytes) + emit_output = True + + if sid in session_last_cmd and session_last_cmd[sid][ + 'arrow_up'] and not session_last_cmd[request.sid][ + 'arrow_left_right']: + session_last_cmd[sid]['cmd'] = output.decode() + session_input_cursor[request.sid] = len( + session_last_cmd[sid]['cmd']) + session_last_cmd[sid]['arrow_up'] = True + + if sid in session_last_cmd and session_last_cmd[sid]['invalid_cmd']: + # If command is invalid then emit error to user. + emit_output = False + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security\r\n"), + 'error': True + }, + namespace='/pty', room=sid) + # If command is valid then emit output to user. + if emit_output: + sio.emit('pty-output', + {'result': output.decode(), + 'error': False}, + namespace='/pty', room=sid) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + + [email protected]('start_process', namespace='/pty') +def start_process(data): + """ + Start the pty terminal and execute psql command and emit results to user. + :param data: + :return: + """ + @copy_current_request_context + def read_and_forward_pty_output(sid, data): + max_read_bytes = 1024 * 20 + + p, parent, fd = create_pty_terminal(connection_data) + + while p and p.poll() is None: + if request.sid in app.config['sessions']: + # This code is added to make this unit testable. + if "is_test" not in data: + sio.sleep(0.01) + else: + data['count'] += 1 + if data['count'] == 5: + break + + timeout = 0 + # module provides access to platform-specific I/O + # monitoring functions + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) + + read_terminal_data(parent, data_ready, max_read_bytes, sid) + + # Check user is authenticated and PSQL is enabled in config. + if current_user.is_authenticated and config.ENABLE_PSQL: + connection_data = [] + try: + db = '' + if data['db']: + db = underscore_unescape(data['db']).replace('\\', "\\\\") + + conn, manager = _get_connection(int(data['sid']), data) + psql_utility = manager.utility('sql') + connection_data = get_connection_str(psql_utility, db, + manager) + except Exception as e: + # If any error raised during the start the PSQL emit error to UI. + # request.sid: This sid is socket id. + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + + try: + if str(data['sid']) not in app.config['sid_soid_mapping']: + # request.sid: refer request.sid as socket id. + app.config['sid_soid_mapping'][str(data['sid'])] = list() + app.config['sid_soid_mapping'][str(data['sid'])].append( + request.sid) + else: + app.config['sid_soid_mapping'][str(data['sid'])].append( + request.sid) + + sio.start_background_task(read_and_forward_pty_output, + request.sid, data) + except Exception as e: + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + else: + # Show error if user is not authenticated. + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def _get_connection(sid, data): + """ + Get the connection object of ERD. + :param sid: + :param did: + :param trans_id: + :return: + """ + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + try: + conn = manager.connection() + # This is added for unit test only, no use in normal execution. + if 'pwd' in data: + kwargs = {'password': data['pwd'], "user": data['user']} + status, msg = conn.connect(**kwargs) + else: + status, msg = conn.connect() + if not status: + app.logger.error(msg) + sio.emit(sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}' + ''.format('Server connection not present.'), + }, namespace='/pty', room=request.sid)) + raise RuntimeError('Server is not connected.') + + return conn, manager + except Exception as e: + app.logger.error(e) + raise + + +def get_connection_str(psql_utility, db, manager): + """ + Get connection string(through connection dsn) + :param psql_utility: PostgreSQL binary path. + :param db: database name to connect specific db. + :return: connection attribute list for PSQL connection. + """ + conn_attr = get_conn_str(manager, db) + conn_attr_list = list() + conn_attr_list.append(psql_utility) + conn_attr_list.append(conn_attr) + return conn_attr_list + + +def get_conn_str(manager, db): + """ + Get connection attributes for psql connection. + :param manager: + :param db: + :return: + """ + manager.export_password_env('PGPASSWORD') + conn_attr =\ + "host={0} port={1} dbname={2} user={3} sslmode={4} " \ + "sslcompression={5} " \ + "".format( + manager.local_bind_host if manager.use_ssh_tunnel else + manager.host, + manager.local_bind_port if manager.use_ssh_tunnel else + manager.port, + db if db != '' else 'postgres', + manager.user if manager.user else 'postgres', + manager.ssl_mode, + True if manager.sslcompression else False, + ) + + if manager.hostaddr: + conn_attr = " {0} hostaddr={1}".format(conn_attr, manager.hostaddr) + + if manager.passfile: + conn_attr = " {0} passfile={1}".format(conn_attr, + get_complete_file_path( + manager.passfile)) + + if get_complete_file_path(manager.sslcert): + conn_attr = " {0} sslcert={1}".format( + conn_attr, get_complete_file_path(manager.sslcert)) + + if get_complete_file_path(manager.sslkey): + conn_attr = " {0} sslkey={1}".format( + conn_attr, get_complete_file_path(manager.sslkey)) + + if get_complete_file_path(manager.sslrootcert): + conn_attr = " {0} sslrootcert={1}".format( + conn_attr, get_complete_file_path(manager.sslrootcert)) + + if get_complete_file_path(manager.sslcrl): + conn_attr = " {0} sslcrl={1}".format( + conn_attr, get_complete_file_path(manager.sslcrl)) + + if manager.service: + conn_attr = " {0} service={1}".format( + conn_attr, get_complete_file_path(manager.service)) + + return conn_attr + + +def check_last_exe_cmd(data): + """ + Check the is user try to execute last executed command. + :param data: + :return: + """ + # If user get previous executed command from history then set + # current command as previous executed command. + if session_last_cmd[request.sid]['cmd'] and session_last_cmd[request.sid][ + 'arrow_up']: + user_input = str( + session_last_cmd[request.sid]['cmd']).strip() + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + else: + if request.sid not in session_input: + session_input[request.sid] = data['input'] + user_input = str(session_input[request.sid]).strip() + else: + user_input = str(session_input[request.sid]).strip() + + return user_input + + +def invalid_cmd(): + """ + Invalid command + :return: + :rtype: + """ + session_last_cmd[request.sid]['invalid_cmd'] = True + + for i in range(len(session_input[request.sid])): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + session_input[request.sid] = '' + + +def check_valid_cmd(user_input): + """ + Check if user entered a valid cmd and \\! command is preset as a string + only in current executing command. if \\! is present as command don't + allow the execution of command. + :param user_input: + :return: + """ + stop_execution = True + # Check \! is passed as string or not. + double_quote_strs = re.findall('"([^"]*)"', user_input) + if not double_quote_strs: + double_quote_strs = re.findall("'([^']*)'", user_input) + + if double_quote_strs: + for sub_str in double_quote_strs: + if re.search("\\\!", sub_str): + stop_execution = False + # break + + if stop_execution: + session_last_cmd[request.sid]['invalid_cmd'] = True + # Remove already added command from terminal. + for i in range(len(user_input)): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + # Add Enter event to execute the command. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + + +def enter_key_press(data): + """ + Handel the Enter key press event. + :param data: + """ + user_input = check_last_exe_cmd(data) + session_input_cursor[request.sid] = 0 + + # If ALLOW_PSQL_SHELL_COMMANDS is False then user can't execute + # \! meta command to run shell commands through PSQL terminal. + # Check before executing the user entered command does not + # contains \! in input. + is_new_connection = session_last_cmd[request.sid][ + 'is_new_connection'] + if user_input.startswith('\\!') and re.match("^\\\!$", user_input) and len( + user_input) == 2 and not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not is_new_connection: + invalid_cmd() + elif re.search("\\\!", user_input) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and\ + not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif user_input == '\q' or user_input == 'q\\q': + # If user enter \q to terminate the PSQL, emit the msg to + # notify user connection is terminated. + sio.emit('pty-output', + { + 'result': gettext( + 'Connection terminated, To create new ' + 'connection please open another psql' + ' tool.'), + 'error': True}, + namespace='/pty', room=request.sid) + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + + else: + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + session_input[request.sid] = '' + session_last_cmd[request.sid]['is_new_connection'] = False + + +def backspace_key_press(): + """ + Handel the backspace key press event. + :return: + :rtype: + """ + session_last_cmd[request.sid]['arrow_left_right'] = True + + if session_last_cmd[request.sid]['cmd']: + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + + user_input = list(session_input[request.sid]) + + if session_input_cursor[request.sid] == 1: + index = 0 + session_input_cursor[request.sid] -= 1 + else: + if session_input_cursor[request.sid] > 0: + index = (session_input_cursor[request.sid]) - 1 + session_input_cursor[request.sid] -= 1 + else: + index = session_input_cursor[request.sid] + session_input_cursor[request.sid] = 0 + + if len(user_input): + del user_input[index] + session_input[request.sid] = "".join(user_input) + + if len(session_input[request.sid]) == 0: + session_input_cursor[request.sid] = 0 + session_last_cmd[request.sid]['cmd'] = '' + + +def set_user_input(data): + """ + Check and set current input as user input in session_input. + :param data: + """ + if session_last_cmd[request.sid]['cmd'] and \ + session_input[request.sid] == '': + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + session_input_cursor[request.sid] = len( + session_input[request.sid]) + else: + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + user_input = list(session_input[request.sid]) + user_input.insert(session_input_cursor[request.sid], + data['input']) + session_input[request.sid] = ''.join(user_input) + session_input_cursor[request.sid] += 1 + session_last_cmd[request.sid]['arrow_left_right'] = False + + +def other_key_press(data): + """ + Handel the other key press from psql tool. + :param data: + :type data: + :return: + :rtype: + """ + if data['key_name'] == 'ArrowLeft': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] > 0: + session_input_cursor[request.sid] -= 1 + + elif data['key_name'] == 'ArrowRight': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] < len( + session_input[request.sid]): + session_input_cursor[request.sid] += 1 + + elif data['key_name'] == 'ArrowUp': + session_last_cmd[request.sid]['arrow_up'] = True + session_last_cmd[request.sid]['arrow_left_right'] = False + session_input[request.sid] = session_last_cmd[request.sid][ + 'cmd'] + session_input_cursor[request.sid] = len( + session_last_cmd[request.sid]['cmd']) + + elif request.sid in session_input and \ + data['key_name'] == 'Backspace' and \ + (len(session_input[request.sid]) or + len(session_last_cmd[request.sid])): + backspace_key_press() + elif request.sid in session_input: + set_user_input(data) + else: + session_input_cursor[request.sid] = 0 + session_input[request.sid] = data['input'] + session_input_cursor[request.sid] += 1 + + # Write user input to terminal parent fd. + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + + [email protected]('socket_input', namespace='/pty') +def socket_input(data): + """ + This get the user input through socket. + :param data: User input from socket. + """ + try: + # request.sid: refer request.sid as socket id. + # Check PSQL enabled setting from config. + enable_psql = True if config.ENABLE_PSQL else False + + if request.sid in app.config['sessions']: + if data['key_name'] == 'Enter' and enable_psql: + enter_key_press(data) + else: + other_key_press(data) + except Exception as e: + # Delete socket id from sessions. + # request.sid: refer request.sid as socket id. + sio.emit('pty-output', + { + 'result': gettext('Invalid session.\r\n'), + 'error': True + }, + namespace='/pty', room=request.sid) + del app.config['sessions'][request.sid] + + [email protected]('resize', namespace='/pty') +def resize(data): + """ + Resize the pty terminal as per the UI terminal. + :param data: UI terminal rows and cols data + """ + # request.sid: refer request.sid as socket id. + if request.sid in app.config['sessions']: + set_term_size(app.config['sessions'][request.sid], data['rows'], + data['cols']) + + [email protected]('disconnect', namespace='/pty') +def disconnect(): + """ + Disconnect the socket and terminate the process + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + disconnect_socket() + + [email protected]('server-disconnect', namespace='/pty') +def server_disconnect(data): + """ + Disconnect the socket and terminate the process after user disconnect + the server. we can't use disconnect event name as it is reserved for socket + internal use. + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata and request.sid in app.config['sid_soid_mapping'][ + data['sid']]: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + app.config['sid_soid_mapping'][data['sid']] = [soid for soid in + app.config[ + 'sid_soid_mapping'][ + data['sid']] if + soid != request.sid] + disconnect_socket() + + +def disconnect_socket(): + os.write(app.config['sessions'][request.sid], '\q\n'.encode()) + sio.sleep(1) + os.close(app.config['sessions'][request.sid]) + os.close(cdata[request.sid]) + del app.config['sessions'][request.sid] diff --git a/web/pgadmin/tools/psql/static/js/index.js b/web/pgadmin/tools/psql/static/js/index.js new file mode 100644 index 00000000..4d88ba04 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/index.js @@ -0,0 +1,23 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import $ from 'jquery'; +import _ from 'underscore'; +import pgAdmin from 'sources/pgadmin'; +import pgBrowser from 'top/browser/static/js/browser'; +import * as csrfToken from 'sources/csrf'; +import {initialize} from './psql_module'; + +let pgBrowserOut = initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser); + +module.exports = { + pgBrowser: pgBrowserOut, +}; diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js new file mode 100644 index 00000000..9ff02aa5 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -0,0 +1,429 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import { Terminal } from 'xterm'; +import { FitAddon } from 'xterm-addon-fit'; +import { WebLinksAddon } from 'xterm-addon-web-links'; +import { SearchAddon } from 'xterm-addon-search'; +import { io } from 'socketio'; +import Alertify from 'pgadmin.alertifyjs'; +import {enable} from 'pgadmin.browser.toolbar'; +import clipboard from 'sources/selection/clipboard'; +import 'wcdocker'; +import {getRandomInt} from 'sources/utils'; + +import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; +import {generateTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; + + +export function setPanelTitle(psqlToolPanel, panelTitle) { + psqlToolPanel.title('<span title="'+panelTitle+'">'+panelTitle+'</span>'); +} + +var wcDocker = window.wcDocker; + +export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) { + var pgBrowser = Browser; + var terminal = Terminal; + var parentData = null; + /* Return back, this has been called more than once */ + if (pgBrowser.psql) + return pgBrowser.psql; + + + // Create an Object Restore of pgBrowser class + pgBrowser.psql = { + init: function() { + this.initialized = true; + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'psql', + module: this, + applies: ['tools'], + callback: 'psql_tool', + priority: 1, + label: gettext('PSQL Tool (Beta)'), + enable: this.psqlToolEnabled, + }]; + + this.enable_psql_tool = pgAdmin['enable_psql']; + if(pgAdmin['enable_psql']) { + pgBrowser.add_menus(menus); + } + + // Creating a new pgBrowser frame to show the data. + var psqlFrameType = new pgBrowser.Frame({ + name: 'frm_psqltool', + showTitle: true, + isCloseable: true, + isPrivate: true, + url: 'about:blank', + }); + + var self = this; + /* Cache may take time to load for the first time + * Keep trying till available + */ + let cacheIntervalId = setInterval(function() { + if(pgBrowser.preference_version() > 0) { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + clearInterval(cacheIntervalId); + } + },0); + + pgBrowser.onPreferencesChange('psql', function() { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + }); + + // Load the newly created frame + psqlFrameType.load(pgBrowser.docker); + return this; + }, + /* Enable/disable PSQL tool menu in tools based + * on node selected. if selected node is present + * in unsupported_nodes, menu will be disabled + * otherwise enabled. + */ + psqlToolEnabled: function(obj) { + + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj) && pgAdmin['enable_psql']) { + if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) { + if (obj._type == 'database' && obj.allowConn) { + return true; + } else if (obj._type != 'database') { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + })(); + + enable(gettext('PSQL Tool'), isEnabled); + return isEnabled; + }, + retrieveAncestorOfTypeServer: function(item) { + let serverInformation = null; + // let aciTreeItem = item || pgBrowser.treeMenu.selected(); + let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); + + if (treeNode) { + let nodeData; + let databaseNode = treeNode.ancestorNode( + (node) => { + nodeData = node.getData(); + return (nodeData._type === 'database'); + } + ); + let isServerNode = (node) => { + nodeData = node.getData(); + return nodeData._type === 'server'; + }; + + if (databaseNode !== null) { + if (nodeData._label.indexOf('=') >= 0) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext( + 'Databases with = symbols in the name cannot be backed up or restored using this utility.' + ) + ); + } else { + if (databaseNode.anyParent(isServerNode)) + serverInformation = nodeData; + } + } else { + if (treeNode.anyFamilyMember(isServerNode)) + serverInformation = nodeData; + } + } + + if (serverInformation === null) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext('Please select server or child node from the browser tree.') + ); + } + return serverInformation; + }, + psql_tool: function(data, aciTreeIdentifier, gen=false) { + const module = 'paths'; + let preference_name = 'pg_bin_dir'; + let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.'); + const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeIdentifier); + + if ((serverInformation.type && serverInformation.type === 'ppas') || + serverInformation.server_type === 'ppas') { + preference_name = 'ppas_bin_dir'; + msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'); + } + const preference = pgBrowser.get_preference(module, preference_name); + if (preference) { + if (!preference.value) { + Alertify.alert(gettext('Configuration required'), msg); + return false; + } + } else { + Alertify.alert( + gettext(this.errorAlertTitle), + gettext('Failed to load preference %s of module %s', preference_name, module) + ); + return false; + } + const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if (node === undefined || !node.getData()) { + Alertify.alert( + gettext('PSQL Error'), + gettext('No object selected.') + ); + return; + } + + parentData = getTreeNodeHierarchyFromIdentifier.call( + pgBrowser, + aciTreeIdentifier + ); + + if(_.isUndefined(parentData.server)) { + Alertify.alert( + gettext('PSQL Error'), + gettext('Please select a server/database object.') + ); + return; + } + + const transId = getRandomInt(1, 9999999); + + var panelTitle = ''; + // Set psql tab title as per prefrences setting. + var title_data = { + 'database': parentData.database ? parentData.database.label : 'postgres' , + 'username': parentData.server.user_name, + 'server': parentData.server.label, + 'type': 'psql_tool', + }; + var tab_title_placeholder = pgBrowser.get_preferences_for_module('browser').psql_tab_title_placeholder; + panelTitle = generateTitle(tab_title_placeholder, title_data); + + const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + + let psqlToolForm = ` + <form id="psqlToolForm" action="${panelUrl}" method="post"> + <input id="title" name="title" hidden /> + <input name="close_url" value="${panelCloseUrl}" hidden /> + </form> + <script> + document.getElementById("title").value = "${_.escape(panelTitle)}"; + document.getElementById("psqlToolForm").submit(); + </script> + `; + var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; + if (open_new_tab && open_new_tab.includes('psql_tool')) { + var newWin = window.open('', '_blank'); + newWin.document.write(psqlToolForm); + newWin.document.title = panelTitle; + } else { + /* On successfully initialization find the properties panel, + * create new panel and add it to the dashboard panel. + */ + var propertiesPanel = pgBrowser.docker.findPanels('properties'); + var psqlToolPanel = pgBrowser.docker.addPanel('frm_psqltool', wcDocker.DOCK.STACKED, propertiesPanel[0]); + + // Set panel title and icon + setPanelTitle(psqlToolPanel, panelTitle); + psqlToolPanel.icon('fas fa-terminal psql-tab-style'); + psqlToolPanel.focus(); + + var openPSQLToolURL = function(j) { + // add spinner element + let $spinner_el = + $(`<div class="pg-sp-container"> + <div class="pg-sp-content"> + <div class="row"> + <div class="col-12 pg-sp-icon"></div> + </div> + </div> + </div>`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { + var frameInitialized = $(j).data('frameInitialized'); + if (frameInitialized) { + clearInterval(init_poller_id); + var frame = $(j).data('embeddedFrame'); + if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); + frame.openHTML(psqlToolForm); + } + } + }, 100); + }; + + openPSQLToolURL(psqlToolPanel); + + } + + }, + getPanelUrls: function(transId, panelTitle, parentData) { + let openUrl = url_for('psql.panel', { + trans_id: transId, + }); + const misc_preferences = pgBrowser.get_preferences_for_module('misc'); + var theme = misc_preferences.theme; + + openUrl += `?sgid=${parentData.server_group._id}` + +`&sid=${parentData.server._id}` + +`&server_type=${parentData.server.server_type}` + + `&theme=${theme}`; + + if(parentData.database && parentData.database._id) { + let db_label = parentData.database._label.replace('\\', '\\\\'); + openUrl += `&db=${db_label}`; + } else { + openUrl += `&db=${''}`; + } + + let closeUrl = url_for('psql.close', { + trans_id: transId, + }); + return [openUrl, closeUrl]; + }, + psql_terminal: function() { + // theme colors + var term = new terminal({ + cursorBlink: true, + macOptionIsMeta: true, + scrollback: 5000, + }); + + return term; + }, + psql_Addon: function(term) { + const fitAddon = this.psql_fit_screen(); + term.loadAddon(fitAddon); + + const webLinksAddon = this.psql_web_link(); + term.loadAddon(webLinksAddon); + + const searchAddon = this.psql_search(); + term.loadAddon(searchAddon); + + fitAddon.fit(); + term.resize(15, 50); + fitAddon.fit(); + return fitAddon; + }, + psql_fit_screen: function() { + return new FitAddon(); + }, + psql_web_link: function() { + return new WebLinksAddon(); + }, + psql_search: function() { + return new SearchAddon(); + }, + psql_socket: function() { + return io('/pty', {pingTimeout: 120000, pingInterval: 25000}); + }, + set_theme: function(term) { + var theme = { + background: getComputedStyle(document.documentElement).getPropertyValue('--psql-background'), + foreground: getComputedStyle(document.documentElement).getPropertyValue('--psql-foreground'), + cursor: getComputedStyle(document.documentElement).getPropertyValue('--psql-cursor'), + cursorAccent: getComputedStyle(document.documentElement).getPropertyValue('--psql-cursorAccent'), + selection: getComputedStyle(document.documentElement).getPropertyValue('--psql-selection'), + }; + term.setOption('theme', theme); + }, + psql_socket_io: function(socket, is_enable, sid, db, server_type, fitAddon, term) { + // Listen all the socket events emit from server. + socket.on('pty-output', function(data){ + if(data.error) { + term.write('\r\n'); + } + term.write(data.result); + if(data.error) { + term.write('\r\n'); + } + }); + // Connect socket + socket.on('connect', () => { + if(is_enable == 'True'){ + socket.emit('start_process', {'sid': sid, 'db': db, 'stype': server_type }); + } + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('conn_error', (response) => { + term.write(response.error); + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('conn_not_allow', () => { + term.write('PSQL connection not allowed'); + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('disconnect-psql', () => { + socket.emit('server-disconnect', {'sid': sid}); + term.write('\r\nServer disconnected, Connection terminated, To create new connection please open another psql tool.'); + }); + }, + psql_terminal_io: function(term, socket) { + // Listen key press event from terminal and emit socket event. + let selected_text = ''; + term.attachCustomKeyEventHandler(e => { + e.stopPropagation(); + if(e.type=='keydown' && e.metaKey &&(e.key == 'v' || e.key == 'V')) { + if(selected_text != '') { + if (selected_text.length > 0) { + socket.emit('socket_input', {'input': selected_text, 'key_name': e.code}); + selected_text = ''; + } + } else { + navigator.clipboard.readText().then( clipText => { + selected_text = clipText; + if (selected_text.length > 0) { + socket.emit('socket_input', {'input': selected_text, 'key_name': e.code}); + selected_text = ''; + } + }); + } + }else if(e.type=='keydown' && e.metaKey && (e.key == 'c' || e.key == 'C')) { + if (term.hasSelection()) { + selected_text = term.getSelection(); + } else { + selected_text = clipboard.readText(); + } + } + return true; + }); + + term.onKey(function (ev) { + if (pgAdmin['allow_psql_shell_commands']) { + socket.emit('socket_input', {'input': ev.key, 'key_name': ev.domEvent.code}); + } else { + socket.emit('socket_input', {'input': ev.key, 'key_name': ev.domEvent.code}); + } + }); + } + }; + + return pgBrowser.psql; +} + diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html new file mode 100644 index 00000000..43b346b2 --- /dev/null +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -0,0 +1,58 @@ +{% extends "base.html" %} +{% block title %}{{title}}{% endblock %} + +{% block css_link %} +<link type="text/css" rel="stylesheet" href="{{ url_for('browser.browser_css')}}"/> +{% endblock %} +{% block body %} +<style> + body {padding: 0px;} + {% if is_desktop_mode and is_linux %} + .alertify .ajs-dimmer,.alertify .ajs-modal{-webkit-transform: none;} + .alertify-notifier{-webkit-transform: none;} + .alertify-notifier .ajs-message{-webkit-transform: none;} + .alertify .ajs-dialog.ajs-shake{-webkit-animation-name: none;} + .sql-editor-busy-icon.fa-pulse{-webkit-animation: none;} + {% endif %} +</style> +<div style="width: 100%; height: 100%;" id="psql-terminal" class="psql_terminal"></div> +{% endblock %} + + +{% block init_script %} +require( + ['sources/generated/psql_tool'], + function(pgBrowser) { + const term = self.pgAdmin.Browser.psql.psql_terminal(); + <!--Addon for fitAddon, webLinkAddon, SearchAddon --> + const fitAddon = self.pgAdmin.Browser.psql.psql_Addon(term); + <!-- Update the theme for terminal as per pgAdmin 4 theme.--> + self.pgAdmin.Browser.psql.set_theme(term); + <!-- Open the terminal --> + term.open(document.getElementById('psql-terminal')); + <!-- Socket--> + const socket = self.pgAdmin.Browser.psql.psql_socket(); + self.pgAdmin.Browser.psql.psql_socket_io(socket, '{{is_enable}}', '{{sid}}', '{{db}}', '{{server_type}}', fitAddon, term); + self.pgAdmin.Browser.psql.psql_terminal_io(term, socket); + + <!-- Resize the terminal --> + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } + + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) + } + } + + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) + }); +{% endblock %} + + diff --git a/web/pgadmin/tools/psql/tests/__init__.py b/web/pgadmin/tools/psql/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web/pgadmin/tools/psql/tests/psql_test_data.json b/web/pgadmin/tools/psql/tests/psql_test_data.json new file mode 100644 index 00000000..4148c75b --- /dev/null +++ b/web/pgadmin/tools/psql/tests/psql_test_data.json @@ -0,0 +1,184 @@ +{ + "psql_user_input": [ + { + "name": "Enter Select 1;", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "move_cursor_up": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "is_history": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowLeft", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowLeft": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowRight", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Read previous executed command", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "move_cursor_right": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\!", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! with other cmd not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\! ls", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Valid commands", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select \"\\!\"", + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "First command as enter", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Exist psql terminal by using \\q", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\q", + "mock_data": { + + }, + "expected_data": { + } + } + ], + "resize_terminal": [ + { + "name": "Resize psql terminal as per UI.", + "is_positive_test": true, + "mocking_required": false, + "input_data": { + "cols": 141, + "rows": 39 + }, + "mock_data": { + + }, + "expected_data": { + } + } + ], + "backend_task": [ + { + "name": "Backend Task", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "Select 1;", + "is_backend_task": true, + "mock_data": { + "is_test": true + }, + "expected_data": { + } + } + ] +} diff --git a/web/pgadmin/tools/psql/tests/test_backend_task.py b/web/pgadmin/tools/psql/tests/test_backend_task.py new file mode 100644 index 00000000..a4f14ee4 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_backend_task.py @@ -0,0 +1,87 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLBackend(BaseTestGenerator): + scenarios = utils.generate_scenarios('backend_task', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'], + 'is_test': True, + 'count': 0 + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_panel.py b/web/pgadmin/tools/psql/tests/test_panel.py new file mode 100644 index 00000000..6f93c8c2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_panel.py @@ -0,0 +1,36 @@ +import uuid +import random +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data + + +class PSQLPanel(BaseTestGenerator): + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + self.theme = 'standard' + + def runTest(self): + trans_id = random.randint(1, 9999999) + url = '/psql/panel/{trans_id}?sgid={sgid}&sid={sid}&server_type=pg' \ + '&db={db_name}&theme={theme}'.\ + format(trans_id=trans_id, sgid=self.sgid, sid=self.sid, + db_name=self.db_name, theme=self.theme) + + response = self.tester.post( + url, data={"title": "panel_title"}, + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_disabled.py b/web/pgadmin/tools/psql/tests/test_psql_disabled.py new file mode 100644 index 00000000..7dc52498 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_disabled.py @@ -0,0 +1,34 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisabled(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = False + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_input.py b/web/pgadmin/tools/psql/tests/test_psql_input.py new file mode 100644 index 00000000..6f6eabe7 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_input.py @@ -0,0 +1,148 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLInput(BaseTestGenerator): + scenarios = utils.generate_scenarios('psql_user_input', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_backspace') and self.is_backspace: + if hasattr(self, 'move_cursor_up') and self.move_cursor_up: + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Backspace' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowUp') and self.is_arrowUp: + if hasattr(self, 'is_history') and self.is_history: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowLeft') and self.is_arrowLeft: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowRight') and self.is_arrowRight: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'move_cursor_right') and self.is_arrowRight: + for i in range(2): + input_data = { + 'input': '', + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + input_data = { + 'input': '', + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_resize_terminal.py b/web/pgadmin/tools/psql/tests/test_resize_terminal.py new file mode 100644 index 00000000..d305c2d0 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_resize_terminal.py @@ -0,0 +1,58 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLResizeTerminal(BaseTestGenerator): + scenarios = utils.generate_scenarios('resize_terminal', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.emit('resize', self.input_data, namespace='/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_connect.py b/web/pgadmin/tools/psql/tests/test_socket_connect.py new file mode 100644 index 00000000..3791525a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_connect.py @@ -0,0 +1,35 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketConnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py new file mode 100644 index 00000000..0619eb30 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py @@ -0,0 +1,52 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisconnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_test_client = app.test_client() + flask_test_client.get('/') + + self.test_client = socketio.test_client( + app, + flask_test_client=flask_test_client, + namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process.py b/web/pgadmin/tools/psql/tests/test_start_process.py new file mode 100644 index 00000000..1245de3f --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process.py @@ -0,0 +1,57 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcess(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + import random + trans_id = random.randint(1, 9999999) + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process_fail.py b/web/pgadmin/tools/psql/tests/test_start_process_fail.py new file mode 100644 index 00000000..0acc7be2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process_fail.py @@ -0,0 +1,48 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcessFail(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + config.ENABLE_PSQL = False + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/utils.py b/web/pgadmin/tools/psql/tests/utils.py new file mode 100644 index 00000000..85bd5373 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/utils.py @@ -0,0 +1,6 @@ +import os +import json + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/psql_test_data.json") as data_file: + test_cases = json.load(data_file) diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss index 0bb40802..a58eb7e9 100644 --- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss +++ b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss @@ -374,3 +374,20 @@ div.strikeout:after { /* Setting it to hardcoded white as the SVG generated is having white bg * Need to check what can be done. */ + +/* Css for psql */ +.psql_terminal .terminal { + padding-top: 1%; + padding-left: 0.5%; + height: 100%; +} + +.psql-icon-style { + font-size: inherit; + padding-left: 0em; +} + +.psql-tab-style { + font-size: small; + padding-left: 0em; +} diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py index 23abfffa..71ae82ea 100644 --- a/web/pgadmin/utils/csrf.py +++ b/web/pgadmin/utils/csrf.py @@ -38,6 +38,7 @@ class _PGCSRFProtect(CSRFProtect): 'pgadmin.tools.schema_diff.ddl_compare', 'pgadmin.authenticate.login', 'pgadmin.tools.erd.panel', + 'pgadmin.tools.psql.panel', ] for exempt in exempt_views: diff --git a/web/pgadmin/utils/preferences.py b/web/pgadmin/utils/preferences.py index 15ceeb1a..e9efe479 100644 --- a/web/pgadmin/utils/preferences.py +++ b/web/pgadmin/utils/preferences.py @@ -72,6 +72,7 @@ class _Preference(object): self.select2 = kwargs.get('select2', None) self.fields = kwargs.get('fields', None) self.allow_blanks = kwargs.get('allow_blanks', None) + self.disabled = kwargs.get('disabled', False) # Look into the configuration table to find out the id of the specific # preference. @@ -252,6 +253,7 @@ class _Preference(object): 'select2': self.select2, 'value': self.get(), 'fields': self.fields, + 'disabled': self.disabled, } return res @@ -414,6 +416,7 @@ class Preferences(object): :param fields: field schema (if preference has more than one field to take input from user e.g. keyboardshortcut preference) :param allow_blanks: Flag specify whether to allow blank value. + :param disabled: Flag specify whether to disable the setting or not. """ min_val = kwargs.get('min_val', None) max_val = kwargs.get('max_val', None) @@ -423,6 +426,7 @@ class Preferences(object): select2 = kwargs.get('select2', None) fields = kwargs.get('fields', None) allow_blanks = kwargs.get('allow_blanks', None) + disabled = kwargs.get('disabled', False) cat = self.__category(category, category_label) if name in cat['preferences']: @@ -439,7 +443,8 @@ class Preferences(object): (cat['preferences'])[name] = res = _Preference( cat['id'], name, label, _type, default, help_str=help_str, min_val=min_val, max_val=max_val, options=options, - select2=select2, fields=fields, allow_blanks=allow_blanks + select2=select2, fields=fields, allow_blanks=allow_blanks, + disabled=disabled ) return res diff --git a/web/webpack.config.js b/web/webpack.config.js index 779f2faa..f631178b 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -355,6 +355,7 @@ module.exports = [{ debugger_direct: './pgadmin/tools/debugger/static/js/direct.js', schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js', erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js', + psql_tool: './pgadmin/tools/psql/static/js/index.js', file_utils: './pgadmin/misc/file_manager/static/js/utility.js', 'pgadmin.style': pgadminCssStyles, pgadmin: pgadminScssStyles, @@ -493,7 +494,7 @@ module.exports = [{ ], }, }, - }, { + },{ test: require.resolve('./node_modules/acitree/js/jquery.aciTree.min'), use: { loader: 'imports-loader', @@ -532,6 +533,7 @@ module.exports = [{ 'pure|pgadmin.tools.storage_manager', 'pure|pgadmin.tools.search_objects', 'pure|pgadmin.tools.erd_module', + 'pure|pgadmin.tools.psql_module', ], }, }, diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 074b2580..e0b28091 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -159,6 +159,15 @@ var webpackShimConfig = { 'jquery.acisortable': path.join(__dirname, './node_modules/acitree/js/jquery.aciSortable.min'), 'jquery.acifragment': path.join(__dirname, './node_modules/acitree/js/jquery.aciFragment.min'), + //xterm + 'xterm': path.join(__dirname, './node_modules/xterm/lib/xterm.js'), + 'xterm-addon-fit': path.join(__dirname, './node_modules/xterm-addon-fit/lib/xterm-addon-fit.js'), + 'xterm-addon-web-links': path.join(__dirname, './node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js'), + 'xterm-addon-search': path.join(__dirname, './node_modules/xterm-addon-search/lib/xterm-addon-search.js'), + + //socket + 'socketio': path.join(__dirname, './node_modules/socket.io-client/dist/socket.io.js'), + // Backbone and Backgrid 'backbone': path.join(__dirname, './node_modules/backbone/backbone'), 'backbone.undo': path.join(__dirname, './node_modules/backbone-undo/Backbone.Undo'), @@ -288,6 +297,8 @@ var webpackShimConfig = { 'pgadmin.tools.storage_manager': path.join(__dirname, './pgadmin/tools/storage_manager/static/js/storage_manager'), 'pgadmin.tools.erd_module': path.join(__dirname, './pgadmin/tools/erd/static/js/erd_module'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index e0b6fd69..3cc079f9 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -177,6 +177,7 @@ module.exports = { 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), 'tools': path.join(__dirname, './pgadmin/tools/'), 'pgadmin.user_management.current_user': regressionDir + '/javascript/fake_current_user', ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-25 09:25 Akshay Joshi <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Akshay Joshi @ 2021-05-25 09:25 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Dave Page <[email protected]> Hi Nikhil Please rebase and send the patch again. On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < [email protected]> wrote: > Hi Akshay/ Team > > On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < > [email protected]> wrote: > >> Hi Nikhil >> >> Following are the review comments: >> >> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >> context menu option should not be visible. >> - Documentation screenshot should be in standard theme for >> consistency, and check the size it's very large. Take the screenshot with >> the new PSQL button on the browser tree. >> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >> - Remove commented code (if any) >> - Check SonarQube (I haven't run) >> >> Please find the updated patch, resolve all the review comments, and > update the code to resolve the SonarQube issues. > >> >> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> wrote: >> >>> Thanks Nikhil. Can someone else review this version please? >>> >>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Dave/ Team, >>>> >>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave/ Team, >>>>>> >>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave/Team, >>>>>>> >>>>>>> >>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Akshay/ Team, >>>>>>>>> >>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>> >>>>>>>> >>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>> which throws an error. Having fixed that... >>>>>>>> >>>>>>>> I also note there's a lot of Javascript in that HTML file. That >>>>>>>> should be pushed into the webpacked bundle I think, and not included inline >>>>>>>> in HTML. >>>>>>>> >>>>>>> I have moved most of the code in the js file, few things are still >>>>>>> in HTML. >>>>>>> >>>>>> >>>>>> Hmm, yes - in particular, colours for the different themes. Please >>>>>> move them into the css for the themes. You have a mix of style, layout and >>>>>> code in this file which needs to be cleaned up. >>>>>> xterm V3 onwards they have provided the API to set the theme and >>>>>> other settings, earlier I tried with CSS to override the theme but couldn’t >>>>>> able to apply the theme properly as some style get applied as in-line style >>>>>> for the HTML, so used the API to set the theme. >>>>>> >>>>> >>>>> OK, but either way we can't hard-code styles from themes in HTML >>>>> templates for individual features; that way leads to madness. >>>>> >>>>> Perhaps Aditya or one of the other team members can give some >>>>> assistance? >>>>> >>>> I have moved the color settings to the respective theme files. Aditya >>>> helped in this. >>>> >>>>> >>>>> >>>>>> >>>>>> >>>>>>> Speaking of themes, the background colour for selected text doesn't >>>>>>> seem right (it's barely visible) in the dark theme. Can you fix that to >>>>>>> match the colouring in the SQL text boxes please? >>>>>>> >>>>>> I tried the default selection color from SQL for the dark and >>>> standard themes but still, it was not readable so just updated the color >>>> code with another color as follows. >>>> 1. Dark Theme: >>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>> 2. High Contrast: (using default SQL selection color) >>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>> 3. Standard: >>>> [image: image.png] >>>> can we go with the colors or should we update it? >>>> >>>>> >>>>>>> >>>>>>>> >>>>>>>>> A couple of other things I noticed: >>>>>>>>> >>>>>>>>> - The button is enabled if the treeview has a Server selected. It >>>>>>>>> could be argued that the query tool should do the same (defaulting to the >>>>>>>>> maintenance database), however, that would be a separate change, and psql >>>>>>>>> should be consistent with the query tool. >>>>>>>>> >>>>>>>> It is now consistent with the query tool. >>>>>>>> >>>>>>>>> >>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>> >>>>>>>>> postgres=# select * from pg_class; >>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>> >>>>>>>> I am not able to reproduce the warning for the terminal (I am >>>>>>>> working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>> reproduce the warning. but found one limitation: >>>>>>>> >>>>>>> >>>>>>> It looks like that can be fixed by adding: >>>>>>> >>>>>>> env={'TERM': 'xterm'} >>>>>>> >>>>>> Added this in the environment when opening the psql panel. >>>> >>>>> >>>>>>> to the subprocess.Popen() call. >>>>>>> >>>>>>> I noticed while I was playing with that, that you are passing the >>>>>>> password as part of the connection string. As I've mentioned in the past, >>>>>>> that is absolutely not acceptable; it will expose the password to all >>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>> using the PGPASSWORD environment variable. >>>>>>> >>>>>>> >>>>>>>> if we try to load data from the table containing millions of >>>>>>>> records, UI gets very slow. >>>>>>>> >>>>>>> Removed the password from the connection string and added >>>> 'PGPASSWORD' in the environment. >>>> >>>>> >>>>>>> Is xtermjs discarding the older buffer contents when it fills up? >>>>>>> Can you tell where the memory usage is? >>>>>>> >>>>>> I checked the psql memory consumption in terminal and pgAdmin psql >>>>>> tool memory consumption is the similar. Also tested the performance and >>>>>> query execution timing is also similar. >>>>>> >>>>> >>>>> OK, so there's probably not much we can do here. >>>>> >>>>> >>>>>> >>>>>>> >>>>>>> >>>>>>>> >>>>>>>>> - I'm sure using \q in the previous version displayed a message >>>>>>>>> saying the session exited (the one on line 138 of editor_template.html). It >>>>>>>>> no longer seems to do so. >>>>>>>>> >>>>>>>> >>>>>>> In addition to the issue above, it looks like the \! blocking may >>>>>>> have lost it's ability to ignore quoted strings: >>>>>>> >>>>>>> pgweb=# select '\!'; >>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>> >>>>>> Fixed the issue now it is consistent with the psql terminal. >>>> >>>>> >>>>>>> >>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>> >>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>> >>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>> >>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we can >>>>>>>>>>>> also add that on the browser tree toolbar. >>>>>>>>>>>> - PSQL Tool menu should be visible for all the child nodes >>>>>>>>>>>> of the database node. Follow the same as Query Tool. >>>>>>>>>>>> - PSQL tab title should be only database server name as the >>>>>>>>>>>> user can change the database/user from PSQL command, so it's been difficult >>>>>>>>>>>> to update the tab title. >>>>>>>>>>>> - PSQL connection is still open even if we disconnect the >>>>>>>>>>>> database server from the browser tree. >>>>>>>>>>>> >>>>>>>>>>>> *Code specific:* >>>>>>>>>>>> >>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>> package.json >>>>>>>>>>>> - Documentation needs to be updated to let the user know >>>>>>>>>>>> from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>> - psql/__init__.py check there are so many unused imports >>>>>>>>>>>> please remove them. >>>>>>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>> - Test cases are showing successful but actually, there are >>>>>>>>>>>> some routing errors please check. >>>>>>>>>>>> >>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>> >>>>>>>>>>> - I was prompted to enter a password. This should be passed in >>>>>>>>>>> the environment to psql as it is for pg_dump etc. >>>>>>>>>>> - There seems to be an issue with terminal compatibility (which >>>>>>>>>>> I didn't have on my prototype): >>>>>>>>>>> >>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>> oid | 79354 >>>>>>>>>>> relname | housing >>>>>>>>>>> ... >>>>>>>>>>> >>>>>>>>>>> - The panel should honour the styleguide. I'm running in dark >>>>>>>>>>> mode, and see a jet black background. I would expect to see the same >>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>> - I spotted at least one print() statement that shouldn't be >>>>>>>>>>> there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>> >>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>> >>>>>>>>>>> - There's a thick white line at the bottom of the panel, where a >>>>>>>>>>> horizontal scrollbar might be if there was one. >>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>>>>>>>>> commands are disabled in psql for security;" >>>>>>>>>>> >>>>>>>>>>> Once we're happy with the patch in general, I'll do a string >>>>>>>>>>> review before committing. In particular, I want to be sure the text in >>>>>>>>>>> config.py is appropriately worded. >>>>>>>>>>> >>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>> >>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while cleanup >>>>>>>>>>>>> I removed the unwanted libraries but forgot to remove the code related to >>>>>>>>>>>>> them. >>>>>>>>>>>>> >>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu >>>>>>>>>>>>>>> option for starting PSQL. >>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>> 2. Added the same option for Server and Database nodes from >>>>>>>>>>>>>>> the tree view. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json that >>>>>>>>>>>>>> makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>> >>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>> configuration >>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>> no extension >>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>> configuration >>>>>>>>>>>>>> >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>> .js >>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>> configuration >>>>>>>>>>>>>> >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>> configuration >>>>>>>>>>>>>> >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>> as directory >>>>>>>>>>>>>> >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>> no extension >>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>> configuration >>>>>>>>>>>>>> >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>> .js >>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>> configuration >>>>>>>>>>>>>> >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>> configuration >>>>>>>>>>>>>> >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>> as directory >>>>>>>>>>>>>> >>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>> >>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in >>>>>>>>>>>>>> 60041 ms >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Regards, >>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>> >>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> Regards, >>>>>>>>>> Nikhil Mohite >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>> >>>>>>>> Regards, >>>>>>>> Nikhil Mohite >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>> >>>>>> >>>>>> Regards, >>>>>> Nikhil Mohite >>>>>> >>>>>>> <https://www.enterprisedb.com; >>>>>>> >>>>>>> -- >>>>>> *Thanks & Regards,* >>>>>> *Nikhil Mohite* >>>>>> *Software Engineer.* >>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>> *Mob.No: +91-7798364578.* >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> Regards, >>>> Nikhil Mohite >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-25 09:38 Nikhil Mohite <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-05-25 09:38 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: pgadmin-hackers; Dave Page <[email protected]> Hi Akshay, Please find the updated patch. (V6) On Tue, May 25, 2021 at 2:55 PM Akshay Joshi <[email protected]> wrote: > Hi Nikhil > > Please rebase and send the patch again. > > On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Akshay/ Team >> >> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >> [email protected]> wrote: >> >>> Hi Nikhil >>> >>> Following are the review comments: >>> >>> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >>> context menu option should not be visible. >>> - Documentation screenshot should be in standard theme for >>> consistency, and check the size it's very large. Take the screenshot with >>> the new PSQL button on the browser tree. >>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>> - Remove commented code (if any) >>> - Check SonarQube (I haven't run) >>> >>> Please find the updated patch, resolve all the review comments, and >> update the code to resolve the SonarQube issues. >> >>> >>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> wrote: >>> >>>> Thanks Nikhil. Can someone else review this version please? >>>> >>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave/ Team, >>>>> >>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave/ Team, >>>>>>> >>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave/Team, >>>>>>>> >>>>>>>> >>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>> >>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>> >>>>>>>>> >>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>> which throws an error. Having fixed that... >>>>>>>>> >>>>>>>>> I also note there's a lot of Javascript in that HTML file. That >>>>>>>>> should be pushed into the webpacked bundle I think, and not included inline >>>>>>>>> in HTML. >>>>>>>>> >>>>>>>> I have moved most of the code in the js file, few things are still >>>>>>>> in HTML. >>>>>>>> >>>>>>> >>>>>>> Hmm, yes - in particular, colours for the different themes. Please >>>>>>> move them into the css for the themes. You have a mix of style, layout and >>>>>>> code in this file which needs to be cleaned up. >>>>>>> xterm V3 onwards they have provided the API to set the theme and >>>>>>> other settings, earlier I tried with CSS to override the theme but couldn’t >>>>>>> able to apply the theme properly as some style get applied as in-line style >>>>>>> for the HTML, so used the API to set the theme. >>>>>>> >>>>>> >>>>>> OK, but either way we can't hard-code styles from themes in HTML >>>>>> templates for individual features; that way leads to madness. >>>>>> >>>>>> Perhaps Aditya or one of the other team members can give some >>>>>> assistance? >>>>>> >>>>> I have moved the color settings to the respective theme files. Aditya >>>>> helped in this. >>>>> >>>>>> >>>>>> >>>>>>> >>>>>>> >>>>>>>> Speaking of themes, the background colour for selected text doesn't >>>>>>>> seem right (it's barely visible) in the dark theme. Can you fix that to >>>>>>>> match the colouring in the SQL text boxes please? >>>>>>>> >>>>>>> I tried the default selection color from SQL for the dark and >>>>> standard themes but still, it was not readable so just updated the color >>>>> code with another color as follows. >>>>> 1. Dark Theme: >>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>> 2. High Contrast: (using default SQL selection color) >>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>> 3. Standard: >>>>> [image: image.png] >>>>> can we go with the colors or should we update it? >>>>> >>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>>> A couple of other things I noticed: >>>>>>>>>> >>>>>>>>>> - The button is enabled if the treeview has a Server selected. It >>>>>>>>>> could be argued that the query tool should do the same (defaulting to the >>>>>>>>>> maintenance database), however, that would be a separate change, and psql >>>>>>>>>> should be consistent with the query tool. >>>>>>>>>> >>>>>>>>> It is now consistent with the query tool. >>>>>>>>> >>>>>>>>>> >>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>> >>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>> >>>>>>>>> I am not able to reproduce the warning for the terminal (I am >>>>>>>>> working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>> >>>>>>>> >>>>>>>> It looks like that can be fixed by adding: >>>>>>>> >>>>>>>> env={'TERM': 'xterm'} >>>>>>>> >>>>>>> Added this in the environment when opening the psql panel. >>>>> >>>>>> >>>>>>>> to the subprocess.Popen() call. >>>>>>>> >>>>>>>> I noticed while I was playing with that, that you are passing the >>>>>>>> password as part of the connection string. As I've mentioned in the past, >>>>>>>> that is absolutely not acceptable; it will expose the password to all >>>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>> using the PGPASSWORD environment variable. >>>>>>>> >>>>>>>> >>>>>>>>> if we try to load data from the table containing millions of >>>>>>>>> records, UI gets very slow. >>>>>>>>> >>>>>>>> Removed the password from the connection string and added >>>>> 'PGPASSWORD' in the environment. >>>>> >>>>>> >>>>>>>> Is xtermjs discarding the older buffer contents when it fills up? >>>>>>>> Can you tell where the memory usage is? >>>>>>>> >>>>>>> I checked the psql memory consumption in terminal and pgAdmin psql >>>>>>> tool memory consumption is the similar. Also tested the performance and >>>>>>> query execution timing is also similar. >>>>>>> >>>>>> >>>>>> OK, so there's probably not much we can do here. >>>>>> >>>>>> >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>>> - I'm sure using \q in the previous version displayed a message >>>>>>>>>> saying the session exited (the one on line 138 of editor_template.html). It >>>>>>>>>> no longer seems to do so. >>>>>>>>>> >>>>>>>>> >>>>>>>> In addition to the issue above, it looks like the \! blocking may >>>>>>>> have lost it's ability to ignore quoted strings: >>>>>>>> >>>>>>>> pgweb=# select '\!'; >>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>> >>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>> >>>>>> >>>>>>>> >>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>> >>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>> >>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>> >>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we can >>>>>>>>>>>>> also add that on the browser tree toolbar. >>>>>>>>>>>>> - PSQL Tool menu should be visible for all the child nodes >>>>>>>>>>>>> of the database node. Follow the same as Query Tool. >>>>>>>>>>>>> - PSQL tab title should be only database server name as >>>>>>>>>>>>> the user can change the database/user from PSQL command, so it's been >>>>>>>>>>>>> difficult to update the tab title. >>>>>>>>>>>>> - PSQL connection is still open even if we disconnect the >>>>>>>>>>>>> database server from the browser tree. >>>>>>>>>>>>> >>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>> >>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>> package.json >>>>>>>>>>>>> - Documentation needs to be updated to let the user know >>>>>>>>>>>>> from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>> - psql/__init__.py check there are so many unused imports >>>>>>>>>>>>> please remove them. >>>>>>>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>> - Test cases are showing successful but actually, there >>>>>>>>>>>>> are some routing errors please check. >>>>>>>>>>>>> >>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>> >>>>>>>>>>>> - I was prompted to enter a password. This should be passed in >>>>>>>>>>>> the environment to psql as it is for pg_dump etc. >>>>>>>>>>>> - There seems to be an issue with terminal compatibility (which >>>>>>>>>>>> I didn't have on my prototype): >>>>>>>>>>>> >>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>> oid | 79354 >>>>>>>>>>>> relname | housing >>>>>>>>>>>> ... >>>>>>>>>>>> >>>>>>>>>>>> - The panel should honour the styleguide. I'm running in dark >>>>>>>>>>>> mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>> - I spotted at least one print() statement that shouldn't be >>>>>>>>>>>> there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>>> >>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>> >>>>>>>>>>>> - There's a thick white line at the bottom of the panel, where >>>>>>>>>>>> a horizontal scrollbar might be if there was one. >>>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: Shell >>>>>>>>>>>> commands are disabled in psql for security;" >>>>>>>>>>>> >>>>>>>>>>>> Once we're happy with the patch in general, I'll do a string >>>>>>>>>>>> review before committing. In particular, I want to be sure the text in >>>>>>>>>>>> config.py is appropriately worded. >>>>>>>>>>>> >>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>> >>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while cleanup >>>>>>>>>>>>>> I removed the unwanted libraries but forgot to remove the code related to >>>>>>>>>>>>>> them. >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu >>>>>>>>>>>>>>>> option for starting PSQL. >>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>> 2. Added the same option for Server and Database nodes from >>>>>>>>>>>>>>>> the tree view. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json that >>>>>>>>>>>>>>> makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error in >>>>>>>>>>>>>>> 60041 ms >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>> >>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>> Nikhil Mohite >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> Nikhil Mohite >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>> >>>>>>> >>>>>>> Regards, >>>>>>> Nikhil Mohite >>>>>>> >>>>>>>> <https://www.enterprisedb.com; >>>>>>>> >>>>>>>> -- >>>>>>> *Thanks & Regards,* >>>>>>> *Nikhil Mohite* >>>>>>> *Software Engineer.* >>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>> *Mob.No: +91-7798364578.* >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> Regards, >>>>> Nikhil Mohite >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> *pgAdmin Hacker | Principal Software Architect* >>> *EDB Postgres <http://edbpostgres.com>* >>> >>> *Mobile: +91 976-788-8246* >>> >> > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [application/octet-stream] RM_2341_V6.patch (510.1K, 6-RM_2341_V6.patch) download | inline diff: diff --git a/docs/en_US/developer_tools.rst b/docs/en_US/developer_tools.rst index 1ff442cc..bb67e33a 100644 --- a/docs/en_US/developer_tools.rst +++ b/docs/en_US/developer_tools.rst @@ -16,3 +16,4 @@ PL/SQL code. editgrid schema_diff erd_tool + psql_tool diff --git a/docs/en_US/images/psql_tool.png b/docs/en_US/images/psql_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..f92e120211f962d6409959c48428177f69ad2d24 GIT binary patch literal 43302 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 SWZO^RbJ)ntFz=xA_5T1GN0V6q literal 0 HcmV?d00001 diff --git a/docs/en_US/images/tool_menu.png b/docs/en_US/images/tool_menu.png index 7747b95503584d4164c55738fa66a0644e8c7dcc..cc85469699ecbfe37ecf0d8d123b944af4fb6a10 100644 GIT binary patch literal 94562 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 Jlu4O=_&+8=@vi^? literal 98642 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�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�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 Yhi{VLr!Tm=3kvuW7m*RJ6x8$oKlO0?Y5)KL diff --git a/docs/en_US/images/toolbar.png b/docs/en_US/images/toolbar.png index aac16b967b93b44576bf2a042b989aa296251648..30223d28acfa9d12d4cf7e9122675249045dfd36 100644 GIT binary patch literal 55279 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 CNuNOg literal 42931 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%0D-NlnK%<oL#WUV3Obj&<*1=JUG#xkE) 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 K<4QTJ@c#j4GvEOL diff --git a/docs/en_US/psql_tool.rst b/docs/en_US/psql_tool.rst new file mode 100644 index 00000000..229a2c5a --- /dev/null +++ b/docs/en_US/psql_tool.rst @@ -0,0 +1,19 @@ +.. _psql_tool: + +****************** +`PSQL Tool`:index: +****************** + +PSQL tool allows user to connect to PostgreSQL server using psql terminal. + +* Open PSQL Tool from Tools menu or context menu PSQL Tool from tree view. + +* PSQL will connect to the selected database from browser tree. + +.. image:: images/psql_tool.png + :alt: PSQL tool window + :align: center + +You can open multiple instance of the PSQL tool in individual tabs simultaneously. +To close the PSQL tool, click the *X* in the upper-right hand corner of the tab bar. + diff --git a/docs/en_US/toolbar.rst b/docs/en_US/toolbar.rst index f4c685f2..60ddc247 100644 --- a/docs/en_US/toolbar.rst +++ b/docs/en_US/toolbar.rst @@ -20,4 +20,6 @@ the selected browser node. * Use the :ref:`Filtered Rows <viewdata_filter>` button to access the Data Filter popup to apply a filter to a set of data for viewing/editing. * Use the :ref:`Search objects <search_objects>` button to access the search objects - dialog. It helps you search any database object. \ No newline at end of file + dialog. It helps you search any database object. +* Use the :ref:`PSQL Tool <psql_tool>` button to open the PSQL Tool in the selected + database context. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 08dc344d..a1477473 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,6 @@ # ############################################################################### -cheroot==8.* Flask==1.* Flask-Gravatar==0.* Flask-Login==0.* @@ -37,3 +36,5 @@ sshtunnel==0.* ldap3==2.* Flask-BabelEx==0.* gssapi==1.6.* +flask-socketio>=5.0.1 +eventlet==0.30.2 diff --git a/web/config.py b/web/config.py index 4d1f9869..2143fc85 100644 --- a/web/config.py +++ b/web/config.py @@ -156,8 +156,8 @@ X_FRAME_OPTIONS = "SAMEORIGIN" # such as JavaScript, CSS, or pretty much anything that the browser loads. # see https://content-security-policy.com/#source_list for more info # e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';" -CONTENT_SECURITY_POLICY = "default-src http: data: blob: 'unsafe-inline' " \ - "'unsafe-eval';" +CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \ + " 'unsafe-eval';" # STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the # Strict-Transport-Security header @@ -636,6 +636,19 @@ KRB_AUTO_CREATE_USER = True KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache') +# PSQL tool settings +# This will enable PSQL tool in pgAdmin. So user can execute the commands using +# PSQL terminal in pgAdmin. +ENABLE_PSQL = True + +# ALLOW_PSQL_SHELL_COMMAND = True will disable the execution of os level +# commands using meta command \! from PSQL terminal. +# As PSQL allow user to execute the os level commands from the PSQL terminal +# user can execute any system level command as per the system login user +# privileges. Default this setting is set to False but if it set to True +# User will able to execute the system level commands through PSQL terminal in +# pgAdmin. +ALLOW_PSQL_SHELL_COMMANDS = False ########################################################################## # Local config settings diff --git a/web/package.json b/web/package.json index 76ca44c0..4f3f0f0f 100644 --- a/web/package.json +++ b/web/package.json @@ -117,6 +117,7 @@ "shim-loader": "^1.0.1", "slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16", "snapsvg-cjs": "^0.0.6", + "socket.io-client": "^4.0.0", "split.js": "^1.5.10", "tablesorter": "^2.31.2", "tempusdominus-bootstrap-4": "^5.1.2", @@ -124,6 +125,10 @@ "underscore": "^1.13.1", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#89e006611f4d0fc24b0a098fa2041821d093be4f", "wkx": "^0.5.0" + "xterm": "^4.11.0", + "xterm-addon-fit": "^0.5.0", + "xterm-addon-search": "^0.8.0", + "xterm-addon-web-links": "^0.4.0" }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index d2bd1af6..dc1924cb 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -13,7 +13,7 @@ to start a web server.""" import sys -from cheroot.wsgi import Server as CherootServer + if sys.version_info < (3, 4): raise RuntimeError('This application must be run under Python 3.4 ' @@ -37,7 +37,7 @@ else: builtins.SERVER_MODE = None import config -from pgadmin import create_app +from pgadmin import create_app, socketio from pgadmin.utils import u_encode, fs_encoding, file_quote from pgadmin.utils.constants import INTERNAL # Get the config database schema version. We store this in pgadmin.model @@ -97,6 +97,8 @@ if not os.path.isfile(config.SQLITE_PATH): ########################################################################## app = create_app() app.debug = False +app.config['sessions'] = dict() + if config.SERVER_MODE: app.wsgi_app = ReverseProxied(app.wsgi_app) @@ -206,17 +208,16 @@ def main(): else: # Can use cheroot instead of flask dev server when not in debug # 10 is default thread count in CherootServer - num_threads = 10 if config.THREADED_MODE else 1 - prod_server = CherootServer( - (config.DEFAULT_SERVER, config.EFFECTIVE_SERVER_PORT), - wsgi_app=app, - numthreads=num_threads, - server_name=config.APP_NAME) + # num_threads = 10 if config.THREADED_MODE else 1 try: - print("Using production server...") - prod_server.start() + socketio.run( + app, + host=config.DEFAULT_SERVER, + port=config.EFFECTIVE_SERVER_PORT, + ) except KeyboardInterrupt: - prod_server.stop() + print("CLOSE SERVER") + socketio.stop() except IOError: app.logger.error("Error starting the app server: %s", sys.exc_info()) diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index a7333537..fad91082 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -19,6 +19,7 @@ from collections import defaultdict from importlib import import_module from flask import Flask, abort, request, current_app, session, url_for +from flask_socketio import SocketIO from werkzeug.exceptions import HTTPException from flask_babelex import Babel, gettext from flask_babelex import gettext as _ @@ -52,10 +53,15 @@ import mimetypes mimetypes.add_type('application/javascript', '.js') mimetypes.add_type('text/css', '.css') + winreg = None if os.name == 'nt': import winreg +socketio = SocketIO(manage_session=False, async_mode='eventlet', + logger=False, engineio_logger=False, debug=False, + ping_interval=25, ping_timeout=120) + class PgAdmin(Flask): def __init__(self, *args, **kwargs): @@ -811,4 +817,5 @@ def create_app(app_name=None): ########################################################################## # All done! ########################################################################## + socketio.init_app(app) return app diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 235db027..d835ca82 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -10,6 +10,7 @@ from flask_babelex import gettext from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\ PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \ PREF_LABEL_OPTIONS +from flask_security import current_user import config LOCK_LAYOUT_LEVEL = { @@ -511,10 +512,12 @@ def register_browser_preferences(self): options=[{'label': gettext('Query Tool'), 'value': 'qt'}, {'label': gettext('Debugger'), 'value': 'debugger'}, {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], - help_str=gettext('Select Query Tool, Debugger, or Schema Diff from ' - 'the drop-down to set open in new browser tab for ' - 'that particular module.'), + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext('Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), select2={ 'multiple': True, 'allowClear': False, 'tags': True, 'first_empty': False, @@ -523,3 +526,16 @@ def register_browser_preferences(self): 'placeholder': gettext('Select open new tab...') } ) + + self.psql_tab_title = self.preference.register( + 'tab_settings', 'psql_tab_title_placeholder', + gettext("PSQL tool tab title"), + 'text', '%DATABASE%/%USERNAME%@%SERVER%', + category_label=PREF_LABEL_DISPLAY, + help_str=gettext( + 'Supported placeholders are %DATABASE%, %USERNAME%, and %SERVER%. ' + 'Users can provide any string with or without placeholders of' + ' their choice. The blank title will be revert back to the' + ' default title with placeholders.' + ) + ) diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index f4165c32..fb7ff12c 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -34,6 +34,7 @@ from pgadmin.utils.constants import UNAUTH_REQ, MIMETYPE_APP_JS, \ SERVER_CONNECTION_CLOSED from sqlalchemy import or_ from pgadmin.utils.preferences import Preferences +from .... import socketio as sio def has_any(data, keys): @@ -1499,6 +1500,13 @@ class ServerNode(PGChildNodeView): # Release Connection manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + # Check if any psql terminal is running for the current disconnecting + # server. If any terminate the psql tool connection. + if 'sid_soid_mapping' in current_app.config and str(sid) in \ + current_app.config['sid_soid_mapping']: + if str(sid) in current_app.config['sid_soid_mapping']: + for i in current_app.config['sid_soid_mapping'][str(sid)]: + sio.emit('disconnect-psql', namespace='/pty', to=i) status = manager.release() diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 01ab89c5..eb20cac5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -122,6 +122,9 @@ define('pgadmin.node.database', [ is_connected: function(node) { return (node && node.connected == true && node.canDisconn == true); }, + is_psql_enabled: function(node) { + return (node && node.connected == true) && pgAdmin['enable_psql']; + }, is_conn_allow: function(node) { return (node && node.allowConn == true); }, diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 45dea090..ffd715f8 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -101,7 +101,8 @@ define('pgadmin.node.server', [ icon: 'fa fa-unlink', enable : 'is_connected',data: { data_disabled: gettext('Database is already disconnected.'), }, - },{ + }, + { name: 'reload_configuration', node: 'server', module: this, applies: ['tools', 'context'], callback: 'reload_configuration', category: 'reload', priority: 6, label: gettext('Reload Configuration'), @@ -728,6 +729,14 @@ define('pgadmin.node.server', [ return false; }, + /* Open psql tool for server*/ + server_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + } }, model: pgAdmin.Browser.Node.Model.extend({ defaults: { diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index 3823ef35..e763aa11 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -64,6 +64,14 @@ define([ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', }]); + + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); } } }, @@ -498,6 +506,13 @@ define([ pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); } }, + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, }); return pgBrowser.Collection; diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index ca3cb1e3..f7c04d0d 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -209,6 +209,16 @@ define('pgadmin.browser.node', [ priority: 997, label: gettext('Search Objects...'), icon: 'fa fa-search', enable: enable, }]); + + if(pgAdmin['enable_psql']) { + // show psql tool same as query tool. + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); + } } // This will add options of scripts eg:'CREATE Script' @@ -903,6 +913,15 @@ define('pgadmin.browser.node', [ pgAdmin.DataGrid.show_query_tool('', i); }, + // Callback to render psql tool. + show_psql_tool: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.psql.psql_tool(d, i, true); + }, + // Logic to change the server background colour // There is no way of applying CSS to parent element so we have to // do it via JS code only diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index 09baaf22..65e29c85 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -56,9 +56,23 @@ let _defaultToolBarButtons = [ toggleClass: '', parentClass: 'pg-toolbar-btn btn-primary-icon', enabled: false, - }, + } ]; +if(pgAdmin['enable_psql']) { + _defaultToolBarButtons.push({ + label: gettext('PSQL Tool'), + ariaLabel: gettext('PSQL Tool'), + btnClass: 'fas fa-terminal', + text: '', + toggled: false, + toggleClass: '', + parentClass: 'pg-toolbar-btn btn-primary-icon pg-toolbar-psql', + enabled: false, + }); +} + + // Place holder for non default tool bar buttons. let _otherToolbarButtons = []; @@ -105,6 +119,13 @@ export function initializeToolbar(panel, wcDocker) { pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected()); else if ('name' in data && data.name === gettext('Search objects')) pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); + else if ('name' in data && data.name === gettext('PSQL Tool')){ + var input = {}, + t = pgAdmin.Browser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgAdmin.Browser.psql.psql_tool(d, i, true); + } }); } diff --git a/web/pgadmin/browser/static/scss/_browser.scss b/web/pgadmin/browser/static/scss/_browser.scss index 0d157384..ae72f0e6 100644 --- a/web/pgadmin/browser/static/scss/_browser.scss +++ b/web/pgadmin/browser/static/scss/_browser.scss @@ -53,3 +53,9 @@ samp, border-width: 1px; font-size: 1.15em; } + +.pg-toolbar-psql { + padding-top: 0em; + font-size: inherit; + align-items: center; +} diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 8597df48..b0a317a5 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -52,6 +52,10 @@ define('pgadmin.browser.utils', pgAdmin['user_inactivity_timeout'] = {{ current_app.config.get('USER_INACTIVITY_TIMEOUT') }}; pgAdmin['override_user_inactivity_timeout'] = '{{ current_app.config.get('OVERRIDE_USER_INACTIVITY_TIMEOUT') }}' == 'True'; + /* GET PSQL Tool related config */ + pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; + // Define list of nodes on which Query tool option doesn't appears var unsupported_nodes = pgAdmin.unsupported_nodes = [ 'server_group', 'server', 'coll-tablespace', 'tablespace', diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py index 312b0ee1..5e22f2d5 100644 --- a/web/pgadmin/browser/utils.py +++ b/web/pgadmin/browser/utils.py @@ -62,7 +62,8 @@ def underscore_unescape(text): ">": '>', """: '"', "`": '`', - "'": "'" + "'": "'", + "'": "'" } # always replace & first diff --git a/web/pgadmin/static/bundle/browser.js b/web/pgadmin/static/bundle/browser.js index 14140a2f..0b3ad81b 100644 --- a/web/pgadmin/static/bundle/browser.js +++ b/web/pgadmin/static/bundle/browser.js @@ -11,6 +11,7 @@ define('bundled_browser',[ 'pgadmin.browser', 'sources/browser/index', 'top/tools/erd/static/js/index', + 'top/tools/psql/static/js/index', ], function(pgBrowser) { pgBrowser.init(); }); diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css index c2a776c8..5b4a9f2d 100644 --- a/web/pgadmin/static/css/style.css +++ b/web/pgadmin/static/css/style.css @@ -21,3 +21,5 @@ @import '../vendor/backgrid/backgrid.css'; @import '../vendor/backgrid/backgrid-select-all.css'; + +@import 'node_modules/xterm/css/xterm.css'; diff --git a/web/pgadmin/static/scss/pgadmin.scss b/web/pgadmin/static/scss/pgadmin.scss index 6c38c6f7..2e5bc6d9 100644 --- a/web/pgadmin/static/scss/pgadmin.scss +++ b/web/pgadmin/static/scss/pgadmin.scss @@ -10,6 +10,11 @@ $theme-colors: ( --color-fg: #{$color-fg}; --color-bg: #{$color-bg}; --border-color: #{$border-color}; + --psql-background: #{$psql-background}; + --psql-foreground: #{$psql-foreground}; + --psql-cursor: #{$psql-cursor}; + --psql-cursorAccent: #{$psql-cursorAccent}; + --psql-selection: #{$psql-selection}; } @import "bootstrap/scss/bootstrap"; diff --git a/web/pgadmin/static/scss/resources/_default.variables.scss b/web/pgadmin/static/scss/resources/_default.variables.scss index ce33424e..d9fb6653 100644 --- a/web/pgadmin/static/scss/resources/_default.variables.scss +++ b/web/pgadmin/static/scss/resources/_default.variables.scss @@ -371,3 +371,10 @@ $erd-link-selected-color: $color-fg !default; $erd-bg-grid: url("data:image/svg+xml, %3Csvg width='100%25' viewBox='0 0 45 45' style='background-color:#{url-friendly-colour($erd-canvas-bg)}' height='100%25' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cpattern id='smallGrid' width='15' height='15' patternUnits='userSpaceOnUse'%3E%3Cpath d='M 15 0 L 0 0 0 15' fill='none' stroke='#{url-friendly-colour($erd-canvas-grid)}' stroke-width='0.5'/%3E%3C/pattern%3E%3Cpattern id='grid' width='45' height='45' patternUnits='userSpaceOnUse'%3E%3Crect width='100' height='100' fill='url(%23smallGrid)'/%3E%3Cpath d='M 100 0 L 0 0 0 100' fill='none' stroke='#{url-friendly-colour($erd-canvas-grid)}' stroke-width='1'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='100%25' height='100%25' fill='url(%23grid)' /%3E%3C/svg%3E%0A"); $select2-readonly: $color-gray-lighter !default; + +// psql tool variables +$psql-background: $color-bg !default; +$psql-foreground: $color-fg !default; +$psql-cursor: $color-fg !default; +$psql-cursorAccent: $color-fg !default; +$psql-selection: #326690 !default; diff --git a/web/pgadmin/static/scss/resources/dark/_theme.variables.scss b/web/pgadmin/static/scss/resources/dark/_theme.variables.scss index efa36df8..2fa907b8 100644 --- a/web/pgadmin/static/scss/resources/dark/_theme.variables.scss +++ b/web/pgadmin/static/scss/resources/dark/_theme.variables.scss @@ -136,3 +136,10 @@ $erd-link-color: $color-fg; $erd-link-selected-color: $color-fg; $select2-readonly: $color-bg; + +// psql tool variables +$psql-background: $color-bg; +$psql-foreground: $color-fg; +$psql-cursor: $color-fg; +$psql-cursorAccent: $color-fg; +$psql-selection: #d6effc; diff --git a/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss b/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss index 682f2622..b4783bce 100644 --- a/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss +++ b/web/pgadmin/static/scss/resources/high_contrast/_theme.variables.scss @@ -207,3 +207,10 @@ $quick-search-a-text-color: $black !default; $quick-search-info-icon: #8A8A8A !default; $select2-readonly: $color-gray; + +// psql tool variables +$psql-background: $color-bg; +$psql-foreground: $color-fg; +$psql-cursor: $color-fg; +$psql-cursorAccent: $color-fg; +$psql-selection: $color-primary-light; diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js index 1348cc45..42efc04d 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js @@ -100,6 +100,10 @@ export function generateTitle(title_placeholder, title_data) { title_placeholder = title_placeholder.replace(new RegExp('%ARGS%'), _.unescape(title_data.args)); title_placeholder = title_placeholder.replace(new RegExp('%SCHEMA%'), _.unescape(title_data.schema)); title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + } else if(title_data.type == 'psql_tool') { + title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database)); + title_placeholder = title_placeholder.replace(new RegExp('%USERNAME%'), _.unescape(title_data.username)); + title_placeholder = title_placeholder.replace(new RegExp('%SERVER%'), _.unescape(title_data.server)); } return _.escape(title_placeholder); diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py new file mode 100644 index 00000000..30b5237c --- /dev/null +++ b/web/pgadmin/tools/psql/__init__.py @@ -0,0 +1,686 @@ +#!/usr/bin/env python3 +import fcntl +import os +import pty +import re +import select +import struct +import termios +import config +import eventlet.green.subprocess as subprocess + +from config import PG_DEFAULT_DRIVER +from flask import Response, url_for, request +from flask import render_template, copy_current_request_context, \ + current_app as app +from flask_babelex import gettext +from flask_security import login_required, current_user +from pgadmin.browser.utils import underscore_unescape +from pgadmin.utils import PgAdminModule +from pgadmin.utils.constants import MIMETYPE_APP_JS +from pgadmin.utils.driver import get_driver +from ... import socketio as sio +from pgadmin.utils import get_complete_file_path + + +session_input = dict() +session_input_cursor = dict() +session_last_cmd = dict() +pdata = dict() +cdata = dict() + + +class PSQLModule(PgAdminModule): + """ + class PSQLModule(PgAdminModule) + A module class for PSQL derived from PgAdminModule. + """ + + LABEL = gettext("PSQL") + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.psql', + 'path': url_for('psql.index') + "psql", + 'when': None + }] + + def get_panels(self): + return [] + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints for PSQL module + """ + return [ + 'psql.panel' + ] + + +blueprint = PSQLModule('psql', __name__, static_url_path='/static') + + [email protected]("/psql.js") +@login_required +def script(): + """render the required javascript""" + return Response( + response=render_template("psql/js/psql.js", _=gettext), + status=200, + mimetype=MIMETYPE_APP_JS + ) + + [email protected]('/panel/<int:trans_id>', + methods=["POST"], + endpoint="panel") +@login_required +def panel(trans_id): + """ + Return panel template for PSQL tools. + :param trans_id: + """ + params = { + 'trans_id': trans_id, + 'title': request.form['title'] + } + if 'sid_soid_mapping' not in app.config: + app.config['sid_soid_mapping'] = dict() + if request.args: + params.update({k: v for k, v in request.args.items()}) + # Set TERM env for xterm. + os.environ['TERM'] = 'xterm' + + return render_template('editor_template.html', + sid=params['sid'], + db=underscore_unescape(params['db']) if params[ + 'db'] else 'postgres', + server_type=params['server_type'], + is_enable=config.ENABLE_PSQL, + title=underscore_unescape(params['title']), + theme=params['theme'] + ) + + +def set_term_size(fd, row, col, xpix=0, ypix=0): + """ + Set the terminal size as per UI xterm size. + :param fd: + :param row: + :param col: + :param xpix: + :param ypix: + """ + term_size = struct.pack('HHHH', row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) + + [email protected]('connect', namespace='/pty') +def connect(): + """ + Connect to the server through socket. + :return: + :rtype: + """ + if config.ENABLE_PSQL: + sio.emit('connected', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + if request.sid in session_last_cmd: + session_last_cmd[request.sid]['is_new_connection'] = False + else: + session_last_cmd[request.sid] = {'cmd': '', 'arrow_up': False, + 'invalid_cmd': False, + 'is_new_connection': False} + else: + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def create_pty_terminal(connection_data): + # Create the pty terminal process, parent and fd are file descriptors + # for parent and child. + parent, fd = pty.openpty() + p = None + if parent is not None: + # Child process + p = subprocess.Popen(connection_data, + preexec_fn=os.setsid, + stdin=fd, + stdout=fd, + stderr=fd, + universal_newlines=True + ) + + app.config['sessions'][request.sid] = parent + pdata[request.sid] = p + cdata[request.sid] = fd + else: + app.config['sessions'][request.sid] = parent + cdata[request.sid] = fd + set_term_size(fd, 50, 50) + + return p, parent, fd + + +def read_terminal_data(parent, data_ready, max_read_bytes, sid): + """ + Read the terminal output. + :param parent: + :param data_ready: + :param max_read_bytes: + :param sid: + :return: + """ + if parent in data_ready: + # Read the output from parent fd (terminal). + output = os.read(parent, max_read_bytes) + emit_output = True + + if sid in session_last_cmd and session_last_cmd[sid][ + 'arrow_up'] and not session_last_cmd[request.sid][ + 'arrow_left_right']: + session_last_cmd[sid]['cmd'] = output.decode() + session_input_cursor[request.sid] = len( + session_last_cmd[sid]['cmd']) + session_last_cmd[sid]['arrow_up'] = True + + if sid in session_last_cmd and session_last_cmd[sid]['invalid_cmd']: + # If command is invalid then emit error to user. + emit_output = False + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security\r\n"), + 'error': True + }, + namespace='/pty', room=sid) + # If command is valid then emit output to user. + if emit_output: + sio.emit('pty-output', + {'result': output.decode(), + 'error': False}, + namespace='/pty', room=sid) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + + [email protected]('start_process', namespace='/pty') +def start_process(data): + """ + Start the pty terminal and execute psql command and emit results to user. + :param data: + :return: + """ + @copy_current_request_context + def read_and_forward_pty_output(sid, data): + max_read_bytes = 1024 * 20 + + p, parent, fd = create_pty_terminal(connection_data) + + while p and p.poll() is None: + if request.sid in app.config['sessions']: + # This code is added to make this unit testable. + if "is_test" not in data: + sio.sleep(0.01) + else: + data['count'] += 1 + if data['count'] == 5: + break + + timeout = 0 + # module provides access to platform-specific I/O + # monitoring functions + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) + + read_terminal_data(parent, data_ready, max_read_bytes, sid) + + # Check user is authenticated and PSQL is enabled in config. + if current_user.is_authenticated and config.ENABLE_PSQL: + connection_data = [] + try: + db = '' + if data['db']: + db = underscore_unescape(data['db']).replace('\\', "\\\\") + + conn, manager = _get_connection(int(data['sid']), data) + psql_utility = manager.utility('sql') + connection_data = get_connection_str(psql_utility, db, + manager) + except Exception as e: + # If any error raised during the start the PSQL emit error to UI. + # request.sid: This sid is socket id. + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + + try: + if str(data['sid']) not in app.config['sid_soid_mapping']: + # request.sid: refer request.sid as socket id. + app.config['sid_soid_mapping'][str(data['sid'])] = list() + app.config['sid_soid_mapping'][str(data['sid'])].append( + request.sid) + else: + app.config['sid_soid_mapping'][str(data['sid'])].append( + request.sid) + + sio.start_background_task(read_and_forward_pty_output, + request.sid, data) + except Exception as e: + sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}'.format(e), + }, namespace='/pty', room=request.sid) + else: + # Show error if user is not authenticated. + sio.emit('conn_not_allow', {'sid': request.sid}, namespace='/pty', + to=request.sid) + + +def _get_connection(sid, data): + """ + Get the connection object of ERD. + :param sid: + :param did: + :param trans_id: + :return: + """ + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + try: + conn = manager.connection() + # This is added for unit test only, no use in normal execution. + if 'pwd' in data: + kwargs = {'password': data['pwd'], "user": data['user']} + status, msg = conn.connect(**kwargs) + else: + status, msg = conn.connect() + if not status: + app.logger.error(msg) + sio.emit(sio.emit( + 'conn_error', + { + 'error': 'Error while running psql command: {0}' + ''.format('Server connection not present.'), + }, namespace='/pty', room=request.sid)) + raise RuntimeError('Server is not connected.') + + return conn, manager + except Exception as e: + app.logger.error(e) + raise + + +def get_connection_str(psql_utility, db, manager): + """ + Get connection string(through connection dsn) + :param psql_utility: PostgreSQL binary path. + :param db: database name to connect specific db. + :return: connection attribute list for PSQL connection. + """ + conn_attr = get_conn_str(manager, db) + conn_attr_list = list() + conn_attr_list.append(psql_utility) + conn_attr_list.append(conn_attr) + return conn_attr_list + + +def get_conn_str(manager, db): + """ + Get connection attributes for psql connection. + :param manager: + :param db: + :return: + """ + manager.export_password_env('PGPASSWORD') + conn_attr =\ + "host={0} port={1} dbname={2} user={3} sslmode={4} " \ + "sslcompression={5} " \ + "".format( + manager.local_bind_host if manager.use_ssh_tunnel else + manager.host, + manager.local_bind_port if manager.use_ssh_tunnel else + manager.port, + db if db != '' else 'postgres', + manager.user if manager.user else 'postgres', + manager.ssl_mode, + True if manager.sslcompression else False, + ) + + if manager.hostaddr: + conn_attr = " {0} hostaddr={1}".format(conn_attr, manager.hostaddr) + + if manager.passfile: + conn_attr = " {0} passfile={1}".format(conn_attr, + get_complete_file_path( + manager.passfile)) + + if get_complete_file_path(manager.sslcert): + conn_attr = " {0} sslcert={1}".format( + conn_attr, get_complete_file_path(manager.sslcert)) + + if get_complete_file_path(manager.sslkey): + conn_attr = " {0} sslkey={1}".format( + conn_attr, get_complete_file_path(manager.sslkey)) + + if get_complete_file_path(manager.sslrootcert): + conn_attr = " {0} sslrootcert={1}".format( + conn_attr, get_complete_file_path(manager.sslrootcert)) + + if get_complete_file_path(manager.sslcrl): + conn_attr = " {0} sslcrl={1}".format( + conn_attr, get_complete_file_path(manager.sslcrl)) + + if manager.service: + conn_attr = " {0} service={1}".format( + conn_attr, get_complete_file_path(manager.service)) + + return conn_attr + + +def check_last_exe_cmd(data): + """ + Check the is user try to execute last executed command. + :param data: + :return: + """ + # If user get previous executed command from history then set + # current command as previous executed command. + if session_last_cmd[request.sid]['cmd'] and session_last_cmd[request.sid][ + 'arrow_up']: + user_input = str( + session_last_cmd[request.sid]['cmd']).strip() + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + else: + if request.sid not in session_input: + session_input[request.sid] = data['input'] + user_input = str(session_input[request.sid]).strip() + else: + user_input = str(session_input[request.sid]).strip() + + return user_input + + +def invalid_cmd(): + """ + Invalid command + :return: + :rtype: + """ + session_last_cmd[request.sid]['invalid_cmd'] = True + + for i in range(len(session_input[request.sid])): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + session_input[request.sid] = '' + + +def check_valid_cmd(user_input): + """ + Check if user entered a valid cmd and \\! command is preset as a string + only in current executing command. if \\! is present as command don't + allow the execution of command. + :param user_input: + :return: + """ + stop_execution = True + # Check \! is passed as string or not. + double_quote_strs = re.findall('"([^"]*)"', user_input) + if not double_quote_strs: + double_quote_strs = re.findall("'([^']*)'", user_input) + + if double_quote_strs: + for sub_str in double_quote_strs: + if re.search("\\\!", sub_str): + stop_execution = False + # break + + if stop_execution: + session_last_cmd[request.sid]['invalid_cmd'] = True + # Remove already added command from terminal. + for i in range(len(user_input)): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + # Add Enter event to execute the command. + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + else: + session_last_cmd[request.sid]['invalid_cmd'] = False + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + + +def enter_key_press(data): + """ + Handel the Enter key press event. + :param data: + """ + user_input = check_last_exe_cmd(data) + session_input_cursor[request.sid] = 0 + + # If ALLOW_PSQL_SHELL_COMMANDS is False then user can't execute + # \! meta command to run shell commands through PSQL terminal. + # Check before executing the user entered command does not + # contains \! in input. + is_new_connection = session_last_cmd[request.sid][ + 'is_new_connection'] + if user_input.startswith('\\!') and re.match("^\\\!$", user_input) and len( + user_input) == 2 and not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not is_new_connection: + invalid_cmd() + elif re.search("\\\!", user_input) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and\ + not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif user_input == '\q' or user_input == 'q\\q': + # If user enter \q to terminate the PSQL, emit the msg to + # notify user connection is terminated. + sio.emit('pty-output', + { + 'result': gettext( + 'Connection terminated, To create new ' + 'connection please open another psql' + ' tool.'), + 'error': True}, + namespace='/pty', room=request.sid) + os.write(app.config['sessions'][request.sid], + '\n'.encode()) + + else: + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + session_input[request.sid] = '' + session_last_cmd[request.sid]['is_new_connection'] = False + + +def backspace_key_press(): + """ + Handel the backspace key press event. + :return: + :rtype: + """ + session_last_cmd[request.sid]['arrow_left_right'] = True + + if session_last_cmd[request.sid]['cmd']: + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + + user_input = list(session_input[request.sid]) + + if session_input_cursor[request.sid] == 1: + index = 0 + session_input_cursor[request.sid] -= 1 + else: + if session_input_cursor[request.sid] > 0: + index = (session_input_cursor[request.sid]) - 1 + session_input_cursor[request.sid] -= 1 + else: + index = session_input_cursor[request.sid] + session_input_cursor[request.sid] = 0 + + if len(user_input): + del user_input[index] + session_input[request.sid] = "".join(user_input) + + if len(session_input[request.sid]) == 0: + session_input_cursor[request.sid] = 0 + session_last_cmd[request.sid]['cmd'] = '' + + +def set_user_input(data): + """ + Check and set current input as user input in session_input. + :param data: + """ + if session_last_cmd[request.sid]['cmd'] and \ + session_input[request.sid] == '': + session_input[request.sid] = \ + session_last_cmd[request.sid]['cmd'] + session_input_cursor[request.sid] = len( + session_input[request.sid]) + else: + session_last_cmd[request.sid]['arrow_up'] = False + session_last_cmd[request.sid]['cmd'] = '' + user_input = list(session_input[request.sid]) + user_input.insert(session_input_cursor[request.sid], + data['input']) + session_input[request.sid] = ''.join(user_input) + session_input_cursor[request.sid] += 1 + session_last_cmd[request.sid]['arrow_left_right'] = False + + +def other_key_press(data): + """ + Handel the other key press from psql tool. + :param data: + :type data: + :return: + :rtype: + """ + if data['key_name'] == 'ArrowLeft': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] > 0: + session_input_cursor[request.sid] -= 1 + + elif data['key_name'] == 'ArrowRight': + session_last_cmd[request.sid]['arrow_left_right'] = True + if session_input_cursor[request.sid] < len( + session_input[request.sid]): + session_input_cursor[request.sid] += 1 + + elif data['key_name'] == 'ArrowUp': + session_last_cmd[request.sid]['arrow_up'] = True + session_last_cmd[request.sid]['arrow_left_right'] = False + session_input[request.sid] = session_last_cmd[request.sid][ + 'cmd'] + session_input_cursor[request.sid] = len( + session_last_cmd[request.sid]['cmd']) + + elif request.sid in session_input and \ + data['key_name'] == 'Backspace' and \ + (len(session_input[request.sid]) or + len(session_last_cmd[request.sid])): + backspace_key_press() + elif request.sid in session_input: + set_user_input(data) + else: + session_input_cursor[request.sid] = 0 + session_input[request.sid] = data['input'] + session_input_cursor[request.sid] += 1 + + # Write user input to terminal parent fd. + os.write(app.config['sessions'][request.sid], + data['input'].encode()) + + [email protected]('socket_input', namespace='/pty') +def socket_input(data): + """ + This get the user input through socket. + :param data: User input from socket. + """ + try: + # request.sid: refer request.sid as socket id. + # Check PSQL enabled setting from config. + enable_psql = True if config.ENABLE_PSQL else False + + if request.sid in app.config['sessions']: + if data['key_name'] == 'Enter' and enable_psql: + enter_key_press(data) + else: + other_key_press(data) + except Exception as e: + # Delete socket id from sessions. + # request.sid: refer request.sid as socket id. + sio.emit('pty-output', + { + 'result': gettext('Invalid session.\r\n'), + 'error': True + }, + namespace='/pty', room=request.sid) + del app.config['sessions'][request.sid] + + [email protected]('resize', namespace='/pty') +def resize(data): + """ + Resize the pty terminal as per the UI terminal. + :param data: UI terminal rows and cols data + """ + # request.sid: refer request.sid as socket id. + if request.sid in app.config['sessions']: + set_term_size(app.config['sessions'][request.sid], data['rows'], + data['cols']) + + [email protected]('disconnect', namespace='/pty') +def disconnect(): + """ + Disconnect the socket and terminate the process + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + disconnect_socket() + + [email protected]('server-disconnect', namespace='/pty') +def server_disconnect(data): + """ + Disconnect the socket and terminate the process after user disconnect + the server. we can't use disconnect event name as it is reserved for socket + internal use. + """ + # request.sid: refer request.sid as socket id. + if request.sid in pdata and request.sid in app.config['sid_soid_mapping'][ + data['sid']]: + # On disconnect socket manually exit the psql terminal and close the + # parend and child fd then kill the subprocess. + app.config['sid_soid_mapping'][data['sid']] = [soid for soid in + app.config[ + 'sid_soid_mapping'][ + data['sid']] if + soid != request.sid] + disconnect_socket() + + +def disconnect_socket(): + os.write(app.config['sessions'][request.sid], '\q\n'.encode()) + sio.sleep(1) + os.close(app.config['sessions'][request.sid]) + os.close(cdata[request.sid]) + del app.config['sessions'][request.sid] diff --git a/web/pgadmin/tools/psql/static/js/index.js b/web/pgadmin/tools/psql/static/js/index.js new file mode 100644 index 00000000..4d88ba04 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/index.js @@ -0,0 +1,23 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import $ from 'jquery'; +import _ from 'underscore'; +import pgAdmin from 'sources/pgadmin'; +import pgBrowser from 'top/browser/static/js/browser'; +import * as csrfToken from 'sources/csrf'; +import {initialize} from './psql_module'; + +let pgBrowserOut = initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser); + +module.exports = { + pgBrowser: pgBrowserOut, +}; diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js new file mode 100644 index 00000000..9ff02aa5 --- /dev/null +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -0,0 +1,429 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import { Terminal } from 'xterm'; +import { FitAddon } from 'xterm-addon-fit'; +import { WebLinksAddon } from 'xterm-addon-web-links'; +import { SearchAddon } from 'xterm-addon-search'; +import { io } from 'socketio'; +import Alertify from 'pgadmin.alertifyjs'; +import {enable} from 'pgadmin.browser.toolbar'; +import clipboard from 'sources/selection/clipboard'; +import 'wcdocker'; +import {getRandomInt} from 'sources/utils'; + +import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; +import {generateTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; + + +export function setPanelTitle(psqlToolPanel, panelTitle) { + psqlToolPanel.title('<span title="'+panelTitle+'">'+panelTitle+'</span>'); +} + +var wcDocker = window.wcDocker; + +export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) { + var pgBrowser = Browser; + var terminal = Terminal; + var parentData = null; + /* Return back, this has been called more than once */ + if (pgBrowser.psql) + return pgBrowser.psql; + + + // Create an Object Restore of pgBrowser class + pgBrowser.psql = { + init: function() { + this.initialized = true; + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'psql', + module: this, + applies: ['tools'], + callback: 'psql_tool', + priority: 1, + label: gettext('PSQL Tool (Beta)'), + enable: this.psqlToolEnabled, + }]; + + this.enable_psql_tool = pgAdmin['enable_psql']; + if(pgAdmin['enable_psql']) { + pgBrowser.add_menus(menus); + } + + // Creating a new pgBrowser frame to show the data. + var psqlFrameType = new pgBrowser.Frame({ + name: 'frm_psqltool', + showTitle: true, + isCloseable: true, + isPrivate: true, + url: 'about:blank', + }); + + var self = this; + /* Cache may take time to load for the first time + * Keep trying till available + */ + let cacheIntervalId = setInterval(function() { + if(pgBrowser.preference_version() > 0) { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + clearInterval(cacheIntervalId); + } + },0); + + pgBrowser.onPreferencesChange('psql', function() { + self.preferences = pgBrowser.get_preferences_for_module('psql'); + }); + + // Load the newly created frame + psqlFrameType.load(pgBrowser.docker); + return this; + }, + /* Enable/disable PSQL tool menu in tools based + * on node selected. if selected node is present + * in unsupported_nodes, menu will be disabled + * otherwise enabled. + */ + psqlToolEnabled: function(obj) { + + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj) && pgAdmin['enable_psql']) { + if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) { + if (obj._type == 'database' && obj.allowConn) { + return true; + } else if (obj._type != 'database') { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + })(); + + enable(gettext('PSQL Tool'), isEnabled); + return isEnabled; + }, + retrieveAncestorOfTypeServer: function(item) { + let serverInformation = null; + // let aciTreeItem = item || pgBrowser.treeMenu.selected(); + let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); + + if (treeNode) { + let nodeData; + let databaseNode = treeNode.ancestorNode( + (node) => { + nodeData = node.getData(); + return (nodeData._type === 'database'); + } + ); + let isServerNode = (node) => { + nodeData = node.getData(); + return nodeData._type === 'server'; + }; + + if (databaseNode !== null) { + if (nodeData._label.indexOf('=') >= 0) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext( + 'Databases with = symbols in the name cannot be backed up or restored using this utility.' + ) + ); + } else { + if (databaseNode.anyParent(isServerNode)) + serverInformation = nodeData; + } + } else { + if (treeNode.anyFamilyMember(isServerNode)) + serverInformation = nodeData; + } + } + + if (serverInformation === null) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext('Please select server or child node from the browser tree.') + ); + } + return serverInformation; + }, + psql_tool: function(data, aciTreeIdentifier, gen=false) { + const module = 'paths'; + let preference_name = 'pg_bin_dir'; + let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.'); + const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeIdentifier); + + if ((serverInformation.type && serverInformation.type === 'ppas') || + serverInformation.server_type === 'ppas') { + preference_name = 'ppas_bin_dir'; + msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'); + } + const preference = pgBrowser.get_preference(module, preference_name); + if (preference) { + if (!preference.value) { + Alertify.alert(gettext('Configuration required'), msg); + return false; + } + } else { + Alertify.alert( + gettext(this.errorAlertTitle), + gettext('Failed to load preference %s of module %s', preference_name, module) + ); + return false; + } + const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if (node === undefined || !node.getData()) { + Alertify.alert( + gettext('PSQL Error'), + gettext('No object selected.') + ); + return; + } + + parentData = getTreeNodeHierarchyFromIdentifier.call( + pgBrowser, + aciTreeIdentifier + ); + + if(_.isUndefined(parentData.server)) { + Alertify.alert( + gettext('PSQL Error'), + gettext('Please select a server/database object.') + ); + return; + } + + const transId = getRandomInt(1, 9999999); + + var panelTitle = ''; + // Set psql tab title as per prefrences setting. + var title_data = { + 'database': parentData.database ? parentData.database.label : 'postgres' , + 'username': parentData.server.user_name, + 'server': parentData.server.label, + 'type': 'psql_tool', + }; + var tab_title_placeholder = pgBrowser.get_preferences_for_module('browser').psql_tab_title_placeholder; + panelTitle = generateTitle(tab_title_placeholder, title_data); + + const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + + let psqlToolForm = ` + <form id="psqlToolForm" action="${panelUrl}" method="post"> + <input id="title" name="title" hidden /> + <input name="close_url" value="${panelCloseUrl}" hidden /> + </form> + <script> + document.getElementById("title").value = "${_.escape(panelTitle)}"; + document.getElementById("psqlToolForm").submit(); + </script> + `; + var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; + if (open_new_tab && open_new_tab.includes('psql_tool')) { + var newWin = window.open('', '_blank'); + newWin.document.write(psqlToolForm); + newWin.document.title = panelTitle; + } else { + /* On successfully initialization find the properties panel, + * create new panel and add it to the dashboard panel. + */ + var propertiesPanel = pgBrowser.docker.findPanels('properties'); + var psqlToolPanel = pgBrowser.docker.addPanel('frm_psqltool', wcDocker.DOCK.STACKED, propertiesPanel[0]); + + // Set panel title and icon + setPanelTitle(psqlToolPanel, panelTitle); + psqlToolPanel.icon('fas fa-terminal psql-tab-style'); + psqlToolPanel.focus(); + + var openPSQLToolURL = function(j) { + // add spinner element + let $spinner_el = + $(`<div class="pg-sp-container"> + <div class="pg-sp-content"> + <div class="row"> + <div class="col-12 pg-sp-icon"></div> + </div> + </div> + </div>`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { + var frameInitialized = $(j).data('frameInitialized'); + if (frameInitialized) { + clearInterval(init_poller_id); + var frame = $(j).data('embeddedFrame'); + if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); + frame.openHTML(psqlToolForm); + } + } + }, 100); + }; + + openPSQLToolURL(psqlToolPanel); + + } + + }, + getPanelUrls: function(transId, panelTitle, parentData) { + let openUrl = url_for('psql.panel', { + trans_id: transId, + }); + const misc_preferences = pgBrowser.get_preferences_for_module('misc'); + var theme = misc_preferences.theme; + + openUrl += `?sgid=${parentData.server_group._id}` + +`&sid=${parentData.server._id}` + +`&server_type=${parentData.server.server_type}` + + `&theme=${theme}`; + + if(parentData.database && parentData.database._id) { + let db_label = parentData.database._label.replace('\\', '\\\\'); + openUrl += `&db=${db_label}`; + } else { + openUrl += `&db=${''}`; + } + + let closeUrl = url_for('psql.close', { + trans_id: transId, + }); + return [openUrl, closeUrl]; + }, + psql_terminal: function() { + // theme colors + var term = new terminal({ + cursorBlink: true, + macOptionIsMeta: true, + scrollback: 5000, + }); + + return term; + }, + psql_Addon: function(term) { + const fitAddon = this.psql_fit_screen(); + term.loadAddon(fitAddon); + + const webLinksAddon = this.psql_web_link(); + term.loadAddon(webLinksAddon); + + const searchAddon = this.psql_search(); + term.loadAddon(searchAddon); + + fitAddon.fit(); + term.resize(15, 50); + fitAddon.fit(); + return fitAddon; + }, + psql_fit_screen: function() { + return new FitAddon(); + }, + psql_web_link: function() { + return new WebLinksAddon(); + }, + psql_search: function() { + return new SearchAddon(); + }, + psql_socket: function() { + return io('/pty', {pingTimeout: 120000, pingInterval: 25000}); + }, + set_theme: function(term) { + var theme = { + background: getComputedStyle(document.documentElement).getPropertyValue('--psql-background'), + foreground: getComputedStyle(document.documentElement).getPropertyValue('--psql-foreground'), + cursor: getComputedStyle(document.documentElement).getPropertyValue('--psql-cursor'), + cursorAccent: getComputedStyle(document.documentElement).getPropertyValue('--psql-cursorAccent'), + selection: getComputedStyle(document.documentElement).getPropertyValue('--psql-selection'), + }; + term.setOption('theme', theme); + }, + psql_socket_io: function(socket, is_enable, sid, db, server_type, fitAddon, term) { + // Listen all the socket events emit from server. + socket.on('pty-output', function(data){ + if(data.error) { + term.write('\r\n'); + } + term.write(data.result); + if(data.error) { + term.write('\r\n'); + } + }); + // Connect socket + socket.on('connect', () => { + if(is_enable == 'True'){ + socket.emit('start_process', {'sid': sid, 'db': db, 'stype': server_type }); + } + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('conn_error', (response) => { + term.write(response.error); + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('conn_not_allow', () => { + term.write('PSQL connection not allowed'); + fitAddon.fit(); + socket.emit('resize', {'cols': term.cols, 'rows': term.rows}); + }); + + socket.on('disconnect-psql', () => { + socket.emit('server-disconnect', {'sid': sid}); + term.write('\r\nServer disconnected, Connection terminated, To create new connection please open another psql tool.'); + }); + }, + psql_terminal_io: function(term, socket) { + // Listen key press event from terminal and emit socket event. + let selected_text = ''; + term.attachCustomKeyEventHandler(e => { + e.stopPropagation(); + if(e.type=='keydown' && e.metaKey &&(e.key == 'v' || e.key == 'V')) { + if(selected_text != '') { + if (selected_text.length > 0) { + socket.emit('socket_input', {'input': selected_text, 'key_name': e.code}); + selected_text = ''; + } + } else { + navigator.clipboard.readText().then( clipText => { + selected_text = clipText; + if (selected_text.length > 0) { + socket.emit('socket_input', {'input': selected_text, 'key_name': e.code}); + selected_text = ''; + } + }); + } + }else if(e.type=='keydown' && e.metaKey && (e.key == 'c' || e.key == 'C')) { + if (term.hasSelection()) { + selected_text = term.getSelection(); + } else { + selected_text = clipboard.readText(); + } + } + return true; + }); + + term.onKey(function (ev) { + if (pgAdmin['allow_psql_shell_commands']) { + socket.emit('socket_input', {'input': ev.key, 'key_name': ev.domEvent.code}); + } else { + socket.emit('socket_input', {'input': ev.key, 'key_name': ev.domEvent.code}); + } + }); + } + }; + + return pgBrowser.psql; +} + diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html new file mode 100644 index 00000000..43b346b2 --- /dev/null +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -0,0 +1,58 @@ +{% extends "base.html" %} +{% block title %}{{title}}{% endblock %} + +{% block css_link %} +<link type="text/css" rel="stylesheet" href="{{ url_for('browser.browser_css')}}"/> +{% endblock %} +{% block body %} +<style> + body {padding: 0px;} + {% if is_desktop_mode and is_linux %} + .alertify .ajs-dimmer,.alertify .ajs-modal{-webkit-transform: none;} + .alertify-notifier{-webkit-transform: none;} + .alertify-notifier .ajs-message{-webkit-transform: none;} + .alertify .ajs-dialog.ajs-shake{-webkit-animation-name: none;} + .sql-editor-busy-icon.fa-pulse{-webkit-animation: none;} + {% endif %} +</style> +<div style="width: 100%; height: 100%;" id="psql-terminal" class="psql_terminal"></div> +{% endblock %} + + +{% block init_script %} +require( + ['sources/generated/psql_tool'], + function(pgBrowser) { + const term = self.pgAdmin.Browser.psql.psql_terminal(); + <!--Addon for fitAddon, webLinkAddon, SearchAddon --> + const fitAddon = self.pgAdmin.Browser.psql.psql_Addon(term); + <!-- Update the theme for terminal as per pgAdmin 4 theme.--> + self.pgAdmin.Browser.psql.set_theme(term); + <!-- Open the terminal --> + term.open(document.getElementById('psql-terminal')); + <!-- Socket--> + const socket = self.pgAdmin.Browser.psql.psql_socket(); + self.pgAdmin.Browser.psql.psql_socket_io(socket, '{{is_enable}}', '{{sid}}', '{{db}}', '{{server_type}}', fitAddon, term); + self.pgAdmin.Browser.psql.psql_terminal_io(term, socket); + + <!-- Resize the terminal --> + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } + + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) + } + } + + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) + }); +{% endblock %} + + diff --git a/web/pgadmin/tools/psql/tests/__init__.py b/web/pgadmin/tools/psql/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web/pgadmin/tools/psql/tests/psql_test_data.json b/web/pgadmin/tools/psql/tests/psql_test_data.json new file mode 100644 index 00000000..4148c75b --- /dev/null +++ b/web/pgadmin/tools/psql/tests/psql_test_data.json @@ -0,0 +1,184 @@ +{ + "psql_user_input": [ + { + "name": "Enter Select 1;", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Enter Backspace", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_backspace": true, + "move_cursor_up": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowUp", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowUp": true, + "is_history": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowLeft", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowLeft": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Enter ArrowRight", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "Read previous executed command", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select 1;", + "is_arrowRight": true, + "move_cursor_right": true, + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\!", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Meta command \\! with other cmd not allowed", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\! ls", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Valid commands", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "select \"\\!\"", + "mock_data": { + + }, + "expected_data": { + } + },{ + "name": "First command as enter", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "", + "mock_data": { + + }, + "expected_data": { + } + }, + { + "name": "Exist psql terminal by using \\q", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "\\q", + "mock_data": { + + }, + "expected_data": { + } + } + ], + "resize_terminal": [ + { + "name": "Resize psql terminal as per UI.", + "is_positive_test": true, + "mocking_required": false, + "input_data": { + "cols": 141, + "rows": 39 + }, + "mock_data": { + + }, + "expected_data": { + } + } + ], + "backend_task": [ + { + "name": "Backend Task", + "is_positive_test": true, + "mocking_required": false, + "input_cmd": "Select 1;", + "is_backend_task": true, + "mock_data": { + "is_test": true + }, + "expected_data": { + } + } + ] +} diff --git a/web/pgadmin/tools/psql/tests/test_backend_task.py b/web/pgadmin/tools/psql/tests/test_backend_task.py new file mode 100644 index 00000000..a4f14ee4 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_backend_task.py @@ -0,0 +1,87 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLBackend(BaseTestGenerator): + scenarios = utils.generate_scenarios('backend_task', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'], + 'is_test': True, + 'count': 0 + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + for p in self.server['db_password']: + input_data = { + 'input': p, + 'key_name': 'Key{0}'.format(p) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_panel.py b/web/pgadmin/tools/psql/tests/test_panel.py new file mode 100644 index 00000000..6f93c8c2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_panel.py @@ -0,0 +1,36 @@ +import uuid +import random +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data + + +class PSQLPanel(BaseTestGenerator): + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + self.theme = 'standard' + + def runTest(self): + trans_id = random.randint(1, 9999999) + url = '/psql/panel/{trans_id}?sgid={sgid}&sid={sid}&server_type=pg' \ + '&db={db_name}&theme={theme}'.\ + format(trans_id=trans_id, sgid=self.sgid, sid=self.sid, + db_name=self.db_name, theme=self.theme) + + response = self.tester.post( + url, data={"title": "panel_title"}, + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_disabled.py b/web/pgadmin/tools/psql/tests/test_psql_disabled.py new file mode 100644 index 00000000..7dc52498 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_disabled.py @@ -0,0 +1,34 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisabled(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = False + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_psql_input.py b/web/pgadmin/tools/psql/tests/test_psql_input.py new file mode 100644 index 00000000..6f6eabe7 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_psql_input.py @@ -0,0 +1,148 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLInput(BaseTestGenerator): + scenarios = utils.generate_scenarios('psql_user_input', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_backspace') and self.is_backspace: + if hasattr(self, 'move_cursor_up') and self.move_cursor_up: + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Backspace' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowUp') and self.is_arrowUp: + if hasattr(self, 'is_history') and self.is_history: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'Key{0}'.format(ip) + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + input_data = { + 'input': '', + 'key_name': 'ArrowUp' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowLeft') and self.is_arrowLeft: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'is_arrowRight') and self.is_arrowRight: + for ip in self.input_cmd: + input_data = { + 'input': ip, + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + self.test_client.get_received('/pty') + + if hasattr(self, 'move_cursor_right') and self.is_arrowRight: + for i in range(2): + input_data = { + 'input': '', + 'key_name': 'ArrowLeft' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + input_data = { + 'input': '', + 'key_name': 'ArrowRight' + } + self.test_client.emit('socket_input', input_data, + namespace='/pty') + + input_data = { + 'input': '\\n', + 'key_name': 'Enter' + } + self.test_client.emit('socket_input', input_data, namespace='/pty') + self.test_client.get_received('/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_resize_terminal.py b/web/pgadmin/tools/psql/tests/test_resize_terminal.py new file mode 100644 index 00000000..d305c2d0 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_resize_terminal.py @@ -0,0 +1,58 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from . import utils as psql_utils +from .... import socketio + + +class PSQLResizeTerminal(BaseTestGenerator): + scenarios = utils.generate_scenarios('resize_terminal', + psql_utils.test_cases) + + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.emit('resize', self.input_data, namespace='/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_connect.py b/web/pgadmin/tools/psql/tests/test_socket_connect.py new file mode 100644 index 00000000..3791525a --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_connect.py @@ -0,0 +1,35 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketConnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py new file mode 100644 index 00000000..0619eb30 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py @@ -0,0 +1,52 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLSocketDisconnect(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_test_client = app.test_client() + flask_test_client.get('/') + + self.test_client = socketio.test_client( + app, + flask_test_client=flask_test_client, + namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process.py b/web/pgadmin/tools/psql/tests/test_start_process.py new file mode 100644 index 00000000..1245de3f --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process.py @@ -0,0 +1,57 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.utils import server_utils as server_utils +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcess(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + database_info = parent_node_dict["database"][-1] + self.did = database_info["db_id"] + self.sid = parent_node_dict["server"][-1]["server_id"] + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + self.server_con = server_utils.connect_server(self, self.sid) + + def runTest(self): + # Fetch flask client to access current user and other cookies. + flask_client = app.test_client() + flask_client.get('/') + self.test_client = socketio.test_client(app, namespace='/pty', + flask_test_client=flask_client) + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + import random + trans_id = random.randint(1, 9999999) + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + + self.test_client.emit('start_process', data, namespace='/pty') + self.test_client.get_received('/pty') + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/test_start_process_fail.py b/web/pgadmin/tools/psql/tests/test_start_process_fail.py new file mode 100644 index 00000000..0acc7be2 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/test_start_process_fail.py @@ -0,0 +1,48 @@ +import uuid +import config +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgAdmin4 import app +from .... import socketio + + +class PSQLStartProcessFail(BaseTestGenerator): + def setUp(self): + self.db_name = "psqltestdb_{0}".format(str(uuid.uuid4())[1:8]) + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + config.ENABLE_PSQL = True + + def runTest(self): + self.test_client = socketio.test_client(app, namespace='/pty') + self.assertTrue(self.test_client.is_connected('/pty')) + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'connected' + assert received[0]['args'][0]['sid'] != '' + + data = { + 'sid': self.sid, + 'db': 'postgres', + 'pwd': self.server['db_password'], + 'user': self.server['username'] + } + config.ENABLE_PSQL = False + self.test_client.emit('start_process', data, namespace='/pty') + received = self.test_client.get_received('/pty') + + assert received[0]['name'] == 'conn_not_allow' + + self.test_client.disconnect(namespace='/pty') + self.assertFalse(self.test_client.is_connected('/pty')) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/psql/tests/utils.py b/web/pgadmin/tools/psql/tests/utils.py new file mode 100644 index 00000000..85bd5373 --- /dev/null +++ b/web/pgadmin/tools/psql/tests/utils.py @@ -0,0 +1,6 @@ +import os +import json + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/psql_test_data.json") as data_file: + test_cases = json.load(data_file) diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss index 0bb40802..a58eb7e9 100644 --- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss +++ b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss @@ -374,3 +374,20 @@ div.strikeout:after { /* Setting it to hardcoded white as the SVG generated is having white bg * Need to check what can be done. */ + +/* Css for psql */ +.psql_terminal .terminal { + padding-top: 1%; + padding-left: 0.5%; + height: 100%; +} + +.psql-icon-style { + font-size: inherit; + padding-left: 0em; +} + +.psql-tab-style { + font-size: small; + padding-left: 0em; +} diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py index 23abfffa..71ae82ea 100644 --- a/web/pgadmin/utils/csrf.py +++ b/web/pgadmin/utils/csrf.py @@ -38,6 +38,7 @@ class _PGCSRFProtect(CSRFProtect): 'pgadmin.tools.schema_diff.ddl_compare', 'pgadmin.authenticate.login', 'pgadmin.tools.erd.panel', + 'pgadmin.tools.psql.panel', ] for exempt in exempt_views: diff --git a/web/pgadmin/utils/preferences.py b/web/pgadmin/utils/preferences.py index 15ceeb1a..e9efe479 100644 --- a/web/pgadmin/utils/preferences.py +++ b/web/pgadmin/utils/preferences.py @@ -72,6 +72,7 @@ class _Preference(object): self.select2 = kwargs.get('select2', None) self.fields = kwargs.get('fields', None) self.allow_blanks = kwargs.get('allow_blanks', None) + self.disabled = kwargs.get('disabled', False) # Look into the configuration table to find out the id of the specific # preference. @@ -252,6 +253,7 @@ class _Preference(object): 'select2': self.select2, 'value': self.get(), 'fields': self.fields, + 'disabled': self.disabled, } return res @@ -414,6 +416,7 @@ class Preferences(object): :param fields: field schema (if preference has more than one field to take input from user e.g. keyboardshortcut preference) :param allow_blanks: Flag specify whether to allow blank value. + :param disabled: Flag specify whether to disable the setting or not. """ min_val = kwargs.get('min_val', None) max_val = kwargs.get('max_val', None) @@ -423,6 +426,7 @@ class Preferences(object): select2 = kwargs.get('select2', None) fields = kwargs.get('fields', None) allow_blanks = kwargs.get('allow_blanks', None) + disabled = kwargs.get('disabled', False) cat = self.__category(category, category_label) if name in cat['preferences']: @@ -439,7 +443,8 @@ class Preferences(object): (cat['preferences'])[name] = res = _Preference( cat['id'], name, label, _type, default, help_str=help_str, min_val=min_val, max_val=max_val, options=options, - select2=select2, fields=fields, allow_blanks=allow_blanks + select2=select2, fields=fields, allow_blanks=allow_blanks, + disabled=disabled ) return res diff --git a/web/webpack.config.js b/web/webpack.config.js index 779f2faa..f631178b 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -355,6 +355,7 @@ module.exports = [{ debugger_direct: './pgadmin/tools/debugger/static/js/direct.js', schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js', erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js', + psql_tool: './pgadmin/tools/psql/static/js/index.js', file_utils: './pgadmin/misc/file_manager/static/js/utility.js', 'pgadmin.style': pgadminCssStyles, pgadmin: pgadminScssStyles, @@ -493,7 +494,7 @@ module.exports = [{ ], }, }, - }, { + },{ test: require.resolve('./node_modules/acitree/js/jquery.aciTree.min'), use: { loader: 'imports-loader', @@ -532,6 +533,7 @@ module.exports = [{ 'pure|pgadmin.tools.storage_manager', 'pure|pgadmin.tools.search_objects', 'pure|pgadmin.tools.erd_module', + 'pure|pgadmin.tools.psql_module', ], }, }, diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 074b2580..e0b28091 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -159,6 +159,15 @@ var webpackShimConfig = { 'jquery.acisortable': path.join(__dirname, './node_modules/acitree/js/jquery.aciSortable.min'), 'jquery.acifragment': path.join(__dirname, './node_modules/acitree/js/jquery.aciFragment.min'), + //xterm + 'xterm': path.join(__dirname, './node_modules/xterm/lib/xterm.js'), + 'xterm-addon-fit': path.join(__dirname, './node_modules/xterm-addon-fit/lib/xterm-addon-fit.js'), + 'xterm-addon-web-links': path.join(__dirname, './node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js'), + 'xterm-addon-search': path.join(__dirname, './node_modules/xterm-addon-search/lib/xterm-addon-search.js'), + + //socket + 'socketio': path.join(__dirname, './node_modules/socket.io-client/dist/socket.io.js'), + // Backbone and Backgrid 'backbone': path.join(__dirname, './node_modules/backbone/backbone'), 'backbone.undo': path.join(__dirname, './node_modules/backbone-undo/Backbone.Undo'), @@ -288,6 +297,8 @@ var webpackShimConfig = { 'pgadmin.tools.storage_manager': path.join(__dirname, './pgadmin/tools/storage_manager/static/js/storage_manager'), 'pgadmin.tools.erd_module': path.join(__dirname, './pgadmin/tools/erd/static/js/erd_module'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index e0b6fd69..3cc079f9 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -177,6 +177,7 @@ module.exports = { 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), + 'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), 'tools': path.join(__dirname, './pgadmin/tools/'), 'pgadmin.user_management.current_user': regressionDir + '/javascript/fake_current_user', ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-05-25 14:50 Akshay Joshi <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Akshay Joshi @ 2021-05-25 14:50 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Dave Page <[email protected]> Thanks, patch applied. I have updated the screenshot and some documentation stuff. On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < [email protected]> wrote: > Hi Akshay, > > > Please find the updated patch. (V6) > On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < > [email protected]> wrote: > >> Hi Nikhil >> >> Please rebase and send the patch again. >> >> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Akshay/ Team >>> >>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> Hi Nikhil >>>> >>>> Following are the review comments: >>>> >>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >>>> context menu option should not be visible. >>>> - Documentation screenshot should be in standard theme for >>>> consistency, and check the size it's very large. Take the screenshot with >>>> the new PSQL button on the browser tree. >>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>> - Remove commented code (if any) >>>> - Check SonarQube (I haven't run) >>>> >>>> Please find the updated patch, resolve all the review comments, and >>> update the code to resolve the SonarQube issues. >>> >>>> >>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> wrote: >>>> >>>>> Thanks Nikhil. Can someone else review this version please? >>>>> >>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave/ Team, >>>>>> >>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave/ Team, >>>>>>>> >>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Dave/Team, >>>>>>>>> >>>>>>>>> >>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>> >>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>> >>>>>>>>>> I also note there's a lot of Javascript in that HTML file. That >>>>>>>>>> should be pushed into the webpacked bundle I think, and not included inline >>>>>>>>>> in HTML. >>>>>>>>>> >>>>>>>>> I have moved most of the code in the js file, few things are still >>>>>>>>> in HTML. >>>>>>>>> >>>>>>>> >>>>>>>> Hmm, yes - in particular, colours for the different themes. Please >>>>>>>> move them into the css for the themes. You have a mix of style, layout and >>>>>>>> code in this file which needs to be cleaned up. >>>>>>>> xterm V3 onwards they have provided the API to set the theme and >>>>>>>> other settings, earlier I tried with CSS to override the theme but couldn’t >>>>>>>> able to apply the theme properly as some style get applied as in-line style >>>>>>>> for the HTML, so used the API to set the theme. >>>>>>>> >>>>>>> >>>>>>> OK, but either way we can't hard-code styles from themes in HTML >>>>>>> templates for individual features; that way leads to madness. >>>>>>> >>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>> assistance? >>>>>>> >>>>>> I have moved the color settings to the respective theme files. Aditya >>>>>> helped in this. >>>>>> >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>> >>>>>>>> I tried the default selection color from SQL for the dark and >>>>>> standard themes but still, it was not readable so just updated the color >>>>>> code with another color as follows. >>>>>> 1. Dark Theme: >>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>> 2. High Contrast: (using default SQL selection color) >>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>> 3. Standard: >>>>>> [image: image.png] >>>>>> can we go with the colors or should we update it? >>>>>> >>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>> >>>>>>>>>>> - The button is enabled if the treeview has a Server selected. >>>>>>>>>>> It could be argued that the query tool should do the same (defaulting to >>>>>>>>>>> the maintenance database), however, that would be a separate change, and >>>>>>>>>>> psql should be consistent with the query tool. >>>>>>>>>>> >>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>> >>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>> >>>>>>>>>> I am not able to reproduce the warning for the terminal (I am >>>>>>>>>> working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>> >>>>>>>>> >>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>> >>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>> >>>>>>>> Added this in the environment when opening the psql panel. >>>>>> >>>>>>> >>>>>>>>> to the subprocess.Popen() call. >>>>>>>>> >>>>>>>>> I noticed while I was playing with that, that you are passing the >>>>>>>>> password as part of the connection string. As I've mentioned in the past, >>>>>>>>> that is absolutely not acceptable; it will expose the password to all >>>>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>> >>>>>>>>> >>>>>>>>>> if we try to load data from the table containing millions of >>>>>>>>>> records, UI gets very slow. >>>>>>>>>> >>>>>>>>> Removed the password from the connection string and added >>>>>> 'PGPASSWORD' in the environment. >>>>>> >>>>>>> >>>>>>>>> Is xtermjs discarding the older buffer contents when it fills up? >>>>>>>>> Can you tell where the memory usage is? >>>>>>>>> >>>>>>>> I checked the psql memory consumption in terminal and pgAdmin psql >>>>>>>> tool memory consumption is the similar. Also tested the performance and >>>>>>>> query execution timing is also similar. >>>>>>>> >>>>>>> >>>>>>> OK, so there's probably not much we can do here. >>>>>>> >>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>>> - I'm sure using \q in the previous version displayed a message >>>>>>>>>>> saying the session exited (the one on line 138 of editor_template.html). It >>>>>>>>>>> no longer seems to do so. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> In addition to the issue above, it looks like the \! blocking may >>>>>>>>> have lost it's ability to ignore quoted strings: >>>>>>>>> >>>>>>>>> pgweb=# select '\!'; >>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>> >>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>> >>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>> >>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>> >>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>> >>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we can >>>>>>>>>>>>>> also add that on the browser tree toolbar. >>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the child >>>>>>>>>>>>>> nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>> - PSQL tab title should be only database server name as >>>>>>>>>>>>>> the user can change the database/user from PSQL command, so it's been >>>>>>>>>>>>>> difficult to update the tab title. >>>>>>>>>>>>>> - PSQL connection is still open even if we disconnect the >>>>>>>>>>>>>> database server from the browser tree. >>>>>>>>>>>>>> >>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>> >>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>> package.json >>>>>>>>>>>>>> - Documentation needs to be updated to let the user know >>>>>>>>>>>>>> from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>> - psql/__init__.py check there are so many unused imports >>>>>>>>>>>>>> please remove them. >>>>>>>>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>> - Test cases are showing successful but actually, there >>>>>>>>>>>>>> are some routing errors please check. >>>>>>>>>>>>>> >>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>> >>>>>>>>>>>>> - I was prompted to enter a password. This should be passed in >>>>>>>>>>>>> the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>> >>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>> relname | housing >>>>>>>>>>>>> ... >>>>>>>>>>>>> >>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in dark >>>>>>>>>>>>> mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>> - I spotted at least one print() statement that shouldn't be >>>>>>>>>>>>> there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>>>> >>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>> >>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, where >>>>>>>>>>>>> a horizontal scrollbar might be if there was one. >>>>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: >>>>>>>>>>>>> Shell commands are disabled in psql for security;" >>>>>>>>>>>>> >>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a string >>>>>>>>>>>>> review before committing. In particular, I want to be sure the text in >>>>>>>>>>>>> config.py is appropriately worded. >>>>>>>>>>>>> >>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu >>>>>>>>>>>>>>>>> option for starting PSQL. >>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database nodes >>>>>>>>>>>>>>>>> from the tree view. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json that >>>>>>>>>>>>>>>> makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error >>>>>>>>>>>>>>>> in 60041 ms >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>> >>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>>> Regards, >>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>>> Nikhil Mohite >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Regards, >>>>>>>> Nikhil Mohite >>>>>>>> >>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>> >>>>>>>>> -- >>>>>>>> *Thanks & Regards,* >>>>>>>> *Nikhil Mohite* >>>>>>>> *Software Engineer.* >>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> Regards, >>>>>> Nikhil Mohite >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> *pgAdmin Hacker | Principal Software Architect* >>>> *EDB Postgres <http://edbpostgres.com>* >>>> >>>> *Mobile: +91 976-788-8246* >>>> >>> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-01 11:58 Nikhil Mohite <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-01 11:58 UTC (permalink / raw) To: pgadmin-hackers; +Cc: Dave Page <[email protected]>; Akshay Joshi <[email protected]> Hi Team, Following are few points related to PSQL tool on windows: 1. Currently using the *pywinpty* library on windows to create pty process and execute the psql.exe. 2. To read the stderr (errors) currently using '2>>&1' arguments to psql.exe command. (It will redirect stderr to stdout ) 3. Windows conPTY is available on Windows 10 only (released after 2018). 4. Windows conPTY does not support the Asynchronous I/O, so to get the terminal output, need to add the read function after every command execution. (something like select() is not available) 5. Also found some performance issues with psql on windows. 1. To read the output from the terminal need to add some sleep time as it will take time to return the output. 2. Resize the terminal is also not consistent and causing the issue if we resize the window faster or multiple times very quickly. 3. Loading large dataset sometimes cause system to non-responsive state.(In this state restart requires) Please find the patch for disable the psql tool for windows platform.(Windows builds are falling due to this sending patch for disable psql on windows.) Reference links: 1. https://github.com/microsoft/terminal/issues/262 2. https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... 3. https://pypi.org/project/pywinpty/ If any suggestions or questions please let me know. Regards, Nikhil Mohite. On Tue, May 25, 2021 at 8:20 PM Akshay Joshi <[email protected]> wrote: > Thanks, patch applied. > > I have updated the screenshot and some documentation stuff. > > On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Akshay, >> >> >> Please find the updated patch. (V6) >> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >> [email protected]> wrote: >> >>> Hi Nikhil >>> >>> Please rebase and send the patch again. >>> >>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Akshay/ Team >>>> >>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> Hi Nikhil >>>>> >>>>> Following are the review comments: >>>>> >>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >>>>> context menu option should not be visible. >>>>> - Documentation screenshot should be in standard theme for >>>>> consistency, and check the size it's very large. Take the screenshot with >>>>> the new PSQL button on the browser tree. >>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>> - Remove commented code (if any) >>>>> - Check SonarQube (I haven't run) >>>>> >>>>> Please find the updated patch, resolve all the review comments, and >>>> update the code to resolve the SonarQube issues. >>>> >>>>> >>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>> >>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave/ Team, >>>>>>> >>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Dave/ Team, >>>>>>>>> >>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave/Team, >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>> >>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>> >>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. That >>>>>>>>>>> should be pushed into the webpacked bundle I think, and not included inline >>>>>>>>>>> in HTML. >>>>>>>>>>> >>>>>>>>>> I have moved most of the code in the js file, few things are >>>>>>>>>> still in HTML. >>>>>>>>>> >>>>>>>>> >>>>>>>>> Hmm, yes - in particular, colours for the different themes. Please >>>>>>>>> move them into the css for the themes. You have a mix of style, layout and >>>>>>>>> code in this file which needs to be cleaned up. >>>>>>>>> xterm V3 onwards they have provided the API to set the theme and >>>>>>>>> other settings, earlier I tried with CSS to override the theme but couldn’t >>>>>>>>> able to apply the theme properly as some style get applied as in-line style >>>>>>>>> for the HTML, so used the API to set the theme. >>>>>>>>> >>>>>>>> >>>>>>>> OK, but either way we can't hard-code styles from themes in HTML >>>>>>>> templates for individual features; that way leads to madness. >>>>>>>> >>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>> assistance? >>>>>>>> >>>>>>> I have moved the color settings to the respective theme files. >>>>>>> Aditya helped in this. >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>> >>>>>>>>> I tried the default selection color from SQL for the dark and >>>>>>> standard themes but still, it was not readable so just updated the color >>>>>>> code with another color as follows. >>>>>>> 1. Dark Theme: >>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>> 3. Standard: >>>>>>> [image: image.png] >>>>>>> can we go with the colors or should we update it? >>>>>>> >>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>> >>>>>>>>>>>> - The button is enabled if the treeview has a Server selected. >>>>>>>>>>>> It could be argued that the query tool should do the same (defaulting to >>>>>>>>>>>> the maintenance database), however, that would be a separate change, and >>>>>>>>>>>> psql should be consistent with the query tool. >>>>>>>>>>>> >>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>> >>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>> >>>>>>>>>>> I am not able to reproduce the warning for the terminal (I am >>>>>>>>>>> working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>> >>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>> >>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>> >>>>>>>> >>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>> >>>>>>>>>> I noticed while I was playing with that, that you are passing the >>>>>>>>>> password as part of the connection string. As I've mentioned in the past, >>>>>>>>>> that is absolutely not acceptable; it will expose the password to all >>>>>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> if we try to load data from the table containing millions of >>>>>>>>>>> records, UI gets very slow. >>>>>>>>>>> >>>>>>>>>> Removed the password from the connection string and added >>>>>>> 'PGPASSWORD' in the environment. >>>>>>> >>>>>>>> >>>>>>>>>> Is xtermjs discarding the older buffer contents when it fills up? >>>>>>>>>> Can you tell where the memory usage is? >>>>>>>>>> >>>>>>>>> I checked the psql memory consumption in terminal and pgAdmin psql >>>>>>>>> tool memory consumption is the similar. Also tested the performance and >>>>>>>>> query execution timing is also similar. >>>>>>>>> >>>>>>>> >>>>>>>> OK, so there's probably not much we can do here. >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> - I'm sure using \q in the previous version displayed a message >>>>>>>>>>>> saying the session exited (the one on line 138 of editor_template.html). It >>>>>>>>>>>> no longer seems to do so. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> In addition to the issue above, it looks like the \! blocking may >>>>>>>>>> have lost it's ability to ignore quoted strings: >>>>>>>>>> >>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>> >>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>> >>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we can >>>>>>>>>>>>>>> also add that on the browser tree toolbar. >>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the child >>>>>>>>>>>>>>> nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>> - PSQL tab title should be only database server name as >>>>>>>>>>>>>>> the user can change the database/user from PSQL command, so it's been >>>>>>>>>>>>>>> difficult to update the tab title. >>>>>>>>>>>>>>> - PSQL connection is still open even if we disconnect >>>>>>>>>>>>>>> the database server from the browser tree. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>> - Documentation needs to be updated to let the user know >>>>>>>>>>>>>>> from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>>>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>> - Test cases are showing successful but actually, there >>>>>>>>>>>>>>> are some routing errors please check. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>> >>>>>>>>>>>>>> - I was prompted to enter a password. This should be passed >>>>>>>>>>>>>> in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>>> >>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>> ... >>>>>>>>>>>>>> >>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in dark >>>>>>>>>>>>>> mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>>> - I spotted at least one print() statement that shouldn't be >>>>>>>>>>>>>> there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>>>>> >>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>> >>>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, >>>>>>>>>>>>>> where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: >>>>>>>>>>>>>> Shell commands are disabled in psql for security;" >>>>>>>>>>>>>> >>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a string >>>>>>>>>>>>>> review before committing. In particular, I want to be sure the text in >>>>>>>>>>>>>> config.py is appropriately worded. >>>>>>>>>>>>>> >>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu >>>>>>>>>>>>>>>>>> option for starting PSQL. >>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database nodes >>>>>>>>>>>>>>>>>> from the tree view. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json >>>>>>>>>>>>>>>>> that makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error >>>>>>>>>>>>>>>>> in 60041 ms >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Regards, >>>>>>>>>>> Nikhil Mohite >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> Nikhil Mohite >>>>>>>>> >>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>> *Thanks & Regards,* >>>>>>>>> *Nikhil Mohite* >>>>>>>>> *Software Engineer.* >>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> Regards, >>>>>>> Nikhil Mohite >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> *pgAdmin Hacker | Principal Software Architect* >>>>> *EDB Postgres <http://edbpostgres.com>* >>>>> >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> *pgAdmin Hacker | Principal Software Architect* >>> *EDB Postgres <http://edbpostgres.com>* >>> >>> *Mobile: +91 976-788-8246* >>> >> > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [application/octet-stream] disable_psql_for_windows.patch (27.0K, 6-disable_psql_for_windows.patch) download | inline diff: diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index 300625c5..edbd491e 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -851,7 +851,8 @@ def utils(): app_version_int=config.APP_VERSION_INT, pg_libpq_version=pg_libpq_version, support_ssh_tunnel=config.SUPPORT_SSH_TUNNEL, - logout_url=_get_logout_url() + logout_url=_get_logout_url(), + platform=sys.platform ), 200, {'Content-Type': MIMETYPE_APP_JS}) diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index d835ca82..0e464c06 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -6,6 +6,7 @@ # This software is released under the PostgreSQL Licence # ########################################################################## +import sys from flask_babelex import gettext from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\ PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \ @@ -505,37 +506,61 @@ def register_browser_preferences(self): ) ) - self.open_in_new_tab = self.preference.register( - 'tab_settings', 'new_browser_tab_open', - gettext("Open in new browser tab"), 'select2', None, - category_label=PREF_LABEL_OPTIONS, - options=[{'label': gettext('Query Tool'), 'value': 'qt'}, - {'label': gettext('Debugger'), 'value': 'debugger'}, - {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, - {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], - help_str=gettext('Select Query Tool, Debugger, Schema Diff, ERD Tool ' - 'or PSQL Tool from the drop-down to set ' - 'open in new browser tab for that particular module.' - ), - select2={ - 'multiple': True, 'allowClear': False, - 'tags': True, 'first_empty': False, - 'selectOnClose': False, 'emptyOptions': True, - 'tokenSeparators': [','], - 'placeholder': gettext('Select open new tab...') - } - ) - - self.psql_tab_title = self.preference.register( - 'tab_settings', 'psql_tab_title_placeholder', - gettext("PSQL tool tab title"), - 'text', '%DATABASE%/%USERNAME%@%SERVER%', - category_label=PREF_LABEL_DISPLAY, - help_str=gettext( - 'Supported placeholders are %DATABASE%, %USERNAME%, and %SERVER%. ' - 'Users can provide any string with or without placeholders of' - ' their choice. The blank title will be revert back to the' - ' default title with placeholders.' + if sys.platform != 'win32': + self.open_in_new_tab = self.preference.register( + 'tab_settings', 'new_browser_tab_open', + gettext("Open in new browser tab"), 'select2', None, + category_label=PREF_LABEL_OPTIONS, + options=[{'label': gettext('Query Tool'), 'value': 'qt'}, + {'label': gettext('Debugger'), 'value': 'debugger'}, + {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext( + 'Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), + select2={ + 'multiple': True, 'allowClear': False, + 'tags': True, 'first_empty': False, + 'selectOnClose': False, 'emptyOptions': True, + 'tokenSeparators': [','], + 'placeholder': gettext('Select open new tab...') + } + ) + + self.psql_tab_title = self.preference.register( + 'tab_settings', 'psql_tab_title_placeholder', + gettext("PSQL tool tab title"), + 'text', '%DATABASE%/%USERNAME%@%SERVER%', + category_label=PREF_LABEL_DISPLAY, + help_str=gettext( + 'Supported placeholders are %DATABASE%, %USERNAME%, ' + 'and %SERVER%. Users can provide any string with or without' + ' placeholders of their choice. The blank title will be revert' + ' back to the default title with placeholders.' + ) + ) + else: + self.open_in_new_tab = self.preference.register( + 'tab_settings', 'new_browser_tab_open', + gettext("Open in new browser tab"), 'select2', None, + category_label=PREF_LABEL_OPTIONS, + options=[{'label': gettext('Query Tool'), 'value': 'qt'}, + {'label': gettext('Debugger'), 'value': 'debugger'}, + {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], + help_str=gettext( + 'Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), + select2={ + 'multiple': True, 'allowClear': False, + 'tags': True, 'first_empty': False, + 'selectOnClose': False, 'emptyOptions': True, + 'tokenSeparators': [','], + 'placeholder': gettext('Select open new tab...') + } ) - ) diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index e763aa11..64442189 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -66,12 +66,14 @@ define([ }]); // show psql tool same as query tool. - pgAdmin.Browser.add_menus([{ - name: 'show_psql_tool', node: this.type, module: this, - applies: ['context'], callback: 'show_psql_tool', - priority: 998, label: gettext('PSQL Tool (Beta)'), - icon: 'fas fa-terminal', - }]); + if(pgAdmin['enable_psql'] && pgAdmin['platform'] != 'win32') { + pgAdmin.Browser.add_menus([{ + name: 'show_psql_tool', node: this.type, module: this, + applies: ['context'], callback: 'show_psql_tool', + priority: 998, label: gettext('PSQL Tool (Beta)'), + icon: 'fas fa-terminal', + }]); + } } } }, diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index f7c04d0d..c2e73931 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -210,7 +210,7 @@ define('pgadmin.browser.node', [ icon: 'fa fa-search', enable: enable, }]); - if(pgAdmin['enable_psql']) { + if(pgAdmin['enable_psql'] && pgAdmin['platform'] != 'win32') { // show psql tool same as query tool. pgAdmin.Browser.add_menus([{ name: 'show_psql_tool', node: this.type, module: this, diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index bc9c13a3..4aaa41ce 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -59,7 +59,7 @@ let _defaultToolBarButtons = [ } ]; -if(pgAdmin['enable_psql']) { +if(pgAdmin['enable_psql'] && pgAdmin['platform'] != 'win32') { _defaultToolBarButtons.unshift({ label: gettext('PSQL Tool'), ariaLabel: gettext('PSQL Tool'), @@ -119,7 +119,7 @@ export function initializeToolbar(panel, wcDocker) { pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected()); else if ('name' in data && data.name === gettext('Search objects')) pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); - else if ('name' in data && data.name === gettext('PSQL Tool')){ + else if ('name' in data && data.name === gettext('PSQL Tool') && pgAdmin['platform'] != 'win32'){ var input = {}, t = pgAdmin.Browser.tree, i = input.item || t.selected(), diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 0634aa70..ec20cbe8 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -54,6 +54,8 @@ define('pgadmin.browser.utils', /* GET PSQL Tool related config */ pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; + pgAdmin['platform'] = '{{platform}}'; // Define list of nodes on which Query tool option doesn't appears var unsupported_nodes = pgAdmin.unsupported_nodes = [ diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py index e871b487..7f5adae9 100644 --- a/web/pgadmin/tools/psql/__init__.py +++ b/web/pgadmin/tools/psql/__init__.py @@ -1,35 +1,35 @@ #!/usr/bin/env python3 -import fcntl + import os -import pty import re import select import struct -import termios import config +from sys import platform as _platform import eventlet.green.subprocess as subprocess - from config import PG_DEFAULT_DRIVER from flask import Response, url_for, request from flask import render_template, copy_current_request_context, \ current_app as app from flask_babelex import gettext from flask_security import login_required, current_user -from pgadmin.browser.utils import underscore_unescape +from pgadmin.browser.utils import underscore_unescape, underscore_escape from pgadmin.utils import PgAdminModule from pgadmin.utils.constants import MIMETYPE_APP_JS from pgadmin.utils.driver import get_driver from ... import socketio as sio from pgadmin.utils import get_complete_file_path -from pgadmin.utils.ajax import internal_server_error +if _platform != 'win32': + import fcntl + import termios + import pty session_input = dict() session_input_cursor = dict() session_last_cmd = dict() pdata = dict() cdata = dict() -_NODES_SQL = 'nodes.sql' class PSQLModule(PgAdminModule): @@ -225,27 +225,35 @@ def start_process(data): """ @copy_current_request_context def read_and_forward_pty_output(sid, data): - max_read_bytes = 1024 * 20 - - p, parent, fd = create_pty_terminal(connection_data) - while p and p.poll() is None: - if request.sid in app.config['sessions']: - # This code is added to make this unit testable. - if "is_test" not in data: - sio.sleep(0.01) - else: - data['count'] += 1 - if data['count'] == 5: - break - - timeout = 0 - # module provides access to platform-specific I/O - # monitoring functions - (data_ready, _, _) = select.select([parent, fd], [], [], - timeout) + max_read_bytes = 1024 * 20 - read_terminal_data(parent, data_ready, max_read_bytes, sid) + if _platform != 'win32': + p, parent, fd = create_pty_terminal(connection_data) + + while p and p.poll() is None: + if request.sid in app.config['sessions']: + # This code is added to make this unit testable. + if "is_test" not in data: + sio.sleep(0.01) + else: + data['count'] += 1 + if data['count'] == 5: + break + + timeout = 0 + # module provides access to platform-specific I/O + # monitoring functions + (data_ready, _, _) = select.select([parent, fd], [], [], + timeout) + + read_terminal_data(parent, data_ready, max_read_bytes, sid) + else: + sio.emit( + 'conn_error', + { + 'error': 'PSQL tool not supported.', + }, namespace='/pty', room=request.sid) # Check user is authenticated and PSQL is enabled in config. if current_user.is_authenticated and config.ENABLE_PSQL: @@ -255,6 +263,8 @@ def start_process(data): if data['db']: db = underscore_unescape(data['db']).replace('\\', "\\\\") + data['db'] = db + conn, manager = _get_connection(int(data['sid']), data) psql_utility = manager.utility('sql') connection_data = get_connection_str(psql_utility, db, @@ -348,15 +358,15 @@ def get_conn_str(manager, db): """ manager.export_password_env('PGPASSWORD') conn_attr =\ - "host={0} port={1} dbname={2} user={3} sslmode={4} " \ - "sslcompression={5} " \ - "".format( + 'host={0} port={1} dbname={2} user={3} sslmode={4} ' \ + 'sslcompression={5} ' \ + ''.format( manager.local_bind_host if manager.use_ssh_tunnel else manager.host, manager.local_bind_port if manager.use_ssh_tunnel else manager.port, - db if db != '' else 'postgres', - manager.user if manager.user else 'postgres', + underscore_unescape(db) if db != '' else 'postgres', + underscore_unescape(manager.user) if manager.user else 'postgres', manager.ssl_mode, True if manager.sslcompression else False, ) @@ -423,7 +433,6 @@ def invalid_cmd(): :rtype: """ session_last_cmd[request.sid]['invalid_cmd'] = True - for i in range(len(session_input[request.sid])): os.write(app.config['sessions'][request.sid], '\b \b'.encode()) @@ -455,6 +464,7 @@ def check_valid_cmd(user_input): if stop_execution: session_last_cmd[request.sid]['invalid_cmd'] = True + # Remove already added command from terminal. for i in range(len(user_input)): os.write(app.config['sessions'][request.sid], @@ -482,6 +492,7 @@ def enter_key_press(data): # contains \! in input. is_new_connection = session_last_cmd[request.sid][ 'is_new_connection'] + if user_input.startswith('\\!') and re.match("^\\\!$", user_input) and len( user_input) == 2 and not config.ALLOW_PSQL_SHELL_COMMANDS \ and not is_new_connection: @@ -490,7 +501,8 @@ def enter_key_press(data): not config.ALLOW_PSQL_SHELL_COMMANDS and\ not session_last_cmd[request.sid]['is_new_connection']: check_valid_cmd(user_input) - elif user_input == '\q' or user_input == 'q\\q': + elif user_input == '\q' or user_input == 'q\\q' or \ + user_input in ['exit', 'exit;']: # If user enter \q to terminate the PSQL, emit the msg to # notify user connection is terminated. sio.emit('pty-output', @@ -501,6 +513,7 @@ def enter_key_press(data): ' tool.'), 'error': True}, namespace='/pty', room=request.sid) + os.write(app.config['sessions'][request.sid], '\n'.encode()) diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js index f0132507..5a6fffc0 100644 --- a/web/pgadmin/tools/psql/static/js/psql_module.js +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -54,7 +54,7 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) }]; this.enable_psql_tool = pgAdmin['enable_psql']; - if(pgAdmin['enable_psql']) { + if(pgAdmin['enable_psql'] && pgAdmin['platform'] != 'win32') { pgBrowser.add_menus(menus); } diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html index 74d9b888..0568ad71 100644 --- a/web/pgadmin/tools/psql/templates/editor_template.html +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -23,36 +23,40 @@ require( ['sources/generated/psql_tool'], function(pgBrowser) { - const term = self.pgAdmin.Browser.psql.psql_terminal(); - <!--Addon for fitAddon, webLinkAddon, SearchAddon --> - const fitAddon = self.pgAdmin.Browser.psql.psql_Addon(term); - <!-- Update the theme for terminal as per pgAdmin 4 theme.--> - self.pgAdmin.Browser.psql.set_theme(term); - <!-- Open the terminal --> - term.open(document.getElementById('psql-terminal')); - <!-- Socket--> - const socket = self.pgAdmin.Browser.psql.psql_socket(); - self.pgAdmin.Browser.psql.psql_socket_io(socket, '{{is_enable}}', '{{sid}}', '{{db}}', '{{server_type}}', fitAddon, term); - self.pgAdmin.Browser.psql.psql_terminal_io(term, socket); - self.pgAdmin.Browser.psql.check_db_name_change('{{db}}', '{{o_db_name}}'); - - <!-- Resize the terminal --> - function fitToscreen(){ - fitAddon.fit() - socket.emit("resize", {"cols": term.cols, "rows": term.rows}) - } + if (self.pgAdmin['platform'] != 'win32') { + const term = self.pgAdmin.Browser.psql.psql_terminal(); + <!--Addon for fitAddon, webLinkAddon, SearchAddon --> + const fitAddon = self.pgAdmin.Browser.psql.psql_Addon(term); + <!-- Update the theme for terminal as per pgAdmin 4 theme.--> + self.pgAdmin.Browser.psql.set_theme(term); + <!-- Open the terminal --> + term.open(document.getElementById('psql-terminal')); + <!-- Socket--> + const socket = self.pgAdmin.Browser.psql.psql_socket(); + self.pgAdmin.Browser.psql.psql_socket_io(socket, '{{is_enable}}', '{{sid}}', '{{db}}', '{{server_type}}', fitAddon, term); + self.pgAdmin.Browser.psql.psql_terminal_io(term, socket); + self.pgAdmin.Browser.psql.check_db_name_change('{{db}}', '{{o_db_name}}'); + + <!-- Resize the terminal --> + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } - function debounce(func, wait_ms) { - let timeout - return function(...args) { - const context = this - clearTimeout(timeout) - timeout = setTimeout(() => func.apply(context, args), wait_ms) + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) + } } - } - const wait_ms = 50;; - window.onresize = debounce(fitToscreen, wait_ms) + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) + } else { + document.getElementById('psql-terminal').innterHTML = 'PSQL not supported' + } }); {% endblock %} diff --git a/web/pgadmin/tools/psql/tests/test_backend_task.py b/web/pgadmin/tools/psql/tests/test_backend_task.py index a4f14ee4..504db305 100644 --- a/web/pgadmin/tools/psql/tests/test_backend_task.py +++ b/web/pgadmin/tools/psql/tests/test_backend_task.py @@ -1,5 +1,6 @@ import uuid import config +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -24,6 +25,8 @@ class PSQLBackend(BaseTestGenerator): self.server_con = server_utils.connect_server(self, self.sid) def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') # Fetch flask client to access current user and other cookies. flask_client = app.test_client() flask_client.get('/') diff --git a/web/pgadmin/tools/psql/tests/test_panel.py b/web/pgadmin/tools/psql/tests/test_panel.py index c53785cc..ca94f309 100644 --- a/web/pgadmin/tools/psql/tests/test_panel.py +++ b/web/pgadmin/tools/psql/tests/test_panel.py @@ -1,5 +1,6 @@ import uuid import random +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -16,6 +17,8 @@ class PSQLPanel(BaseTestGenerator): self.theme = 'standard' def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') trans_id = random.randint(1, 9999999) url = '/psql/panel/{trans_id}?sgid={sgid}&sid={sid}&did={did}' \ '&server_type=pg&db={db_name}&theme={theme}'.\ diff --git a/web/pgadmin/tools/psql/tests/test_psql_disabled.py b/web/pgadmin/tools/psql/tests/test_psql_disabled.py index 7dc52498..fdae5d66 100644 --- a/web/pgadmin/tools/psql/tests/test_psql_disabled.py +++ b/web/pgadmin/tools/psql/tests/test_psql_disabled.py @@ -1,5 +1,6 @@ import uuid import config +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -17,6 +18,8 @@ class PSQLSocketDisabled(BaseTestGenerator): config.ENABLE_PSQL = False def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') self.test_client = socketio.test_client(app, namespace='/pty') self.assertTrue(self.test_client.is_connected('/pty')) received = self.test_client.get_received('/pty') diff --git a/web/pgadmin/tools/psql/tests/test_psql_input.py b/web/pgadmin/tools/psql/tests/test_psql_input.py index 6f6eabe7..b5a8d656 100644 --- a/web/pgadmin/tools/psql/tests/test_psql_input.py +++ b/web/pgadmin/tools/psql/tests/test_psql_input.py @@ -1,5 +1,6 @@ import uuid import config +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -24,6 +25,8 @@ class PSQLInput(BaseTestGenerator): self.server_con = server_utils.connect_server(self, self.sid) def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') # Fetch flask client to access current user and other cookies. flask_client = app.test_client() flask_client.get('/') diff --git a/web/pgadmin/tools/psql/tests/test_resize_terminal.py b/web/pgadmin/tools/psql/tests/test_resize_terminal.py index d305c2d0..ff981963 100644 --- a/web/pgadmin/tools/psql/tests/test_resize_terminal.py +++ b/web/pgadmin/tools/psql/tests/test_resize_terminal.py @@ -1,5 +1,6 @@ import uuid import config +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -24,6 +25,8 @@ class PSQLResizeTerminal(BaseTestGenerator): self.server_con = server_utils.connect_server(self, self.sid) def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') # Fetch flask client to access current user and other cookies. flask_client = app.test_client() flask_client.get('/') diff --git a/web/pgadmin/tools/psql/tests/test_socket_connect.py b/web/pgadmin/tools/psql/tests/test_socket_connect.py index 3791525a..8a0d8d61 100644 --- a/web/pgadmin/tools/psql/tests/test_socket_connect.py +++ b/web/pgadmin/tools/psql/tests/test_socket_connect.py @@ -1,5 +1,6 @@ import uuid import config +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -17,6 +18,8 @@ class PSQLSocketConnect(BaseTestGenerator): config.ENABLE_PSQL = True def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') self.test_client = socketio.test_client(app, namespace='/pty') self.assertTrue(self.test_client.is_connected('/pty')) received = self.test_client.get_received('/pty') diff --git a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py index 0619eb30..086b85f9 100644 --- a/web/pgadmin/tools/psql/tests/test_socket_disconnect.py +++ b/web/pgadmin/tools/psql/tests/test_socket_disconnect.py @@ -1,5 +1,6 @@ import uuid import config +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -17,6 +18,8 @@ class PSQLSocketDisconnect(BaseTestGenerator): config.ENABLE_PSQL = True def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') # Fetch flask client to access current user and other cookies. flask_test_client = app.test_client() flask_test_client.get('/') diff --git a/web/pgadmin/tools/psql/tests/test_start_process.py b/web/pgadmin/tools/psql/tests/test_start_process.py index 1245de3f..4bc316df 100644 --- a/web/pgadmin/tools/psql/tests/test_start_process.py +++ b/web/pgadmin/tools/psql/tests/test_start_process.py @@ -1,5 +1,6 @@ import uuid import config +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -21,6 +22,8 @@ class PSQLStartProcess(BaseTestGenerator): self.server_con = server_utils.connect_server(self, self.sid) def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') # Fetch flask client to access current user and other cookies. flask_client = app.test_client() flask_client.get('/') diff --git a/web/pgadmin/tools/psql/tests/test_start_process_fail.py b/web/pgadmin/tools/psql/tests/test_start_process_fail.py index 0acc7be2..6abfc511 100644 --- a/web/pgadmin/tools/psql/tests/test_start_process_fail.py +++ b/web/pgadmin/tools/psql/tests/test_start_process_fail.py @@ -1,5 +1,6 @@ import uuid import config +import sys from pgadmin.utils.route import BaseTestGenerator from regression.python_test_utils import test_utils as utils from regression import parent_node_dict @@ -17,6 +18,8 @@ class PSQLStartProcessFail(BaseTestGenerator): config.ENABLE_PSQL = True def runTest(self): + if sys.platform == 'win32': + self.skipTest('PSQL disabled for windows') self.test_client = socketio.test_client(app, namespace='/pty') self.assertTrue(self.test_client.is_connected('/pty')) received = self.test_client.get_received('/pty') ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-03 08:36 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-03 08:36 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> Hi On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < [email protected]> wrote: > Hi Team, > > Following are few points related to PSQL tool on windows: > > 1. Currently using the *pywinpty* library on windows to create pty > process and execute the psql.exe. > 2. To read the stderr (errors) currently using '2>>&1' arguments to > psql.exe command. (It will redirect stderr to stdout ) > 3. Windows conPTY is available on Windows 10 only (released after > 2018). > 4. Windows conPTY does not support the Asynchronous I/O, so to get the > terminal output, need to add the read function after every command > execution. (something like select() is not available) > 5. Also found some performance issues with psql on windows. > 1. To read the output from the terminal need to add some sleep time > as it will take time to return the output. > 2. Resize the terminal is also not consistent and causing the issue > if we resize the window faster or multiple times very quickly. > 3. Loading large dataset sometimes cause system to non-responsive > state.(In this state restart requires) > > Please find the patch for disable the psql tool for windows > platform.(Windows builds are falling due to this sending patch for disable > psql on windows.) > Disabling major features on our most common deployment platform really isn't a good option. I assume all of the above options are related to lack of async I/O? Have you tried forcing the use of winpty rather than conpty? > > Reference links: > > 1. https://github.com/microsoft/terminal/issues/262 > 2. > https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... > 3. https://pypi.org/project/pywinpty/ > > > If any suggestions or questions please let me know. > > Regards, > Nikhil Mohite. > > On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < > [email protected]> wrote: > >> Thanks, patch applied. >> >> I have updated the screenshot and some documentation stuff. >> >> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Akshay, >>> >>> >>> Please find the updated patch. (V6) >>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> Hi Nikhil >>>> >>>> Please rebase and send the patch again. >>>> >>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Akshay/ Team >>>>> >>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Nikhil >>>>>> >>>>>> Following are the review comments: >>>>>> >>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >>>>>> context menu option should not be visible. >>>>>> - Documentation screenshot should be in standard theme for >>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>> the new PSQL button on the browser tree. >>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>> - Remove commented code (if any) >>>>>> - Check SonarQube (I haven't run) >>>>>> >>>>>> Please find the updated patch, resolve all the review comments, and >>>>> update the code to resolve the SonarQube issues. >>>>> >>>>>> >>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>> >>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave/ Team, >>>>>>>> >>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave/ Team, >>>>>>>>>> >>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>> >>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>> >>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. That >>>>>>>>>>>> should be pushed into the webpacked bundle I think, and not included inline >>>>>>>>>>>> in HTML. >>>>>>>>>>>> >>>>>>>>>>> I have moved most of the code in the js file, few things are >>>>>>>>>>> still in HTML. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>> xterm V3 onwards they have provided the API to set the theme and >>>>>>>>>> other settings, earlier I tried with CSS to override the theme but couldn’t >>>>>>>>>> able to apply the theme properly as some style get applied as in-line style >>>>>>>>>> for the HTML, so used the API to set the theme. >>>>>>>>>> >>>>>>>>> >>>>>>>>> OK, but either way we can't hard-code styles from themes in HTML >>>>>>>>> templates for individual features; that way leads to madness. >>>>>>>>> >>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>> assistance? >>>>>>>>> >>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>> Aditya helped in this. >>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>> >>>>>>>>>> I tried the default selection color from SQL for the dark and >>>>>>>> standard themes but still, it was not readable so just updated the color >>>>>>>> code with another color as follows. >>>>>>>> 1. Dark Theme: >>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>> 3. Standard: >>>>>>>> [image: image.png] >>>>>>>> can we go with the colors or should we update it? >>>>>>>> >>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>> >>>>>>>>>>>>> - The button is enabled if the treeview has a Server selected. >>>>>>>>>>>>> It could be argued that the query tool should do the same (defaulting to >>>>>>>>>>>>> the maintenance database), however, that would be a separate change, and >>>>>>>>>>>>> psql should be consistent with the query tool. >>>>>>>>>>>>> >>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>> >>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>> >>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I am >>>>>>>>>>>> working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>> >>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>> >>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>> >>>>>>>>> >>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>> >>>>>>>>>>> I noticed while I was playing with that, that you are passing >>>>>>>>>>> the password as part of the connection string. As I've mentioned in the >>>>>>>>>>> past, that is absolutely not acceptable; it will expose the password to all >>>>>>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> if we try to load data from the table containing millions of >>>>>>>>>>>> records, UI gets very slow. >>>>>>>>>>>> >>>>>>>>>>> Removed the password from the connection string and added >>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>> >>>>>>>>> >>>>>>>>>>> Is xtermjs discarding the older buffer contents when it fills >>>>>>>>>>> up? Can you tell where the memory usage is? >>>>>>>>>>> >>>>>>>>>> I checked the psql memory consumption in terminal and pgAdmin >>>>>>>>>> psql tool memory consumption is the similar. Also tested the performance >>>>>>>>>> and query execution timing is also similar. >>>>>>>>>> >>>>>>>>> >>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> In addition to the issue above, it looks like the \! blocking >>>>>>>>>>> may have lost it's ability to ignore quoted strings: >>>>>>>>>>> >>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>> >>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>> >>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we can >>>>>>>>>>>>>>>> also add that on the browser tree toolbar. >>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the child >>>>>>>>>>>>>>>> nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>> - PSQL tab title should be only database server name as >>>>>>>>>>>>>>>> the user can change the database/user from PSQL command, so it's been >>>>>>>>>>>>>>>> difficult to update the tab title. >>>>>>>>>>>>>>>> - PSQL connection is still open even if we disconnect >>>>>>>>>>>>>>>> the database server from the browser tree. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>> - Documentation needs to be updated to let the user >>>>>>>>>>>>>>>> know from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed from >>>>>>>>>>>>>>>> requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>> - Test cases are showing successful but actually, there >>>>>>>>>>>>>>>> are some routing errors please check. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> - I was prompted to enter a password. This should be passed >>>>>>>>>>>>>>> in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in >>>>>>>>>>>>>>> dark mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>>>> - I spotted at least one print() statement that shouldn't be >>>>>>>>>>>>>>> there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, >>>>>>>>>>>>>>> where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: >>>>>>>>>>>>>>> Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a string >>>>>>>>>>>>>>> review before committing. In particular, I want to be sure the text in >>>>>>>>>>>>>>> config.py is appropriately worded. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu >>>>>>>>>>>>>>>>>>> option for starting PSQL. >>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database nodes >>>>>>>>>>>>>>>>>>> from the tree view. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json >>>>>>>>>>>>>>>>>> that makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 error >>>>>>>>>>>>>>>>>> in 60041 ms >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>>> Nikhil Mohite >>>>>>>>>> >>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>> *Thanks & Regards,* >>>>>>>>>> *Nikhil Mohite* >>>>>>>>>> *Software Engineer.* >>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> Regards, >>>>>>>> Nikhil Mohite >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> *Thanks & Regards* >>>>>> *Akshay Joshi* >>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>> >>>>>> *Mobile: +91 976-788-8246* >>>>>> >>>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> *pgAdmin Hacker | Principal Software Architect* >>>> *EDB Postgres <http://edbpostgres.com>* >>>> >>>> *Mobile: +91 976-788-8246* >>>> >>> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-03 08:39 Akshay Joshi <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Akshay Joshi @ 2021-06-03 08:39 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: > Hi > > On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Team, >> >> Following are few points related to PSQL tool on windows: >> >> 1. Currently using the *pywinpty* library on windows to create pty >> process and execute the psql.exe. >> 2. To read the stderr (errors) currently using '2>>&1' arguments to >> psql.exe command. (It will redirect stderr to stdout ) >> 3. Windows conPTY is available on Windows 10 only (released after >> 2018). >> 4. Windows conPTY does not support the Asynchronous I/O, so to get >> the terminal output, need to add the read function after every command >> execution. (something like select() is not available) >> 5. Also found some performance issues with psql on windows. >> 1. To read the output from the terminal need to add some sleep >> time as it will take time to return the output. >> 2. Resize the terminal is also not consistent and causing the >> issue if we resize the window faster or multiple times very quickly. >> 3. Loading large dataset sometimes cause system to non-responsive >> state.(In this state restart requires) >> >> Please find the patch for disable the psql tool for windows >> platform.(Windows builds are falling due to this sending patch for disable >> psql on windows.) >> > > Disabling major features on our most common deployment platform really > isn't a good option. I assume all of the above options are related to lack > of async I/O? > We have temporarily disabled the feature until found a solution, to generate the nightly build for testing. > > Have you tried forcing the use of winpty rather than conpty? > > >> >> Reference links: >> >> 1. https://github.com/microsoft/terminal/issues/262 >> 2. >> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >> 3. https://pypi.org/project/pywinpty/ >> >> >> If any suggestions or questions please let me know. >> >> Regards, >> Nikhil Mohite. >> >> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >> [email protected]> wrote: >> >>> Thanks, patch applied. >>> >>> I have updated the screenshot and some documentation stuff. >>> >>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Akshay, >>>> >>>> >>>> Please find the updated patch. (V6) >>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> Hi Nikhil >>>>> >>>>> Please rebase and send the patch again. >>>>> >>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Akshay/ Team >>>>>> >>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Nikhil >>>>>>> >>>>>>> Following are the review comments: >>>>>>> >>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >>>>>>> context menu option should not be visible. >>>>>>> - Documentation screenshot should be in standard theme for >>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>> the new PSQL button on the browser tree. >>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>> - Remove commented code (if any) >>>>>>> - Check SonarQube (I haven't run) >>>>>>> >>>>>>> Please find the updated patch, resolve all the review comments, and >>>>>> update the code to resolve the SonarQube issues. >>>>>> >>>>>>> >>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>> >>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Dave/ Team, >>>>>>>>> >>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>> >>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>> >>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. >>>>>>>>>>>>> That should be pushed into the webpacked bundle I think, and not included >>>>>>>>>>>>> inline in HTML. >>>>>>>>>>>>> >>>>>>>>>>>> I have moved most of the code in the js file, few things are >>>>>>>>>>>> still in HTML. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>> xterm V3 onwards they have provided the API to set the theme and >>>>>>>>>>> other settings, earlier I tried with CSS to override the theme but couldn’t >>>>>>>>>>> able to apply the theme properly as some style get applied as in-line style >>>>>>>>>>> for the HTML, so used the API to set the theme. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> OK, but either way we can't hard-code styles from themes in HTML >>>>>>>>>> templates for individual features; that way leads to madness. >>>>>>>>>> >>>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>>> assistance? >>>>>>>>>> >>>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>>> Aditya helped in this. >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>>> >>>>>>>>>>> I tried the default selection color from SQL for the dark and >>>>>>>>> standard themes but still, it was not readable so just updated the color >>>>>>>>> code with another color as follows. >>>>>>>>> 1. Dark Theme: >>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>> 3. Standard: >>>>>>>>> [image: image.png] >>>>>>>>> can we go with the colors or should we update it? >>>>>>>>> >>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>> >>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>> >>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>> >>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>> >>>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I am >>>>>>>>>>>>> working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>> >>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>> >>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>> >>>>>>>>>> >>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>> >>>>>>>>>>>> I noticed while I was playing with that, that you are passing >>>>>>>>>>>> the password as part of the connection string. As I've mentioned in the >>>>>>>>>>>> past, that is absolutely not acceptable; it will expose the password to all >>>>>>>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> if we try to load data from the table containing millions of >>>>>>>>>>>>> records, UI gets very slow. >>>>>>>>>>>>> >>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>> >>>>>>>>>> >>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it fills >>>>>>>>>>>> up? Can you tell where the memory usage is? >>>>>>>>>>>> >>>>>>>>>>> I checked the psql memory consumption in terminal and pgAdmin >>>>>>>>>>> psql tool memory consumption is the similar. Also tested the performance >>>>>>>>>>> and query execution timing is also similar. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> In addition to the issue above, it looks like the \! blocking >>>>>>>>>>>> may have lost it's ability to ignore quoted strings: >>>>>>>>>>>> >>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>> >>>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>>> >>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we >>>>>>>>>>>>>>>>> can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the child >>>>>>>>>>>>>>>>> nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>> - PSQL tab title should be only database server name >>>>>>>>>>>>>>>>> as the user can change the database/user from PSQL command, so it's been >>>>>>>>>>>>>>>>> difficult to update the tab title. >>>>>>>>>>>>>>>>> - PSQL connection is still open even if we disconnect >>>>>>>>>>>>>>>>> the database server from the browser tree. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the user >>>>>>>>>>>>>>>>> know from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed >>>>>>>>>>>>>>>>> from requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be passed >>>>>>>>>>>>>>>> in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in >>>>>>>>>>>>>>>> dark mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>>>>> - I spotted at least one print() statement that shouldn't >>>>>>>>>>>>>>>> be there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, >>>>>>>>>>>>>>>> where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: >>>>>>>>>>>>>>>> Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add Menu >>>>>>>>>>>>>>>>>>>> option for starting PSQL. >>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database nodes >>>>>>>>>>>>>>>>>>>> from the tree view. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json >>>>>>>>>>>>>>>>>>> that makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Regards, >>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Regards, >>>>>>>>>>> Nikhil Mohite >>>>>>>>>>> >>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>> *Software Engineer.* >>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>> Nikhil Mohite >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Thanks & Regards* >>>>>>> *Akshay Joshi* >>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>> >>>>>>> *Mobile: +91 976-788-8246* >>>>>>> >>>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> *pgAdmin Hacker | Principal Software Architect* >>>>> *EDB Postgres <http://edbpostgres.com>* >>>>> >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> *pgAdmin Hacker | Principal Software Architect* >>> *EDB Postgres <http://edbpostgres.com>* >>> >>> *Mobile: +91 976-788-8246* >>> >> > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-07 05:45 Nikhil Mohite <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 2 replies; 54+ messages in thread From: Nikhil Mohite @ 2021-06-07 05:45 UTC (permalink / raw) To: pgadmin-hackers; +Cc: Dave Page <[email protected]>; Akshay Joshi <[email protected]> Hi Team, Please find the updated patch for added psql tool for windows platform. Also fixed a few issues reported by Fahar. 1. If the database name contains escape characters psql unable to connect. 2. If the user terminates the connection by entering "exit", psql will show connection termination msg. Regards, Nikhil Mohite. On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi <[email protected]> wrote: > > > On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Team, >>> >>> Following are few points related to PSQL tool on windows: >>> >>> 1. Currently using the *pywinpty* library on windows to create pty >>> process and execute the psql.exe. >>> 2. To read the stderr (errors) currently using '2>>&1' arguments to >>> psql.exe command. (It will redirect stderr to stdout ) >>> 3. Windows conPTY is available on Windows 10 only (released after >>> 2018). >>> 4. Windows conPTY does not support the Asynchronous I/O, so to get >>> the terminal output, need to add the read function after every command >>> execution. (something like select() is not available) >>> 5. Also found some performance issues with psql on windows. >>> 1. To read the output from the terminal need to add some sleep >>> time as it will take time to return the output. >>> 2. Resize the terminal is also not consistent and causing the >>> issue if we resize the window faster or multiple times very quickly. >>> 3. Loading large dataset sometimes cause system to non-responsive >>> state.(In this state restart requires) >>> >>> Please find the patch for disable the psql tool for windows >>> platform.(Windows builds are falling due to this sending patch for disable >>> psql on windows.) >>> >> >> Disabling major features on our most common deployment platform really >> isn't a good option. I assume all of the above options are related to lack >> of async I/O? >> > > We have temporarily disabled the feature until found a solution, to > generate the nightly build for testing. > >> >> Have you tried forcing the use of winpty rather than conpty? >> >> >>> >>> Reference links: >>> >>> 1. https://github.com/microsoft/terminal/issues/262 >>> 2. >>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>> 3. https://pypi.org/project/pywinpty/ >>> >>> >>> If any suggestions or questions please let me know. >>> >>> Regards, >>> Nikhil Mohite. >>> >>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> Thanks, patch applied. >>>> >>>> I have updated the screenshot and some documentation stuff. >>>> >>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Akshay, >>>>> >>>>> >>>>> Please find the updated patch. (V6) >>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Nikhil >>>>>> >>>>>> Please rebase and send the patch again. >>>>>> >>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Akshay/ Team >>>>>>> >>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Nikhil >>>>>>>> >>>>>>>> Following are the review comments: >>>>>>>> >>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >>>>>>>> context menu option should not be visible. >>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>> the new PSQL button on the browser tree. >>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>> - Remove commented code (if any) >>>>>>>> - Check SonarQube (I haven't run) >>>>>>>> >>>>>>>> Please find the updated patch, resolve all the review comments, and >>>>>>> update the code to resolve the SonarQube issues. >>>>>>> >>>>>>>> >>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>> >>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave/ Team, >>>>>>>>>> >>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>> >>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>> >>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. >>>>>>>>>>>>>> That should be pushed into the webpacked bundle I think, and not included >>>>>>>>>>>>>> inline in HTML. >>>>>>>>>>>>>> >>>>>>>>>>>>> I have moved most of the code in the js file, few things are >>>>>>>>>>>>> still in HTML. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>>> xterm V3 onwards they have provided the API to set the theme >>>>>>>>>>>> and other settings, earlier I tried with CSS to override the theme but >>>>>>>>>>>> couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> OK, but either way we can't hard-code styles from themes in HTML >>>>>>>>>>> templates for individual features; that way leads to madness. >>>>>>>>>>> >>>>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>>>> assistance? >>>>>>>>>>> >>>>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>>>> Aditya helped in this. >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>> >>>>>>>>>>>> I tried the default selection color from SQL for the dark and >>>>>>>>>> standard themes but still, it was not readable so just updated the color >>>>>>>>>> code with another color as follows. >>>>>>>>>> 1. Dark Theme: >>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>> 3. Standard: >>>>>>>>>> [image: image.png] >>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>> >>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I am >>>>>>>>>>>>>> working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>> >>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>> >>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>> >>>>>>>>>>>>> I noticed while I was playing with that, that you are passing >>>>>>>>>>>>> the password as part of the connection string. As I've mentioned in the >>>>>>>>>>>>> past, that is absolutely not acceptable; it will expose the password to all >>>>>>>>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> if we try to load data from the table containing millions of >>>>>>>>>>>>>> records, UI gets very slow. >>>>>>>>>>>>>> >>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it fills >>>>>>>>>>>>> up? Can you tell where the memory usage is? >>>>>>>>>>>>> >>>>>>>>>>>> I checked the psql memory consumption in terminal and pgAdmin >>>>>>>>>>>> psql tool memory consumption is the similar. Also tested the performance >>>>>>>>>>>> and query execution timing is also similar. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> In addition to the issue above, it looks like the \! blocking >>>>>>>>>>>>> may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>> >>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>> >>>>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we >>>>>>>>>>>>>>>>>> can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the child >>>>>>>>>>>>>>>>>> nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server name >>>>>>>>>>>>>>>>>> as the user can change the database/user from PSQL command, so it's been >>>>>>>>>>>>>>>>>> difficult to update the tab title. >>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we disconnect >>>>>>>>>>>>>>>>>> the database server from the browser tree. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the user >>>>>>>>>>>>>>>>>> know from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed >>>>>>>>>>>>>>>>>> from requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in >>>>>>>>>>>>>>>>> dark mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>>>>>> - I spotted at least one print() statement that shouldn't >>>>>>>>>>>>>>>>> be there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, >>>>>>>>>>>>>>>>> where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: >>>>>>>>>>>>>>>>> Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database nodes >>>>>>>>>>>>>>>>>>>>> from the tree view. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json >>>>>>>>>>>>>>>>>>>> that makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>> >>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> Regards, >>>>>>>>>> Nikhil Mohite >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> *Thanks & Regards* >>>>>>>> *Akshay Joshi* >>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>> >>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> *Thanks & Regards* >>>>>> *Akshay Joshi* >>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>> >>>>>> *Mobile: +91 976-788-8246* >>>>>> >>>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> *pgAdmin Hacker | Principal Software Architect* >>>> *EDB Postgres <http://edbpostgres.com>* >>>> >>>> *Mobile: +91 976-788-8246* >>>> >>> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [application/octet-stream] RM_2341_v7.patch (26.3K, 6-RM_2341_v7.patch) download | inline diff: diff --git a/requirements.txt b/requirements.txt index ebdb1b21..469aa964 100644 --- a/requirements.txt +++ b/requirements.txt @@ -37,6 +37,7 @@ ldap3==2.* Flask-BabelEx==0.* gssapi==1.6.* flask-socketio>=5.0.1 -eventlet==0.30.2 +eventlet==0.31.0 httpagentparser==1.9.* user-agents==2.2.0 +pywinpty==1.1.* diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 0e464c06..0dbe589c 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -506,61 +506,38 @@ def register_browser_preferences(self): ) ) - if sys.platform != 'win32': - self.open_in_new_tab = self.preference.register( - 'tab_settings', 'new_browser_tab_open', - gettext("Open in new browser tab"), 'select2', None, - category_label=PREF_LABEL_OPTIONS, - options=[{'label': gettext('Query Tool'), 'value': 'qt'}, - {'label': gettext('Debugger'), 'value': 'debugger'}, - {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, - {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], - help_str=gettext( - 'Select Query Tool, Debugger, Schema Diff, ERD Tool ' - 'or PSQL Tool from the drop-down to set ' - 'open in new browser tab for that particular module.' - ), - select2={ - 'multiple': True, 'allowClear': False, - 'tags': True, 'first_empty': False, - 'selectOnClose': False, 'emptyOptions': True, - 'tokenSeparators': [','], - 'placeholder': gettext('Select open new tab...') - } - ) - - self.psql_tab_title = self.preference.register( - 'tab_settings', 'psql_tab_title_placeholder', - gettext("PSQL tool tab title"), - 'text', '%DATABASE%/%USERNAME%@%SERVER%', - category_label=PREF_LABEL_DISPLAY, - help_str=gettext( - 'Supported placeholders are %DATABASE%, %USERNAME%, ' - 'and %SERVER%. Users can provide any string with or without' - ' placeholders of their choice. The blank title will be revert' - ' back to the default title with placeholders.' - ) - ) - else: - self.open_in_new_tab = self.preference.register( - 'tab_settings', 'new_browser_tab_open', - gettext("Open in new browser tab"), 'select2', None, - category_label=PREF_LABEL_OPTIONS, - options=[{'label': gettext('Query Tool'), 'value': 'qt'}, - {'label': gettext('Debugger'), 'value': 'debugger'}, - {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], - help_str=gettext( - 'Select Query Tool, Debugger, Schema Diff, ERD Tool ' - 'or PSQL Tool from the drop-down to set ' - 'open in new browser tab for that particular module.' - ), - select2={ - 'multiple': True, 'allowClear': False, - 'tags': True, 'first_empty': False, - 'selectOnClose': False, 'emptyOptions': True, - 'tokenSeparators': [','], - 'placeholder': gettext('Select open new tab...') - } + self.open_in_new_tab = self.preference.register( + 'tab_settings', 'new_browser_tab_open', + gettext("Open in new browser tab"), 'select2', None, + category_label=PREF_LABEL_OPTIONS, + options=[{'label': gettext('Query Tool'), 'value': 'qt'}, + {'label': gettext('Debugger'), 'value': 'debugger'}, + {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext( + 'Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), + select2={ + 'multiple': True, 'allowClear': False, + 'tags': True, 'first_empty': False, + 'selectOnClose': False, 'emptyOptions': True, + 'tokenSeparators': [','], + 'placeholder': gettext('Select open new tab...') + } + ) + + self.psql_tab_title = self.preference.register( + 'tab_settings', 'psql_tab_title_placeholder', + gettext("PSQL tool tab title"), + 'text', '%DATABASE%/%USERNAME%@%SERVER%', + category_label=PREF_LABEL_DISPLAY, + help_str=gettext( + 'Supported placeholders are %DATABASE%, %USERNAME%, ' + 'and %SERVER%. Users can provide any string with or without' + ' placeholders of their choice. The blank title will be revert' + ' back to the default title with placeholders.' ) + ) diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index 64442189..47c87715 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -66,7 +66,7 @@ define([ }]); // show psql tool same as query tool. - if(pgAdmin['enable_psql'] && pgAdmin['platform'] != 'win32') { + if(pgAdmin['enable_psql']) { pgAdmin.Browser.add_menus([{ name: 'show_psql_tool', node: this.type, module: this, applies: ['context'], callback: 'show_psql_tool', diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index c2e73931..f7c04d0d 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -210,7 +210,7 @@ define('pgadmin.browser.node', [ icon: 'fa fa-search', enable: enable, }]); - if(pgAdmin['enable_psql'] && pgAdmin['platform'] != 'win32') { + if(pgAdmin['enable_psql']) { // show psql tool same as query tool. pgAdmin.Browser.add_menus([{ name: 'show_psql_tool', node: this.type, module: this, diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index 4aaa41ce..bc9c13a3 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -59,7 +59,7 @@ let _defaultToolBarButtons = [ } ]; -if(pgAdmin['enable_psql'] && pgAdmin['platform'] != 'win32') { +if(pgAdmin['enable_psql']) { _defaultToolBarButtons.unshift({ label: gettext('PSQL Tool'), ariaLabel: gettext('PSQL Tool'), @@ -119,7 +119,7 @@ export function initializeToolbar(panel, wcDocker) { pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected()); else if ('name' in data && data.name === gettext('Search objects')) pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); - else if ('name' in data && data.name === gettext('PSQL Tool') && pgAdmin['platform'] != 'win32'){ + else if ('name' in data && data.name === gettext('PSQL Tool')){ var input = {}, t = pgAdmin.Browser.tree, i = input.item || t.selected(), diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py index 5e22f2d5..139ac673 100644 --- a/web/pgadmin/browser/utils.py +++ b/web/pgadmin/browser/utils.py @@ -63,7 +63,8 @@ def underscore_unescape(text): """: '"', "`": '`', "'": "'", - "'": "'" + "'": "'", + """: '"' } # always replace & first diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py index 7f5adae9..f62e0743 100644 --- a/web/pgadmin/tools/psql/__init__.py +++ b/web/pgadmin/tools/psql/__init__.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 - import os import re import select @@ -20,7 +19,9 @@ from pgadmin.utils.driver import get_driver from ... import socketio as sio from pgadmin.utils import get_complete_file_path -if _platform != 'win32': +if _platform == 'win32': + from winpty import PtyProcess +else: import fcntl import termios import pty @@ -101,8 +102,8 @@ def panel(trans_id): return render_template('editor_template.html', sid=params['sid'], - db=underscore_unescape(params['db']) if params[ - 'db'] else 'postgres', + db=underscore_unescape( + o_db_name) if o_db_name else 'postgres', server_type=params['server_type'], is_enable=config.ENABLE_PSQL, title=underscore_unescape(params['title']), @@ -120,8 +121,13 @@ def set_term_size(fd, row, col, xpix=0, ypix=0): :param xpix: :param ypix: """ - term_size = struct.pack('HHHH', row, col, xpix, ypix) - fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) + if _platform == 'win32': + app.config['sessions'][request.sid].setwinsize(row, col) + # data = {'key_name': 'Enter', 'input': '\n'} + # socket_input(data) + else: + term_size = struct.pack('HHHH', row, col, xpix, ypix) + fcntl.ioctl(fd, termios.TIOCSWINSZ, term_size) @sio.on('connect', namespace='/pty') @@ -216,6 +222,19 @@ def read_terminal_data(parent, data_ready, max_read_bytes, sid): session_last_cmd[request.sid]['invalid_cmd'] = False +def read_stdout(process, sid, max_read_bytes, win_emit_output=True): + (data_ready, _, _) = select.select([process.fd], [], [], 0) + if process.fd in data_ready: + output = process.read(max_read_bytes) + if win_emit_output: + sio.emit('pty-output', + {'result': output, + 'error': False}, + namespace='/pty', room=sid) + + sio.sleep(0) + + @sio.on('start_process', namespace='/pty') def start_process(data): """ @@ -227,8 +246,24 @@ def start_process(data): def read_and_forward_pty_output(sid, data): max_read_bytes = 1024 * 20 + import time + if _platform == 'win32': + + os.environ['PYWINPTY_BACKEND'] = '1' + process = PtyProcess.spawn('cmd.exe') + + process.write(r'"{0}" "{1}" 2>>&1'.format(connection_data[0], + connection_data[1])) + process.write("\r\n") + app.config['sessions'][request.sid] = process + pdata[request.sid] = process + set_term_size(process, 50, 50) + + while True: + read_stdout(process, sid, max_read_bytes, + win_emit_output=True) + else: - if _platform != 'win32': p, parent, fd = create_pty_terminal(connection_data) while p and p.poll() is None: @@ -248,12 +283,6 @@ def start_process(data): timeout) read_terminal_data(parent, data_ready, max_read_bytes, sid) - else: - sio.emit( - 'conn_error', - { - 'error': 'PSQL tool not supported.', - }, namespace='/pty', room=request.sid) # Check user is authenticated and PSQL is enabled in config. if current_user.is_authenticated and config.ENABLE_PSQL: @@ -342,14 +371,14 @@ def get_connection_str(psql_utility, db, manager): :param db: database name to connect specific db. :return: connection attribute list for PSQL connection. """ - conn_attr = get_conn_str(manager, db) + conn_attr = get_conn_str_win(manager, db) conn_attr_list = list() conn_attr_list.append(psql_utility) conn_attr_list.append(conn_attr) return conn_attr_list -def get_conn_str(manager, db): +def get_conn_str_win(manager, db): """ Get connection attributes for psql connection. :param manager: @@ -357,46 +386,48 @@ def get_conn_str(manager, db): :return: """ manager.export_password_env('PGPASSWORD') + db = db.replace('"', '\\"') + db = db.replace("'", "\\'") conn_attr =\ - 'host={0} port={1} dbname={2} user={3} sslmode={4} ' \ - 'sslcompression={5} ' \ + 'host=\'{0}\' port=\'{1}\' dbname=\'{2}\' user=\'{3}\' ' \ + 'sslmode=\'{4}\' sslcompression=\'{5}\' ' \ ''.format( manager.local_bind_host if manager.use_ssh_tunnel else manager.host, manager.local_bind_port if manager.use_ssh_tunnel else manager.port, - underscore_unescape(db) if db != '' else 'postgres', + db if db != '' else 'postgres', underscore_unescape(manager.user) if manager.user else 'postgres', manager.ssl_mode, True if manager.sslcompression else False, ) if manager.hostaddr: - conn_attr = " {0} hostaddr={1}".format(conn_attr, manager.hostaddr) + conn_attr = " {0} hostaddr='{1}'".format(conn_attr, manager.hostaddr) if manager.passfile: - conn_attr = " {0} passfile={1}".format(conn_attr, - get_complete_file_path( - manager.passfile)) + conn_attr = " {0} passfile='{1}'".format(conn_attr, + get_complete_file_path( + manager.passfile)) if get_complete_file_path(manager.sslcert): - conn_attr = " {0} sslcert={1}".format( + conn_attr = " {0} sslcert='{1}'".format( conn_attr, get_complete_file_path(manager.sslcert)) if get_complete_file_path(manager.sslkey): - conn_attr = " {0} sslkey={1}".format( + conn_attr = " {0} sslkey='{1}'".format( conn_attr, get_complete_file_path(manager.sslkey)) if get_complete_file_path(manager.sslrootcert): - conn_attr = " {0} sslrootcert={1}".format( + conn_attr = " {0} sslrootcert='{1}'".format( conn_attr, get_complete_file_path(manager.sslrootcert)) if get_complete_file_path(manager.sslcrl): - conn_attr = " {0} sslcrl={1}".format( + conn_attr = " {0} sslcrl='{1}'".format( conn_attr, get_complete_file_path(manager.sslcrl)) if manager.service: - conn_attr = " {0} service={1}".format( + conn_attr = " {0} service='{1}'".format( conn_attr, get_complete_file_path(manager.service)) return conn_attr @@ -433,12 +464,27 @@ def invalid_cmd(): :rtype: """ session_last_cmd[request.sid]['invalid_cmd'] = True - for i in range(len(session_input[request.sid])): - os.write(app.config['sessions'][request.sid], - '\b \b'.encode()) + if _platform == 'win32': + for i in range(len(session_input[request.sid])): + app.config['sessions'][request.sid].write('\b \b') + app.config['sessions'][request.sid].write('\r\n') + + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security\r\n"), + 'error': True + }, + namespace='/pty', room=request.sid) + else: + for i in range(len(session_input[request.sid])): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) - os.write(app.config['sessions'][request.sid], - '\n'.encode()) + os.write(app.config['sessions'][request.sid], + '\n'.encode()) session_input[request.sid] = '' @@ -464,18 +510,36 @@ def check_valid_cmd(user_input): if stop_execution: session_last_cmd[request.sid]['invalid_cmd'] = True + if _platform == 'win32': + # Remove already added command from terminal. + for i in range(len(user_input)): + app.config['sessions'][request.sid].write('\b \b') + app.config['sessions'][request.sid].write('\n') - # Remove already added command from terminal. - for i in range(len(user_input)): + sio.emit( + 'pty-output', + { + 'result': gettext( + "ERROR: Shell commands are disabled " + "in psql for security\r\n"), + 'error': True + }, + namespace='/pty', room=request.sid) + else: + # Remove already added command from terminal. + for i in range(len(user_input)): + os.write(app.config['sessions'][request.sid], + '\b \b'.encode()) + # Add Enter event to execute the command. os.write(app.config['sessions'][request.sid], - '\b \b'.encode()) - # Add Enter event to execute the command. - os.write(app.config['sessions'][request.sid], - '\n'.encode()) + '\n'.encode()) else: session_last_cmd[request.sid]['invalid_cmd'] = False - os.write(app.config['sessions'][request.sid], - '\n'.encode()) + if _platform == 'win32': + app.config['sessions'][request.sid].write('\n') + else: + os.write(app.config['sessions'][request.sid], + '\n'.encode()) def enter_key_press(data): @@ -501,8 +565,8 @@ def enter_key_press(data): not config.ALLOW_PSQL_SHELL_COMMANDS and\ not session_last_cmd[request.sid]['is_new_connection']: check_valid_cmd(user_input) - elif user_input == '\q' or user_input == 'q\\q' or \ - user_input in ['exit', 'exit;']: + elif user_input == '\q' or user_input == 'q\\q' or user_input in ['exit', + 'exit;']: # If user enter \q to terminate the PSQL, emit the msg to # notify user connection is terminated. sio.emit('pty-output', @@ -514,12 +578,20 @@ def enter_key_press(data): 'error': True}, namespace='/pty', room=request.sid) - os.write(app.config['sessions'][request.sid], - '\n'.encode()) + if _platform == 'win32': + app.config['sessions'][request.sid].write('\n') + del app.config['sessions'][request.sid] + else: + os.write(app.config['sessions'][request.sid], + '\n'.encode()) else: - os.write(app.config['sessions'][request.sid], - data['input'].encode()) + if _platform == 'win32': + app.config['sessions'][request.sid].write( + "{0}".format(data['input'])) + else: + os.write(app.config['sessions'][request.sid], + data['input'].encode()) session_input[request.sid] = '' session_last_cmd[request.sid]['is_new_connection'] = False @@ -619,9 +691,13 @@ def other_key_press(data): session_input[request.sid] = data['input'] session_input_cursor[request.sid] += 1 - # Write user input to terminal parent fd. - os.write(app.config['sessions'][request.sid], - data['input'].encode()) + if _platform == 'win32': + app.config['sessions'][request.sid].write( + "{0}".format(data['input'])) + else: + # Write user input to terminal parent fd. + os.write(app.config['sessions'][request.sid], + data['input'].encode()) @sio.on('socket_input', namespace='/pty') @@ -697,11 +773,17 @@ def server_disconnect(data): def disconnect_socket(): - os.write(app.config['sessions'][request.sid], '\q\n'.encode()) - sio.sleep(1) - os.close(app.config['sessions'][request.sid]) - os.close(cdata[request.sid]) - del app.config['sessions'][request.sid] + if _platform == 'win32': + if request.sid in app.config['sessions']: + process = app.config['sessions'][request.sid] + process.terminate() + del app.config['sessions'][request.sid] + else: + os.write(app.config['sessions'][request.sid], '\q\n'.encode()) + sio.sleep(1) + os.close(app.config['sessions'][request.sid]) + os.close(cdata[request.sid]) + del app.config['sessions'][request.sid] def _get_database(sid, did): diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js index 6a0ae191..85bccb1a 100644 --- a/web/pgadmin/tools/psql/static/js/psql_module.js +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -55,7 +55,7 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) }]; this.enable_psql_tool = pgAdmin['enable_psql']; - if(pgAdmin['enable_psql'] && pgAdmin['platform'] != 'win32') { + if(pgAdmin['enable_psql']) { pgBrowser.add_menus(menus); } @@ -156,11 +156,12 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) var tab_title_placeholder = pgBrowser.get_preferences_for_module('browser').psql_tab_title_placeholder; panelTitle = generateTitle(tab_title_placeholder, title_data); - const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + const [panelUrl, panelCloseUrl, db_label] = this.getPanelUrls(transId, panelTitle, parentData, gen); let psqlToolForm = ` <form id="psqlToolForm" action="${panelUrl}" method="post"> <input id="title" name="title" hidden /> + <input id='db' value='${db_label}' hidden /> <input name="close_url" value="${panelCloseUrl}" hidden /> </form> <script> @@ -228,9 +229,11 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) +`&did=${parentData.database._id}` +`&server_type=${parentData.server.server_type}` + `&theme=${theme}`; - + let db_label = ''; if(parentData.database && parentData.database._id) { - let db_label = parentData.database._label.replace('\\', '\\\\'); + db_label = _.escape(parentData.database._label.replace('\\', '\\\\')); + db_label = db_label.replace('\'', '\''); + db_label = db_label.replace('"', '\"'); openUrl += `&db=${db_label}`; } else { openUrl += `&db=${''}`; @@ -239,7 +242,7 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) let closeUrl = url_for('psql.close', { trans_id: transId, }); - return [openUrl, closeUrl]; + return [openUrl, closeUrl, db_label]; }, psql_terminal: function() { // theme colors @@ -375,4 +378,3 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) return pgBrowser.psql; } - diff --git a/web/pgadmin/tools/psql/templates/editor_template.html b/web/pgadmin/tools/psql/templates/editor_template.html index 0568ad71..17b8a04d 100644 --- a/web/pgadmin/tools/psql/templates/editor_template.html +++ b/web/pgadmin/tools/psql/templates/editor_template.html @@ -23,41 +23,36 @@ require( ['sources/generated/psql_tool'], function(pgBrowser) { - if (self.pgAdmin['platform'] != 'win32') { - const term = self.pgAdmin.Browser.psql.psql_terminal(); - <!--Addon for fitAddon, webLinkAddon, SearchAddon --> - const fitAddon = self.pgAdmin.Browser.psql.psql_Addon(term); - <!-- Update the theme for terminal as per pgAdmin 4 theme.--> - self.pgAdmin.Browser.psql.set_theme(term); - <!-- Open the terminal --> - term.open(document.getElementById('psql-terminal')); - <!-- Socket--> - const socket = self.pgAdmin.Browser.psql.psql_socket(); - self.pgAdmin.Browser.psql.psql_socket_io(socket, '{{is_enable}}', '{{sid}}', '{{db}}', '{{server_type}}', fitAddon, term); - self.pgAdmin.Browser.psql.psql_terminal_io(term, socket); - self.pgAdmin.Browser.psql.check_db_name_change('{{db}}', '{{o_db_name}}'); + const term = self.pgAdmin.Browser.psql.psql_terminal(); + <!--Addon for fitAddon, webLinkAddon, SearchAddon --> + const fitAddon = self.pgAdmin.Browser.psql.psql_Addon(term); + <!-- Update the theme for terminal as per pgAdmin 4 theme.--> + self.pgAdmin.Browser.psql.set_theme(term); + <!-- Open the terminal --> + term.open(document.getElementById('psql-terminal')); + <!-- Socket--> + const socket = self.pgAdmin.Browser.psql.psql_socket(); + self.pgAdmin.Browser.psql.psql_socket_io(socket, '{{is_enable}}', '{{sid}}', '{{db | replace("'", "\'")| replace('"', '\"') | replace('\\', '\\\\')}}', '{{server_type}}', fitAddon, term); + self.pgAdmin.Browser.psql.psql_terminal_io(term, socket); + self.pgAdmin.Browser.psql.check_db_name_change('{{db}}', '{{o_db_name}}'); + + <!-- Resize the terminal --> + function fitToscreen(){ + fitAddon.fit() + socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + } - <!-- Resize the terminal --> - function fitToscreen(){ - fitAddon.fit() - socket.emit("resize", {"cols": term.cols, "rows": term.rows}) + function debounce(func, wait_ms) { + let timeout + return function(...args) { + const context = this + clearTimeout(timeout) + timeout = setTimeout(() => func.apply(context, args), wait_ms) } + } - function debounce(func, wait_ms) { - let timeout - return function(...args) { - const context = this - clearTimeout(timeout) - timeout = setTimeout(() => func.apply(context, args), wait_ms) - } - } + const wait_ms = 50;; + window.onresize = debounce(fitToscreen, wait_ms) - const wait_ms = 50;; - window.onresize = debounce(fitToscreen, wait_ms) - } else { - document.getElementById('psql-terminal').innterHTML = 'PSQL not supported' - } }); {% endblock %} - - ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-07 08:36 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 1 sibling, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-07 08:36 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> Hi On Mon, Jun 7, 2021 at 6:45 AM Nikhil Mohite <[email protected]> wrote: > Hi Team, > > Please find the updated patch for added psql tool for windows platform. > Cool :-). Does this fix the issues you described previously? If not, can you please ensure the limitations are noted in the documentation for the feature? > Also fixed a few issues reported by Fahar. > 1. If the database name contains escape characters psql unable to connect. > 2. If the user terminates the connection by entering "exit", psql will > show connection termination msg. > > > Regards, > Nikhil Mohite. > > On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi <[email protected]> > wrote: > >> >> >> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Team, >>>> >>>> Following are few points related to PSQL tool on windows: >>>> >>>> 1. Currently using the *pywinpty* library on windows to create pty >>>> process and execute the psql.exe. >>>> 2. To read the stderr (errors) currently using '2>>&1' arguments to >>>> psql.exe command. (It will redirect stderr to stdout ) >>>> 3. Windows conPTY is available on Windows 10 only (released after >>>> 2018). >>>> 4. Windows conPTY does not support the Asynchronous I/O, so to get >>>> the terminal output, need to add the read function after every command >>>> execution. (something like select() is not available) >>>> 5. Also found some performance issues with psql on windows. >>>> 1. To read the output from the terminal need to add some sleep >>>> time as it will take time to return the output. >>>> 2. Resize the terminal is also not consistent and causing the >>>> issue if we resize the window faster or multiple times very quickly. >>>> 3. Loading large dataset sometimes cause system to >>>> non-responsive state.(In this state restart requires) >>>> >>>> Please find the patch for disable the psql tool for windows >>>> platform.(Windows builds are falling due to this sending patch for disable >>>> psql on windows.) >>>> >>> >>> Disabling major features on our most common deployment platform really >>> isn't a good option. I assume all of the above options are related to lack >>> of async I/O? >>> >> >> We have temporarily disabled the feature until found a solution, to >> generate the nightly build for testing. >> >>> >>> Have you tried forcing the use of winpty rather than conpty? >>> >>> >>>> >>>> Reference links: >>>> >>>> 1. https://github.com/microsoft/terminal/issues/262 >>>> 2. >>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>> 3. https://pypi.org/project/pywinpty/ >>>> >>>> >>>> If any suggestions or questions please let me know. >>>> >>>> Regards, >>>> Nikhil Mohite. >>>> >>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> Thanks, patch applied. >>>>> >>>>> I have updated the screenshot and some documentation stuff. >>>>> >>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Akshay, >>>>>> >>>>>> >>>>>> Please find the updated patch. (V6) >>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Nikhil >>>>>>> >>>>>>> Please rebase and send the patch again. >>>>>>> >>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Akshay/ Team >>>>>>>> >>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Nikhil >>>>>>>>> >>>>>>>>> Following are the review comments: >>>>>>>>> >>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >>>>>>>>> context menu option should not be visible. >>>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>>> the new PSQL button on the browser tree. >>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>>> - Remove commented code (if any) >>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>> >>>>>>>>> Please find the updated patch, resolve all the review comments, >>>>>>>> and update the code to resolve the SonarQube issues. >>>>>>>> >>>>>>>>> >>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>> >>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>> >>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>> >>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. >>>>>>>>>>>>>>> That should be pushed into the webpacked bundle I think, and not included >>>>>>>>>>>>>>> inline in HTML. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> I have moved most of the code in the js file, few things are >>>>>>>>>>>>>> still in HTML. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the theme >>>>>>>>>>>>> and other settings, earlier I tried with CSS to override the theme but >>>>>>>>>>>>> couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> OK, but either way we can't hard-code styles from themes in >>>>>>>>>>>> HTML templates for individual features; that way leads to madness. >>>>>>>>>>>> >>>>>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>>>>> assistance? >>>>>>>>>>>> >>>>>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>>>>> Aditya helped in this. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>> >>>>>>>>>>>>> I tried the default selection color from SQL for the dark and >>>>>>>>>>> standard themes but still, it was not readable so just updated the color >>>>>>>>>>> code with another color as follows. >>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>> 3. Standard: >>>>>>>>>>> [image: image.png] >>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I >>>>>>>>>>>>>>> am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>> >>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>> >>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>> >>>>>>>>>>>>>> I noticed while I was playing with that, that you are passing >>>>>>>>>>>>>> the password as part of the connection string. As I've mentioned in the >>>>>>>>>>>>>> past, that is absolutely not acceptable; it will expose the password to all >>>>>>>>>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> if we try to load data from the table containing millions of >>>>>>>>>>>>>>> records, UI gets very slow. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it fills >>>>>>>>>>>>>> up? Can you tell where the memory usage is? >>>>>>>>>>>>>> >>>>>>>>>>>>> I checked the psql memory consumption in terminal and pgAdmin >>>>>>>>>>>>> psql tool memory consumption is the similar. Also tested the performance >>>>>>>>>>>>> and query execution timing is also similar. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> In addition to the issue above, it looks like the \! blocking >>>>>>>>>>>>>> may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>> >>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>> >>>>>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we >>>>>>>>>>>>>>>>>>> can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the child >>>>>>>>>>>>>>>>>>> nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server name >>>>>>>>>>>>>>>>>>> as the user can change the database/user from PSQL command, so it's been >>>>>>>>>>>>>>>>>>> difficult to update the tab title. >>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the user >>>>>>>>>>>>>>>>>>> know from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed >>>>>>>>>>>>>>>>>>> from requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in >>>>>>>>>>>>>>>>>> dark mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that shouldn't >>>>>>>>>>>>>>>>>> be there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, >>>>>>>>>>>>>>>>>> where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: >>>>>>>>>>>>>>>>>> Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json >>>>>>>>>>>>>>>>>>>>> that makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Regards, >>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>> >>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>> Nikhil Mohite >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> *Thanks & Regards* >>>>>>>>> *Akshay Joshi* >>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>> >>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Thanks & Regards* >>>>>>> *Akshay Joshi* >>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>> >>>>>>> *Mobile: +91 976-788-8246* >>>>>>> >>>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> *pgAdmin Hacker | Principal Software Architect* >>>>> *EDB Postgres <http://edbpostgres.com>* >>>>> >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-07 08:45 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-07 08:45 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> Hi Dave, On Mon, Jun 7, 2021 at 2:07 PM Dave Page <[email protected]> wrote: > Hi > > On Mon, Jun 7, 2021 at 6:45 AM Nikhil Mohite < > [email protected]> wrote: > >> Hi Team, >> >> Please find the updated patch for added psql tool for windows platform. >> > > Cool :-). Does this fix the issues you described previously? If not, can > you please ensure the limitations are noted in the documentation for the > feature? > Yes, the issues I mentioned earlier are fixed, it is now consistent with other supporting platforms. > > >> Also fixed a few issues reported by Fahar. >> 1. If the database name contains escape characters psql unable to connect. >> 2. If the user terminates the connection by entering "exit", psql will >> show connection termination msg. >> >> >> Regards, >> Nikhil Mohite. >> >> Regards, Nikhil Mohite > On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi <[email protected]> >> wrote: >> >>> >>> >>> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Team, >>>>> >>>>> Following are few points related to PSQL tool on windows: >>>>> >>>>> 1. Currently using the *pywinpty* library on windows to create >>>>> pty process and execute the psql.exe. >>>>> 2. To read the stderr (errors) currently using '2>>&1' arguments >>>>> to psql.exe command. (It will redirect stderr to stdout ) >>>>> 3. Windows conPTY is available on Windows 10 only (released after >>>>> 2018). >>>>> 4. Windows conPTY does not support the Asynchronous I/O, so to get >>>>> the terminal output, need to add the read function after every command >>>>> execution. (something like select() is not available) >>>>> 5. Also found some performance issues with psql on windows. >>>>> 1. To read the output from the terminal need to add some sleep >>>>> time as it will take time to return the output. >>>>> 2. Resize the terminal is also not consistent and causing the >>>>> issue if we resize the window faster or multiple times very quickly. >>>>> 3. Loading large dataset sometimes cause system to >>>>> non-responsive state.(In this state restart requires) >>>>> >>>>> Please find the patch for disable the psql tool for windows >>>>> platform.(Windows builds are falling due to this sending patch for disable >>>>> psql on windows.) >>>>> >>>> >>>> Disabling major features on our most common deployment platform really >>>> isn't a good option. I assume all of the above options are related to lack >>>> of async I/O? >>>> >>> >>> We have temporarily disabled the feature until found a solution, to >>> generate the nightly build for testing. >>> >>>> >>>> Have you tried forcing the use of winpty rather than conpty? >>>> >>>> >>>>> >>>>> Reference links: >>>>> >>>>> 1. https://github.com/microsoft/terminal/issues/262 >>>>> 2. >>>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>>> 3. https://pypi.org/project/pywinpty/ >>>>> >>>>> >>>>> If any suggestions or questions please let me know. >>>>> >>>>> Regards, >>>>> Nikhil Mohite. >>>>> >>>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>>> [email protected]> wrote: >>>>> >>>>>> Thanks, patch applied. >>>>>> >>>>>> I have updated the screenshot and some documentation stuff. >>>>>> >>>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Akshay, >>>>>>> >>>>>>> >>>>>>> Please find the updated patch. (V6) >>>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Nikhil >>>>>>>> >>>>>>>> Please rebase and send the patch again. >>>>>>>> >>>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Akshay/ Team >>>>>>>>> >>>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Nikhil >>>>>>>>>> >>>>>>>>>> Following are the review comments: >>>>>>>>>> >>>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree >>>>>>>>>> and context menu option should not be visible. >>>>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>>>> the new PSQL button on the browser tree. >>>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>>>> - Remove commented code (if any) >>>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>>> >>>>>>>>>> Please find the updated patch, resolve all the review comments, >>>>>>>>> and update the code to resolve the SonarQube issues. >>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>>> >>>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>> >>>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. >>>>>>>>>>>>>>>> That should be pushed into the webpacked bundle I think, and not included >>>>>>>>>>>>>>>> inline in HTML. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I have moved most of the code in the js file, few things are >>>>>>>>>>>>>>> still in HTML. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the theme >>>>>>>>>>>>>> and other settings, earlier I tried with CSS to override the theme but >>>>>>>>>>>>>> couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> OK, but either way we can't hard-code styles from themes in >>>>>>>>>>>>> HTML templates for individual features; that way leads to madness. >>>>>>>>>>>>> >>>>>>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>>>>>> assistance? >>>>>>>>>>>>> >>>>>>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>>>>>> Aditya helped in this. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>>> >>>>>>>>>>>>>> I tried the default selection color from SQL for the dark and >>>>>>>>>>>> standard themes but still, it was not readable so just updated the color >>>>>>>>>>>> code with another color as follows. >>>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>>> 3. Standard: >>>>>>>>>>>> [image: image.png] >>>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I >>>>>>>>>>>>>>>> am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I noticed while I was playing with that, that you are >>>>>>>>>>>>>>> passing the password as part of the connection string. As I've mentioned in >>>>>>>>>>>>>>> the past, that is absolutely not acceptable; it will expose the password to >>>>>>>>>>>>>>> all manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> if we try to load data from the table containing millions >>>>>>>>>>>>>>>> of records, UI gets very slow. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it >>>>>>>>>>>>>>> fills up? Can you tell where the memory usage is? >>>>>>>>>>>>>>> >>>>>>>>>>>>>> I checked the psql memory consumption in terminal and pgAdmin >>>>>>>>>>>>>> psql tool memory consumption is the similar. Also tested the performance >>>>>>>>>>>>>> and query execution timing is also similar. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> In addition to the issue above, it looks like the \! >>>>>>>>>>>>>>> blocking may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we >>>>>>>>>>>>>>>>>>>> can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the >>>>>>>>>>>>>>>>>>>> child nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server >>>>>>>>>>>>>>>>>>>> name as the user can change the database/user from PSQL command, so it's >>>>>>>>>>>>>>>>>>>> been difficult to update the tab title. >>>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the user >>>>>>>>>>>>>>>>>>>> know from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed >>>>>>>>>>>>>>>>>>>> from requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in >>>>>>>>>>>>>>>>>>> dark mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that >>>>>>>>>>>>>>>>>>> shouldn't be there (debug output should go through the logger) - >>>>>>>>>>>>>>>>>>> psql/__init__.py:235 >>>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password in >>>>>>>>>>>>>>>>>>> a connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, >>>>>>>>>>>>>>>>>>> where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: >>>>>>>>>>>>>>>>>>> "ERROR: Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in >>>>>>>>>>>>>>>>>>>>>> package.json that makes it invalid. If I fix that, then I get the error >>>>>>>>>>>>>>>>>>>>>> below, so I'm guessing the intention was to actually include another >>>>>>>>>>>>>>>>>>>>>> package there? >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> ERROR in >>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>> >>>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>>> Regards, >>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> *Thanks & Regards* >>>>>>>>>> *Akshay Joshi* >>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>> >>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> *Thanks & Regards* >>>>>>>> *Akshay Joshi* >>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>> >>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> *Thanks & Regards* >>>>>> *Akshay Joshi* >>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>> >>>>>> *Mobile: +91 976-788-8246* >>>>>> >>>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> *pgAdmin Hacker | Principal Software Architect* >>> *EDB Postgres <http://edbpostgres.com>* >>> >>> *Mobile: +91 976-788-8246* >>> >> > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-07 09:04 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 0 replies; 54+ messages in thread From: Dave Page @ 2021-06-07 09:04 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> On Mon, Jun 7, 2021 at 9:45 AM Nikhil Mohite <[email protected]> wrote: > Hi Dave, > > On Mon, Jun 7, 2021 at 2:07 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Mon, Jun 7, 2021 at 6:45 AM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Team, >>> >>> Please find the updated patch for added psql tool for windows platform. >>> >> >> Cool :-). Does this fix the issues you described previously? If not, can >> you please ensure the limitations are noted in the documentation for the >> feature? >> > Yes, the issues I mentioned earlier are fixed, it is now consistent with > other supporting platforms. > Awesome! Nice work :-) > >> >>> Also fixed a few issues reported by Fahar. >>> 1. If the database name contains escape characters psql unable to >>> connect. >>> 2. If the user terminates the connection by entering "exit", psql will >>> show connection termination msg. >>> >>> >>> Regards, >>> Nikhil Mohite. >>> >>> Regards, > Nikhil Mohite > >> On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> >>>> >>>> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Team, >>>>>> >>>>>> Following are few points related to PSQL tool on windows: >>>>>> >>>>>> 1. Currently using the *pywinpty* library on windows to create >>>>>> pty process and execute the psql.exe. >>>>>> 2. To read the stderr (errors) currently using '2>>&1' arguments >>>>>> to psql.exe command. (It will redirect stderr to stdout ) >>>>>> 3. Windows conPTY is available on Windows 10 only (released after >>>>>> 2018). >>>>>> 4. Windows conPTY does not support the Asynchronous I/O, so to >>>>>> get the terminal output, need to add the read function after every command >>>>>> execution. (something like select() is not available) >>>>>> 5. Also found some performance issues with psql on windows. >>>>>> 1. To read the output from the terminal need to add some sleep >>>>>> time as it will take time to return the output. >>>>>> 2. Resize the terminal is also not consistent and causing the >>>>>> issue if we resize the window faster or multiple times very quickly. >>>>>> 3. Loading large dataset sometimes cause system to >>>>>> non-responsive state.(In this state restart requires) >>>>>> >>>>>> Please find the patch for disable the psql tool for windows >>>>>> platform.(Windows builds are falling due to this sending patch for disable >>>>>> psql on windows.) >>>>>> >>>>> >>>>> Disabling major features on our most common deployment platform really >>>>> isn't a good option. I assume all of the above options are related to lack >>>>> of async I/O? >>>>> >>>> >>>> We have temporarily disabled the feature until found a solution, to >>>> generate the nightly build for testing. >>>> >>>>> >>>>> Have you tried forcing the use of winpty rather than conpty? >>>>> >>>>> >>>>>> >>>>>> Reference links: >>>>>> >>>>>> 1. https://github.com/microsoft/terminal/issues/262 >>>>>> 2. >>>>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>>>> 3. https://pypi.org/project/pywinpty/ >>>>>> >>>>>> >>>>>> If any suggestions or questions please let me know. >>>>>> >>>>>> Regards, >>>>>> Nikhil Mohite. >>>>>> >>>>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Thanks, patch applied. >>>>>>> >>>>>>> I have updated the screenshot and some documentation stuff. >>>>>>> >>>>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Akshay, >>>>>>>> >>>>>>>> >>>>>>>> Please find the updated patch. (V6) >>>>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Nikhil >>>>>>>>> >>>>>>>>> Please rebase and send the patch again. >>>>>>>>> >>>>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Akshay/ Team >>>>>>>>>> >>>>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Nikhil >>>>>>>>>>> >>>>>>>>>>> Following are the review comments: >>>>>>>>>>> >>>>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree >>>>>>>>>>> and context menu option should not be visible. >>>>>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>>>>> the new PSQL button on the browser tree. >>>>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>>>>> - Remove commented code (if any) >>>>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>>>> >>>>>>>>>>> Please find the updated patch, resolve all the review comments, >>>>>>>>>> and update the code to resolve the SonarQube issues. >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>>>> >>>>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>> >>>>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. >>>>>>>>>>>>>>>>> That should be pushed into the webpacked bundle I think, and not included >>>>>>>>>>>>>>>>> inline in HTML. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I have moved most of the code in the js file, few things >>>>>>>>>>>>>>>> are still in HTML. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the theme >>>>>>>>>>>>>>> and other settings, earlier I tried with CSS to override the theme but >>>>>>>>>>>>>>> couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> OK, but either way we can't hard-code styles from themes in >>>>>>>>>>>>>> HTML templates for individual features; that way leads to madness. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>>>>>>> assistance? >>>>>>>>>>>>>> >>>>>>>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>>>>>>> Aditya helped in this. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I tried the default selection color from SQL for the dark >>>>>>>>>>>>> and standard themes but still, it was not readable so just updated the >>>>>>>>>>>>> color code with another color as follows. >>>>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>>>> 3. Standard: >>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I >>>>>>>>>>>>>>>>> am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I noticed while I was playing with that, that you are >>>>>>>>>>>>>>>> passing the password as part of the connection string. As I've mentioned in >>>>>>>>>>>>>>>> the past, that is absolutely not acceptable; it will expose the password to >>>>>>>>>>>>>>>> all manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> if we try to load data from the table containing millions >>>>>>>>>>>>>>>>> of records, UI gets very slow. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it >>>>>>>>>>>>>>>> fills up? Can you tell where the memory usage is? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I checked the psql memory consumption in terminal and >>>>>>>>>>>>>>> pgAdmin psql tool memory consumption is the similar. Also tested the >>>>>>>>>>>>>>> performance and query execution timing is also similar. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> In addition to the issue above, it looks like the \! >>>>>>>>>>>>>>>> blocking may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, >>>>>>>>>>>>>>>>>>>>> we can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the >>>>>>>>>>>>>>>>>>>>> child nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server >>>>>>>>>>>>>>>>>>>>> name as the user can change the database/user from PSQL command, so it's >>>>>>>>>>>>>>>>>>>>> been difficult to update the tab title. >>>>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the >>>>>>>>>>>>>>>>>>>>> user know from where the PSQL tool will open and on which node it is >>>>>>>>>>>>>>>>>>>>> applicable. >>>>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed >>>>>>>>>>>>>>>>>>>>> from requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal >>>>>>>>>>>>>>>>>>>> compatibility (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running >>>>>>>>>>>>>>>>>>>> in dark mode, and see a jet black background. I would expect to see the >>>>>>>>>>>>>>>>>>>> same background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that >>>>>>>>>>>>>>>>>>>> shouldn't be there (debug output should go through the logger) - >>>>>>>>>>>>>>>>>>>> psql/__init__.py:235 >>>>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password in >>>>>>>>>>>>>>>>>>>> a connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', >>>>>>>>>>>>>>>>>>>> '') >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the >>>>>>>>>>>>>>>>>>>> panel, where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: >>>>>>>>>>>>>>>>>>>> "ERROR: Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in >>>>>>>>>>>>>>>>>>>>>>> package.json that makes it invalid. If I fix that, then I get the error >>>>>>>>>>>>>>>>>>>>>>> below, so I'm guessing the intention was to actually include another >>>>>>>>>>>>>>>>>>>>>>> package there? >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> ERROR in >>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>> >>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> *Thanks & Regards* >>>>>>>>> *Akshay Joshi* >>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>> >>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Thanks & Regards* >>>>>>> *Akshay Joshi* >>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>> >>>>>>> *Mobile: +91 976-788-8246* >>>>>>> >>>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> *pgAdmin Hacker | Principal Software Architect* >>>> *EDB Postgres <http://edbpostgres.com>* >>>> >>>> *Mobile: +91 976-788-8246* >>>> >>> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-08 09:29 Akshay Joshi <[email protected]> parent: Nikhil Mohite <[email protected]> 1 sibling, 1 reply; 54+ messages in thread From: Akshay Joshi @ 2021-06-08 09:29 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Dave Page <[email protected]> Thanks, the patch applied. On Mon, Jun 7, 2021 at 11:15 AM Nikhil Mohite < [email protected]> wrote: > Hi Team, > > Please find the updated patch for added psql tool for windows platform. > Also fixed a few issues reported by Fahar. > 1. If the database name contains escape characters psql unable to connect. > 2. If the user terminates the connection by entering "exit", psql will > show connection termination msg. > > > Regards, > Nikhil Mohite. > > On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi <[email protected]> > wrote: > >> >> >> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Team, >>>> >>>> Following are few points related to PSQL tool on windows: >>>> >>>> 1. Currently using the *pywinpty* library on windows to create pty >>>> process and execute the psql.exe. >>>> 2. To read the stderr (errors) currently using '2>>&1' arguments to >>>> psql.exe command. (It will redirect stderr to stdout ) >>>> 3. Windows conPTY is available on Windows 10 only (released after >>>> 2018). >>>> 4. Windows conPTY does not support the Asynchronous I/O, so to get >>>> the terminal output, need to add the read function after every command >>>> execution. (something like select() is not available) >>>> 5. Also found some performance issues with psql on windows. >>>> 1. To read the output from the terminal need to add some sleep >>>> time as it will take time to return the output. >>>> 2. Resize the terminal is also not consistent and causing the >>>> issue if we resize the window faster or multiple times very quickly. >>>> 3. Loading large dataset sometimes cause system to >>>> non-responsive state.(In this state restart requires) >>>> >>>> Please find the patch for disable the psql tool for windows >>>> platform.(Windows builds are falling due to this sending patch for disable >>>> psql on windows.) >>>> >>> >>> Disabling major features on our most common deployment platform really >>> isn't a good option. I assume all of the above options are related to lack >>> of async I/O? >>> >> >> We have temporarily disabled the feature until found a solution, to >> generate the nightly build for testing. >> >>> >>> Have you tried forcing the use of winpty rather than conpty? >>> >>> >>>> >>>> Reference links: >>>> >>>> 1. https://github.com/microsoft/terminal/issues/262 >>>> 2. >>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>> 3. https://pypi.org/project/pywinpty/ >>>> >>>> >>>> If any suggestions or questions please let me know. >>>> >>>> Regards, >>>> Nikhil Mohite. >>>> >>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> Thanks, patch applied. >>>>> >>>>> I have updated the screenshot and some documentation stuff. >>>>> >>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Akshay, >>>>>> >>>>>> >>>>>> Please find the updated patch. (V6) >>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Nikhil >>>>>>> >>>>>>> Please rebase and send the patch again. >>>>>>> >>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Akshay/ Team >>>>>>>> >>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Nikhil >>>>>>>>> >>>>>>>>> Following are the review comments: >>>>>>>>> >>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree and >>>>>>>>> context menu option should not be visible. >>>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>>> the new PSQL button on the browser tree. >>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>>> - Remove commented code (if any) >>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>> >>>>>>>>> Please find the updated patch, resolve all the review comments, >>>>>>>> and update the code to resolve the SonarQube issues. >>>>>>>> >>>>>>>>> >>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>> >>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>> >>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>> >>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. >>>>>>>>>>>>>>> That should be pushed into the webpacked bundle I think, and not included >>>>>>>>>>>>>>> inline in HTML. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> I have moved most of the code in the js file, few things are >>>>>>>>>>>>>> still in HTML. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the theme >>>>>>>>>>>>> and other settings, earlier I tried with CSS to override the theme but >>>>>>>>>>>>> couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> OK, but either way we can't hard-code styles from themes in >>>>>>>>>>>> HTML templates for individual features; that way leads to madness. >>>>>>>>>>>> >>>>>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>>>>> assistance? >>>>>>>>>>>> >>>>>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>>>>> Aditya helped in this. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>> >>>>>>>>>>>>> I tried the default selection color from SQL for the dark and >>>>>>>>>>> standard themes but still, it was not readable so just updated the color >>>>>>>>>>> code with another color as follows. >>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>> 3. Standard: >>>>>>>>>>> [image: image.png] >>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I >>>>>>>>>>>>>>> am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>> >>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>> >>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>> >>>>>>>>>>>>>> I noticed while I was playing with that, that you are passing >>>>>>>>>>>>>> the password as part of the connection string. As I've mentioned in the >>>>>>>>>>>>>> past, that is absolutely not acceptable; it will expose the password to all >>>>>>>>>>>>>> manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> if we try to load data from the table containing millions of >>>>>>>>>>>>>>> records, UI gets very slow. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it fills >>>>>>>>>>>>>> up? Can you tell where the memory usage is? >>>>>>>>>>>>>> >>>>>>>>>>>>> I checked the psql memory consumption in terminal and pgAdmin >>>>>>>>>>>>> psql tool memory consumption is the similar. Also tested the performance >>>>>>>>>>>>> and query execution timing is also similar. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> In addition to the issue above, it looks like the \! blocking >>>>>>>>>>>>>> may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>> >>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>> >>>>>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we >>>>>>>>>>>>>>>>>>> can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the child >>>>>>>>>>>>>>>>>>> nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server name >>>>>>>>>>>>>>>>>>> as the user can change the database/user from PSQL command, so it's been >>>>>>>>>>>>>>>>>>> difficult to update the tab title. >>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the user >>>>>>>>>>>>>>>>>>> know from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed >>>>>>>>>>>>>>>>>>> from requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in >>>>>>>>>>>>>>>>>> dark mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that shouldn't >>>>>>>>>>>>>>>>>> be there (debug output should go through the logger) - psql/__init__.py:235 >>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password in a >>>>>>>>>>>>>>>>>> connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, >>>>>>>>>>>>>>>>>> where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: "ERROR: >>>>>>>>>>>>>>>>>> Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in package.json >>>>>>>>>>>>>>>>>>>>> that makes it invalid. If I fix that, then I get the error below, so I'm >>>>>>>>>>>>>>>>>>>>> guessing the intention was to actually include another package there? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> ERROR in ./pgadmin/tools/psql/static/js/psql_module.js >>>>>>>>>>>>>>>>>>>>> 23:50-82 >>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Regards, >>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>> >>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>> Nikhil Mohite >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> *Thanks & Regards* >>>>>>>>> *Akshay Joshi* >>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>> >>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Thanks & Regards* >>>>>>> *Akshay Joshi* >>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>> >>>>>>> *Mobile: +91 976-788-8246* >>>>>>> >>>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> *pgAdmin Hacker | Principal Software Architect* >>>>> *EDB Postgres <http://edbpostgres.com>* >>>>> >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-10 10:08 Nikhil Mohite <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-10 10:08 UTC (permalink / raw) To: pgadmin-hackers; Dave Page <[email protected]>; +Cc: Akshay Joshi <[email protected]> Hi Dave/ Team, We are facing an issue with winpty.dll on Windows server 2016 and Windows 7(these are platforms on which we have tested). Files required for winpty are present in the site-packages but still, it is unable to load the winpty.dll file on these specific platforms. We have tested it on Windows 10 pro and Windows server 2019 and it is working fine. (Also tried building the local pywinpty but unable to build it.) ref link for winPty https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... Until we found the solution we can do the following solution for this. 1. We can add check if specific windows platform is not supporting winpty, show error msg when user open psql tool [image: image.png] 2. Diable the psql on these platforms by setting ENABLE_PSQL=False. If anyone has any other solution please let me know. Regards, Nikhil Mohite. On Tue, Jun 8, 2021 at 2:59 PM Akshay Joshi <[email protected]> wrote: > Thanks, the patch applied. > > On Mon, Jun 7, 2021 at 11:15 AM Nikhil Mohite < > [email protected]> wrote: > >> Hi Team, >> >> Please find the updated patch for added psql tool for windows platform. >> Also fixed a few issues reported by Fahar. >> 1. If the database name contains escape characters psql unable to connect. >> 2. If the user terminates the connection by entering "exit", psql will >> show connection termination msg. >> >> >> Regards, >> Nikhil Mohite. >> >> On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi < >> [email protected]> wrote: >> >>> >>> >>> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Team, >>>>> >>>>> Following are few points related to PSQL tool on windows: >>>>> >>>>> 1. Currently using the *pywinpty* library on windows to create >>>>> pty process and execute the psql.exe. >>>>> 2. To read the stderr (errors) currently using '2>>&1' arguments >>>>> to psql.exe command. (It will redirect stderr to stdout ) >>>>> 3. Windows conPTY is available on Windows 10 only (released after >>>>> 2018). >>>>> 4. Windows conPTY does not support the Asynchronous I/O, so to get >>>>> the terminal output, need to add the read function after every command >>>>> execution. (something like select() is not available) >>>>> 5. Also found some performance issues with psql on windows. >>>>> 1. To read the output from the terminal need to add some sleep >>>>> time as it will take time to return the output. >>>>> 2. Resize the terminal is also not consistent and causing the >>>>> issue if we resize the window faster or multiple times very quickly. >>>>> 3. Loading large dataset sometimes cause system to >>>>> non-responsive state.(In this state restart requires) >>>>> >>>>> Please find the patch for disable the psql tool for windows >>>>> platform.(Windows builds are falling due to this sending patch for disable >>>>> psql on windows.) >>>>> >>>> >>>> Disabling major features on our most common deployment platform really >>>> isn't a good option. I assume all of the above options are related to lack >>>> of async I/O? >>>> >>> >>> We have temporarily disabled the feature until found a solution, to >>> generate the nightly build for testing. >>> >>>> >>>> Have you tried forcing the use of winpty rather than conpty? >>>> >>>> >>>>> >>>>> Reference links: >>>>> >>>>> 1. https://github.com/microsoft/terminal/issues/262 >>>>> 2. >>>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>>> 3. https://pypi.org/project/pywinpty/ >>>>> >>>>> >>>>> If any suggestions or questions please let me know. >>>>> >>>>> Regards, >>>>> Nikhil Mohite. >>>>> >>>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>>> [email protected]> wrote: >>>>> >>>>>> Thanks, patch applied. >>>>>> >>>>>> I have updated the screenshot and some documentation stuff. >>>>>> >>>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Akshay, >>>>>>> >>>>>>> >>>>>>> Please find the updated patch. (V6) >>>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Nikhil >>>>>>>> >>>>>>>> Please rebase and send the patch again. >>>>>>>> >>>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Akshay/ Team >>>>>>>>> >>>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Nikhil >>>>>>>>>> >>>>>>>>>> Following are the review comments: >>>>>>>>>> >>>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree >>>>>>>>>> and context menu option should not be visible. >>>>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>>>> the new PSQL button on the browser tree. >>>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>>>> - Remove commented code (if any) >>>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>>> >>>>>>>>>> Please find the updated patch, resolve all the review comments, >>>>>>>>> and update the code to resolve the SonarQube issues. >>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>>> >>>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>> >>>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. >>>>>>>>>>>>>>>> That should be pushed into the webpacked bundle I think, and not included >>>>>>>>>>>>>>>> inline in HTML. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I have moved most of the code in the js file, few things are >>>>>>>>>>>>>>> still in HTML. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the theme >>>>>>>>>>>>>> and other settings, earlier I tried with CSS to override the theme but >>>>>>>>>>>>>> couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> OK, but either way we can't hard-code styles from themes in >>>>>>>>>>>>> HTML templates for individual features; that way leads to madness. >>>>>>>>>>>>> >>>>>>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>>>>>> assistance? >>>>>>>>>>>>> >>>>>>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>>>>>> Aditya helped in this. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>>> >>>>>>>>>>>>>> I tried the default selection color from SQL for the dark and >>>>>>>>>>>> standard themes but still, it was not readable so just updated the color >>>>>>>>>>>> code with another color as follows. >>>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>>> 3. Standard: >>>>>>>>>>>> [image: image.png] >>>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I >>>>>>>>>>>>>>>> am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I noticed while I was playing with that, that you are >>>>>>>>>>>>>>> passing the password as part of the connection string. As I've mentioned in >>>>>>>>>>>>>>> the past, that is absolutely not acceptable; it will expose the password to >>>>>>>>>>>>>>> all manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> if we try to load data from the table containing millions >>>>>>>>>>>>>>>> of records, UI gets very slow. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it >>>>>>>>>>>>>>> fills up? Can you tell where the memory usage is? >>>>>>>>>>>>>>> >>>>>>>>>>>>>> I checked the psql memory consumption in terminal and pgAdmin >>>>>>>>>>>>>> psql tool memory consumption is the similar. Also tested the performance >>>>>>>>>>>>>> and query execution timing is also similar. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> In addition to the issue above, it looks like the \! >>>>>>>>>>>>>>> blocking may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, we >>>>>>>>>>>>>>>>>>>> can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the >>>>>>>>>>>>>>>>>>>> child nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server >>>>>>>>>>>>>>>>>>>> name as the user can change the database/user from PSQL command, so it's >>>>>>>>>>>>>>>>>>>> been difficult to update the tab title. >>>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the user >>>>>>>>>>>>>>>>>>>> know from where the PSQL tool will open and on which node it is applicable. >>>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed >>>>>>>>>>>>>>>>>>>> from requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal compatibility >>>>>>>>>>>>>>>>>>> (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running in >>>>>>>>>>>>>>>>>>> dark mode, and see a jet black background. I would expect to see the same >>>>>>>>>>>>>>>>>>> background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that >>>>>>>>>>>>>>>>>>> shouldn't be there (debug output should go through the logger) - >>>>>>>>>>>>>>>>>>> psql/__init__.py:235 >>>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password in >>>>>>>>>>>>>>>>>>> a connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the panel, >>>>>>>>>>>>>>>>>>> where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: >>>>>>>>>>>>>>>>>>> "ERROR: Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in >>>>>>>>>>>>>>>>>>>>>> package.json that makes it invalid. If I fix that, then I get the error >>>>>>>>>>>>>>>>>>>>>> below, so I'm guessing the intention was to actually include another >>>>>>>>>>>>>>>>>>>>>> package there? >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> ERROR in >>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid alias >>>>>>>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>> >>>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>>> Regards, >>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> *Thanks & Regards* >>>>>>>>>> *Akshay Joshi* >>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>> >>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> *Thanks & Regards* >>>>>>>> *Akshay Joshi* >>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>> >>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> *Thanks & Regards* >>>>>> *Akshay Joshi* >>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>> >>>>>> *Mobile: +91 976-788-8246* >>>>>> >>>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> *pgAdmin Hacker | Principal Software Architect* >>> *EDB Postgres <http://edbpostgres.com>* >>> >>> *Mobile: +91 976-788-8246* >>> >> > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [image/png] image.png (36.9K, 6-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-10 11:52 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-10 11:52 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> Hi On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < [email protected]> wrote: > Hi Dave/ Team, > > We are facing an issue with winpty.dll on Windows server 2016 and Windows > 7(these are platforms on which we have tested). > Files required for winpty are present in the site-packages but still, it > is unable to load the winpty.dll file on these specific platforms. We have > tested it on Windows 10 pro and Windows server 2019 and it is working fine. > (Also tried building the local pywinpty but unable to build it.) ref link > for winPty > https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... > Does winpty.exe run, if executed from the command line instead of pgAdmin? If not, does dependency walker show any missing libraries that are required? > > Until we found the solution we can do the following solution for this. > 1. We can add check if specific windows platform is not supporting winpty, > show error msg when user open psql tool > [image: image.png] > 2. Diable the psql on these platforms by setting ENABLE_PSQL=False. > > > If anyone has any other solution please let me know. > > Regards, > Nikhil Mohite. > > On Tue, Jun 8, 2021 at 2:59 PM Akshay Joshi <[email protected]> > wrote: > >> Thanks, the patch applied. >> >> On Mon, Jun 7, 2021 at 11:15 AM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Team, >>> >>> Please find the updated patch for added psql tool for windows platform. >>> Also fixed a few issues reported by Fahar. >>> 1. If the database name contains escape characters psql unable to >>> connect. >>> 2. If the user terminates the connection by entering "exit", psql will >>> show connection termination msg. >>> >>> >>> Regards, >>> Nikhil Mohite. >>> >>> On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> >>>> >>>> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Team, >>>>>> >>>>>> Following are few points related to PSQL tool on windows: >>>>>> >>>>>> 1. Currently using the *pywinpty* library on windows to create >>>>>> pty process and execute the psql.exe. >>>>>> 2. To read the stderr (errors) currently using '2>>&1' arguments >>>>>> to psql.exe command. (It will redirect stderr to stdout ) >>>>>> 3. Windows conPTY is available on Windows 10 only (released after >>>>>> 2018). >>>>>> 4. Windows conPTY does not support the Asynchronous I/O, so to >>>>>> get the terminal output, need to add the read function after every command >>>>>> execution. (something like select() is not available) >>>>>> 5. Also found some performance issues with psql on windows. >>>>>> 1. To read the output from the terminal need to add some sleep >>>>>> time as it will take time to return the output. >>>>>> 2. Resize the terminal is also not consistent and causing the >>>>>> issue if we resize the window faster or multiple times very quickly. >>>>>> 3. Loading large dataset sometimes cause system to >>>>>> non-responsive state.(In this state restart requires) >>>>>> >>>>>> Please find the patch for disable the psql tool for windows >>>>>> platform.(Windows builds are falling due to this sending patch for disable >>>>>> psql on windows.) >>>>>> >>>>> >>>>> Disabling major features on our most common deployment platform really >>>>> isn't a good option. I assume all of the above options are related to lack >>>>> of async I/O? >>>>> >>>> >>>> We have temporarily disabled the feature until found a solution, to >>>> generate the nightly build for testing. >>>> >>>>> >>>>> Have you tried forcing the use of winpty rather than conpty? >>>>> >>>>> >>>>>> >>>>>> Reference links: >>>>>> >>>>>> 1. https://github.com/microsoft/terminal/issues/262 >>>>>> 2. >>>>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>>>> 3. https://pypi.org/project/pywinpty/ >>>>>> >>>>>> >>>>>> If any suggestions or questions please let me know. >>>>>> >>>>>> Regards, >>>>>> Nikhil Mohite. >>>>>> >>>>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Thanks, patch applied. >>>>>>> >>>>>>> I have updated the screenshot and some documentation stuff. >>>>>>> >>>>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Akshay, >>>>>>>> >>>>>>>> >>>>>>>> Please find the updated patch. (V6) >>>>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Nikhil >>>>>>>>> >>>>>>>>> Please rebase and send the patch again. >>>>>>>>> >>>>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Akshay/ Team >>>>>>>>>> >>>>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Nikhil >>>>>>>>>>> >>>>>>>>>>> Following are the review comments: >>>>>>>>>>> >>>>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree >>>>>>>>>>> and context menu option should not be visible. >>>>>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>>>>> the new PSQL button on the browser tree. >>>>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>>>>> - Remove commented code (if any) >>>>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>>>> >>>>>>>>>>> Please find the updated patch, resolve all the review comments, >>>>>>>>>> and update the code to resolve the SonarQube issues. >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>>>> >>>>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>> >>>>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML file. >>>>>>>>>>>>>>>>> That should be pushed into the webpacked bundle I think, and not included >>>>>>>>>>>>>>>>> inline in HTML. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I have moved most of the code in the js file, few things >>>>>>>>>>>>>>>> are still in HTML. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the theme >>>>>>>>>>>>>>> and other settings, earlier I tried with CSS to override the theme but >>>>>>>>>>>>>>> couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> OK, but either way we can't hard-code styles from themes in >>>>>>>>>>>>>> HTML templates for individual features; that way leads to madness. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Perhaps Aditya or one of the other team members can give some >>>>>>>>>>>>>> assistance? >>>>>>>>>>>>>> >>>>>>>>>>>>> I have moved the color settings to the respective theme files. >>>>>>>>>>>>> Aditya helped in this. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Speaking of themes, the background colour for selected text >>>>>>>>>>>>>>>> doesn't seem right (it's barely visible) in the dark theme. Can you fix >>>>>>>>>>>>>>>> that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I tried the default selection color from SQL for the dark >>>>>>>>>>>>> and standard themes but still, it was not readable so just updated the >>>>>>>>>>>>> color code with another color as follows. >>>>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>>>> 3. Standard: >>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal (I >>>>>>>>>>>>>>>>> am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I noticed while I was playing with that, that you are >>>>>>>>>>>>>>>> passing the password as part of the connection string. As I've mentioned in >>>>>>>>>>>>>>>> the past, that is absolutely not acceptable; it will expose the password to >>>>>>>>>>>>>>>> all manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> if we try to load data from the table containing millions >>>>>>>>>>>>>>>>> of records, UI gets very slow. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it >>>>>>>>>>>>>>>> fills up? Can you tell where the memory usage is? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I checked the psql memory consumption in terminal and >>>>>>>>>>>>>>> pgAdmin psql tool memory consumption is the similar. Also tested the >>>>>>>>>>>>>>> performance and query execution timing is also similar. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> In addition to the issue above, it looks like the \! >>>>>>>>>>>>>>>> blocking may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Fixed the issue now it is consistent with the psql terminal. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, >>>>>>>>>>>>>>>>>>>>> we can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the >>>>>>>>>>>>>>>>>>>>> child nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server >>>>>>>>>>>>>>>>>>>>> name as the user can change the database/user from PSQL command, so it's >>>>>>>>>>>>>>>>>>>>> been difficult to update the tab title. >>>>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the >>>>>>>>>>>>>>>>>>>>> user know from where the PSQL tool will open and on which node it is >>>>>>>>>>>>>>>>>>>>> applicable. >>>>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be removed >>>>>>>>>>>>>>>>>>>>> from requirements.txt and also remove the import statement from pgAdmin4.py >>>>>>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal >>>>>>>>>>>>>>>>>>>> compatibility (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running >>>>>>>>>>>>>>>>>>>> in dark mode, and see a jet black background. I would expect to see the >>>>>>>>>>>>>>>>>>>> same background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that >>>>>>>>>>>>>>>>>>>> shouldn't be there (debug output should go through the logger) - >>>>>>>>>>>>>>>>>>>> psql/__init__.py:235 >>>>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password in >>>>>>>>>>>>>>>>>>>> a connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', >>>>>>>>>>>>>>>>>>>> '') >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the >>>>>>>>>>>>>>>>>>>> panel, where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: >>>>>>>>>>>>>>>>>>>> "ERROR: Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, while >>>>>>>>>>>>>>>>>>>>>> cleanup I removed the unwanted libraries but forgot to remove the code >>>>>>>>>>>>>>>>>>>>>> related to them. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in >>>>>>>>>>>>>>>>>>>>>>> package.json that makes it invalid. If I fix that, then I get the error >>>>>>>>>>>>>>>>>>>>>>> below, so I'm guessing the intention was to actually include another >>>>>>>>>>>>>>>>>>>>>>> package there? >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> ERROR in >>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>> >>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> *Thanks & Regards* >>>>>>>>> *Akshay Joshi* >>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>> >>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Thanks & Regards* >>>>>>> *Akshay Joshi* >>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>> >>>>>>> *Mobile: +91 976-788-8246* >>>>>>> >>>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> *pgAdmin Hacker | Principal Software Architect* >>>> *EDB Postgres <http://edbpostgres.com>* >>>> >>>> *Mobile: +91 976-788-8246* >>>> >>> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [image/png] image.png (36.9K, 6-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-10 13:00 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-10 13:00 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> Hi Dave, On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: > Hi > > On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < > [email protected]> wrote: > >> Hi Dave/ Team, >> >> We are facing an issue with winpty.dll on Windows server 2016 and Windows >> 7(these are platforms on which we have tested). >> Files required for winpty are present in the site-packages but still, it >> is unable to load the winpty.dll file on these specific platforms. We have >> tested it on Windows 10 pro and Windows server 2019 and it is working fine. >> (Also tried building the local pywinpty but unable to build it.) ref link >> for winPty >> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >> > > Does winpty.exe run, if executed from the command line instead of pgAdmin? > If not, does dependency walker show any missing libraries that are required? > Not found the winpty.exe in site packages, but as per the winpty documents "winpty-agent.exe" will start the process with a new, hidden console window. It is not showing any error while installing the package. I tried to use it outside the pgAdmin but still facing the same error "Exception in import winpty DLL load failed while importing winpty: The specified procedure could not be found."(created a separate python environment for this) 1. if try to run winpty-agent.exe from the command line, it shows the user entered inputs on the same terminal, not showing any errors. [image: image.png] 2. I found winpty.exe in the other installed app (Git command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through the command line not getting any error, it is showing user entered inputs on the same terminal. (It is not related to pgAdmin but just tried to check winpty.exe throwing any error or not) [image: image.png] > >> >> Until we found the solution we can do the following solution for this. >> 1. We can add check if specific windows platform is not supporting >> winpty, show error msg when user open psql tool >> [image: image.png] >> 2. Diable the psql on these platforms by setting ENABLE_PSQL=False. >> >> >> If anyone has any other solution please let me know. >> >> Regards, >> Nikhil Mohite. >> >> On Tue, Jun 8, 2021 at 2:59 PM Akshay Joshi < >> [email protected]> wrote: >> >>> Thanks, the patch applied. >>> >>> On Mon, Jun 7, 2021 at 11:15 AM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Team, >>>> >>>> Please find the updated patch for added psql tool for windows platform. >>>> Also fixed a few issues reported by Fahar. >>>> 1. If the database name contains escape characters psql unable to >>>> connect. >>>> 2. If the user terminates the connection by entering "exit", psql will >>>> show connection termination msg. >>>> >>>> >>>> Regards, >>>> Nikhil Mohite. >>>> >>>> On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> >>>>> >>>>> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Team, >>>>>>> >>>>>>> Following are few points related to PSQL tool on windows: >>>>>>> >>>>>>> 1. Currently using the *pywinpty* library on windows to create >>>>>>> pty process and execute the psql.exe. >>>>>>> 2. To read the stderr (errors) currently using '2>>&1' arguments >>>>>>> to psql.exe command. (It will redirect stderr to stdout ) >>>>>>> 3. Windows conPTY is available on Windows 10 only (released >>>>>>> after 2018). >>>>>>> 4. Windows conPTY does not support the Asynchronous I/O, so to >>>>>>> get the terminal output, need to add the read function after every command >>>>>>> execution. (something like select() is not available) >>>>>>> 5. Also found some performance issues with psql on windows. >>>>>>> 1. To read the output from the terminal need to add some >>>>>>> sleep time as it will take time to return the output. >>>>>>> 2. Resize the terminal is also not consistent and causing the >>>>>>> issue if we resize the window faster or multiple times very quickly. >>>>>>> 3. Loading large dataset sometimes cause system to >>>>>>> non-responsive state.(In this state restart requires) >>>>>>> >>>>>>> Please find the patch for disable the psql tool for windows >>>>>>> platform.(Windows builds are falling due to this sending patch for disable >>>>>>> psql on windows.) >>>>>>> >>>>>> >>>>>> Disabling major features on our most common deployment platform >>>>>> really isn't a good option. I assume all of the above options are related >>>>>> to lack of async I/O? >>>>>> >>>>> >>>>> We have temporarily disabled the feature until found a solution, >>>>> to generate the nightly build for testing. >>>>> >>>>>> >>>>>> Have you tried forcing the use of winpty rather than conpty? >>>>>> >>>>>> >>>>>>> >>>>>>> Reference links: >>>>>>> >>>>>>> 1. https://github.com/microsoft/terminal/issues/262 >>>>>>> 2. >>>>>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>>>>> 3. https://pypi.org/project/pywinpty/ >>>>>>> >>>>>>> >>>>>>> If any suggestions or questions please let me know. >>>>>>> >>>>>>> Regards, >>>>>>> Nikhil Mohite. >>>>>>> >>>>>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Thanks, patch applied. >>>>>>>> >>>>>>>> I have updated the screenshot and some documentation stuff. >>>>>>>> >>>>>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Akshay, >>>>>>>>> >>>>>>>>> >>>>>>>>> Please find the updated patch. (V6) >>>>>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Nikhil >>>>>>>>>> >>>>>>>>>> Please rebase and send the patch again. >>>>>>>>>> >>>>>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Akshay/ Team >>>>>>>>>>> >>>>>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>> >>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>> >>>>>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree >>>>>>>>>>>> and context menu option should not be visible. >>>>>>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>>>>>> the new PSQL button on the browser tree. >>>>>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>>>>>> - Remove commented code (if any) >>>>>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>>>>> >>>>>>>>>>>> Please find the updated patch, resolve all the review comments, >>>>>>>>>>> and update the code to resolve the SonarQube issues. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>>>>> >>>>>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Please find the attached updated patch for the psql tool. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML >>>>>>>>>>>>>>>>>> file. That should be pushed into the webpacked bundle I think, and not >>>>>>>>>>>>>>>>>> included inline in HTML. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I have moved most of the code in the js file, few things >>>>>>>>>>>>>>>>> are still in HTML. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hmm, yes - in particular, colours for the different themes. >>>>>>>>>>>>>>>> Please move them into the css for the themes. You have a mix of style, >>>>>>>>>>>>>>>> layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the >>>>>>>>>>>>>>>> theme and other settings, earlier I tried with CSS to override the theme >>>>>>>>>>>>>>>> but couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> OK, but either way we can't hard-code styles from themes in >>>>>>>>>>>>>>> HTML templates for individual features; that way leads to madness. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Perhaps Aditya or one of the other team members can give >>>>>>>>>>>>>>> some assistance? >>>>>>>>>>>>>>> >>>>>>>>>>>>>> I have moved the color settings to the respective theme >>>>>>>>>>>>>> files. Aditya helped in this. >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Speaking of themes, the background colour for selected >>>>>>>>>>>>>>>>> text doesn't seem right (it's barely visible) in the dark theme. Can you >>>>>>>>>>>>>>>>> fix that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I tried the default selection color from SQL for the dark >>>>>>>>>>>>>> and standard themes but still, it was not readable so just updated the >>>>>>>>>>>>>> color code with another color as follows. >>>>>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>>>>> 3. Standard: >>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal >>>>>>>>>>>>>>>>>> (I am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I noticed while I was playing with that, that you are >>>>>>>>>>>>>>>>> passing the password as part of the connection string. As I've mentioned in >>>>>>>>>>>>>>>>> the past, that is absolutely not acceptable; it will expose the password to >>>>>>>>>>>>>>>>> all manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> if we try to load data from the table containing millions >>>>>>>>>>>>>>>>>> of records, UI gets very slow. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it >>>>>>>>>>>>>>>>> fills up? Can you tell where the memory usage is? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I checked the psql memory consumption in terminal and >>>>>>>>>>>>>>>> pgAdmin psql tool memory consumption is the similar. Also tested the >>>>>>>>>>>>>>>> performance and query execution timing is also similar. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> In addition to the issue above, it looks like the \! >>>>>>>>>>>>>>>>> blocking may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Fixed the issue now it is consistent with the psql >>>>>>>>>>>>>> terminal. >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, >>>>>>>>>>>>>>>>>>>>>> we can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the >>>>>>>>>>>>>>>>>>>>>> child nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server >>>>>>>>>>>>>>>>>>>>>> name as the user can change the database/user from PSQL command, so it's >>>>>>>>>>>>>>>>>>>>>> been difficult to update the tab title. >>>>>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt and >>>>>>>>>>>>>>>>>>>>>> package.json >>>>>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the >>>>>>>>>>>>>>>>>>>>>> user know from where the PSQL tool will open and on which node it is >>>>>>>>>>>>>>>>>>>>>> applicable. >>>>>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many unused >>>>>>>>>>>>>>>>>>>>>> imports please remove them. >>>>>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be >>>>>>>>>>>>>>>>>>>>>> removed from requirements.txt and also remove the import statement from >>>>>>>>>>>>>>>>>>>>>> pgAdmin4.py >>>>>>>>>>>>>>>>>>>>>> - Test cases are showing successful but actually, >>>>>>>>>>>>>>>>>>>>>> there are some routing errors please check. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal >>>>>>>>>>>>>>>>>>>>> compatibility (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running >>>>>>>>>>>>>>>>>>>>> in dark mode, and see a jet black background. I would expect to see the >>>>>>>>>>>>>>>>>>>>> same background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that >>>>>>>>>>>>>>>>>>>>> shouldn't be there (debug output should go through the logger) - >>>>>>>>>>>>>>>>>>>>> psql/__init__.py:235 >>>>>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password >>>>>>>>>>>>>>>>>>>>> in a connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', >>>>>>>>>>>>>>>>>>>>> '') >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the >>>>>>>>>>>>>>>>>>>>> panel, where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: >>>>>>>>>>>>>>>>>>>>> "ERROR: Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, >>>>>>>>>>>>>>>>>>>>>>> while cleanup I removed the unwanted libraries but forgot to remove the >>>>>>>>>>>>>>>>>>>>>>> code related to them. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in >>>>>>>>>>>>>>>>>>>>>>>> package.json that makes it invalid. If I fix that, then I get the error >>>>>>>>>>>>>>>>>>>>>>>> below, so I'm guessing the intention was to actually include another >>>>>>>>>>>>>>>>>>>>>>>> package there? >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> ERROR in >>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with 1 >>>>>>>>>>>>>>>>>>>>>>>> error in 60041 ms >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>> >>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> *Thanks & Regards* >>>>>>>>>> *Akshay Joshi* >>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>> >>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> *Thanks & Regards* >>>>>>>> *Akshay Joshi* >>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>> >>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> *pgAdmin Hacker | Principal Software Architect* >>>>> *EDB Postgres <http://edbpostgres.com>* >>>>> >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> *pgAdmin Hacker | Principal Software Architect* >>> *EDB Postgres <http://edbpostgres.com>* >>> >>> *Mobile: +91 976-788-8246* >>> >> > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > Regards, Nikhil Mohite Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [image/png] image.png (36.9K, 6-image.png) download | view image [image/png] image.png (42.2K, 7-image.png) download | view image [image/png] image.png (26.6K, 8-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-10 13:07 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-10 13:07 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> Hi On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < [email protected]> wrote: > Hi Dave, > > On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Dave/ Team, >>> >>> We are facing an issue with winpty.dll on Windows server 2016 and >>> Windows 7(these are platforms on which we have tested). >>> Files required for winpty are present in the site-packages but still, it >>> is unable to load the winpty.dll file on these specific platforms. We have >>> tested it on Windows 10 pro and Windows server 2019 and it is working fine. >>> (Also tried building the local pywinpty but unable to build it.) ref link >>> for winPty >>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>> >> >> Does winpty.exe run, if executed from the command line instead of >> pgAdmin? If not, does dependency walker show any missing libraries that are >> required? >> > Not found the winpty.exe in site packages, but as per the winpty documents > "winpty-agent.exe" will start the process with a new, hidden console > window. It is not showing any error while installing the package. I tried > to use it outside the pgAdmin but still facing the same error "Exception in > import winpty DLL load failed while importing winpty: The specified > procedure could not be found."(created a separate python environment for > this) > > 1. if try to run winpty-agent.exe from the command line, it shows the user > entered inputs on the same terminal, not showing any errors. > [image: image.png] > > 2. I found winpty.exe in the other installed app (Git command line: > C:\Program Files (x86)\Git\usr\bin) if try to run it through the command > line not getting any error, it is showing user entered inputs on the same > terminal. (It is not related to pgAdmin but just tried to check winpty.exe > throwing any error or not) > [image: image.png] > Hmmm, that sounds oddly similar to an issue I had with Kerberos on Windows when I was mucking around with that. I can't remember the exact details, but as a test, does the problem go away if winpty.dll is copied into the Windows system32 directory? > > > >> >>> >>> Until we found the solution we can do the following solution for this. >>> 1. We can add check if specific windows platform is not supporting >>> winpty, show error msg when user open psql tool >>> [image: image.png] >>> 2. Diable the psql on these platforms by setting ENABLE_PSQL=False. >>> >>> >>> If anyone has any other solution please let me know. >>> >>> Regards, >>> Nikhil Mohite. >>> >>> On Tue, Jun 8, 2021 at 2:59 PM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> Thanks, the patch applied. >>>> >>>> On Mon, Jun 7, 2021 at 11:15 AM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Team, >>>>> >>>>> Please find the updated patch for added psql tool for windows platform. >>>>> Also fixed a few issues reported by Fahar. >>>>> 1. If the database name contains escape characters psql unable to >>>>> connect. >>>>> 2. If the user terminates the connection by entering "exit", psql will >>>>> show connection termination msg. >>>>> >>>>> >>>>> Regards, >>>>> Nikhil Mohite. >>>>> >>>>> On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi < >>>>> [email protected]> wrote: >>>>> >>>>>> >>>>>> >>>>>> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Team, >>>>>>>> >>>>>>>> Following are few points related to PSQL tool on windows: >>>>>>>> >>>>>>>> 1. Currently using the *pywinpty* library on windows to create >>>>>>>> pty process and execute the psql.exe. >>>>>>>> 2. To read the stderr (errors) currently using '2>>&1' >>>>>>>> arguments to psql.exe command. (It will redirect stderr to stdout ) >>>>>>>> 3. Windows conPTY is available on Windows 10 only (released >>>>>>>> after 2018). >>>>>>>> 4. Windows conPTY does not support the Asynchronous I/O, so to >>>>>>>> get the terminal output, need to add the read function after every command >>>>>>>> execution. (something like select() is not available) >>>>>>>> 5. Also found some performance issues with psql on windows. >>>>>>>> 1. To read the output from the terminal need to add some >>>>>>>> sleep time as it will take time to return the output. >>>>>>>> 2. Resize the terminal is also not consistent and causing >>>>>>>> the issue if we resize the window faster or multiple times very quickly. >>>>>>>> 3. Loading large dataset sometimes cause system to >>>>>>>> non-responsive state.(In this state restart requires) >>>>>>>> >>>>>>>> Please find the patch for disable the psql tool for windows >>>>>>>> platform.(Windows builds are falling due to this sending patch for disable >>>>>>>> psql on windows.) >>>>>>>> >>>>>>> >>>>>>> Disabling major features on our most common deployment platform >>>>>>> really isn't a good option. I assume all of the above options are related >>>>>>> to lack of async I/O? >>>>>>> >>>>>> >>>>>> We have temporarily disabled the feature until found a solution, >>>>>> to generate the nightly build for testing. >>>>>> >>>>>>> >>>>>>> Have you tried forcing the use of winpty rather than conpty? >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> Reference links: >>>>>>>> >>>>>>>> 1. https://github.com/microsoft/terminal/issues/262 >>>>>>>> 2. >>>>>>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>>>>>> 3. https://pypi.org/project/pywinpty/ >>>>>>>> >>>>>>>> >>>>>>>> If any suggestions or questions please let me know. >>>>>>>> >>>>>>>> Regards, >>>>>>>> Nikhil Mohite. >>>>>>>> >>>>>>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Thanks, patch applied. >>>>>>>>> >>>>>>>>> I have updated the screenshot and some documentation stuff. >>>>>>>>> >>>>>>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Akshay, >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Please find the updated patch. (V6) >>>>>>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Nikhil >>>>>>>>>>> >>>>>>>>>>> Please rebase and send the patch again. >>>>>>>>>>> >>>>>>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Akshay/ Team >>>>>>>>>>>> >>>>>>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>> >>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>> >>>>>>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser tree >>>>>>>>>>>>> and context menu option should not be visible. >>>>>>>>>>>>> - Documentation screenshot should be in standard theme for >>>>>>>>>>>>> consistency, and check the size it's very large. Take the screenshot with >>>>>>>>>>>>> the new PSQL button on the browser tree. >>>>>>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new changes. >>>>>>>>>>>>> - Remove commented code (if any) >>>>>>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>>>>>> >>>>>>>>>>>>> Please find the updated patch, resolve all the review >>>>>>>>>>>> comments, and update the code to resolve the SonarQube issues. >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Please find the attached updated patch for the psql >>>>>>>>>>>>>>>>>>>> tool. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML >>>>>>>>>>>>>>>>>>> file. That should be pushed into the webpacked bundle I think, and not >>>>>>>>>>>>>>>>>>> included inline in HTML. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> I have moved most of the code in the js file, few things >>>>>>>>>>>>>>>>>> are still in HTML. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hmm, yes - in particular, colours for the different >>>>>>>>>>>>>>>>> themes. Please move them into the css for the themes. You have a mix of >>>>>>>>>>>>>>>>> style, layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the >>>>>>>>>>>>>>>>> theme and other settings, earlier I tried with CSS to override the theme >>>>>>>>>>>>>>>>> but couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> OK, but either way we can't hard-code styles from themes in >>>>>>>>>>>>>>>> HTML templates for individual features; that way leads to madness. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Perhaps Aditya or one of the other team members can give >>>>>>>>>>>>>>>> some assistance? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I have moved the color settings to the respective theme >>>>>>>>>>>>>>> files. Aditya helped in this. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Speaking of themes, the background colour for selected >>>>>>>>>>>>>>>>>> text doesn't seem right (it's barely visible) in the dark theme. Can you >>>>>>>>>>>>>>>>>> fix that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I tried the default selection color from SQL for the dark >>>>>>>>>>>>>>> and standard themes but still, it was not readable so just updated the >>>>>>>>>>>>>>> color code with another color as follows. >>>>>>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>>>>>> 3. Standard: >>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal >>>>>>>>>>>>>>>>>>> (I am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> I noticed while I was playing with that, that you are >>>>>>>>>>>>>>>>>> passing the password as part of the connection string. As I've mentioned in >>>>>>>>>>>>>>>>>> the past, that is absolutely not acceptable; it will expose the password to >>>>>>>>>>>>>>>>>> all manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> if we try to load data from the table containing >>>>>>>>>>>>>>>>>>> millions of records, UI gets very slow. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Removed the password from the connection string and added >>>>>>>>>>>>>>> 'PGPASSWORD' in the environment. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it >>>>>>>>>>>>>>>>>> fills up? Can you tell where the memory usage is? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I checked the psql memory consumption in terminal and >>>>>>>>>>>>>>>>> pgAdmin psql tool memory consumption is the similar. Also tested the >>>>>>>>>>>>>>>>> performance and query execution timing is also similar. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed a >>>>>>>>>>>>>>>>>>>> message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> In addition to the issue above, it looks like the \! >>>>>>>>>>>>>>>>>> blocking may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Fixed the issue now it is consistent with the psql >>>>>>>>>>>>>>> terminal. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query tool, >>>>>>>>>>>>>>>>>>>>>>> we can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the >>>>>>>>>>>>>>>>>>>>>>> child nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server >>>>>>>>>>>>>>>>>>>>>>> name as the user can change the database/user from PSQL command, so it's >>>>>>>>>>>>>>>>>>>>>>> been difficult to update the tab title. >>>>>>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt >>>>>>>>>>>>>>>>>>>>>>> and package.json >>>>>>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the >>>>>>>>>>>>>>>>>>>>>>> user know from where the PSQL tool will open and on which node it is >>>>>>>>>>>>>>>>>>>>>>> applicable. >>>>>>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many >>>>>>>>>>>>>>>>>>>>>>> unused imports please remove them. >>>>>>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be >>>>>>>>>>>>>>>>>>>>>>> removed from requirements.txt and also remove the import statement from >>>>>>>>>>>>>>>>>>>>>>> pgAdmin4.py >>>>>>>>>>>>>>>>>>>>>>> - Test cases are showing successful but >>>>>>>>>>>>>>>>>>>>>>> actually, there are some routing errors please check. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal >>>>>>>>>>>>>>>>>>>>>> compatibility (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm running >>>>>>>>>>>>>>>>>>>>>> in dark mode, and see a jet black background. I would expect to see the >>>>>>>>>>>>>>>>>>>>>> same background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that >>>>>>>>>>>>>>>>>>>>>> shouldn't be there (debug output should go through the logger) - >>>>>>>>>>>>>>>>>>>>>> psql/__init__.py:235 >>>>>>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password >>>>>>>>>>>>>>>>>>>>>> in a connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>>>>>> conn_attr = conn_attr.replace('password=xxx', >>>>>>>>>>>>>>>>>>>>>> '') >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the >>>>>>>>>>>>>>>>>>>>>> panel, where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: >>>>>>>>>>>>>>>>>>>>>> "ERROR: Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do a >>>>>>>>>>>>>>>>>>>>>> string review before committing. In particular, I want to be sure the text >>>>>>>>>>>>>>>>>>>>>> in config.py is appropriately worded. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, >>>>>>>>>>>>>>>>>>>>>>>> while cleanup I removed the unwanted libraries but forgot to remove the >>>>>>>>>>>>>>>>>>>>>>>> code related to them. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in >>>>>>>>>>>>>>>>>>>>>>>>> package.json that makes it invalid. If I fix that, then I get the error >>>>>>>>>>>>>>>>>>>>>>>>> below, so I'm guessing the intention was to actually include another >>>>>>>>>>>>>>>>>>>>>>>>> package there? >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> ERROR in >>>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js 17:19-43 >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with >>>>>>>>>>>>>>>>>>>>>>>>> 1 error in 60041 ms >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>> >>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>> >>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> *Thanks & Regards* >>>>>>>>> *Akshay Joshi* >>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>> >>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> *Thanks & Regards* >>>>>> *Akshay Joshi* >>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>> >>>>>> *Mobile: +91 976-788-8246* >>>>>> >>>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> *pgAdmin Hacker | Principal Software Architect* >>>> *EDB Postgres <http://edbpostgres.com>* >>>> >>>> *Mobile: +91 976-788-8246* >>>> >>> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> Regards, > Nikhil Mohite > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [image/png] image.png (36.9K, 6-image.png) download | view image [image/png] image.png (42.2K, 7-image.png) download | view image [image/png] image.png (26.6K, 8-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-10 13:22 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-10 13:22 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> Hi Dave, On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: > Hi > > On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Dave, >> >> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Dave/ Team, >>>> >>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>> Windows 7(these are platforms on which we have tested). >>>> Files required for winpty are present in the site-packages but still, >>>> it is unable to load the winpty.dll file on these specific platforms. We >>>> have tested it on Windows 10 pro and Windows server 2019 and it is working >>>> fine. (Also tried building the local pywinpty but unable to build it.) ref >>>> link for winPty >>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>> >>> >>> Does winpty.exe run, if executed from the command line instead of >>> pgAdmin? If not, does dependency walker show any missing libraries that are >>> required? >>> >> Not found the winpty.exe in site packages, but as per the winpty >> documents "winpty-agent.exe" will start the process with a new, hidden >> console window. It is not showing any error while installing the package. I >> tried to use it outside the pgAdmin but still facing the same error >> "Exception in import winpty DLL load failed while importing winpty: The >> specified procedure could not be found."(created a separate python >> environment for this) >> >> 1. if try to run winpty-agent.exe from the command line, it shows the >> user entered inputs on the same terminal, not showing any errors. >> [image: image.png] >> >> 2. I found winpty.exe in the other installed app (Git command line: >> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >> line not getting any error, it is showing user entered inputs on the same >> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >> throwing any error or not) >> [image: image.png] >> > > Hmmm, that sounds oddly similar to an issue I had with Kerberos on Windows > when I was mucking around with that. I can't remember the exact details, > but as a test, does the problem go away if winpty.dll is copied into the > Windows system32 directory? > Tried it but still facing the same issue. > > > >> >> >> >>> >>>> >>>> Until we found the solution we can do the following solution for this. >>>> 1. We can add check if specific windows platform is not supporting >>>> winpty, show error msg when user open psql tool >>>> [image: image.png] >>>> 2. Diable the psql on these platforms by setting ENABLE_PSQL=False. >>>> >>>> >>>> If anyone has any other solution please let me know. >>>> >>>> Regards, >>>> Nikhil Mohite. >>>> >>>> On Tue, Jun 8, 2021 at 2:59 PM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> Thanks, the patch applied. >>>>> >>>>> On Mon, Jun 7, 2021 at 11:15 AM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Team, >>>>>> >>>>>> Please find the updated patch for added psql tool for windows >>>>>> platform. >>>>>> Also fixed a few issues reported by Fahar. >>>>>> 1. If the database name contains escape characters psql unable to >>>>>> connect. >>>>>> 2. If the user terminates the connection by entering "exit", psql >>>>>> will show connection termination msg. >>>>>> >>>>>> >>>>>> Regards, >>>>>> Nikhil Mohite. >>>>>> >>>>>> On Thu, Jun 3, 2021 at 2:10 PM Akshay Joshi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> On Thu, Jun 3, 2021 at 2:07 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Tue, Jun 1, 2021 at 12:58 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Team, >>>>>>>>> >>>>>>>>> Following are few points related to PSQL tool on windows: >>>>>>>>> >>>>>>>>> 1. Currently using the *pywinpty* library on windows to >>>>>>>>> create pty process and execute the psql.exe. >>>>>>>>> 2. To read the stderr (errors) currently using '2>>&1' >>>>>>>>> arguments to psql.exe command. (It will redirect stderr to stdout ) >>>>>>>>> 3. Windows conPTY is available on Windows 10 only (released >>>>>>>>> after 2018). >>>>>>>>> 4. Windows conPTY does not support the Asynchronous I/O, so to >>>>>>>>> get the terminal output, need to add the read function after every command >>>>>>>>> execution. (something like select() is not available) >>>>>>>>> 5. Also found some performance issues with psql on windows. >>>>>>>>> 1. To read the output from the terminal need to add some >>>>>>>>> sleep time as it will take time to return the output. >>>>>>>>> 2. Resize the terminal is also not consistent and causing >>>>>>>>> the issue if we resize the window faster or multiple times very quickly. >>>>>>>>> 3. Loading large dataset sometimes cause system to >>>>>>>>> non-responsive state.(In this state restart requires) >>>>>>>>> >>>>>>>>> Please find the patch for disable the psql tool for windows >>>>>>>>> platform.(Windows builds are falling due to this sending patch for disable >>>>>>>>> psql on windows.) >>>>>>>>> >>>>>>>> >>>>>>>> Disabling major features on our most common deployment platform >>>>>>>> really isn't a good option. I assume all of the above options are related >>>>>>>> to lack of async I/O? >>>>>>>> >>>>>>> >>>>>>> We have temporarily disabled the feature until found a solution, >>>>>>> to generate the nightly build for testing. >>>>>>> >>>>>>>> >>>>>>>> Have you tried forcing the use of winpty rather than conpty? >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> Reference links: >>>>>>>>> >>>>>>>>> 1. https://github.com/microsoft/terminal/issues/262 >>>>>>>>> 2. >>>>>>>>> https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-conso.... >>>>>>>>> 3. https://pypi.org/project/pywinpty/ >>>>>>>>> >>>>>>>>> >>>>>>>>> If any suggestions or questions please let me know. >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> Nikhil Mohite. >>>>>>>>> >>>>>>>>> On Tue, May 25, 2021 at 8:20 PM Akshay Joshi < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Thanks, patch applied. >>>>>>>>>> >>>>>>>>>> I have updated the screenshot and some documentation stuff. >>>>>>>>>> >>>>>>>>>> On Tue, May 25, 2021 at 3:08 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Akshay, >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Please find the updated patch. (V6) >>>>>>>>>>> On Tue, May 25, 2021 at 2:55 PM Akshay Joshi < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>> >>>>>>>>>>>> Please rebase and send the patch again. >>>>>>>>>>>> >>>>>>>>>>>> On Tue, May 25, 2021 at 2:52 PM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Akshay/ Team >>>>>>>>>>>>> >>>>>>>>>>>>> On Mon, May 24, 2021 at 9:19 PM Akshay Joshi < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>> >>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>> >>>>>>>>>>>>>> - Set "ENABLE_PSQL = False", PSQL button from browser >>>>>>>>>>>>>> tree and context menu option should not be visible. >>>>>>>>>>>>>> - Documentation screenshot should be in standard theme >>>>>>>>>>>>>> for consistency, and check the size it's very large. Take the screenshot >>>>>>>>>>>>>> with the new PSQL button on the browser tree. >>>>>>>>>>>>>> - Update 'menu_bar.rst' and 'toolbar.rst' with new >>>>>>>>>>>>>> changes. >>>>>>>>>>>>>> - Remove commented code (if any) >>>>>>>>>>>>>> - Check SonarQube (I haven't run) >>>>>>>>>>>>>> >>>>>>>>>>>>>> Please find the updated patch, resolve all the review >>>>>>>>>>>>> comments, and update the code to resolve the SonarQube issues. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, May 20, 2021 at 2:52 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thanks Nikhil. Can someone else review this version please? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Wed, May 19, 2021 at 2:42 PM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Wed, May 19, 2021 at 1:43 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Wed, May 19, 2021 at 8:58 AM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Tue, May 18, 2021 at 8:41 PM Dave Page < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Tue, May 18, 2021 at 12:12 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Dave/Team, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 6:47 PM Dave Page < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Mon, May 17, 2021 at 11:01 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Akshay/ Team, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Please find the attached updated patch for the psql >>>>>>>>>>>>>>>>>>>>> tool. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hmm, this version is also broken. There's a typo in >>>>>>>>>>>>>>>>>>>> editor_template.html on line 138 - it splits a string across two lines >>>>>>>>>>>>>>>>>>>> which throws an error. Having fixed that... >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> I also note there's a lot of Javascript in that HTML >>>>>>>>>>>>>>>>>>>> file. That should be pushed into the webpacked bundle I think, and not >>>>>>>>>>>>>>>>>>>> included inline in HTML. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I have moved most of the code in the js file, few things >>>>>>>>>>>>>>>>>>> are still in HTML. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hmm, yes - in particular, colours for the different >>>>>>>>>>>>>>>>>> themes. Please move them into the css for the themes. You have a mix of >>>>>>>>>>>>>>>>>> style, layout and code in this file which needs to be cleaned up. >>>>>>>>>>>>>>>>>> xterm V3 onwards they have provided the API to set the >>>>>>>>>>>>>>>>>> theme and other settings, earlier I tried with CSS to override the theme >>>>>>>>>>>>>>>>>> but couldn’t able to apply the theme properly as some style get applied as >>>>>>>>>>>>>>>>>> in-line style for the HTML, so used the API to set the theme. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> OK, but either way we can't hard-code styles from themes >>>>>>>>>>>>>>>>> in HTML templates for individual features; that way leads to madness. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Perhaps Aditya or one of the other team members can give >>>>>>>>>>>>>>>>> some assistance? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I have moved the color settings to the respective theme >>>>>>>>>>>>>>>> files. Aditya helped in this. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Speaking of themes, the background colour for selected >>>>>>>>>>>>>>>>>>> text doesn't seem right (it's barely visible) in the dark theme. Can you >>>>>>>>>>>>>>>>>>> fix that to match the colouring in the SQL text boxes please? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> I tried the default selection color from SQL for the dark >>>>>>>>>>>>>>>> and standard themes but still, it was not readable so just updated the >>>>>>>>>>>>>>>> color code with another color as follows. >>>>>>>>>>>>>>>> 1. Dark Theme: >>>>>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.29.43 PM.png] >>>>>>>>>>>>>>>> 2. High Contrast: (using default SQL selection color) >>>>>>>>>>>>>>>> [image: Screenshot 2021-05-19 at 6.59.52 PM.png] >>>>>>>>>>>>>>>> 3. Standard: >>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>> can we go with the colors or should we update it? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> A couple of other things I noticed: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - The button is enabled if the treeview has a Server >>>>>>>>>>>>>>>>>>>>> selected. It could be argued that the query tool should do the same >>>>>>>>>>>>>>>>>>>>> (defaulting to the maintenance database), however, that would be a separate >>>>>>>>>>>>>>>>>>>>> change, and psql should be consistent with the query tool. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> It is now consistent with the query tool. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - If I do a "select * from pg_class;" I still get: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> postgres=# select * from pg_class; >>>>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> I am not able to reproduce the warning for the terminal >>>>>>>>>>>>>>>>>>>> (I am working on Catalina 10.15.7), I checked on browsers (chrome, firefox, >>>>>>>>>>>>>>>>>>>> Safari) and also checked on local nwjs runtime but still not able to >>>>>>>>>>>>>>>>>>>> reproduce the warning. but found one limitation: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> It looks like that can be fixed by adding: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> env={'TERM': 'xterm'} >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Added this in the environment when opening the psql panel. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> to the subprocess.Popen() call. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I noticed while I was playing with that, that you are >>>>>>>>>>>>>>>>>>> passing the password as part of the connection string. As I've mentioned in >>>>>>>>>>>>>>>>>>> the past, that is absolutely not acceptable; it will expose the password to >>>>>>>>>>>>>>>>>>> all manner of tools (such as ps -ef). You *must* pass the password to psql >>>>>>>>>>>>>>>>>>> using the PGPASSWORD environment variable. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> if we try to load data from the table containing >>>>>>>>>>>>>>>>>>>> millions of records, UI gets very slow. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Removed the password from the connection string and >>>>>>>>>>>>>>>> added 'PGPASSWORD' in the environment. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Is xtermjs discarding the older buffer contents when it >>>>>>>>>>>>>>>>>>> fills up? Can you tell where the memory usage is? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> I checked the psql memory consumption in terminal and >>>>>>>>>>>>>>>>>> pgAdmin psql tool memory consumption is the similar. Also tested the >>>>>>>>>>>>>>>>>> performance and query execution timing is also similar. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> OK, so there's probably not much we can do here. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> - I'm sure using \q in the previous version displayed >>>>>>>>>>>>>>>>>>>>> a message saying the session exited (the one on line 138 of >>>>>>>>>>>>>>>>>>>>> editor_template.html). It no longer seems to do so. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> In addition to the issue above, it looks like the \! >>>>>>>>>>>>>>>>>>> blocking may have lost it's ability to ignore quoted strings: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> pgweb=# select '\!'; >>>>>>>>>>>>>>>>>>> ERROR: Shell commands are disabled in psql for security >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Fixed the issue now it is consistent with the psql >>>>>>>>>>>>>>>> terminal. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 3:40 PM Dave Page < >>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Tue, May 11, 2021 at 9:02 AM Akshay Joshi < >>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Hi Nikhil >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Following are the review comments: >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> *GUI specific*: >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> - We need a panel icon for PSQL like query >>>>>>>>>>>>>>>>>>>>>>>> tool, we can also add that on the browser tree toolbar. >>>>>>>>>>>>>>>>>>>>>>>> - PSQL Tool menu should be visible for all the >>>>>>>>>>>>>>>>>>>>>>>> child nodes of the database node. Follow the same as Query Tool. >>>>>>>>>>>>>>>>>>>>>>>> - PSQL tab title should be only database server >>>>>>>>>>>>>>>>>>>>>>>> name as the user can change the database/user from PSQL command, so it's >>>>>>>>>>>>>>>>>>>>>>>> been difficult to update the tab title. >>>>>>>>>>>>>>>>>>>>>>>> - PSQL connection is still open even if we >>>>>>>>>>>>>>>>>>>>>>>> disconnect the database server from the browser tree. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> *Code specific:* >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> - Remove an extra space from requirements.txt >>>>>>>>>>>>>>>>>>>>>>>> and package.json >>>>>>>>>>>>>>>>>>>>>>>> - Documentation needs to be updated to let the >>>>>>>>>>>>>>>>>>>>>>>> user know from where the PSQL tool will open and on which node it is >>>>>>>>>>>>>>>>>>>>>>>> applicable. >>>>>>>>>>>>>>>>>>>>>>>> - psql/__init__.py check there are so many >>>>>>>>>>>>>>>>>>>>>>>> unused imports please remove them. >>>>>>>>>>>>>>>>>>>>>>>> - We are not using cheroot so it should be >>>>>>>>>>>>>>>>>>>>>>>> removed from requirements.txt and also remove the import statement from >>>>>>>>>>>>>>>>>>>>>>>> pgAdmin4.py >>>>>>>>>>>>>>>>>>>>>>>> - Test cases are showing successful but >>>>>>>>>>>>>>>>>>>>>>>> actually, there are some routing errors please check. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> A few other things I noticed: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> - I was prompted to enter a password. This should be >>>>>>>>>>>>>>>>>>>>>>> passed in the environment to psql as it is for pg_dump etc. >>>>>>>>>>>>>>>>>>>>>>> - There seems to be an issue with terminal >>>>>>>>>>>>>>>>>>>>>>> compatibility (which I didn't have on my prototype): >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> ml=# select * from pg_class; >>>>>>>>>>>>>>>>>>>>>>> WARNING: terminal is not fully functional >>>>>>>>>>>>>>>>>>>>>>> -[ RECORD 1 >>>>>>>>>>>>>>>>>>>>>>> ]-------+---------------------------------------------- >>>>>>>>>>>>>>>>>>>>>>> oid | 79354 >>>>>>>>>>>>>>>>>>>>>>> relname | housing >>>>>>>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> - The panel should honour the styleguide. I'm >>>>>>>>>>>>>>>>>>>>>>> running in dark mode, and see a jet black background. I would expect to see >>>>>>>>>>>>>>>>>>>>>>> the same background/foreground colours as the treeview. >>>>>>>>>>>>>>>>>>>>>>> - I spotted at least one print() statement that >>>>>>>>>>>>>>>>>>>>>>> shouldn't be there (debug output should go through the logger) - >>>>>>>>>>>>>>>>>>>>>>> psql/__init__.py:235 >>>>>>>>>>>>>>>>>>>>>>> - This seems suspect - why would there be a password >>>>>>>>>>>>>>>>>>>>>>> in a connection string we've built? And why would it be xxx? >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> if 'password=xxx' in conn_attr: >>>>>>>>>>>>>>>>>>>>>>> conn_attr = >>>>>>>>>>>>>>>>>>>>>>> conn_attr.replace('password=xxx', '') >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> - There's a thick white line at the bottom of the >>>>>>>>>>>>>>>>>>>>>>> panel, where a horizontal scrollbar might be if there was one. >>>>>>>>>>>>>>>>>>>>>>> - The trailing semi-colon should be removed from: >>>>>>>>>>>>>>>>>>>>>>> "ERROR: Shell commands are disabled in psql for security;" >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Once we're happy with the patch in general, I'll do >>>>>>>>>>>>>>>>>>>>>>> a string review before committing. In particular, I want to be sure the >>>>>>>>>>>>>>>>>>>>>>> text in config.py is appropriately worded. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> This is shaping up nicely! Good work. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:32 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> PFA updated patch, sorry for the inconvenience, >>>>>>>>>>>>>>>>>>>>>>>>> while cleanup I removed the unwanted libraries but forgot to remove the >>>>>>>>>>>>>>>>>>>>>>>>> code related to them. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 7:10 PM Dave Page < >>>>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> On Mon, May 10, 2021 at 1:45 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Please find the attached patch for RM-2341 >>>>>>>>>>>>>>>>>>>>>>>>>>> <https://redmine.postgresql.org/issues/2341;: Add >>>>>>>>>>>>>>>>>>>>>>>>>>> Menu option for starting PSQL. >>>>>>>>>>>>>>>>>>>>>>>>>>> 1. Added new Option PSQL Tool in Tools menu. >>>>>>>>>>>>>>>>>>>>>>>>>>> 2. Added the same option for Server and Database >>>>>>>>>>>>>>>>>>>>>>>>>>> nodes from the tree view. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Unfortunately there's a trailing comma in >>>>>>>>>>>>>>>>>>>>>>>>>> package.json that makes it invalid. If I fix that, then I get the error >>>>>>>>>>>>>>>>>>>>>>>>>> below, so I'm guessing the intention was to actually include another >>>>>>>>>>>>>>>>>>>>>>>>>> package there? >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> ERROR in >>>>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js/psql_module.js 23:50-82 >>>>>>>>>>>>>>>>>>>>>>>>>> Module not found: Error: Can't resolve >>>>>>>>>>>>>>>>>>>>>>>>>> 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>>>>> resolve 'local-echo-controller' in >>>>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/pgadmin/tools/psql/static/js' >>>>>>>>>>>>>>>>>>>>>>>>>> Parsed request is a module >>>>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>>>>> aliased with mapping 'local-echo-controller': >>>>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' to >>>>>>>>>>>>>>>>>>>>>>>>>> '/Users/dpage/git/pgadmin4/web/node_modules/local-echo' >>>>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>>>> ./pgadmin/tools/psql/static/js) >>>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a valid >>>>>>>>>>>>>>>>>>>>>>>>>> alias configuration >>>>>>>>>>>>>>>>>>>>>>>>>> root path /Users/dpage/git/pgadmin4/web >>>>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>>>> ./Users/dpage/git/pgadmin4/web/node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.js >>>>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx >>>>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/Users/dpage/git/pgadmin4/web/node_modules/local-echo >>>>>>>>>>>>>>>>>>>>>>>>>> doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>>> using description file: >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/package.json (relative path: >>>>>>>>>>>>>>>>>>>>>>>>>> ./node_modules/local-echo) >>>>>>>>>>>>>>>>>>>>>>>>>> no extension >>>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>>> .js >>>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.js doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>>> .jsx >>>>>>>>>>>>>>>>>>>>>>>>>> Field 'browser' doesn't contain a >>>>>>>>>>>>>>>>>>>>>>>>>> valid alias configuration >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo.jsx doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>>> as directory >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> /Users/dpage/git/pgadmin4/web/node_modules/local-echo doesn't exist >>>>>>>>>>>>>>>>>>>>>>>>>> @ ./pgadmin/tools/psql/static/js/index.js >>>>>>>>>>>>>>>>>>>>>>>>>> 17:19-43 >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> 2021-05-10 14:38:37: webpack 5.21.2 compiled with >>>>>>>>>>>>>>>>>>>>>>>>>> 1 error in 60041 ms >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> <https://www.enterprisedb.com; >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> *Thanks & Regards,* >>>>>>>>>>>>>>>>>> *Nikhil Mohite* >>>>>>>>>>>>>>>>>> *Software Engineer.* >>>>>>>>>>>>>>>>>> *EDB Postgres* <https://www.enterprisedb.com/; >>>>>>>>>>>>>>>>>> *Mob.No: +91-7798364578.* >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>> Nikhil Mohite >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>>>> >>>>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> *Thanks & Regards* >>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>>>> >>>>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> *Thanks & Regards* >>>>>>>>>> *Akshay Joshi* >>>>>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>>>>> >>>>>>>>>> *Mobile: +91 976-788-8246* >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Thanks & Regards* >>>>>>> *Akshay Joshi* >>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>> >>>>>>> *Mobile: +91 976-788-8246* >>>>>>> >>>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> *pgAdmin Hacker | Principal Software Architect* >>>>> *EDB Postgres <http://edbpostgres.com>* >>>>> >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> Regards, >> Nikhil Mohite >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > Regards, Nikhil Mohite Attachments: [image/png] Screenshot 2021-05-19 at 6.29.43 PM.png (81.5K, 3-Screenshot%202021-05-19%20at%206.29.43%20PM.png) download | view image [image/png] Screenshot 2021-05-19 at 6.59.52 PM.png (76.3K, 4-Screenshot%202021-05-19%20at%206.59.52%20PM.png) download | view image [image/png] image.png (52.6K, 5-image.png) download | view image [image/png] image.png (36.9K, 6-image.png) download | view image [image/png] image.png (42.2K, 7-image.png) download | view image [image/png] image.png (26.6K, 8-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-10 14:50 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 2 replies; 54+ messages in thread From: Dave Page @ 2021-06-10 14:50 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < [email protected]> wrote: > Hi Dave, > > On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Dave, >>> >>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave/ Team, >>>>> >>>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>>> Windows 7(these are platforms on which we have tested). >>>>> Files required for winpty are present in the site-packages but still, >>>>> it is unable to load the winpty.dll file on these specific platforms. We >>>>> have tested it on Windows 10 pro and Windows server 2019 and it is working >>>>> fine. (Also tried building the local pywinpty but unable to build it.) ref >>>>> link for winPty >>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>> >>>> >>>> Does winpty.exe run, if executed from the command line instead of >>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>> required? >>>> >>> Not found the winpty.exe in site packages, but as per the winpty >>> documents "winpty-agent.exe" will start the process with a new, hidden >>> console window. It is not showing any error while installing the package. I >>> tried to use it outside the pgAdmin but still facing the same error >>> "Exception in import winpty DLL load failed while importing winpty: The >>> specified procedure could not be found."(created a separate python >>> environment for this) >>> >>> 1. if try to run winpty-agent.exe from the command line, it shows the >>> user entered inputs on the same terminal, not showing any errors. >>> [image: image.png] >>> >>> 2. I found winpty.exe in the other installed app (Git command line: >>> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >>> line not getting any error, it is showing user entered inputs on the same >>> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >>> throwing any error or not) >>> [image: image.png] >>> >> >> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >> Windows when I was mucking around with that. I can't remember the exact >> details, but as a test, does the problem go away if winpty.dll is copied >> into the Windows system32 directory? >> > Tried it but still facing the same issue. > OK, I had a fiddle around, and see the same thing. I can't do a simple import of winpty. On 2019 it's fine. I tried various tricks that I've used in the past to make sure libraries are found etc. Could this be because it's trying to use the conpty interface in Windows 10 and above? If we can't get this to work tomorrow, I think it's fine to simply hide the menu options and button if the server detects it's running on an unsupported version of Windows. Of course, this should be documented. We also need to make sure we know *exactly* what versions it does and does not work on. -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-10 15:46 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 1 sibling, 0 replies; 54+ messages in thread From: Nikhil Mohite @ 2021-06-10 15:46 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: pgadmin-hackers; Akshay Joshi <[email protected]> Hi Dave, On Thu, Jun 10, 2021 at 8:21 PM Dave Page <[email protected]> wrote: > > > On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Dave, >> >> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Dave, >>>> >>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave/ Team, >>>>>> >>>>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>>>> Windows 7(these are platforms on which we have tested). >>>>>> Files required for winpty are present in the site-packages but still, >>>>>> it is unable to load the winpty.dll file on these specific platforms. We >>>>>> have tested it on Windows 10 pro and Windows server 2019 and it is working >>>>>> fine. (Also tried building the local pywinpty but unable to build it.) ref >>>>>> link for winPty >>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>> >>>>> >>>>> Does winpty.exe run, if executed from the command line instead of >>>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>>> required? >>>>> >>>> Not found the winpty.exe in site packages, but as per the winpty >>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>> console window. It is not showing any error while installing the package. I >>>> tried to use it outside the pgAdmin but still facing the same error >>>> "Exception in import winpty DLL load failed while importing winpty: The >>>> specified procedure could not be found."(created a separate python >>>> environment for this) >>>> >>>> 1. if try to run winpty-agent.exe from the command line, it shows the >>>> user entered inputs on the same terminal, not showing any errors. >>>> [image: image.png] >>>> >>>> 2. I found winpty.exe in the other installed app (Git command line: >>>> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >>>> line not getting any error, it is showing user entered inputs on the same >>>> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >>>> throwing any error or not) >>>> [image: image.png] >>>> >>> >>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>> Windows when I was mucking around with that. I can't remember the exact >>> details, but as a test, does the problem go away if winpty.dll is copied >>> into the Windows system32 directory? >>> >> Tried it but still facing the same issue. >> > > OK, I had a fiddle around, and see the same thing. I can't do a simple > import of winpty. On 2019 it's fine. I tried various tricks that I've used > in the past to make sure libraries are found etc. > > Could this be because it's trying to use the conpty interface in Windows > 10 and above? > Not sure about this, but as per the pywinpty it should select the API (ConPty or WinPty ) which is available on the platform, but ConPty will take precedence over WinPty. > > If we can't get this to work tomorrow, I think it's fine to simply hide > the menu options and button if the server detects it's running on an > unsupported version of Windows. Of course, this should be documented. We > also need to make sure we know *exactly* what versions it does and does not > work on. > Okay, I will check if required I will update the document accordingly. > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > Regards, Nikhil Mohite Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 06:44 Fahar Abbas <[email protected]> parent: Dave Page <[email protected]> 1 sibling, 2 replies; 54+ messages in thread From: Fahar Abbas @ 2021-06-11 06:44 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> Hi, pgadmin4 is failing on following operating systems : Windows 2016 Windows 2012 Windows 07 Windows 2008R2 Windows 10 64 pgadmin4 is working fine in following operating system: Windows 2019 On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: > > > On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Dave, >> >> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Dave, >>>> >>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave/ Team, >>>>>> >>>>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>>>> Windows 7(these are platforms on which we have tested). >>>>>> Files required for winpty are present in the site-packages but still, >>>>>> it is unable to load the winpty.dll file on these specific platforms. We >>>>>> have tested it on Windows 10 pro and Windows server 2019 and it is working >>>>>> fine. (Also tried building the local pywinpty but unable to build it.) ref >>>>>> link for winPty >>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>> >>>>> >>>>> Does winpty.exe run, if executed from the command line instead of >>>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>>> required? >>>>> >>>> Not found the winpty.exe in site packages, but as per the winpty >>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>> console window. It is not showing any error while installing the package. I >>>> tried to use it outside the pgAdmin but still facing the same error >>>> "Exception in import winpty DLL load failed while importing winpty: The >>>> specified procedure could not be found."(created a separate python >>>> environment for this) >>>> >>>> 1. if try to run winpty-agent.exe from the command line, it shows the >>>> user entered inputs on the same terminal, not showing any errors. >>>> [image: image.png] >>>> >>>> 2. I found winpty.exe in the other installed app (Git command line: >>>> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >>>> line not getting any error, it is showing user entered inputs on the same >>>> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >>>> throwing any error or not) >>>> [image: image.png] >>>> >>> >>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>> Windows when I was mucking around with that. I can't remember the exact >>> details, but as a test, does the problem go away if winpty.dll is copied >>> into the Windows system32 directory? >>> >> Tried it but still facing the same issue. >> > > OK, I had a fiddle around, and see the same thing. I can't do a simple > import of winpty. On 2019 it's fine. I tried various tricks that I've used > in the past to make sure libraries are found etc. > > Could this be because it's trying to use the conpty interface in Windows > 10 and above? > > If we can't get this to work tomorrow, I think it's fine to simply hide > the menu options and button if the server detects it's running on an > unsupported version of Windows. Of course, this should be documented. We > also need to make sure we know *exactly* what versions it does and does not > work on. > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > -- Fahar Abbas EnterpriseDB Corporation Phone Office: +92-51-835-8874 Phone Direct: +92-51-8466803 Mobile: +92-333-5409707 Skype ID: *live:fahar.abbas* Website: www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 07:31 Akshay Joshi <[email protected]> parent: Fahar Abbas <[email protected]> 1 sibling, 0 replies; 54+ messages in thread From: Akshay Joshi @ 2021-06-11 07:31 UTC (permalink / raw) To: Fahar Abbas <[email protected]>; +Cc: Dave Page <[email protected]>; Nikhil Mohite <[email protected]>; pgadmin-hackers Hi Nikhil I tried on Windows 2016 server by creating a new virtual environment but still it is failing [image: Screenshot 2021-06-11 at 12.57.15 PM.png] FYI, a new version of "*pywinpty-1.1.2"* is released today. Can you please open a ticket on the community with the above screenshot? On Fri, Jun 11, 2021 at 12:14 PM Fahar Abbas <[email protected]> wrote: > Hi, > > pgadmin4 is failing on following operating systems : > Windows 2016 > Windows 2012 > Windows 07 > Windows 2008R2 > Windows 10 64 > > pgadmin4 is working fine in following operating system: > Windows 2019 > > On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: > >> >> >> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Dave, >>> >>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave, >>>>> >>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave/ Team, >>>>>>> >>>>>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>>>>> Windows 7(these are platforms on which we have tested). >>>>>>> Files required for winpty are present in the site-packages but >>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>> build it.) ref link for winPty >>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>> >>>>>> >>>>>> Does winpty.exe run, if executed from the command line instead of >>>>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>>>> required? >>>>>> >>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>> console window. It is not showing any error while installing the package. I >>>>> tried to use it outside the pgAdmin but still facing the same error >>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>> specified procedure could not be found."(created a separate python >>>>> environment for this) >>>>> >>>>> 1. if try to run winpty-agent.exe from the command line, it shows the >>>>> user entered inputs on the same terminal, not showing any errors. >>>>> [image: image.png] >>>>> >>>>> 2. I found winpty.exe in the other installed app (Git command line: >>>>> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >>>>> line not getting any error, it is showing user entered inputs on the same >>>>> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >>>>> throwing any error or not) >>>>> [image: image.png] >>>>> >>>> >>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>>> Windows when I was mucking around with that. I can't remember the exact >>>> details, but as a test, does the problem go away if winpty.dll is copied >>>> into the Windows system32 directory? >>>> >>> Tried it but still facing the same issue. >>> >> >> OK, I had a fiddle around, and see the same thing. I can't do a simple >> import of winpty. On 2019 it's fine. I tried various tricks that I've used >> in the past to make sure libraries are found etc. >> >> Could this be because it's trying to use the conpty interface in Windows >> 10 and above? >> >> If we can't get this to work tomorrow, I think it's fine to simply hide >> the menu options and button if the server detects it's running on an >> unsupported version of Windows. Of course, this should be documented. We >> also need to make sure we know *exactly* what versions it does and does not >> work on. >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > Fahar Abbas > EnterpriseDB Corporation > Phone Office: +92-51-835-8874 > Phone Direct: +92-51-8466803 > Mobile: +92-333-5409707 > Skype ID: *live:fahar.abbas* > Website: www.enterprisedb.com > -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image [image/png] Screenshot 2021-06-11 at 12.57.15 PM.png (97.5K, 5-Screenshot%202021-06-11%20at%2012.57.15%20PM.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 08:12 Dave Page <[email protected]> parent: Fahar Abbas <[email protected]> 1 sibling, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-11 08:12 UTC (permalink / raw) To: Fahar Abbas <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> Hi On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas <[email protected]> wrote: > Hi, > > pgadmin4 is failing on following operating systems : > Windows 2016 > Windows 2012 > Windows 07 > Windows 2008R2 > Windows 10 64 > What version of Windows 10? I *think* conpty was introduced in 1809. > > pgadmin4 is working fine in following operating system: > Windows 2019 > > On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: > >> >> >> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Dave, >>> >>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave, >>>>> >>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave/ Team, >>>>>>> >>>>>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>>>>> Windows 7(these are platforms on which we have tested). >>>>>>> Files required for winpty are present in the site-packages but >>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>> build it.) ref link for winPty >>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>> >>>>>> >>>>>> Does winpty.exe run, if executed from the command line instead of >>>>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>>>> required? >>>>>> >>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>> console window. It is not showing any error while installing the package. I >>>>> tried to use it outside the pgAdmin but still facing the same error >>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>> specified procedure could not be found."(created a separate python >>>>> environment for this) >>>>> >>>>> 1. if try to run winpty-agent.exe from the command line, it shows the >>>>> user entered inputs on the same terminal, not showing any errors. >>>>> [image: image.png] >>>>> >>>>> 2. I found winpty.exe in the other installed app (Git command line: >>>>> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >>>>> line not getting any error, it is showing user entered inputs on the same >>>>> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >>>>> throwing any error or not) >>>>> [image: image.png] >>>>> >>>> >>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>>> Windows when I was mucking around with that. I can't remember the exact >>>> details, but as a test, does the problem go away if winpty.dll is copied >>>> into the Windows system32 directory? >>>> >>> Tried it but still facing the same issue. >>> >> >> OK, I had a fiddle around, and see the same thing. I can't do a simple >> import of winpty. On 2019 it's fine. I tried various tricks that I've used >> in the past to make sure libraries are found etc. >> >> Could this be because it's trying to use the conpty interface in Windows >> 10 and above? >> >> If we can't get this to work tomorrow, I think it's fine to simply hide >> the menu options and button if the server detects it's running on an >> unsupported version of Windows. Of course, this should be documented. We >> also need to make sure we know *exactly* what versions it does and does not >> work on. >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > Fahar Abbas > EnterpriseDB Corporation > Phone Office: +92-51-835-8874 > Phone Direct: +92-51-8466803 > Mobile: +92-333-5409707 > Skype ID: *live:fahar.abbas* > Website: www.enterprisedb.com > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 08:25 Fahar Abbas <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Fahar Abbas @ 2021-06-11 08:25 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> Windows 10 Enterprise 2016 LTSB. On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: > Hi > > On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas <[email protected]> > wrote: > >> Hi, >> >> pgadmin4 is failing on following operating systems : >> Windows 2016 >> Windows 2012 >> Windows 07 >> Windows 2008R2 >> Windows 10 64 >> > > What version of Windows 10? I *think* conpty was introduced in 1809. > > >> >> pgadmin4 is working fine in following operating system: >> Windows 2019 >> >> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: >> >>> >>> >>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Dave, >>>> >>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave, >>>>>> >>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave/ Team, >>>>>>>> >>>>>>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>>>>>> Windows 7(these are platforms on which we have tested). >>>>>>>> Files required for winpty are present in the site-packages but >>>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>> build it.) ref link for winPty >>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>> >>>>>>> >>>>>>> Does winpty.exe run, if executed from the command line instead of >>>>>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>>>>> required? >>>>>>> >>>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>>> console window. It is not showing any error while installing the package. I >>>>>> tried to use it outside the pgAdmin but still facing the same error >>>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>>> specified procedure could not be found."(created a separate python >>>>>> environment for this) >>>>>> >>>>>> 1. if try to run winpty-agent.exe from the command line, it shows the >>>>>> user entered inputs on the same terminal, not showing any errors. >>>>>> [image: image.png] >>>>>> >>>>>> 2. I found winpty.exe in the other installed app (Git command line: >>>>>> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >>>>>> line not getting any error, it is showing user entered inputs on the same >>>>>> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >>>>>> throwing any error or not) >>>>>> [image: image.png] >>>>>> >>>>> >>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>>>> Windows when I was mucking around with that. I can't remember the exact >>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>> into the Windows system32 directory? >>>>> >>>> Tried it but still facing the same issue. >>>> >>> >>> OK, I had a fiddle around, and see the same thing. I can't do a simple >>> import of winpty. On 2019 it's fine. I tried various tricks that I've used >>> in the past to make sure libraries are found etc. >>> >>> Could this be because it's trying to use the conpty interface in Windows >>> 10 and above? >>> >>> If we can't get this to work tomorrow, I think it's fine to simply hide >>> the menu options and button if the server detects it's running on an >>> unsupported version of Windows. Of course, this should be documented. We >>> also need to make sure we know *exactly* what versions it does and does not >>> work on. >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> Fahar Abbas >> EnterpriseDB Corporation >> Phone Office: +92-51-835-8874 >> Phone Direct: +92-51-8466803 >> Mobile: +92-333-5409707 >> Skype ID: *live:fahar.abbas* >> Website: www.enterprisedb.com >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > -- Fahar Abbas EnterpriseDB Corporation Phone Office: +92-51-835-8874 Phone Direct: +92-51-8466803 Mobile: +92-333-5409707 Skype ID: *live:fahar.abbas* Website: www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 08:28 Dave Page <[email protected]> parent: Fahar Abbas <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-11 08:28 UTC (permalink / raw) To: Fahar Abbas <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas <[email protected]> wrote: > Windows 10 Enterprise 2016 LTSB. > Hmm, I assume that is version 1607. Can you test with 1809 please? And if that doesn't work, try 1909. > > On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas <[email protected]> >> wrote: >> >>> Hi, >>> >>> pgadmin4 is failing on following operating systems : >>> Windows 2016 >>> Windows 2012 >>> Windows 07 >>> Windows 2008R2 >>> Windows 10 64 >>> >> >> What version of Windows 10? I *think* conpty was introduced in 1809. >> >> >>> >>> pgadmin4 is working fine in following operating system: >>> Windows 2019 >>> >>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: >>> >>>> >>>> >>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave, >>>>> >>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave, >>>>>>> >>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Dave/ Team, >>>>>>>>> >>>>>>>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>>>>>>> Windows 7(these are platforms on which we have tested). >>>>>>>>> Files required for winpty are present in the site-packages but >>>>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>> build it.) ref link for winPty >>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>> >>>>>>>> >>>>>>>> Does winpty.exe run, if executed from the command line instead of >>>>>>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>>>>>> required? >>>>>>>> >>>>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>>>> console window. It is not showing any error while installing the package. I >>>>>>> tried to use it outside the pgAdmin but still facing the same error >>>>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>>>> specified procedure could not be found."(created a separate python >>>>>>> environment for this) >>>>>>> >>>>>>> 1. if try to run winpty-agent.exe from the command line, it shows >>>>>>> the user entered inputs on the same terminal, not showing any errors. >>>>>>> [image: image.png] >>>>>>> >>>>>>> 2. I found winpty.exe in the other installed app (Git command line: >>>>>>> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >>>>>>> line not getting any error, it is showing user entered inputs on the same >>>>>>> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >>>>>>> throwing any error or not) >>>>>>> [image: image.png] >>>>>>> >>>>>> >>>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>>>>> Windows when I was mucking around with that. I can't remember the exact >>>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>>> into the Windows system32 directory? >>>>>> >>>>> Tried it but still facing the same issue. >>>>> >>>> >>>> OK, I had a fiddle around, and see the same thing. I can't do a simple >>>> import of winpty. On 2019 it's fine. I tried various tricks that I've used >>>> in the past to make sure libraries are found etc. >>>> >>>> Could this be because it's trying to use the conpty interface in >>>> Windows 10 and above? >>>> >>>> If we can't get this to work tomorrow, I think it's fine to simply hide >>>> the menu options and button if the server detects it's running on an >>>> unsupported version of Windows. Of course, this should be documented. We >>>> also need to make sure we know *exactly* what versions it does and does not >>>> work on. >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> >>> >>> -- >>> Fahar Abbas >>> EnterpriseDB Corporation >>> Phone Office: +92-51-835-8874 >>> Phone Direct: +92-51-8466803 >>> Mobile: +92-333-5409707 >>> Skype ID: *live:fahar.abbas* >>> Website: www.enterprisedb.com >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > Fahar Abbas > EnterpriseDB Corporation > Phone Office: +92-51-835-8874 > Phone Direct: +92-51-8466803 > Mobile: +92-333-5409707 > Skype ID: *live:fahar.abbas* > Website: www.enterprisedb.com > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 08:34 Fahar Abbas <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Fahar Abbas @ 2021-06-11 08:34 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> Sure Dave, I will create a new VM with the latest iso. Nikhil is not able to reproduce the issue on Windows 10 with the latest version. So the issue is reproducible with older versions. Kind Regards, On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: > > > On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas <[email protected]> > wrote: > >> Windows 10 Enterprise 2016 LTSB. >> > > Hmm, I assume that is version 1607. Can you test with 1809 please? And if > that doesn't work, try 1909. > > >> >> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>> [email protected]> wrote: >>> >>>> Hi, >>>> >>>> pgadmin4 is failing on following operating systems : >>>> Windows 2016 >>>> Windows 2012 >>>> Windows 07 >>>> Windows 2008R2 >>>> Windows 10 64 >>>> >>> >>> What version of Windows 10? I *think* conpty was introduced in 1809. >>> >>> >>>> >>>> pgadmin4 is working fine in following operating system: >>>> Windows 2019 >>>> >>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: >>>> >>>>> >>>>> >>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave, >>>>>> >>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave, >>>>>>>> >>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave/ Team, >>>>>>>>>> >>>>>>>>>> We are facing an issue with winpty.dll on Windows server 2016 and >>>>>>>>>> Windows 7(these are platforms on which we have tested). >>>>>>>>>> Files required for winpty are present in the site-packages but >>>>>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>> build it.) ref link for winPty >>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>> >>>>>>>>> >>>>>>>>> Does winpty.exe run, if executed from the command line instead of >>>>>>>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>>>>>>> required? >>>>>>>>> >>>>>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>>>>> console window. It is not showing any error while installing the package. I >>>>>>>> tried to use it outside the pgAdmin but still facing the same error >>>>>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>>>>> specified procedure could not be found."(created a separate python >>>>>>>> environment for this) >>>>>>>> >>>>>>>> 1. if try to run winpty-agent.exe from the command line, it shows >>>>>>>> the user entered inputs on the same terminal, not showing any errors. >>>>>>>> [image: image.png] >>>>>>>> >>>>>>>> 2. I found winpty.exe in the other installed app (Git command line: >>>>>>>> C:\Program Files (x86)\Git\usr\bin) if try to run it through the command >>>>>>>> line not getting any error, it is showing user entered inputs on the same >>>>>>>> terminal. (It is not related to pgAdmin but just tried to check winpty.exe >>>>>>>> throwing any error or not) >>>>>>>> [image: image.png] >>>>>>>> >>>>>>> >>>>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>>>>>> Windows when I was mucking around with that. I can't remember the exact >>>>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>>>> into the Windows system32 directory? >>>>>>> >>>>>> Tried it but still facing the same issue. >>>>>> >>>>> >>>>> OK, I had a fiddle around, and see the same thing. I can't do a simple >>>>> import of winpty. On 2019 it's fine. I tried various tricks that I've used >>>>> in the past to make sure libraries are found etc. >>>>> >>>>> Could this be because it's trying to use the conpty interface in >>>>> Windows 10 and above? >>>>> >>>>> If we can't get this to work tomorrow, I think it's fine to simply >>>>> hide the menu options and button if the server detects it's running on an >>>>> unsupported version of Windows. Of course, this should be documented. We >>>>> also need to make sure we know *exactly* what versions it does and does not >>>>> work on. >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >>>> >>>> -- >>>> Fahar Abbas >>>> EnterpriseDB Corporation >>>> Phone Office: +92-51-835-8874 >>>> Phone Direct: +92-51-8466803 >>>> Mobile: +92-333-5409707 >>>> Skype ID: *live:fahar.abbas* >>>> Website: www.enterprisedb.com >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> Fahar Abbas >> EnterpriseDB Corporation >> Phone Office: +92-51-835-8874 >> Phone Direct: +92-51-8466803 >> Mobile: +92-333-5409707 >> Skype ID: *live:fahar.abbas* >> Website: www.enterprisedb.com >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > -- Fahar Abbas EnterpriseDB Corporation Phone Office: +92-51-835-8874 Phone Direct: +92-51-8466803 Mobile: +92-333-5409707 Skype ID: *live:fahar.abbas* Website: www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 08:39 Dave Page <[email protected]> parent: Fahar Abbas <[email protected]> 0 siblings, 2 replies; 54+ messages in thread From: Dave Page @ 2021-06-11 08:39 UTC (permalink / raw) To: Fahar Abbas <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas <[email protected]> wrote: > Sure Dave, I will create a new VM with the latest iso. > Not the latest. 1809 please. And if that doesn't work, 1909. We need to understand exactly what versions work and which don't. > Nikhil is not able to reproduce the issue on Windows 10 with the latest > version. So the issue is reproducible with older versions. > > Kind Regards, > On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: > >> >> >> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas <[email protected]> >> wrote: >> >>> Windows 10 Enterprise 2016 LTSB. >>> >> >> Hmm, I assume that is version 1607. Can you test with 1809 please? And if >> that doesn't work, try 1909. >> >> >>> >>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>> [email protected]> wrote: >>>> >>>>> Hi, >>>>> >>>>> pgadmin4 is failing on following operating systems : >>>>> Windows 2016 >>>>> Windows 2012 >>>>> Windows 07 >>>>> Windows 2008R2 >>>>> Windows 10 64 >>>>> >>>> >>>> What version of Windows 10? I *think* conpty was introduced in 1809. >>>> >>>> >>>>> >>>>> pgadmin4 is working fine in following operating system: >>>>> Windows 2019 >>>>> >>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> >>>>>> >>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave, >>>>>>> >>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Dave, >>>>>>>>> >>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>> >>>>>>>>>>> We are facing an issue with winpty.dll on Windows server 2016 >>>>>>>>>>> and Windows 7(these are platforms on which we have tested). >>>>>>>>>>> Files required for winpty are present in the site-packages but >>>>>>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>>> build it.) ref link for winPty >>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Does winpty.exe run, if executed from the command line instead of >>>>>>>>>> pgAdmin? If not, does dependency walker show any missing libraries that are >>>>>>>>>> required? >>>>>>>>>> >>>>>>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>>>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>>>>>> console window. It is not showing any error while installing the package. I >>>>>>>>> tried to use it outside the pgAdmin but still facing the same error >>>>>>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>>>>>> specified procedure could not be found."(created a separate python >>>>>>>>> environment for this) >>>>>>>>> >>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it shows >>>>>>>>> the user entered inputs on the same terminal, not showing any errors. >>>>>>>>> [image: image.png] >>>>>>>>> >>>>>>>>> 2. I found winpty.exe in the other installed app (Git command >>>>>>>>> line: C:\Program Files (x86)\Git\usr\bin) if try to run it through the >>>>>>>>> command line not getting any error, it is showing user entered inputs on >>>>>>>>> the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>> [image: image.png] >>>>>>>>> >>>>>>>> >>>>>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>>>>>>> Windows when I was mucking around with that. I can't remember the exact >>>>>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>>>>> into the Windows system32 directory? >>>>>>>> >>>>>>> Tried it but still facing the same issue. >>>>>>> >>>>>> >>>>>> OK, I had a fiddle around, and see the same thing. I can't do a >>>>>> simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>> I've used in the past to make sure libraries are found etc. >>>>>> >>>>>> Could this be because it's trying to use the conpty interface in >>>>>> Windows 10 and above? >>>>>> >>>>>> If we can't get this to work tomorrow, I think it's fine to simply >>>>>> hide the menu options and button if the server detects it's running on an >>>>>> unsupported version of Windows. Of course, this should be documented. We >>>>>> also need to make sure we know *exactly* what versions it does and does not >>>>>> work on. >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> >>>>> >>>>> -- >>>>> Fahar Abbas >>>>> EnterpriseDB Corporation >>>>> Phone Office: +92-51-835-8874 >>>>> Phone Direct: +92-51-8466803 >>>>> Mobile: +92-333-5409707 >>>>> Skype ID: *live:fahar.abbas* >>>>> Website: www.enterprisedb.com >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> >>> >>> -- >>> Fahar Abbas >>> EnterpriseDB Corporation >>> Phone Office: +92-51-835-8874 >>> Phone Direct: +92-51-8466803 >>> Mobile: +92-333-5409707 >>> Skype ID: *live:fahar.abbas* >>> Website: www.enterprisedb.com >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > Fahar Abbas > EnterpriseDB Corporation > Phone Office: +92-51-835-8874 > Phone Direct: +92-51-8466803 > Mobile: +92-333-5409707 > Skype ID: *live:fahar.abbas* > Website: www.enterprisedb.com > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 08:42 Fahar Abbas <[email protected]> parent: Dave Page <[email protected]> 1 sibling, 0 replies; 54+ messages in thread From: Fahar Abbas @ 2021-06-11 08:42 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> Sure Dave, I will update you soon. On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: > > > On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas <[email protected]> > wrote: > >> Sure Dave, I will create a new VM with the latest iso. >> > > Not the latest. 1809 please. And if that doesn't work, 1909. We need to > understand exactly what versions work and which don't. > > > >> Nikhil is not able to reproduce the issue on Windows 10 with the latest >> version. So the issue is reproducible with older versions. >> >> Kind Regards, >> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: >> >>> >>> >>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>> [email protected]> wrote: >>> >>>> Windows 10 Enterprise 2016 LTSB. >>>> >>> >>> Hmm, I assume that is version 1607. Can you test with 1809 please? And >>> if that doesn't work, try 1909. >>> >>> >>>> >>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi, >>>>>> >>>>>> pgadmin4 is failing on following operating systems : >>>>>> Windows 2016 >>>>>> Windows 2012 >>>>>> Windows 07 >>>>>> Windows 2008R2 >>>>>> Windows 10 64 >>>>>> >>>>> >>>>> What version of Windows 10? I *think* conpty was introduced in 1809. >>>>> >>>>> >>>>>> >>>>>> pgadmin4 is working fine in following operating system: >>>>>> Windows 2019 >>>>>> >>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave, >>>>>>>> >>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave, >>>>>>>>>> >>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>> >>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server 2016 >>>>>>>>>>>> and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>> Files required for winpty are present in the site-packages but >>>>>>>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>>>> build it.) ref link for winPty >>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Does winpty.exe run, if executed from the command line instead >>>>>>>>>>> of pgAdmin? If not, does dependency walker show any missing libraries that >>>>>>>>>>> are required? >>>>>>>>>>> >>>>>>>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>>>>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>>>>>>> console window. It is not showing any error while installing the package. I >>>>>>>>>> tried to use it outside the pgAdmin but still facing the same error >>>>>>>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>>>>>>> specified procedure could not be found."(created a separate python >>>>>>>>>> environment for this) >>>>>>>>>> >>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it shows >>>>>>>>>> the user entered inputs on the same terminal, not showing any errors. >>>>>>>>>> [image: image.png] >>>>>>>>>> >>>>>>>>>> 2. I found winpty.exe in the other installed app (Git command >>>>>>>>>> line: C:\Program Files (x86)\Git\usr\bin) if try to run it through the >>>>>>>>>> command line not getting any error, it is showing user entered inputs on >>>>>>>>>> the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>> [image: image.png] >>>>>>>>>> >>>>>>>>> >>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>>>>>>>> Windows when I was mucking around with that. I can't remember the exact >>>>>>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>>>>>> into the Windows system32 directory? >>>>>>>>> >>>>>>>> Tried it but still facing the same issue. >>>>>>>> >>>>>>> >>>>>>> OK, I had a fiddle around, and see the same thing. I can't do a >>>>>>> simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>> >>>>>>> Could this be because it's trying to use the conpty interface in >>>>>>> Windows 10 and above? >>>>>>> >>>>>>> If we can't get this to work tomorrow, I think it's fine to simply >>>>>>> hide the menu options and button if the server detects it's running on an >>>>>>> unsupported version of Windows. Of course, this should be documented. We >>>>>>> also need to make sure we know *exactly* what versions it does and does not >>>>>>> work on. >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Fahar Abbas >>>>>> EnterpriseDB Corporation >>>>>> Phone Office: +92-51-835-8874 >>>>>> Phone Direct: +92-51-8466803 >>>>>> Mobile: +92-333-5409707 >>>>>> Skype ID: *live:fahar.abbas* >>>>>> Website: www.enterprisedb.com >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >>>> >>>> -- >>>> Fahar Abbas >>>> EnterpriseDB Corporation >>>> Phone Office: +92-51-835-8874 >>>> Phone Direct: +92-51-8466803 >>>> Mobile: +92-333-5409707 >>>> Skype ID: *live:fahar.abbas* >>>> Website: www.enterprisedb.com >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> Fahar Abbas >> EnterpriseDB Corporation >> Phone Office: +92-51-835-8874 >> Phone Direct: +92-51-8466803 >> Mobile: +92-333-5409707 >> Skype ID: *live:fahar.abbas* >> Website: www.enterprisedb.com >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > -- Fahar Abbas EnterpriseDB Corporation Phone Office: +92-51-835-8874 Phone Direct: +92-51-8466803 Mobile: +92-333-5409707 Skype ID: *live:fahar.abbas* Website: www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 12:45 Fahar Abbas <[email protected]> parent: Dave Page <[email protected]> 1 sibling, 1 reply; 54+ messages in thread From: Fahar Abbas @ 2021-06-11 12:45 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> Hi Dave, On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: > > > On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas <[email protected]> > wrote: > >> Sure Dave, I will create a new VM with the latest iso. >> > > Not the latest. 1809 please. And if that doesn't work, 1909. We need to > understand exactly what versions work and which don't. > > pgadmin4 is working fine on Windows 10 x64(1809). Do I also need to test pgadmin4 on 1909 iso? > > > >> Nikhil is not able to reproduce the issue on Windows 10 with the latest >> version. So the issue is reproducible with older versions. >> >> Kind Regards, >> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: >> >>> >>> >>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>> [email protected]> wrote: >>> >>>> Windows 10 Enterprise 2016 LTSB. >>>> >>> >>> Hmm, I assume that is version 1607. Can you test with 1809 please? And >>> if that doesn't work, try 1909. >>> >>> >>>> >>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi, >>>>>> >>>>>> pgadmin4 is failing on following operating systems : >>>>>> Windows 2016 >>>>>> Windows 2012 >>>>>> Windows 07 >>>>>> Windows 2008R2 >>>>>> Windows 10 64 >>>>>> >>>>> >>>>> What version of Windows 10? I *think* conpty was introduced in 1809. >>>>> >>>>> >>>>>> >>>>>> pgadmin4 is working fine in following operating system: >>>>>> Windows 2019 >>>>>> >>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave, >>>>>>>> >>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave, >>>>>>>>>> >>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>> >>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server 2016 >>>>>>>>>>>> and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>> Files required for winpty are present in the site-packages but >>>>>>>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>>>> build it.) ref link for winPty >>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Does winpty.exe run, if executed from the command line instead >>>>>>>>>>> of pgAdmin? If not, does dependency walker show any missing libraries that >>>>>>>>>>> are required? >>>>>>>>>>> >>>>>>>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>>>>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>>>>>>> console window. It is not showing any error while installing the package. I >>>>>>>>>> tried to use it outside the pgAdmin but still facing the same error >>>>>>>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>>>>>>> specified procedure could not be found."(created a separate python >>>>>>>>>> environment for this) >>>>>>>>>> >>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it shows >>>>>>>>>> the user entered inputs on the same terminal, not showing any errors. >>>>>>>>>> [image: image.png] >>>>>>>>>> >>>>>>>>>> 2. I found winpty.exe in the other installed app (Git command >>>>>>>>>> line: C:\Program Files (x86)\Git\usr\bin) if try to run it through the >>>>>>>>>> command line not getting any error, it is showing user entered inputs on >>>>>>>>>> the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>> [image: image.png] >>>>>>>>>> >>>>>>>>> >>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos on >>>>>>>>> Windows when I was mucking around with that. I can't remember the exact >>>>>>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>>>>>> into the Windows system32 directory? >>>>>>>>> >>>>>>>> Tried it but still facing the same issue. >>>>>>>> >>>>>>> >>>>>>> OK, I had a fiddle around, and see the same thing. I can't do a >>>>>>> simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>> >>>>>>> Could this be because it's trying to use the conpty interface in >>>>>>> Windows 10 and above? >>>>>>> >>>>>>> If we can't get this to work tomorrow, I think it's fine to simply >>>>>>> hide the menu options and button if the server detects it's running on an >>>>>>> unsupported version of Windows. Of course, this should be documented. We >>>>>>> also need to make sure we know *exactly* what versions it does and does not >>>>>>> work on. >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Fahar Abbas >>>>>> EnterpriseDB Corporation >>>>>> Phone Office: +92-51-835-8874 >>>>>> Phone Direct: +92-51-8466803 >>>>>> Mobile: +92-333-5409707 >>>>>> Skype ID: *live:fahar.abbas* >>>>>> Website: www.enterprisedb.com >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >>>> >>>> -- >>>> Fahar Abbas >>>> EnterpriseDB Corporation >>>> Phone Office: +92-51-835-8874 >>>> Phone Direct: +92-51-8466803 >>>> Mobile: +92-333-5409707 >>>> Skype ID: *live:fahar.abbas* >>>> Website: www.enterprisedb.com >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> Fahar Abbas >> EnterpriseDB Corporation >> Phone Office: +92-51-835-8874 >> Phone Direct: +92-51-8466803 >> Mobile: +92-333-5409707 >> Skype ID: *live:fahar.abbas* >> Website: www.enterprisedb.com >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > -- Fahar Abbas EnterpriseDB Corporation Phone Office: +92-51-835-8874 Phone Direct: +92-51-8466803 Mobile: +92-333-5409707 Skype ID: *live:fahar.abbas* Website: www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-11 12:54 Dave Page <[email protected]> parent: Fahar Abbas <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-11 12:54 UTC (permalink / raw) To: Fahar Abbas <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Akshay Joshi <[email protected]> Hi On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas <[email protected]> wrote: > Hi Dave, > > On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: > >> >> >> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas <[email protected]> >> wrote: >> >>> Sure Dave, I will create a new VM with the latest iso. >>> >> >> Not the latest. 1809 please. And if that doesn't work, 1909. We need to >> understand exactly what versions work and which don't. >> >> pgadmin4 is working fine on Windows 10 x64(1809). > Great, thanks! > > Do I also need to test pgadmin4 on 1909 iso? > I don't think so. I'm 99% certain that what we're seeing is that it works on the versions of Windows that support conpty, but not the older ones where the pywinpty library is *supposed* to fall back to using winpty. Hopefully Nikhil can get to the bottom of the problem with the pywinpty folks. > >> >>> Nikhil is not able to reproduce the issue on Windows 10 with the latest >>> version. So the issue is reproducible with older versions. >>> >>> Kind Regards, >>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: >>> >>>> >>>> >>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>> [email protected]> wrote: >>>> >>>>> Windows 10 Enterprise 2016 LTSB. >>>>> >>>> >>>> Hmm, I assume that is version 1607. Can you test with 1809 please? And >>>> if that doesn't work, try 1909. >>>> >>>> >>>>> >>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi, >>>>>>> >>>>>>> pgadmin4 is failing on following operating systems : >>>>>>> Windows 2016 >>>>>>> Windows 2012 >>>>>>> Windows 07 >>>>>>> Windows 2008R2 >>>>>>> Windows 10 64 >>>>>>> >>>>>> >>>>>> What version of Windows 10? I *think* conpty was introduced in 1809. >>>>>> >>>>>> >>>>>>> >>>>>>> pgadmin4 is working fine in following operating system: >>>>>>> Windows 2019 >>>>>>> >>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Dave, >>>>>>>>> >>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave, >>>>>>>>>>> >>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>> >>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server 2016 >>>>>>>>>>>>> and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>> Files required for winpty are present in the site-packages but >>>>>>>>>>>>> still, it is unable to load the winpty.dll file on these specific >>>>>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>>>>> build it.) ref link for winPty >>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Does winpty.exe run, if executed from the command line instead >>>>>>>>>>>> of pgAdmin? If not, does dependency walker show any missing libraries that >>>>>>>>>>>> are required? >>>>>>>>>>>> >>>>>>>>>>> Not found the winpty.exe in site packages, but as per the winpty >>>>>>>>>>> documents "winpty-agent.exe" will start the process with a new, hidden >>>>>>>>>>> console window. It is not showing any error while installing the package. I >>>>>>>>>>> tried to use it outside the pgAdmin but still facing the same error >>>>>>>>>>> "Exception in import winpty DLL load failed while importing winpty: The >>>>>>>>>>> specified procedure could not be found."(created a separate python >>>>>>>>>>> environment for this) >>>>>>>>>>> >>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it >>>>>>>>>>> shows the user entered inputs on the same terminal, not showing any errors. >>>>>>>>>>> [image: image.png] >>>>>>>>>>> >>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git command >>>>>>>>>>> line: C:\Program Files (x86)\Git\usr\bin) if try to run it through the >>>>>>>>>>> command line not getting any error, it is showing user entered inputs on >>>>>>>>>>> the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>> [image: image.png] >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos >>>>>>>>>> on Windows when I was mucking around with that. I can't remember the exact >>>>>>>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>>>>>>> into the Windows system32 directory? >>>>>>>>>> >>>>>>>>> Tried it but still facing the same issue. >>>>>>>>> >>>>>>>> >>>>>>>> OK, I had a fiddle around, and see the same thing. I can't do a >>>>>>>> simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>>> >>>>>>>> Could this be because it's trying to use the conpty interface in >>>>>>>> Windows 10 and above? >>>>>>>> >>>>>>>> If we can't get this to work tomorrow, I think it's fine to simply >>>>>>>> hide the menu options and button if the server detects it's running on an >>>>>>>> unsupported version of Windows. Of course, this should be documented. We >>>>>>>> also need to make sure we know *exactly* what versions it does and does not >>>>>>>> work on. >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Fahar Abbas >>>>>>> EnterpriseDB Corporation >>>>>>> Phone Office: +92-51-835-8874 >>>>>>> Phone Direct: +92-51-8466803 >>>>>>> Mobile: +92-333-5409707 >>>>>>> Skype ID: *live:fahar.abbas* >>>>>>> Website: www.enterprisedb.com >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> >>>>> >>>>> -- >>>>> Fahar Abbas >>>>> EnterpriseDB Corporation >>>>> Phone Office: +92-51-835-8874 >>>>> Phone Direct: +92-51-8466803 >>>>> Mobile: +92-333-5409707 >>>>> Skype ID: *live:fahar.abbas* >>>>> Website: www.enterprisedb.com >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> >>> >>> -- >>> Fahar Abbas >>> EnterpriseDB Corporation >>> Phone Office: +92-51-835-8874 >>> Phone Direct: +92-51-8466803 >>> Mobile: +92-333-5409707 >>> Skype ID: *live:fahar.abbas* >>> Website: www.enterprisedb.com >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > Fahar Abbas > EnterpriseDB Corporation > Phone Office: +92-51-835-8874 > Phone Direct: +92-51-8466803 > Mobile: +92-333-5409707 > Skype ID: *live:fahar.abbas* > Website: www.enterprisedb.com > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 04:55 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-14 04:55 UTC (permalink / raw) To: pgadmin-hackers; +Cc: Fahar Abbas <[email protected]>; Akshay Joshi <[email protected]>; Dave Page <[email protected]> Hi Team, Please find the updated patch for the PSQL tool, Added check if the Windows version is not supporting the ConPty or WinPty disable the PSQL for that version. (PSQL option will not visible to the user). I have raised the issue with "pywinpty" https://github.com/spyder-ide/pywinpty/issues/161 Regards, Nikhil Mohite On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> wrote: > Hi > > On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas <[email protected]> > wrote: > >> Hi Dave, >> >> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: >> >>> >>> >>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>> [email protected]> wrote: >>> >>>> Sure Dave, I will create a new VM with the latest iso. >>>> >>> >>> Not the latest. 1809 please. And if that doesn't work, 1909. We need to >>> understand exactly what versions work and which don't. >>> >>> pgadmin4 is working fine on Windows 10 x64(1809). >> > > Great, thanks! > > >> >> Do I also need to test pgadmin4 on 1909 iso? >> > > I don't think so. I'm 99% certain that what we're seeing is that it works > on the versions of Windows that support conpty, but not the older ones > where the pywinpty library is *supposed* to fall back to using winpty. > > Hopefully Nikhil can get to the bottom of the problem with the > pywinpty folks. > > > >> >>> >>>> Nikhil is not able to reproduce the issue on Windows 10 with the latest >>>> version. So the issue is reproducible with older versions. >>>> >>>> Kind Regards, >>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: >>>> >>>>> >>>>> >>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>> [email protected]> wrote: >>>>> >>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>> >>>>> >>>>> Hmm, I assume that is version 1607. Can you test with 1809 please? And >>>>> if that doesn't work, try 1909. >>>>> >>>>> >>>>>> >>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi, >>>>>>>> >>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>> Windows 2016 >>>>>>>> Windows 2012 >>>>>>>> Windows 07 >>>>>>>> Windows 2008R2 >>>>>>>> Windows 10 64 >>>>>>>> >>>>>>> >>>>>>> What version of Windows 10? I *think* conpty was introduced in 1809. >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>> Windows 2019 >>>>>>>> >>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave, >>>>>>>>>> >>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave, >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>> >>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server 2016 >>>>>>>>>>>>>> and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>> Files required for winpty are present in the site-packages >>>>>>>>>>>>>> but still, it is unable to load the winpty.dll file on these specific >>>>>>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>>>>>> build it.) ref link for winPty >>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Does winpty.exe run, if executed from the command line instead >>>>>>>>>>>>> of pgAdmin? If not, does dependency walker show any missing libraries that >>>>>>>>>>>>> are required? >>>>>>>>>>>>> >>>>>>>>>>>> Not found the winpty.exe in site packages, but as per the >>>>>>>>>>>> winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>> environment for this) >>>>>>>>>>>> >>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it >>>>>>>>>>>> shows the user entered inputs on the same terminal, not showing any errors. >>>>>>>>>>>> [image: image.png] >>>>>>>>>>>> >>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git command >>>>>>>>>>>> line: C:\Program Files (x86)\Git\usr\bin) if try to run it through the >>>>>>>>>>>> command line not getting any error, it is showing user entered inputs on >>>>>>>>>>>> the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>> [image: image.png] >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos >>>>>>>>>>> on Windows when I was mucking around with that. I can't remember the exact >>>>>>>>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>>>>>>>> into the Windows system32 directory? >>>>>>>>>>> >>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>> >>>>>>>>> >>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't do a >>>>>>>>> simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>>>> >>>>>>>>> Could this be because it's trying to use the conpty interface in >>>>>>>>> Windows 10 and above? >>>>>>>>> >>>>>>>>> If we can't get this to work tomorrow, I think it's fine to simply >>>>>>>>> hide the menu options and button if the server detects it's running on an >>>>>>>>> unsupported version of Windows. Of course, this should be documented. We >>>>>>>>> also need to make sure we know *exactly* what versions it does and does not >>>>>>>>> work on. >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Fahar Abbas >>>>>>>> EnterpriseDB Corporation >>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>> Mobile: +92-333-5409707 >>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>> Website: www.enterprisedb.com >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Fahar Abbas >>>>>> EnterpriseDB Corporation >>>>>> Phone Office: +92-51-835-8874 >>>>>> Phone Direct: +92-51-8466803 >>>>>> Mobile: +92-333-5409707 >>>>>> Skype ID: *live:fahar.abbas* >>>>>> Website: www.enterprisedb.com >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >>>> >>>> -- >>>> Fahar Abbas >>>> EnterpriseDB Corporation >>>> Phone Office: +92-51-835-8874 >>>> Phone Direct: +92-51-8466803 >>>> Mobile: +92-333-5409707 >>>> Skype ID: *live:fahar.abbas* >>>> Website: www.enterprisedb.com >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> Fahar Abbas >> EnterpriseDB Corporation >> Phone Office: +92-51-835-8874 >> Phone Direct: +92-51-8466803 >> Mobile: +92-333-5409707 >> Skype ID: *live:fahar.abbas* >> Website: www.enterprisedb.com >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 05:24 Nikhil Mohite <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-14 05:24 UTC (permalink / raw) To: pgadmin-hackers; +Cc: Fahar Abbas <[email protected]>; Akshay Joshi <[email protected]>; Dave Page <[email protected]> Hi Team, PFA patch v8 On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < [email protected]> wrote: > Hi Team, > > Please find the updated patch for the PSQL tool, Added check if the > Windows version is not supporting the ConPty or WinPty disable the PSQL for > that version. (PSQL option will not visible to the user). > > I have raised the issue with "pywinpty" > https://github.com/spyder-ide/pywinpty/issues/161 > > Regards, > Nikhil Mohite > > On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas <[email protected]> >> wrote: >> >>> Hi Dave, >>> >>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: >>> >>>> >>>> >>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>> [email protected]> wrote: >>>> >>>>> Sure Dave, I will create a new VM with the latest iso. >>>>> >>>> >>>> Not the latest. 1809 please. And if that doesn't work, 1909. We need to >>>> understand exactly what versions work and which don't. >>>> >>>> pgadmin4 is working fine on Windows 10 x64(1809). >>> >> >> Great, thanks! >> >> >>> >>> Do I also need to test pgadmin4 on 1909 iso? >>> >> >> I don't think so. I'm 99% certain that what we're seeing is that it works >> on the versions of Windows that support conpty, but not the older ones >> where the pywinpty library is *supposed* to fall back to using winpty. >> >> Hopefully Nikhil can get to the bottom of the problem with the >> pywinpty folks. >> >> >> >>> >>>> >>>>> Nikhil is not able to reproduce the issue on Windows 10 with the >>>>> latest version. So the issue is reproducible with older versions. >>>>> >>>>> Kind Regards, >>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> >>>>>> >>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>> >>>>>> >>>>>> Hmm, I assume that is version 1607. Can you test with 1809 please? >>>>>> And if that doesn't work, try 1909. >>>>>> >>>>>> >>>>>>> >>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi, >>>>>>>>> >>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>> Windows 2016 >>>>>>>>> Windows 2012 >>>>>>>>> Windows 07 >>>>>>>>> Windows 2008R2 >>>>>>>>> Windows 10 64 >>>>>>>>> >>>>>>>> >>>>>>>> What version of Windows 10? I *think* conpty was introduced in 1809. >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>> Windows 2019 >>>>>>>>> >>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave, >>>>>>>>>>> >>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server >>>>>>>>>>>>>>> 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>> Files required for winpty are present in the site-packages >>>>>>>>>>>>>>> but still, it is unable to load the winpty.dll file on these specific >>>>>>>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>>>>>>> build it.) ref link for winPty >>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>> >>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per the >>>>>>>>>>>>> winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>> environment for this) >>>>>>>>>>>>> >>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it >>>>>>>>>>>>> shows the user entered inputs on the same terminal, not showing any errors. >>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>> >>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git command >>>>>>>>>>>>> line: C:\Program Files (x86)\Git\usr\bin) if try to run it through the >>>>>>>>>>>>> command line not getting any error, it is showing user entered inputs on >>>>>>>>>>>>> the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with Kerberos >>>>>>>>>>>> on Windows when I was mucking around with that. I can't remember the exact >>>>>>>>>>>> details, but as a test, does the problem go away if winpty.dll is copied >>>>>>>>>>>> into the Windows system32 directory? >>>>>>>>>>>> >>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't do a >>>>>>>>>> simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>>>>> >>>>>>>>>> Could this be because it's trying to use the conpty interface in >>>>>>>>>> Windows 10 and above? >>>>>>>>>> >>>>>>>>>> If we can't get this to work tomorrow, I think it's fine to >>>>>>>>>> simply hide the menu options and button if the server detects it's running >>>>>>>>>> on an unsupported version of Windows. Of course, this should be documented. >>>>>>>>>> We also need to make sure we know *exactly* what versions it does and does >>>>>>>>>> not work on. >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Fahar Abbas >>>>>>>>> EnterpriseDB Corporation >>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>> Website: www.enterprisedb.com >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Fahar Abbas >>>>>>> EnterpriseDB Corporation >>>>>>> Phone Office: +92-51-835-8874 >>>>>>> Phone Direct: +92-51-8466803 >>>>>>> Mobile: +92-333-5409707 >>>>>>> Skype ID: *live:fahar.abbas* >>>>>>> Website: www.enterprisedb.com >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> >>>>> >>>>> -- >>>>> Fahar Abbas >>>>> EnterpriseDB Corporation >>>>> Phone Office: +92-51-835-8874 >>>>> Phone Direct: +92-51-8466803 >>>>> Mobile: +92-333-5409707 >>>>> Skype ID: *live:fahar.abbas* >>>>> Website: www.enterprisedb.com >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> >>> >>> -- >>> Fahar Abbas >>> EnterpriseDB Corporation >>> Phone Office: +92-51-835-8874 >>> Phone Direct: +92-51-8466803 >>> Mobile: +92-333-5409707 >>> Skype ID: *live:fahar.abbas* >>> Website: www.enterprisedb.com >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image [application/octet-stream] RM_2341_v8.patch (7.0K, 5-RM_2341_v8.patch) download | inline diff: diff --git a/docs/en_US/psql_tool.rst b/docs/en_US/psql_tool.rst index 94692586..d8773214 100644 --- a/docs/en_US/psql_tool.rst +++ b/docs/en_US/psql_tool.rst @@ -10,6 +10,10 @@ PSQL tool allows user to connect to PostgreSQL/EDB Advanced server using psql te * PSQL will connect to the current connected database from browser tree. +* PSQL utility does support execution of OS meta commands by using "\\!". Due to security concerns we have disabled the execution of such commands in pgAdmin PSQL tool. To enable OS meta commands set ALLOW_PSQL_SHELL_COMMANDS = True in configuration. + +* For Windows platform this feature is available on Windows 10 (1809 version and onwards). + .. image:: images/psql_tool.png :alt: PSQL tool window :align: center diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index 2042ada8..41a7e328 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -60,7 +60,7 @@ winreg = None if os.name == 'nt': import winreg -socketio = SocketIO(manage_session=False, async_mode='eventlet', +socketio = SocketIO(manage_session=False, async_mode='threading', logger=False, engineio_logger=False, debug=False, ping_interval=25, ping_timeout=120) diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index 6e9fb629..fa7aa9e5 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -855,7 +855,8 @@ def utils(): support_ssh_tunnel=config.SUPPORT_SSH_TUNNEL, logout_url=_get_logout_url(), platform=sys.platform, - qt_default_placeholder=QT_DEFAULT_PLACEHOLDER + qt_default_placeholder=QT_DEFAULT_PLACEHOLDER, + enable_psql=config.ENABLE_PSQL ), 200, {'Content-Type': MIMETYPE_APP_JS}) diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index cfe279b4..c2c16ad8 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -505,39 +505,39 @@ def register_browser_preferences(self): ' revert back to the default title with placeholders.' ) ) + if config.ENABLE_PSQL: + self.open_in_new_tab = self.preference.register( + 'tab_settings', 'new_browser_tab_open', + gettext("Open in new browser tab"), 'select2', None, + category_label=PREF_LABEL_OPTIONS, + options=[{'label': gettext('Query Tool'), 'value': 'qt'}, + {'label': gettext('Debugger'), 'value': 'debugger'}, + {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, + {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], + help_str=gettext( + 'Select Query Tool, Debugger, Schema Diff, ERD Tool ' + 'or PSQL Tool from the drop-down to set ' + 'open in new browser tab for that particular module.' + ), + select2={ + 'multiple': True, 'allowClear': False, + 'tags': True, 'first_empty': False, + 'selectOnClose': False, 'emptyOptions': True, + 'tokenSeparators': [','], + 'placeholder': gettext('Select open new tab...') + } + ) - self.open_in_new_tab = self.preference.register( - 'tab_settings', 'new_browser_tab_open', - gettext("Open in new browser tab"), 'select2', None, - category_label=PREF_LABEL_OPTIONS, - options=[{'label': gettext('Query Tool'), 'value': 'qt'}, - {'label': gettext('Debugger'), 'value': 'debugger'}, - {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, - {'label': gettext('ERD Tool'), 'value': 'erd_tool'}, - {'label': gettext('PSQL Tool'), 'value': 'psql_tool'}], - help_str=gettext( - 'Select Query Tool, Debugger, Schema Diff, ERD Tool ' - 'or PSQL Tool from the drop-down to set ' - 'open in new browser tab for that particular module.' - ), - select2={ - 'multiple': True, 'allowClear': False, - 'tags': True, 'first_empty': False, - 'selectOnClose': False, 'emptyOptions': True, - 'tokenSeparators': [','], - 'placeholder': gettext('Select open new tab...') - } - ) - - self.psql_tab_title = self.preference.register( - 'tab_settings', 'psql_tab_title_placeholder', - gettext("PSQL tool tab title"), - 'text', '%DATABASE%/%USERNAME%@%SERVER%', - category_label=PREF_LABEL_DISPLAY, - help_str=gettext( - 'Supported placeholders are %DATABASE%, %USERNAME%, ' - 'and %SERVER%. Users can provide any string with or without' - ' placeholders of their choice. The blank title will be revert' - ' back to the default title with placeholders.' + self.psql_tab_title = self.preference.register( + 'tab_settings', 'psql_tab_title_placeholder', + gettext("PSQL tool tab title"), + 'text', '%DATABASE%/%USERNAME%@%SERVER%', + category_label=PREF_LABEL_DISPLAY, + help_str=gettext( + 'Supported placeholders are %DATABASE%, %USERNAME%, ' + 'and %SERVER%. Users can provide any string with or without' + ' placeholders of their choice. The blank title will be revert' + ' back to the default title with placeholders.' + ) ) - ) diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 17268a4e..e38bf1b4 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -53,7 +53,7 @@ define('pgadmin.browser.utils', pgAdmin['override_user_inactivity_timeout'] = '{{ current_app.config.get('OVERRIDE_USER_INACTIVITY_TIMEOUT') }}' == 'True'; /* GET PSQL Tool related config */ - pgAdmin['enable_psql'] = '{{ current_app.config.get('ENABLE_PSQL') }}' == 'True'; + pgAdmin['enable_psql'] = '{{enable_psql}}' == 'True'; pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True'; pgAdmin['platform'] = '{{platform}}'; pgAdmin['qt_default_placeholder'] = '{{qt_default_placeholder}}' diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py index f62e0743..cb10d5db 100644 --- a/web/pgadmin/tools/psql/__init__.py +++ b/web/pgadmin/tools/psql/__init__.py @@ -20,7 +20,12 @@ from ... import socketio as sio from pgadmin.utils import get_complete_file_path if _platform == 'win32': - from winpty import PtyProcess + # Check Windows platform support for WinPty api, Disable psql + # if not supporting + try: + from winpty import PtyProcess + except ImportError as error: + config.ENABLE_PSQL = False else: import fcntl import termios ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 06:18 Akshay Joshi <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Akshay Joshi @ 2021-06-14 06:18 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: pgadmin-hackers; Fahar Abbas <[email protected]>; Dave Page <[email protected]> Thanks, the patch applied. On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < [email protected]> wrote: > Hi Team, > > PFA patch v8 > > On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < > [email protected]> wrote: > >> Hi Team, >> >> Please find the updated patch for the PSQL tool, Added check if the >> Windows version is not supporting the ConPty or WinPty disable the PSQL for >> that version. (PSQL option will not visible to the user). >> >> I have raised the issue with "pywinpty" >> https://github.com/spyder-ide/pywinpty/issues/161 >> >> Regards, >> Nikhil Mohite >> >> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>> [email protected]> wrote: >>> >>>> Hi Dave, >>>> >>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: >>>> >>>>> >>>>> >>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>> [email protected]> wrote: >>>>> >>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>> >>>>> >>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We need >>>>> to understand exactly what versions work and which don't. >>>>> >>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>> >>> >>> Great, thanks! >>> >>> >>>> >>>> Do I also need to test pgadmin4 on 1909 iso? >>>> >>> >>> I don't think so. I'm 99% certain that what we're seeing is that it >>> works on the versions of Windows that support conpty, but not the older >>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>> >>> Hopefully Nikhil can get to the bottom of the problem with the >>> pywinpty folks. >>> >>> >>> >>>> >>>>> >>>>>> Nikhil is not able to reproduce the issue on Windows 10 with the >>>>>> latest version. So the issue is reproducible with older versions. >>>>>> >>>>>> Kind Regards, >>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>> >>>>>>> >>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 please? >>>>>>> And if that doesn't work, try 1909. >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi, >>>>>>>>>> >>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>> Windows 2016 >>>>>>>>>> Windows 2012 >>>>>>>>>> Windows 07 >>>>>>>>>> Windows 2008R2 >>>>>>>>>> Windows 10 64 >>>>>>>>>> >>>>>>>>> >>>>>>>>> What version of Windows 10? I *think* conpty was introduced in >>>>>>>>> 1809. >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>> Windows 2019 >>>>>>>>>> >>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Dave, >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server >>>>>>>>>>>>>>>> 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>> Files required for winpty are present in the site-packages >>>>>>>>>>>>>>>> but still, it is unable to load the winpty.dll file on these specific >>>>>>>>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>>>>>>>> build it.) ref link for winPty >>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per the >>>>>>>>>>>>>> winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>> >>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it >>>>>>>>>>>>>> shows the user entered inputs on the same terminal, not showing any errors. >>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>> >>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git command >>>>>>>>>>>>>> line: C:\Program Files (x86)\Git\usr\bin) if try to run it through the >>>>>>>>>>>>>> command line not getting any error, it is showing user entered inputs on >>>>>>>>>>>>>> the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>> >>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't do a >>>>>>>>>>> simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>>>>>> >>>>>>>>>>> Could this be because it's trying to use the conpty interface in >>>>>>>>>>> Windows 10 and above? >>>>>>>>>>> >>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine to >>>>>>>>>>> simply hide the menu options and button if the server detects it's running >>>>>>>>>>> on an unsupported version of Windows. Of course, this should be documented. >>>>>>>>>>> We also need to make sure we know *exactly* what versions it does and does >>>>>>>>>>> not work on. >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Fahar Abbas >>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Fahar Abbas >>>>>>>> EnterpriseDB Corporation >>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>> Mobile: +92-333-5409707 >>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>> Website: www.enterprisedb.com >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Fahar Abbas >>>>>> EnterpriseDB Corporation >>>>>> Phone Office: +92-51-835-8874 >>>>>> Phone Direct: +92-51-8466803 >>>>>> Mobile: +92-333-5409707 >>>>>> Skype ID: *live:fahar.abbas* >>>>>> Website: www.enterprisedb.com >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >>>> >>>> -- >>>> Fahar Abbas >>>> EnterpriseDB Corporation >>>> Phone Office: +92-51-835-8874 >>>> Phone Direct: +92-51-8466803 >>>> Mobile: +92-333-5409707 >>>> Skype ID: *live:fahar.abbas* >>>> Website: www.enterprisedb.com >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 13:13 Nikhil Mohite <[email protected]> parent: Akshay Joshi <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-14 13:13 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: pgadmin-hackers; Fahar Abbas <[email protected]>; Dave Page <[email protected]> Hi Akshay, Please find the updated patch for psql, Updated invalid command logic added 3 more commands in it. 1. \copy or \COPY 2. \e or \E 3. \ef or \EF Now user can't execute these commands if allow shell commands is set to False. If required any changes please let me know. Regards, Nikhil Mohite On Mon, Jun 14, 2021 at 11:48 AM Akshay Joshi <[email protected]> wrote: > Thanks, the patch applied. > > On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < > [email protected]> wrote: > >> Hi Team, >> >> PFA patch v8 >> >> On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Team, >>> >>> Please find the updated patch for the PSQL tool, Added check if the >>> Windows version is not supporting the ConPty or WinPty disable the PSQL for >>> that version. (PSQL option will not visible to the user). >>> >>> I have raised the issue with "pywinpty" >>> https://github.com/spyder-ide/pywinpty/issues/161 >>> >>> Regards, >>> Nikhil Mohite >>> >>> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>>> [email protected]> wrote: >>>> >>>>> Hi Dave, >>>>> >>>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> >>>>>> >>>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>>> >>>>>> >>>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We need >>>>>> to understand exactly what versions work and which don't. >>>>>> >>>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>>> >>>> >>>> Great, thanks! >>>> >>>> >>>>> >>>>> Do I also need to test pgadmin4 on 1909 iso? >>>>> >>>> >>>> I don't think so. I'm 99% certain that what we're seeing is that it >>>> works on the versions of Windows that support conpty, but not the older >>>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>>> >>>> Hopefully Nikhil can get to the bottom of the problem with the >>>> pywinpty folks. >>>> >>>> >>>> >>>>> >>>>>> >>>>>>> Nikhil is not able to reproduce the issue on Windows 10 with the >>>>>>> latest version. So the issue is reproducible with older versions. >>>>>>> >>>>>>> Kind Regards, >>>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>>> >>>>>>>> >>>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 please? >>>>>>>> And if that doesn't work, try 1909. >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi, >>>>>>>>>>> >>>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>>> Windows 2016 >>>>>>>>>>> Windows 2012 >>>>>>>>>>> Windows 07 >>>>>>>>>>> Windows 2008R2 >>>>>>>>>>> Windows 10 64 >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> What version of Windows 10? I *think* conpty was introduced in >>>>>>>>>> 1809. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>>> Windows 2019 >>>>>>>>>>> >>>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server >>>>>>>>>>>>>>>>> 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>>> Files required for winpty are present in the site-packages >>>>>>>>>>>>>>>>> but still, it is unable to load the winpty.dll file on these specific >>>>>>>>>>>>>>>>> platforms. We have tested it on Windows 10 pro and Windows server 2019 and >>>>>>>>>>>>>>>>> it is working fine. (Also tried building the local pywinpty but unable to >>>>>>>>>>>>>>>>> build it.) ref link for winPty >>>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per the >>>>>>>>>>>>>>> winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it >>>>>>>>>>>>>>> shows the user entered inputs on the same terminal, not showing any errors. >>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git >>>>>>>>>>>>>>> command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through >>>>>>>>>>>>>>> the command line not getting any error, it is showing user entered inputs >>>>>>>>>>>>>>> on the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>>> >>>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't do a >>>>>>>>>>>> simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>>>>>>> >>>>>>>>>>>> Could this be because it's trying to use the conpty interface >>>>>>>>>>>> in Windows 10 and above? >>>>>>>>>>>> >>>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine to >>>>>>>>>>>> simply hide the menu options and button if the server detects it's running >>>>>>>>>>>> on an unsupported version of Windows. Of course, this should be documented. >>>>>>>>>>>> We also need to make sure we know *exactly* what versions it does and does >>>>>>>>>>>> not work on. >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Fahar Abbas >>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Fahar Abbas >>>>>>>>> EnterpriseDB Corporation >>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>> Website: www.enterprisedb.com >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Fahar Abbas >>>>>>> EnterpriseDB Corporation >>>>>>> Phone Office: +92-51-835-8874 >>>>>>> Phone Direct: +92-51-8466803 >>>>>>> Mobile: +92-333-5409707 >>>>>>> Skype ID: *live:fahar.abbas* >>>>>>> Website: www.enterprisedb.com >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> >>>>> >>>>> -- >>>>> Fahar Abbas >>>>> EnterpriseDB Corporation >>>>> Phone Office: +92-51-835-8874 >>>>> Phone Direct: +92-51-8466803 >>>>> Mobile: +92-333-5409707 >>>>> Skype ID: *live:fahar.abbas* >>>>> Website: www.enterprisedb.com >>>>> >>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image [application/octet-stream] RM_2341_v9.patch (2.8K, 5-RM_2341_v9.patch) download | inline diff: diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py index cb10d5db..befd2e0e 100644 --- a/web/pgadmin/tools/psql/__init__.py +++ b/web/pgadmin/tools/psql/__init__.py @@ -495,8 +495,9 @@ def invalid_cmd(): def check_valid_cmd(user_input): """ - Check if user entered a valid cmd and \\! command is preset as a string - only in current executing command. if \\! is present as command don't + Check if user entered a valid cmd and \\!, \\copy, \\e and \\ef command is + preset as a string only in current executing command. + if \\!, \\copy, \\e and \\ef is present as command don't allow the execution of command. :param user_input: :return: @@ -512,6 +513,12 @@ def check_valid_cmd(user_input): if re.search("\\\!", sub_str): stop_execution = False # break + if re.search("\\\copy", sub_str.lower()): + stop_execution = False + if re.search("\\\e", sub_str.lower()): + stop_execution = False + if re.search("\\\ef", sub_str.lower()): + stop_execution = False if stop_execution: session_last_cmd[request.sid]['invalid_cmd'] = True @@ -570,6 +577,30 @@ def enter_key_press(data): not config.ALLOW_PSQL_SHELL_COMMANDS and\ not session_last_cmd[request.sid]['is_new_connection']: check_valid_cmd(user_input) + elif (user_input.lower().startswith('\copy') and + re.match("^\\\copy$", user_input.lower()))\ + and not config.ALLOW_PSQL_SHELL_COMMANDS: + invalid_cmd() + elif re.search("\\\copy", user_input.lower()) \ + and not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif (user_input.lower().startswith('\e') and + re.match("^\\\e$", user_input.lower())) and\ + not config.ALLOW_PSQL_SHELL_COMMANDS: + invalid_cmd() + elif re.search("\\\e", user_input.lower()) \ + and not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif (user_input.lower().startswith('\ef') and + re.match("^\\\ef$", user_input.lower())) and\ + not config.ALLOW_PSQL_SHELL_COMMANDS: + invalid_cmd() + elif re.search("\\\ef", user_input.lower()) \ + and not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) elif user_input == '\q' or user_input == 'q\\q' or user_input in ['exit', 'exit;']: # If user enter \q to terminate the PSQL, emit the msg to ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 13:18 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-14 13:18 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers; Fahar Abbas <[email protected]> Hi On Mon, Jun 14, 2021 at 2:13 PM Nikhil Mohite < [email protected]> wrote: > Hi Akshay, > > Please find the updated patch for psql, Updated invalid command logic > added 3 more commands in it. > 1. \copy or \COPY > 2. \e or \E > 3. \ef or \EF > Should they just be case insensitive? > > Now user can't execute these commands if allow shell commands is set to > False. > What about \lo_import and \lo_export? I think those are potentially dangerous too. Also, \echo. > > If required any changes please let me know. > > Regards, > Nikhil Mohite > > On Mon, Jun 14, 2021 at 11:48 AM Akshay Joshi < > [email protected]> wrote: > >> Thanks, the patch applied. >> >> On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Team, >>> >>> PFA patch v8 >>> >>> On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Team, >>>> >>>> Please find the updated patch for the PSQL tool, Added check if the >>>> Windows version is not supporting the ConPty or WinPty disable the PSQL for >>>> that version. (PSQL option will not visible to the user). >>>> >>>> I have raised the issue with "pywinpty" >>>> https://github.com/spyder-ide/pywinpty/issues/161 >>>> >>>> Regards, >>>> Nikhil Mohite >>>> >>>> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Dave, >>>>>> >>>>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>>>> >>>>>>> >>>>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We need >>>>>>> to understand exactly what versions work and which don't. >>>>>>> >>>>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>>>> >>>>> >>>>> Great, thanks! >>>>> >>>>> >>>>>> >>>>>> Do I also need to test pgadmin4 on 1909 iso? >>>>>> >>>>> >>>>> I don't think so. I'm 99% certain that what we're seeing is that it >>>>> works on the versions of Windows that support conpty, but not the older >>>>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>>>> >>>>> Hopefully Nikhil can get to the bottom of the problem with the >>>>> pywinpty folks. >>>>> >>>>> >>>>> >>>>>> >>>>>>> >>>>>>>> Nikhil is not able to reproduce the issue on Windows 10 with the >>>>>>>> latest version. So the issue is reproducible with older versions. >>>>>>>> >>>>>>>> Kind Regards, >>>>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>>>> >>>>>>>>> >>>>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 please? >>>>>>>>> And if that doesn't work, try 1909. >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi, >>>>>>>>>>>> >>>>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>>>> Windows 2016 >>>>>>>>>>>> Windows 2012 >>>>>>>>>>>> Windows 07 >>>>>>>>>>>> Windows 2008R2 >>>>>>>>>>>> Windows 10 64 >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> What version of Windows 10? I *think* conpty was introduced in >>>>>>>>>>> 1809. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>>>> Windows 2019 >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server >>>>>>>>>>>>>>>>>> 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>>>> Files required for winpty are present in the >>>>>>>>>>>>>>>>>> site-packages but still, it is unable to load the winpty.dll file on these >>>>>>>>>>>>>>>>>> specific platforms. We have tested it on Windows 10 pro and Windows server >>>>>>>>>>>>>>>>>> 2019 and it is working fine. (Also tried building the local pywinpty but >>>>>>>>>>>>>>>>>> unable to build it.) ref link for winPty >>>>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per the >>>>>>>>>>>>>>>> winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, it >>>>>>>>>>>>>>>> shows the user entered inputs on the same terminal, not showing any errors. >>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git >>>>>>>>>>>>>>>> command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through >>>>>>>>>>>>>>>> the command line not getting any error, it is showing user entered inputs >>>>>>>>>>>>>>>> on the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>>>> >>>>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't do >>>>>>>>>>>>> a simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>>>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>>>>>>>> >>>>>>>>>>>>> Could this be because it's trying to use the conpty interface >>>>>>>>>>>>> in Windows 10 and above? >>>>>>>>>>>>> >>>>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine to >>>>>>>>>>>>> simply hide the menu options and button if the server detects it's running >>>>>>>>>>>>> on an unsupported version of Windows. Of course, this should be documented. >>>>>>>>>>>>> We also need to make sure we know *exactly* what versions it does and does >>>>>>>>>>>>> not work on. >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Fahar Abbas >>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Fahar Abbas >>>>>>>> EnterpriseDB Corporation >>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>> Mobile: +92-333-5409707 >>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>> Website: www.enterprisedb.com >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Fahar Abbas >>>>>> EnterpriseDB Corporation >>>>>> Phone Office: +92-51-835-8874 >>>>>> Phone Direct: +92-51-8466803 >>>>>> Mobile: +92-333-5409707 >>>>>> Skype ID: *live:fahar.abbas* >>>>>> Website: www.enterprisedb.com >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 14:17 Nikhil Mohite <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-14 14:17 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: pgadmin-hackers; Fahar Abbas <[email protected]>; Dave Page <[email protected]> Hi Akshay, I have added the following commands for invalid command check: 1. \lo_import 2. \lo_export 3. \w or write 4. \o or \output 5. \g I am referring to the https://www.postgresql.org/docs/12/app-psql.html link for finding the commands. PFA patch V10. On Mon, Jun 14, 2021 at 6:48 PM Dave Page <[email protected]> wrote: > Hi > > On Mon, Jun 14, 2021 at 2:13 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Akshay, >> >> Please find the updated patch for psql, Updated invalid command logic >> added 3 more commands in it. >> 1. \copy or \COPY >> 2. \e or \E >> 3. \ef or \EF >> > > Should they just be case insensitive? > \ commands are case sensitive. > > >> >> Now user can't execute these commands if allow shell commands is set to >> False. >> > > What about \lo_import and \lo_export? I think those are potentially > dangerous too. Also, \echo. > added this as well. > > >> >> If required any changes please let me know. >> >> Regards, >> Nikhil Mohite >> >> On Mon, Jun 14, 2021 at 11:48 AM Akshay Joshi < >> [email protected]> wrote: >> >>> Thanks, the patch applied. >>> >>> On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Team, >>>> >>>> PFA patch v8 >>>> >>>> On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Team, >>>>> >>>>> Please find the updated patch for the PSQL tool, Added check if the >>>>> Windows version is not supporting the ConPty or WinPty disable the PSQL for >>>>> that version. (PSQL option will not visible to the user). >>>>> >>>>> I have raised the issue with "pywinpty" >>>>> https://github.com/spyder-ide/pywinpty/issues/161 >>>>> >>>>> Regards, >>>>> Nikhil Mohite >>>>> >>>>> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> wrote: >>>>> >>>>>> Hi >>>>>> >>>>>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Dave, >>>>>>> >>>>>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>>>>> >>>>>>>> >>>>>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We >>>>>>>> need to understand exactly what versions work and which don't. >>>>>>>> >>>>>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>>>>> >>>>>> >>>>>> Great, thanks! >>>>>> >>>>>> >>>>>>> >>>>>>> Do I also need to test pgadmin4 on 1909 iso? >>>>>>> >>>>>> >>>>>> I don't think so. I'm 99% certain that what we're seeing is that it >>>>>> works on the versions of Windows that support conpty, but not the older >>>>>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>>>>> >>>>>> Hopefully Nikhil can get to the bottom of the problem with the >>>>>> pywinpty folks. >>>>>> >>>>>> >>>>>> >>>>>>> >>>>>>>> >>>>>>>>> Nikhil is not able to reproduce the issue on Windows 10 with the >>>>>>>>> latest version. So the issue is reproducible with older versions. >>>>>>>>> >>>>>>>>> Kind Regards, >>>>>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 >>>>>>>>>> please? And if that doesn't work, try 1909. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi, >>>>>>>>>>>>> >>>>>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>>>>> Windows 2016 >>>>>>>>>>>>> Windows 2012 >>>>>>>>>>>>> Windows 07 >>>>>>>>>>>>> Windows 2008R2 >>>>>>>>>>>>> Windows 10 64 >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> What version of Windows 10? I *think* conpty was introduced in >>>>>>>>>>>> 1809. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>>>>> Windows 2019 >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows server >>>>>>>>>>>>>>>>>>> 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>>>>> Files required for winpty are present in the >>>>>>>>>>>>>>>>>>> site-packages but still, it is unable to load the winpty.dll file on these >>>>>>>>>>>>>>>>>>> specific platforms. We have tested it on Windows 10 pro and Windows server >>>>>>>>>>>>>>>>>>> 2019 and it is working fine. (Also tried building the local pywinpty but >>>>>>>>>>>>>>>>>>> unable to build it.) ref link for winPty >>>>>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per the >>>>>>>>>>>>>>>>> winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, >>>>>>>>>>>>>>>>> it shows the user entered inputs on the same terminal, not showing any >>>>>>>>>>>>>>>>> errors. >>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git >>>>>>>>>>>>>>>>> command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through >>>>>>>>>>>>>>>>> the command line not getting any error, it is showing user entered inputs >>>>>>>>>>>>>>>>> on the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't do >>>>>>>>>>>>>> a simple import of winpty. On 2019 it's fine. I tried various tricks that >>>>>>>>>>>>>> I've used in the past to make sure libraries are found etc. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Could this be because it's trying to use the conpty interface >>>>>>>>>>>>>> in Windows 10 and above? >>>>>>>>>>>>>> >>>>>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine to >>>>>>>>>>>>>> simply hide the menu options and button if the server detects it's running >>>>>>>>>>>>>> on an unsupported version of Windows. Of course, this should be documented. >>>>>>>>>>>>>> We also need to make sure we know *exactly* what versions it does and does >>>>>>>>>>>>>> not work on. >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Fahar Abbas >>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Fahar Abbas >>>>>>>>> EnterpriseDB Corporation >>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>> Website: www.enterprisedb.com >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Fahar Abbas >>>>>>> EnterpriseDB Corporation >>>>>>> Phone Office: +92-51-835-8874 >>>>>>> Phone Direct: +92-51-8466803 >>>>>>> Mobile: +92-333-5409707 >>>>>>> Skype ID: *live:fahar.abbas* >>>>>>> Website: www.enterprisedb.com >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Dave Page >>>>>> Blog: https://pgsnake.blogspot.com >>>>>> Twitter: @pgsnake >>>>>> >>>>>> EDB: https://www.enterprisedb.com >>>>>> >>>>>> >>> >>> -- >>> *Thanks & Regards* >>> *Akshay Joshi* >>> *pgAdmin Hacker | Principal Software Architect* >>> *EDB Postgres <http://edbpostgres.com>* >>> >>> *Mobile: +91 976-788-8246* >>> >> > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > Regards, Nikhil Mohite Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image [application/octet-stream] RM_2341_v10.patch (6.6K, 5-RM_2341_v10.patch) download | inline diff: diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py index cb10d5db..e99d169b 100644 --- a/web/pgadmin/tools/psql/__init__.py +++ b/web/pgadmin/tools/psql/__init__.py @@ -495,8 +495,9 @@ def invalid_cmd(): def check_valid_cmd(user_input): """ - Check if user entered a valid cmd and \\! command is preset as a string - only in current executing command. if \\! is present as command don't + Check if user entered a valid cmd and \\!, \\copy, \\e and \\ef command is + preset as a string only in current executing command. + if \\!, \\copy, \\e and \\ef is present as command don't allow the execution of command. :param user_input: :return: @@ -512,6 +513,26 @@ def check_valid_cmd(user_input): if re.search("\\\!", sub_str): stop_execution = False # break + if re.search("\\\copy", sub_str.lower()): + stop_execution = False + if re.search("\\\e", sub_str.lower()): + stop_execution = False + if re.search("\\\ef", sub_str.lower()): + stop_execution = False + if re.search("\\\i", sub_str.lower()): + stop_execution = False + if re.search("\\\lo_import", sub_str.lower()) or \ + re.search("lo_import", sub_str.lower()): + stop_execution = False + if re.search("\\\lo_export", sub_str.lower()) or \ + re.search("lo_export", sub_str.lower()): + stop_execution = False + if re.search("\\\g", sub_str.lower()): + stop_execution = False + if re.search("\\\o", sub_str.lower()): + stop_execution = False + if re.search("\\\w", sub_str.lower()): + stop_execution = False if stop_execution: session_last_cmd[request.sid]['invalid_cmd'] = True @@ -570,8 +591,87 @@ def enter_key_press(data): not config.ALLOW_PSQL_SHELL_COMMANDS and\ not session_last_cmd[request.sid]['is_new_connection']: check_valid_cmd(user_input) - elif user_input == '\q' or user_input == 'q\\q' or user_input in ['exit', - 'exit;']: + elif (user_input.lower().startswith('\copy') and + re.match("^\\\copy$", user_input.lower()))\ + and not config.ALLOW_PSQL_SHELL_COMMANDS: + invalid_cmd() + elif re.search("\\\copy", user_input.lower()) \ + and not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif (user_input.lower().startswith('\e') and + re.match("^\\\e$", user_input.lower())) and\ + not config.ALLOW_PSQL_SHELL_COMMANDS: + invalid_cmd() + elif re.search("\\\e", user_input.lower()) \ + and not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif (user_input.lower().startswith('\ef') and + re.match("^\\\ef$", user_input.lower())) and\ + not config.ALLOW_PSQL_SHELL_COMMANDS: + invalid_cmd() + elif re.search("\\\ef", user_input.lower()) \ + and not config.ALLOW_PSQL_SHELL_COMMANDS \ + and not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif user_input.lower().startswith('\i') and \ + re.match("^\\\i$", user_input) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and not is_new_connection: + invalid_cmd() + elif re.search("\\\i", user_input.lower()) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif (user_input.lower().startswith('\lo_import') or + user_input.lower().startswith('lo_import')) and \ + (re.match("^\\\lo_import$", user_input.lower()) or + re.match("^lo_import$", user_input.lower())) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and not is_new_connection: + invalid_cmd() + elif (re.search("\\\lo_import", user_input.lower()) or + re.search("lo_import", user_input.lower())) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif (user_input.lower().startswith('\lo_export') or + user_input.lower().startswith('lo_export')) and \ + (re.match("^\\\lo_export$", user_input.lower()) or + re.match("^lo_export$", user_input.lower())) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and not is_new_connection: + invalid_cmd() + elif (re.search("\\\lo_export", user_input.lower()) or + re.search("lo_export", user_input.lower())) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif user_input.lower().startswith('\g') and \ + re.match("^\\\g$", user_input.lower()) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and not is_new_connection: + invalid_cmd() + elif re.search("\\\g", user_input.lower()) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif user_input.lower().startswith('\o') and \ + re.match("^\\\o$", user_input.lower()) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and not is_new_connection: + invalid_cmd() + elif re.search("\\\o", user_input.lower()) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + elif user_input.lower().startswith('\w') and \ + re.match("^\\\w$", user_input.lower()) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and not is_new_connection: + invalid_cmd() + elif re.search("\\\w", user_input.lower()) and \ + not config.ALLOW_PSQL_SHELL_COMMANDS and \ + not session_last_cmd[request.sid]['is_new_connection']: + check_valid_cmd(user_input) + + elif user_input == '\q' or user_input == 'q\\q' or user_input in\ + ['\quit','exit', 'exit;']: # If user enter \q to terminate the PSQL, emit the msg to # notify user connection is terminated. sio.emit('pty-output', ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 14:26 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 1 reply; 54+ messages in thread From: Dave Page @ 2021-06-14 14:26 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers; Fahar Abbas <[email protected]> Hi On Mon, Jun 14, 2021 at 3:18 PM Nikhil Mohite < [email protected]> wrote: > Hi Akshay, > > I have added the following commands for invalid command check: > > 1. \lo_import > 2. \lo_export > 3. \w or write > 4. \o or \output > 5. \g > > \qecho? \ev? I'm very concerned we're missing more here, and will continue to miss new commands that are added to psql in the future. I think we need to disable the feature entirely in server mode by default, and probably remove the code that attempts to filter out commands. Then it just becomes a case of "this can be dangerous in server mode, as your user will be able to run arbitrary commands on the server. Enable at your own risk". > I am referring to the https://www.postgresql.org/docs/12/app-psql.html > link for finding the commands. > PFA patch V10. > > > On Mon, Jun 14, 2021 at 6:48 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Mon, Jun 14, 2021 at 2:13 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Akshay, >>> >>> Please find the updated patch for psql, Updated invalid command logic >>> added 3 more commands in it. >>> 1. \copy or \COPY >>> 2. \e or \E >>> 3. \ef or \EF >>> >> >> Should they just be case insensitive? >> > \ commands are case sensitive. > So what are \E and \EF? I can't see them in the pg13 docs. > >> >>> >>> Now user can't execute these commands if allow shell commands is set to >>> False. >>> >> >> What about \lo_import and \lo_export? I think those are potentially >> dangerous too. Also, \echo. >> > added this as well. > >> >> >>> >>> If required any changes please let me know. >>> >>> Regards, >>> Nikhil Mohite >>> >>> On Mon, Jun 14, 2021 at 11:48 AM Akshay Joshi < >>> [email protected]> wrote: >>> >>>> Thanks, the patch applied. >>>> >>>> On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Team, >>>>> >>>>> PFA patch v8 >>>>> >>>>> On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Team, >>>>>> >>>>>> Please find the updated patch for the PSQL tool, Added check if the >>>>>> Windows version is not supporting the ConPty or WinPty disable the PSQL for >>>>>> that version. (PSQL option will not visible to the user). >>>>>> >>>>>> I have raised the issue with "pywinpty" >>>>>> https://github.com/spyder-ide/pywinpty/issues/161 >>>>>> >>>>>> Regards, >>>>>> Nikhil Mohite >>>>>> >>>>>> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Dave, >>>>>>>> >>>>>>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>>>>>> >>>>>>>>> >>>>>>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We >>>>>>>>> need to understand exactly what versions work and which don't. >>>>>>>>> >>>>>>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>>>>>> >>>>>>> >>>>>>> Great, thanks! >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> Do I also need to test pgadmin4 on 1909 iso? >>>>>>>> >>>>>>> >>>>>>> I don't think so. I'm 99% certain that what we're seeing is that it >>>>>>> works on the versions of Windows that support conpty, but not the older >>>>>>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>>>>>> >>>>>>> Hopefully Nikhil can get to the bottom of the problem with the >>>>>>> pywinpty folks. >>>>>>> >>>>>>> >>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>>> Nikhil is not able to reproduce the issue on Windows 10 with the >>>>>>>>>> latest version. So the issue is reproducible with older versions. >>>>>>>>>> >>>>>>>>>> Kind Regards, >>>>>>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 >>>>>>>>>>> please? And if that doesn't work, try 1909. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi >>>>>>>>>>>>> >>>>>>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>> >>>>>>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>>>>>> Windows 2016 >>>>>>>>>>>>>> Windows 2012 >>>>>>>>>>>>>> Windows 07 >>>>>>>>>>>>>> Windows 2008R2 >>>>>>>>>>>>>> Windows 10 64 >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> What version of Windows 10? I *think* conpty was introduced in >>>>>>>>>>>>> 1809. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>>>>>> Windows 2019 >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows >>>>>>>>>>>>>>>>>>>> server 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>>>>>> Files required for winpty are present in the >>>>>>>>>>>>>>>>>>>> site-packages but still, it is unable to load the winpty.dll file on these >>>>>>>>>>>>>>>>>>>> specific platforms. We have tested it on Windows 10 pro and Windows server >>>>>>>>>>>>>>>>>>>> 2019 and it is working fine. (Also tried building the local pywinpty but >>>>>>>>>>>>>>>>>>>> unable to build it.) ref link for winPty >>>>>>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per the >>>>>>>>>>>>>>>>>> winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, >>>>>>>>>>>>>>>>>> it shows the user entered inputs on the same terminal, not showing any >>>>>>>>>>>>>>>>>> errors. >>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git >>>>>>>>>>>>>>>>>> command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through >>>>>>>>>>>>>>>>>> the command line not getting any error, it is showing user entered inputs >>>>>>>>>>>>>>>>>> on the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't >>>>>>>>>>>>>>> do a simple import of winpty. On 2019 it's fine. I tried various tricks >>>>>>>>>>>>>>> that I've used in the past to make sure libraries are found etc. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Could this be because it's trying to use the >>>>>>>>>>>>>>> conpty interface in Windows 10 and above? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine to >>>>>>>>>>>>>>> simply hide the menu options and button if the server detects it's running >>>>>>>>>>>>>>> on an unsupported version of Windows. Of course, this should be documented. >>>>>>>>>>>>>>> We also need to make sure we know *exactly* what versions it does and does >>>>>>>>>>>>>>> not work on. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Fahar Abbas >>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Fahar Abbas >>>>>>>> EnterpriseDB Corporation >>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>> Mobile: +92-333-5409707 >>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>> Website: www.enterprisedb.com >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EDB: https://www.enterprisedb.com >>>>>>> >>>>>>> >>>> >>>> -- >>>> *Thanks & Regards* >>>> *Akshay Joshi* >>>> *pgAdmin Hacker | Principal Software Architect* >>>> *EDB Postgres <http://edbpostgres.com>* >>>> >>>> *Mobile: +91 976-788-8246* >>>> >>> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> Regards, > Nikhil Mohite > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 14:35 Akshay Joshi <[email protected]> parent: Dave Page <[email protected]> 0 siblings, 2 replies; 54+ messages in thread From: Akshay Joshi @ 2021-06-14 14:35 UTC (permalink / raw) To: Dave Page <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Fahar Abbas <[email protected]> Hi Dave On Mon, Jun 14, 2021 at 7:57 PM Dave Page <[email protected]> wrote: > Hi > > On Mon, Jun 14, 2021 at 3:18 PM Nikhil Mohite < > [email protected]> wrote: > >> Hi Akshay, >> >> I have added the following commands for invalid command check: >> >> 1. \lo_import >> 2. \lo_export >> 3. \w or write >> 4. \o or \output >> 5. \g >> >> \qecho? \ev? > > I'm very concerned we're missing more here, and will continue to miss new > commands that are added to psql in the future. > > I think we need to disable the feature entirely in server mode by default, > and probably remove the code that attempts to filter out commands. > If I understand correctly we need to change in config.py and make ENABLE_PSQL = False in server mode. > > Then it just becomes a case of "this can be dangerous in server mode, as > your user will be able to run arbitrary commands on the server. Enable at > your own risk". > The above note will go into the config.py as a comment or in the documentation. > > >> I am referring to the https://www.postgresql.org/docs/12/app-psql.html >> link for finding the commands. >> PFA patch V10. >> >> >> On Mon, Jun 14, 2021 at 6:48 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Mon, Jun 14, 2021 at 2:13 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Akshay, >>>> >>>> Please find the updated patch for psql, Updated invalid command logic >>>> added 3 more commands in it. >>>> 1. \copy or \COPY >>>> 2. \e or \E >>>> 3. \ef or \EF >>>> >>> >>> Should they just be case insensitive? >>> >> \ commands are case sensitive. >> > > So what are \E and \EF? I can't see them in the pg13 docs. > > >> >>> >>>> >>>> Now user can't execute these commands if allow shell commands is set to >>>> False. >>>> >>> >>> What about \lo_import and \lo_export? I think those are potentially >>> dangerous too. Also, \echo. >>> >> added this as well. >> >>> >>> >>>> >>>> If required any changes please let me know. >>>> >>>> Regards, >>>> Nikhil Mohite >>>> >>>> On Mon, Jun 14, 2021 at 11:48 AM Akshay Joshi < >>>> [email protected]> wrote: >>>> >>>>> Thanks, the patch applied. >>>>> >>>>> On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Team, >>>>>> >>>>>> PFA patch v8 >>>>>> >>>>>> On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Team, >>>>>>> >>>>>>> Please find the updated patch for the PSQL tool, Added check if the >>>>>>> Windows version is not supporting the ConPty or WinPty disable the PSQL for >>>>>>> that version. (PSQL option will not visible to the user). >>>>>>> >>>>>>> I have raised the issue with "pywinpty" >>>>>>> https://github.com/spyder-ide/pywinpty/issues/161 >>>>>>> >>>>>>> Regards, >>>>>>> Nikhil Mohite >>>>>>> >>>>>>> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> wrote: >>>>>>> >>>>>>>> Hi >>>>>>>> >>>>>>>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Dave, >>>>>>>>> >>>>>>>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We >>>>>>>>>> need to understand exactly what versions work and which don't. >>>>>>>>>> >>>>>>>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>>>>>>> >>>>>>>> >>>>>>>> Great, thanks! >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> Do I also need to test pgadmin4 on 1909 iso? >>>>>>>>> >>>>>>>> >>>>>>>> I don't think so. I'm 99% certain that what we're seeing is that it >>>>>>>> works on the versions of Windows that support conpty, but not the older >>>>>>>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>>>>>>> >>>>>>>> Hopefully Nikhil can get to the bottom of the problem with the >>>>>>>> pywinpty folks. >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>>> Nikhil is not able to reproduce the issue on Windows 10 with the >>>>>>>>>>> latest version. So the issue is reproducible with older versions. >>>>>>>>>>> >>>>>>>>>>> Kind Regards, >>>>>>>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 >>>>>>>>>>>> please? And if that doesn't work, try 1909. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>>>>>>> Windows 2016 >>>>>>>>>>>>>>> Windows 2012 >>>>>>>>>>>>>>> Windows 07 >>>>>>>>>>>>>>> Windows 2008R2 >>>>>>>>>>>>>>> Windows 10 64 >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> What version of Windows 10? I *think* conpty was introduced >>>>>>>>>>>>>> in 1809. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>>>>>>> Windows 2019 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows >>>>>>>>>>>>>>>>>>>>> server 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>>>>>>> Files required for winpty are present in the >>>>>>>>>>>>>>>>>>>>> site-packages but still, it is unable to load the winpty.dll file on these >>>>>>>>>>>>>>>>>>>>> specific platforms. We have tested it on Windows 10 pro and Windows server >>>>>>>>>>>>>>>>>>>>> 2019 and it is working fine. (Also tried building the local pywinpty but >>>>>>>>>>>>>>>>>>>>> unable to build it.) ref link for winPty >>>>>>>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per >>>>>>>>>>>>>>>>>>> the winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command line, >>>>>>>>>>>>>>>>>>> it shows the user entered inputs on the same terminal, not showing any >>>>>>>>>>>>>>>>>>> errors. >>>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git >>>>>>>>>>>>>>>>>>> command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through >>>>>>>>>>>>>>>>>>> the command line not getting any error, it is showing user entered inputs >>>>>>>>>>>>>>>>>>> on the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't >>>>>>>>>>>>>>>> do a simple import of winpty. On 2019 it's fine. I tried various tricks >>>>>>>>>>>>>>>> that I've used in the past to make sure libraries are found etc. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Could this be because it's trying to use the >>>>>>>>>>>>>>>> conpty interface in Windows 10 and above? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine to >>>>>>>>>>>>>>>> simply hide the menu options and button if the server detects it's running >>>>>>>>>>>>>>>> on an unsupported version of Windows. Of course, this should be documented. >>>>>>>>>>>>>>>> We also need to make sure we know *exactly* what versions it does and does >>>>>>>>>>>>>>>> not work on. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Fahar Abbas >>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Fahar Abbas >>>>>>>>> EnterpriseDB Corporation >>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>> Website: www.enterprisedb.com >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Dave Page >>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>> Twitter: @pgsnake >>>>>>>> >>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>> >>>>>>>> >>>>> >>>>> -- >>>>> *Thanks & Regards* >>>>> *Akshay Joshi* >>>>> *pgAdmin Hacker | Principal Software Architect* >>>>> *EDB Postgres <http://edbpostgres.com>* >>>>> >>>>> *Mobile: +91 976-788-8246* >>>>> >>>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> Regards, >> Nikhil Mohite >> > > > -- > Dave Page > Blog: https://pgsnake.blogspot.com > Twitter: @pgsnake > > EDB: https://www.enterprisedb.com > > -- *Thanks & Regards* *Akshay Joshi* *pgAdmin Hacker | Principal Software Architect* *EDB Postgres <http://edbpostgres.com>* *Mobile: +91 976-788-8246* Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 14:43 Nikhil Mohite <[email protected]> parent: Akshay Joshi <[email protected]> 1 sibling, 1 reply; 54+ messages in thread From: Nikhil Mohite @ 2021-06-14 14:43 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: Dave Page <[email protected]>; pgadmin-hackers; Fahar Abbas <[email protected]> Hi Dave, On Mon, Jun 14, 2021 at 8:05 PM Akshay Joshi <[email protected]> wrote: > Hi Dave > > On Mon, Jun 14, 2021 at 7:57 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Mon, Jun 14, 2021 at 3:18 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Akshay, >>> >>> I have added the following commands for invalid command check: >>> >>> 1. \lo_import >>> 2. \lo_export >>> 3. \w or write >>> 4. \o or \output >>> 5. \g >>> >>> \qecho? \ev? >> >> I'm very concerned we're missing more here, and will continue to miss new >> commands that are added to psql in the future. >> >> I think we need to disable the feature entirely in server mode by >> default, and probably remove the code that attempts to filter out commands. >> > In this case, ALLOW_SHELL_COMMAND will be not useful, should we remove it from config.py? > > If I understand correctly we need to change in config.py and make > ENABLE_PSQL = False in server mode. > >> >> Then it just becomes a case of "this can be dangerous in server mode, as >> your user will be able to run arbitrary commands on the server. Enable at >> your own risk". >> > > The above note will go into the config.py as a comment or in the > documentation. > >> >>> I am referring to the https://www.postgresql.org/docs/12/app-psql.html >>> link for finding the commands. >>> PFA patch V10. >>> >>> >>> On Mon, Jun 14, 2021 at 6:48 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Mon, Jun 14, 2021 at 2:13 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Akshay, >>>>> >>>>> Please find the updated patch for psql, Updated invalid command logic >>>>> added 3 more commands in it. >>>>> 1. \copy or \COPY >>>>> 2. \e or \E >>>>> 3. \ef or \EF >>>>> >>>> >>>> Should they just be case insensitive? >>>> >>> \ commands are case sensitive. >>> >> >> So what are \E and \EF? I can't see them in the pg13 docs. >> > These commands open the vi editor on macOS and notepad on windows for writing the commands. > >> >>> >>>> >>>>> >>>>> Now user can't execute these commands if allow shell commands is set >>>>> to False. >>>>> >>>> >>>> What about \lo_import and \lo_export? I think those are potentially >>>> dangerous too. Also, \echo. >>>> >>> added this as well. >>> >>>> >>>> >>>>> >>>>> If required any changes please let me know. >>>>> >>>>> Regards, >>>>> Nikhil Mohite >>>>> >>>>> On Mon, Jun 14, 2021 at 11:48 AM Akshay Joshi < >>>>> [email protected]> wrote: >>>>> >>>>>> Thanks, the patch applied. >>>>>> >>>>>> On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Team, >>>>>>> >>>>>>> PFA patch v8 >>>>>>> >>>>>>> On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Team, >>>>>>>> >>>>>>>> Please find the updated patch for the PSQL tool, Added check if the >>>>>>>> Windows version is not supporting the ConPty or WinPty disable the PSQL for >>>>>>>> that version. (PSQL option will not visible to the user). >>>>>>>> >>>>>>>> I have raised the issue with "pywinpty" >>>>>>>> https://github.com/spyder-ide/pywinpty/issues/161 >>>>>>>> >>>>>>>> Regards, >>>>>>>> Nikhil Mohite >>>>>>>> >>>>>>>> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave, >>>>>>>>>> >>>>>>>>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We >>>>>>>>>>> need to understand exactly what versions work and which don't. >>>>>>>>>>> >>>>>>>>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>>>>>>>> >>>>>>>>> >>>>>>>>> Great, thanks! >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> Do I also need to test pgadmin4 on 1909 iso? >>>>>>>>>> >>>>>>>>> >>>>>>>>> I don't think so. I'm 99% certain that what we're seeing is that >>>>>>>>> it works on the versions of Windows that support conpty, but not the older >>>>>>>>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>>>>>>>> >>>>>>>>> Hopefully Nikhil can get to the bottom of the problem with the >>>>>>>>> pywinpty folks. >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> Nikhil is not able to reproduce the issue on Windows 10 with >>>>>>>>>>>> the latest version. So the issue is reproducible with older versions. >>>>>>>>>>>> >>>>>>>>>>>> Kind Regards, >>>>>>>>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 >>>>>>>>>>>>> please? And if that doesn't work, try 1909. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>>>>>>>> Windows 2016 >>>>>>>>>>>>>>>> Windows 2012 >>>>>>>>>>>>>>>> Windows 07 >>>>>>>>>>>>>>>> Windows 2008R2 >>>>>>>>>>>>>>>> Windows 10 64 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> What version of Windows 10? I *think* conpty was introduced >>>>>>>>>>>>>>> in 1809. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>>>>>>>> Windows 2019 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows >>>>>>>>>>>>>>>>>>>>>> server 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>>>>>>>> Files required for winpty are present in the >>>>>>>>>>>>>>>>>>>>>> site-packages but still, it is unable to load the winpty.dll file on these >>>>>>>>>>>>>>>>>>>>>> specific platforms. We have tested it on Windows 10 pro and Windows server >>>>>>>>>>>>>>>>>>>>>> 2019 and it is working fine. (Also tried building the local pywinpty but >>>>>>>>>>>>>>>>>>>>>> unable to build it.) ref link for winPty >>>>>>>>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per >>>>>>>>>>>>>>>>>>>> the winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command >>>>>>>>>>>>>>>>>>>> line, it shows the user entered inputs on the same terminal, not showing >>>>>>>>>>>>>>>>>>>> any errors. >>>>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git >>>>>>>>>>>>>>>>>>>> command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through >>>>>>>>>>>>>>>>>>>> the command line not getting any error, it is showing user entered inputs >>>>>>>>>>>>>>>>>>>> on the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't >>>>>>>>>>>>>>>>> do a simple import of winpty. On 2019 it's fine. I tried various tricks >>>>>>>>>>>>>>>>> that I've used in the past to make sure libraries are found etc. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Could this be because it's trying to use the >>>>>>>>>>>>>>>>> conpty interface in Windows 10 and above? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine >>>>>>>>>>>>>>>>> to simply hide the menu options and button if the server detects it's >>>>>>>>>>>>>>>>> running on an unsupported version of Windows. Of course, this should be >>>>>>>>>>>>>>>>> documented. We also need to make sure we know *exactly* what versions it >>>>>>>>>>>>>>>>> does and does not work on. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Fahar Abbas >>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> >>>>>> >>>>>> -- >>>>>> *Thanks & Regards* >>>>>> *Akshay Joshi* >>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>> >>>>>> *Mobile: +91 976-788-8246* >>>>>> >>>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> Regards, >>> Nikhil Mohite >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > Regards, Nikhil Mohite Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 14:44 Dave Page <[email protected]> parent: Akshay Joshi <[email protected]> 1 sibling, 0 replies; 54+ messages in thread From: Dave Page @ 2021-06-14 14:44 UTC (permalink / raw) To: Akshay Joshi <[email protected]>; +Cc: Nikhil Mohite <[email protected]>; pgadmin-hackers; Fahar Abbas <[email protected]> On Mon, Jun 14, 2021 at 3:35 PM Akshay Joshi <[email protected]> wrote: > Hi Dave > > On Mon, Jun 14, 2021 at 7:57 PM Dave Page <[email protected]> wrote: > >> Hi >> >> On Mon, Jun 14, 2021 at 3:18 PM Nikhil Mohite < >> [email protected]> wrote: >> >>> Hi Akshay, >>> >>> I have added the following commands for invalid command check: >>> >>> 1. \lo_import >>> 2. \lo_export >>> 3. \w or write >>> 4. \o or \output >>> 5. \g >>> >>> \qecho? \ev? >> >> I'm very concerned we're missing more here, and will continue to miss new >> commands that are added to psql in the future. >> >> I think we need to disable the feature entirely in server mode by >> default, and probably remove the code that attempts to filter out commands. >> > > If I understand correctly we need to change in config.py and make > ENABLE_PSQL = False in server mode. > Right - but we'd also have the redundant command filtering code (and config option), which we should remove. > >> Then it just becomes a case of "this can be dangerous in server mode, as >> your user will be able to run arbitrary commands on the server. Enable at >> your own risk". >> > > The above note will go into the config.py as a comment or in the > documentation. > I'm thinking the patch to config.py would be something like the following. There would be other minor changes required of course, but this part of the patch should indicate what would be required: Index: web/config.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/web/config.py b/web/config.py --- a/web/config.py (revision 4a3a5174b2b0793cea0a2575c10814a784f5f0a1) +++ b/web/config.py (date 1623241653320) @@ -645,18 +645,12 @@ ########################################################################## # PSQL tool settings ########################################################################## -# This will enable PSQL tool in pgAdmin. So user can execute the commands -# using PSQL terminal in pgAdmin. -ENABLE_PSQL = True +# This will enable PSQL tool in pgAdmin when running in server mode. +# PSQL is always enabled in Desktop mode, however in server mode it is +# disabled by default because users can run arbitrary commands on the +# server through it. +ENABLE_PSQL = False -# ALLOW_PSQL_SHELL_COMMAND = True will disable the execution of os level -# commands using meta command \! from PSQL terminal. -# As PSQL allow user to execute the os level commands from the PSQL terminal -# user can execute any system level command as per the system login user -# privileges. Default this setting is set to False but if it set to True -# User will able to execute the system level commands through PSQL terminal -# in pgAdmin. -ALLOW_PSQL_SHELL_COMMANDS = False ########################################################################## # ENABLE_BINARY_PATH_BROWSING setting is used to enable the browse button # while selecting binary path for the database server in server mode. > >> >>> I am referring to the https://www.postgresql.org/docs/12/app-psql.html >>> link for finding the commands. >>> PFA patch V10. >>> >>> >>> On Mon, Jun 14, 2021 at 6:48 PM Dave Page <[email protected]> wrote: >>> >>>> Hi >>>> >>>> On Mon, Jun 14, 2021 at 2:13 PM Nikhil Mohite < >>>> [email protected]> wrote: >>>> >>>>> Hi Akshay, >>>>> >>>>> Please find the updated patch for psql, Updated invalid command logic >>>>> added 3 more commands in it. >>>>> 1. \copy or \COPY >>>>> 2. \e or \E >>>>> 3. \ef or \EF >>>>> >>>> >>>> Should they just be case insensitive? >>>> >>> \ commands are case sensitive. >>> >> >> So what are \E and \EF? I can't see them in the pg13 docs. >> >> >>> >>>> >>>>> >>>>> Now user can't execute these commands if allow shell commands is set >>>>> to False. >>>>> >>>> >>>> What about \lo_import and \lo_export? I think those are potentially >>>> dangerous too. Also, \echo. >>>> >>> added this as well. >>> >>>> >>>> >>>>> >>>>> If required any changes please let me know. >>>>> >>>>> Regards, >>>>> Nikhil Mohite >>>>> >>>>> On Mon, Jun 14, 2021 at 11:48 AM Akshay Joshi < >>>>> [email protected]> wrote: >>>>> >>>>>> Thanks, the patch applied. >>>>>> >>>>>> On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi Team, >>>>>>> >>>>>>> PFA patch v8 >>>>>>> >>>>>>> On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Team, >>>>>>>> >>>>>>>> Please find the updated patch for the PSQL tool, Added check if the >>>>>>>> Windows version is not supporting the ConPty or WinPty disable the PSQL for >>>>>>>> that version. (PSQL option will not visible to the user). >>>>>>>> >>>>>>>> I have raised the issue with "pywinpty" >>>>>>>> https://github.com/spyder-ide/pywinpty/issues/161 >>>>>>>> >>>>>>>> Regards, >>>>>>>> Nikhil Mohite >>>>>>>> >>>>>>>> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave, >>>>>>>>>> >>>>>>>>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We >>>>>>>>>>> need to understand exactly what versions work and which don't. >>>>>>>>>>> >>>>>>>>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>>>>>>>> >>>>>>>>> >>>>>>>>> Great, thanks! >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> Do I also need to test pgadmin4 on 1909 iso? >>>>>>>>>> >>>>>>>>> >>>>>>>>> I don't think so. I'm 99% certain that what we're seeing is that >>>>>>>>> it works on the versions of Windows that support conpty, but not the older >>>>>>>>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>>>>>>>> >>>>>>>>> Hopefully Nikhil can get to the bottom of the problem with the >>>>>>>>> pywinpty folks. >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> Nikhil is not able to reproduce the issue on Windows 10 with >>>>>>>>>>>> the latest version. So the issue is reproducible with older versions. >>>>>>>>>>>> >>>>>>>>>>>> Kind Regards, >>>>>>>>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 >>>>>>>>>>>>> please? And if that doesn't work, try 1909. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>>>>>>>> Windows 2016 >>>>>>>>>>>>>>>> Windows 2012 >>>>>>>>>>>>>>>> Windows 07 >>>>>>>>>>>>>>>> Windows 2008R2 >>>>>>>>>>>>>>>> Windows 10 64 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> What version of Windows 10? I *think* conpty was introduced >>>>>>>>>>>>>>> in 1809. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>>>>>>>> Windows 2019 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows >>>>>>>>>>>>>>>>>>>>>> server 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>>>>>>>> Files required for winpty are present in the >>>>>>>>>>>>>>>>>>>>>> site-packages but still, it is unable to load the winpty.dll file on these >>>>>>>>>>>>>>>>>>>>>> specific platforms. We have tested it on Windows 10 pro and Windows server >>>>>>>>>>>>>>>>>>>>>> 2019 and it is working fine. (Also tried building the local pywinpty but >>>>>>>>>>>>>>>>>>>>>> unable to build it.) ref link for winPty >>>>>>>>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command line >>>>>>>>>>>>>>>>>>>>> instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per >>>>>>>>>>>>>>>>>>>> the winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command >>>>>>>>>>>>>>>>>>>> line, it shows the user entered inputs on the same terminal, not showing >>>>>>>>>>>>>>>>>>>> any errors. >>>>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git >>>>>>>>>>>>>>>>>>>> command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through >>>>>>>>>>>>>>>>>>>> the command line not getting any error, it is showing user entered inputs >>>>>>>>>>>>>>>>>>>> on the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I can't >>>>>>>>>>>>>>>>> do a simple import of winpty. On 2019 it's fine. I tried various tricks >>>>>>>>>>>>>>>>> that I've used in the past to make sure libraries are found etc. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Could this be because it's trying to use the >>>>>>>>>>>>>>>>> conpty interface in Windows 10 and above? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine >>>>>>>>>>>>>>>>> to simply hide the menu options and button if the server detects it's >>>>>>>>>>>>>>>>> running on an unsupported version of Windows. Of course, this should be >>>>>>>>>>>>>>>>> documented. We also need to make sure we know *exactly* what versions it >>>>>>>>>>>>>>>>> does and does not work on. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dave Page >>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>> >>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dave Page >>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>> >>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Fahar Abbas >>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>> >>>>>>>>> >>>>>> >>>>>> -- >>>>>> *Thanks & Regards* >>>>>> *Akshay Joshi* >>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>> >>>>>> *Mobile: +91 976-788-8246* >>>>>> >>>>> >>>> >>>> -- >>>> Dave Page >>>> Blog: https://pgsnake.blogspot.com >>>> Twitter: @pgsnake >>>> >>>> EDB: https://www.enterprisedb.com >>>> >>>> Regards, >>> Nikhil Mohite >>> >> >> >> -- >> Dave Page >> Blog: https://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EDB: https://www.enterprisedb.com >> >> > > -- > *Thanks & Regards* > *Akshay Joshi* > *pgAdmin Hacker | Principal Software Architect* > *EDB Postgres <http://edbpostgres.com>* > > *Mobile: +91 976-788-8246* > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
* Re: [pgAdmin][RM-2341]: Add menu option for starting PSQL @ 2021-06-14 14:48 Dave Page <[email protected]> parent: Nikhil Mohite <[email protected]> 0 siblings, 0 replies; 54+ messages in thread From: Dave Page @ 2021-06-14 14:48 UTC (permalink / raw) To: Nikhil Mohite <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers; Fahar Abbas <[email protected]> Hi On Mon, Jun 14, 2021 at 3:43 PM Nikhil Mohite < [email protected]> wrote: > Hi Dave, > > On Mon, Jun 14, 2021 at 8:05 PM Akshay Joshi < > [email protected]> wrote: > >> Hi Dave >> >> On Mon, Jun 14, 2021 at 7:57 PM Dave Page <[email protected]> wrote: >> >>> Hi >>> >>> On Mon, Jun 14, 2021 at 3:18 PM Nikhil Mohite < >>> [email protected]> wrote: >>> >>>> Hi Akshay, >>>> >>>> I have added the following commands for invalid command check: >>>> >>>> 1. \lo_import >>>> 2. \lo_export >>>> 3. \w or write >>>> 4. \o or \output >>>> 5. \g >>>> >>>> \qecho? \ev? >>> >>> I'm very concerned we're missing more here, and will continue to miss >>> new commands that are added to psql in the future. >>> >>> I think we need to disable the feature entirely in server mode by >>> default, and probably remove the code that attempts to filter out commands. >>> >> In this case, ALLOW_SHELL_COMMAND will be not useful, should we remove it > from config.py? > Right, that's what I'm suggesting (see previous email). We simply do the following: - Always enable psql in desktop mode. - Only enable psql in server mode, if the admin overrides the default configuration > >> If I understand correctly we need to change in config.py and make >> ENABLE_PSQL = False in server mode. >> >>> >>> Then it just becomes a case of "this can be dangerous in server mode, as >>> your user will be able to run arbitrary commands on the server. Enable at >>> your own risk". >>> >> >> The above note will go into the config.py as a comment or in the >> documentation. >> > >>> >>>> I am referring to the https://www.postgresql.org/docs/12/app-psql.html >>>> link for finding the commands. >>>> PFA patch V10. >>>> >>>> >>>> On Mon, Jun 14, 2021 at 6:48 PM Dave Page <[email protected]> wrote: >>>> >>>>> Hi >>>>> >>>>> On Mon, Jun 14, 2021 at 2:13 PM Nikhil Mohite < >>>>> [email protected]> wrote: >>>>> >>>>>> Hi Akshay, >>>>>> >>>>>> Please find the updated patch for psql, Updated invalid command logic >>>>>> added 3 more commands in it. >>>>>> 1. \copy or \COPY >>>>>> 2. \e or \E >>>>>> 3. \ef or \EF >>>>>> >>>>> >>>>> Should they just be case insensitive? >>>>> >>>> \ commands are case sensitive. >>>> >>> >>> So what are \E and \EF? I can't see them in the pg13 docs. >>> >> These commands open the vi editor on macOS and notepad on windows for > writing the commands. > Not on my installation: postgres=# \E invalid command \E Try \? for help. postgres=# \EF invalid command \EF Try \? for help. \e and \ef (and \ev) do what you describe though. > >>> >>>> >>>>> >>>>>> >>>>>> Now user can't execute these commands if allow shell commands is set >>>>>> to False. >>>>>> >>>>> >>>>> What about \lo_import and \lo_export? I think those are potentially >>>>> dangerous too. Also, \echo. >>>>> >>>> added this as well. >>>> >>>>> >>>>> >>>>>> >>>>>> If required any changes please let me know. >>>>>> >>>>>> Regards, >>>>>> Nikhil Mohite >>>>>> >>>>>> On Mon, Jun 14, 2021 at 11:48 AM Akshay Joshi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Thanks, the patch applied. >>>>>>> >>>>>>> On Mon, Jun 14, 2021 at 10:55 AM Nikhil Mohite < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Team, >>>>>>>> >>>>>>>> PFA patch v8 >>>>>>>> >>>>>>>> On Mon, Jun 14, 2021 at 10:25 AM Nikhil Mohite < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> Hi Team, >>>>>>>>> >>>>>>>>> Please find the updated patch for the PSQL tool, Added check if >>>>>>>>> the Windows version is not supporting the ConPty or WinPty disable the PSQL >>>>>>>>> for that version. (PSQL option will not visible to the user). >>>>>>>>> >>>>>>>>> I have raised the issue with "pywinpty" >>>>>>>>> https://github.com/spyder-ide/pywinpty/issues/161 >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> Nikhil Mohite >>>>>>>>> >>>>>>>>> On Fri, Jun 11, 2021 at 6:25 PM Dave Page <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> Hi >>>>>>>>>> >>>>>>>>>> On Fri, Jun 11, 2021 at 1:45 PM Fahar Abbas < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Dave, >>>>>>>>>>> >>>>>>>>>>> On Fri, Jun 11, 2021 at 1:39 PM Dave Page <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Fri, Jun 11, 2021 at 9:35 AM Fahar Abbas < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Sure Dave, I will create a new VM with the latest iso. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Not the latest. 1809 please. And if that doesn't work, 1909. We >>>>>>>>>>>> need to understand exactly what versions work and which don't. >>>>>>>>>>>> >>>>>>>>>>>> pgadmin4 is working fine on Windows 10 x64(1809). >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Great, thanks! >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Do I also need to test pgadmin4 on 1909 iso? >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> I don't think so. I'm 99% certain that what we're seeing is that >>>>>>>>>> it works on the versions of Windows that support conpty, but not the older >>>>>>>>>> ones where the pywinpty library is *supposed* to fall back to using winpty. >>>>>>>>>> >>>>>>>>>> Hopefully Nikhil can get to the bottom of the problem with the >>>>>>>>>> pywinpty folks. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> Nikhil is not able to reproduce the issue on Windows 10 with >>>>>>>>>>>>> the latest version. So the issue is reproducible with older versions. >>>>>>>>>>>>> >>>>>>>>>>>>> Kind Regards, >>>>>>>>>>>>> On Fri, Jun 11, 2021 at 1:28 PM Dave Page <[email protected]> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Fri, Jun 11, 2021 at 9:25 AM Fahar Abbas < >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Windows 10 Enterprise 2016 LTSB. >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hmm, I assume that is version 1607. Can you test with 1809 >>>>>>>>>>>>>> please? And if that doesn't work, try 1909. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Fri, Jun 11, 2021 at 1:12 PM Dave Page <[email protected]> >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Fri, Jun 11, 2021 at 7:44 AM Fahar Abbas < >>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> pgadmin4 is failing on following operating systems : >>>>>>>>>>>>>>>>> Windows 2016 >>>>>>>>>>>>>>>>> Windows 2012 >>>>>>>>>>>>>>>>> Windows 07 >>>>>>>>>>>>>>>>> Windows 2008R2 >>>>>>>>>>>>>>>>> Windows 10 64 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> What version of Windows 10? I *think* conpty was introduced >>>>>>>>>>>>>>>> in 1809. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> pgadmin4 is working fine in following operating system: >>>>>>>>>>>>>>>>> Windows 2019 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 7:51 PM Dave Page < >>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:22 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 6:37 PM Dave Page < >>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 2:00 PM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Dave, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 5:22 PM Dave Page < >>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Thu, Jun 10, 2021 at 11:08 AM Nikhil Mohite < >>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi Dave/ Team, >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> We are facing an issue with winpty.dll on Windows >>>>>>>>>>>>>>>>>>>>>>> server 2016 and Windows 7(these are platforms on which we have tested). >>>>>>>>>>>>>>>>>>>>>>> Files required for winpty are present in the >>>>>>>>>>>>>>>>>>>>>>> site-packages but still, it is unable to load the winpty.dll file on these >>>>>>>>>>>>>>>>>>>>>>> specific platforms. We have tested it on Windows 10 pro and Windows server >>>>>>>>>>>>>>>>>>>>>>> 2019 and it is working fine. (Also tried building the local pywinpty but >>>>>>>>>>>>>>>>>>>>>>> unable to build it.) ref link for winPty >>>>>>>>>>>>>>>>>>>>>>> https://github.com/rprichard/winpty#:~:text=winpty%20is%20a%20Windows%20software,in%20a%20Cygwin%2FM.... >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Does winpty.exe run, if executed from the command >>>>>>>>>>>>>>>>>>>>>> line instead of pgAdmin? If not, does dependency walker show any missing >>>>>>>>>>>>>>>>>>>>>> libraries that are required? >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Not found the winpty.exe in site packages, but as per >>>>>>>>>>>>>>>>>>>>> the winpty documents "winpty-agent.exe" will start the process with a new, >>>>>>>>>>>>>>>>>>>>> hidden console window. It is not showing any error while installing the >>>>>>>>>>>>>>>>>>>>> package. I tried to use it outside the pgAdmin but still facing the same >>>>>>>>>>>>>>>>>>>>> error "Exception in import winpty DLL load failed while importing winpty: >>>>>>>>>>>>>>>>>>>>> The specified procedure could not be found."(created a separate python >>>>>>>>>>>>>>>>>>>>> environment for this) >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> 1. if try to run winpty-agent.exe from the command >>>>>>>>>>>>>>>>>>>>> line, it shows the user entered inputs on the same terminal, not showing >>>>>>>>>>>>>>>>>>>>> any errors. >>>>>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> 2. I found winpty.exe in the other installed app (Git >>>>>>>>>>>>>>>>>>>>> command line: C:\Program Files (x86)\Git\usr\bin) if try to run it through >>>>>>>>>>>>>>>>>>>>> the command line not getting any error, it is showing user entered inputs >>>>>>>>>>>>>>>>>>>>> on the same terminal. (It is not related to pgAdmin but just tried to check >>>>>>>>>>>>>>>>>>>>> winpty.exe throwing any error or not) >>>>>>>>>>>>>>>>>>>>> [image: image.png] >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hmmm, that sounds oddly similar to an issue I had with >>>>>>>>>>>>>>>>>>>> Kerberos on Windows when I was mucking around with that. I can't remember >>>>>>>>>>>>>>>>>>>> the exact details, but as a test, does the problem go away if winpty.dll is >>>>>>>>>>>>>>>>>>>> copied into the Windows system32 directory? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Tried it but still facing the same issue. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> OK, I had a fiddle around, and see the same thing. I >>>>>>>>>>>>>>>>>> can't do a simple import of winpty. On 2019 it's fine. I tried various >>>>>>>>>>>>>>>>>> tricks that I've used in the past to make sure libraries are found etc. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Could this be because it's trying to use the >>>>>>>>>>>>>>>>>> conpty interface in Windows 10 and above? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> If we can't get this to work tomorrow, I think it's fine >>>>>>>>>>>>>>>>>> to simply hide the menu options and button if the server detects it's >>>>>>>>>>>>>>>>>> running on an unsupported version of Windows. Of course, this should be >>>>>>>>>>>>>>>>>> documented. We also need to make sure we know *exactly* what versions it >>>>>>>>>>>>>>>>>> does and does not work on. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Fahar Abbas >>>>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Fahar Abbas >>>>>>>>>>> EnterpriseDB Corporation >>>>>>>>>>> Phone Office: +92-51-835-8874 >>>>>>>>>>> Phone Direct: +92-51-8466803 >>>>>>>>>>> Mobile: +92-333-5409707 >>>>>>>>>>> Skype ID: *live:fahar.abbas* >>>>>>>>>>> Website: www.enterprisedb.com >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dave Page >>>>>>>>>> Blog: https://pgsnake.blogspot.com >>>>>>>>>> Twitter: @pgsnake >>>>>>>>>> >>>>>>>>>> EDB: https://www.enterprisedb.com >>>>>>>>>> >>>>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> *Thanks & Regards* >>>>>>> *Akshay Joshi* >>>>>>> *pgAdmin Hacker | Principal Software Architect* >>>>>>> *EDB Postgres <http://edbpostgres.com>* >>>>>>> >>>>>>> *Mobile: +91 976-788-8246* >>>>>>> >>>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: https://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EDB: https://www.enterprisedb.com >>>>> >>>>> Regards, >>>> Nikhil Mohite >>>> >>> >>> >>> -- >>> Dave Page >>> Blog: https://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EDB: https://www.enterprisedb.com >>> >>> >> >> -- >> *Thanks & Regards* >> *Akshay Joshi* >> *pgAdmin Hacker | Principal Software Architect* >> *EDB Postgres <http://edbpostgres.com>* >> >> *Mobile: +91 976-788-8246* >> > Regards, > Nikhil Mohite > -- Dave Page Blog: https://pgsnake.blogspot.com Twitter: @pgsnake EDB: https://www.enterprisedb.com Attachments: [image/png] image.png (42.2K, 3-image.png) download | view image [image/png] image.png (26.6K, 4-image.png) download | view image ^ permalink raw reply [nested|flat] 54+ messages in thread
end of thread, other threads:[~2021-06-14 14:48 UTC | newest] Thread overview: 54+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2021-05-10 12:45 [pgAdmin][RM-2341]: Add menu option for starting PSQL Nikhil Mohite <[email protected]> 2021-05-10 13:40 ` Dave Page <[email protected]> 2021-05-10 14:01 ` Nikhil Mohite <[email protected]> 2021-05-11 08:02 ` Akshay Joshi <[email protected]> 2021-05-11 10:10 ` Dave Page <[email protected]> 2021-05-17 10:01 ` Nikhil Mohite <[email protected]> 2021-05-17 13:17 ` Dave Page <[email protected]> 2021-05-18 11:12 ` Nikhil Mohite <[email protected]> 2021-05-18 15:11 ` Dave Page <[email protected]> 2021-05-19 07:58 ` Nikhil Mohite <[email protected]> 2021-05-19 08:13 ` Dave Page <[email protected]> 2021-05-19 13:42 ` Nikhil Mohite <[email protected]> 2021-05-20 09:22 ` Dave Page <[email protected]> 2021-05-24 15:49 ` Akshay Joshi <[email protected]> 2021-05-25 09:22 ` Nikhil Mohite <[email protected]> 2021-05-25 09:25 ` Akshay Joshi <[email protected]> 2021-05-25 09:38 ` Nikhil Mohite <[email protected]> 2021-05-25 14:50 ` Akshay Joshi <[email protected]> 2021-06-01 11:58 ` Nikhil Mohite <[email protected]> 2021-06-03 08:36 ` Dave Page <[email protected]> 2021-06-03 08:39 ` Akshay Joshi <[email protected]> 2021-06-07 05:45 ` Nikhil Mohite <[email protected]> 2021-06-07 08:36 ` Dave Page <[email protected]> 2021-06-07 08:45 ` Nikhil Mohite <[email protected]> 2021-06-07 09:04 ` Dave Page <[email protected]> 2021-06-08 09:29 ` Akshay Joshi <[email protected]> 2021-06-10 10:08 ` Nikhil Mohite <[email protected]> 2021-06-10 11:52 ` Dave Page <[email protected]> 2021-06-10 13:00 ` Nikhil Mohite <[email protected]> 2021-06-10 13:07 ` Dave Page <[email protected]> 2021-06-10 13:22 ` Nikhil Mohite <[email protected]> 2021-06-10 14:50 ` Dave Page <[email protected]> 2021-06-10 15:46 ` Nikhil Mohite <[email protected]> 2021-06-11 06:44 ` Fahar Abbas <[email protected]> 2021-06-11 07:31 ` Akshay Joshi <[email protected]> 2021-06-11 08:12 ` Dave Page <[email protected]> 2021-06-11 08:25 ` Fahar Abbas <[email protected]> 2021-06-11 08:28 ` Dave Page <[email protected]> 2021-06-11 08:34 ` Fahar Abbas <[email protected]> 2021-06-11 08:39 ` Dave Page <[email protected]> 2021-06-11 08:42 ` Fahar Abbas <[email protected]> 2021-06-11 12:45 ` Fahar Abbas <[email protected]> 2021-06-11 12:54 ` Dave Page <[email protected]> 2021-06-14 04:55 ` Nikhil Mohite <[email protected]> 2021-06-14 05:24 ` Nikhil Mohite <[email protected]> 2021-06-14 06:18 ` Akshay Joshi <[email protected]> 2021-06-14 13:13 ` Nikhil Mohite <[email protected]> 2021-06-14 13:18 ` Dave Page <[email protected]> 2021-06-14 14:17 ` Nikhil Mohite <[email protected]> 2021-06-14 14:26 ` Dave Page <[email protected]> 2021-06-14 14:35 ` Akshay Joshi <[email protected]> 2021-06-14 14:43 ` Nikhil Mohite <[email protected]> 2021-06-14 14:48 ` Dave Page <[email protected]> 2021-06-14 14:44 ` Dave Page <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox