Skip to content

Commit

Permalink
Initial work on add_column, refs #4
Browse files Browse the repository at this point in the history
Still needs form validation and nice errors.
  • Loading branch information
simonw committed Mar 15, 2020
1 parent fc7f694 commit 50e1957
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 2 deletions.
24 changes: 22 additions & 2 deletions datasette_edit_tables/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,37 @@ def get_columns(conn):
)

async def delete_table(self, database, table):
def delete_table(conn):
def do_delete_table(conn):
db = sqlite_utils.Database(conn)
db[table].disable_fts()
db[table].drop()
db.vacuum()

await datasette.databases[database.name].execute_write_fn(
delete_table, block=True
do_delete_table, block=True
)

return RedirectResponse(
"/{}".format(quote_plus(database.name)), status_code=302,
)

async def add_column(self, database, table, formdata):
name = formdata["name"]
type = formdata["type"]

def do_add_column(conn):
db = sqlite_utils.Database(conn)
db[table].add_column(name, type)

await datasette.databases[database.name].execute_write_fn(
do_add_column, block=True
)

return RedirectResponse(
"/{}/{}".format(quote_plus(database.name), quote_plus(table)),
status_code=302,
)

async def post(self, request):
table = request.path_params["table"]
databases = self.get_databases()
Expand All @@ -154,6 +171,9 @@ async def post(self, request):
if "delete_table" in formdata:
return await self.delete_table(database, table)

if "add_column" in formdata:
return await self.add_column(database, table, formdata)

return HTMLResponse("Unknown operation", status_code=400)

return EditTablesIndex, EditTablesDatabase, EditTablesTable
17 changes: 17 additions & 0 deletions datasette_edit_tables/templates/edit_tables_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,23 @@ <h2>Columns</h2>
{% endfor %}
</ul>

<h2>Add a column</h2>

<form action="/-/edit-tables/{{ database.name|quote_plus }}/{{ table|quote_plus }}" method="post">
<input type="hidden" name="csrftoken" value="{{ csrftoken }}">
<input type="hidden" name="add_column" value="1">
<p><label>Name <input type="text" name="name"></label>
<label>Type <select name="type">
<option value="text">text</option>
<option value="integer">integer number</option>
<option value="float">floating point number</option>
<option value="blob">binary data</option>
</select></label></p>
<input type="submit" value="Add column">
</form>

<h2>Delete table</h2>

<form action="/-/edit-tables/{{ database.name|quote_plus }}/{{ table|quote_plus }}" method="post">
<input type="hidden" name="csrftoken" value="{{ csrftoken }}">
<input type="hidden" name="delete_table" value="1">
Expand Down
33 changes: 33 additions & 0 deletions tests/test_edit_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,36 @@ async def test_delete_table(db_path):
)
assert 302 == response.status_code
assert "creatures" not in db.table_names()


@pytest.mark.asyncio
@pytest.mark.parametrize(
"col_type,expected_type",
[("text", str), ("integer", int), ("float", float), ("blob", bytes)],
)
async def test_add_column(db_path, col_type, expected_type):
app = Datasette([db_path]).app()
db = sqlite_utils.Database(db_path)
table = db["creatures"]
assert {"name": str, "description": str} == table.columns_dict
async with httpx.AsyncClient(app=app) as client:
# Get a csrftoken
csrftoken = (
await client.get("http://localhost/-/edit-tables/data/creatures")
).cookies["csrftoken"]
response = await client.post(
"http://localhost/-/edit-tables/data/creatures",
data={
"add_column": "1",
"csrftoken": csrftoken,
"name": "new_col",
"type": col_type,
},
allow_redirects=False,
)
assert 302 == response.status_code
assert {
"name": str,
"description": str,
"new_col": expected_type,
} == table.columns_dict

0 comments on commit 50e1957

Please sign in to comment.