mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-11-13 09:53:53 +00:00
Added content-range headers
This commit is contained in:
parent
3eb17666bf
commit
faafe5abea
13
pkg/common/reflection_utils.go
Normal file
13
pkg/common/reflection_utils.go
Normal file
@ -0,0 +1,13 @@
|
||||
package common
|
||||
|
||||
import "reflect"
|
||||
|
||||
func Len(v any) int {
|
||||
val := reflect.ValueOf(v)
|
||||
switch val.Kind() {
|
||||
case reflect.Slice, reflect.Array, reflect.Map, reflect.String, reflect.Chan:
|
||||
return val.Len()
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@ -18,6 +18,11 @@ type RequestOptions struct {
|
||||
CustomOperators []CustomOperator `json:"customOperators"`
|
||||
ComputedColumns []ComputedColumn `json:"computedColumns"`
|
||||
Parameters []Parameter `json:"parameters"`
|
||||
|
||||
// Cursor pagination
|
||||
CursorForward string `json:"cursor_forward"`
|
||||
CursorBackward string `json:"cursor_backward"`
|
||||
FetchRowNumber *string `json:"fetch_row_number"`
|
||||
}
|
||||
|
||||
type Parameter struct {
|
||||
@ -68,6 +73,7 @@ type Response struct {
|
||||
|
||||
type Metadata struct {
|
||||
Total int64 `json:"total"`
|
||||
Count int64 `json:"count"`
|
||||
Filtered int64 `json:"filtered"`
|
||||
Limit int `json:"limit"`
|
||||
Offset int `json:"offset"`
|
||||
|
||||
@ -31,7 +31,9 @@ func (opts *ExtendedRequestOptions) GetCursorFilter(
|
||||
modelColumns []string, // optional: for validation
|
||||
expandJoins map[string]string, // optional: alias → JOIN SQL
|
||||
) (string, error) {
|
||||
|
||||
if strings.Contains(tableName, ".") {
|
||||
tableName = strings.SplitN(tableName, ".", 2)[1]
|
||||
}
|
||||
// --------------------------------------------------------------------- //
|
||||
// 1. Determine active cursor
|
||||
// --------------------------------------------------------------------- //
|
||||
@ -137,11 +139,11 @@ func (opts *ExtendedRequestOptions) GetCursorFilter(
|
||||
// ------------------------------------------------------------------------- //
|
||||
// Helper: get active cursor (forward or backward)
|
||||
func (opts *ExtendedRequestOptions) getActiveCursor() (id string, direction CursorDirection) {
|
||||
if opts.CursorForward != "" {
|
||||
return opts.CursorForward, CursorForward
|
||||
if opts.RequestOptions.CursorForward != "" {
|
||||
return opts.RequestOptions.CursorForward, CursorForward
|
||||
}
|
||||
if opts.CursorBackward != "" {
|
||||
return opts.CursorBackward, CursorBackward
|
||||
if opts.RequestOptions.CursorBackward != "" {
|
||||
return opts.RequestOptions.CursorBackward, CursorBackward
|
||||
}
|
||||
return "", 0
|
||||
}
|
||||
|
||||
@ -339,7 +339,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
|
||||
}
|
||||
|
||||
// Apply cursor-based pagination
|
||||
if len(options.CursorForward) > 0 || len(options.CursorBackward) > 0 {
|
||||
if len(options.RequestOptions.CursorForward) > 0 || len(options.RequestOptions.CursorBackward) > 0 {
|
||||
logger.Debug("Applying cursor pagination")
|
||||
|
||||
// Get primary key name
|
||||
@ -389,6 +389,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
|
||||
|
||||
metadata := &common.Metadata{
|
||||
Total: int64(total),
|
||||
Count: int64(common.Len(modelPtr)),
|
||||
Filtered: int64(total),
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
@ -937,7 +938,12 @@ func (h *Handler) sendFormattedResponse(w common.ResponseWriter, data interface{
|
||||
if options.CleanJSON {
|
||||
data = h.cleanJSON(data)
|
||||
}
|
||||
|
||||
w.SetHeader("Content-Type", "application/json")
|
||||
w.SetHeader("Content-Range", fmt.Sprintf("%d-%d/%d", metadata.Offset, int64(metadata.Offset)+metadata.Count, metadata.Filtered))
|
||||
w.SetHeader("X-Api-Range-Total", fmt.Sprintf("%d", metadata.Filtered))
|
||||
w.SetHeader("X-Api-Range-Size", fmt.Sprintf("%d", metadata.Count))
|
||||
|
||||
// Format response based on response format option
|
||||
switch options.ResponseFormat {
|
||||
case "simple":
|
||||
|
||||
@ -28,23 +28,18 @@ type ExtendedRequestOptions struct {
|
||||
Expand []ExpandOption
|
||||
|
||||
// Advanced features
|
||||
AdvancedSQL map[string]string // Column -> SQL expression
|
||||
ComputedQL map[string]string // Column -> CQL expression
|
||||
Distinct bool
|
||||
SkipCount bool
|
||||
SkipCache bool
|
||||
FetchRowNumber *string
|
||||
PKRow *string
|
||||
AdvancedSQL map[string]string // Column -> SQL expression
|
||||
ComputedQL map[string]string // Column -> CQL expression
|
||||
Distinct bool
|
||||
SkipCount bool
|
||||
SkipCache bool
|
||||
PKRow *string
|
||||
|
||||
// Response format
|
||||
ResponseFormat string // "simple", "detail", "syncfusion"
|
||||
|
||||
// Transaction
|
||||
AtomicTransaction bool
|
||||
|
||||
// Cursor pagination
|
||||
CursorForward string
|
||||
CursorBackward string
|
||||
}
|
||||
|
||||
// ExpandOption represents a relation expansion configuration
|
||||
@ -171,9 +166,9 @@ func (h *Handler) parseOptionsFromHeaders(r common.Request) ExtendedRequestOptio
|
||||
options.Offset = &offset
|
||||
}
|
||||
case strings.HasPrefix(normalizedKey, "x-cursor-forward"):
|
||||
options.CursorForward = decodedValue
|
||||
options.RequestOptions.CursorForward = decodedValue
|
||||
case strings.HasPrefix(normalizedKey, "x-cursor-backward"):
|
||||
options.CursorBackward = decodedValue
|
||||
options.RequestOptions.CursorBackward = decodedValue
|
||||
|
||||
// Advanced Features
|
||||
case strings.HasPrefix(normalizedKey, "x-advsql-"):
|
||||
@ -189,7 +184,7 @@ func (h *Handler) parseOptionsFromHeaders(r common.Request) ExtendedRequestOptio
|
||||
case strings.HasPrefix(normalizedKey, "x-skipcache"):
|
||||
options.SkipCache = strings.ToLower(decodedValue) == "true"
|
||||
case strings.HasPrefix(normalizedKey, "x-fetch-rownumber"):
|
||||
options.FetchRowNumber = &decodedValue
|
||||
options.RequestOptions.FetchRowNumber = &decodedValue
|
||||
case strings.HasPrefix(normalizedKey, "x-pkrow"):
|
||||
options.PKRow = &decodedValue
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user