diff --git a/api/compose/spec.json b/api/compose/spec.json index d1d2ca10b..729775401 100644 --- a/api/compose/spec.json +++ b/api/compose/spec.json @@ -987,6 +987,12 @@ "type": "uint", "required": false, "title": "Returned items per page (default 50)" + }, + { + "name": "sort", + "required": false, + "title": "Sort charts", + "type": "string" } ] } diff --git a/api/compose/spec/chart.json b/api/compose/spec/chart.json index dd9b96161..488580b5e 100644 --- a/api/compose/spec/chart.json +++ b/api/compose/spec/chart.json @@ -53,6 +53,12 @@ "required": false, "title": "Returned items per page (default 50)", "type": "uint" + }, + { + "name": "sort", + "required": false, + "title": "Sort charts", + "type": "string" } ] } diff --git a/compose/repository/chart.go b/compose/repository/chart.go index 190153ce6..ed29f4e81 100644 --- a/compose/repository/chart.go +++ b/compose/repository/chart.go @@ -9,6 +9,7 @@ import ( "gopkg.in/Masterminds/squirrel.v1" "github.com/cortezaproject/corteza-server/compose/types" + "github.com/cortezaproject/corteza-server/pkg/rh" ) type ( @@ -49,14 +50,20 @@ func (r chart) table() string { func (r chart) columns() []string { return []string{ - "id", "rel_namespace", "handle", "name", "config", - "created_at", "updated_at", "deleted_at", + "id", + "rel_namespace", + "handle", + "name", + "config", + "created_at", + "updated_at", + "deleted_at", } } func (r chart) query() squirrel.SelectBuilder { return squirrel. - Select(). + Select(r.columns()...). From(r.table()). Where("deleted_at IS NULL") } @@ -70,13 +77,13 @@ func (r chart) FindByHandle(namespaceID uint64, handle string) (*types.Chart, er } func (r chart) findOneBy(namespaceID uint64, field string, value interface{}) (*types.Chart, error) { - var c = &types.Chart{} + var ( + c = &types.Chart{} - err := r.findOneInNamespaceBy( - namespaceID, - r.query().Columns(r.columns()...), - squirrel.Eq{field: value}, - c, + q = r.query(). + Where(squirrel.Eq{field: value, "rel_namespace": namespaceID}) + + err = rh.FetchOne(r.db(), q, c) ) if err == nil && c.ID == 0 { @@ -89,34 +96,43 @@ func (r chart) findOneBy(namespaceID uint64, field string, value interface{}) (* func (r chart) Find(filter types.ChartFilter) (set types.ChartSet, f types.ChartFilter, err error) { f = filter + if f.Sort == "" { + f.Sort = "id ASC" + } + query := r.query() if filter.NamespaceID > 0 { - query = query.Where("rel_namespace = ?", filter.NamespaceID) + query = query.Where(squirrel.Eq{"rel_namespace": filter.NamespaceID}) } if f.Query != "" { - q := "%" + f.Query + "%" - query = query.Where("name like ?", q) + q := "%" + strings.ToLower(f.Query) + "%" + query = query.Where(squirrel.Or{ + squirrel.Like{"LOWER(name)": q}, + }) } if f.Handle != "" { - query = query.Where("LOWER(handle) = ?", strings.ToLower(f.Handle)) + query = query.Where("LOWER(handle) = LOWER(?)", f.Handle) } if f.IsReadable != nil { query = query.Where(f.IsReadable) } - if f.Count, err = r.count(query); err != nil || f.Count == 0 { + var orderBy []string + if orderBy, err = rh.ParseOrder(f.Sort, r.columns()...); err != nil { + return + } else { + query = query.OrderBy(orderBy...) + } + + if f.Count, err = rh.Count(r.db(), query); err != nil || f.Count == 0 { return } - query = query. - Columns(r.columns()...). - OrderBy("id ASC") - - return set, f, r.fetchPaged(&set, query, f.Page, f.PerPage) + return set, f, rh.FetchPaged(r.db(), query, f.Page, f.PerPage, &set) } func (r chart) Create(mod *types.Chart) (*types.Chart, error) { diff --git a/compose/rest/chart.go b/compose/rest/chart.go index 1c2419d74..914e66c7d 100644 --- a/compose/rest/chart.go +++ b/compose/rest/chart.go @@ -8,6 +8,7 @@ import ( "github.com/cortezaproject/corteza-server/compose/rest/request" "github.com/cortezaproject/corteza-server/compose/service" "github.com/cortezaproject/corteza-server/compose/types" + "github.com/cortezaproject/corteza-server/pkg/rh" "github.com/pkg/errors" ) @@ -52,10 +53,12 @@ func (ctrl Chart) List(ctx context.Context, r *request.ChartList) (interface{}, f := types.ChartFilter{ NamespaceID: r.NamespaceID, - Handle: r.Handle, - Query: r.Query, - PerPage: r.PerPage, - Page: r.Page, + Handle: r.Handle, + Query: r.Query, + + Sort: r.Sort, + + PageFilter: rh.Paging(r.Page, r.PerPage), } set, filter, err := ctrl.chart.With(ctx).Find(f) diff --git a/compose/rest/namespace.go b/compose/rest/namespace.go index 46d6f0d32..3d4aba50c 100644 --- a/compose/rest/namespace.go +++ b/compose/rest/namespace.go @@ -8,6 +8,7 @@ import ( "github.com/cortezaproject/corteza-server/compose/rest/request" "github.com/cortezaproject/corteza-server/compose/service" "github.com/cortezaproject/corteza-server/compose/types" + "github.com/cortezaproject/corteza-server/pkg/rh" ) type ( @@ -57,11 +58,12 @@ func (Namespace) New() *Namespace { func (ctrl Namespace) List(ctx context.Context, r *request.NamespaceList) (interface{}, error) { f := types.NamespaceFilter{ - Query: r.Query, - Slug: r.Slug, - PerPage: r.PerPage, - Page: r.Page, - Sort: r.Sort, + Query: r.Query, + Slug: r.Slug, + + Sort: r.Sort, + + PageFilter: rh.Paging(r.Page, r.PerPage), } set, filter, err := ctrl.namespace.With(ctx).Find(f) diff --git a/compose/rest/request/chart.go b/compose/rest/request/chart.go index 3447d7592..3ab230fa7 100644 --- a/compose/rest/request/chart.go +++ b/compose/rest/request/chart.go @@ -39,6 +39,7 @@ type ChartList struct { Handle string Page uint PerPage uint + Sort string NamespaceID uint64 `json:",string"` } @@ -53,6 +54,7 @@ func (r ChartList) Auditable() map[string]interface{} { out["handle"] = r.Handle out["page"] = r.Page out["perPage"] = r.PerPage + out["sort"] = r.Sort out["namespaceID"] = r.NamespaceID return out @@ -97,6 +99,9 @@ func (r *ChartList) Fill(req *http.Request) (err error) { if val, ok := get["perPage"]; ok { r.PerPage = parseUint(val) } + if val, ok := get["sort"]; ok { + r.Sort = val + } r.NamespaceID = parseUInt64(chi.URLParam(req, "namespaceID")) return err diff --git a/compose/types/chart.go b/compose/types/chart.go index 756a15f3a..9b558b113 100644 --- a/compose/types/chart.go +++ b/compose/types/chart.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/cortezaproject/corteza-server/pkg/permissions" + "github.com/cortezaproject/corteza-server/pkg/rh" ) type ( @@ -42,10 +43,11 @@ type ( NamespaceID uint64 `json:"namespaceID,string"` Handle string `json:"handle"` Query string `json:"query"` - Page uint `json:"page"` - PerPage uint `json:"perPage"` - // Sort string `json:"sort"` - Count uint `json:"count"` + + Sort string `json:"sort"` + + // Standard paging fields & helpers + rh.PageFilter // Resource permission check filter IsReadable *permissions.ResourceFilter `json:"-"` diff --git a/compose/types/namespace.go b/compose/types/namespace.go index 3d3ca72bf..985116c97 100644 --- a/compose/types/namespace.go +++ b/compose/types/namespace.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/cortezaproject/corteza-server/pkg/permissions" + "github.com/cortezaproject/corteza-server/pkg/rh" ) type ( @@ -24,12 +25,13 @@ type ( } NamespaceFilter struct { - Query string `json:"query"` - Slug string `json:"slug"` - Page uint `json:"page"` - PerPage uint `json:"perPage"` - Sort string `json:"sort"` - Count uint `json:"count"` + Query string `json:"query"` + Slug string `json:"slug"` + + Sort string `json:"sort"` + + // Standard paging fields & helpers + rh.PageFilter // Resource permission check filter IsReadable *permissions.ResourceFilter `json:"-"` diff --git a/docs/compose/README.md b/docs/compose/README.md index a1da3db76..67d0cb9e5 100644 --- a/docs/compose/README.md +++ b/docs/compose/README.md @@ -410,6 +410,7 @@ | handle | string | GET | Search charts by handle | N/A | NO | | page | uint | GET | Page number (0 based) | N/A | NO | | perPage | uint | GET | Returned items per page (default 50) | N/A | NO | +| sort | string | GET | Sort charts | N/A | NO | | namespaceID | uint64 | PATH | Namespace ID | N/A | YES | ## List/read charts