schemas.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. package got
  2. import (
  3. "fmt"
  4. . "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/common" // . "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/gen"
  5. G "github.com/dave/jennifer/jen"
  6. "regexp"
  7. "strings"
  8. "time" // "github.com/davecgh/go-spew/spew"
  9. )
  10. var (
  11. filled = map[string]*Entity{}
  12. numberRegex = regexp.MustCompile("(int|float).*")
  13. // bool
  14. // string
  15. // int int8 int16 int32 int64
  16. // uint uint8 uint16 uint32 uint64 uintptr
  17. // byte // alias for uint8
  18. // rune // alias for int32
  19. // // represents a Unicode code point
  20. // float32 float64
  21. // complex64 complex128
  22. primitiveRegex = regexp.MustCompile(`^(bool|string|u?int\d{0,2}|byte|rune|float\d{0,2}|complex\d{2,3})$`)
  23. )
  24. func GenSchemas(p *Project) error {
  25. var (
  26. // requiredOnCreate bool
  27. hasAddOrRemove bool
  28. filename string
  29. inputName string
  30. typ string
  31. extName string
  32. f *G.File
  33. propertie *G.Statement
  34. extend *G.Statement
  35. base = "models/"
  36. posfix = ""
  37. properties G.Statement
  38. // values G.Dict
  39. cproperties map[string]*G.Statement
  40. addUpdate map[string]string
  41. removeUpdate map[string]map[string]string
  42. entityName string
  43. entityPatchName string
  44. propName string
  45. entityInfo *EntityInfo
  46. inputProperties G.Statement
  47. patchProperties G.Statement
  48. referenceProperties G.Statement
  49. entities, err = Schemas(p)
  50. // entities = p.Schemas
  51. // err error
  52. )
  53. if err != nil {
  54. return err
  55. }
  56. go GenModelIndex(p)
  57. if err = GenFilterEntityDocument(p); err != nil {
  58. return err
  59. }
  60. for _, entity := range entities {
  61. entityInfo = p.ResponseEntity(entity.ID)
  62. if entityInfo.IsGeneric {
  63. continue
  64. }
  65. inputName = ""
  66. entityPatchName = ""
  67. hasAddOrRemove = false
  68. // requiredOnCreate = false
  69. entityName = GenericPart.ReplaceAllString(entity.ID, "")
  70. filename = base + strings.ToLower(entityName)
  71. // f = G.NewFile(p.Package)
  72. f = G.NewFile("models")
  73. generateIndexsEntity(f, entity)
  74. // fmt.Println("Gerando entity: ", entityName)
  75. cproperties = map[string]*G.Statement{}
  76. // f.Comment(entity.Description)
  77. properties = G.Statement{}
  78. patchProperties = G.Statement{
  79. G.Qual(API_URL, "PatchHistoryRegister").Tag(map[string]string{
  80. "json": "-",
  81. "bson": ",inline",
  82. }),
  83. }
  84. entityModel := G.Qual(API_URL, "EntityModel").Tag(map[string]string{
  85. "json": "-",
  86. "bson": "-",
  87. })
  88. patchProperties = append(patchProperties, entityModel)
  89. // values = G.Dict{}
  90. // entityInfo = p.IsGenericEntity(entity.ID)
  91. inputProperties = G.Statement{
  92. // G.Qual(API_URL, "DotNotation").Tag(map[string]string{
  93. // "json": "-",
  94. // "bson": ",inline",
  95. // }),
  96. G.Id("DotNotation map[string]interface{}").Tag(map[string]string{
  97. "json": "-",
  98. "bson": ",inline",
  99. }),
  100. }
  101. // inputProperties = append(inputProperties, entityModel)
  102. referenceProperties = G.Statement{}
  103. addUpdate = map[string]string{}
  104. removeUpdate = map[string]map[string]string{}
  105. for _, meta := range entity.Properties {
  106. // fmt.Println("Gerando ---------- ", entityName, "---------", propName, "----", meta.Array)
  107. if meta.Targets != "" && !strings.Contains(meta.Targets, "go") {
  108. continue
  109. }
  110. propName = strings.Title(meta.ID)
  111. propertie = G.Id(propName)
  112. meta.FillTags(p, propName)
  113. posfix = ""
  114. // Registra a relaao entre as entidades
  115. if meta.Relation {
  116. posfix = "Reference"
  117. SR.Add(&Relation{
  118. Source: meta.GetType(),
  119. Target: entity.ID,
  120. Attr: strings.Replace(meta.Tags["bson"], ",omitempty", "", 1),
  121. DB: entity.DB,
  122. Collection: entity.Collection,
  123. IsArray: meta.Array,
  124. })
  125. }
  126. typ = meta.Type + posfix
  127. if typ == "any" {
  128. typ = "interface{}"
  129. }
  130. if meta.Array {
  131. hasAddOrRemove = true
  132. propertie.Op("*")
  133. propertie.Index()
  134. if !meta.Readonly {
  135. extName = "Add" + propName
  136. addUpdate[extName] = meta.ID
  137. extend = G.Id(extName).Index().Id(ConvType(typ)).Tag(map[string]string{
  138. "json": extName + ",omitempty",
  139. "bson": extName + ",omitempty",
  140. })
  141. patchProperties = append(patchProperties, extend)
  142. extName = "Remove" + propName
  143. removeUpdate[extName] = map[string]string{
  144. "type": ConvType(typ),
  145. "propId": meta.ID,
  146. }
  147. extend = G.Id(extName).Index().Interface().Tag(map[string]string{
  148. "json": extName + ",omitempty",
  149. "bson": extName + ",omitempty",
  150. })
  151. patchProperties = append(patchProperties, extend)
  152. }
  153. }
  154. // propertie.Id(entityInfo.TranslateType(meta.Type) + posfix)
  155. if strings.Contains(typ, ".") {
  156. typt := strings.Split(typ, ".")
  157. propertie.Qual(ImportMap(typt[0]), ConvType(typt[1]))
  158. } else {
  159. propertie.Id(ConvType(typ))
  160. }
  161. entity.HasMode = true
  162. // Adiciona as tags caso sejam definidas
  163. if meta.Tags != nil {
  164. // if name, ok := meta.Tags["valid"]; ok && strings.Contains(name, "requiredOnCreate") {
  165. // entity.HasMode = true
  166. // }
  167. propertie.Tag(meta.Tags)
  168. // if name, ok := meta.Tags["json"]; ok {
  169. // // tsPropertieName = strings.Split(name, ",")[0]
  170. // }
  171. } else {
  172. // tsPropertieName = meta.ID
  173. }
  174. // Adiciona a crescricao como comentario
  175. // tsPropertie = &ts.Group{}
  176. if meta.Description != "" {
  177. propertie.Comment(meta.Description)
  178. // tsPropertie.Comment(meta.Description)
  179. }
  180. // if tsPropertieName != "" {
  181. // tsPropertie.Add(ts.Public().Id(tsPropertieName).Op(":").Id(ts.ConvType(meta.Type)))
  182. // if meta.Array {
  183. // tsPropertie.Add(ts.Index())
  184. // }
  185. // tsPropertie.Endl()
  186. // tsProperties = append(tsProperties, tsPropertie)
  187. // }
  188. cproperties[meta.ID] = propertie
  189. // Adiciona o valor padrao de inicializacao
  190. // spew.Dump(meta)
  191. // if tvalue, ok := meta.Autogenerate["create"]; ok {
  192. // switch tvalue {
  193. // case "objectId":
  194. // values[G.Id(propName)] = G.Qual(BSON_PRIMITIVE, "NewObjectID").Call()
  195. // case "now":
  196. // values[G.Id(propName)] = G.Qual("time", "Now").Call().Id(".Unix()")
  197. // case "time:now":
  198. // case "user:current":
  199. // default:
  200. // // Verifica se possui valor padrão
  201. // if meta.Default != nil {
  202. // values[G.Id(propName)] = G.Lit(meta.Default)
  203. // }
  204. // }
  205. // }
  206. // Adiciona as propriedades readonly na entidade principal
  207. // e as que tem permissao de escrita na entidade input
  208. if !meta.Readonly {
  209. inputProperties = append(inputProperties, propertie)
  210. } else {
  211. properties = append(properties, propertie)
  212. }
  213. // Adiciona a propriedade que é referencia a lista de propriedades
  214. // da entidade reference
  215. if meta.Reference {
  216. if propName == "Id" {
  217. propertie = G.Id("Id").Interface().Tag(map[string]string{
  218. "json": "_id",
  219. "bson": "_id",
  220. })
  221. }
  222. referenceProperties = append(referenceProperties, propertie)
  223. }
  224. }
  225. extend = G.Qual(API_URL, "EntityModel").Tag(map[string]string{
  226. "json": "-",
  227. "bson": ",inline",
  228. })
  229. inputProperties = append(G.Statement{extend}, inputProperties...)
  230. if len(inputProperties) > 0 {
  231. // if entity.HasMode {
  232. // values[G.Id("Mode")] = G.Qual(API_URL, "Mode").Values(G.Dict{
  233. // G.Id("M"): G.Lit("create"),
  234. // })
  235. // }
  236. if len(properties) == 0 {
  237. properties = inputProperties
  238. patchProperties = append(patchProperties, G.Id("Set").Op("*").Id(entityName).Tag(map[string]string{
  239. "json": "$set,omitempty",
  240. "bson": "$set,omitempty",
  241. }))
  242. } else {
  243. inputName = entity.ID + "Input"
  244. extend = G.Id(inputName).Tag(map[string]string{
  245. "json": ",inline",
  246. "bson": ",inline",
  247. })
  248. properties = append(G.Statement{extend}, properties...)
  249. f.Comment("Representação Input aplicada em operações de update.")
  250. f.Type().Id(inputName).Struct(inputProperties...)
  251. patchProperties = append(patchProperties, G.Id("Set").Op("*").Id(inputName).Tag(map[string]string{
  252. "json": "$set,omitempty",
  253. "bson": "-",
  254. }))
  255. }
  256. }
  257. if len(referenceProperties) > 0 {
  258. f.Comment("Representação reference aplicada quando a entidade é associada a outra.")
  259. f.Type().Id(entity.ID + "Reference").Struct(referenceProperties...)
  260. }
  261. // if entity.Representations != nil {
  262. // for k, rep := range entity.Representations {
  263. // tproperties = G.Statement{}
  264. // for _, attr := range rep {
  265. // tproperties = append(tproperties, cproperties[attr])
  266. // }
  267. // f.Comment("Representação " + k)
  268. // f.Type().Id(entity.ID + k).Struct(tproperties...)
  269. // }
  270. // }
  271. if len(patchProperties) > 1 {
  272. entityPatchName = fmt.Sprintf("%sPatchs", entityName)
  273. f.Comment(entity.Description).Line().Comment("Representação de atualização")
  274. // patchProperties = append(G.Statement{*entityModel}, patchProperties)
  275. f.Type().Id(entityPatchName).Struct(patchProperties...)
  276. }
  277. // Cria a entidade normal
  278. f.Comment(entity.Description).Line().Comment("Representação Completa")
  279. f.Type().Id(entityName).Struct(properties...)
  280. // Cria a entidade em typescript
  281. // tsModels.Line().Export().Class().Id(strings.Title(entity.ID)).Block(tsProperties...).Line()
  282. f.Comment("Cria uma instancia de " + entity.ID + ".")
  283. // Cria a função de instanciar um novo elemento com os valores padrão determinados
  284. f.Func().Id("New"+entityName).Params().Op("*").Id(entityName).Block(
  285. G.Id("entity").Op(":=").Op("&").Id(entityName).Values(),
  286. G.Do(func(x *G.Statement) {
  287. if entity.HasMode {
  288. x.Add(G.Id(`entity.SetMode("create")`))
  289. }
  290. }),
  291. G.Do(func(part *G.Statement) {
  292. // user := false
  293. for _, prop := range entity.Properties {
  294. typ := ConvType(prop.Type)
  295. isMap := strings.Contains(typ, "map")
  296. if prop.Relation {
  297. typ = typ + "Reference"
  298. }
  299. if def, ok := prop.Autogenerate["create"]; ok {
  300. switch def.Type {
  301. case "objectId":
  302. part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Qual(BSON_PRIMITIVE, "NewObjectID()").Line())
  303. case "now":
  304. part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Qual("time", "Now").Call().Id(".Unix()").Line())
  305. case "default":
  306. part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Lit(prop.Default).Line())
  307. }
  308. } else if prop.Array {
  309. part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("= &").Index().Id(typ).Values().Line())
  310. } else if isMap {
  311. part.Add(G.Id("entity").Dot(strings.Title(prop.ID)).Op("=").Id(typ).Values().Line())
  312. }
  313. }
  314. }).Line(),
  315. G.Return(G.Id("entity")).Line(),
  316. )
  317. // update = bson.M{"$set": f.Entity}
  318. // if data, ok = f.Entity.Push(); ok {
  319. // update["$push"] = data
  320. // }
  321. // if data, ok = f.Entity.Pull(); ok {
  322. // update["$pull"] = data
  323. // }
  324. if entityPatchName != "" {
  325. f.Func().Params(
  326. G.Id("t").Op("*").Id(entityPatchName),
  327. ).Id("Patch").Params().Op("*").Qual(BSON, "A").Block(
  328. G.Id("updt").Op(":=").Qual(BSON, "A").Values(
  329. G.Qual(BSON, "M").Values(G.Lit("$set").Id(": t.Set")),
  330. ).Line(),
  331. G.Do(func(y *G.Statement) {
  332. if !hasAddOrRemove {
  333. return
  334. }
  335. stmts := G.Statement{
  336. G.Id("hasAdd").Op(":=").Lit(0).Line(),
  337. G.Id("hasRemove").Op(":=").Lit(0).Line(),
  338. G.Id("pull").Op(":=").Qual(BSON, "M").Values().Line(),
  339. G.Id("push").Op(":=").Qual(BSON, "M").Values().Line(),
  340. }
  341. // add entitys
  342. // spew.Dump(addUpdate)
  343. for prop, value := range addUpdate {
  344. stmts = append(stmts, G.If(G.Len(G.Id("t").Dot(prop)).Op(">").Lit(0)).Block(
  345. G.Id("hasAdd").Op("++"),
  346. G.Id("push").Index(G.Lit(value)).Op("=").Qual(BSON, "M").Values(G.Dict{
  347. G.Lit("$each"): G.Id("t").Dot(prop),
  348. }),
  349. ).Line())
  350. }
  351. // spew.Dump(removeUpdate)
  352. // remove entitys
  353. for prop, value := range removeUpdate {
  354. stmts = append(stmts, G.If(G.Len(G.Id("t").Dot(prop)).Op(">").Lit(0)).Block(
  355. G.Id("hasRemove").Op("++"),
  356. G.Do(func(hasRemove *G.Statement) {
  357. var assign G.Dict
  358. // Se o array for de um atributo de tipo primitivo
  359. if primitiveRegex.MatchString(value["type"]) {
  360. assign = G.Dict{
  361. G.Lit("$in"): G.Id("t").Dot(prop),
  362. }
  363. } else {
  364. assign = G.Dict{
  365. G.Lit("_id"): G.Qual(BSON, "M").Values(G.Dict{
  366. G.Lit("$in"): G.Id("t").Dot(prop),
  367. }),
  368. }
  369. }
  370. hasRemove.Id("pull").Index(G.Lit(value["propId"])).Op("=").Qual(BSON, "M").Values(assign)
  371. }),
  372. ).Line())
  373. }
  374. // fmt.Println("Remove:", inputName, prop, value)
  375. // fmt.Printf("%#v", G.If(G.Len(G.Id("t").Dot(prop)).Op(">").Lit(0)).Block(
  376. // G.Id("hasRemove").Op("++"),
  377. // G.Id("pull").Index(G.Lit(value)).Op("=").Qual(BSON, "M").Values(G.Dict{
  378. // G.Lit("$in"): G.Id("t").Dot(prop),
  379. // }),
  380. // ).Line())
  381. // x.Add(G.If(G.Len(G.Id("t").Dot(prop)).Op(">").Lit(0)).Block(
  382. // G.Id("hasRemove").Op("++"),
  383. // G.Id("pull").Index(G.Lit(value)).Op("=").Qual(BSON, "M").Values(G.Dict{
  384. // G.Lit("$in"): G.Id("t").Dot(prop),
  385. // }),
  386. // ).Line())
  387. stmts = append(stmts, G.If(G.Id("hasAdd").Op(">").Lit(0)).Block(
  388. // G.Id("updt").Index(G.Lit("$push")).Op("=").Id("push"),
  389. G.Id("updt").Op("=").Append(
  390. G.Id("updt"),
  391. G.Qual(BSON, "M").Values(G.Lit("$push").Id(": push")),
  392. ),
  393. // .Index(G.Lit("$push")).Op("=").Id("push"),
  394. ).Line())
  395. stmts = append(stmts, G.If(G.Id("hasRemove").Op(">").Lit(0)).Block(
  396. // G.Id("updt").Index(G.Lit("$pull")).Op("=").Id("pull"),
  397. G.Id("updt").Op("=").Append(
  398. G.Id("updt"),
  399. G.Qual(BSON, "M").Values(G.Lit("$pull").Id(": pull")),
  400. ),
  401. ).Line())
  402. y.Add(stmts...)
  403. }),
  404. G.Return(G.Op("&").Id("updt")),
  405. )
  406. }
  407. // Salva o arquivo da entidade
  408. // if err := f.Save(fmt.Sprintf("%s/%s/%s_gen.go", p.OutPath, p.Package, filename)); err != nil {
  409. if err := Write(fmt.Sprintf("%s/%s/%s_gen.go", p.OutPath, p.Package, filename), f); err != nil {
  410. return err
  411. }
  412. } // Fim do for de schema
  413. return nil
  414. }
  415. func ConvType(ntype string) string {
  416. if len(ntype) < 3 {
  417. fmt.Printf("Invalid type name '%s':\n", ntype)
  418. }
  419. if ntype[0:3] == "map" {
  420. parts := strings.Split(ntype, "|")
  421. ntype = fmt.Sprintf("map[%s]%s", parts[1], parts[2])
  422. }
  423. return ntype
  424. }
  425. func GenModelIndex(p *Project) error {
  426. var (
  427. // Index = G.NewFile(p.Package)
  428. Index = G.NewFile("models")
  429. )
  430. Index.Id(`type Entity struct {}`).Line()
  431. Index.Comment("")
  432. Index.Var().Defs(
  433. G.Id("Api").Op("=").Op("&").Qual(API_URL, "Mongo").Values(),
  434. ).Line()
  435. return Write(fmt.Sprintf("%s/%s/models/index_gen.go", p.OutPath, p.Package), Index)
  436. }
  437. func fill(p *Project, schema *Entity) (*Entity, error) {
  438. var (
  439. // found, ok bool
  440. found bool
  441. cls *Entity
  442. // newSchema = &(*schema)
  443. err error
  444. )
  445. // Se o esquema ainda não esta completo com as classes extendidas caso possua
  446. if _, found = filled[schema.ID]; !found {
  447. // fEntity = schema
  448. //
  449. // fmt.Println("Fill ............ ", schema.ID)
  450. // fmt.Println("Nao estava cheio ", schema.ID)
  451. for _, entity := range schema.Extends {
  452. if cls, err = fill(p, p.GetSchema(entity)); err != nil {
  453. return nil, err
  454. }
  455. // fmt.Println("extends ", entity)
  456. // if cls, ok = filled[entity]; !ok {
  457. // cls = p.GetSchema(entity)
  458. // // fmt.Println("Não tava cheio", entity)
  459. // // fmt.Println("fill:", schema)
  460. // // fmt.Println(cls)
  461. // if err = fill(p, cls); err != nil {
  462. // return err
  463. // }
  464. // }
  465. // else {
  466. // fmt.Println("estava cheio ", entity)
  467. // fmt.Println("Merge ", schema.ID, cls.ID, ok)
  468. schema.Properties = append(schema.Properties, cls.Properties...)
  469. }
  470. // for _, x := range schema.Properties {
  471. // fmt.Println("fill----------------", schema.ID, x.ID, len(schema.Properties))
  472. // }
  473. filled[schema.ID] = schema
  474. }
  475. return filled[schema.ID], nil
  476. }
  477. func Schemas(p *Project) ([]*Entity, error) {
  478. var (
  479. err error
  480. entities = []*Entity{}
  481. )
  482. for _, schema := range p.Schemas {
  483. if schema, err = fill(p, schema); err != nil {
  484. return nil, err
  485. }
  486. if schema.Type != "abstract" {
  487. entities = append(entities, schema)
  488. }
  489. // for _, x := range schema.Properties {
  490. // fmt.Printf("%s , %s, %p\n", schema.ID, x.ID, x)
  491. // }
  492. }
  493. // for _, s := range entities {
  494. // for _, x := range s.Properties {
  495. // fmt.Printf("final-schemas....%s , %s, %p\n", s.ID, x.ID, x)
  496. // }
  497. // }
  498. return entities, nil
  499. }
  500. func GenFilterEntityDocument(p *Project) error {
  501. var (
  502. content string
  503. path string
  504. err error
  505. )
  506. for _, s := range p.Schemas {
  507. if s.Type == "nested.object" {
  508. continue
  509. }
  510. // fmt.Println("gerando filtro ", s.ID)
  511. filter := &ApiFilter{
  512. Id: strings.ToLower(s.ID),
  513. Date: time.Now().Unix(),
  514. }
  515. for _, attr := range s.Properties {
  516. if attr.Filter == nil {
  517. continue
  518. }
  519. // Atualiza o tipo do filtro na estrutura do campo
  520. for _, filterItem := range attr.Filter {
  521. FilterTypeMap(attr, filterItem)
  522. // Atualiza o path da query
  523. if filterItem.Type == "nested" {
  524. FilterPath(filter, p, attr, attr.ID)
  525. } else {
  526. if filterItem.Path == "" {
  527. filterItem.Path = attr.ID
  528. }
  529. if filterItem.UserEnumAsOptions {
  530. filterItem.Options = []FilterOption{}
  531. // if len(attr.Values) == 0 {
  532. // attr.Values = make([]string, len(attr.Enum))
  533. // }
  534. // values = make()
  535. // }
  536. for key, value := range attr.Enum {
  537. filterItem.Options = append(filterItem.Options, FilterOption{
  538. Value: attr.Values[key],
  539. Label: value,
  540. })
  541. }
  542. }
  543. filter.Fields = append(filter.Fields, filterItem)
  544. }
  545. }
  546. }
  547. if filter.Fields == nil {
  548. continue
  549. }
  550. if content, err = JSONStringfy(filter); err != nil {
  551. return err
  552. }
  553. path = fmt.Sprintf("%s/filters/%s.json", p.OutPath, strings.ToLower(s.ID))
  554. // fmt.Printf("storing filter '%s'\n",path)
  555. if err = FilePutContents(path, content, 0777); err != nil {
  556. return err
  557. }
  558. }
  559. return nil
  560. }
  561. func FilterPath(filter *ApiFilter, p *Project, attr *Propertie, path string) {
  562. var (
  563. nfil Filter
  564. npath string
  565. typ = attr.Type
  566. )
  567. if attr.Relation {
  568. typ += "Reference"
  569. }
  570. entity := p.GetSchema(typ)
  571. for _, x := range entity.Properties {
  572. if x.Filter == nil {
  573. continue
  574. }
  575. npath = fmt.Sprintf("%s.%s", path, x.ID)
  576. for _, item := range x.Filter {
  577. if item.Type != "nested" {
  578. nfil = *item
  579. if nfil.Path == "" {
  580. nfil.Path = npath
  581. }
  582. FilterTypeMap(x, item)
  583. filter.Fields = append(filter.Fields, &nfil)
  584. } else {
  585. FilterPath(filter, p, x, npath)
  586. }
  587. }
  588. }
  589. }
  590. func FilterTypeMap(attr *Propertie, f *Filter) {
  591. typ := f.Type
  592. if typ != "" {
  593. return
  594. }
  595. switch {
  596. // Se o tipo for numerico
  597. case numberRegex.Match([]byte(typ)):
  598. f.Type = "number"
  599. default:
  600. f.Type = attr.Type
  601. }
  602. }
  603. func generateIndexsEntity(file *G.File, entity *Entity) {
  604. // keys := G.{}
  605. // options := G.Dict{
  606. // G.Id("Unique"): G.Lit(true),
  607. // // G.Id("Key"): G.Lit("unique"),
  608. // // G.Id("Value"): G.Lit(true),
  609. // }
  610. var create = false
  611. indexOptions := G.Dict{
  612. G.Id("Keys"): G.Qual(BSONX, "Doc").ValuesFunc(func(keys *G.Group) {
  613. for _, propertie := range entity.Properties {
  614. if propertie.Unique {
  615. keys.Add(G.Values(G.Lit(propertie.ID), G.Qual(BSONX, "Int32").Call(G.Lit(1))))
  616. create = true
  617. // keys[G.Lit(propertie.ID)] = G.Lit(1)
  618. }
  619. }
  620. }),
  621. // G.Id("Options"): G.Qual(BSON, "M").Values(options),
  622. G.Id("Options"): G.Id("opts.SetUnique(true)"),
  623. }
  624. if create {
  625. file.Line().Func().Id("init").Call().Block(
  626. G.Id("models.Api.Ready().Subscribe").Call(
  627. G.Func().Call(G.Id("value").Id("...interface{}")).Block(
  628. G.Id("opts := &").Qual("go.mongodb.org/mongo-driver/mongo/options", "IndexOptions").Values(),
  629. G.Id(`index := `).Qual("go.mongodb.org/mongo-driver/mongo", "IndexModel").Values(indexOptions),
  630. // G.Qual("fmt", "Println").Call(G.Lit("create index for "), G.Lit(entity.ID)),
  631. G.Id(`if err := models.Api.CreateIndex(`).Lit(entity.DB).Id(`, `).Lit(entity.Collection).Id(`, index); err != nil`).
  632. Block(
  633. G.Id("panic").Call(
  634. G.Qual("fmt", "Sprintf").Call(
  635. // G.Lit(fmt.Sprintf("Index %s creation error %s", entity.ID, err.Error())),
  636. G.Id(`"Index`).Id(entity.ID).Id(`creation error %s", err.Error()`),
  637. ),
  638. ).Line(),
  639. // (`).
  640. // Call().
  641. // Line().
  642. ),
  643. ),
  644. ),
  645. )
  646. // .BlockFunc(func(statement *G.Group) {
  647. // statement.Add(
  648. // ,
  649. // )
  650. // statement.Add(G.Line().Id("})"))
  651. // })
  652. }
  653. }