[wip] server

Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
Anton Nesterov 2024-08-14 14:02:20 +02:00
parent 476afeac50
commit 8fd9a369d1
No known key found for this signature in database
GPG key ID: 59121E8AE2851FB5
6 changed files with 122 additions and 1 deletions

View file

@ -15,3 +15,8 @@ type Dialect interface {
GetColumnName(key string) string GetColumnName(key string) string
NormalizeValue(interface{}) interface{} NormalizeValue(interface{}) interface{}
} }
var DIALECTS = map[string]Dialect{
"sqlite3": SQLite{},
"sqlite": SQLite{},
}

View file

@ -26,11 +26,17 @@ type Request struct {
var allowedMethods = strings.Split(builder.BUILDER_CLIENT_METHODS, "|") var allowedMethods = strings.Split(builder.BUILDER_CLIENT_METHODS, "|")
func (q *Request) Parse(dialect adapter.Dialect) (adapter.Query, error) { func (q *Request) Parse(dialect adapter.Dialect) (adapter.Query, error) {
if q.Db == "" {
return adapter.Query{}, fmt.Errorf("Request format: db url is required")
}
if len(q.Commands) == 0 {
return adapter.Query{}, fmt.Errorf("Request format: commands are required")
}
b := builder.New(dialect) b := builder.New(dialect)
for _, cmd := range q.Commands { for _, cmd := range q.Commands {
if !slices.Contains(allowedMethods, cmd.Method) { if !slices.Contains(allowedMethods, cmd.Method) {
return adapter.Query{}, fmt.Errorf( return adapter.Query{}, fmt.Errorf(
"method %s is not allowed, awailable methods are %v", "method %s is not allowed, available methods are %v",
cmd.Method, cmd.Method,
allowedMethods, allowedMethods,
) )

View file

@ -1,3 +1,25 @@
module l12.xyz/dal/server module l12.xyz/dal/server
go 1.22.6 go 1.22.6
replace l12.xyz/dal/filters v0.0.0 => ../filters
replace l12.xyz/dal/builder v0.0.0 => ../builder
replace l12.xyz/dal/adapter v0.0.0 => ../adapter
replace l12.xyz/dal/utils v0.0.0 => ../utils
require l12.xyz/dal/proto v0.0.0
replace l12.xyz/dal/proto v0.0.0 => ../proto
require (
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/tinylib/msgp v1.2.0 // indirect
l12.xyz/dal/adapter v0.0.0 // indirect
l12.xyz/dal/builder v0.0.0 // indirect
l12.xyz/dal/filters v0.0.0 // indirect
l12.xyz/dal/utils v0.0.0 // indirect
)

6
pkg/server/go.sum Normal file
View file

@ -0,0 +1,6 @@
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 h1:jYi87L8j62qkXzaYHAQAhEapgukhenIMZRBKTNRLHJ4=
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/tinylib/msgp v1.2.0 h1:0uKB/662twsVBpYUPbokj4sTSKhWFKB7LopO2kWK8lY=
github.com/tinylib/msgp v1.2.0/go.mod h1:2vIGs3lcUo8izAATNobrCHevYZC/LMsJtw4JPiYPHro=

55
pkg/server/handler.go Normal file
View file

@ -0,0 +1,55 @@
package server
import (
"fmt"
"io"
"net/http"
"l12.xyz/dal/adapter"
"l12.xyz/dal/proto"
)
func QueryHandler(db adapter.DBAdapter) http.Handler {
dialect, ok := adapter.DIALECTS[db.Type]
if !ok {
panic(fmt.Errorf("dialect %s not found", db.Type))
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
bodyReader, err := r.GetBody()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
body, err := io.ReadAll(bodyReader)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
req := proto.Request{}
req.UnmarshalMsg(body)
query, err := req.Parse(dialect)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Println(query, "QueryHandler")
rows, err := db.Query(query)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/x-msgpack")
defer rows.Close()
for rows.Next() {
row := []byte{}
rows.Scan(row)
w.Write(row)
}
})
}

View file

@ -0,0 +1,27 @@
package server
import (
"bytes"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"l12.xyz/dal/adapter"
)
func TestQueryHandler(t *testing.T) {
body := []byte(`{
"something": "wrong",
}`)
req, err := http.NewRequest("POST", "/", bytes.NewBuffer(body))
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler := QueryHandler(adapter.DBAdapter{
Type: "sqlite3",
})
handler.ServeHTTP(rr, req)
fmt.Println(rr.Code == 400)
}