diff --git a/pkg/adapter/types.go b/pkg/adapter/types.go index d9869de..dd46e54 100644 --- a/pkg/adapter/types.go +++ b/pkg/adapter/types.go @@ -15,3 +15,8 @@ type Dialect interface { GetColumnName(key string) string NormalizeValue(interface{}) interface{} } + +var DIALECTS = map[string]Dialect{ + "sqlite3": SQLite{}, + "sqlite": SQLite{}, +} diff --git a/pkg/proto/request.go b/pkg/proto/request.go index 29d6cbd..214750c 100644 --- a/pkg/proto/request.go +++ b/pkg/proto/request.go @@ -26,11 +26,17 @@ type Request struct { var allowedMethods = strings.Split(builder.BUILDER_CLIENT_METHODS, "|") 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) for _, cmd := range q.Commands { if !slices.Contains(allowedMethods, cmd.Method) { 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, allowedMethods, ) diff --git a/pkg/server/go.mod b/pkg/server/go.mod index 1d2f90d..6e16d41 100644 --- a/pkg/server/go.mod +++ b/pkg/server/go.mod @@ -1,3 +1,25 @@ module l12.xyz/dal/server 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 +) diff --git a/pkg/server/go.sum b/pkg/server/go.sum new file mode 100644 index 0000000..0faa69d --- /dev/null +++ b/pkg/server/go.sum @@ -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= diff --git a/pkg/server/handler.go b/pkg/server/handler.go new file mode 100644 index 0000000..6fbb668 --- /dev/null +++ b/pkg/server/handler.go @@ -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) + } + }) +} diff --git a/pkg/server/handler_test.go b/pkg/server/handler_test.go new file mode 100644 index 0000000..52cb105 --- /dev/null +++ b/pkg/server/handler_test.go @@ -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) +}