Skip to content

Commit

Permalink
fix: correct count query logic in ListNotifications
Browse files Browse the repository at this point in the history
  • Loading branch information
endyApina committed Oct 14, 2024
1 parent 9b39f37 commit 30f889e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 11 deletions.
20 changes: 13 additions & 7 deletions pkg/repository/notificationrepository/notificationRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,33 @@ func NewNotificationRepository(db *sqlx.DB) (port.NotificationRepository, error)
}

func (r *NotificationRepository) ListNotifications(ctx context.Context, resultSelector query.ResultSelector) (notifications []models.Notification, totalResults uint64, err error) {
var rows []notificationRow
var (
notificationRows []notificationRow
notificationFieldMappings = notificationFieldMapping()
)

queryString, args, err := repository.BuildQuery(resultSelector, unfilteredListNotificationsQuery, notificationFieldMapping())
listQuery, queryParams, err := repository.BuildQuery(resultSelector, unfilteredListNotificationsQuery, notificationFieldMappings)
if err != nil {
return nil, 0, err
}
queryString = r.client.Rebind(queryString)
err = r.client.SelectContext(ctx, &rows, queryString, args...)
err = r.client.SelectContext(ctx, &notificationRows, r.client.Rebind(listQuery), queryParams...)
if err != nil {
err = fmt.Errorf("error getting notifications from database: %w", err)
return
}

err = r.client.QueryRowxContext(ctx, `SELECT count(*) FROM `+notificationsTable).Scan(&totalResults)
countQuery, queryParams, err := repository.BuildCountQuery(resultSelector.Filter, unfilteredCountNotificationsQuery, notificationFieldMappings)
if err != nil {
return nil, 0, err
}
err = r.client.QueryRowxContext(ctx, r.client.Rebind(countQuery), queryParams...).Scan(&totalResults)
if err != nil {
err = fmt.Errorf("error getting total results: %w", err)
return
}

notifications = make([]models.Notification, 0, len(rows))
for _, row := range rows {
notifications = make([]models.Notification, 0, len(notificationRows))
for _, row := range notificationRows {
notification, err := row.ToNotificationModel()
if err != nil {
return nil, 0, fmt.Errorf("failed to transform notification db entry: %w", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const notificationsTable = "notification_service.notifications"

const createNotificationQuery = `INSERT INTO ` + notificationsTable + ` (origin, origin_uri, timestamp, title, detail, level, custom_fields) VALUES (:origin, :origin_uri, :timestamp, :title, :detail, :level, :custom_fields) RETURNING *`
const unfilteredListNotificationsQuery = `SELECT * FROM ` + notificationsTable
const unfilteredCountNotificationsQuery = `SELECT COUNT(*) FROM ` + notificationsTable

type notificationRow struct {
Id string `db:"id"`
Expand Down
27 changes: 23 additions & 4 deletions pkg/repository/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,39 @@ import (
"fmt"
pgQuery "github.com/greenbone/opensight-golang-libraries/pkg/postgres/query"
"github.com/greenbone/opensight-golang-libraries/pkg/query"
"github.com/greenbone/opensight-golang-libraries/pkg/query/filter"
)

func BuildQuery(resultSelector query.ResultSelector, baseQuery string, fieldMapping map[string]string) (string, []any, error) {
// helper function to build the query condition
func buildQueryCondition(resultSelector query.ResultSelector, baseQuery string, fieldMapping map[string]string) (string, []any, error) {
querySettings := &pgQuery.Settings{
FilterFieldMapping: fieldMapping,
}

qb := pgQuery.NewPostgresQueryBuilder(querySettings)
queryCondition, arg, err := qb.Build(resultSelector)
queryCondition, args, err := qb.Build(resultSelector)
if err != nil {
return "", nil, fmt.Errorf("error building query condition: %w", err)
}

listQuery := baseQuery + ` ` + queryCondition
fullQuery := baseQuery + ` ` + queryCondition
return fullQuery, args, nil
}

// BuildQuery builds a query for retrieving results based on the provided result selector
func BuildQuery(resultSelector query.ResultSelector, baseQuery string, fieldMapping map[string]string) (string, []any, error) {
return buildQueryCondition(resultSelector, baseQuery, fieldMapping)
}

// BuildCountQuery builds a count query based on the provided filter request
func BuildCountQuery(filterRequest *filter.Request, baseQuery string, fieldMapping map[string]string) (string, []any, error) {
if filterRequest == nil {
return baseQuery, nil, nil
}

resultSelector := query.ResultSelector{
Filter: filterRequest,
}

return listQuery, arg, nil
return buildQueryCondition(resultSelector, baseQuery, fieldMapping)
}

0 comments on commit 30f889e

Please sign in to comment.