Browse Source

set params in context

EUGENIO SOUZA CARVALHO 4 years ago
parent
commit
1b63f07a93

+ 7 - 5
api/mongo.go

@@ -80,6 +80,7 @@ type Mongo struct {
 	// Addrs    string `json:"addrs"`
 	subject *BehaviorSubjectStruct
 	client  *mongo.Client
+	Credential *options.Credential
 	Config  string `json:"config"`
 	Clients map[string]*mongo.Client
 }
@@ -169,11 +170,15 @@ func (t *Mongo) Ready() *BehaviorSubjectStruct {
 }
 
 func (t *Mongo) Init() (err error) {
-	var ()
 
 	fmt.Printf("Connection string '%s'", t.Config)
+	clientOpts := options.Client().ApplyURI(t.Config)
 
-	if t.client, err = mongo.NewClient(options.Client().ApplyURI(t.Config)); err != nil {
+	if t.Credential != nil {
+		clientOpts.SetAuth(*t.Credential)
+	}
+	// if t.client, err = mongo.NewClient(setOptions); err != nil {
+	if t.client, err = mongo.Connect(context.TODO(), clientOpts); err != nil {
 		return
 	}
 
@@ -707,11 +712,8 @@ func (t *Mongo) FindMany(f *Filter) (cursor *mongo.Cursor, err *errs.Error) {
 			}
 
 			slicev := entitiesValue.Elem()
-			// fmt.Println("aaaaaaa000000000000001")
 			slicev = slicev.Slice(0, slicev.Cap())
-			// fmt.Println("aaaaaaa000000000000002")
 			typ := slicev.Type().Elem()
-			// fmt.Println("aaaaaaa000000000000003")
 
 			for cursor.Next(ctx) {
 

+ 6 - 3
api/sse/hub.go

@@ -2,6 +2,7 @@ package sse
 
 import (
 	"encoding/json"
+	"fmt"
 	"net/http"
 	"time"
 
@@ -251,7 +252,7 @@ reset:
 	for {
 		select {
 		case <-ticker5Second.C:
-			// ctx.Application().Logger().Warnf("init.notification.loop 5s")
+			ctx.Application().Logger().Warnf("init.notification.loop 5s")
 
 			if count, redisErr = redis.Int(conn.Do("LLEN", channelId)); count == 0 || redisErr != nil {
 				continue reset
@@ -260,17 +261,19 @@ reset:
 			for ; count > 0; count-- {
 
 				if payload, redisErr = redis.String(conn.Do("LPOP", channelId)); redisErr != nil {
-					// ctx.Application().Logger().Errorf("NotificationError:", redisErr)
+					ctx.Application().Logger().Errorf("NotificationError:", redisErr)
 				} else {
 					event := &Event{}
 					json.Unmarshal([]byte(payload), event)
+
+					fmt.Println("emit event ", event)
 					channel.Emit(event)
 					break
 				}
 			}
 
 		case <-finalizeMain:
-			// ctx.Application().Logger().Infof("notification.finalize.disconect(%s)", channelId)
+			ctx.Application().Logger().Infof("notification.finalize.disconect(%s)", channelId)
 			close(finalizeMain)
 			return
 		}

+ 6 - 4
common/models.go

@@ -235,6 +235,7 @@ type Method struct {
 	Parameters          map[string]*Parameter  `json:"parametersmap"`
 	Preconditions       []Action               `json:"preconditions"`
 	BeforeResponse      []Action               `json:"beforeResponse"`
+	BeforeParseRequest  []Action               `json:"beforeParseRequest"`
 	Custom              map[string]interface{} `json:"custom"`
 	// Parameters     map[string]*Parameter `json:"parameters"`
 }
@@ -287,6 +288,7 @@ type Propertie struct {
 	Autogenerate      map[string]AutoGenDef  `json:"-"`
 	Targets           string                 `json:"targets"`
 	Array             bool                   `json:"array"`
+	Required          bool                   `json:"required"`
 	Relation          bool                   `json:"relation"`
 	TagVisited        bool                   `json:"-"`
 	Reference         bool                   `json:"reference"`
@@ -374,14 +376,14 @@ func RequestParams(args string, params map[string]*Parameter) func(ctx context.C
 				return nil, invalidArgument
 			}
 
-			if !emptyValue && param.ConvertTo != ""  {
+			if !emptyValue && param.ConvertTo != "" {
 				if value, err = convertValueByType(param.ConvertTo, value); err != nil {
 					invalidArgument := errs.InvalidArgument()
 					invalidArgument.Message = fmt.Sprintf(
-						"ParamTypeConversionError: param '%s' in '%s' with value '%v'. Waiting a %s ", 
+						"ParamTypeConversionError: param '%s' in '%s' with value '%v'. Waiting a %s ",
 						param.ID,
 						param.Location,
-						value, 
+						value,
 						param.ConvertTo,
 					)
 					return nil, invalidArgument
@@ -418,7 +420,7 @@ var (
 		"number":   stringToFloat,
 	}
 
-	validationParamFunctions = map[string]func(*Parameter,interface{}, interface{}) *errs.Error{
+	validationParamFunctions = map[string]func(*Parameter, interface{}, interface{}) *errs.Error{
 		"min": func(param *Parameter, value interface{}, minString interface{}) *errs.Error {
 			var input float64
 

+ 167 - 0
translate/got/middleware_pipe.go

@@ -0,0 +1,167 @@
+package got
+
+import (
+	"text/template"
+
+	. "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/common"
+	G "github.com/dave/jennifer/jen"
+)
+
+var (
+	pipeStmtsTmpl *template.Template
+	pipeStmtsErr  error
+)
+
+func init() {
+
+	pipeStmtsTmpl, pipeStmtsErr = ParseTemplate(`
+	{{if .preconditions}}
+		if resp, err = executeAction(
+			ctx,
+			{{.preconditions}},
+		); err != nil {
+			return
+		}
+	{{end}}
+	return`)
+
+	if pipeStmtsErr != nil {
+		panic(pipeStmtsErr)
+	}
+}
+
+var (
+	GenPipeStmts = &Middleware{
+		Id:   "post",
+		Type: "method",
+		Fn: func(ctx *MiddlewareContext) error {
+
+			var (
+				method  = ctx.Method
+				context = map[string]interface{}{
+					"preconditions": parseMethodActions(method.Preconditions),
+				}
+			)
+			// Nome do metodo que verifica se a entidade tem dependencias
+			out, _ := TemplateToString(pipeStmtsTmpl, context)
+			ctx.Statement.Block(G.Id(out)).Line()
+			return nil
+		},
+	}
+)
+
+// var (
+// 	project        = ctx.Project
+// 	method         = ctx.Method
+// 	responseEntity = GenericPart.ReplaceAllString(method.Response, "")
+// )
+
+// if responseEntity == "" {
+// 	panic("Modelo de resposta não definido")
+// }
+
+// ctx.Statement.Block(
+// 	// Declaracao das variaveis
+// 	G.Var().Defs(
+// 		// G.Id("err").Op("*").Qual(API_ERROR, "Error"),
+// 		G.Id("entity").Op("=").Id("New"+method.Entity).Call(),
+// 	).Line(),
+
+// 	// Fazendo o parse do body
+// 	G.If(
+// 		G.Id("err").Op("=").Qual(API_URL, "ReadJson").Call(G.Id("ctx"), G.Id("entity")),
+// 		G.Id("err").Op("!=").Id("nil"),
+// 	).Block(
+// 		// G.Id("api").Dot("Falha").Call(
+// 		// 	G.Id("ctx"),
+// 		// 	G.Id("api").Dot("ErrGeneral"),
+// 		// 	G.Id("err").Dot("Error").Call(),
+// 		// 	G.Nil(),
+// 		// ),
+// 		// G.Return(G.Id("err")),
+// 		G.Return(),
+// 	).Line(),
+
+// 	G.Id("values").Op(":=").Id("ctx").Dot("Values()").Line(),
+
+// 	G.Do(func(part *G.Statement) {
+// 		entity := ctx.Project.GetSchema(method.Entity)
+// 		user := false
+// 		for _, prop := range entity.Properties {
+// 			if def, ok := prop.Autogenerate["create_action"]; ok {
+// 				switch def.Type {
+// 				case "user":
+// 					if !user {
+// 						part.Add(G.Id(`user := values.Get("$user.ref").(*UserReference)`).Line())
+// 						user = true
+// 					}
+// 					part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Id("user").Line())
+// 				case "now":
+// 					part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Qual("time", "Now").Call().Id(".Unix()").Line())
+// 				case "fn":
+// 					part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Id(def.Args[0]).Call().Line())
+// 				default:
+// 					// fmt.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
+// 					// spew.Dump(def)
+// 					// parts := strings.Split(def, "#")
+// 					// part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Qual("time", "Now").Call().Id(".Unix()").Line())
+// 				}
+// 			}
+// 		}
+// 	}).Line(),
+
+// 	G.Do(func(s *G.Statement) {
+// 		entity := ctx.Project.EntityDesc(method.Entity)
+// 		if entity != nil && entity.HasMode {
+// 			s.Add(G.Id(`entity.SetMode("create")`))
+// 		}
+// 	}),
+// 	G.If(
+// 		G.Id("err").Op("=").Qual(API_URL, "Validate").Call(G.Id("entity")),
+// 		G.Id("err").Op("!=").Id("nil"),
+// 	).Block(
+// 		// G.Return(G.Id("err")),
+// 		G.Return(),
+// 	).Line(),
+
+// 	// Carrega o filtro do contexto para adicionar a entidade
+// 	G.Id("filter").Op(":=").Id("values").Dot("Get").Call(
+// 		G.Lit("$filter"),
+// 	).Assert(G.Op("*").Qual(API_URL, "Filter")).Line(),
+
+// 	// Adiciona a entidade
+// 	G.Id("filter").Dot("DB").Op("=").Lit(ctx.Project.GetEntityDB(method.Entity)),
+// 	G.Id("filter").Dot("Collection").Op("=").Lit(ctx.Project.GetCollection(method.Entity)),
+// 	G.Id("filter").Dot("Entity").Op("=").Id("entity"),
+// 	generateHookCall(project, method, "beforePersist"),
+// 	// Inseri a entidade na coleção e verifica se a operação ocorreu com exito
+// 	G.If(
+// 		G.List(G.Id("_"), G.Id("err")).Op("=").Id("Models").Dot("InsertOne").Call(
+// 			G.Id("filter"),
+// 		),
+// 		G.Id("err").Op("!=").Id("nil"),
+// 	).Block(
+// 		// G.Id("api").Dot("Falha").Call(
+// 		// 	G.Id("ctx"),
+// 		// 	G.Id("api").Dot("ErrGeneral"),
+// 		// 	G.Id("err").Dot("Error").Call(),
+// 		// 	G.Nil(),
+// 		// ),
+// 		// bson.IsObjectIdHex(m.Id.Hex())
+// 		// G.Return(G.Id("err")),
+// 		G.Return(),
+// 	),
+
+// 	// Envia a resposta pro usuario em caso de sucesso
+// 	// G.Line().Id("ctx").Dot("JSON").Call(G.Qual(APIC, "Map").Values(G.Dict{
+// 	// 	G.Lit("entity"): G.Id("entity"),
+// 	// })),
+// 	// G.Line().Id("resp").Dot("Entity").Op("=").Id("entity"),
+// 	// G.Line().Id("resp").Op("=").Id(responseEntity).Values(G.Dict{
+// 	// 	G.Id("Entity"): G.Id("entity"),
+// 	// }),
+// 	G.Line().Id("resp").Op("=").Id("entity"),
+// 	generateHookCall(project, method, "beforeSend"),
+// 	// G.Return(G.Nil()),
+// 	G.Return(),
+// )

+ 23 - 15
translate/got/middleware_post.go

@@ -18,22 +18,29 @@ func init() {
 	createStmtsTmpl, createStmtsErr = ParseTemplate(`
 	var (
 		entity = models.New{{.entity}}()
+		values = ctx.Values()
 	)
+	values.Set("entity", entity)
+	{{if .entityAlias }} values.Set("{{.entityAlias}}", entity) {{end}}
+
+	{{if .beforeRequestParse}}
+		if _, err = executeAction(
+			ctx,
+			{{.beforeRequestParse}},
+		); err != nil {
+			return
+		}
+	{{end}}
 
 	if err = api.ReadJson(ctx, entity); err != nil {
 		return
 	}
 
-	values := ctx.Values()
-
 	user := values.Get("$user.ref").(*models.UserReference)
 	entity.CreatedBy = user
 	entity.UpdatedBy = user
 	entity.SetMode("create")
 
-	values.Set("entity", entity)
-
-	{{if .entityAlias }} values.Set("{{.entityAlias}}", entity) {{end}}
 
 	if err = api.Validate(entity); err != nil {
 		return
@@ -91,16 +98,17 @@ var (
 				beforeSend       = method.Hook("beforeSend")
 				beforePersist    = method.Hook("beforePersist")
 				context          = map[string]interface{}{
-					"dbName":           dbName,
-					"collectionName":   collectionName,
-					"entity":           method.Entity,
-					"dependenceMethod": dependenceMethod,
-					"beforePersist":    beforePersist,
-					"beforeSend":       beforeSend,
-					"methodName":       strings.Title(method.ID),
-					"preconditions":    parseMethodActions(method.Preconditions),
-					"beforeResponse":   parseMethodActions(method.BeforeResponse),
-					"entityAlias":      getCustom(method.Custom, "go.entity.alias"),
+					"dbName":             dbName,
+					"collectionName":     collectionName,
+					"entity":             method.Entity,
+					"dependenceMethod":   dependenceMethod,
+					"beforePersist":      beforePersist,
+					"beforeSend":         beforeSend,
+					"methodName":         strings.Title(method.ID),
+					"preconditions":      parseMethodActions(method.Preconditions),
+					"beforeResponse":     parseMethodActions(method.BeforeResponse),
+					"beforeParseRequest": parseMethodActions(method.BeforeParseRequest),
+					"entityAlias":        getCustom(method.Custom, "go.entity.alias"),
 				}
 			)
 			// Nome do metodo que verifica se a entidade tem dependencias

+ 11 - 1
translate/got/resources.go

@@ -34,6 +34,7 @@ var (
 		"patch":     GenPatchStmts,
 		"delete":    GenDeleteStmts,
 		"get_one":   GenGetStmtsOne,
+		"pipe":      GenPipeStmts,
 		"filter":    GenGetFilter,
 		"get_list":  GenGetStmtsList,
 		"undelete":  GenUndeleteStmts,
@@ -308,9 +309,14 @@ func GenIndexApi(p *Project) error {
 		}
 
 		func executeAction(ctx context.Context, actions ...func(context.Context) (interface{}, *`).Qual(API_ERROR, "Error").Id(`)) (resp interface{},err *errs.Error){
+			var stopPropagation bool
 			for _, action := range actions {
-				if resp, err = action(ctx); err != nil || resp != nil {
+				resp, err = action(ctx)
+				stopPropagation,_ = ctx.Values().GetBool("stop.propagation")
+				switch {
+				case stopPropagation, err != nil, resp != nil:
 					return
+					
 				}
 			}
 			return
@@ -481,6 +487,10 @@ func generateActionsFiles(p *Project, f *G.File, r *Resource, method *Method) {
 		actions = append(actions, method.BeforeResponse...)
 	}
 
+	if method.BeforeParseRequest != nil {
+		actions = append(actions, method.BeforeParseRequest...)
+	}
+
 	for _, action := range actions {
 
 		path := fmt.Sprintf(

+ 9 - 3
translate/tst/schemas.go

@@ -76,9 +76,13 @@ func GenSchemas(p *Project) error {
 			}
 
 			if attribName != "" {
-
+				optional := "?"
+				// if getCustom(meta.Custom, "ts.optional").(bool) {
+				// if !meta.Required {
+				// 	options = "?"
+				// }
 				// attrib.Add(TS.Public().Id(attribName).Op(":").Id(TS.ConvType(meta.Type)))
-				attrib.Add(TS.Id(attribName).Op(":").Id(TS.ConvType(meta.Type)))
+				attrib.Add(TS.Id(attribName).Id(optional).Op(":").Id(TS.ConvType(meta.Type)))
 				if meta.Array {
 					attrib.Add(TS.Index())
 				}
@@ -88,10 +92,12 @@ func GenSchemas(p *Project) error {
 		} // Fim do loop dos atributos
 
 		// attribs = append(attribs, TS.Constructor(TS.Raw("opts: any")).Block(TS.Raw("opts && Object.assign(this,opts);")))
+		unshift := []TS.CodeInterface{TS.Id(`constructor(entity?:any){ if(entity){Object.assign(this, entity);}}`)}
+
+		attribs = append(unshift, attribs...)
 
 		module.Line().Export().Class().Id(strings.Title(entity.ID)).Block(
 			// module.Line().Export().Interface().Id(strings.Title(entity.ID)).Block(
-			// TS.Constructor(TS.Id(`options: `)),
 			attribs...,
 		).Line()