Make store sorting more robust
This commit is contained in:
@@ -119,7 +119,7 @@ func (s Store) {{ toggleExport .Search.Export "Search" $.Types.Plural }}(ctx con
|
||||
{{- else }}
|
||||
{{- if $.Search.EnableSorting }}
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, f.Sort, s.sortable{{ export $.Types.Singular }}Columns()...); err != nil {
|
||||
if q, err = setOrderBy(q, f.Sort, s.sortable{{ export $.Types.Singular }}Columns()); err != nil {
|
||||
return err
|
||||
}
|
||||
{{ end -}}
|
||||
@@ -182,12 +182,12 @@ func (s Store) {{ unexport "fetchFullPageOf" $.Types.Plural }} (
|
||||
}
|
||||
{{ else if .Search.EnableSorting }}
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortable{{ export $.Types.Singular }}Columns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortable{{ export $.Types.Singular }}Columns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
{{ else if .RDBMS.Columns.PrimaryKeyFields }}
|
||||
// Sort by primary keys by default
|
||||
if q, err = setOrderBy(q, sort, {{ range .RDBMS.Columns.PrimaryKeyFields }}"{{ .Column }}",{{ end }}); err != nil {
|
||||
if q, err = setOrderBy(q, sort, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
{{ end }}
|
||||
@@ -576,11 +576,14 @@ func (Store) {{ unexport $.Types.Singular }}Columns(aa ... string) []string {
|
||||
// sortable{{ $.Types.Singular }}Columns returns all {{ $.Types.Singular }} columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortable{{ $.Types.Singular }}Columns() []string {
|
||||
return []string{
|
||||
func (Store) sortable{{ $.Types.Singular }}Columns() map[string]string {
|
||||
return map[string]string{
|
||||
{{ range $.RDBMS.Columns }}
|
||||
{{- if .IsSortable -}}
|
||||
"{{ .Column }}",
|
||||
"{{ toLower .Column }}": "{{ .Column }}",
|
||||
{{- if not (eq (.Field|toLower) (.Column|toLower)) }}
|
||||
"{{ toLower .Field }}": "{{ .Column }}",
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ func (s Store) fetchFullPageOfActionlogs(
|
||||
}
|
||||
|
||||
// Sort by primary keys by default
|
||||
if q, err = setOrderBy(q, sort, "id"); err != nil {
|
||||
if q, err = setOrderBy(q, sort, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfApplications(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableApplicationColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableApplicationColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -439,13 +439,14 @@ func (Store) applicationColumns(aa ...string) []string {
|
||||
// sortableApplicationColumns returns all Application columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableApplicationColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"name",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableApplicationColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "name": "name", "created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfComposeCharts(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableComposeChartColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableComposeChartColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -449,14 +449,14 @@ func (Store) composeChartColumns(aa ...string) []string {
|
||||
// sortableComposeChartColumns returns all ComposeChart columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableComposeChartColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"handle",
|
||||
"name",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableComposeChartColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "handle": "handle", "name": "name", "created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfComposeModules(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableComposeModuleColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableComposeModuleColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -459,14 +459,14 @@ func (Store) composeModuleColumns(aa ...string) []string {
|
||||
// sortableComposeModuleColumns returns all ComposeModule columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableComposeModuleColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"handle",
|
||||
"name",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableComposeModuleColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "handle": "handle", "name": "name", "created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfComposeNamespaces(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableComposeNamespaceColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableComposeNamespaceColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -448,14 +448,14 @@ func (Store) composeNamespaceColumns(aa ...string) []string {
|
||||
// sortableComposeNamespaceColumns returns all ComposeNamespace columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableComposeNamespaceColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"name",
|
||||
"slug",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableComposeNamespaceColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "name": "name", "slug": "slug", "created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfComposePages(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableComposePageColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableComposePageColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -469,13 +469,14 @@ func (Store) composePageColumns(aa ...string) []string {
|
||||
// sortableComposePageColumns returns all ComposePage columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableComposePageColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"weight",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableComposePageColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "weight": "weight", "created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -449,12 +449,14 @@ func (Store) composeRecordColumns(aa ...string) []string {
|
||||
// sortableComposeRecordColumns returns all ComposeRecord columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableComposeRecordColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableComposeRecordColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/ql"
|
||||
"github.com/cortezaproject/corteza-server/pkg/slice"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
"strings"
|
||||
)
|
||||
@@ -316,14 +315,14 @@ func (s Store) composeRecordPostLoadProcessor(ctx context.Context, m *types.Modu
|
||||
|
||||
func (s Store) composeRecordsSorter(m *types.Module, q squirrel.SelectBuilder, sort filter.SortExprSet) (squirrel.SelectBuilder, error) {
|
||||
var (
|
||||
sortable = slice.ToStringBoolMap(s.sortableComposeRecordColumns())
|
||||
sortable = s.sortableComposeRecordColumns()
|
||||
sqlSort = make([]string, len(sort))
|
||||
)
|
||||
|
||||
for i, c := range sort {
|
||||
var err error
|
||||
if sortable[c.Column] {
|
||||
sqlSort[i] = c.Column
|
||||
if col, has := sortable[strings.ToLower(c.Column)]; has {
|
||||
sqlSort[i] = col
|
||||
} else if f := m.Fields.FindByName(c.Column); f != nil {
|
||||
sqlSort[i], err = s.config.CastModuleFieldToColumnType(f, c.Column)
|
||||
} else {
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfMessagingChannels(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableMessagingChannelColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableMessagingChannelColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -447,9 +447,9 @@ func (Store) messagingChannelColumns(aa ...string) []string {
|
||||
// sortableMessagingChannelColumns returns all MessagingChannel columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableMessagingChannelColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
func (Store) sortableMessagingChannelColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/healthcheck"
|
||||
"github.com/cortezaproject/corteza-server/pkg/ql"
|
||||
"github.com/cortezaproject/corteza-server/pkg/sentry"
|
||||
"github.com/cortezaproject/corteza-server/pkg/slice"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
"github.com/cortezaproject/corteza-server/store/rdbms/ddl"
|
||||
"github.com/jmoiron/sqlx"
|
||||
@@ -422,16 +421,23 @@ func setCursorCond(q squirrel.SelectBuilder, cursor *filter.PagingCursor) squirr
|
||||
return q
|
||||
}
|
||||
|
||||
func setOrderBy(q squirrel.SelectBuilder, sort filter.SortExprSet, ss ...string) (squirrel.SelectBuilder, error) {
|
||||
func setOrderBy(q squirrel.SelectBuilder, sort filter.SortExprSet, sortable map[string]string) (squirrel.SelectBuilder, error) {
|
||||
var (
|
||||
sortable = slice.ToStringBoolMap(ss)
|
||||
sqlSort = make([]string, len(sort))
|
||||
col string
|
||||
has bool
|
||||
sqlSort = make([]string, len(sort))
|
||||
)
|
||||
|
||||
for i, c := range sort {
|
||||
if sortable[c.Column] {
|
||||
sqlSort[i] = sort[i].Column
|
||||
if sortable != nil {
|
||||
// When sortable map is given, test each sort column
|
||||
if col, has = sortable[strings.ToLower(c.Column)]; !has {
|
||||
return q, fmt.Errorf("column %q is not sortable", c.Column)
|
||||
}
|
||||
|
||||
sqlSort[i] = col
|
||||
} else {
|
||||
return q, fmt.Errorf("column %q is not sortable", c.Column)
|
||||
sqlSort[i] = c.Column
|
||||
}
|
||||
|
||||
if sort[i].Descending {
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfReminders(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableReminderColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableReminderColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -449,13 +449,16 @@ func (Store) reminderColumns(aa ...string) []string {
|
||||
// sortableReminderColumns returns all Reminder columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableReminderColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"remind_at",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableReminderColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "remind_at": "remind_at",
|
||||
"remindat": "remind_at",
|
||||
"created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfRoles(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableRoleColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableRoleColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -461,15 +461,16 @@ func (Store) roleColumns(aa ...string) []string {
|
||||
// sortableRoleColumns returns all Role columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableRoleColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"name",
|
||||
"handle",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"archived_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableRoleColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "name": "name", "handle": "handle", "created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"archived_at": "archived_at",
|
||||
"archivedat": "archived_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Store) fetchFullPageOfUsers(
|
||||
}
|
||||
|
||||
// Apply sorting expr from filter to query
|
||||
if q, err = setOrderBy(q, sort, s.sortableUserColumns()...); err != nil {
|
||||
if q, err = setOrderBy(q, sort, s.sortableUserColumns()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -480,17 +480,16 @@ func (Store) userColumns(aa ...string) []string {
|
||||
// sortableUserColumns returns all User columns flagged as sortable
|
||||
//
|
||||
// With optional string arg, all columns are returned aliased
|
||||
func (Store) sortableUserColumns() []string {
|
||||
return []string{
|
||||
"id",
|
||||
"email",
|
||||
"username",
|
||||
"name",
|
||||
"handle",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"suspended_at",
|
||||
"deleted_at",
|
||||
func (Store) sortableUserColumns() map[string]string {
|
||||
return map[string]string{
|
||||
"id": "id", "email": "email", "username": "username", "name": "name", "handle": "handle", "created_at": "created_at",
|
||||
"createdat": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
"updatedat": "updated_at",
|
||||
"suspended_at": "suspended_at",
|
||||
"suspendedat": "suspended_at",
|
||||
"deleted_at": "deleted_at",
|
||||
"deletedat": "deleted_at",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user