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:
parent
6109187286
commit
e2dda7ae0c
2 changed files with 22 additions and 6 deletions
|
@ -548,8 +548,7 @@ class BQLShell(bc_query_shell.BQLShell):
|
||||||
self.last_line_parsed = line
|
self.last_line_parsed = line
|
||||||
super().run_parser(line, default_close_date)
|
super().run_parser(line, default_close_date)
|
||||||
|
|
||||||
@functools.wraps(bc_query_shell.BQLShell.on_Select, ('__doc__',))
|
def _select(self, statement: QueryStatement) -> None:
|
||||||
def on_Select(self, statement: QueryStatement) -> None:
|
|
||||||
output_format: str = self.vars['format']
|
output_format: str = self.vars['format']
|
||||||
try:
|
try:
|
||||||
render_func = getattr(self, f'_render_{output_format}')
|
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)
|
logger.debug("rendering query as %s", output_format)
|
||||||
render_func(statement, row_types, rows)
|
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:
|
def _hint_TypeError(self, error: TypeError, statement: QueryStatement) -> None:
|
||||||
try:
|
try:
|
||||||
errmsg = str(error.args[0])
|
errmsg = str(error.args[0])
|
||||||
|
@ -653,7 +662,7 @@ class QueryODS(core.BaseODS[NamedTuple, None]):
|
||||||
])
|
])
|
||||||
|
|
||||||
def is_empty(self) -> bool:
|
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:
|
def section_key(self, row: NamedTuple) -> None:
|
||||||
return None
|
return None
|
||||||
|
@ -760,9 +769,12 @@ class QueryODS(core.BaseODS[NamedTuple, None]):
|
||||||
query_string: Optional[str]=None,
|
query_string: Optional[str]=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if self.is_empty():
|
if self.is_empty():
|
||||||
self.sheet.setAttribute('name', "Query 1")
|
query_count = 1
|
||||||
else:
|
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:
|
for name, row_type in row_types:
|
||||||
if issubclass(row_type, datetime.date):
|
if issubclass(row_type, datetime.date):
|
||||||
col_width = 1.0
|
col_width = 1.0
|
||||||
|
@ -785,6 +797,10 @@ class QueryODS(core.BaseODS[NamedTuple, None]):
|
||||||
cell_func(value)
|
cell_func(value)
|
||||||
for cell_func, value in zip(cell_funcs, row)
|
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):
|
class ReportFormat(enum.Enum):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[metadata]
|
[metadata]
|
||||||
name = conservancy_beancount
|
name = conservancy_beancount
|
||||||
version = 1.19.7
|
version = 1.19.8
|
||||||
author = Software Freedom Conservancy
|
author = Software Freedom Conservancy
|
||||||
author_email = info@sfconservancy.org
|
author_email = info@sfconservancy.org
|
||||||
description = Plugin, library, and reports for reading Conservancy’s books
|
description = Plugin, library, and reports for reading Conservancy’s books
|
||||||
|
|
Loading…
Reference in a new issue