From d67596acd921f75caaa4e604bc1ccf163bd0729e Mon Sep 17 00:00:00 2001 From: JP Appel Date: Wed, 2 Jul 2025 02:11:26 -0400 Subject: Add experimental http server --- pkg/query/query.go | 20 +++++++++++++++- pkg/server/server.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 pkg/server/server.go (limited to 'pkg') diff --git a/pkg/query/query.go b/pkg/query/query.go index 57ba3e1..3552c3f 100644 --- a/pkg/query/query.go +++ b/pkg/query/query.go @@ -1,9 +1,27 @@ package query -import "strings" +import ( + "fmt" + "strings" +) func writeIndent(b *strings.Builder, level int) { for range level { b.WriteByte('\t') } } + +func Compile(userQuery string, optimizationLevel int, numWorkers uint) (CompilationArtifact, error) { + if numWorkers == 0 { + return CompilationArtifact{}, fmt.Errorf("Cannot compile with 0 workers") + } + + clause, err := Parse(Lex(userQuery)) + if err != nil { + return CompilationArtifact{}, err + } + + NewOptimizer(clause, numWorkers).Optimize(optimizationLevel) + + return clause.Compile() +} diff --git a/pkg/server/server.go b/pkg/server/server.go new file mode 100644 index 0000000..8b66e62 --- /dev/null +++ b/pkg/server/server.go @@ -0,0 +1,67 @@ +package server + +import ( + "bytes" + "io" + "log/slog" + "net/http" + "strings" + + "github.com/jpappel/atlas/pkg/data" + "github.com/jpappel/atlas/pkg/index" + "github.com/jpappel/atlas/pkg/query" +) + +func info(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` +

Atlas Server

+

This is the experimental atlas server! + Try POSTing a query to

/search

+ `)) +} + +func New(db *data.Query) *http.ServeMux { + mux := http.NewServeMux() + + mux.HandleFunc("/", info) + mux.HandleFunc("/search", func(w http.ResponseWriter, r *http.Request) { + b := &strings.Builder{} + if _, err := io.Copy(b, r.Body); err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte("Error processing request")) + slog.Error("Error reading request body", slog.String("err", err.Error())) + return + } + artifact, err := query.Compile(b.String(), 0, 1) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + slog.Error("Error compiling query", slog.String("err", err.Error())) + return + } + + pathDocs, err := db.Execute(artifact) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte("Error executing query")) + slog.Error("Error executing query", slog.String("err", err.Error())) + return + } + docs := make([]*index.Document, 0, len(pathDocs)) + for _, doc := range pathDocs { + docs = append(docs, doc) + } + + var buf bytes.Buffer + _, err = query.JsonOutput{}.OutputTo(&buf, docs) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte("Error while writing output")) + slog.Error("Error writing json output", slog.String("err", err.Error())) + } + + io.Copy(w, &buf) + }) + + return mux +} -- cgit v1.2.3