sq/libsq/ast/handle.go
Neil O'Toole db55986980
#307: Ingest cache (#354)
- Support for ingest cache, download cache, and progress bars.
2024-01-14 18:45:34 -07:00

82 lines
1.8 KiB
Go

package ast
import (
"slices"
"github.com/samber/lo"
"github.com/neilotoole/sq/libsq/ast/internal/slq"
"github.com/neilotoole/sq/libsq/core/tablefq"
)
// HandleNode models a source handle such as "@sakila".
type HandleNode struct {
baseNode
}
// Handle returns the handle value, e.g. "@sakila".
func (d *HandleNode) Handle() string {
return d.text
}
// String returns a log/debug-friendly representation.
func (d *HandleNode) String() string {
return nodeString(d)
}
// VisitHandle implements slq.SLQVisitor.
func (v *parseTreeVisitor) VisitHandle(ctx *slq.HandleContext) any {
node := &HandleNode{}
node.text = ctx.GetText()
node.parent = v.cur
node.ctx = ctx.HANDLE()
return v.cur.AddChild(node)
}
// VisitHandleTable implements slq.SLQVisitor.
func (v *parseTreeVisitor) VisitHandleTable(ctx *slq.HandleTableContext) any {
node := &TblSelectorNode{}
node.parent = v.cur
node.ctx = ctx
node.text = ctx.GetText()
node.handle = ctx.HANDLE().GetText()
var err error
selTbl, err := extractSelVal(ctx.NAME())
if err != nil {
return err
}
node.tbl = tablefq.From(selTbl)
return v.cur.AddChild(node)
}
// ExtractHandles returns a sorted slice of all handles mentioned
// in the AST. Duplicate mentions are removed.
func ExtractHandles(ast *AST) []string {
var handles []string
handleNodes := FindNodes[*HandleNode](ast)
for _, n := range handleNodes {
handles = append(handles, n.Handle())
}
joinNodes := FindNodes[*JoinNode](ast)
for _, n := range joinNodes {
if n != nil && n.Table().Handle() != "" {
handles = append(handles, n.Table().Handle())
}
}
tblSelNodes := FindNodes[*TblSelectorNode](ast)
for _, n := range tblSelNodes {
if n.Handle() != "" {
handles = append(handles, n.Handle())
}
}
handles = lo.Uniq(handles)
slices.Sort(handles)
return handles
}