123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971 |
- package got
- import (
- "fmt"
- . "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/common" // . "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/gen"
- G "github.com/dave/jennifer/jen"
- "regexp"
- "strings"
- "time" // "github.com/davecgh/go-spew/spew"
- )
- var (
- filled = map[string]*Entity{}
- numberRegex = regexp.MustCompile("(int|float).*")
- // bool
- // string
- // int int8 int16 int32 int64
- // uint uint8 uint16 uint32 uint64 uintptr
- // byte // alias for uint8
- // rune // alias for int32
- // // represents a Unicode code point
- // float32 float64
- // complex64 complex128
- primitiveRegex = regexp.MustCompile(`^(bool|string|u?int\d{0,2}|byte|rune|float\d{0,2}|interface|complex\d{2,3})$`)
- )
- func hasReplaceMethod(typ string) bool{
- typ = strings.Replace(typ, "*","", 1)
- return !primitiveRegex.MatchString(typ)
- }
- func replaceAccessType(typ string) (accessType string) {
- typ = strings.Replace(typ, "*","", 1)
- if strings.Contains(typ, "map"){
- accessType = "map"
- } else {
- accessType = "id"
- }
- return
- }
- func GenSchemas(p *Project) error {
- var (
- // requiredOnCreate bool
- hasAddOrRemove bool
- filename string
- inputName string
- typ string
- extName string
- f *G.File
- propertie *G.Statement
- extend *G.Statement
- base = "models/"
- posfix = ""
- properties G.Statement
- // values G.Dict
- cproperties map[string]*G.Statement
- addUpdate map[string]string
- replaceUpdate map[string]map[string]string
- removeUpdate map[string]map[string]string
- entityName string
- entityPatchName string
- propName string
- entityInfo *EntityInfo
- inputProperties G.Statement
- patchProperties G.Statement
- referenceProperties G.Statement
- entities, err = Schemas(p)
- // entities = p.Schemas
- // err error
- )
- if err != nil {
- return err
- }
- go GenModelIndex(p)
- if err = GenFilterEntityDocument(p); err != nil {
- return err
- }
- if err = GenEntityHelpers(p); err != nil {
- return err
- }
- for _, entity := range entities {
- entityInfo = p.ResponseEntity(entity.ID)
- if entityInfo.IsGeneric {
- continue
- }
- inputName = entity.ID
- entityPatchName = ""
- hasAddOrRemove = false
- // requiredOnCreate = false
- entityName = GenericPart.ReplaceAllString(entity.ID, "")
- filename = base + strings.ToLower(entityName)
- // f = G.NewFile(p.Package)
- f = G.NewFile("models")
- generateIndexsEntity(f, entity)
- // fmt.Println("Gerando entity: ", entityName)
- cproperties = map[string]*G.Statement{}
- // f.Comment(entity.Description)
- properties = G.Statement{}
- patchProperties = G.Statement{
- G.Qual(API_URL, "PatchHistoryRegister").Tag(map[string]string{
- "json": "-",
- "bson": ",inline",
- }),
- }
- entityModel := G.Qual(API_URL, "EntityModel").Tag(map[string]string{
- "json": "-",
- "bson": "-",
- })
- patchProperties = append(patchProperties, entityModel)
- // values = G.Dict{}
- // entityInfo = p.IsGenericEntity(entity.ID)
- inputProperties = G.Statement{
- // G.Qual(API_URL, "DotNotation").Tag(map[string]string{
- // "json": "-",
- // "bson": ",inline",
- // }),
- G.Id("DotNotation map[string]interface{}").Tag(map[string]string{
- "json": "-",
- "bson": ",inline",
- }),
- }
- // inputProperties = append(inputProperties, entityModel)
- referenceProperties = G.Statement{}
- addUpdate = map[string]string{}
- replaceUpdate = map[string]map[string]string{}
- removeUpdate = map[string]map[string]string{}
- for _, meta := range entity.Properties {
- // fmt.Println("Gerando ---------- ", entityName, "---------", propName, "----", meta.Array)
- if meta.Targets != "" && !strings.Contains(meta.Targets, "go") {
- continue
- }
- propName = strings.Title(meta.ID)
- propertie = G.Id(propName)
- meta.FillTags(p, propName)
- posfix = ""
- // Registra a relaao entre as entidades
- if meta.Relation {
- posfix = "Reference"
- SR.Add(&Relation{
- Source: meta.GetType(),
- Target: entity.ID,
- Attr: strings.Replace(meta.Tags["bson"], ",omitempty", "", 1),
- DB: entity.DB,
- Collection: entity.Collection,
- IsArray: meta.Array,
- })
- }
- typ = meta.Type + posfix
- if typ == "any" {
- typ = "interface{}"
- }
- if meta.Array {
- hasAddOrRemove = true
- propertie.Op("*")
- propertie.Index()
- if !meta.Readonly {
- extName = "Add" + propName
- addUpdate[extName] = meta.ID
- extend = G.Id(extName).Index().Id(ConvType(typ)).Tag(map[string]string{
- "json": extName + ",omitempty",
- "bson": extName + ",omitempty",
- })
- patchProperties = append(patchProperties, extend)
- if hasReplaceMethod(typ) {
- extName = "Replace" + propName
- replaceUpdate[extName] = map[string]string{
- "name": meta.ID,
- "type": replaceAccessType(typ),
- }
- extend = G.Id(extName).Index().Id(ConvType(typ)).Tag(map[string]string{
- "json": extName + ",omitempty",
- "bson": extName + ",omitempty",
- })
- patchProperties = append(patchProperties, extend)
- }
- extName = "Remove" + propName
- removeUpdate[extName] = map[string]string{
- "type": ConvType(typ),
- "propId": meta.ID,
- }
- extend = G.Id(extName).Index().Interface().Tag(map[string]string{
- "json": extName + ",omitempty",
- "bson": extName + ",omitempty",
- })
- patchProperties = append(patchProperties, extend)
- }
- }
- // propertie.Id(entityInfo.TranslateType(meta.Type) + posfix)
- if strings.Contains(typ, ".") {
- typt := strings.Split(typ, ".")
- propertie.Qual(ImportMap(typt[0]), ConvType(typt[1]))
- } else {
- propertie.Id(ConvType(typ))
- }
- entity.HasMode = true
- // Adiciona as tags caso sejam definidas
- if meta.Tags != nil {
- // if name, ok := meta.Tags["valid"]; ok && strings.Contains(name, "requiredOnCreate") {
- // entity.HasMode = true
- // }
- propertie.Tag(meta.Tags)
- // if name, ok := meta.Tags["json"]; ok {
- // // tsPropertieName = strings.Split(name, ",")[0]
- // }
- } else {
- // tsPropertieName = meta.ID
- }
- // Adiciona a crescricao como comentario
- // tsPropertie = &ts.Group{}
- if meta.Description != "" {
- propertie.Comment(meta.Description)
- // tsPropertie.Comment(meta.Description)
- }
- // if tsPropertieName != "" {
- // tsPropertie.Add(ts.Public().Id(tsPropertieName).Op(":").Id(ts.ConvType(meta.Type)))
- // if meta.Array {
- // tsPropertie.Add(ts.Index())
- // }
- // tsPropertie.Endl()
- // tsProperties = append(tsProperties, tsPropertie)
- // }
- cproperties[meta.ID] = propertie
- // Adiciona o valor padrao de inicializacao
- // spew.Dump(meta)
- // if tvalue, ok := meta.Autogenerate["create"]; ok {
- // switch tvalue {
- // case "objectId":
- // values[G.Id(propName)] = G.Qual(BSON_PRIMITIVE, "NewObjectID").Call()
- // case "now":
- // values[G.Id(propName)] = G.Qual("time", "Now").Call().Id(".Unix()")
- // case "time:now":
- // case "user:current":
- // default:
- // // Verifica se possui valor padrão
- // if meta.Default != nil {
- // values[G.Id(propName)] = G.Lit(meta.Default)
- // }
- // }
- // }
- // Adiciona as propriedades readonly na entidade principal
- // e as que tem permissao de escrita na entidade input
- if !meta.Readonly {
- inputProperties = append(inputProperties, propertie)
- } else {
- properties = append(properties, propertie)
- }
- // Adiciona a propriedade que é referencia a lista de propriedades
- // da entidade reference
- if meta.Reference {
- if propName == "Id" {
- propertie = G.Id("Id").Interface().Tag(map[string]string{
- "json": "_id",
- "bson": "_id",
- })
- }
- referenceProperties = append(referenceProperties, propertie)
- }
- }
- extend = G.Qual(API_URL, "EntityModel").Tag(map[string]string{
- "json": "-",
- "bson": ",inline",
- })
- inputProperties = append(G.Statement{extend}, inputProperties...)
- if len(inputProperties) > 0 {
- // if entity.HasMode {
- // values[G.Id("Mode")] = G.Qual(API_URL, "Mode").Values(G.Dict{
- // G.Id("M"): G.Lit("create"),
- // })
- // }
- if len(properties) == 0 {
- properties = inputProperties
- patchProperties = append(patchProperties, G.Id("Set").Op("*").Id(entityName).Tag(map[string]string{
- "json": "$set,omitempty",
- "bson": "$set,omitempty",
- }))
- } else {
- inputName = entity.ID + "Input"
- extend = G.Id(inputName).Tag(map[string]string{
- "json": ",inline",
- "bson": ",inline",
- })
- properties = append(G.Statement{extend}, properties...)
- f.Comment("Representação Input aplicada em operações de update.")
- f.Type().Id(inputName).Struct(inputProperties...)
- patchProperties = append(patchProperties, G.Id("Set").Op("*").Id(inputName).Tag(map[string]string{
- "json": "$set,omitempty",
- "bson": "-",
- }))
- }
- }
- if len(referenceProperties) > 0 {
- f.Comment("Representação reference aplicada quando a entidade é associada a outra.")
- f.Type().Id(entity.ID + "Reference").Struct(referenceProperties...)
- }
- // if entity.Representations != nil {
- // for k, rep := range entity.Representations {
- // tproperties = G.Statement{}
- // for _, attr := range rep {
- // tproperties = append(tproperties, cproperties[attr])
- // }
- // f.Comment("Representação " + k)
- // f.Type().Id(entity.ID + k).Struct(tproperties...)
- // }
- // }
- if len(patchProperties) > 1 {
- entityPatchName = fmt.Sprintf("%sPatchs", entityName)
- f.Comment(entity.Description).Line().Comment("Representação de atualização")
- // patchProperties = append(G.Statement{*entityModel}, patchProperties)
- f.Type().Id(entityPatchName).Struct(patchProperties...)
- }
- // Cria a entidade normal
- f.Comment(entity.Description).Line().Comment("Representação Completa")
- f.Type().Id(entityName).Struct(properties...)
- // Cria a entidade em typescript
- // tsModels.Line().Export().Class().Id(strings.Title(entity.ID)).Block(tsProperties...).Line()
- f.Comment("Cria uma instancia de " + entity.ID + ".")
- // Cria a função de instanciar um novo elemento com os valores padrão determinados
- f.Func().Id("New"+entityName).Params().Op("*").Id(entityName).Block(
- G.Id("entity").Op(":=").Op("&").Id(entityName).Values(),
- G.Do(func(x *G.Statement) {
- if entity.HasMode {
- x.Add(G.Id(`entity.SetMode("create")`))
- }
- }),
- G.Do(func(part *G.Statement) {
- // user := false
- for _, prop := range entity.Properties {
- typ := ConvType(prop.Type)
- isMap := strings.Contains(typ, "map")
- if prop.Relation {
- typ = typ + "Reference"
- }
- if def, ok := prop.Autogenerate["create"]; ok {
- switch def.Type {
- case "objectId":
- part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Qual(BSON_PRIMITIVE, "NewObjectID()").Line())
- case "now":
- part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Qual("time", "Now").Call().Id(".Unix()").Line())
- case "default":
- part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Lit(prop.Default).Line())
- }
- } else if prop.Array {
- part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("= &").Index().Id(typ).Values().Line())
- } else if isMap {
- part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Id(typ).Values().Line())
- }
- }
- }).Line(),
- G.Return(G.Id("entity")).Line(),
- )
- // update = bson.M{"$set": f.Entity}
- // if data, ok = f.Entity.Push(); ok {
- // update["$push"] = data
- // }
- // if data, ok = f.Entity.Pull(); ok {
- // update["$pull"] = data
- // }
- if entityPatchName != "" {
- f.Func().Params(
- G.Id("t").Op("*").Id(entityPatchName),
- ).Id("Patch").Params().Params(
- G.Op("*").Qual(BSON, "A"),
- G.Op("*").Qual("go.mongodb.org/mongo-driver/mongo/options", "UpdateOptions"),
- ).Block(
-
- G.Id("updt").Op(":=").Qual(BSON, "A").Values(),
- G.Id("patchOptions := ").Qual("go.mongodb.org/mongo-driver/mongo/options","Update").Call(),
- G.Do(func(y *G.Statement) {
- if !hasAddOrRemove {
- return
- }
- stmts := G.Statement{
- G.Id("hasAdd").Op(":=").Lit(0).Line(),
- G.Id("hasReplace").Op(":=").Lit(0).Line(),
- G.Id("hasRemove").Op(":=").Lit(0).Line(),
- G.Id("pull").Op(":=").Qual(BSON, "M").Values().Line(),
- G.Id("push").Op(":=").Qual(BSON, "M").Values().Line(),
- G.Id("dotNotation := map[string]interface{}{}").Line(),
- G.Id("arrayFilters := []interface{}{}").Line(),
- }
- // add entitys
- // spew.Dump(addUpdate)
- for prop, value := range addUpdate {
- stmts = append(stmts, G.If(G.Len(G.Id("t").Dot(prop)).Op(">").Lit(0)).Block(
- G.Id("hasAdd").Op("++"),
- G.Id("push").Index(G.Lit(value)).Op("=").Qual(BSON, "M").Values(G.Dict{
- G.Lit("$each"): G.Id("t").Dot(prop),
- }),
- ).Line())
- }
- // replace entitys
- // spew.Dump(addUpdate)
- for prop, value := range replaceUpdate {
- prop = fmt.Sprintf("t.%s", prop)
- stmts = append(stmts, G.If(G.Len(G.Id(prop)).Op(">").Lit(0)).Block(
- G.Id("hasReplace").Op("++"),
- G.Do(func(replace *G.Statement) {
- name := value["name"]
- typi := value["type"]
- arrayFiltersTemplates := map[string]string{
- "id": `arrayFilters = append(arrayFilters, bson.M{
- api.Format("%s._id", key): value.Id,
- })`,
- "map": `arrayFilters = append(arrayFilters, bson.M{
- api.Format("%s._id", key): value["_id"],
- })`,
- }
- arrayFilters := arrayFiltersTemplates[typi]
- template := fmt.Sprintf(`for idx, value := range %s {
- key := api.Format("%s%%d", idx)
- dotNotation[api.Format("%s.$[%%s]", key)] = value
- %s
- }`,
- prop,
- name,
- name,
- arrayFilters,
- )
- replace.Add(G.Id(template))
- }),
- ).Line())
- }
- // remove entitys
- for prop, value := range removeUpdate {
- stmts = append(stmts, G.If(G.Len(G.Id("t").Dot(prop)).Op(">").Lit(0)).Block(
- G.Id("hasRemove").Op("++"),
- G.Do(func(hasRemove *G.Statement) {
- var assign G.Dict
- // Se o array for de um atributo de tipo primitivo
- if primitiveRegex.MatchString(value["type"]) {
- assign = G.Dict{
- G.Lit("$in"): G.Id("t").Dot(prop),
- }
- } else {
- assign = G.Dict{
- G.Lit("_id"): G.Qual(BSON, "M").Values(G.Dict{
- G.Lit("$in"): G.Id("t").Dot(prop),
- }),
- }
- }
- hasRemove.Id("pull").Index(G.Lit(value["propId"])).Op("=").Qual(BSON, "M").Values(assign)
- }),
- ).Line())
- }
- // fmt.Println("Remove:", inputName, prop, value)
- // fmt.Printf("%#v", G.If(G.Len(G.Id("t").Dot(prop)).Op(">").Lit(0)).Block(
- // G.Id("hasRemove").Op("++"),
- // G.Id("pull").Index(G.Lit(value)).Op("=").Qual(BSON, "M").Values(G.Dict{
- // G.Lit("$in"): G.Id("t").Dot(prop),
- // }),
- // ).Line())
- // x.Add(G.If(G.Len(G.Id("t").Dot(prop)).Op(">").Lit(0)).Block(
- // G.Id("hasRemove").Op("++"),
- // G.Id("pull").Index(G.Lit(value)).Op("=").Qual(BSON, "M").Values(G.Dict{
- // G.Lit("$in"): G.Id("t").Dot(prop),
- // }),
- // ).Line())
- stmts = append(stmts, G.If(G.Id("hasAdd").Op(">").Lit(0)).Block(
- // G.Id("updt").Index(G.Lit("$push")).Op("=").Id("push"),
- G.Id("updt").Op("=").Append(
- G.Id("updt"),
- G.Qual(BSON, "M").Values(G.Lit("$push").Id(": push")),
- ),
- // .Index(G.Lit("$push")).Op("=").Id("push"),
- ).Line())
-
- stmts = append(stmts, G.If(G.Id("hasRemove").Op(">").Lit(0)).Block(
- // G.Id("updt").Index(G.Lit("$pull")).Op("=").Id("pull"),
- G.Id("updt").Op("=").Append(
- G.Id("updt"),
- G.Qual(BSON, "M").Values(G.Lit("$pull").Id(": pull")),
- ),
- ).Line())
-
- stmts = append(stmts, G.If(G.Id("hasReplace").Op(">").Lit(0)).Block(
- G.Id(fmt.Sprintf(`if t.Set == nil {
- t.Set = &%s{}
- }
- t.Set.DotNotation = dotNotation
-
- patchOptions.SetArrayFilters(options.ArrayFilters{
- Filters: arrayFilters,
- })
- `,
- inputName,
- )),
- ).Line())
- y.Add(stmts...)
- }),
- G.Id(`if t.Set != nil {
- updt = append(updt, bson.M{"$set": t.Set})
- }`).Line(),
- // []interface{}{bson.D{
- // {"elem._id", 1},
- // }}
- G.Return(
- G.Op("&").Id("updt"),
- G.Id("patchOptions"),
- ),
- )
- }
- // Salva o arquivo da entidade
- if err := Write(p.Paths.Build("/%s/%s_gen.go", p.Package, filename), f); err != nil {
- return err
- }
- } // Fim do for de schema
- return nil
- }
- func ConvType(ntype string) string {
- if len(ntype) < 3 {
- fmt.Printf("Invalid type name '%s':\n", ntype)
- }
- if ntype[0:3] == "map" {
- parts := strings.Split(ntype, "|")
- ntype = fmt.Sprintf("map[%s]%s", parts[1], parts[2])
- }
- return ntype
- }
- func GenModelIndex(p *Project) error {
- var (
- // Index = G.NewFile(p.Package)
- Index = G.NewFile("models")
- )
- Index.Id(`type Entity struct {}`).Line()
- Index.Comment("")
- Index.Var().Defs(
- G.Id("Api").Op("=").Op("&").Qual(API_URL, "Mongo").Values(),
- ).Line()
- return Write(p.Paths.Build("/%s/models/index_gen.go", p.Package), Index)
- }
- func fill(p *Project, schema *Entity) (*Entity, error) {
- var (
- // found, ok bool
- found bool
- cls *Entity
- // newSchema = &(*schema)
- err error
- )
- // Se o esquema ainda não esta completo com as classes extendidas caso possua
- if _, found = filled[schema.ID]; !found {
- // fEntity = schema
- //
- // fmt.Println("Fill ............ ", schema.ID)
- // fmt.Println("Nao estava cheio ", schema.ID)
- for _, entity := range schema.Extends {
- if cls, err = fill(p, p.GetSchema(entity)); err != nil {
- return nil, err
- }
- // fmt.Println("extends ", entity)
- // if cls, ok = filled[entity]; !ok {
- // cls = p.GetSchema(entity)
- // // fmt.Println("Não tava cheio", entity)
- // // fmt.Println("fill:", schema)
- // // fmt.Println(cls)
- // if err = fill(p, cls); err != nil {
- // return err
- // }
- // }
- // else {
- // fmt.Println("estava cheio ", entity)
- // fmt.Println("Merge ", schema.ID, cls.ID, ok)
- schema.Properties = append(schema.Properties, cls.Properties...)
- }
- // for _, x := range schema.Properties {
- // fmt.Println("fill----------------", schema.ID, x.ID, len(schema.Properties))
- // }
- filled[schema.ID] = schema
- }
- return filled[schema.ID], nil
- }
- func Schemas(p *Project) ([]*Entity, error) {
- var (
- err error
- entities = []*Entity{}
- )
- for _, schema := range p.Schemas {
- if schema, err = fill(p, schema); err != nil {
- return nil, err
- }
- if schema.Type != "abstract" {
- entities = append(entities, schema)
- }
- // for _, x := range schema.Properties {
- // fmt.Printf("%s , %s, %p\n", schema.ID, x.ID, x)
- // }
- }
- // for _, s := range entities {
- // for _, x := range s.Properties {
- // fmt.Printf("final-schemas....%s , %s, %p\n", s.ID, x.ID, x)
- // }
- // }
- return entities, nil
- }
- func GenFilterEntityDocument(p *Project) error {
- var (
- content string
- path string
- err error
- )
- for _, s := range p.Schemas {
- if s.Type == "nested.object" {
- continue
- }
- // fmt.Println("gerando filtro ", s.ID)
- filter := &ApiFilter{
- Id: strings.ToLower(s.ID),
- Date: time.Now().Unix(),
- }
- for _, attr := range s.Properties {
- if attr.Filter == nil {
- continue
- }
- // Atualiza o tipo do filtro na estrutura do campo
- for _, filterItem := range attr.Filter {
- FilterTypeMap(attr, filterItem)
- // Atualiza o path da query
- if filterItem.Type == "nested" {
- FilterPath(filter, p, attr, attr.ID)
- } else {
- if filterItem.Path == "" {
- filterItem.Path = attr.ID
- }
- if filterItem.UserEnumAsOptions {
- filterItem.Options = []FilterOption{}
- // if len(attr.Values) == 0 {
- // attr.Values = make([]string, len(attr.Enum))
- // }
- // values = make()
- // }
- for key, value := range attr.Enum {
- filterItem.Options = append(filterItem.Options, FilterOption{
- Value: attr.Values[key],
- Label: value,
- })
- }
- }
- filter.Fields = append(filter.Fields, filterItem)
- }
- }
- }
- if filter.Fields == nil {
- continue
- }
- if content, err = JSONStringfy(filter); err != nil {
- return err
- }
- path = p.Paths.Dist("/filters/%s.json", strings.ToLower(s.ID))
- if err = FilePutContents(path, content, 0777); err != nil {
- return err
- }
- }
- return nil
- }
- func FilterPath(filter *ApiFilter, p *Project, attr *Propertie, path string) {
- var (
- nfil Filter
- npath string
- typ = attr.Type
- )
- if attr.Relation {
- typ += "Reference"
- }
- entity := p.GetSchema(typ)
- for _, x := range entity.Properties {
- if x.Filter == nil {
- continue
- }
- npath = fmt.Sprintf("%s.%s", path, x.ID)
- for _, item := range x.Filter {
- if item.Type != "nested" {
- nfil = *item
- if nfil.Path == "" {
- nfil.Path = npath
- }
- FilterTypeMap(x, item)
- filter.Fields = append(filter.Fields, &nfil)
- } else {
- FilterPath(filter, p, x, npath)
- }
- }
- }
- }
- func FilterTypeMap(attr *Propertie, f *Filter) {
- typ := f.Type
- if typ != "" {
- return
- }
- switch {
- // Se o tipo for numerico
- case numberRegex.Match([]byte(typ)):
- f.Type = "number"
- default:
- f.Type = attr.Type
- }
- }
- func generateIndexsEntity(file *G.File, entity *Entity) {
- // keys := G.{}
- // options := G.Dict{
- // G.Id("Unique"): G.Lit(true),
- // // G.Id("Key"): G.Lit("unique"),
- // // G.Id("Value"): G.Lit(true),
- // }
- var create = false
- indexOptions := G.Dict{
- G.Id("Keys"): G.Qual(BSONX, "Doc").ValuesFunc(func(keys *G.Group) {
- for _, propertie := range entity.Properties {
- if propertie.Unique {
- keys.Add(G.Values(G.Lit(propertie.ID), G.Qual(BSONX, "Int32").Call(G.Lit(1))))
- create = true
- // keys[G.Lit(propertie.ID)] = G.Lit(1)
- }
- }
- }),
- // G.Id("Options"): G.Qual(BSON, "M").Values(options),
- G.Id("Options"): G.Id("opts.SetUnique(true)"),
- }
- if create {
- file.Line().Func().Id("init").Call().Block(
- G.Id("models.Api.Ready().Subscribe").Call(
- G.Func().Call(G.Id("value").Id("...interface{}")).Block(
- G.Id("opts := &").Qual("go.mongodb.org/mongo-driver/mongo/options", "IndexOptions").Values(),
- G.Id(`index := `).Qual("go.mongodb.org/mongo-driver/mongo", "IndexModel").Values(indexOptions),
- // G.Qual("fmt", "Println").Call(G.Lit("create index for "), G.Lit(entity.ID)),
- G.Id(`if err := models.Api.CreateIndex(`).Lit(entity.DB).Id(`, `).Lit(entity.Collection).Id(`, index); err != nil`).
- Block(
- G.Id("panic").Call(
- G.Qual("fmt", "Sprintf").Call(
- // G.Lit(fmt.Sprintf("Index %s creation error %s", entity.ID, err.Error())),
- G.Id(`"Index`).Id(entity.ID).Id(`creation error %s", err.Error()`),
- ),
- ).Line(),
- // (`).
- // Call().
- // Line().
- ),
- ),
- ),
- )
- // .BlockFunc(func(statement *G.Group) {
- // statement.Add(
- // ,
- // )
- // statement.Add(G.Line().Id("})"))
- // })
- }
- }
- func GenEntityHelpers(project *Project) error {
- file := G.NewFile("models")
- entities, err := Schemas(project)
- if err != nil {
- return err
- }
- file.Add(G.Id(`
- import(
- "reflect"
- "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/api/errs"
- context "github.com/kataras/iris/v12/context"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- )
- `))
- getStmtsTmpl, getStmtsErr := ParseTemplate(`
- func Get{{.entity}}ByID(
- ctx context.Context,
- id interface{},
- ) (
- entity *{{.entity}},
- err *errs.Error,
- ) {
- var errd error
- entity = &{{.entity}}{}
- value := reflect.ValueOf(id)
- if value.Kind() == reflect.Ptr {
- id = value.Elem()
- }
- if idString, ok := id.(string); ok {
- if id, errd = primitive.ObjectIDFromHex(idString); errd != nil {
- return
- }
- }
- options := Filter{{.entity}}Options(ctx)
- options.Query = &bson.M{"_id": id}
- options.Entity = entity
-
- if _, err = Api.FindOne(options); err != nil {
- return
- }
- return
- }
- `)
- if getStmtsErr != nil {
- return getStmtsErr
- }
- for _, entity := range entities {
- entityInfo := project.ResponseEntity(entity.ID)
- if entityInfo.IsGeneric || entity.Type != "object" {
- continue
- }
- context := map[string]interface{}{
- "entity": strings.Title(entity.ID),
- }
- out, _ := TemplateToString(getStmtsTmpl, context)
- file.Add(G.Id(out).Line())
- }
-
- if err := Write(
- fmt.Sprintf("../project/include/go/models/get_helpers.go"),
- file,
- ); err != nil {
- return err
- }
- return nil
- }
|