From 7de883b8c0f34f7b3e94bb40d964ec87aa9f1713 Mon Sep 17 00:00:00 2001 From: Evstigneev Denis Date: Fri, 11 Aug 2023 16:24:16 +0300 Subject: [PATCH] add storage sqlite GetModule with save ineq --- handler/handlers.go | 40 ++++++++++++++++++++++++++++---- storage/sqlite/quries.go | 4 ++++ storage/sqlite/storage.go | 48 +++++++++++++++++++++++++++++++++++++++ storage/storage.go | 1 + storage/storage_test.go | 42 ++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 storage/storage_test.go diff --git a/handler/handlers.go b/handler/handlers.go index a9cbfc4..c39bf0b 100644 --- a/handler/handlers.go +++ b/handler/handlers.go @@ -2,9 +2,7 @@ package handler import ( "context" - "io" - "net/http" - + "encoding/json" cmsstorage "go.unistack.org/cms-service/storage" "go.unistack.org/micro/v3" "go.unistack.org/micro/v3/errors" @@ -13,6 +11,10 @@ import ( cligit "go.unistack.org/unistack-org/pkgdash/service/client_git" "go.unistack.org/unistack-org/pkgdash/storage" "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" + "io" + "net/http" + "net/url" ) type Handler struct { @@ -156,7 +158,37 @@ func (h *Handler) GetModule(w http.ResponseWriter, r *http.Request) { logger := h.svc.Logger() logger.Debug(ctx, "Start GetModule") - //rsp := new(pb.GetModuleRsp) + req := new(pb.GetModuleReq) + if err := h.URLValuesToProto(r.URL.Query(), req); err != nil { + logger.Errorf(ctx, "Required parameter missing: %v", err) + h.writer.Response(ctx, w, err) + return + } + +} + +func (h *Handler) URLValuesToProto(vals url.Values, msg proto.Message) error { + params := make(map[string]interface{}) + var err error + for k, v := range vals { + if len(v) == 0 { + continue + } + switch k { + case "id": + params[k] = v + default: + params[k] = v[0] + } + } + b, err := json.Marshal(params) + if err != nil { + return NewUnmarshalError(err) + } + if err = h.Unmarshal(b, msg); err != nil { + return NewUnmarshalError(err) + } + return nil } func NewHandler(svc micro.Service, w writer, client cligit.Client) *Handler { diff --git a/storage/sqlite/quries.go b/storage/sqlite/quries.go index df92c68..2b6922b 100644 --- a/storage/sqlite/quries.go +++ b/storage/sqlite/quries.go @@ -24,5 +24,9 @@ insert into package(name, url, modules) values ($1, $2, $3); insert into module(name, version, last_version) values %s returning id; +` + queryGetModule = ` +select id, name, version, last_version from module +where id in %s ; ` ) diff --git a/storage/sqlite/storage.go b/storage/sqlite/storage.go index 1b2f140..db09ca0 100644 --- a/storage/sqlite/storage.go +++ b/storage/sqlite/storage.go @@ -225,6 +225,50 @@ func (s *Sqlite) InsertButchModules(ctx context.Context, req []models.Module) ([ return result, err } +func (s *Sqlite) GetModule(ctx context.Context, req *pb.GetModuleReq) (result []models.Module, err error) { + query := "" + if len(req.ModulesId) < 1 { + query = fmt.Sprintf(queryGetModule, "() or 1=1") + } else { + query = fmt.Sprintf(queryGetModule, generateArrayIneq(len(req.GetModulesId()))) + } + + rows, err := s.db.QueryContext(ctx, query, convertSliceUInt(req.ModulesId...)...) + if err != nil { + return nil, err + } + defer func() { + if err = rows.Close(); err != nil { + return + } + err = rows.Err() + }() + + for rows.Next() { + tmp := models.Module{} + if err = rows.Scan( + &tmp.ID, + &tmp.Name, + &tmp.Version, + &tmp.LastVersion, + ); err != nil { + return nil, err + } + + result = append(result, tmp) + } + + return result, err +} + +func convertSliceUInt(arg ...uint64) []interface{} { + result := make([]interface{}, 0, len(arg)) + for i := range arg { + result = append(result, arg[i]) + } + return result +} + func generateQuery(rsp []models.Module) string { const pattern = `%c('%s', '%s', '%s')` build := strings.Builder{} @@ -237,3 +281,7 @@ func generateQuery(rsp []models.Module) string { return fmt.Sprintf(queryInsMsgGetIDs, build.String()) } + +func generateArrayIneq(count int) string { + return "(?" + strings.Repeat(",?", count-1) + ")" +} diff --git a/storage/storage.go b/storage/storage.go index 7d93511..255e60f 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -32,6 +32,7 @@ type Storage interface { AddComment(ctx context.Context, req *pb.AddCommentReq) error AddPackage(ctx context.Context, req *pb.AddPackageReq) error InsertButchModules(ctx context.Context, req []models.Module) ([]uint64, error) + GetModule(ctx context.Context, req *pb.GetModuleReq) ([]models.Module, error) } func NewStorage(name string, db *sql.DB) (interface{}, error) { diff --git a/storage/storage_test.go b/storage/storage_test.go new file mode 100644 index 0000000..6ae3572 --- /dev/null +++ b/storage/storage_test.go @@ -0,0 +1,42 @@ +package storage + +import ( + "context" + "database/sql" + "fmt" + pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate" + "go.unistack.org/unistack-org/pkgdash/storage/sqlite" + "testing" +) + +func TestGetModule(t *testing.T) { + conn, err := sql.Open("sqlite3", "/Users/devstigneev_local/GolandProjects/unistack/pkgdash/identifier.sqlite") + if err != nil { + t.Fatal(err) + } + defer conn.Close() + if err = conn.Ping(); err != nil { + t.Fatal(err) + } + + st, err := sqlite.NewStorage(conn) + if err != nil { + t.Fatal(err) + } + + s, ok := st.(Storage) + if !ok { + t.Fatal("typecast error") + } + + req := &pb.GetModuleReq{ + ModulesId: []uint64{1, 2, 5, 40}, + } + + module, err := s.GetModule(context.Background(), req) + if err != nil { + t.Fatal(err) + } + + fmt.Println(module) +}