diff options
Diffstat (limited to 'dev-db/mycli/files')
-rw-r--r-- | dev-db/mycli/files/mycli-1.22.2_p20201026.patch | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/dev-db/mycli/files/mycli-1.22.2_p20201026.patch b/dev-db/mycli/files/mycli-1.22.2_p20201026.patch new file mode 100644 index 000000000000..3e7c719bf396 --- /dev/null +++ b/dev-db/mycli/files/mycli-1.22.2_p20201026.patch @@ -0,0 +1,470 @@ +diff --git a/.travis.yml b/.travis.yml +index 0afb5cc..182dea7 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -12,7 +12,7 @@ matrix: + + install: + - pip install -r requirements-dev.txt +- - pip install -e . ++ - pip install --no-cache-dir -e . + - sudo rm -f /etc/mysql/conf.d/performance-schema.cnf + - sudo service mysql restart + +diff --git a/README.md b/README.md +index efe804d..d5a0687 100644 +--- a/README.md ++++ b/README.md +@@ -96,6 +96,7 @@ $ sudo apt-get install mycli # Only on debian or ubuntu + --local-infile BOOLEAN Enable/disable LOAD DATA LOCAL INFILE. + --login-path TEXT Read this path from the login file. + -e, --execute TEXT Execute command and quit. ++ --init-command TEXT SQL statement to execute after connecting. + --help Show this message and exit. + + Features +diff --git a/changelog.md b/changelog.md +index a4fea35..508c801 100644 +--- a/changelog.md ++++ b/changelog.md +@@ -1,9 +1,22 @@ ++TBD ++=== ++ ++Features: ++--------- ++ ++* Add an option `--init-command` to execute SQL after connecting (Thanks: [KITAGAWA Yasutaka]). ++ ++Bug Fixes: ++---------- ++* Fixed compatibility with sqlparse 0.4 (Thanks: [mtorromeo]). ++ + 1.22.2 + ====== + + Bug Fixes: + ---------- +-* Make the `pwd` module optional. ++ ++* Make the `pwd` module optional. + + 1.22.1 + ====== +@@ -18,6 +31,11 @@ Features: + * Add an option `--list-ssh-config` to list ssh configurations. + * Add an option `--ssh-config-path` to choose ssh configuration path. + ++Bug Fixes: ++---------- ++ ++* Fix specifying empty password with `--password=''` when config file has a password set (Thanks: [Zach DeCook]). ++ + + 1.21.1 + ====== +@@ -28,6 +46,7 @@ Bug Fixes: + + * Fix broken auto-completion for favorite queries (Thanks: [Amjith]). + * Fix undefined variable exception when running with --no-warn (Thanks: [Georgy Frolov]) ++* Support setting color for null value (Thanks: [laixintao]) + + 1.21.0 + ====== +@@ -768,3 +787,6 @@ Bug Fixes: + [François Pietka]: https://github.com/fpietka + [Frederic Aoustin]: https://github.com/fraoustin + [Georgy Frolov]: https://github.com/pasenor ++[Zach DeCook]: https://zachdecook.com ++[laixintao]: https://github.com/laixintao ++[mtorromeo]: https://github.com/mtorromeo +diff --git a/mycli/AUTHORS b/mycli/AUTHORS +index b3636d9..a1204b0 100644 +--- a/mycli/AUTHORS ++++ b/mycli/AUTHORS +@@ -72,6 +72,10 @@ Contributors: + * Jakub Boukal + * Takeshi D. Itoh + * laixintao ++ * Zach DeCook ++ * kevinhwang91 ++ * KITAGAWA Yasutaka ++ * Massimiliano Torromeo + + Creator: + -------- +diff --git a/mycli/clistyle.py b/mycli/clistyle.py +index c94f793..293f0f4 100644 +--- a/mycli/clistyle.py ++++ b/mycli/clistyle.py +@@ -34,6 +34,7 @@ TOKEN_TO_PROMPT_STYLE = { + Token.Output.Header: 'output.header', + Token.Output.OddRow: 'output.odd-row', + Token.Output.EvenRow: 'output.even-row', ++ Token.Output.Null: 'output.null', + Token.Prompt: 'prompt', + Token.Continuation: 'continuation', + } +diff --git a/mycli/main.py b/mycli/main.py +index 03797a0..dffd724 100755 +--- a/mycli/main.py ++++ b/mycli/main.py +@@ -98,7 +98,7 @@ class MyCli(object): + xdg_config_home = "~/.config" + system_config_files = [ + '/etc/myclirc', +- os.path.join(xdg_config_home, "mycli", "myclirc") ++ os.path.join(os.path.expanduser(xdg_config_home), "mycli", "myclirc") + ] + + default_config_file = os.path.join(PACKAGE_ROOT, 'myclirc') +@@ -152,7 +152,7 @@ class MyCli(object): + c['main'].as_bool('auto_vertical_output') + + # Write user config if system config wasn't the last config loaded. +- if c.filename not in self.system_config_files: ++ if c.filename not in self.system_config_files and not os.path.exists(myclirc): + write_default_config(self.default_config_file, myclirc) + + # audit log +@@ -363,7 +363,7 @@ class MyCli(object): + def connect(self, database='', user='', passwd='', host='', port='', + socket='', charset='', local_infile='', ssl='', + ssh_user='', ssh_host='', ssh_port='', +- ssh_password='', ssh_key_filename=''): ++ ssh_password='', ssh_key_filename='', init_command=''): + + cnf = {'database': None, + 'user': None, +@@ -396,7 +396,7 @@ class MyCli(object): + port = port or cnf['port'] + ssl = ssl or {} + +- passwd = passwd or cnf['password'] ++ passwd = passwd if isinstance(passwd, str) else cnf['password'] + charset = charset or cnf['default-character-set'] or 'utf8' + + # Favor whichever local_infile option is set. +@@ -420,7 +420,7 @@ class MyCli(object): + self.sqlexecute = SQLExecute( + database, user, passwd, host, port, socket, charset, + local_infile, ssl, ssh_user, ssh_host, ssh_port, +- ssh_password, ssh_key_filename ++ ssh_password, ssh_key_filename, init_command + ) + except OperationalError as e: + if ('Access denied for user' in e.args[1]): +@@ -429,7 +429,7 @@ class MyCli(object): + self.sqlexecute = SQLExecute( + database, user, new_passwd, host, port, socket, + charset, local_infile, ssl, ssh_user, ssh_host, +- ssh_port, ssh_password, ssh_key_filename ++ ssh_port, ssh_password, ssh_key_filename, init_command + ) + else: + raise e +@@ -1051,6 +1051,8 @@ class MyCli(object): + help='Read this path from the login file.') + @click.option('-e', '--execute', type=str, + help='Execute command and quit.') ++@click.option('--init-command', type=str, ++ help='SQL statement to execute after connecting.') + @click.argument('database', default='', nargs=1) + def cli(database, user, host, port, socket, password, dbname, + version, verbose, prompt, logfile, defaults_group_suffix, +@@ -1058,7 +1060,8 @@ def cli(database, user, host, port, socket, password, dbname, + 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): ++ ssh_key_filename, list_ssh_config, ssh_config_path, ssh_config_host, ++ init_command): + """A MySQL terminal client with auto-completion and syntax highlighting. + + \b +@@ -1182,7 +1185,8 @@ def cli(database, user, host, port, socket, password, dbname, + ssh_host=ssh_host, + ssh_port=ssh_port, + ssh_password=ssh_password, +- ssh_key_filename=ssh_key_filename ++ ssh_key_filename=ssh_key_filename, ++ init_command=init_command + ) + + mycli.logger.debug('Launch Params: \n' +diff --git a/mycli/myclirc b/mycli/myclirc +index 534b201..ba3ea1e 100644 +--- a/mycli/myclirc ++++ b/mycli/myclirc +@@ -111,6 +111,7 @@ bottom-toolbar.transaction.failed = 'bg:#222222 #ff005f bold' + output.header = "#00ff5f bold" + output.odd-row = "" + output.even-row = "" ++output.null = "#808080" + + # Favorite queries. + [favorite_queries] +diff --git a/mycli/packages/completion_engine.py b/mycli/packages/completion_engine.py +index 2b19c32..3cff2cc 100644 +--- a/mycli/packages/completion_engine.py ++++ b/mycli/packages/completion_engine.py +@@ -2,7 +2,6 @@ import os + import sys + import sqlparse + from sqlparse.sql import Comparison, Identifier, Where +-from sqlparse.compat import text_type + from .parseutils import last_word, extract_tables, find_prev_keyword + from .special import parse_special_command + +@@ -55,7 +54,7 @@ def suggest_type(full_text, text_before_cursor): + stmt_start, stmt_end = 0, 0 + + for statement in parsed: +- stmt_len = len(text_type(statement)) ++ stmt_len = len(str(statement)) + stmt_start, stmt_end = stmt_end, stmt_end + stmt_len + + if stmt_end >= current_pos: +diff --git a/mycli/sqlexecute.py b/mycli/sqlexecute.py +index c68af0f..7534982 100644 +--- a/mycli/sqlexecute.py ++++ b/mycli/sqlexecute.py +@@ -42,7 +42,7 @@ class SQLExecute(object): + + def __init__(self, database, user, password, host, port, socket, charset, + local_infile, ssl, ssh_user, ssh_host, ssh_port, ssh_password, +- ssh_key_filename): ++ ssh_key_filename, init_command=None): + self.dbname = database + self.user = user + self.password = password +@@ -59,12 +59,13 @@ class SQLExecute(object): + self.ssh_port = ssh_port + self.ssh_password = ssh_password + self.ssh_key_filename = ssh_key_filename ++ self.init_command = init_command + self.connect() + + def connect(self, database=None, user=None, password=None, host=None, + port=None, socket=None, charset=None, local_infile=None, + ssl=None, ssh_host=None, ssh_port=None, ssh_user=None, +- ssh_password=None, ssh_key_filename=None): ++ ssh_password=None, ssh_key_filename=None, init_command=None): + db = (database or self.dbname) + user = (user or self.user) + password = (password or self.password) +@@ -79,6 +80,7 @@ class SQLExecute(object): + ssh_port = (ssh_port or self.ssh_port) + ssh_password = (ssh_password or self.ssh_password) + ssh_key_filename = (ssh_key_filename or self.ssh_key_filename) ++ init_command = (init_command or self.init_command) + _logger.debug( + 'Connection DB Params: \n' + '\tdatabase: %r' +@@ -93,9 +95,11 @@ class SQLExecute(object): + '\tssh_host: %r' + '\tssh_port: %r' + '\tssh_password: %r' +- '\tssh_key_filename: %r', ++ '\tssh_key_filename: %r' ++ '\tinit_command: %r', + db, user, host, port, socket, charset, local_infile, ssl, +- ssh_user, ssh_host, ssh_port, ssh_password, ssh_key_filename ++ ssh_user, ssh_host, ssh_port, ssh_password, ssh_key_filename, ++ init_command + ) + conv = conversions.copy() + conv.update({ +@@ -110,12 +114,16 @@ class SQLExecute(object): + if ssh_host: + defer_connect = True + ++ client_flag = pymysql.constants.CLIENT.INTERACTIVE ++ if init_command and len(list(special.split_queries(init_command))) > 1: ++ client_flag |= pymysql.constants.CLIENT.MULTI_STATEMENTS ++ + conn = pymysql.connect( + database=db, user=user, password=password, host=host, port=port, + unix_socket=socket, use_unicode=True, charset=charset, +- autocommit=True, client_flag=pymysql.constants.CLIENT.INTERACTIVE, ++ autocommit=True, client_flag=client_flag, + local_infile=local_infile, conv=conv, ssl=ssl, program_name="mycli", +- defer_connect=defer_connect ++ defer_connect=defer_connect, init_command=init_command + ) + + if ssh_host: +@@ -146,6 +154,7 @@ class SQLExecute(object): + self.socket = socket + self.charset = charset + self.ssl = ssl ++ self.init_command = init_command + # retrieve connection id + self.reset_connection_id() + +diff --git a/requirements-dev.txt b/requirements-dev.txt +index 8e206a5..7a38ed5 100644 +--- a/requirements-dev.txt ++++ b/requirements-dev.txt +@@ -3,8 +3,8 @@ pytest!=3.3.0 + pytest-cov==2.4.0 + tox + twine==1.12.1 +-behave +-pexpect ++behave>=1.2.4 ++pexpect==3.3 + coverage==5.0.4 + codecov==2.0.9 + autopep8==1.3.3 +diff --git a/setup.py b/setup.py +index 156cd1a..fbab22e 100755 +--- a/setup.py ++++ b/setup.py +@@ -24,7 +24,7 @@ install_requirements = [ + 'sqlparse>=0.3.0,<0.4.0', + 'configobj >= 5.0.5', + 'cryptography >= 1.0.0', +- 'cli_helpers[styles] > 1.1.0', ++ 'cli_helpers[styles] >= 2.0.1', + ] + + +@@ -65,7 +65,7 @@ class test(TestCommand): + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' +- self.behave_args = '' ++ self.behave_args = '--no-capture' + + def run_tests(self): + unit_test_errno = subprocess.call( +diff --git a/test/features/environment.py b/test/features/environment.py +index 1a49dbe..cb35140 100644 +--- a/test/features/environment.py ++++ b/test/features/environment.py +@@ -16,7 +16,7 @@ def before_all(context): + os.environ['LINES'] = "100" + os.environ['COLUMNS'] = "100" + os.environ['EDITOR'] = 'ex' +- os.environ['LC_ALL'] = 'en_US.utf8' ++ os.environ['LC_ALL'] = 'en_US.UTF-8' + os.environ['PROMPT_TOOLKIT_NO_CPR'] = '1' + + test_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +@@ -118,11 +118,12 @@ def after_scenario(context, _): + host = context.conf['host'] + dbname = context.currentdb + context.cli.expect_exact( +- '{0}@{1}:{2}> '.format( ++ '{0}@{1}:{2}>'.format( + user, host, dbname + ), + timeout=5 + ) ++ context.cli.sendcontrol('c') + context.cli.sendcontrol('d') + context.cli.expect_exact(pexpect.EOF, timeout=5) + +diff --git a/test/features/steps/crud_database.py b/test/features/steps/crud_database.py +index a0bfa53..be6dec0 100644 +--- a/test/features/steps/crud_database.py ++++ b/test/features/steps/crud_database.py +@@ -64,15 +64,13 @@ def step_see_prompt(context): + user = context.conf['user'] + host = context.conf['host'] + dbname = context.currentdb +- wrappers.expect_exact(context, '{0}@{1}:{2}> '.format( +- user, host, dbname), timeout=5) +- context.atprompt = True ++ wrappers.wait_prompt(context, '{0}@{1}:{2}> '.format(user, host, dbname)) + + + @then('we see help output') + def step_see_help(context): + for expected_line in context.fixture_data['help_commands.txt']: +- wrappers.expect_exact(context, expected_line + '\r\n', timeout=1) ++ wrappers.expect_exact(context, expected_line, timeout=1) + + + @then('we see database created') +@@ -96,10 +94,7 @@ def step_see_db_dropped_no_default(context): + context.currentdb = None + + wrappers.expect_exact(context, 'Query OK, 0 rows affected', timeout=2) +- wrappers.expect_exact(context, '{0}@{1}:{2}> '.format( +- user, host, database), timeout=5) +- +- context.atprompt = True ++ wrappers.wait_prompt(context, '{0}@{1}:{2}>'.format(user, host, database)) + + + @then('we see database connected') +diff --git a/test/features/steps/wrappers.py b/test/features/steps/wrappers.py +index 565ca59..de833dd 100644 +--- a/test/features/steps/wrappers.py ++++ b/test/features/steps/wrappers.py +@@ -88,7 +88,7 @@ def wait_prompt(context, prompt=None): + user = context.conf['user'] + host = context.conf['host'] + dbname = context.currentdb +- prompt = '{0}@{1}:{2}> '.format( ++ prompt = '{0}@{1}:{2}>'.format( + user, host, dbname), + expect_exact(context, prompt, timeout=5) + context.atprompt = True +diff --git a/test/test_main.py b/test/test_main.py +index 3f92bd1..707c359 100644 +--- a/test/test_main.py ++++ b/test/test_main.py +@@ -492,3 +492,37 @@ def test_ssh_config(monkeypatch): + MockMyCli.connect_args["ssh_host"] == "arg_host" and \ + MockMyCli.connect_args["ssh_port"] == 3 and \ + MockMyCli.connect_args["ssh_key_filename"] == "/path/to/key" ++ ++ ++@dbtest ++def test_init_command_arg(executor): ++ init_command = "set sql_select_limit=1000" ++ sql = 'show variables like "sql_select_limit";' ++ runner = CliRunner() ++ result = runner.invoke( ++ cli, args=CLI_ARGS + ["--init-command", init_command], input=sql ++ ) ++ ++ expected = "sql_select_limit\t1000\n" ++ assert result.exit_code == 0 ++ assert expected in result.output ++ ++ ++@dbtest ++def test_init_command_multiple_arg(executor): ++ init_command = 'set sql_select_limit=2000; set max_join_size=20000' ++ sql = ( ++ 'show variables like "sql_select_limit";\n' ++ 'show variables like "max_join_size"' ++ ) ++ runner = CliRunner() ++ result = runner.invoke( ++ cli, args=CLI_ARGS + ['--init-command', init_command], input=sql ++ ) ++ ++ expected_sql_select_limit = 'sql_select_limit\t2000\n' ++ expected_max_join_size = 'max_join_size\t20000\n' ++ ++ assert result.exit_code == 0 ++ assert expected_sql_select_limit in result.output ++ assert expected_max_join_size in result.output +diff --git a/test/test_tabular_output.py b/test/test_tabular_output.py +index 7d7d000..c20c7de 100644 +--- a/test/test_tabular_output.py ++++ b/test/test_tabular_output.py +@@ -16,7 +16,7 @@ from pymysql.constants import FIELD_TYPE + @pytest.fixture + def mycli(): + cli = MyCli() +- cli.connect(None, USER, PASSWORD, HOST, PORT, None) ++ cli.connect(None, USER, PASSWORD, HOST, PORT, None, init_command=None) + return cli + + |