111 lines
2.2 KiB
Go

package main
import (
"context"
"encoding/json"
"fmt"
"io"
"os"
//"github.com/DataDog/go-sqllexer"
"log"
"net/http"
"query-inter/q"
"time"
)
func main() {
//selectQuery := "SELECT MIN(Price) AS SmallestPrice, CategoryID FROM Products GROUP BY CategoryID;"
PORT := os.Getenv("PORT")
if PORT == "" {
log.Panicln("PORT could not be read from env")
}
StartServer(PORT)
//allStatements := q.ExtractSqlStatmentsFromString(selectQuery)
//fmt.Println(allStatements)
//lexer := sqllexer.New(selectQuery)
//for {
// token := lexer.Scan()
// fmt.Println(token.Value, token.Type)
//
// if token.Type == sqllexer.EOF {
// break
// }
//}
//for _, sql := range allStatements {
//query := q.ParseSelectStatement(sql)
//fmt.Print(i)
//fmt.Println(query)
//fmt.Println(query.GetFullSql())
//}
}
func StartServer(port string) {
http.HandleFunc("/query", HandlePostQuery)
fmt.Println("Starting Server on 8080")
fmt.Println("call POST /query with { sql: string }")
log.Fatal(http.ListenAndServe(":"+port, nil))
}
type QueryRequest struct {
SQL string `json:"sql"`
}
func HandlePostQuery(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Error reading request body", http.StatusBadRequest)
return
}
defer r.Body.Close()
var request QueryRequest
err = json.Unmarshal(body, &request)
if err != nil {
http.Error(w, "Error parsing JSON: "+string(body), http.StatusBadRequest)
return
}
ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second)
defer cancel()
var query q.Query
done := make(chan struct{})
go func() {
defer cancel()
query, err = q.Parse(request.SQL)
done <- struct{}{}
}()
select {
case <-done:
// Proceed
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) // Set the HTTP status code
jsonData, err := q.MarshalSelect(query)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_, err = w.Write(jsonData)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
case <-ctx.Done():
http.Error(w, "Request timed out", http.StatusRequestTimeout)
return
}
}