summaryrefslogtreecommitdiffstats
path: root/mycli/main.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2022-09-07 09:38:57 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2022-09-07 09:39:08 +0000
commitf0ae12072ba1868526f2ae57615538777d9538f4 (patch)
treef639c1078fc22f434d074470d7b50f58f0ac6e4e /mycli/main.py
parentReleasing debian version 1.25.0-1. (diff)
downloadmycli-f0ae12072ba1868526f2ae57615538777d9538f4.tar.xz
mycli-f0ae12072ba1868526f2ae57615538777d9538f4.zip
Merging upstream version 1.26.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mycli/main.py')
-rwxr-xr-xmycli/main.py80
1 files changed, 62 insertions, 18 deletions
diff --git a/mycli/main.py b/mycli/main.py
index 08f0755..208572d 100755
--- a/mycli/main.py
+++ b/mycli/main.py
@@ -24,6 +24,7 @@ from cli_helpers.tabular_output import preprocessors
from cli_helpers.utils import strip_ansi
import click
import sqlparse
+import sqlglot
from mycli.packages.parseutils import is_dropping_database, is_destructive
from prompt_toolkit.completion import DynamicCompleter
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
@@ -123,6 +124,7 @@ class MyCli(object):
self.logfile = logfile
self.defaults_suffix = defaults_suffix
self.login_path = login_path
+ self.toolbar_error_message = None
# self.cnf_files is a class variable that stores the list of mysql
# config files to read in at launch.
@@ -341,6 +343,7 @@ class MyCli(object):
'mysqld': {
'socket': 'default_socket',
'port': 'default_port',
+ 'user': 'default_user',
},
}
@@ -447,7 +450,7 @@ class MyCli(object):
if not any(v for v in ssl.values()):
ssl = None
- # if the passwd is not specfied try to set it using the password_file option
+ # if the passwd is not specified try to set it using the password_file option
password_from_file = self.get_password_from_file(password_file)
passwd = passwd or password_from_file
@@ -581,6 +584,34 @@ class MyCli(object):
return True
return False
+ def handle_prettify_binding(self, text):
+ try:
+ statements = sqlglot.parse(text, read='mysql')
+ except Exception as e:
+ statements = []
+ if len(statements) == 1:
+ pretty_text = statements[0].sql(pretty=True, pad=4, dialect='mysql')
+ else:
+ pretty_text = ''
+ self.toolbar_error_message = 'Prettify failed to parse statement'
+ if len(pretty_text) > 0:
+ pretty_text = pretty_text + ';'
+ return pretty_text
+
+ def handle_unprettify_binding(self, text):
+ try:
+ statements = sqlglot.parse(text, read='mysql')
+ except Exception as e:
+ statements = []
+ if len(statements) == 1:
+ unpretty_text = statements[0].sql(pretty=False, dialect='mysql')
+ else:
+ unpretty_text = ''
+ self.toolbar_error_message = 'Unprettify failed to parse statement'
+ if len(unpretty_text) > 0:
+ unpretty_text = unpretty_text + ';'
+ return unpretty_text
+
def run_cli(self):
iterations = 0
sqlexecute = self.sqlexecute
@@ -723,7 +754,7 @@ class MyCli(object):
except KeyboardInterrupt:
pass
if self.beep_after_seconds > 0 and t >= self.beep_after_seconds:
- self.echo('\a', err=True, nl=False)
+ self.bell()
if special.is_timing_enabled():
self.echo('Time: %0.03fs' % t)
except KeyboardInterrupt:
@@ -739,19 +770,23 @@ class MyCli(object):
except KeyboardInterrupt:
# get last connection id
connection_id_to_kill = sqlexecute.connection_id
- logger.debug("connection id to kill: %r", connection_id_to_kill)
- # Restart connection to the database
- sqlexecute.connect()
- try:
- for title, cur, headers, status in sqlexecute.run('kill %s' % connection_id_to_kill):
- status_str = str(status).lower()
- if status_str.find('ok') > -1:
- logger.debug("cancelled query, connection id: %r, sql: %r",
- connection_id_to_kill, text)
- self.echo("cancelled query", err=True, fg='red')
- except Exception as e:
- self.echo('Encountered error while cancelling query: {}'.format(e),
- err=True, fg='red')
+ # some mysql compatible databases may not implemente connection_id()
+ if connection_id_to_kill > 0:
+ logger.debug("connection id to kill: %r", connection_id_to_kill)
+ # Restart connection to the database
+ sqlexecute.connect()
+ try:
+ for title, cur, headers, status in sqlexecute.run('kill %s' % connection_id_to_kill):
+ status_str = str(status).lower()
+ if status_str.find('ok') > -1:
+ logger.debug("cancelled query, connection id: %r, sql: %r",
+ connection_id_to_kill, text)
+ self.echo("cancelled query", err=True, fg='red')
+ except Exception as e:
+ self.echo('Encountered error while cancelling query: {}'.format(e),
+ err=True, fg='red')
+ else:
+ logger.debug("Did not get a connection id, skip cancelling query")
except NotImplementedError:
self.echo('Not Yet Implemented.', fg="yellow")
except OperationalError as e:
@@ -860,6 +895,11 @@ class MyCli(object):
self.log_output(s)
click.secho(s, **kwargs)
+ def bell(self):
+ """Print a bell on the stderr.
+ """
+ click.secho('\a', err=True, nl=False)
+
def get_output_margin(self, status=None):
"""Get the output margin (number of rows for the prompt, footer and
timing message."""
@@ -933,8 +973,9 @@ class MyCli(object):
os.environ['LESS'] = '-RXF'
cnf = self.read_my_cnf_files(self.cnf_files, ['pager', 'skip-pager'])
- if cnf['pager']:
- special.set_pager(cnf['pager'])
+ cnf_pager = cnf['pager'] or self.config['main']['pager']
+ if cnf_pager:
+ special.set_pager(cnf_pager)
self.explicit_pager = True
else:
self.explicit_pager = False
@@ -1084,6 +1125,8 @@ class MyCli(object):
@click.option('--ssh-config-path', help='Path to ssh configuration.',
default=os.path.expanduser('~') + '/.ssh/config')
@click.option('--ssh-config-host', help='Host to connect to ssh server reading from ssh configuration.')
+@click.option('--ssl', 'ssl_enable', is_flag=True,
+ help='Enable SSL for connection (automatically enabled with other flags).')
@click.option('--ssl-ca', help='CA file in PEM format.',
type=click.Path(exists=True))
@click.option('--ssl-capath', help='CA directory.')
@@ -1142,7 +1185,7 @@ class MyCli(object):
def cli(database, user, host, port, socket, password, dbname,
version, verbose, prompt, logfile, defaults_group_suffix,
defaults_file, login_path, auto_vertical_output, local_infile,
- ssl_ca, ssl_capath, ssl_cert, ssl_key, ssl_cipher,
+ ssl_enable, ssl_ca, ssl_capath, ssl_cert, ssl_key, ssl_cipher,
ssl_verify_server_cert, table, csv, warn, execute, myclirc, dsn,
list_dsn, ssh_user, ssh_host, ssh_port, ssh_password,
ssh_key_filename, list_ssh_config, ssh_config_path, ssh_config_host,
@@ -1197,6 +1240,7 @@ def cli(database, user, host, port, socket, password, dbname,
database = dbname or database
ssl = {
+ 'enable': ssl_enable,
'ca': ssl_ca and os.path.expanduser(ssl_ca),
'cert': ssl_cert and os.path.expanduser(ssl_cert),
'key': ssl_key and os.path.expanduser(ssl_key),