]> git.openstreetmap.org Git - nominatim.git/blobdiff - nominatim/api/logging.py
implement actual database searches
[nominatim.git] / nominatim / api / logging.py
index 05598660254bd0a42fe04f66c446174e5ce4a515..fdff73beb078ad14f0e6ad6104ece434e93e387a 100644 (file)
@@ -7,7 +7,7 @@
 """
 Functions for specialised logging with HTML output.
 """
-from typing import Any, cast
+from typing import Any, Iterator, Optional, List, cast
 from contextvars import ContextVar
 import textwrap
 import io
@@ -56,6 +56,11 @@ class BaseLogger:
         """
 
 
+    def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
+        """ Print the table generated by the generator function.
+        """
+
+
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable') -> None:
         """ Print the SQL for the given statement.
         """
@@ -101,9 +106,28 @@ class HTMLLogger(BaseLogger):
 
 
     def var_dump(self, heading: str, var: Any) -> None:
+        if callable(var):
+            var = var()
+
         self._write(f'<h5>{heading}</h5>{self._python_var(var)}')
 
 
+    def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
+        head = next(rows)
+        assert head
+        self._write(f'<table><thead><tr><th colspan="{len(head)}">{heading}</th></tr><tr>')
+        for cell in head:
+            self._write(f'<th>{cell}</th>')
+        self._write('</tr></thead><tbody>')
+        for row in rows:
+            if row is not None:
+                self._write('<tr>')
+                for cell in row:
+                    self._write(f'<td>{cell}</td>')
+                self._write('</tr>')
+        self._write('</tbody></table>')
+
+
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable') -> None:
         sqlstr = self.format_sql(conn, statement)
         if CODE_HIGHLIGHT:
@@ -155,9 +179,33 @@ class TextLogger(BaseLogger):
 
 
     def var_dump(self, heading: str, var: Any) -> None:
+        if callable(var):
+            var = var()
+
         self._write(f'{heading}:\n  {self._python_var(var)}\n\n')
 
 
+    def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
+        self._write(f'{heading}:\n')
+        data = [list(map(self._python_var, row)) if row else None for row in rows]
+        assert data[0] is not None
+        num_cols = len(data[0])
+
+        maxlens = [max(len(d[i]) for d in data if d) for i in range(num_cols)]
+        tablewidth = sum(maxlens) + 3 * num_cols + 1
+        row_format = '| ' +' | '.join(f'{{:<{l}}}' for l in maxlens) + ' |\n'
+        self._write('-'*tablewidth + '\n')
+        self._write(row_format.format(*data[0]))
+        self._write('-'*tablewidth + '\n')
+        for row in data[1:]:
+            if row:
+                self._write(row_format.format(*row))
+            else:
+                self._write('-'*tablewidth + '\n')
+        if data[-1]:
+            self._write('-'*tablewidth + '\n')
+
+
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable') -> None:
         sqlstr = '\n| '.join(textwrap.wrap(self.format_sql(conn, statement), width=78))
         self._write(f"| {sqlstr}\n\n")