Skip to content

Commit 520c37f

Browse files
authored
Merge branch 'master' into feature/ssh_config
2 parents 6917294 + 6b4174b commit 520c37f

File tree

10 files changed

+52
-16
lines changed

10 files changed

+52
-16
lines changed

changelog.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ Features:
77
* Add an option `--list-ssh-config` to list ssh configurations.
88
* Add an option `--ssh-config-path` to choose ssh configuration path.
99

10-
1.20.2
11-
=======
10+
11+
1.21.1
12+
======
1213

1314

1415
Bug Fixes:
1516
----------
1617

1718
* Fix broken auto-completion for favorite queries (Thanks: [Amjith]).
18-
19+
* Fix undefined variable exception when running with --no-warn (Thanks: [Georgy Frolov])
1920

2021
1.21.0
2122
======
@@ -26,6 +27,8 @@ Features:
2627
* Mark `update` without `where`-clause as destructive query (Thanks: [Klaus Wünschel]).
2728
* Added DELIMITER command (Thanks: [Georgy Frolov])
2829
* Added clearer error message when failing to connect to the default socket.
30+
* Extend main.is_dropping_database check with create after delete statement.
31+
* Search `${XDG_CONFIG_HOME}/mycli/myclirc` after `${HOME}/.myclirc` and before `/etc/myclirc` (Thanks: [Takeshi D. Itoh])
2932

3033
Bug Fixes:
3134
----------

mycli/AUTHORS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ Contributors:
6969
* Georgy Frolov
7070
* Jonathan Lloyd
7171
* Nathan Huang
72+
* Jakub Boukal
73+
* Takeshi D. Itoh
7274
* laixintao
7375

7476
Creator:

mycli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.21.0'
1+
__version__ = '1.21.1'

mycli/main.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,14 @@ class MyCli(object):
8787
'~/.my.cnf'
8888
]
8989

90+
# check XDG_CONFIG_HOME exists and not an empty string
91+
if os.environ.get("XDG_CONFIG_HOME"):
92+
xdg_config_home = os.environ.get("XDG_CONFIG_HOME")
93+
else:
94+
xdg_config_home = "~/.config"
9095
system_config_files = [
9196
'/etc/myclirc',
97+
os.path.join(xdg_config_home, "mycli", "myclirc")
9298
]
9399

