Skip to content

Commit

Permalink
edit-row-details on tables with text primary keys, refs #10
Browse files Browse the repository at this point in the history
  • Loading branch information
asg017 committed Aug 9, 2023
1 parent c4fe163 commit 963c73c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 13 deletions.
18 changes: 17 additions & 1 deletion datasette_write_ui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datasette import hookimpl, Response, Forbidden
from datasette.utils import escape_sqlite
from typing import Any, TypedDict
from datasette.utils import tilde_decode


@hookimpl
Expand Down Expand Up @@ -76,14 +77,29 @@ async def edit_row_details(scope, receive, datasette, request):
column_list = ", ".join(
list(map(lambda column: escape_sqlite(column.get("name")), columns))
)
pk_columns = [
row[0]
for row in await db.execute(
"select name from pragma_table_xinfo(?) where pk != 0 order by pk",
[table_name],
)
]

# TODO only works in single primary key tables
id_column = "rowid" if len(pk_columns) == 0 else pk_columns[0]
results = await db.execute(
f"select {column_list} from {table_name} where rowid = ?", [pks]
f"select {column_list} from {table_name} where {escape_sqlite(id_column)} = ?",
[tilde_decode(pks)],
)

fields = []
row = results.first()

if row is None:
return Response.json(
{"ok": False, "message": "No matching row found."}, status=400
)

for column in columns:
value = row[column["name"]]
fields.append(
Expand Down
21 changes: 12 additions & 9 deletions tests/students.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,26 @@ insert into students values (2, 'brian', 20, 90.0, 0);
insert into students values (3, 'craig', 30, 124.5, 0);

create table courses(
id int primary key,
name text
name text primary key
);

insert into courses values(1, 'MATH 101');
insert into courses values(2, 'MATH 102');
insert into courses values('MATH 101');
insert into courses values('MATH 102');

create table enrollees(
--! primarily an example of a table with composite primary keys

course_id int,
course_id text,
student_id int,
dropped_at date,
primary key(course_id, student_id)
);

insert into enrollees values (1, 1, null);
insert into enrollees values (1, 2, null);
insert into enrollees values (1, 3, null);
insert into enrollees values (2, 1, '2023-01-15');
insert into enrollees values ('MATH 101', 1, null);
insert into enrollees values ('MATH 101', 2, null);
insert into enrollees values ('MATH 101', 3, null);
insert into enrollees values ('MATH 102', 1, '2023-01-15');

create table t(a int);

insert into t(a) values (1);
38 changes: 35 additions & 3 deletions tests/test_datasette_write_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,21 @@ def get_permission_from_table_html(html):
@pytest.fixture
def students_db_path(tmpdir):
path = str(tmpdir / "students.db")
sqlite_utils.Database(path)["students"].insert_all(
db = sqlite_utils.Database(path)
db["students"].insert_all(
[
{"name": "alex", "age": 10},
{"name": "brian", "age": 20},
{"name": "craig", "age": 30, "[weird (column)]": 1},
]
)
db.execute("create table courses(name text primary key) without rowid")
db["courses"].insert_all(
[
{"name": "MATH 101"},
{"name": "MATH 102"},
]
)
return path


Expand Down Expand Up @@ -110,6 +118,11 @@ async def test_insert_row_details_route(students_db_path):
async def test_update_row_details_route(students_db_path):
datasette = Datasette([students_db_path])

response = await datasette.client.get(
"/-/datasette-write-ui/insert-row-details?db=students&table=students",
)
assert response.status_code == 403

response = await datasette.client.get(
"/-/datasette-write-ui/edit-row-details?db=students&table=students&primaryKeys=1",
cookies={"ds_actor": datasette.sign(actor_root, "actor")},
Expand All @@ -136,6 +149,25 @@ async def test_update_row_details_route(students_db_path):
}

response = await datasette.client.get(
"/-/datasette-write-ui/insert-row-details?db=students&table=students",
"/-/datasette-write-ui/edit-row-details?db=students&table=courses&primaryKeys=MATH+101",
cookies={"ds_actor": datasette.sign(actor_root, "actor")},
)
assert response.status_code == 403
assert response.status_code == 200
assert response.json() == {
"fields": [
{
"key": "name",
"value": "MATH 101",
"type": "str",
"pk": True,
"editable": False,
},
]
}

response = await datasette.client.get(
"/-/datasette-write-ui/edit-row-details?db=students&table=courses&primaryKeys=not_exist",
cookies={"ds_actor": datasette.sign(actor_root, "actor")},
)
assert response.status_code == 400
assert response.json() == {"ok": False, "message": "No matching row found."}

0 comments on commit 963c73c

Please sign in to comment.