From 0a410222cbacc7986e4f8a2ec3775a85515280a9 Mon Sep 17 00:00:00 2001 From: symphony-dbcli Date: Mon, 8 Jun 2026 18:22:32 +0000 Subject: [PATCH] Fix #244: Automatically decode hex for BLOB fields --- CHANGELOG.md | 1 + litecli/sqlexecute.py | 12 +++++++++++- tests/test_sqlexecute.py | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e429af4..617e314 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Bug Fixes +- Display SQLite BLOB values as decoded hex strings in query results. - Expand `~` in configured log file paths before opening the log. ### Internal diff --git a/litecli/sqlexecute.py b/litecli/sqlexecute.py index 5e52b73..633bccf 100644 --- a/litecli/sqlexecute.py +++ b/litecli/sqlexecute.py @@ -29,6 +29,16 @@ # }) +def _decode_blob(value: Any) -> Any: + if isinstance(value, bytes): + return value.hex().upper() + return value + + +def _decode_blobs(row: tuple) -> tuple: + return tuple(_decode_blob(value) for value in row) + + class SQLExecute(object): databases_query = """ PRAGMA database_list @@ -163,7 +173,7 @@ def get_result(self, cursor: Any) -> tuple[str | None, list | None, list | None, if cursor.description is not None: headers = [x[0] for x in cursor.description] status = "{count} row{s} in set" - cursor = list(cursor) + cursor = [_decode_blobs(row) for row in cursor] rowcount = len(cursor) else: _logger.debug("No rows in result.") diff --git a/tests/test_sqlexecute.py b/tests/test_sqlexecute.py index 3fdaef1..64db514 100644 --- a/tests/test_sqlexecute.py +++ b/tests/test_sqlexecute.py @@ -52,6 +52,15 @@ def test_binary(executor): assert_result_equal(results, headers=["blb"], rows=[(expected,)]) +@dbtest +def test_blob_returns_hex(executor): + run(executor, """create table foo(blb BLOB NOT NULL)""") + run(executor, """INSERT INTO foo VALUES (x'0101C30A')""") + results = run(executor, """select * from foo""") + + assert_result_equal(results, headers=["blb"], rows=[("0101C30A",)]) + + @dbtest def test_table_and_columns_query(executor): run(executor, "create table a(x text, y text)")