add handlers, storage(Postgres, sqlite) #3

Merged
vtolstov merged 12 commits from devstigneev/pkgdash:master into master 2023-08-11 20:12:16 +03:00
5 changed files with 131 additions and 4 deletions
Showing only changes of commit 7de883b8c0 - Show all commits

View File

@ -2,9 +2,7 @@ package handler
import ( import (
"context" "context"
"io" "encoding/json"
"net/http"
cmsstorage "go.unistack.org/cms-service/storage" cmsstorage "go.unistack.org/cms-service/storage"
"go.unistack.org/micro/v3" "go.unistack.org/micro/v3"
"go.unistack.org/micro/v3/errors" "go.unistack.org/micro/v3/errors"
@ -13,6 +11,10 @@ import (
cligit "go.unistack.org/unistack-org/pkgdash/service/client_git" cligit "go.unistack.org/unistack-org/pkgdash/service/client_git"
"go.unistack.org/unistack-org/pkgdash/storage" "go.unistack.org/unistack-org/pkgdash/storage"
"google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"io"
"net/http"
"net/url"
) )
type Handler struct { type Handler struct {
@ -156,7 +158,37 @@ func (h *Handler) GetModule(w http.ResponseWriter, r *http.Request) {
logger := h.svc.Logger() logger := h.svc.Logger()
logger.Debug(ctx, "Start GetModule") 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 { func NewHandler(svc micro.Service, w writer, client cligit.Client) *Handler {

View File

@ -24,5 +24,9 @@ insert into package(name, url, modules) values ($1, $2, $3);
insert into module(name, version, last_version) values insert into module(name, version, last_version) values
%s %s
returning id; returning id;
`
queryGetModule = `
select id, name, version, last_version from module
where id in %s ;
` `
) )

View File

@ -225,6 +225,50 @@ func (s *Sqlite) InsertButchModules(ctx context.Context, req []models.Module) ([
return result, err 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 { func generateQuery(rsp []models.Module) string {
const pattern = `%c('%s', '%s', '%s')` const pattern = `%c('%s', '%s', '%s')`
build := strings.Builder{} build := strings.Builder{}
@ -237,3 +281,7 @@ func generateQuery(rsp []models.Module) string {
return fmt.Sprintf(queryInsMsgGetIDs, build.String()) return fmt.Sprintf(queryInsMsgGetIDs, build.String())
} }
func generateArrayIneq(count int) string {
return "(?" + strings.Repeat(",?", count-1) + ")"
}

View File

@ -32,6 +32,7 @@ type Storage interface {
AddComment(ctx context.Context, req *pb.AddCommentReq) error AddComment(ctx context.Context, req *pb.AddCommentReq) error
AddPackage(ctx context.Context, req *pb.AddPackageReq) error AddPackage(ctx context.Context, req *pb.AddPackageReq) error
InsertButchModules(ctx context.Context, req []models.Module) ([]uint64, 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) { func NewStorage(name string, db *sql.DB) (interface{}, error) {

42
storage/storage_test.go Normal file
View File

@ -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)
}