Some checks are pending
Docs Deploy / build_and_deploy (push) Waiting to run
Generate Docs / cli (push) Waiting to run
Generate Config Doc / cli (push) Waiting to run
Go formatting / go-formatting (push) Waiting to run
Check links / markdown-link-check (push) Waiting to run
Integration / pre-test (push) Waiting to run
Integration / test on (push) Blocked by required conditions
Integration / status (push) Blocked by required conditions
Lint / Lint Go code (push) Waiting to run
Test / test (ubuntu-latest) (push) Waiting to run
199 lines
4.5 KiB
Go
199 lines
4.5 KiB
Go
package query
|
|
|
|
import "fmt"
|
|
|
|
const (
|
|
// DefaultPageSize defines the default number of results to select per page.
|
|
DefaultPageSize = 30
|
|
|
|
SortOrderAsc = "asc"
|
|
SortOrderDesc = "desc"
|
|
)
|
|
|
|
// Pager describes support for paging query results.
|
|
type Pager interface {
|
|
// PageSize returns the size for each query result set.
|
|
PageSize() uint32
|
|
|
|
// AtPage returns the result set page to query.
|
|
AtPage() uint32
|
|
|
|
// IsPagingEnabled checks if the query results should be paginated.
|
|
IsPagingEnabled() bool
|
|
}
|
|
|
|
// SortBy contains info on how to sort query results.
|
|
type SortBy struct {
|
|
Field string
|
|
Order string
|
|
}
|
|
|
|
// Filter describes a filter to apply to a query.
|
|
type Filter interface {
|
|
fmt.Stringer
|
|
|
|
// Field returns the name of the filtered field.
|
|
Field() string
|
|
|
|
// Value returns the value to use for filtering.
|
|
Value() any
|
|
}
|
|
|
|
// Filterer describes support for filtering query results.
|
|
type Filterer interface {
|
|
// Filters returns the list of filters to apply to the query.
|
|
Filters() []Filter
|
|
}
|
|
|
|
type queryOptions struct {
|
|
pageSize uint32
|
|
atPage uint32
|
|
args []any
|
|
fields []string
|
|
sortBy []SortBy
|
|
filters []Filter
|
|
}
|
|
|
|
// Option configures queries.
|
|
type Option func(*Query)
|
|
|
|
// AtPage assigns a page to select.
|
|
// Pages start from page one, so assigning page zero selects the first page.
|
|
func AtPage(page uint32) Option {
|
|
return func(q *Query) {
|
|
if page == 0 {
|
|
q.options.atPage = 1
|
|
} else {
|
|
q.options.atPage = page
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithPageSize assigns the number of results to select per page.
|
|
// The default page size is used when size zero is assigned.
|
|
func WithPageSize(size uint32) Option {
|
|
return func(q *Query) {
|
|
if size == 0 {
|
|
q.options.pageSize = DefaultPageSize
|
|
} else {
|
|
q.options.pageSize = size
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithoutPaging disables the paging of results.
|
|
// All results are selected when paging is disabled.
|
|
func WithoutPaging() Option {
|
|
return func(q *Query) {
|
|
q.options.pageSize = 0
|
|
}
|
|
}
|
|
|
|
// WithFilters adds one or more filters to apply to the query.
|
|
func WithFilters(f ...Filter) Option {
|
|
return func(q *Query) {
|
|
q.options.filters = f
|
|
}
|
|
}
|
|
|
|
// WithArgs adds one or more arguments to the query.
|
|
func WithArgs(args ...any) Option {
|
|
return func(q *Query) {
|
|
q.options.args = args
|
|
}
|
|
}
|
|
|
|
// Fields assigns the field names to query.
|
|
// The default is to select all fields.
|
|
func Fields(fields ...string) Option {
|
|
return func(q *Query) {
|
|
q.options.fields = fields
|
|
}
|
|
}
|
|
|
|
// SortByFields orders the query by one or more fields.
|
|
// Use `WithSortBy` option when multiple order by directions are needed.
|
|
func SortByFields(order string, fields ...string) Option {
|
|
return func(q *Query) {
|
|
for _, f := range fields {
|
|
q.options.sortBy = append(q.options.sortBy, SortBy{
|
|
Field: f,
|
|
Order: order,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithSortBy orders the query by one or more fields.
|
|
func WithSortBy(o ...SortBy) Option {
|
|
return func(q *Query) {
|
|
q.options.sortBy = append(q.options.sortBy, o...)
|
|
}
|
|
}
|
|
|
|
// New creates a new query that selects results from an entity.
|
|
// The name is the name of an entity which depending on the data backend have
|
|
// different meanings. In a relational database the name should be a table,
|
|
// function or view, while in a NoSQL database it should be a collection.
|
|
func New(name string, options ...Option) Query {
|
|
q := Query{
|
|
name: name,
|
|
options: queryOptions{
|
|
pageSize: DefaultPageSize,
|
|
atPage: 1,
|
|
},
|
|
}
|
|
|
|
for _, apply := range options {
|
|
apply(&q)
|
|
}
|
|
|
|
return q
|
|
}
|
|
|
|
// Query describes how to select values from a data backend.
|
|
type Query struct {
|
|
name string
|
|
options queryOptions
|
|
}
|
|
|
|
// Name returns the name of the database table, collection, view or function to select.
|
|
func (q Query) Name() string {
|
|
return q.name
|
|
}
|
|
|
|
// Args returns the arguments for query.
|
|
// Arguments are used when the query calls a function in the data backend.
|
|
func (q Query) Args() []any {
|
|
return q.options.args
|
|
}
|
|
|
|
// Fields returns list of field names to select.
|
|
func (q Query) Fields() []string {
|
|
return q.options.fields
|
|
}
|
|
|
|
// SortBy returns the sort info for the query.
|
|
func (q Query) SortBy() []SortBy {
|
|
return q.options.sortBy
|
|
}
|
|
|
|
// PageSize returns the size for each query result set.
|
|
func (q Query) PageSize() uint32 {
|
|
return q.options.pageSize
|
|
}
|
|
|
|
// AtPage returns the result set page to query.
|
|
func (q Query) AtPage() uint32 {
|
|
return q.options.atPage
|
|
}
|
|
|
|
// Filters returns the list of filters to apply to the query.
|
|
func (q Query) Filters() []Filter {
|
|
return q.options.filters
|
|
}
|
|
|
|
// IsPagingEnabled checks if the query results should be paginated.
|
|
func (q Query) IsPagingEnabled() bool {
|
|
return q.options.pageSize > 0
|
|
}
|