Updating query mechanism for receipts

This commit is contained in:
Ethan Wellenreiter 2025-08-09 16:34:11 -04:00
parent 7effe9daa4
commit 16d783b1c8
4 changed files with 49 additions and 35 deletions

View File

@ -4,14 +4,11 @@ import (
"context"
"net/http"
l_context "git.ewellenr.ca/receipt_indexer/backend/internal/context"
"git.ewellenr.ca/receipt_indexer/backend/internal/storage"
"git.ewellenr.ca/receipt_indexer/backend/internal/storage/cache"
)
type receiptKey string
const receiptCtx receiptKey = "receipt"
type receiptsQuery struct {
Length int `json:"length"`
List []*storage.Receipt `json:"list"`
@ -20,7 +17,7 @@ type receiptsQuery struct {
func (app *application) getReceiptsHandler(w http.ResponseWriter, r *http.Request) {
// get the page and size from context
// default them to something
receipts, err := app.store.Receipts.GetForUser(r.Context(), getUserFromContext(r).ID)
receipts, err := app.getReceipts(r.Context(), getUserFromContext(r).ID)
if err != nil {
app.internalServerError(w, r, err)
return
@ -32,13 +29,13 @@ func (app *application) getReceiptsHandler(w http.ResponseWriter, r *http.Reques
}
func (app *application) getReceiptHandler(w http.ResponseWriter, r *http.Request) {
receipt, err := app.store.Receipts.GetByID(r.Context())
receipt, err := app.getReceipt(r.Context(), getReceiptFromContext(r).ID)
if err != nil {
app.internalServerError(w, r, err)
return
}
if err := app.jsonResponse(w, http.StatusOK, &receiptsQuery{Length: len(receipts), List: receipts}); err != nil {
if err := app.jsonResponse(w, http.StatusOK, receipt); err != nil {
app.internalServerError(w, r, err)
}
}
@ -91,32 +88,46 @@ func (app *application) getReceipts(ctx context.Context, userID int64) ([]*stora
return app.store.Receipts.GetForUser(ctx, userID)
}
var queryID int64 = 0 //encode it here
// encode the query into a string so that it's "indexable"
queryID, err := storage.EncodeReceiptQuery(ctx, userID)
receiptIDs, err := app.cacheStorage.ReceiptList.Get(ctx, queryID)
if err != nil {
return nil, err
}
var receipts []*storage.Receipt = nil
if receiptIDs == nil {
receipts, err := app.store.Receipts.GetForUser(ctx, userID)
if err != nil {
return nil, err
}
receiptIDs = []int64{}
for _, val := range receipts {
receiptIDs = append(receiptIDs, val.ID)
}
if err := app.cacheStorage.ReceiptList.Set(ctx, cache.ReceiptListKeyVal{ID: queryID, List: receiptIDs}); err != nil {
if err := app.cacheStorage.ReceiptList.Set(ctx, cache.ReceiptListKeyVal{UserID: userID, QueryEncoding: queryID, List: receiptIDs}); err != nil {
return nil, err
}
} else {
for _, id := range receiptIDs {
temp_receipt, err := app.getReceipt(ctx, id)
if err != nil {
return nil, err
}
receipts = append(receipts, temp_receipt)
}
}
return receipt, nil
return receipts, nil
}
func getReceiptFromContext(r *http.Request) *storage.Receipt {
receipt, _ := r.Context().Value(receiptCtx).(*storage.Receipt)
receipt, _ := r.Context().Value(l_context.ReceiptCtx).(*storage.Receipt)
return receipt
}

View File

@ -2,20 +2,22 @@ package context
import "net/http"
type pageKey string
type (
pageKey string
pagesizeKey string
queryParamsKey string
receiptKey string
)
const PageCtx pageKey = "page"
type pagesizeKey string
const PagesizeCtx pagesizeKey = "pageSize"
type queryParamsKey string
const QueryParamsCtx queryParamsKey = "queryParams"
const (
PageCtx pageKey = "page"
PagesizeCtx pagesizeKey = "pageSize"
QueryParamsCtx queryParamsKey = "queryParams"
ReceiptCtx receiptKey = "receipt"
)
func getPageAndSizeFromContext(r *http.Request) (int, int) {
pageNumber, _ := r.Context().Value(pageCtx).(int)
pageSize, _ := r.Context().Value(pagesizeCtx).(int)
pageNumber, _ := r.Context().Value(PageCtx).(int)
pageSize, _ := r.Context().Value(PagesizeCtx).(int)
return pageNumber, pageSize
}

View File

@ -45,9 +45,9 @@ type Storage struct {
Delete(ctx context.Context, id int64)
}
ReceiptList interface {
Get(ctx context.Context, id int64) ([]int64, error)
Get(ctx context.Context, queryencoding string) ([]int64, error)
Set(ctx context.Context, receiptidList ReceiptListKeyVal) error
Delete(ctx context.Context, id int64)
Delete(ctx context.Context, queryencoding string)
}
ReceiptImage interface {
Get(ctx context.Context, id int64) (*storage.Image, error)

View File

@ -9,20 +9,21 @@ import (
)
type ReceiptListKeyVal struct {
ID int64 `json:"id"`
List []int64 `json:"list"`
UserID int64 `json:"user_id"`
QueryEncoding string `json:"query_encoding"`
List []int64 `json:"list"`
}
type ReceiptListStore struct {
rdb *redis.Client
}
func (s *ReceiptListStore) generateCacheKey(id int64) string {
return fmt.Sprintf("receiptList-%d", id)
func (s *ReceiptListStore) generateCacheKey(encoding string) string {
return fmt.Sprintf("receiptList-%s", encoding)
}
func (s *ReceiptListStore) Get(ctx context.Context, id int64) ([]int64, error) {
cacheKey := s.generateCacheKey(id)
func (s *ReceiptListStore) Get(ctx context.Context, queryencoding string) ([]int64, error) {
cacheKey := s.generateCacheKey(queryencoding)
data, err := s.rdb.Get(ctx, cacheKey).Result()
if err == redis.Nil {
@ -43,7 +44,7 @@ func (s *ReceiptListStore) Get(ctx context.Context, id int64) ([]int64, error) {
}
func (s *ReceiptListStore) Set(ctx context.Context, receiptidList ReceiptListKeyVal) error {
cacheKey := s.generateCacheKey(receiptidList.ID)
cacheKey := s.generateCacheKey(receiptidList.QueryEncoding)
json, err := json.Marshal(receiptidList)
if err != nil {
@ -53,7 +54,7 @@ func (s *ReceiptListStore) Set(ctx context.Context, receiptidList ReceiptListKey
return s.rdb.Set(ctx, cacheKey, json, ReceiptsQueryExpTime).Err()
}
func (s *ReceiptListStore) Delete(ctx context.Context, id int64) {
cacheKey := s.generateCacheKey(id)
func (s *ReceiptListStore) Delete(ctx context.Context, queryencoding string) {
cacheKey := s.generateCacheKey(queryencoding)
s.rdb.Del(ctx, cacheKey)
}