mirror of
https://github.com/boolean-maybe/tiki
synced 2026-04-21 13:37:20 +00:00
225 lines
5.5 KiB
Go
225 lines
5.5 KiB
Go
package ruki
|
|
|
|
import "time"
|
|
|
|
// --- top-level union types ---
|
|
|
|
// Statement is the result of parsing a CRUD command.
|
|
// Exactly one variant is non-nil.
|
|
type Statement struct {
|
|
Select *SelectStmt
|
|
Create *CreateStmt
|
|
Update *UpdateStmt
|
|
Delete *DeleteStmt
|
|
}
|
|
|
|
// SelectStmt represents "select [fields] [where <condition>] [order by <field> [asc|desc], ...] [| run(...) | clipboard()]".
|
|
type SelectStmt struct {
|
|
Fields []string // nil = all ("select" or "select *"); non-nil = specific fields
|
|
Where Condition // nil = select all
|
|
OrderBy []OrderByClause // nil = unordered
|
|
Pipe *PipeAction // optional pipe suffix: "| run(...)" or "| clipboard()"
|
|
}
|
|
|
|
// PipeAction is a discriminated union for pipe targets.
|
|
// Exactly one variant is non-nil.
|
|
type PipeAction struct {
|
|
Run *RunAction
|
|
Clipboard *ClipboardAction
|
|
}
|
|
|
|
// ClipboardAction represents "clipboard()" as a pipe target.
|
|
type ClipboardAction struct{}
|
|
|
|
// CreateStmt represents "create <field>=<value>...".
|
|
type CreateStmt struct {
|
|
Assignments []Assignment
|
|
}
|
|
|
|
// UpdateStmt represents "update where <condition> set <field>=<value>...".
|
|
type UpdateStmt struct {
|
|
Where Condition
|
|
Set []Assignment
|
|
}
|
|
|
|
// DeleteStmt represents "delete where <condition>".
|
|
type DeleteStmt struct {
|
|
Where Condition
|
|
}
|
|
|
|
// --- triggers ---
|
|
|
|
// Trigger is the result of parsing a reactive rule.
|
|
type Trigger struct {
|
|
Timing string // "before" or "after"
|
|
Event string // "create", "update", or "delete"
|
|
Where Condition // optional guard (nil if omitted)
|
|
Action *Statement // after-triggers only (create/update/delete, not select)
|
|
Run *RunAction // after-triggers only (alternative to Action)
|
|
Deny *string // before-triggers only
|
|
}
|
|
|
|
// RunAction represents "run(<string-expr>)" as a top-level trigger action.
|
|
type RunAction struct {
|
|
Command Expr
|
|
}
|
|
|
|
// TimeTrigger is the result of parsing a periodic time trigger.
|
|
// It wraps a mutating statement (create, update, or delete) with a schedule interval.
|
|
type TimeTrigger struct {
|
|
Interval DurationLiteral // e.g. {1, "hour"}, {1, "day"}
|
|
Action *Statement // create, update, or delete (never select)
|
|
}
|
|
|
|
// Rule is the result of parsing a trigger definition.
|
|
// Exactly one variant is non-nil.
|
|
type Rule struct {
|
|
Trigger *Trigger
|
|
TimeTrigger *TimeTrigger
|
|
}
|
|
|
|
// --- conditions ---
|
|
|
|
// Condition is the interface for all boolean condition nodes.
|
|
type Condition interface {
|
|
conditionNode()
|
|
}
|
|
|
|
// BinaryCondition represents "<condition> and/or <condition>".
|
|
type BinaryCondition struct {
|
|
Op string // "and" or "or"
|
|
Left Condition
|
|
Right Condition
|
|
}
|
|
|
|
// NotCondition represents "not <condition>".
|
|
type NotCondition struct {
|
|
Inner Condition
|
|
}
|
|
|
|
// CompareExpr represents "<expr> <op> <expr>".
|
|
type CompareExpr struct {
|
|
Left Expr
|
|
Op string // "=", "!=", "<", ">", "<=", ">="
|
|
Right Expr
|
|
}
|
|
|
|
// IsEmptyExpr represents "<expr> is [not] empty".
|
|
type IsEmptyExpr struct {
|
|
Expr Expr
|
|
Negated bool // true = "is not empty"
|
|
}
|
|
|
|
// InExpr represents "<value> [not] in <collection>".
|
|
type InExpr struct {
|
|
Value Expr
|
|
Collection Expr
|
|
Negated bool // true = "not in"
|
|
}
|
|
|
|
// QuantifierExpr represents "<expr> any/all <condition>".
|
|
type QuantifierExpr struct {
|
|
Expr Expr
|
|
Kind string // "any" or "all"
|
|
Condition Condition
|
|
}
|
|
|
|
func (*BinaryCondition) conditionNode() {}
|
|
func (*NotCondition) conditionNode() {}
|
|
func (*CompareExpr) conditionNode() {}
|
|
func (*IsEmptyExpr) conditionNode() {}
|
|
func (*InExpr) conditionNode() {}
|
|
func (*QuantifierExpr) conditionNode() {}
|
|
|
|
// --- expressions ---
|
|
|
|
// Expr is the interface for all expression nodes.
|
|
type Expr interface {
|
|
exprNode()
|
|
}
|
|
|
|
// FieldRef represents a bare field name like "status" or "priority".
|
|
type FieldRef struct {
|
|
Name string
|
|
}
|
|
|
|
// QualifiedRef represents "old.field" or "new.field".
|
|
type QualifiedRef struct {
|
|
Qualifier string // "old" or "new"
|
|
Name string
|
|
}
|
|
|
|
// StringLiteral represents a double-quoted string value.
|
|
type StringLiteral struct {
|
|
Value string
|
|
}
|
|
|
|
// IntLiteral represents an integer value.
|
|
type IntLiteral struct {
|
|
Value int
|
|
}
|
|
|
|
// DateLiteral represents a YYYY-MM-DD date.
|
|
type DateLiteral struct {
|
|
Value time.Time
|
|
}
|
|
|
|
// DurationLiteral represents a number+unit like "2day" or "1week".
|
|
type DurationLiteral struct {
|
|
Value int
|
|
Unit string
|
|
}
|
|
|
|
// ListLiteral represents ["a", "b", ...].
|
|
type ListLiteral struct {
|
|
Elements []Expr
|
|
}
|
|
|
|
// EmptyLiteral represents the "empty" keyword.
|
|
type EmptyLiteral struct{}
|
|
|
|
// FunctionCall represents "name(args...)".
|
|
type FunctionCall struct {
|
|
Name string
|
|
Args []Expr
|
|
}
|
|
|
|
// BinaryExpr represents "<expr> +/- <expr>".
|
|
type BinaryExpr struct {
|
|
Op string // "+" or "-"
|
|
Left Expr
|
|
Right Expr
|
|
}
|
|
|
|
// SubQuery represents "select [where <condition>]" used inside count().
|
|
type SubQuery struct {
|
|
Where Condition // nil = select all
|
|
}
|
|
|
|
func (*FieldRef) exprNode() {}
|
|
func (*QualifiedRef) exprNode() {}
|
|
func (*StringLiteral) exprNode() {}
|
|
func (*IntLiteral) exprNode() {}
|
|
func (*DateLiteral) exprNode() {}
|
|
func (*DurationLiteral) exprNode() {}
|
|
func (*ListLiteral) exprNode() {}
|
|
func (*EmptyLiteral) exprNode() {}
|
|
func (*FunctionCall) exprNode() {}
|
|
func (*BinaryExpr) exprNode() {}
|
|
func (*SubQuery) exprNode() {}
|
|
|
|
// --- order by ---
|
|
|
|
// OrderByClause represents a single sort criterion in "order by <field> [asc|desc]".
|
|
type OrderByClause struct {
|
|
Field string // field name
|
|
Desc bool // true = descending, false = ascending (default)
|
|
}
|
|
|
|
// --- assignments ---
|
|
|
|
// Assignment represents "field=value" in create/update statements.
|
|
type Assignment struct {
|
|
Field string
|
|
Value Expr
|
|
}
|