fix: Ensure accurate Total Count and correct Limit=0 handling
This commit finalizes the complex querying logic: - **Refactor `GetAll` (sqlite.go):** Reworks the internal logic to ensure the total number of matching records (`totalCount`) is calculated via a separate COUNT query *before* applying LIMIT/OFFSET. - **Corrected Pagination:** Adds an explicit check in `GetAll` to return an empty `items` list when `limit=0`, while still reporting the correct `totalCount`. - **API Handler Update:** Consumes the accurate `totalCount` returned by the Store layer and includes it in the final API response under the `totalItems` field.
This commit is contained in:
parent
4704d7802b
commit
07cdb55411
|
|
@ -1,3 +1,4 @@
|
|||
// upupa_dataist_ir/internal/api/handlers.go
|
||||
package api
|
||||
|
||||
import (
|
||||
|
|
@ -108,7 +109,7 @@ func (a *API) GetAllRecordsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
offset = 0
|
||||
}
|
||||
|
||||
records, err := a.Records.GetAll(collection.ID, finalFilters, orderBy, limit, offset)
|
||||
records, totalItems, err := a.Records.GetAll(collection.ID, finalFilters, orderBy, limit, offset)
|
||||
if err != nil {
|
||||
log.Printf("Error retrieving records: %v", err)
|
||||
http.Error(w, "Failed to retrieve records", http.StatusInternalServerError)
|
||||
|
|
@ -120,7 +121,7 @@ func (a *API) GetAllRecordsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
response := map[string]interface{}{
|
||||
"items": records,
|
||||
"totalItems": len(records),
|
||||
"totalItems": totalItems,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
"orderBy": orderBy,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// internal/store/repository.go
|
||||
// internal/store/repository
|
||||
package store
|
||||
|
||||
import "upupa_dataist_ir/pkg/models"
|
||||
|
|
@ -10,9 +10,7 @@ type CollectionRepository interface {
|
|||
|
||||
type RecordRepository interface {
|
||||
CreateRecord(r models.Record) (models.Record, error)
|
||||
|
||||
GetAll(collectionID string, filters map[string]interface{}, orderBy string, limit, offset int) ([]models.Record, error)
|
||||
|
||||
GetAll(collectionID string, filters map[string]interface{}, orderBy string, limit, offset int) ([]models.Record, int, error)
|
||||
GetByID(collectionID, recordID string) (models.Record, error)
|
||||
Update(r models.Record) error
|
||||
Delete(collectionID, recordID string) error
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// upupa_dataist_ir/internal/store/sqlite.go
|
||||
package store
|
||||
|
||||
import (
|
||||
|
|
@ -96,15 +97,14 @@ func (s *SQLiteStore) CreateRecord(r models.Record) (models.Record, error) {
|
|||
return s.GetByID(r.CollectionID, r.ID)
|
||||
}
|
||||
|
||||
func (s *SQLiteStore) GetAll(collectionID string, filters map[string]interface{}, orderBy string, limit, offset int) ([]models.Record, error) {
|
||||
func (s *SQLiteStore) GetAll(collectionID string, filters map[string]interface{}, orderBy string, limit, offset int) ([]models.Record, int, error) {
|
||||
|
||||
baseQuery := `SELECT id, collection_id, created, updated, data FROM records WHERE collection_id = ?`
|
||||
|
||||
args := []interface{}{collectionID}
|
||||
|
||||
filterClause := ""
|
||||
if len(filters) > 0 {
|
||||
filterClause := ""
|
||||
|
||||
for key, value := range filters {
|
||||
field, op, err := parseFilterKey(key)
|
||||
if err != nil {
|
||||
|
|
@ -117,23 +117,32 @@ func (s *SQLiteStore) GetAll(collectionID string, filters map[string]interface{}
|
|||
filterClause += fmt.Sprintf(" AND %s %s ?", caster, op)
|
||||
args = append(args, value)
|
||||
}
|
||||
|
||||
baseQuery += filterClause
|
||||
}
|
||||
|
||||
countQuery := "SELECT COUNT(*) FROM records WHERE collection_id = ?" + filterClause
|
||||
var totalCount int
|
||||
err := s.db.QueryRow(countQuery, args...).Scan(&totalCount)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if limit == 0 {
|
||||
return []models.Record{}, totalCount, nil
|
||||
}
|
||||
|
||||
baseQuery += filterClause
|
||||
|
||||
sortClause := " ORDER BY created DESC"
|
||||
if orderBy != "" {
|
||||
sortClause = buildOrderClause(orderBy)
|
||||
}
|
||||
baseQuery += sortClause
|
||||
|
||||
if limit > 0 {
|
||||
baseQuery += fmt.Sprintf(" LIMIT %d OFFSET %d", limit, offset)
|
||||
}
|
||||
baseQuery += fmt.Sprintf(" LIMIT %d OFFSET %d", limit, offset)
|
||||
|
||||
rows, err := s.db.Query(baseQuery, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
|
|
@ -147,12 +156,12 @@ func (s *SQLiteStore) GetAll(collectionID string, filters map[string]interface{}
|
|||
|
||||
err := rows.Scan(&r.ID, &r.CollectionID, &r.Created, &r.Updated, &dataStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
data, err := unmarshalRecordData(dataStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
r.Data = data
|
||||
|
|
@ -160,10 +169,10 @@ func (s *SQLiteStore) GetAll(collectionID string, filters map[string]interface{}
|
|||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return records, nil
|
||||
return records, totalCount, nil
|
||||
}
|
||||
|
||||
func (s *SQLiteStore) GetByID(collectionID, recordID string) (models.Record, error) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue