feat: Filters for datasets enpoint

This commit is contained in:
2026-07-01 00:28:07 +05:00
parent 27a8d8b4f5
commit 8d9e11db0c
6 changed files with 136 additions and 40 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
"gis/internal/domain"
@@ -302,23 +303,42 @@ func scanDatasetSummary(row pgx.Row) (domain.DatasetSummary, error) {
return d, err
}
// ListSummaries returns a page of dataset summaries ordered by creation time
// (newest first). When categoryID is non-nil it filters to that category.
func (r *DatasetRepository) ListSummaries(ctx context.Context, categoryID *uuid.UUID, limit, offset int) ([]domain.DatasetSummary, error) {
base := `SELECT ` + datasetSummaryColumns + ` FROM datasets`
var (
rows pgx.Rows
err error
)
if categoryID != nil {
rows, err = r.pool.Query(ctx,
base+` WHERE category_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`,
*categoryID, limit, offset)
} else {
rows, err = r.pool.Query(ctx,
base+` ORDER BY created_at DESC LIMIT $1 OFFSET $2`, limit, offset)
// datasetFilterClause builds the WHERE fragment for the given filter, appending
// its values to args. It returns a fragment beginning with " WHERE " when any
// condition applies, or the empty string when the filter is empty.
func datasetFilterClause(f domain.DatasetFilter, args []any) (string, []any) {
var conds []string
if f.CategoryID != nil {
args = append(args, *f.CategoryID)
conds = append(conds, fmt.Sprintf("category_id = $%d", len(args)))
}
if f.FileType != nil {
args = append(args, *f.FileType)
conds = append(conds, fmt.Sprintf("file_type = $%d", len(args)))
}
if f.Automated != nil {
args = append(args, *f.Automated)
conds = append(conds, fmt.Sprintf("automated = $%d", len(args)))
}
if f.Status != nil {
args = append(args, *f.Status)
conds = append(conds, fmt.Sprintf("status = $%d", len(args)))
}
if len(conds) == 0 {
return "", args
}
return " WHERE " + strings.Join(conds, " AND "), args
}
// ListSummaries returns a page of dataset summaries ordered by creation time
// (newest first), constrained by the given filter.
func (r *DatasetRepository) ListSummaries(ctx context.Context, filter domain.DatasetFilter, limit, offset int) ([]domain.DatasetSummary, error) {
where, args := datasetFilterClause(filter, nil)
args = append(args, limit, offset)
query := fmt.Sprintf(`SELECT %s FROM datasets%s ORDER BY created_at DESC LIMIT $%d OFFSET $%d`,
datasetSummaryColumns, where, len(args)-1, len(args))
rows, err := r.pool.Query(ctx, query, args...)
if err != nil {
return nil, mapError(err)
}
@@ -335,15 +355,11 @@ func (r *DatasetRepository) ListSummaries(ctx context.Context, categoryID *uuid.
return summaries, mapError(rows.Err())
}
// Count returns the number of datasets, optionally filtered to a category.
func (r *DatasetRepository) Count(ctx context.Context, categoryID *uuid.UUID) (int, error) {
// Count returns the number of datasets matching the given filter.
func (r *DatasetRepository) Count(ctx context.Context, filter domain.DatasetFilter) (int, error) {
where, args := datasetFilterClause(filter, nil)
var n int
var err error
if categoryID != nil {
err = r.pool.QueryRow(ctx, `SELECT count(*) FROM datasets WHERE category_id = $1`, *categoryID).Scan(&n)
} else {
err = r.pool.QueryRow(ctx, `SELECT count(*) FROM datasets`).Scan(&n)
}
err := r.pool.QueryRow(ctx, `SELECT count(*) FROM datasets`+where, args...).Scan(&n)
return n, mapError(err)
}