Skip to content

Commit c1f7911

Browse files
authored
Merge pull request #234 from lonetwin/uri-arg
Add support for URI style database names
2 parents c072661 + ed0d893 commit c1f7911

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
## Upcoming (TBC)
1+
## Upcoming (TBD)
2+
3+
### Features
4+
5+
* Add support for opening 'file:' URIs with parameters. [(#234)](https://github.com/dbcli/litecli/pull/234)
26

37
### Bug Fixes
48

59
* Avoid Click 8.1.* to prevent messing up the pager when the PAGER env var has a string with spaces.
610

11+
712
## 1.16.0 - 2025-08-16
813

914
### Features

litecli/sqlexecute.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import sqlparse
1616
import os.path
17+
from urllib.parse import urlparse
1718

1819
from .packages import special
1920

@@ -68,20 +69,27 @@ def connect(self, database=None):
6869
db = database or self.dbname
6970
_logger.debug("Connection DB Params: \n\tdatabase: %r", db)
7071

71-
db_name = os.path.expanduser(db)
72-
db_dir_name = os.path.dirname(os.path.abspath(db_name))
73-
if not os.path.exists(db_dir_name):
74-
raise Exception("Path does not exist: {}".format(db_dir_name))
72+
location = urlparse(db)
73+
if location.scheme and location.scheme == "file":
74+
uri = True
75+
db_name = db
76+
db_filename = location.path
77+
else:
78+
uri = False
79+
db_filename = db_name = os.path.expanduser(db)
80+
db_dir_name = os.path.dirname(os.path.abspath(db_filename))
81+
if not os.path.exists(db_dir_name):
82+
raise Exception("Path does not exist: {}".format(db_dir_name))
7583

76-
conn = sqlite3.connect(database=db_name, isolation_level=None)
84+
conn = sqlite3.connect(database=db_name, isolation_level=None, uri=uri)
7785
conn.text_factory = lambda x: x.decode("utf-8", "backslashreplace")
7886
if self.conn:
7987
self.conn.close()
8088

8189
self.conn = conn
8290
# Update them after the connection is made to ensure that it was a
8391
# successful connection.
84-
self.dbname = db
92+
self.dbname = db_filename
8593

8694
def run(self, statement):
8795
"""Execute the sql in the database and return the results. The results

tests/test_main.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
from unittest.mock import patch
77

88
import click
9+
import pytest
910
from click.testing import CliRunner
1011

1112
from litecli.main import cli, LiteCli
1213
from litecli.packages.special.main import COMMANDS as SPECIAL_COMMANDS
13-
from utils import dbtest, run
14+
from utils import dbtest, run, create_db, db_connection
1415

1516
test_dir = os.path.abspath(os.path.dirname(__file__))
1617
project_dir = os.path.dirname(test_dir)
@@ -330,3 +331,30 @@ def test_get_prompt(mock_datetime):
330331
# 12. Windows path
331332
lc.connect("C:\\Users\\litecli\\litecli_test.db")
332333
assert lc.get_prompt(r"\d") == "C:\\Users\\litecli\\litecli_test.db"
334+
335+
336+
@pytest.mark.parametrize(
337+
"uri, expected_dbname",
338+
[
339+
("file:{tmp_path}/test.db", "{tmp_path}/test.db"),
340+
("file:{tmp_path}/test.db?mode=ro", "{tmp_path}/test.db"),
341+
("file:{tmp_path}/test.db?mode=ro&cache=shared", "{tmp_path}/test.db"),
342+
],
343+
)
344+
def test_file_uri(tmp_path, uri, expected_dbname):
345+
"""
346+
Test that `file:` URIs are correctly handled
347+
ref:
348+
https://docs.python.org/3/library/sqlite3.html#sqlite3-uri-tricks
349+
https://www.sqlite.org/c3ref/open.html#urifilenameexamples
350+
"""
351+
# - ensure db exists
352+
db_path = tmp_path / "test.db"
353+
create_db(db_path)
354+
db_connection(db_path)
355+
uri = uri.format(tmp_path=tmp_path)
356+
357+
lc = LiteCli()
358+
lc.connect(uri)
359+
360+
assert lc.get_prompt(r"\d") == expected_dbname.format(tmp_path=tmp_path)

0 commit comments

Comments
 (0)