2023-07-08 08:43:30 -06:00
|
|
|
package models
|
|
|
|
|
2023-08-14 16:50:09 -06:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
)
|
2023-08-11 14:24:11 -06:00
|
|
|
|
2023-07-08 08:43:30 -06:00
|
|
|
// maps to frontend/src/app/models/widget/dashboard-widget-query.ts
|
|
|
|
type QueryResource struct {
|
|
|
|
Use string `json:"use"`
|
|
|
|
Select []string `json:"select"`
|
|
|
|
From string `json:"from"`
|
|
|
|
Where map[string]interface{} `json:"where"`
|
2023-10-01 18:05:55 -06:00
|
|
|
Limit *int `json:"limit,omitempty"`
|
|
|
|
Offset *int `json:"offset,omitempty"`
|
2023-08-11 14:24:11 -06:00
|
|
|
|
|
|
|
//aggregation fields
|
2023-08-14 00:35:02 -06:00
|
|
|
Aggregations *QueryResourceAggregations `json:"aggregations"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type QueryResourceAggregations struct {
|
|
|
|
CountBy string `json:"count_by"` //alias for both groupby and orderby, cannot be used together
|
|
|
|
|
|
|
|
GroupBy string `json:"group_by"`
|
|
|
|
OrderBy string `json:"order_by"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *QueryResource) Validate() error {
|
|
|
|
if len(q.Use) > 0 {
|
|
|
|
return fmt.Errorf("'use' is not supported yet")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(q.From) == 0 {
|
|
|
|
return fmt.Errorf("'from' is required")
|
|
|
|
}
|
|
|
|
|
|
|
|
if q.Aggregations != nil {
|
|
|
|
if len(q.Select) > 0 {
|
|
|
|
return fmt.Errorf("cannot use 'select' and 'aggregations' together")
|
|
|
|
}
|
|
|
|
if len(q.Aggregations.CountBy) > 0 {
|
|
|
|
if len(q.Aggregations.GroupBy) > 0 {
|
|
|
|
return fmt.Errorf("cannot use 'count_by' and 'group_by' together")
|
|
|
|
}
|
|
|
|
if len(q.Aggregations.OrderBy) > 0 {
|
|
|
|
return fmt.Errorf("cannot use 'count_by' and 'order_by' together")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(q.Aggregations.CountBy) == 0 && len(q.Aggregations.OrderBy) == 0 && len(q.Aggregations.GroupBy) == 0 {
|
|
|
|
return fmt.Errorf("aggregations must have at least one of 'count_by', 'group_by', or 'order_by'")
|
|
|
|
}
|
2023-08-14 16:50:09 -06:00
|
|
|
if strings.Contains(q.Aggregations.CountBy, " ") {
|
|
|
|
return fmt.Errorf("count_by cannot have spaces (or aliases)")
|
|
|
|
}
|
|
|
|
if strings.Contains(q.Aggregations.GroupBy, " ") {
|
|
|
|
return fmt.Errorf("group_by cannot have spaces (or aliases)")
|
|
|
|
}
|
|
|
|
if strings.Contains(q.Aggregations.OrderBy, " ") {
|
|
|
|
return fmt.Errorf("order_by cannot have spaces (or aliases)")
|
|
|
|
}
|
2023-10-01 18:05:55 -06:00
|
|
|
}
|
2023-08-14 00:35:02 -06:00
|
|
|
|
2023-10-01 18:05:55 -06:00
|
|
|
if q.Limit != nil && *q.Limit < 0 {
|
|
|
|
return fmt.Errorf("'limit' must be greater than or equal to zero")
|
|
|
|
}
|
|
|
|
if q.Offset != nil && *q.Offset < 0 {
|
|
|
|
return fmt.Errorf("'offset' must be greater than or equal to zero")
|
2023-08-14 00:35:02 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2023-07-08 08:43:30 -06:00
|
|
|
}
|