Skip to content

Commit 354b6c2

Browse files
committed
Implement pagination token and page size
1 parent a158acc commit 354b6c2

File tree

2 files changed

+118
-1
lines changed

2 files changed

+118
-1
lines changed

lib/gcpspanner/missing_one_implementation_feature_list.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,24 @@ type MissingOneImplFeatureListPage struct {
4040
FeatureList []MissingOneImplFeature
4141
}
4242

43+
// missingOneImplCursor: Represents a point for resuming queries based on the
44+
// numerical offset from the start of the result set. Useful for pagination.
45+
type missingOneImplFeatureListCursor struct {
46+
Offset int `json:"offset"`
47+
}
48+
49+
// decodemissingOneImplFeatureListCursor provides a wrapper around the generic decodeCursor.
50+
func decodemissingOneImplFeatureListCursor(cursor string) (*missingOneImplFeatureListCursor, error) {
51+
return decodeCursor[missingOneImplFeatureListCursor](cursor)
52+
}
53+
54+
// encodemissingOneImplFeatureListCursor provides a wrapper around the generic encodeCursor.
55+
func encodemissingOneImplFeatureListCursor(offset int) string {
56+
return encodeCursor(missingOneImplFeatureListCursor{
57+
Offset: offset,
58+
})
59+
}
60+
4361
// MissingOneImplFeature contains information regarding the list of features implemented in all other browsers but not
4462
// in the target browser.
4563
type MissingOneImplFeature struct {
@@ -69,16 +87,23 @@ AND
6987
{{ end }}
7088
1=1
7189
ORDER BY KEY ASC
90+
LIMIT @limit
91+
{{ if .Offset }}
92+
OFFSET {{ .Offset }}
93+
{{ end }}
7294
`
7395

7496
type missingOneImplFeatureListTemplateData struct {
7597
OtherBrowsersParamNames []string
98+
Offset int
7699
}
77100

78101
func buildMissingOneImplFeatureListTemplate(
79102
targetBrowser string,
80103
otherBrowsers []string,
81104
targetDate time.Time,
105+
cursor *missingOneImplFeatureListCursor,
106+
pageSize int,
82107
) spanner.Statement {
83108
params := map[string]interface{}{}
84109
allBrowsers := make([]string, len(otherBrowsers)+1)
@@ -93,9 +118,11 @@ func buildMissingOneImplFeatureListTemplate(
93118
}
94119

95120
params["targetDate"] = targetDate
121+
params["limit"] = pageSize
96122

97123
tmplData := missingOneImplFeatureListTemplateData{
98124
OtherBrowsersParamNames: otherBrowsersParamNames,
125+
Offset: cursor.Offset,
99126
}
100127

101128
sql := missingOneImplFeatureListTemplate.Execute(tmplData)
@@ -110,14 +137,27 @@ func (c *Client) MissingOneImplFeatureList(
110137
targetBrowser string,
111138
otherBrowsers []string,
112139
targetDate time.Time,
140+
pageSize int,
141+
pageToken *string,
113142
) (*MissingOneImplFeatureListPage, error) {
143+
var cursor *missingOneImplFeatureListCursor
144+
var err error
145+
if pageToken != nil {
146+
cursor, err = decodemissingOneImplFeatureListCursor(*pageToken)
147+
if err != nil {
148+
return nil, errors.Join(ErrInternalQueryFailure, err)
149+
}
150+
}
151+
114152
txn := c.ReadOnlyTransaction()
115153
defer txn.Close()
116154

117155
stmt := buildMissingOneImplFeatureListTemplate(
118156
targetBrowser,
119157
otherBrowsers,
120158
targetDate,
159+
cursor,
160+
pageSize,
121161
)
122162

123163
it := txn.Query(ctx, stmt)
@@ -144,5 +184,14 @@ func (c *Client) MissingOneImplFeatureList(
144184
NextPageToken: nil,
145185
}
146186

187+
if len(results) == pageSize {
188+
previousOffset := 0
189+
if cursor != nil {
190+
previousOffset = cursor.Offset
191+
}
192+
token := encodemissingOneImplFeatureListCursor(previousOffset + pageSize)
193+
page.NextPageToken = &token
194+
}
195+
147196
return &page, nil
148197
}

lib/gcpspanner/missing_one_implementation_feature_list_test.go

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,14 @@ func loadDataForListMissingOneImplFeatureList(ctx context.Context, t *testing.T,
128128
}
129129

130130
func assertMissingOneImplFeatureList(ctx context.Context, t *testing.T, targetDate time.Time,
131-
targetBrowser string, otherBrowsers []string, expectedPage *MissingOneImplFeatureListPage) {
131+
targetBrowser string, otherBrowsers []string, expectedPage *MissingOneImplFeatureListPage, token *string, pageSize int) {
132132
result, err := spannerClient.MissingOneImplFeatureList(
133133
ctx,
134134
targetBrowser,
135135
otherBrowsers,
136136
targetDate,
137+
pageSize,
138+
token,
137139
)
138140
if err != nil {
139141
t.Errorf("Unexpected error: %v", err)
@@ -157,6 +159,8 @@ func testMissingOneImplFeatureListSuite(
157159
"barBrowser",
158160
}
159161
targetDate := time.Date(2024, 4, 15, 0, 0, 0, 0, time.UTC)
162+
pageSize := 25
163+
token := encodemissingOneImplFeatureListCursor(0)
160164

161165
t.Run("simple successful query", func(t *testing.T) {
162166
expectedResult := &MissingOneImplFeatureListPage{
@@ -183,6 +187,8 @@ func testMissingOneImplFeatureListSuite(
183187
targetBrowser,
184188
otherBrowsers,
185189
expectedResult,
190+
&token,
191+
pageSize,
186192
)
187193
})
188194

@@ -199,6 +205,8 @@ func testMissingOneImplFeatureListSuite(
199205
targetBrowser,
200206
otherBrowsers,
201207
expectedResult,
208+
&token,
209+
pageSize,
202210
)
203211
})
204212

@@ -231,8 +239,68 @@ func testMissingOneImplFeatureListSuite(
231239
targetBrowser,
232240
subsetBrowsers,
233241
expectedResult,
242+
&token,
243+
pageSize,
234244
)
235245
})
246+
247+
t.Run("simple successful query with pagination", func(t *testing.T) {
248+
pageToken := encodemissingOneImplFeatureListCursor(1)
249+
expectedResult := &MissingOneImplFeatureListPage{
250+
NextPageToken: nil,
251+
FeatureList: []MissingOneImplFeature{
252+
// fooBrowser 113 release
253+
// Currently supported features:
254+
// fooBrowser: FeatureX, FeatureZ, FeatureY, FeatureW
255+
// barBrowser: FeatureX, FeatureZ, FeatureY, FeatureW
256+
// bazBrowser: FeatureX, FeatureY
257+
// Missing in on for bazBrowser: FeatureW, FeatureZ
258+
{
259+
WebFeatureID: "FeatureZ",
260+
},
261+
},
262+
}
263+
assertMissingOneImplFeatureList(
264+
ctx,
265+
t,
266+
targetDate,
267+
targetBrowser,
268+
otherBrowsers,
269+
expectedResult,
270+
&pageToken,
271+
pageSize,
272+
)
273+
})
274+
275+
t.Run("Return a page token with page size 1", func(t *testing.T) {
276+
onePerPage := 1
277+
nextToken := encodemissingOneImplFeatureListCursor(1)
278+
expectedResult := &MissingOneImplFeatureListPage{
279+
NextPageToken: &nextToken,
280+
FeatureList: []MissingOneImplFeature{
281+
// fooBrowser 113 release
282+
// Currently supported features:
283+
// fooBrowser: FeatureX, FeatureZ, FeatureY, FeatureW
284+
// barBrowser: FeatureX, FeatureZ, FeatureY, FeatureW
285+
// bazBrowser: FeatureX, FeatureY
286+
// Missing in on for bazBrowser: FeatureW, FeatureZ
287+
{
288+
WebFeatureID: "FeatureW",
289+
},
290+
},
291+
}
292+
assertMissingOneImplFeatureList(
293+
ctx,
294+
t,
295+
targetDate,
296+
targetBrowser,
297+
otherBrowsers,
298+
expectedResult,
299+
&token,
300+
onePerPage,
301+
)
302+
})
303+
236304
})
237305
}
238306

0 commit comments

Comments
 (0)