diff --git a/internal/api/handlers.go b/internal/api/handlers.go index f04b684..6423cce 100644 --- a/internal/api/handlers.go +++ b/internal/api/handlers.go @@ -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, diff --git a/internal/store/repository.go b/internal/store/repository.go index d0c1a5b..c39cafe 100644 --- a/internal/store/repository.go +++ b/internal/store/repository.go @@ -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 diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go index ad9b521..7fbe392 100644 --- a/internal/store/sqlite.go +++ b/internal/store/sqlite.go @@ -1,3 +1,4 @@ +// upupa_dataist_ir/internal/store/sqlite.go package store import ( @@ -39,9 +40,9 @@ func (s *SQLiteStore) InitSchema() error { CREATE TABLE IF NOT EXISTS records ( id TEXT PRIMARY KEY, collection_id TEXT NOT NULL, - created DATETIME DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), - updated DATETIME DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), - data TEXT NOT NULL, + created DATETIME DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), + updated DATETIME DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), + data TEXT NOT NULL, FOREIGN KEY (collection_id) REFERENCES collections (id) ON DELETE CASCADE ); @@ -84,8 +85,8 @@ func (s *SQLiteStore) CreateRecord(r models.Record) (models.Record, error) { return r, err } - query := `INSERT INTO records - (id, collection_id, data) + query := `INSERT INTO records + (id, collection_id, data) VALUES (?, ?, ?)` _, err = s.db.Exec(query, r.ID, r.CollectionID, jsonData) @@ -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,15 +169,15 @@ 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) { - query := `SELECT id, collection_id, created, updated, data - FROM records + query := `SELECT id, collection_id, created, updated, data + FROM records WHERE collection_id = ? AND id = ?` row := s.db.QueryRow(query, collectionID, recordID)