Refactor SQL query result into its own object
authorKarl O. Pinc <kop@karlpinc.com>
Mon, 19 Aug 2024 17:16:43 +0000 (12:16 -0500)
committerKarl O. Pinc <kop@karlpinc.com>
Mon, 19 Aug 2024 17:16:43 +0000 (12:16 -0500)
src/pgwui_sql/templates/sql.mak
src/pgwui_sql/views/sql.py

index 5859f373aaac59855777487761d53e407a5594a6..b63ba179e556b1ca34bda48e224bbd8a3b558e60 100644 (file)
   </tr>
 </%def>
 
-<%def name="result_table(rows=[], status=[])" filter="trim">
-  ## Passing the result rows and processing them here avoids duplicating
-  ## the results in RAM.
-  <table>
-    ${caller.body()}
-    <tbody>
-      % for row in rows:
-          ${self.render_row(row.data)}
-      % endfor
-    </tbody>
-  </table>
-  <p>
-    % for status_row in status:
-      % if not loop.first:
-          <br>
-      % endif
-      ${status_row.data}
-    % endfor
-  </p>
-</%def>
-
 <%def name="sql_error()">
   <p>${caller.body()}</p>  
 </%def>
   command_result = []
   status_result = []
   %>
-  <hr>
   % for result_row in result_rows:
-      <% type = result_row.type %>
-      % if type == 'data':
-          <% command_result.append(result_row) %>
-      % elif type == 'status':
-          <% status_result.append(result_row) %>
-      % else:
-        % if new_result:
-          <%self:result_table
-                 rows="${command_result}" status="${status_result}">
-            ${self.render_heading(new_result.data)}
-          </%self:result_table>
-          <hr>
-          <%
-          command_result = []
-          status_result = []
-          %>
-        % endif
-        % if type == 'new_result':
-            <% new_result = result_row %>
-        % elif type == 'error':
-          <%self:sql_error>
-            ${result_row.data}
-          </%self:sql_error>
-        % endif
+      <hr>
+      % if result_row.statusmessage is not None:
+          <p>${result_row.statusmessage.data.split(' ')[0]}</p>
       % endif
-  % endfor
 
-  <%self:result_table
-         rows="${command_result}" status="${status_result}">
-    ${self.render_heading(new_result.data)}
-  </%self:result_table>
+      % if result_row.rows:
+          <table>
+            % if result_row.heading is not None:
+                ${self.render_heading(result_row.heading.data)}
+            % endif
+            <tbody>
+              % for row in result_row.rows:
+                  ${self.render_row(row.data)}
+              % endfor
+            </tbody>
+          </table>
+      % endif
+
+      <p>${result_row.rowcount.data}</p>
+  % endfor
   <hr>
 </%def>
 
index 59884ba0a4f0b2ed8ee0f36bbe6da4d70bf78373..2c29db8689aa1b044ed6e6472b743b4d6abff54a 100644 (file)
@@ -81,28 +81,29 @@ class SQLForm(pgwui_core.forms.UploadFormBaseMixin,
 
 @attrs.define()
 class SQLResult():
+    rows = attrs.field(factory=list)
+    statusmessage = attrs.field(default=None)
+    rowcount = attrs.field(default=None)
+    heading = attrs.field(default=None)
+
+
+@attrs.define()
+class ResultRow():
     data = attrs.field(default=None)
-    type = attrs.field(default=None)
 
-    def build_new_result_row(self, cur, have_rows):
-        self.type = 'new_result'
-        if have_rows:
-            # The data contains the column headings
-            self.data = [col.name for col in cur.description]
+    def build_heading_row(self, cur):
+        self.data = [col.name for col in cur.description]
         return self
 
     def build_statusmessage_row(self, cur):
-        self.type = 'status'
         self.data = cur.statusmessage
         return self
 
     def build_rowcount_row(self, cur):
-        self.type = 'status'
         self.data = f'{cur.rowcount} rows affected'
         return self
 
     def build_data_row(self, data):
-        self.type = 'data'
         self.data = data
         return self
 
@@ -178,13 +179,11 @@ class SQLHandler(pgwui_core.core.SessionDBHandler):
                                   descr=err.diag.message_primary,
                                   detail=self.format_detail(err, stmt_text))
 
-    def get_result_rows(self, cur, sql_results):
-        first = True
+    def get_result_rows(self, cur):
+        rows = []
         while (row := cur.fetchone()) is not None:
-            if first:
-                sql_results.append(SQLResult().build_new_result_row(cur, True))
-                first = False
-            sql_results.append(SQLResult().build_data_row(row))
+            rows.append(ResultRow().build_data_row(row))
+        return rows
 
     def cleanup(self):
         '''
@@ -198,14 +197,13 @@ class SQLHandler(pgwui_core.core.SessionDBHandler):
         sql_results = self.sql_results
         nextset = True
         while nextset is True:
-            have_rows = cur.rownumber is not None
-            if have_rows:
-                self.get_result_rows(cur, sql_results)
-            else:
-                sql_results.append(SQLResult().build_new_result_row(
-                    cur, have_rows))
-            sql_results.append(SQLResult().build_statusmessage_row(cur))
-            sql_results.append(SQLResult().build_rowcount_row(cur))
+            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.statusmessage = ResultRow().build_statusmessage_row(cur)
+            sql_result.rowcount = ResultRow().build_rowcount_row(cur)
+            sql_results.append(sql_result)
             nextset = cur.nextset()
 
     def factory(self, ue):