html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,issue,performed_via_github_app
https://github.com/simonw/datasette/issues/1518#issuecomment-997472214,https://api.github.com/repos/simonw/datasette/issues/1518,997472214,IC_kwDOBm6k_c47dDfW,9599,2021-12-19T22:22:08Z,2021-12-19T22:22:08Z,OWNER,"I sketched out a chained SQL builder pattern that might be useful for further tidying up this code - though with the new plugin hook I'm less excited about it than I was:
```python
class TableQuery:
def __init__(self, table, columns, pks, is_view=False, prev=None):
self.table = table
self.columns = columns
self.pks = pks
self.is_view = is_view
self.prev = prev
# These can be changed for different instances in the chain:
self._where_clauses = None
self._order_by = None
self._page_size = None
self._offset = None
self._select_columns = None
self.select_all_columns = '*'
self.select_specified_columns = '*'
@property
def where_clauses(self):
wheres = []
current = self
while current:
if current._where_clauses is not None:
wheres.extend(current._where_clauses)
current = current.prev
return list(reversed(wheres))
def where(self, where):
new_cls = TableQuery(self.table, self.columns, self.pks, self.is_view, self)
new_cls._where_clauses = [where]
return new_cls
@classmethod
async def introspect(cls, db, table):
return cls(
table,
columns = await db.table_columns(table),
pks = await db.primary_keys(table),
is_view = bool(await db.get_view_definition(table))
)
@property
def sql_from(self):
return f""from {self.table}{self.sql_where}""
@property
def sql_where(self):
if not self.where_clauses:
return """"
else:
return f"" where {' and '.join(self.where_clauses)}""
@property
def sql_no_order_no_limit(self):
return f""select {self.select_all_columns} from {self.table}{self.sql_where}""
@property
def sql(self):
return f""select {self.select_specified_columns} from {self.table} {self.sql_where}{self._order_by} limit {self._page_size}{self._offset}""
@property
def sql_count(self):
return f""select count(*) {self.sql_from}""
def __repr__(self):
return f""""
```
Usage:
```python
from datasette.app import Datasette
ds = Datasette(memory=True, files=[""/Users/simon/Dropbox/Development/datasette/fixtures.db""])
db = ds.get_database(""fixtures"")
query = await TableQuery.introspect(db, ""facetable"")
print(query.where(""foo = bar"").where(""baz = 1"").sql_count)
# 'select count(*) from facetable where foo = bar and baz = 1'
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1058072543,