@@ -94,9 +94,9 @@ type KeysetPagination struct {
94
94
sqlIdName string
95
95
// name of the field in the struct that is returned from the database
96
96
idFieldName string
97
- // the last id value read and the offset in which it was read
98
- lastId string // TODO: should this be int?
99
- lastOffset int
97
+ // the first and last id values in the page
98
+ firstId string
99
+ lastId string
100
100
}
101
101
102
102
func NewKeysetPagination (offset int , pageSize int , sqlIdName string , idFieldName string ) (* KeysetPagination , error ) {
@@ -111,23 +111,34 @@ func NewKeysetPagination(offset int, pageSize int, sqlIdName string, idFieldName
111
111
pageSize : pageSize ,
112
112
sqlIdName : sqlIdName ,
113
113
idFieldName : idFieldName ,
114
+ firstId : "" ,
114
115
lastId : "" ,
115
- lastOffset : - 1 ,
116
116
}, nil
117
117
}
118
118
119
119
func (p * KeysetPagination ) GoToOffset (offset int ) (driver.Pagination , error ) {
120
120
if offset < 0 {
121
121
return NewEmptyPagination (), nil
122
122
}
123
- return & KeysetPagination {
124
- offset : offset ,
125
- pageSize : p .pageSize ,
126
- sqlIdName : p .sqlIdName ,
127
- idFieldName : p .idFieldName ,
128
- lastId : p .lastId ,
129
- lastOffset : p .lastOffset ,
130
- }, nil
123
+ if offset == p .offset + p .pageSize {
124
+ return & KeysetPagination {
125
+ offset : offset ,
126
+ pageSize : p .pageSize ,
127
+ sqlIdName : p .sqlIdName ,
128
+ idFieldName : p .idFieldName ,
129
+ firstId : p .lastId ,
130
+ lastId : "" ,
131
+ }, nil
132
+ } else {
133
+ return & KeysetPagination {
134
+ offset : offset ,
135
+ pageSize : p .pageSize ,
136
+ sqlIdName : p .sqlIdName ,
137
+ idFieldName : p .idFieldName ,
138
+ firstId : "" ,
139
+ lastId : "" ,
140
+ }, nil
141
+ }
131
142
}
132
143
133
144
func (p * KeysetPagination ) GoToPage (pageNum int ) (driver.Pagination , error ) {
@@ -146,7 +157,6 @@ func (p *KeysetPagination) Prev() (driver.Pagination, error) { return p.GoBack(1
146
157
func (p * KeysetPagination ) Next () (driver.Pagination , error ) { return p .GoForward (1 ) }
147
158
func (p * KeysetPagination ) UpdateId (id string ) {
148
159
p .lastId = id
149
- p .lastOffset = p .offset
150
160
}
151
161
152
162
func NewPaginationInterpreter () * paginationInterpreter {
@@ -164,22 +174,22 @@ func (i *paginationInterpreter) Interpret(p driver.Pagination, sql driver.SqlQue
164
174
case * NoPagination :
165
175
return sql , nil
166
176
case * OffsetPagination :
167
- sql .SetLimit (fmt . Sprintf ( "%d" , pagination .pageSize ) )
168
- sql .SetOffset (fmt . Sprintf ( "%d" , pagination .offset ) )
177
+ sql .SetLimit (pagination .pageSize )
178
+ sql .SetOffset (pagination .offset )
169
179
return sql , nil
170
180
case * KeysetPagination :
171
181
sql .SetOrder (fmt .Sprintf ("%s ASC" , pagination .sqlIdName ))
172
- sql .SetLimit (fmt . Sprintf ( "%d" , pagination .pageSize ) )
173
- if ( pagination .lastOffset != - 1 ) && ( pagination . offset == pagination . lastOffset + pagination . pageSize ) {
174
- lastId := sql .AddParam (pagination .lastId )
182
+ sql .SetLimit (pagination .pageSize )
183
+ if pagination .firstId != "" {
184
+ lastId := sql .AddParam (pagination .firstId )
175
185
sql .AddWhere (fmt .Sprintf ("%s>$%d" , pagination .sqlIdName , lastId ))
176
186
} else {
177
- sql .SetOffset (fmt . Sprintf ( "%d" , pagination .offset ) )
187
+ sql .SetOffset (pagination .offset )
178
188
}
179
189
return sql , nil
180
190
case * EmptyPagination :
181
- sql .SetLimit ("0" )
182
- sql .SetOffset ("0" )
191
+ sql .SetLimit (0 )
192
+ sql .SetOffset (0 )
183
193
return sql , nil
184
194
default :
185
195
return sql , errors .Errorf ("invalid pagination option %+v" , pagination )
@@ -196,21 +206,21 @@ func NewPaginationUpdater[R comparable]() *paginationUpdater[R] {
196
206
return & paginationUpdater [R ]{}
197
207
}
198
208
199
- func (i * paginationUpdater [R ]) Update (recs * driver.PageIterator [* R ]) (* driver.PageIterator [* R ], error ) {
209
+ func (i * paginationUpdater [R ]) Update (recs driver.PageIterator [* R ]) (driver.PageIterator [* R ], error ) {
200
210
switch page := recs .Pagination .(type ) {
201
211
case * KeysetPagination :
202
212
items := recs .Items
203
213
record , newIt , err := collections .ReadLast (items )
204
214
if err != nil {
205
- return nil , err
215
+ return recs , err
206
216
}
207
217
if record != nil {
208
218
refRec := reflect .ValueOf (* record )
209
219
id := refRec .FieldByName (page .idFieldName )
210
220
page .UpdateId (id .String ())
211
221
}
212
- return (& driver.PageIterator [* R ]{Items : newIt , Pagination : page }), nil
222
+ return (driver.PageIterator [* R ]{Items : newIt , Pagination : page }), nil
213
223
default :
214
- return (& driver.PageIterator [* R ]{Items : recs .Items , Pagination : recs .Pagination }), nil
224
+ return (driver.PageIterator [* R ]{Items : recs .Items , Pagination : recs .Pagination }), nil
215
225
}
216
226
}
0 commit comments