query

package
v0.1.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 3, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const RenderLogs = "logs"

RenderLogs is the Render value that selects the canonical LogsTable presentation.

Variables

View Source
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

View Source
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

View Source
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

func DecodeOptions[T any](opts map[string]any) (T, error)

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 OrQueries

func OrQueries(db *gorm.DB, queries ...*gorm.DB) *gorm.DB

OrQueries combines multiple gorm queries with OR logic

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

func (d ParamDef) DisplayLabel() string

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.

const (
	ParamTypeString  ParamType = "string"
	ParamTypeNumber  ParamType = "number"
	ParamTypeBoolean ParamType = "boolean"
	ParamTypeDate    ParamType = "date"
	ParamTypeEnum    ParamType = "enum"
)

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

func GetProcessor(typ string) (Processor, error)

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

func GetProvider(typ string) (Provider, error)

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

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

func Execute(ctx context.Context, p Profile, params ...map[string]any) (*Result, error)

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`.

func (*Result) Render added in v0.1.13

func (r *Result) Render(columns []ColumnDef, format string) (string, error)

Render formats the Result in the given clicky format (e.g. "table", "csv", "json", "xlsx", "html").

func (*Result) Table added in v0.1.13

func (r *Result) Table(columns []ColumnDef) api.TextTable

Table builds a clicky TextTable from the Result. When columns is empty, the columns are derived from the union of row keys (sorted for determinism).

type Row added in v0.1.13

type Row = map[string]any

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.

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:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL