123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- package got
- import (
- "fmt"
- "text/template"
- api "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/api"
- . "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/common"
- // "github.com/davecgh/go-spew/spew"
- )
- var (
- updateRelationStmtsTmpl *template.Template
- updateRelationStmtsErr error
- )
- func init() {
- updateRelationStmtsTmpl, updateRelationStmtsErr = ParseTemplate(`
- func UpdateRelation{{.entity}}(options *api.Filter) {
- var (
- filter *api.Filter
- err *errs.Error
- entity = &models.{{.entity}}Reference{}
- wg = sync.WaitGroup{}
- )
-
- options.Entity = entity
-
- if _, err = models.Api.FindOne(options); err != nil {
- return
- }
-
- entity.Id = entity.Id.(primitive.ObjectID).Hex()
- {{range .relations}}
- wg.Add(1)
- go func(){
- defer wg.Done()
-
- filter = &api.Filter{
- Collection: "{{.Collection}}",
- DB: "{{.DB}}",
- Patchs: &bson.A{bson.M{"$set": bson.M{"{{.path}}": entity}}},
- Query: &bson.M{"{{.attr}}._id": entity.Id},
- }
-
- if _, err = models.Api.PatchMany(filter); err != nil {
- fmt.Println(err.Error())
- }
- }()
- {{end}}
- wg.Wait()
- }`)
- if updateRelationStmtsErr != nil {
- panic(updateRelationStmtsErr)
- }
- }
- func createUpdateRelationMethod(method *Method, context map[string]interface{}) (out string, err error) {
- var (
- indexMap = map[bool]string{
- true: ".$",
- false: "",
- }
- hasUpdateRelation = SR.Has(method.Entity)
- relations = []map[string]interface{}{}
- updRelation = UPDATE_RELATION + method.Entity
- _, updateRelationMethodDefined = relationFunctionDefined[updRelation]
- )
- context["hasUpdateRelation"] = hasUpdateRelation
- context["relations"] = &relations
- if hasUpdateRelation {
- if updateRelationMethodDefined {
- err = fmt.Errorf("function defined")
- return
- }
- relationFunctionDefined[updRelation] = true
- fmt.Printf("Generate update callback for entity '%s'\n", method.Entity)
- for _, relation := range SR.Get(method.Entity) {
- if relation.DB == "" || relation.Collection == "" {
- api.LogWarning(0, fmt.Sprintf("DB and Collection are required! %s -> %s", relation.Target, relation.Source))
- continue
- }
- relations = append(relations, map[string]interface{}{
- "DB": relation.DB,
- "Collection": relation.Collection,
- "attr": relation.Attr,
- "path": fmt.Sprintf("%s%s", relation.Attr, indexMap[relation.IsArray]),
- })
- }
- out, err = TemplateToString(updateRelationStmtsTmpl, context)
- }
- return
- }
- // var (
- // GenUpdateStmts = &Middleware{
- // Id: "implement",
- // Type: "method",
- // Fn: func(ctx *MiddlewareContext) error {
- // var (
- // project = ctx.Project
- // method = ctx.Method
- // dbName = project.GetEntityDB(method.Entity)
- // collectionName = project.GetCollection(method.Entity)
- // dependenceMethod = BASE_HAS_DEPENDE + method.Entity
- // updRelation = UPDATE_RELATION + method.Entity
- // indexMap = map[bool]string{
- // true: ".$",
- // false: "",
- // }
- // beforeSend = method.Hook("beforeSend")
- // beforePersist = method.Hook("beforePersist")
- // hasUpdateRelation = SR.Has(method.Entity)
- // _, updateRelationMethodDefined = relationFunctionDefined[updRelation]
- // relations = []map[string]interface{}{}
- // context = map[string]interface{}{
- // "dbName": dbName,
- // "collectionName": collectionName,
- // "entity": method.Entity,
- // "dependenceMethod": dependenceMethod,
- // "beforeSend": beforeSend,
- // "beforePersist": beforePersist,
- // "hasUpdateRelation": hasUpdateRelation,
- // "relations": &relations,
- // }
- // )
- // if beforePersist {
- // generateHookCall(project, method, "beforePersist")
- // }
- // if beforeSend {
- // generateHookCall(project, method, "beforeSend")
- // }
- // // Nome do metodo que verifica se a entidade tem dependencias
- // out, _ := TemplateToString(updateStmtsTmpl, context)
- // afterMethod := ctx.Statement.Block(G.Id(out)).Line()
- // return nil
- // },
- // }
- // )
- // j = G.Id("filter").Op("=").Op("&").Qual(API_URL, "Filter").Values(G.Dict{
- // // Especifica a collection
- // G.Id("DB"): G.Lit(relation.DB),
- // G.Id("Collection"): G.Lit(relation.Collection),
- // // Especifica a query
- // G.Id("Query"): G.Op("&").Qual(BSON, "M").Values(G.Dict{
- // G.Lit(attrId + "._id"): G.Id("f").Dot("Id").Dot("Hex").Call(),
- // }),
- // // G.Id("Entity"): G.Qual(BSON, "M").Values(G.Dict{
- // // G.Lit("$set"): G.Qual(BSON, "M").Values(G.Dict{
- // // G.Lit(attrId + index): G.Id("f").Dot("Entity"),
- // // }),
- // // }),
- // G.Id("Patchs"): G.Op("&").Qual(BSON, "A").Values(
- // G.Qual(BSON, "M").Values(G.Dict{
- // G.Lit("$set"): G.Qual(BSON, "M").Values(G.Dict{
- // G.Lit(attrId + index): G.Id("f").Dot("Entity"),
- // }),
- // }),
- // ),
- // }).Line().If(
- // G.List(G.Id("_"), G.Id("err")).Op("=").Id("Models").Dot("PatchMany").Call(
- // G.Id("filter"),
- // ),
- // G.Id("err").Op("!=").Id("nil"),
- // ).Block(
- // G.Qual("fmt", "Println").Call(G.Id("err").Dot("Error").Call()),
- // ).Line().Line()
- // k.Add(j)
- // .Do(func(s *G.Statement) {
- // _, found := relationFunctionDefined[updRelation]
- // if !createUpdateRelation || found {
- // return
- // }
- // s.Comment(updRelation + " atualiza as referências da entidade " + method.Entity).Line()
- // s.Func().Id(updRelation).Params(
- // G.Id("f").Op("*").Qual(API_URL, "Filter"),
- // ).Block(
- // G.Var().Defs(
- // G.Id("filter").Op("*").Qual(API_URL, "Filter"),
- // G.Id("err").Op("*").Qual(API_ERROR, "Error"),
- // ),
- // // atualiza o filtro para a entidade de referencia
- // G.Id("f").Dot("Entity").Op("=").Op("&").Id(method.Entity+"Reference").Values(),
- // // Carrega os dados do banco para atualizar nas entidades relacionadas
- // G.If(
- // G.List(G.Id("_"), G.Id("err")).Op("=").Id("Models").Dot("FindOne").Call(
- // G.Id("f"),
- // ),
- // G.Id("err").Op("!=").Id("nil"),
- // ).Block(
- // G.Return(),
- // ),
- // G.Do(func(k *G.Statement) { // Adiciona as regras de atualizacao
- // var (
- // j *G.Statement
- // index string
- // )
- // for _, relation := range SR.Get(method.Entity) {
- // if relation.DB == "" || relation.Collection == "" {
- // api.LogWarning(0, fmt.Sprintf("Relation DB or Collection can't be empty! %s -> %s", relation.Target, relation.Source))
- // continue
- // }
- // // spew.Dump(relation)
- // // panic("sss")
- // // e := project.GetSchema(relation)
- // attrId := relation.Attr
- // if relation.IsArray {
- // index = ".$"
- // } else {
- // index = ""
- // }
- // j = G.Id("filter").Op("=").Op("&").Qual(API_URL, "Filter").Values(G.Dict{
- // // Especifica a collection
- // G.Id("DB"): G.Lit(relation.DB),
- // G.Id("Collection"): G.Lit(relation.Collection),
- // // Especifica a query
- // G.Id("Query"): G.Op("&").Qual(BSON, "M").Values(G.Dict{
- // G.Lit(attrId + "._id"): G.Id("f").Dot("Id").Dot("Hex").Call(),
- // }),
- // // G.Id("Entity"): G.Qual(BSON, "M").Values(G.Dict{
- // // G.Lit("$set"): G.Qual(BSON, "M").Values(G.Dict{
- // // G.Lit(attrId + index): G.Id("f").Dot("Entity"),
- // // }),
- // // }),
- // G.Id("Patchs"): G.Op("&").Qual(BSON, "A").Values(
- // G.Qual(BSON, "M").Values(G.Dict{
- // G.Lit("$set"): G.Qual(BSON, "M").Values(G.Dict{
- // G.Lit(attrId + index): G.Id("f").Dot("Entity"),
- // }),
- // }),
- // ),
- // }).Line().If(
- // G.List(G.Id("_"), G.Id("err")).Op("=").Id("Models").Dot("PatchMany").Call(
- // G.Id("filter"),
- // ),
- // G.Id("err").Op("!=").Id("nil"),
- // ).Block(
- // G.Qual("fmt", "Println").Call(G.Id("err").Dot("Error").Call()),
- // ).Line().Line()
- // k.Add(j)
- // }
- // }),
- // )
- // })
- // var (
- // // UpdateRelationRotine *G.Statement
- // method = ctx.Method
- // project = ctx.Project
- // updRelation = UPDATE_RELATION + method.Entity
- // createUpdateRelation = false
- // entity = method.Request
- // responseEntity = GenericPart.ReplaceAllString(method.Response, "")
- // )
- // if entity == "" {
- // panic("Modelo de request não definido em UpdateStmt!")
- // }
- // if responseEntity == "" {
- // panic("Modelo de response não definido!")
- // }
- // ctx.Statement.Block(
- // // Declaracao das variaveis
- // G.Var().Defs(
- // // G.Id("err").Op("*").Qual(API_ERROR, "Error"),
- // G.Id("entity").Op("=").Op("&").Id(entity).Values(),
- // ).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(),
- // ),
- // 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(),
- // // Captura a base de values
- // G.Id("values").Op(":=").Id("ctx").Dot("Values").Call(),
- // // Gera as atribuicoes de variaveis que seram atualizadas (usuario e ultimo update quando existir)
- // G.Do(func(part *G.Statement) {
- // entity := ctx.Project.GetSchema(method.Entity)
- // user := false
- // for _, prop := range entity.Properties {
- // if def, ok := prop.Autogenerate["update"]; 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())
- // }
- // }
- // }
- // }).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").Line(),
- // 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("UpdateOne").Call(
- // // G.Lit(ctx.Project.GetCollection(method.Entity)),
- // 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(),
- // ),
- // // Cria a rotina de atualização de relacionamentos
- // G.Do(func(s *G.Statement) {
- // if SR.Has(method.Entity) {
- // createUpdateRelation = true
- // relationFunctionDefined[updRelation] = true
- // s.Comment("Cria uma thread que executa a atualizaca das referências.").Line().Go().Func().Params().Block(
- // G.Id(updRelation).Call(G.Id("filter")),
- // ).Call()
- // }
- // }),
- // // Envia a resposta pro usuario em caso de sucesso
- // // 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(),
- // ).Line()
|