Skip to content

Commit 1f34a49

Browse files
authored
Merge pull request #1200 from dbcli/amjith/init-per-dsn
Amjith/init per dsn
2 parents 3da3aa0 + bb18b0c commit 1f34a49

File tree

7 files changed

+86
-6
lines changed

7 files changed

+86
-6
lines changed

changelog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
Upcoming Release (TBD)
2+
======================
3+
4+
Features
5+
--------
6+
7+
* DSN specific init-command in myclirc. Fixes (#1195)
8+
9+
10+
111
1.29.2 (2024/12/11)
212
===================
313

mycli/main.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import stat
1111
from collections import namedtuple
1212

13+
from pygments.lexer import combined
14+
1315
try:
1416
from pwd import getpwuid
1517
except ImportError:
@@ -1262,9 +1264,13 @@ def cli(
12621264

12631265
dsn_uri = None
12641266

1265-
# Treat the database argument as a DSN alias if we're missing
1266-
# other connection information.
1267-
if mycli.config["alias_dsn"] and database and "://" not in database and not any([user, password, host, port, login_path]):
1267+
# Treat the database argument as a DSN alias only if it matches a configured alias
1268+
if (
1269+
database
1270+
and "://" not in database
1271+
and not any([user, password, host, port, login_path])
1272+
and database in mycli.config.get("alias_dsn", {})
1273+
):
12681274
dsn, database = database, ""
12691275

12701276
if database and "://" in database:
@@ -1306,6 +1312,29 @@ def cli(
13061312
ssh_key_filename = ssh_key_filename if ssh_key_filename else ssh_config.get("identityfile", [None])[0]
13071313

13081314
ssh_key_filename = ssh_key_filename and os.path.expanduser(ssh_key_filename)
1315+
# Merge init-commands: global, DSN-specific, then CLI
1316+
init_cmds = []
1317+
# 1) Global init-commands
1318+
global_section = mycli.config.get("init-commands", {})
1319+
for _, val in global_section.items():
1320+
if isinstance(val, (list, tuple)):
1321+
init_cmds.extend(val)
1322+
elif val:
1323+
init_cmds.append(val)
1324+
# 2) DSN-specific init-commands
1325+
if dsn:
1326+
alias_section = mycli.config.get("alias_dsn.init-commands", {})
1327+
if dsn in alias_section:
1328+
val = alias_section.get(dsn)
1329+
if isinstance(val, (list, tuple)):
1330+
init_cmds.extend(val)
1331+
elif val:
1332+
init_cmds.append(val)
1333+
# 3) CLI-provided init_command
1334+
if init_command:
1335+
init_cmds.append(init_command)
1336+
1337+
combined_init_cmd = "; ".join(cmd.strip() for cmd in init_cmds if cmd)
13091338

13101339
mycli.connect(
13111340
database=database,
@@ -1321,11 +1350,14 @@ def cli(
13211350
ssh_port=ssh_port,
13221351
ssh_password=ssh_password,
13231352
ssh_key_filename=ssh_key_filename,
1324-
init_command=init_command,
1353+
init_command=combined_init_cmd,
13251354
charset=charset,
13261355
password_file=password_file,
13271356
)
13281357

1358+
if combined_init_cmd:
1359+
click.echo("Executing init-command: %s" % combined_init_cmd, err=True)
1360+
13291361
mycli.logger.debug("Launch Params: \n" "\tdatabase: %r" "\tuser: %r" "\thost: %r" "\tport: %r", database, user, host, port)
13301362

13311363
# --execute argument

mycli/myclirc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,22 @@ output.null = "#808080"
151151
# sql.whitespace = ''
152152

153153
# Favorite queries.
154+
# You can add your favorite queries here. They will be available in the
155+
# REPL when you type `\f` or `\f <query_name>`.
154156
[favorite_queries]
157+
# example = "SELECT * FROM example_table WHERE id = 1"
158+
159+
# Initial commands to execute when connecting to any database.
160+
[init-commands]
161+
# read_only = "SET SESSION TRANSACTION READ ONLY"
162+
155163

156164
# Use the -d option to reference a DSN.
157165
# Special characters in passwords and other strings can be escaped with URL encoding.
158166
[alias_dsn]
159167
# example_dsn = mysql://[user[:password]@][host][:port][/dbname]
168+
169+
# Initial commands to execute when connecting to a DSN alias.
170+
[alias_dsn.init-commands]
171+
# Define one or more SQL statements per alias (semicolon-separated).
172+
# example_dsn = "SET sql_select_limit=1000; SET time_zone='+00:00'"

mycli/sqlexecute.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def connect(
233233
ssl=ssl_context,
234234
program_name="mycli",
235235
defer_connect=defer_connect,
236-
init_command=init_command,
236+
init_command=init_command or None,
237237
)
238238

239239
if ssh_host:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ authors = [{ name = "Mycli Core Team", email = "mycli-dev@googlegroups.com" }]
99
urls = { homepage = "http://mycli.net" }
1010

1111
dependencies = [
12-
"click >= 7.0",
12+
"click >= 7.0,<8.1.8",
1313
"cryptography >= 1.0.0",
1414
"Pygments>=1.6",
1515
"prompt_toolkit>=3.0.6,<4.0.0",

test/myclirc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,25 @@ output.null = "#808080"
151151
# sql.whitespace = ''
152152

153153
# Favorite queries.
154+
# You can add your favorite queries here. They will be available in the
155+
# REPL when you type `\f` or `\f <query_name>`.
154156
[favorite_queries]
155157
check = 'select "✔"'
156158
foo_args = 'SELECT $1, "$2", "$3"'
159+
# example = "SELECT * FROM example_table WHERE id = 1"
160+
161+
# Initial commands to execute when connecting to any database.
162+
[init-commands]
163+
# read_only = "SET SESSION TRANSACTION READ ONLY"
164+
global_limit = "set sql_select_limit=9999"
165+
157166

158167
# Use the -d option to reference a DSN.
159168
# Special characters in passwords and other strings can be escaped with URL encoding.
160169
[alias_dsn]
161170
# example_dsn = mysql://[user[:password]@][host][:port][/dbname]
171+
172+
# Initial commands to execute when connecting to a DSN alias.
173+
[alias_dsn.init-commands]
174+
# Define one or more SQL statements per alias (semicolon-separated).
175+
# example_dsn = "SET sql_select_limit=1000; SET time_zone='+00:00'"

test/test_main.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,3 +553,14 @@ def test_init_command_multiple_arg(executor):
553553
assert result.exit_code == 0
554554
assert expected_sql_select_limit in result.output
555555
assert expected_max_join_size in result.output
556+
557+
@dbtest
558+
def test_global_init_commands(executor):
559+
"""Tests that global init-commands from config are executed by default."""
560+
# The global init-commands section in test/myclirc sets sql_select_limit=9999
561+
sql = 'show variables like "sql_select_limit";'
562+
runner = CliRunner()
563+
result = runner.invoke(cli, args=CLI_ARGS, input=sql)
564+
expected = "sql_select_limit\t9999\n"
565+
assert result.exit_code == 0
566+
assert expected in result.output

0 commit comments

Comments
 (0)