{"html_url": "https://github.com/simonw/datasette/issues/473#issuecomment-996275108", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/473", "id": 996275108, "node_id": "IC_kwDOBm6k_c47YfOk", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T23:32:22Z", "updated_at": "2021-12-16T23:32:30Z", "author_association": "OWNER", "body": "This filter design can only influence the `where` component of the SQL clause - it's not able to modify the `SELECT` columns or adjust the `ORDER BY` or `OFFSET LIMIT` parts. I think that's OK.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 445850934, "label": "Plugin hook: filters_from_request"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-996272906", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 996272906, "node_id": "IC_kwDOBm6k_c47YesK", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T23:27:42Z", "updated_at": "2021-12-16T23:27:42Z", "author_association": "OWNER", "body": "Got a TIL out of this: https://til.simonwillison.net/pluggy/multiple-hooks-same-file", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/473#issuecomment-996267817", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/473", "id": 996267817, "node_id": "IC_kwDOBm6k_c47Ydcp", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T23:17:52Z", "updated_at": "2021-12-16T23:19:00Z", "author_association": "OWNER", "body": "I revisited this idea in #1518 and came up with a slightly different name and design for the hook:\r\n\r\n```python\r\n@hookspec\r\ndef filters_from_request(request, database, table, datasette):\r\n \"\"\"\r\n Return FilterArguments(\r\n where_clauses=[str, str, str],\r\n params={},\r\n human_descriptions=[str, str, str],\r\n extra_context={}\r\n ) based on the request\"\"\"\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 445850934, "label": "Plugin hook: filters_from_request"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-996264617", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 996264617, "node_id": "IC_kwDOBm6k_c47Ycqp", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T23:11:12Z", "updated_at": "2021-12-16T23:11:12Z", "author_association": "OWNER", "body": "I managed to extract both `_search=` and `_where=` out using a prototype of that hook. I wonder if it could extract the complex code for `?_next` too?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-996250585", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 996250585, "node_id": "IC_kwDOBm6k_c47YZPZ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T22:43:37Z", "updated_at": "2021-12-16T22:45:07Z", "author_association": "OWNER", "body": "Ran into a problem prototyping that hook up for handling `?_where=` - that feature also adds a little bit of extra template context in order to show the interface for removing wheres - the `extra_wheres_for_ui` variable: https://github.com/simonw/datasette/blob/0663d5525cc41e9260ac7d1f6386d3a6eb5ad2a9/datasette/views/table.py#L457-L463\r\n\r\nMaybe change to this?\r\n\r\n```python\r\nclass FilterArguments(NamedTuple):\r\n where_clauses: List[str]\r\n params: Dict[str, Union[str, int, float]]\r\n human_descriptions: List[str]\r\n extra_context: Dict[str, Any]\r\n```\r\nThat might be necessary for `_search` too.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-996248713", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 996248713, "node_id": "IC_kwDOBm6k_c47YYyJ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T22:39:47Z", "updated_at": "2021-12-16T22:39:47Z", "author_association": "OWNER", "body": "The hook could return a named tuple like this one:\r\n```python\r\nfrom typing import NamedTuple, List, Optional, Union, Dict\r\n\r\nclass FilterArguments(NamedTuple):\r\n where_clauses: List[str]\r\n params: Dict[str, Union[str, int, float]]\r\n human_descriptions: List[str]\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-996240802", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 996240802, "node_id": "IC_kwDOBm6k_c47YW2i", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T22:25:00Z", "updated_at": "2021-12-16T22:36:04Z", "author_association": "OWNER", "body": "I think that plugin hook would get given the `request` object (and `datasette` and the name of the database and table) and returns a list of SQL fragments, a dictionary of lookup arguments and a list of human-description fragments - or an awaitable.\r\n\r\n`filters_from_request(request, database, table, datasette)` perhaps? (Similar in name to `actor_from_request`).\r\n\r\n```python\r\n@hookspec\r\ndef filters_from_request(request, database, table, datasette):\r\n \"\"\"Return (where_clauses, params_dict, human_descriptions) based on the request\"\"\"\r\n```\r\n\r\nTurns out that's pretty much exactly what I implemented in 5116c4ec8aed5091e1f75415424b80f613518dc6 for #473:\r\n\r\n```python\r\n\r\n@hookspec\r\ndef table_filter():\r\n \"Custom filtering of the current table based on the request\"\r\n```\r\n```python\r\nTableFilter = namedtuple(\"TableFilter\", (\r\n \"human_description_extras\", \"where_clauses\", \"params\")\r\n)\r\n```\r\n```python\r\n # filter_arguments plugin hook support\r\n for awaitable_fn in pm.hook.table_filter():\r\n extras = await awaitable_fn(\r\n view=self, name=name, table=table, request=request\r\n )\r\n human_description_extras.extend(extras.human_description_extras)\r\n where_clauses.extend(extras.where_clauses)\r\n params.update(extras.params)\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/358#issuecomment-996232461", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/358", "id": 996232461, "node_id": "IC_kwDOCGYnMM47YU0N", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T22:10:39Z", "updated_at": "2021-12-16T22:10:39Z", "author_association": "OWNER", "body": "This goes beyond the `transform()` method - the curious methods that create new SQL tables could benefit from the ability to add `CHECK` constraints too.\r\n\r\nI haven't used these myself, do you have any `CREATE TABLE` examples that use them that you can share?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1082651698, "label": "Support for CHECK constraints"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1552#issuecomment-996229007", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1552", "id": 996229007, "node_id": "IC_kwDOBm6k_c47YT-P", "user": {"value": 3556, "label": "davidbgk"}, "created_at": "2021-12-16T22:04:39Z", "updated_at": "2021-12-16T22:04:39Z", "author_association": "CONTRIBUTOR", "body": "Wow, that was fast, thank you so much @simonw !\r\n\r\n> I'm also not convinced that this configuration syntax is right. It's a bit weird having a `\"facets\"` list that can either by column-name-strings or `{\"type-of-facet\": \"column-name\"}` objects. Maybe there's a better design for this?\r\n\r\nI agree that it's not ideal, my initial naive approach was to detect if it's an array, like what is done here:\r\n\r\nhttps://github.com/simonw/datasette/blob/2c07327d23d9c5cf939ada9ba4091c1b8b2ba42d/datasette/facets.py#L312-L313\r\n\r\nBut it requires an extra query to determine the type, which is a bit problematic, especially for big tables I guess.\r\n\r\nTaking a look at #510, I wonder if a `facet_delimiter` should be defined for that kind of columns (that would help our team not to have an intermediary conversion step from `foo|bar` to `[\"foo\",\"bar\"]` for instance).\r\n\r\nTo be consistent with the `--extract-column` parameter, maybe an explicit casting/delimiter would be useful: `--set-column 'Foo:Array:|'`.\r\n\r\nThrowing a lot of ideas without knowing the big picture\u2026 but sometimes newcomers have superpowers :).", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1078702875, "label": "Allow to set `facets_array` in metadata (like current `facets`)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-996227713", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 996227713, "node_id": "IC_kwDOBm6k_c47YTqB", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T22:02:35Z", "updated_at": "2021-12-16T22:03:55Z", "author_association": "OWNER", "body": "Is there an opportunity to refactor things using a new plugin hook here? Maybe the `register_filters` hook from #473, where the hook becomes responsible for building where clauses (and human descriptions of them) based on the incoming query string.\r\n\r\nThat version dealt with `Filter` classes, but those might be a bit too low-level for this.\r\n\r\n`?_spatial_within=GEOJSON` was an interesting idea attached to that issue.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-996225889", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 996225889, "node_id": "IC_kwDOBm6k_c47YTNh", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T21:59:32Z", "updated_at": "2021-12-16T22:00:42Z", "author_association": "OWNER", "body": "I added a ton of comments to the `data()` method which really helps get a better feel for how this all works: https://github.com/simonw/datasette/blob/0663d5525cc41e9260ac7d1f6386d3a6eb5ad2a9/datasette/views/table.py#L322", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-996225235", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 996225235, "node_id": "IC_kwDOBm6k_c47YTDT", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-12-16T21:58:24Z", "updated_at": "2021-12-16T21:58:41Z", "author_association": "OWNER", "body": "A fundamental operation of this view is to construct the SQL query and accompanying human description based on the incoming query string parameters.\r\n\r\nThe human description is the bit at the top of https://latest.datasette.io/fixtures/searchable?_search=dog&_sort=pk&_facet=text2&text2=sara+weasel that says:\r\n\r\n> 1 row where search matches \"dog\" and text2 = \"sara weasel\" sorted by pk\r\n\r\n(Also used in the page `