94100
default_config_file = os.path.join(PACKAGE_ROOT, 'myclirc')
@@ -162,7 +168,7 @@ def __init__(self, sqlexecute=None, prompt=None,
162168
prompt_cnf = self.read_my_cnf_files(self.cnf_files, ['prompt'])['prompt']
163169
self.prompt_format = prompt or prompt_cnf or c['main']['prompt'] or \
164170
self.default_prompt
165-
self.prompt_continuation_format = c['main']['prompt_continuation']
171+
self.multiline_continuation_char = c['main']['prompt_continuation']
166172
keyword_casing = c['main'].get('keyword_casing', 'auto')
167173

168174
self.query_history = []
@@ -539,8 +545,14 @@ def get_message():
539545
prompt = self.get_prompt('\\d> ')
540546
return [('class:prompt', prompt)]
541547

542-
def get_continuation(width, line_number, is_soft_wrap):
543-
continuation = ' ' * (width - 1) + ' '
548+
def get_continuation(width, *_):
549+
if self.multiline_continuation_char:
550+
left_padding = width - len(self.multiline_continuation_char)
551+
continuation = " " * \
552+
max((left_padding - 1), 0) + \
553+
self.multiline_continuation_char + " "
554+
else:
555+
continuation = " "
544556
return [('class:continuation', continuation)]
545557

546558
def show_suggestion_tip():
@@ -575,6 +587,8 @@ def one_iteration(text=None):
575587
else:
576588
self.echo('Wise choice!')
577589
return
590+
else:
591+
destroy = True
578592

579593
# Keep track of whether or not the query is mutating. In case
580594
# of a multi-statement query, the overall query is considered

mycli/myclirc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ wider_completion_menu = False
6666
# \A - DSN alias name (from the [alias_dsn] section)
6767
# \u - Username
6868
prompt = '\t \u@\h:\d> '
69-
prompt_continuation = '-> '
69+
prompt_continuation = '->'
7070

7171
# Skip intro info on startup and outro info on exit
7272
less_chatty = False

mycli/packages/parseutils.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ def is_open_quote(sql):
241241

242242
def is_dropping_database(queries, dbname):
243243
"""Determine if the query is dropping a specific database."""
244+
result = False
244245
if dbname is None:
245246
return False
246247

@@ -253,16 +254,14 @@ def normalize_db_name(db):
253254
keywords = [t for t in query.tokens if t.is_keyword]
254255
if len(keywords) < 2:
255256
continue
256-
if keywords[0].normalized == "DROP" and keywords[1].value.lower() in (
257+
if keywords[0].normalized in ("DROP", "CREATE") and keywords[1].value.lower() in (
257258
"database",
258259
"schema",
259260
):
260261
database_token = next(
261262
(t for t in query.tokens if isinstance(t, Identifier)), None
262263
)
263-
return (
264-
database_token is not None
265-
and normalize_db_name(database_token.get_name()) == dbname
266-
)
264+
if database_token is not None and normalize_db_name(database_token.get_name()) == dbname:
265+
result = keywords[0].normalized == "DROP"
267266
else:
268-
return False
267+
return result

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
install_requirements = [
2020
'click >= 7.0',
2121
'Pygments >= 1.6',
22-
'prompt_toolkit>=2.0.6,<3.0.0',
22+
'prompt_toolkit>=3.0.0,<4.0.0',
2323
'PyMySQL >= 0.9.2',
2424
'sqlparse>=0.3.0,<0.4.0',
2525
'configobj >= 5.0.5',

test/features/crud_table.feature

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ Feature: manipulate tables:
2828
then we see null selected
2929

3030
Scenario: confirm destructive query
31-
When we query "delete from foo;"
31+
When we query "create table foo(x integer);"
32+
and we query "delete from foo;"
3233
and we answer the destructive warning with "y"
3334
then we see text "Your call!"
3435

@@ -37,6 +38,12 @@ Feature: manipulate tables:
3738
and we answer the destructive warning with "n"
3839
then we see text "Wise choice!"
3940

41+
Scenario: no destructive warning if disabled in config
42+
When we run dbcli with --no-warn
43+
and we query "create table blabla(x integer);"
44+
and we query "delete from blabla;"
45+
Then we see text "Query OK"
46+
4047
Scenario: confirm destructive query with invalid response
4148
When we query "delete from foo;"
4249
then we answer the destructive warning with invalid "1" and see text "is not a valid boolean"

test/features/environment.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88

99
from steps.wrappers import run_cli, wait_prompt
1010

11+
test_log_file = os.path.join(os.environ['HOME'], '.mycli.test.log')
12+
1113

1214
def before_all(context):
1315
"""Set env parameters."""
1416
os.environ['LINES'] = "100"
1517
os.environ['COLUMNS'] = "100"
1618
os.environ['EDITOR'] = 'ex'
1719
os.environ['LC_ALL'] = 'en_US.utf8'
20+
os.environ['PROMPT_TOOLKIT_NO_CPR'] = '1'
1821

1922
test_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
2023
login_path_file = os.path.join(test_dir, 'mylogin.cnf')
@@ -95,12 +98,18 @@ def before_step(context, _):
9598

9699

97100
def before_scenario(context, _):
101+
with open(test_log_file, 'w') as f:
102+
f.write('')
98103
run_cli(context)
99104
wait_prompt(context)
100105

101106

102107
def after_scenario(context, _):
103108
"""Cleans up after each test complete."""
109+
with open(test_log_file) as f:
110+
for line in f:
111+
if 'error' in line.lower():
112+
raise RuntimeError(f'Error in log file: {line}')
104113

105114
if hasattr(context, 'cli') and not context.exit_sent:
106115
# Quit nicely.

test/test_parseutils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ def test_query_has_where_clause(sql, has_where_clause):
175175
('drop schema foo', 'bar', False),
176176
('drop database bar', 'foo', False),
177177
('drop database foo', None, False),
178+
('drop database foo; create database foo', 'foo', False),
179+
('drop database foo; create database bar', 'foo', True),
178180
('select bar from foo; drop database bazz', 'foo', False),
179181
('select bar from foo; drop database bazz', 'bazz', True),
180182
('-- dropping database \n '

0 commit comments

Comments
 (0)