Skip to content

Commit

Permalink
--raw-lines option, closes #539
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed May 7, 2023
1 parent 8f9a729 commit 373b788
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/cli-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ See :ref:`cli_query`.
--json-cols Detect JSON cols and output them as JSON, not
escaped strings
-r, --raw Raw output, first column of first row
--raw-lines Raw output, first column of each row
-p, --param <TEXT TEXT>... Named :parameters for SQL query
--functions TEXT Python code defining one or more custom SQL
functions
Expand Down Expand Up @@ -192,6 +193,7 @@ See :ref:`cli_memory`.
--json-cols Detect JSON cols and output them as JSON, not
escaped strings
-r, --raw Raw output, first column of first row
--raw-lines Raw output, first column of each row
-p, --param <TEXT TEXT>... Named :parameters for SQL query
--encoding TEXT Character encoding for CSV input, defaults to
utf-8
Expand Down
3 changes: 3 additions & 0 deletions docs/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ For example, to retrieve a binary image from a ``BLOB`` column and store it in a

$ sqlite-utils photos.db "select contents from photos where id=1" --raw > myphoto.jpg

To return the first column of each result as raw data, separated by newlines, use ``--raw-lines``::

$ sqlite-utils photos.db "select caption from photos" --raw-lines > captions.txt

.. _cli_query_parameters:

Expand Down
53 changes: 50 additions & 3 deletions sqlite_utils/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1653,6 +1653,7 @@ def drop_view(path, view, ignore, load_extension):
)
@output_options
@click.option("-r", "--raw", is_flag=True, help="Raw output, first column of first row")
@click.option("--raw-lines", is_flag=True, help="Raw output, first column of each row")
@click.option(
"-p",
"--param",
Expand All @@ -1677,6 +1678,7 @@ def query(
fmt,
json_cols,
raw,
raw_lines,
param,
load_extension,
functions,
Expand All @@ -1700,7 +1702,19 @@ def query(
_register_functions(db, functions)

_execute_query(
db, sql, param, raw, table, csv, tsv, no_headers, fmt, nl, arrays, json_cols
db,
sql,
param,
raw,
raw_lines,
table,
csv,
tsv,
no_headers,
fmt,
nl,
arrays,
json_cols,
)


Expand Down Expand Up @@ -1728,6 +1742,7 @@ def query(
)
@output_options
@click.option("-r", "--raw", is_flag=True, help="Raw output, first column of first row")
@click.option("--raw-lines", is_flag=True, help="Raw output, first column of each row")
@click.option(
"-p",
"--param",
Expand Down Expand Up @@ -1773,6 +1788,7 @@ def memory(
fmt,
json_cols,
raw,
raw_lines,
param,
encoding,
no_detect_types,
Expand Down Expand Up @@ -1879,12 +1895,36 @@ def memory(
_register_functions(db, functions)

_execute_query(
db, sql, param, raw, table, csv, tsv, no_headers, fmt, nl, arrays, json_cols
db,
sql,
param,
raw,
raw_lines,
table,
csv,
tsv,
no_headers,
fmt,
nl,
arrays,
json_cols,
)


def _execute_query(
db, sql, param, raw, table, csv, tsv, no_headers, fmt, nl, arrays, json_cols
db,
sql,
param,
raw,
raw_lines,
table,
csv,
tsv,
no_headers,
fmt,
nl,
arrays,
json_cols,
):
with db.conn:
try:
Expand All @@ -1903,6 +1943,13 @@ def _execute_query(
sys.stdout.buffer.write(data)
else:
sys.stdout.write(str(data))
elif raw_lines:
for row in cursor:
data = row[0]
if isinstance(data, bytes):
sys.stdout.buffer.write(data + b"\n")
else:
sys.stdout.write(str(data) + "\n")
elif fmt or table:
print(
tabulate.tabulate(
Expand Down
15 changes: 15 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,21 @@ def test_query_raw(db_path, content, is_binary):
assert result.output == str(content)


@pytest.mark.parametrize(
"content,is_binary",
[(b"\x00\x0Fbinary", True), ("this is text", False), (1, False), (1.5, False)],
)
def test_query_raw_lines(db_path, content, is_binary):
Database(db_path)["files"].insert_all({"content": content} for _ in range(3))
result = CliRunner().invoke(
cli.cli, [db_path, "select content from files", "--raw-lines"]
)
if is_binary:
assert result.stdout_bytes == b"\n".join(content for _ in range(3)) + b"\n"
else:
assert result.output == "\n".join(str(content) for _ in range(3)) + "\n"


def test_query_memory_does_not_create_file(tmpdir):
owd = os.getcwd()
try:
Expand Down

0 comments on commit 373b788

Please sign in to comment.