mirror of
https://github.com/simonw/datasette.git
synced 2026-08-18 15:24:06 +02:00
Round-trip binary primary key values in row URLs (#2419)
path_from_row_pks encoded a bytes (BLOB) primary key with str(bit), which isn't reversible, and the row lookup decoded every URL component to text, so a row with a binary primary key produced a 404. Encode bytes losslessly with a new tilde_encode_bytes, add tilde_decode_to_bytes, and decode BLOB primary key components back to bytes when looking up the row (non-UTF-8 values shown as hex). Adds regression tests.
This commit is contained in:
parent
db82123108
commit
b81b833c81
4 changed files with 88 additions and 11 deletions
|
|
@ -1,6 +1,6 @@
|
|||
from datasette.app import Datasette
|
||||
from datasette.events import RenameTableEvent
|
||||
from datasette.utils import error_body, escape_sqlite, sqlite3
|
||||
from datasette.utils import error_body, escape_sqlite, path_from_row_pks, sqlite3
|
||||
from .utils import last_event
|
||||
import pytest
|
||||
import time
|
||||
|
|
@ -2717,3 +2717,27 @@ async def test_create_using_alter_against_existing_table(
|
|||
insert_rows_event = ds_write._tracked_events[1]
|
||||
assert insert_rows_event.name == "insert-rows"
|
||||
assert insert_rows_event.num_rows == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_row_page_with_binary_primary_key(ds_write):
|
||||
# Regression test for #2419 - a row with a binary (BLOB) primary key value
|
||||
# should be reachable via its generated URL instead of returning a 404.
|
||||
db = ds_write.get_database("data")
|
||||
await db.execute_write(
|
||||
"create table binary_pk (id integer, term blob, primary key (id, term))"
|
||||
)
|
||||
terms = (b"0thei'", b"\xff\x00abc")
|
||||
for term in terms:
|
||||
await db.execute_write(
|
||||
"insert into binary_pk (id, term) values (?, ?)", [3, term]
|
||||
)
|
||||
for term in terms:
|
||||
path = path_from_row_pks(
|
||||
{"id": 3, "term": term}, ["id", "term"], use_rowid=False
|
||||
)
|
||||
html = await ds_write.client.get(f"/data/binary_pk/{path}")
|
||||
assert html.status_code == 200, html.text
|
||||
js = await ds_write.client.get(f"/data/binary_pk/{path}.json?_shape=array")
|
||||
assert js.status_code == 200, js.text
|
||||
assert len(js.json()) == 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue