niki/pkg/database/postgres/pagination.go

86 lines
2.2 KiB
Go

package postgres
import (
"context"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
// page number pagination
type RequestPagination struct {
PageNumber int64 `json:"page_number"`
}
type ResponsePagination struct {
PageNumber int64 `json:"page_number"`
PageSize int64 `json:"page_size"`
TotalPages int64 `json:"total_pages"`
}
type DBPagination struct {
PageNumber int64
PageSize int64
}
type ScannerFunc[T any] func(scanner Scanner) (T, error)
func PageNumberPagination[T any](ctx context.Context, countQuery string, fetchQuery string, conn *DB, countQueryStmt statementKey, fetchQueryStmt statementKey, op richerror.Op, scanner ScannerFunc[T], countParams []any, fetchParams []any) ([]T, int64, error) {
var totalCount int64
countStmt, CountStErr := conn.PrepareStatement(ctx, countQueryStmt, countQuery)
if CountStErr != nil {
return nil, 0, richerror.New(op).WithErr(CountStErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgFailedQuery)
}
countErr := countStmt.QueryRowContext(ctx, countParams...).Scan(&totalCount)
if countErr != nil {
return nil, 0, richerror.New(op).WithErr(countErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgFailedQuery)
}
//// get records
stmt, StErr := conn.PrepareStatement(ctx, fetchQueryStmt, fetchQuery)
if StErr != nil {
return nil, 0, richerror.New(op).WithErr(StErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgFailedQuery)
}
queryRows, qrErr := stmt.QueryContext(ctx, fetchParams...)
if qrErr != nil {
return nil, 0, richerror.New(op).WithErr(qrErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgFailedQuery)
}
defer queryRows.Close()
var itemsList []T
for queryRows.Next() {
item, err := scanner(queryRows)
if err != nil {
return nil, 0, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
}
itemsList = append(itemsList, item)
}
if qErr := queryRows.Err(); qErr != nil {
return nil, 0, richerror.New(op).WithErr(qErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
}
return itemsList, totalCount, nil
}