Documentation
¶
Index ¶
- Constants
- Variables
- func DecodeOptions[T any](opts map[string]any) (T, error)
- func FlushResourceSelectorCache()
- func OrQueries(db *gorm.DB, queries ...*gorm.DB) *gorm.DB
- func ParseFilteringQuery(query string, decodeURL bool) (grammar.FilteringQuery, error)
- func QueryResourceSelectors[T any](ctx context.Context, queryModel QueryModel, selectColumns []string, limit int, ...) ([]T, error)
- func RegisterProcessor(p Processor)
- func RegisterProvider(p Provider)
- func RegisteredProcessors() []string
- func RegisteredProviders() []string
- func SetResourceSelectorClause(ctx context.Context, resourceSelector types.ResourceSelector, query *gorm.DB, ...) (*gorm.DB, error)
- type ColumnDef
- type ColumnType
- type ParamDef
- type ParamType
- type Processor
- type ProcessorSpec
- type Profile
- type Provider
- type ProviderConfig
- type ProviderRequest
- type QueryModel
- type Result
- type Row
- type SubQuery
Constants ¶
const RenderLogs = "logs"
RenderLogs is the Render value that selects the canonical LogsTable presentation.
Variables ¶
var CommonFields = map[string]func(ctx context.Context, tx *gorm.DB, val string) (*gorm.DB, error){ "limit": func(ctx context.Context, tx *gorm.DB, val string) (*gorm.DB, error) { if i, err := strconv.Atoi(val); err == nil { return tx.Limit(i), nil } else { return nil, err } }, "sort": func(ctx context.Context, tx *gorm.DB, sort string) (*gorm.DB, error) { return tx.Order(clause.OrderByColumn{Column: clause.Column{Name: sort}}), nil }, "offset": func(ctx context.Context, tx *gorm.DB, val string) (*gorm.DB, error) { if i, err := strconv.Atoi(val); err == nil { return tx.Offset(i), nil } else { return nil, err } }, }
CommonFields provides built-in query field handlers for common operations
var DateMapper = func(ctx context.Context, val string) (any, error) { if expr, err := datemath.Parse(val); err != nil { return nil, fmt.Errorf("invalid date '%s': %s", val, err) } else { return expr.Time(), nil } }
DateMapper maps date expressions (including datemath like "now-7d") to actual time values
var JSONPathMapper = func(ctx context.Context, tx *gorm.DB, column string, op grammar.QueryOperator, path string, val string) *gorm.DB { if !slices.Contains([]grammar.QueryOperator{grammar.Eq, grammar.Neq}, op) { op = grammar.Eq } values := strings.Split(val, ",") for _, v := range values { tx = tx.Where(fmt.Sprintf(`TRIM(BOTH '"' from jsonb_path_query_first(%s, '$.%s')::TEXT) %s ?`, column, path, op), v) } return tx }
JSONPathMapper handles JSONPath queries against JSONB columns
Functions ¶
func DecodeOptions ¶ added in v0.1.13
DecodeOptions decodes a ProviderRequest.Options map into a provider-specific options struct T via a JSON round-trip (T's json tags drive the mapping). Returns the zero T when opts is empty.
func FlushResourceSelectorCache ¶
func FlushResourceSelectorCache()
FlushResourceSelectorCache flushes all resource selector caches
func ParseFilteringQuery ¶
func ParseFilteringQuery(query string, decodeURL bool) (grammar.FilteringQuery, error)
ParseFilteringQuery parses a filtering query string
func QueryResourceSelectors ¶
func QueryResourceSelectors[T any]( ctx context.Context, queryModel QueryModel, selectColumns []string, limit int, clauses []clause.Expression, resourceSelectors ...types.ResourceSelector, ) ([]T, error)
QueryResourceSelectors queries a table using multiple resource selectors. It returns the combined results from all selectors, respecting the limit.
Example usage:
model := QueryModel{
Table: "my_resources",
Columns: []string{"id", "name", "type"},
HasTags: true,
}
results, err := QueryResourceSelectors[MyResource](ctx, model, []string{"id", "name"}, 100, nil, selectors...)
func RegisterProcessor ¶ added in v0.1.13
func RegisterProcessor(p Processor)
RegisterProcessor adds p to the global processor registry, keyed by p.Type().
func RegisterProvider ¶ added in v0.1.13
func RegisterProvider(p Provider)
RegisterProvider adds p to the global provider registry, keyed by p.Type(). A later registration for the same type replaces the earlier one.
func RegisteredProcessors ¶ added in v0.1.13
func RegisteredProcessors() []string
RegisteredProcessors returns the registered processor types, sorted.
func RegisteredProviders ¶ added in v0.1.13
func RegisteredProviders() []string
RegisteredProviders returns the registered provider types, sorted.
func SetResourceSelectorClause ¶
func SetResourceSelectorClause( ctx context.Context, resourceSelector types.ResourceSelector, query *gorm.DB, queryModel QueryModel, ) (*gorm.DB, error)
SetResourceSelectorClause applies a ResourceSelector to a GORM query. The caller must provide a QueryModel that defines the table structure and capabilities.
Returns the modified query and any error encountered.
Types ¶
type ColumnDef ¶ added in v0.1.13
type ColumnDef struct {
// Name is the row key this column reads from and the default header label.
Name string `json:"name" yaml:"name"`
// Label overrides the column header. Defaults to a prettified Name.
Label string `json:"label,omitempty" yaml:"label,omitempty"`
// Type is the semantic type used for formatting. Defaults to string.
Type ColumnType `json:"type,omitempty" yaml:"type,omitempty"`
// Format overrides the clicky format string (e.g. "date", "bytes",
// "duration", "currency"). When empty it is derived from Type.
Format string `json:"format,omitempty" yaml:"format,omitempty"`
// Unit is an optional display unit (e.g. "ms", "MiB").
Unit string `json:"unit,omitempty" yaml:"unit,omitempty"`
// Width is an optional max display width in characters.
Width int `json:"width,omitempty" yaml:"width,omitempty"`
// CEL is an optional expression computing the cell value from the row.
// The row is exposed as `row` in the CEL environment.
CEL string `json:"cel,omitempty" yaml:"cel,omitempty"`
// Hidden excludes the column from rendered output while keeping it available
// to CEL and processors.
Hidden bool `json:"hidden,omitempty" yaml:"hidden,omitempty"`
}
ColumnDef declares one output column of a Profile.
type ColumnType ¶ added in v0.1.13
type ColumnType string
ColumnType is the semantic type of a column. It drives default formatting in the render layer (see render.go) and the clicky-ui contract.
The set mirrors duty/view.ColumnType so view specs port cleanly; it is expanded with format/filter/badge metadata in Phase 2.
const ( ColumnTypeString ColumnType = "string" ColumnTypeNumber ColumnType = "number" ColumnTypeBoolean ColumnType = "boolean" ColumnTypeDateTime ColumnType = "datetime" ColumnTypeDuration ColumnType = "duration" ColumnTypeBytes ColumnType = "bytes" ColumnTypeStatus ColumnType = "status" ColumnTypeHealth ColumnType = "health" )
type ParamDef ¶ added in v0.1.13
type ParamDef struct {
// Name is the parameter key, referenced in the query as `{{.params.<Name>}}`.
Name string `json:"name" yaml:"name"`
// Label is the human-facing name for the FilterBar. Defaults to Name.
Label string `json:"label,omitempty" yaml:"label,omitempty"`
// Type drives validation/coercion. Defaults to string.
Type ParamType `json:"type,omitempty" yaml:"type,omitempty"`
// Default is used when no value is supplied.
Default any `json:"default,omitempty" yaml:"default,omitempty"`
// Options enumerates the allowed values (an enum). When set, a supplied value
// must be one of these.
Options []string `json:"options,omitempty" yaml:"options,omitempty"`
// Required fails execution when no value (and no Default) is supplied.
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
// Description is shown as the FilterBar tooltip.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// Template optionally rewrites the resolved value; "{value}" is replaced with
// the supplied value (e.g. "{value}-api").
Template string `json:"template,omitempty" yaml:"template,omitempty"`
}
ParamDef declares one server-side filter parameter of a Profile. Supplied values are validated and coerced against the declaration, then exposed to the query template under `params.<Name>` before the provider runs. This mirrors legacy trace-profile params.
func (ParamDef) DisplayLabel ¶ added in v0.1.13
DisplayLabel returns the Label when set, otherwise the Name.
type ParamType ¶ added in v0.1.13
type ParamType string
ParamType is the declared type of a Profile parameter. It drives validation, coercion of incoming (string) values, and the per-profile JSON schema.
type Processor ¶ added in v0.1.13
type Processor interface {
// Type is the registry key (e.g. "sqlite.merge", "sqlite.recon").
Type() string
// Process transforms in according to spec and returns the new Result.
Process(ctx context.Context, spec ProcessorSpec, in *Result) (*Result, error)
}
Processor is a post-query step applied to a Result (e.g. sqlite merge, reconciliation). Implementations self-register via RegisterProcessor and are selected by ProcessorSpec.Type. Like providers, processors live in a subpackage that consumers blank-import.
func GetProcessor ¶ added in v0.1.13
GetProcessor returns the registered Processor for typ, or an error listing the available types.
type ProcessorSpec ¶ added in v0.1.13
type ProcessorSpec struct {
// Type is the registered processor key (e.g. "sqlite.merge", "sqlite.recon").
Type string `json:"type" yaml:"type"`
// Config is the processor-specific configuration.
Config map[string]any `json:"config,omitempty" yaml:"config,omitempty"`
}
ProcessorSpec names a post-query processor and carries its raw config, which the processor decodes for itself.
type Profile ¶ added in v0.1.13
type Profile struct {
// Name identifies the Profile (e.g. "SQL Server trace").
Name string `json:"profile" yaml:"profile"`
// Provider selects and configures the backend the Profile reads from.
Provider ProviderConfig `json:"provider" yaml:"provider"`
// Query is the provider-native query (SQL, PromQL, HTTP path, etc.). It may
// reference declared params as `{{.params.<name>}}` (or `$(...)`), which are
// rendered before the provider runs.
Query string `json:"query,omitempty" yaml:"query,omitempty"`
// Params declares the server-side filter parameters the Profile accepts. Their
// resolved values are templated into Query (and context sub-queries) and drive
// the per-profile FilterBar schema.
Params []ParamDef `json:"params,omitempty" yaml:"params,omitempty"`
// Columns declares the output columns in display order. When empty, the
// provider's raw row keys are used.
Columns []ColumnDef `json:"columns,omitempty" yaml:"columns,omitempty"`
// Processors are post-query steps (e.g. sqlite merge/recon) applied in order.
Processors []ProcessorSpec `json:"processors,omitempty" yaml:"processors,omitempty"`
// Context defines secondary queries whose single result becomes a named side
// object on the Result (e.g. Policy, Plan, Integrations).
Context map[string]SubQuery `json:"context,omitempty" yaml:"context,omitempty"`
// Output lists the render targets (e.g. table, html, xlsx, json).
Output []string `json:"output,omitempty" yaml:"output,omitempty"`
// Render selects how the frontend presents the result. "table" (the default,
// when empty) uses the generic data table; "logs" maps the columns onto the
// canonical LogsTable view (timestamp/level/pod/logger/thread/message, plus an
// optional duration column) for trace/log profiles. Filtering stays server-side
// via Params regardless of render mode.
Render string `json:"render,omitempty" yaml:"render,omitempty"`
}
Profile is a declarative, CEL-driven view over a data provider. It names the backend to read from, the provider-native query, the output columns (with optional CEL formatting), post-query processors, and named context objects.
A Profile is the unifying abstraction across legacy "trace profiles", duty View specs, and ad-hoc reports.
type Provider ¶ added in v0.1.13
type Provider interface {
// Type is the registry key (e.g. "sql", "http", "prometheus").
Type() string
// Execute runs req against the backend and returns the raw rows.
Execute(ctx context.Context, req ProviderRequest) ([]Row, error)
}
Provider executes a Profile's query against a single backend type and returns the raw rows. Implementations register themselves via RegisterProvider and are selected by ProviderConfig.Type.
func GetProvider ¶ added in v0.1.13
GetProvider returns the registered Provider for typ, or an error listing the available types when none is registered.
type ProviderConfig ¶ added in v0.1.13
type ProviderConfig struct {
// Type is the registered provider key (e.g. "sql", "http", "prometheus").
Type string `json:"type" yaml:"type"`
// Connection references a connection (connection://name) or an inline DSN/URL.
Connection string `json:"connection,omitempty" yaml:"connection,omitempty"`
// Options carries provider-specific knobs.
Options map[string]any `json:"options,omitempty" yaml:"options,omitempty"`
}
ProviderConfig selects a registered Provider and supplies the connection and provider-specific options.
type ProviderRequest ¶ added in v0.1.13
type ProviderRequest struct {
// Connection references a connection (connection://name) or an inline DSN/URL.
Connection string
// Query is the provider-native query string.
Query string
// Options carries provider-specific knobs from ProviderConfig.Options.
Options map[string]any
}
ProviderRequest is the resolved input handed to a Provider by the engine.
type QueryModel ¶
type QueryModel struct {
// Table name
Table string
// Custom functions to map fields to clauses
// Example: map["custom_field"] = func(ctx, tx, val) { ... custom query logic ... }
Custom map[string]func(ctx context.Context, tx *gorm.DB, val string) (*gorm.DB, error)
// List of jsonb columns that store a map.
// These columns can be addressed using dot notation to access the JSON fields directly
// Example: tags.cluster or tags.namespace.
JSONMapColumns []string
// List of columns that can be addressed on the search query.
// Any other fields will be treated as a property lookup.
Columns []string
// Alias maps fields from the search query to the table columns
// Example: map["created"] = "created_at"
Aliases map[string]string
// True when the table has a "tags" column
HasTags bool
// True when the table has a "labels" column
HasLabels bool
// True when the table has properties column
HasProperties bool
// FieldMapper maps the value of these fields
// Example: map["created_at"] = DateMapper
FieldMapper map[string]func(ctx context.Context, id string) (any, error)
}
QueryModel defines the structure and capabilities of a queryable table/resource. Consumers can create their own QueryModel instances for their specific tables.
func (QueryModel) Apply ¶
func (qm QueryModel) Apply(ctx context.Context, q grammar.QueryField, tx *gorm.DB) (*gorm.DB, []clause.Expression, error)
Apply processes a query field and converts it to GORM clauses. It handles: - Field aliases - Field value mapping (via FieldMapper) - Common field operations (limit, sort, offset) - Custom field handlers - JSON path queries - Property filtering Returns the modified transaction, clauses to add, and any error
type Result ¶ added in v0.1.13
type Result struct {
// Profile is the name of the Profile that produced this Result.
Profile string `json:"profile,omitempty" yaml:"profile,omitempty"`
// Rows are the primary tabular records.
Rows []Row `json:"rows" yaml:"rows"`
// Context holds named side objects keyed by SubQuery name.
Context map[string]any `json:"context,omitempty" yaml:"context,omitempty"`
}
Result is the output of executing a Profile: the tabular rows plus any named context objects (Policy/Plan/Integrations side panels, each produced by a SubQuery).
func Execute ¶ added in v0.1.13
Execute runs a Profile end-to-end: resolve the supplied params, render the query, dispatch to the provider, evaluate CEL columns, run any context SubQueries, and apply processors.
params carries the server-side filter values for the Profile's declared Params (omit when there are none). They are validated/coerced against the declarations and exposed to the query template as `params`.
type Row ¶ added in v0.1.13
Row is a single result record keyed by column name. It is a type alias for the generic map so provider code (ported from duty/dataquery) and CEL evaluation can treat rows uniformly.
type SubQuery ¶ added in v0.1.13
type SubQuery struct {
Provider ProviderConfig `json:"provider" yaml:"provider"`
Query string `json:"query,omitempty" yaml:"query,omitempty"`
}
SubQuery is a secondary provider query whose result is attached to the Result as a named context object.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package processor contains built-in post-query processors for the query engine: sqlite-backed merge and key-based reconciliation.
|
Package processor contains built-in post-query processors for the query engine: sqlite-backed merge and key-based reconciliation. |
|
Package providers contains the built-in data providers for the query engine.
|
Package providers contains the built-in data providers for the query engine. |
|
Package schema generates JSON Schema (Draft 2020-12) documents that drive the clicky-ui forms and tables of the query app:
|
Package schema generates JSON Schema (Draft 2020-12) documents that drive the clicky-ui forms and tables of the query app: |