mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-07-31 06:37:39 +00:00
feat(handler): implement default sort configuration for models
* Add SetDefaultSort method to configure default sort order * Implement getDefaultSort method to retrieve configured defaults * Update handleRead to apply default sort when none specified * Add tests for default sort functionality
This commit is contained in:
@@ -30,6 +30,7 @@ type Handler struct {
|
||||
hooks *HookRegistry
|
||||
fallbackHandler FallbackHandler
|
||||
openAPIGenerator func() (string, error)
|
||||
defaultSort map[string][]common.SortOption
|
||||
}
|
||||
|
||||
// NewHandler creates a new API handler with database and registry abstractions
|
||||
@@ -56,6 +57,32 @@ func (h *Handler) SetFallbackHandler(fallback FallbackHandler) {
|
||||
h.fallbackHandler = fallback
|
||||
}
|
||||
|
||||
// SetDefaultSort sets the sort order applied to list ("read") results when a
|
||||
// request does not specify its own sort. Pass an empty schema and name to set
|
||||
// a global default used by any model without a more specific default.
|
||||
func (h *Handler) SetDefaultSort(schema, name string, sort ...common.SortOption) {
|
||||
if h.defaultSort == nil {
|
||||
h.defaultSort = make(map[string][]common.SortOption)
|
||||
}
|
||||
h.defaultSort[defaultSortKey(schema, name)] = sort
|
||||
}
|
||||
|
||||
// getDefaultSort returns the configured default sort for a model, falling
|
||||
// back to the global default (registered with an empty schema and name).
|
||||
func (h *Handler) getDefaultSort(schema, name string) []common.SortOption {
|
||||
if h.defaultSort == nil {
|
||||
return nil
|
||||
}
|
||||
if sort, ok := h.defaultSort[defaultSortKey(schema, name)]; ok {
|
||||
return sort
|
||||
}
|
||||
return h.defaultSort[defaultSortKey("", "")]
|
||||
}
|
||||
|
||||
func defaultSortKey(schema, name string) string {
|
||||
return fmt.Sprintf("%s.%s", schema, name)
|
||||
}
|
||||
|
||||
// GetDatabase returns the underlying database connection
|
||||
// Implements common.SpecHandler interface
|
||||
func (h *Handler) GetDatabase() common.Database {
|
||||
@@ -345,6 +372,11 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
|
||||
query = query.Where(customOp.SQL)
|
||||
}
|
||||
|
||||
// Fall back to the configured default sort when the request didn't specify one
|
||||
if len(options.Sort) == 0 {
|
||||
options.Sort = common.ResolveSortColumns(h.getDefaultSort(schema, entity), reflection.GetPrimaryKeyName(model))
|
||||
}
|
||||
|
||||
// Apply sorting
|
||||
for _, sort := range options.Sort {
|
||||
direction := "ASC"
|
||||
|
||||
@@ -41,6 +41,36 @@ func TestSetFallbackHandler(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultSort(t *testing.T) {
|
||||
handler := NewHandler(nil, nil)
|
||||
|
||||
// No default configured yet
|
||||
if got := handler.getDefaultSort("public", "users"); got != nil {
|
||||
t.Errorf("Expected no default sort, got %v", got)
|
||||
}
|
||||
|
||||
// Global default
|
||||
global := []common.SortOption{{Column: "created_at", Direction: "desc"}}
|
||||
handler.SetDefaultSort("", "", global...)
|
||||
|
||||
if got := handler.getDefaultSort("public", "users"); !reflect.DeepEqual(got, global) {
|
||||
t.Errorf("Expected global default sort %v, got %v", global, got)
|
||||
}
|
||||
|
||||
// Per-model default overrides the global default
|
||||
perModel := []common.SortOption{{Column: "name", Direction: "asc"}}
|
||||
handler.SetDefaultSort("public", "users", perModel...)
|
||||
|
||||
if got := handler.getDefaultSort("public", "users"); !reflect.DeepEqual(got, perModel) {
|
||||
t.Errorf("Expected per-model default sort %v, got %v", perModel, got)
|
||||
}
|
||||
|
||||
// Other models still fall back to the global default
|
||||
if got := handler.getDefaultSort("public", "orders"); !reflect.DeepEqual(got, global) {
|
||||
t.Errorf("Expected global default sort %v for unrelated model, got %v", global, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDatabase(t *testing.T) {
|
||||
handler := NewHandler(nil, nil)
|
||||
db := handler.GetDatabase()
|
||||
|
||||
Reference in New Issue
Block a user