query: Let the user interrupt interactive queries.

This makes it easier to iterate on a query because you don't have to restart
the program and reload the books if something goes sideways.
This commit is contained in:
Brett Smith 2021-04-01 09:57:42 -04:00
parent 6109187286
commit e2dda7ae0c
2 changed files with 22 additions and 6 deletions

View file

@ -548,8 +548,7 @@ class BQLShell(bc_query_shell.BQLShell):
self.last_line_parsed = line
super().run_parser(line, default_close_date)
@functools.wraps(bc_query_shell.BQLShell.on_Select, ('__doc__',))
def on_Select(self, statement: QueryStatement) -> None:
def _select(self, statement: QueryStatement) -> None:
output_format: str = self.vars['format']
try:
render_func = getattr(self, f'_render_{output_format}')
@ -587,6 +586,16 @@ class BQLShell(bc_query_shell.BQLShell):
logger.debug("rendering query as %s", output_format)
render_func(statement, row_types, rows)
@functools.wraps(bc_query_shell.BQLShell.on_Select, ('__doc__',))
def on_Select(self, statement: QueryStatement) -> None:
try:
self._select(statement)
except KeyboardInterrupt:
if self.is_interactive:
logger.info("interrupted")
else:
raise
def _hint_TypeError(self, error: TypeError, statement: QueryStatement) -> None:
try:
errmsg = str(error.args[0])
@ -653,7 +662,7 @@ class QueryODS(core.BaseODS[NamedTuple, None]):
])
def is_empty(self) -> bool:
return not self.sheet.childNodes
return not self.document.spreadsheet.firstChild.getAttribute('name').startswith('Query ')
def section_key(self, row: NamedTuple) -> None:
return None
@ -760,9 +769,12 @@ class QueryODS(core.BaseODS[NamedTuple, None]):
query_string: Optional[str]=None,
) -> None:
if self.is_empty():
self.sheet.setAttribute('name', "Query 1")
query_count = 1
else:
self.use_sheet(f"Query {len(self.document.spreadsheet.childNodes) + 1}")
query_count = len(self.document.spreadsheet.childNodes) + 1
# We avoid using self.use_sheet() because fully building the sheet
# before adding it to the doc makes the query safer to interrupt.
self.sheet = odf.table.Table(name=f"Query {query_count}")
for name, row_type in row_types:
if issubclass(row_type, datetime.date):
col_width = 1.0
@ -785,6 +797,10 @@ class QueryODS(core.BaseODS[NamedTuple, None]):
cell_func(value)
for cell_func, value in zip(cell_funcs, row)
))
if query_count == 1:
self.document.spreadsheet.childNodes[-1] = self.sheet
else:
self.document.spreadsheet.appendChild(self.sheet)
class ReportFormat(enum.Enum):

View file

@ -1,6 +1,6 @@
[metadata]
name = conservancy_beancount
version = 1.19.7
version = 1.19.8
author = Software Freedom Conservancy
author_email = info@sfconservancy.org
description = Plugin, library, and reports for reading Conservancys books