From a4d86693394ba9b181b5928c1c6e8c31c9bb2b64 Mon Sep 17 00:00:00 2001 From: JP Appel Date: Mon, 30 Jun 2025 17:18:45 -0400 Subject: Implement compiled query execution --- cmd/query.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 cmd/query.go (limited to 'cmd/query.go') diff --git a/cmd/query.go b/cmd/query.go new file mode 100644 index 0000000..40c9e58 --- /dev/null +++ b/cmd/query.go @@ -0,0 +1,84 @@ +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/jpappel/atlas/pkg/data" + "github.com/jpappel/atlas/pkg/index" + "github.com/jpappel/atlas/pkg/query" +) + +type QueryFlags struct { + Outputer query.Outputer + CustomFormat string + OptimizationLevel int +} + +func setupQueryFlags(args []string, fs *flag.FlagSet, flags *QueryFlags) { + // NOTE: providing `-outFormat` before `-outCustomFormat` might ignore user specified format + fs.Func("outFormat", "output `format` for queries (default, json, custom)", + func(arg string) error { + switch arg { + case "default": + flags.Outputer = query.DefaultOutput{} + return nil + case "json": + flags.Outputer = query.JsonOutput{} + return nil + case "custom": + var err error + flags.Outputer, err = query.NewCustomOutput(flags.CustomFormat, dateFormat) + return err + } + return fmt.Errorf("Unrecognized output format: %s", arg) + }) + fs.StringVar(&flags.CustomFormat, "outCustomFormat", query.DefaultOutputFormat, "format string for --outFormat custom, see EXAMPLES for more details") + fs.IntVar(&flags.OptimizationLevel, "optLevel", 0, "optimization `level` for queries, 0 is automatic, <0 to disable") + + fs.Parse(args[1:]) +} + +func runQuery(gFlags GlobalFlags, qFlags QueryFlags, db *data.Query, searchQuery string) byte { + tokens := query.Lex(searchQuery) + clause, err := query.Parse(tokens) + if err != nil { + fmt.Fprintln(os.Stderr, "Failed to parse query: ", err) + return 1 + } + + o := query.NewOptimizer(clause, gFlags.NumWorkers) + o.Optimize(qFlags.OptimizationLevel) + + artifact, err := clause.Compile() + if err != nil { + fmt.Fprintln(os.Stderr, "Failed to compile query: ", err) + return 1 + } + + results, err := db.Execute(artifact) + if err != nil { + fmt.Fprintln(os.Stderr, "Failed to execute query: ", err) + return 1 + } + + if len(results) == 0 { + fmt.Println("No results.") + return 0 + } + + outputableResults := make([]*index.Document, 0, len(results)) + for _, v := range results { + outputableResults = append(outputableResults, v) + } + + s, err := qFlags.Outputer.Output(outputableResults) + if err != nil { + fmt.Fprintln(os.Stderr, "Failed to output results: ", err) + return 1 + } + + fmt.Println(s) + return 0 +} -- cgit v1.2.3