From f31b7381aaa3d89172a30597a4f9455b802a400d Mon Sep 17 00:00:00 2001
From: Tomas Kopecek <tkopecek@redhat.com>
Date: May 04 2021 07:37:52 +0000
Subject: [PATCH 1/2] web: don't use count(*) on first tasks page


Fixes: https://pagure.io/koji/issue/2482

---

diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py
index 0aac456..cf68d17 100644
--- a/www/kojiweb/index.py
+++ b/www/kojiweb/index.py
@@ -612,7 +612,8 @@ def tasks(environ, owner=None, state='active', view='tree', method='all', hostID
     values['order'] = order
 
     tasks = kojiweb.util.paginateMethod(server, values, 'listTasks', kw={'opts': opts},
-                                        start=start, dataName='tasks', prefix='task', order=order)
+                                        start=start, dataName='tasks', prefix='task',
+                                        order=order, first_page_count=False)
 
     if view == 'tree':
         server.multicall = True
diff --git a/www/kojiweb/tasks.chtml b/www/kojiweb/tasks.chtml
index 842d617..8f26373 100644
--- a/www/kojiweb/tasks.chtml
+++ b/www/kojiweb/tasks.chtml
@@ -105,6 +105,7 @@ All
     </tr>
     <tr>
       <td class="paginate" colspan="6">
+        #if $taskPages is not None
         #if $len($taskPages) > 1
         <form class="pageJump" action="">
           Page:
@@ -124,6 +125,9 @@ All
         #if $taskStart + $taskCount < $totalTasks
         <a href="tasks?start=#echo $taskStart + $taskRange#$util.passthrough_except($self)">&gt;&gt;&gt;</a>
         #end if
+        #else
+        <a href="tasks?start=$taskRange$util.passthrough_except($self)">&gt;&gt;&gt;</a>
+        #end if
       </td>
     </tr>
     <tr class="list-header">
@@ -164,6 +168,7 @@ All
     #end if
     <tr>
       <td class="paginate" colspan="6">
+        #if $taskPages is not None
         #if $len($taskPages) > 1
         <form class="pageJump" action="">
           Page:
@@ -183,6 +188,9 @@ All
         #if $taskStart + $taskCount < $totalTasks
         <a href="tasks?start=#echo $taskStart + $taskRange#$util.passthrough_except($self)">&gt;&gt;&gt;</a>
         #end if
+        #else
+        <a href="tasks?start=$taskRange$util.passthrough_except($self)">&gt;&gt;&gt;</a>
+        #end if
       </td>
     </tr>
   </table>
diff --git a/www/lib/kojiweb/util.py b/www/lib/kojiweb/util.py
index 7bc4dca..a71797e 100644
--- a/www/lib/kojiweb/util.py
+++ b/www/lib/kojiweb/util.py
@@ -303,10 +303,15 @@ def paginateList(values, data, start, dataName, prefix=None, order=None, noneGre
 
 
 def paginateMethod(server, values, methodName, args=None, kw=None,
-                   start=None, dataName=None, prefix=None, order=None, pageSize=50):
+                   start=None, dataName=None, prefix=None, order=None, pageSize=50,
+                   first_page_count=True):
     """Paginate the results of the method with the given name when called with the given args and
     kws. The method must support the queryOpts keyword parameter, and pagination is done in the
-    database."""
+    database.
+
+    :param bool first_page_count: If set to False, count is not returned for first page
+                                  to speedup default page.
+    """
     if args is None:
         args = []
     if kw is None:
@@ -320,8 +325,11 @@ def paginateMethod(server, values, methodName, args=None, kw=None,
     if not RE_ORDER.match(order):
         raise ValueError("Ordering is not alphanumeric: %r" % order)
 
-    kw['queryOpts'] = {'countOnly': True}
-    totalRows = getattr(server, methodName)(*args, **kw)
+    if start == 0 and not first_page_count:
+        totalRows = None
+    else:
+        kw['queryOpts'] = {'countOnly': True}
+        totalRows = getattr(server, methodName)(*args, **kw)
 
     kw['queryOpts'] = {'order': order,
                        'offset': start,
@@ -329,6 +337,10 @@ def paginateMethod(server, values, methodName, args=None, kw=None,
     data = getattr(server, methodName)(*args, **kw)
     count = len(data)
 
+    if start == 0 and count < pageSize:
+        # we've got everything on the first page
+        totalRows = count
+
     _populateValues(values, dataName, prefix, data, totalRows, start, count, pageSize, order)
 
     return data
@@ -370,7 +382,6 @@ def _populateValues(values, dataName, prefix, data, totalRows, start, count, pag
     values[dataName] = data
     # Don't use capitalize() to title() here, they mess up
     # mixed-case name
-    values['total' + dataName[0].upper() + dataName[1:]] = totalRows
     # Possibly prepend a prefix to the numeric parameters, to avoid namespace collisions
     # when there is more than one list on the same page
     values[(prefix and prefix + 'Start' or 'start')] = start
@@ -379,12 +390,16 @@ def _populateValues(values, dataName, prefix, data, totalRows, start, count, pag
     values[(prefix and prefix + 'Order' or 'order')] = order
     currentPage = start // pageSize
     values[(prefix and prefix + 'CurrentPage' or 'currentPage')] = currentPage
-    totalPages = int(totalRows // pageSize)
-    if totalRows % pageSize > 0:
-        totalPages += 1
-    pages = [page for page in range(0, totalPages)
-             if (abs(page - currentPage) < 100 or ((page + 1) % 100 == 0))]
-    values[(prefix and prefix + 'Pages') or 'pages'] = pages
+    values['total' + dataName[0].upper() + dataName[1:]] = totalRows
+    if totalRows is not None:
+        totalPages = int(totalRows // pageSize)
+        if totalRows % pageSize > 0:
+            totalPages += 1
+        pages = [page for page in range(0, totalPages)
+                 if (abs(page - currentPage) < 100 or ((page + 1) % 100 == 0))]
+        values[(prefix and prefix + 'Pages') or 'pages'] = pages
+    else:
+        values[(prefix and prefix + 'Pages') or 'pages'] = None
 
 
 def stateName(stateID):

From d968caf75bf2f4cfd95b300a6fc0c51bc73aeaef Mon Sep 17 00:00:00 2001
From: Tomas Kopecek <tkopecek@redhat.com>
Date: May 04 2021 07:43:35 +0000
Subject: [PATCH 2/2] better label


---

diff --git a/www/kojiweb/tasks.chtml b/www/kojiweb/tasks.chtml
index 8f26373..ea9c645 100644
--- a/www/kojiweb/tasks.chtml
+++ b/www/kojiweb/tasks.chtml
@@ -126,6 +126,7 @@ All
         <a href="tasks?start=#echo $taskStart + $taskRange#$util.passthrough_except($self)">&gt;&gt;&gt;</a>
         #end if
         #else
+        <strong>Tasks #echo $taskStart + 1 # through #echo $taskStart + $taskCount#</strong>
         <a href="tasks?start=$taskRange$util.passthrough_except($self)">&gt;&gt;&gt;</a>
         #end if
       </td>
@@ -189,6 +190,7 @@ All
         <a href="tasks?start=#echo $taskStart + $taskRange#$util.passthrough_except($self)">&gt;&gt;&gt;</a>
         #end if
         #else
+        <strong>Tasks #echo $taskStart + 1 # through #echo $taskStart + $taskCount#</strong>
         <a href="tasks?start=$taskRange$util.passthrough_except($self)">&gt;&gt;&gt;</a>
         #end if
       </td>

