Add field for null representation output
authorKarl O. Pinc <kop@karlpinc.com>
Fri, 20 Sep 2024 18:03:04 +0000 (13:03 -0500)
committerKarl O. Pinc <kop@karlpinc.com>
Fri, 20 Sep 2024 18:03:04 +0000 (13:03 -0500)
src/pgwui_sql/templates/sql_edit.mak
src/pgwui_sql/views/base.py
src/pgwui_sql/views/sql.py
tests/templates/test_templates.py

index 7dda16bcf4b7b1c5b45b4b9624ddeca39dd020b9..145531ea42eafd62e0f794e95b1e50320e9b24a7 100644 (file)
       </tr>
 </%def>
 
+<%def name="null_rep_row(tab_index)">
+      <tr>
+        <%self.lib:td_label for_id="null_rep_id">
+          Show NULL<a
+             href="https://en.wikipedia.org/wiki/Null_(SQL)"
+             target="_blank"
+             class="help"
+          >*</a> values as:
+        </%self.lib:td_label>
+        <%self.lib:td_input tab_index="${tab_index}">
+          <input name="null_rep"
+                 tabindex="${tab_index.val}"
+                 id="null_rep_id"
+                 type="text"
+                 size="10"
+                 value="${null_rep}"
+                 />
+        </%self.lib:td_input>
+      </tr>
+</%def>
+
 <%def name="file_input_row(tab_index)">
       <tr>
         <%self.lib:td_label for_id="upload_sql_id">
 <%def name="controls(tab_index)">
   <table>
     ${self.file_input_row(tab_index)}
+    ${self.null_rep_row(tab_index)}
     ${self.download_row(tab_index)}
     ${self.download_as_row(tab_index)}
   </table>
index 9ad366bbd4d504a7f401f0ae4f188aba25d33b5d..7878ab082991d1c5a10dbb6a9d2763628c46e8e9 100644 (file)
@@ -39,6 +39,7 @@ class SQLInitialPost(pgwui_core.forms.UserInitialPost):
     sql = attrs.field(default='')
     upload_sql = attrs.field(default=False)
     sql_file = attrs.field(default=None)
+    null_rep = attrs.field(default='')
     download = attrs.field(default=False)
     download_fmt = attrs.field(default=CSV)
     download_as = attrs.field(default=ONE_FILE)
@@ -53,6 +54,13 @@ class SQLWTForm(pgwui_core.forms.AuthWTForm):
     sql = wtforms.fields.TextAreaField('SQL:', id='sql_id')
     upload_sql = wtforms.fields.BooleanField(
         'Execute SQL from a file:', id='upload_sql_id')
+    null_rep = wtforms.fields.StringField(
+        ('Show NULL<a'
+         ' href="https://en.wikipedia.org/wiki/Null_(SQL)"'
+         ' target="_blank"'
+         ' class="help"'
+         '>*</a> values as:'),
+        id='null_rep_id')
     sql_file = wtforms.fields.FileField(
         'File of SQL statements')
     download = wtforms.fields.BooleanField(
@@ -82,6 +90,7 @@ class SQLForm(pgwui_core.forms.UploadFormBaseMixin,
     sql_file = attrs.field(default=None)
     sql_file_read = attrs.field(default=False)
     filename = attrs.field(default=None)
+    null_rep = attrs.field(default='')
     download = attrs.field(default=False)
     download_fmt = attrs.field(default=None)
     download_as = attrs.field(default=None)
@@ -116,6 +125,7 @@ class SQLForm(pgwui_core.forms.UploadFormBaseMixin,
         else:
             self['sql'] = self._form.sql.data
 
+        self['null_rep'] = self._form.null_rep.data
         self['download'] = self._form.download.data
         self['download_fmt'] = self._form.download_fmt.data
         self['download_as'] = self._form.download_as.data
@@ -127,6 +137,7 @@ class SQLForm(pgwui_core.forms.UploadFormBaseMixin,
         '''
         response = super().write(result, errors)
         response['sql'] = self['sql']
+        response['null_rep'] = self['null_rep']
 
         if self['download']:
             download_checked = CHECKED
index 538dabd54ca6800ca368c062d4cb1ce37257b5bd..7e0d39851600e6f338e1cd3bb857989b3c787dd0 100644 (file)
@@ -44,6 +44,7 @@ class SQLResult():
 @attrs.define()
 class ResultRow():
     data = attrs.field(default=None)
+    null_rep = attrs.field(default='')
 
     def build_heading_row(self, cur):
         self.data = [col.name for col in cur.description]
@@ -57,8 +58,8 @@ class ResultRow():
         self.data = f'{cur.rowcount} rows affected'
         return self
 
-    def build_data_row(self, data):
-        self.data = data
+    def build_data_row(self, data, null_rep):
+        self.data = [null_rep if item is None else item for item in data]
         return self
 
 
@@ -157,10 +158,10 @@ class SQLResultsHandler(pgwui_core.core.SessionDBHandler):
                 descr=err.diag.message_primary,
                 detail=self.format_detail(err, stmt_text))
 
-    def get_result_rows(self, cur):
+    def get_result_rows(self, cur, null_rep):
         rows = []
         while (row := cur.fetchone()) is not None:
-            rows.append(ResultRow().build_data_row(row))
+            rows.append(ResultRow().build_data_row(row, null_rep))
         return rows
 
     def get_db_search_path(self):
@@ -187,6 +188,7 @@ class SQLResultsHandler(pgwui_core.core.SessionDBHandler):
         interleaving errors with output.
         '''
         cur = self.cur
+        null_rep = self.uf['null_rep']
 
         # Adjust the executed SQL to use the requested search_path
         # Change the form content so that the user sees the change
@@ -205,7 +207,7 @@ class SQLResultsHandler(pgwui_core.core.SessionDBHandler):
             sql_result = SQLResult()
             if cur.rownumber is not None:
                 sql_result.heading = ResultRow().build_heading_row(cur)
-                sql_result.rows = self.get_result_rows(cur)
+                sql_result.rows = self.get_result_rows(cur, null_rep)
             sql_result.statusmessage = ResultRow().build_statusmessage_row(cur)
             sql_result.rowcount = ResultRow().build_rowcount_row(cur)
             sql_results.append(sql_result)
index 60f8ed0d65182d583aba0236805f68d67126330f..dacf9528eff4dd42b7a59579968d598926e64161 100644 (file)
@@ -67,6 +67,7 @@ stock_template_args = {
     'one_file_checked': CHECKED,
     'many_files_checked': UNCHECKED,
     'include_sql': True,
+    'null_rep': '',
 }
 
 # The templates to test