@@ -3,6 +3,8 @@ package managers
33import (
44 "context"
55 "database/sql"
6+ "fmt"
7+ "strings"
68
79 "github.com/Masterminds/squirrel"
810
@@ -79,35 +81,56 @@ func (m *baseManager) GetPageInfo(ctx context.Context, table string, page parame
7981 span .SetTag ("pageInfo.curent" , pageInfo .Current )
8082 span .SetTag ("pageInfo.itemsPerPage" , pageInfo .ItemsPerPage )
8183
82- builder := m .GetQueryBuilder ()
83-
84- err = builder .
85- Select ("COUNT(*)" ).
86- From (table ).
87- Where (scope ).
88- QueryRowContext (ctx ).
89- Scan (& pageInfo .UnfilteredItemCount )
90- if err != nil {
91- return pageInfo , err
84+ filterSQL := "1 = 1"
85+ filterArgs := []interface {}{}
86+ if filter != nil {
87+ filterSQL , filterArgs , err = filter .ToSql ()
88+ if err != nil {
89+ return pageInfo , err
90+ }
9291 }
9392
94- if filter != nil {
95- err = builder .
96- Select ("COUNT(*)" ).
97- From (table ).
98- Where (scope ).
99- Where (filter ).
100- QueryRowContext (ctx ).
101- Scan (& pageInfo .ItemCount )
93+ scopeSQL := "1 = 1"
94+ scopeArgs := []interface {}{}
95+ if scope != nil {
96+ scopeSQL , scopeArgs , err = scope .ToSql ()
10297 if err != nil {
10398 return pageInfo , err
10499 }
105- } else {
106- pageInfo .ItemCount = pageInfo .UnfilteredItemCount
100+ }
101+
102+ query := replaceQuestionMarks (fmt .Sprintf (`
103+ SELECT COUNT(*) AS unfilteredItemCount, SUM(hit) AS itemCount FROM (
104+ SELECT
105+ *,
106+ (CASE WHEN (%s) THEN 1 ELSE 0 END) AS hit
107+ FROM %s
108+ WHERE %s
109+ ) AS subquery` , filterSQL , table , scopeSQL ))
110+
111+ args := append (filterArgs , scopeArgs ... )
112+ row := m .db .QueryRowContext (ctx , query , args ... )
113+ err = row .Scan (& pageInfo .UnfilteredItemCount , & pageInfo .ItemCount )
114+ if err != nil {
115+ return pageInfo , err
107116 }
108117
109118 span .SetTag ("pageInfo.itemCount" , pageInfo .ItemCount )
110119 span .SetTag ("pageInfo.unfilteredItemCount" , pageInfo .UnfilteredItemCount )
111120
112121 return pageInfo , err
113122}
123+
124+ func replaceQuestionMarks (query string ) string {
125+ res := query
126+ i := 1
127+ for {
128+ next := strings .Replace (res , "?" , fmt .Sprintf ("$%d" , i ), 1 )
129+ if next == res {
130+ break
131+ }
132+ i ++
133+ res = next
134+ }
135+ return res
136+ }
0 commit comments