diff --git a/pkg/web/handler/core.go b/pkg/web/handler/core.go index fe2b5be40..b2ea958f9 100644 --- a/pkg/web/handler/core.go +++ b/pkg/web/handler/core.go @@ -106,3 +106,31 @@ func DoReadOne(_ context.Context, obj CObject, a web.Auth) (maxPermission int, e events.DispatchPending(s) return maxPermission, nil } + +// DoReadAll runs the ReadAll + commit pipeline for a CObject. obj may carry +// scoping context (e.g., TaskID on LabelTask). Returns the result slice/ +// interface, the result count, and total count. Pagination header math and +// nil-slice normalization remain the caller's responsibility. +func DoReadAll(_ context.Context, obj CObject, a web.Auth, search string, page, perPage int) (result any, resultCount int, total int64, err error) { + s := db.NewSession() + defer func() { + if cerr := s.Close(); cerr != nil { + log.Errorf("Could not close session: %s", cerr) + } + }() + + result, resultCount, total, err = obj.ReadAll(s, a, search, page, perPage) + if err != nil { + _ = s.Rollback() + events.CleanupPending(s) + return nil, 0, 0, err + } + + if err = s.Commit(); err != nil { + events.CleanupPending(s) + return nil, 0, 0, err + } + + events.DispatchPending(s) + return result, resultCount, total, nil +} diff --git a/pkg/web/handler/read_all.go b/pkg/web/handler/read_all.go index 6b7538690..680c3baf7 100644 --- a/pkg/web/handler/read_all.go +++ b/pkg/web/handler/read_all.go @@ -25,8 +25,6 @@ import ( "strconv" vconfig "code.vikunja.io/api/pkg/config" - "code.vikunja.io/api/pkg/db" - "code.vikunja.io/api/pkg/events" "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/modules/auth" @@ -91,22 +89,11 @@ func (c *WebHandler) ReadAllWeb(ctx *echo.Context) error { perPageNumber = vconfig.ServiceMaxItemsPerPage.GetInt() } - // Create the db session - s := db.NewSession() - defer func() { - err = s.Close() - if err != nil { - log.Errorf("Could not close session: %s", err) - } - }() - // Search search := ctx.QueryParam("s") - result, resultCount, numberOfItems, err := currentStruct.ReadAll(s, currentAuth, search, pageNumber, perPageNumber) + result, resultCount, numberOfItems, err := DoReadAll(ctx.Request().Context(), currentStruct, currentAuth, search, pageNumber, perPageNumber) if err != nil { - _ = s.Rollback() - events.CleanupPending(s) return err } @@ -127,14 +114,6 @@ func (c *WebHandler) ReadAllWeb(ctx *echo.Context) error { ctx.Response().Header().Set("x-pagination-result-count", strconv.FormatInt(int64(resultCount), 10)) ctx.Response().Header().Set("Access-Control-Expose-Headers", "x-pagination-total-pages, x-pagination-result-count") - err = s.Commit() - if err != nil { - events.CleanupPending(s) - return err - } - - events.DispatchPending(s) - // Ensure we return an empty array instead of null when there are no results. // We need to use reflection here because a nil slice wrapped in an interface{} // is not equal to nil (the interface contains a nil value but is not nil itself).