middleware_delete.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. package got
  2. import (
  3. "text/template"
  4. . "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/common"
  5. G "github.com/dave/jennifer/jen"
  6. )
  7. const ()
  8. var (
  9. deleteStmtsTmpl, hasDepDeleteStmtsTmpl *template.Template
  10. deleteStmtsErr error
  11. )
  12. func init() {
  13. deleteStmtsTmpl, deleteStmtsErr = ParseTemplate(`
  14. filter := ctx.Values().Get("$filter").(*api.Filter)
  15. filter.DB = "{{.dbName}}"
  16. filter.Collection = "{{.collectionName}}"
  17. {{if .createDepFunc}}
  18. if HasDep{{.entity}}(filter) {
  19. err = errs.FailedPrecondition().Details(&errs.Detail{
  20. Message: "Ocorreu um conflito ao remover a entidade '{{.entity}}'",
  21. })
  22. return
  23. }
  24. {{end}}
  25. {{if .preconditions}}
  26. if _, err = executeAction(
  27. ctx,
  28. {{.preconditions}},
  29. ); err != nil {
  30. return
  31. }
  32. {{end}}
  33. if replacement := ctx.Values().Get("replace.default.patch"); replacement != nil {
  34. filter.Patchs = replacement.(*bson.A)
  35. } else {
  36. filter.Patchs = api.DeletedPatch()
  37. }
  38. if _, err = models.Api.PatchOne(filter); err != nil {
  39. err.Details(&errs.Detail{
  40. Dominio: "",
  41. Reason: "",
  42. Location: "middleware.path",
  43. LocationType: "middleware.operation",
  44. })
  45. }
  46. {{if .beforeResponse}}
  47. if resp, err = executeAction(
  48. ctx,
  49. {{.beforeResponse}},
  50. ); err != nil || resp != nil {
  51. return
  52. }
  53. {{end}}
  54. resp = ""
  55. return`)
  56. if deleteStmtsErr != nil {
  57. panic(deleteStmtsErr)
  58. }
  59. hasDepDeleteStmtsTmpl, deleteStmtsErr = ParseTemplate(`
  60. // {{.dependenceMethod}} verifica se a entidade '{{.entity}}' possui dependencias com outras entidades.
  61. func {{.dependenceMethod}}(options *api.Filter) bool {
  62. var (
  63. foundChan = make(chan bool)
  64. find = func(db, collection, attr string) {
  65. exists, _ := models.Api.Exists(&api.Filter{
  66. DB: db,
  67. Collection: collection,
  68. Query: &bson.M{attr: options.Id},
  69. })
  70. foundChan <- exists
  71. }
  72. )
  73. {{range .relations}}
  74. go find("{{.DB}}", "{{.Collection}}", "{{.Attr}}._id")
  75. {{end}}
  76. for i := 0; i < {{.relationCount}}; i++ {
  77. select {
  78. {{range $idx, $relation := .relations}} case x{{$idx}} := <-foundChan:
  79. if x{{$idx}} {
  80. return true
  81. }
  82. {{end}}
  83. }
  84. }
  85. return false
  86. }`)
  87. if deleteStmtsErr != nil {
  88. panic(deleteStmtsErr)
  89. }
  90. }
  91. var (
  92. GenDeleteStmts = &Middleware{
  93. Id: "delete",
  94. Type: "method",
  95. Fn: func(ctx *MiddlewareContext) error {
  96. var (
  97. project = ctx.Project
  98. method = ctx.Method
  99. dbName = project.GetEntityDB(method.Entity)
  100. collectionName = project.GetCollection(method.Entity)
  101. relations = SR.Get(method.Entity)
  102. relationCount = len(relations)
  103. dependenceMethod = BASE_HAS_DEPENDE + method.Entity
  104. createDepFunc = SR.Has(method.Entity)
  105. beforeSend = method.Hook("beforeSend")
  106. beforePersist = method.Hook("beforePersist")
  107. context = map[string]interface{}{
  108. "dbName": dbName,
  109. "collectionName": collectionName,
  110. "entity": method.Entity,
  111. "createDepFunc": createDepFunc,
  112. "relationCount": relationCount,
  113. "relations": relations,
  114. "dependenceMethod": dependenceMethod,
  115. "beforePersist": beforePersist,
  116. "beforeSend": beforeSend,
  117. "preconditions": parseMethodActions(method.Preconditions),
  118. "beforeResponse": parseMethodActions(method.BeforeResponse),
  119. }
  120. )
  121. // Nome do metodo que verifica se a entidade tem dependencias
  122. out, _ := TemplateToString(deleteStmtsTmpl, context)
  123. afterMethod := ctx.Statement.Block(G.Id(out)).Line()
  124. if createDepFunc {
  125. out, _ = TemplateToString(hasDepDeleteStmtsTmpl, context)
  126. afterMethod.Id(out)
  127. }
  128. return nil
  129. },
  130. }
  131. )
  132. // afterDefineDelete.Do(func(x *G.Statement) {
  133. // x.Add(G.Comment(
  134. // fmt.Sprintf("%s verifica se a entidade '%s' possui dependencias com outras entidades.", dependenceMethod, method.Entity),
  135. // ).Line())
  136. // // Cria as variaveis
  137. // block := G.Func().Id(dependenceMethod).Params(
  138. // G.Id("f").Op("*").Qual(API_URL, "Filter"),
  139. // ).Bool().BlockFunc(func(b *G.Group) {
  140. // for index, relation := range relations {
  141. // // for index, _ := range relations {
  142. // indexStr = strconv.Itoa(index)
  143. // cIndex = "c" + indexStr
  144. // xIndex = "x" + indexStr
  145. // // Cria o canal para a variavel
  146. // vars = append(vars, G.Id(cIndex).Op("=").Id("make").Call(G.Chan().Bool()))
  147. // // Define um case para um canal
  148. // cases = append(cases, G.Case(G.Id(xIndex).Op(":=").Op("<-").Id("c"+indexStr)).Block(
  149. // G.If(G.Id(xIndex)).Block(G.Return(G.True())),
  150. // ))
  151. // rotines = append(rotines, G.Go().Func().Params().Block(
  152. // G.Id("filter").Op(":=").Op("&").Qual(API_URL, "Filter").Values(G.Dict{
  153. // // Especifica a collection
  154. // G.Id("DB"): G.Lit(relation.DB),
  155. // G.Id("Collection"): G.Lit(relation.Collection),
  156. // // Especifica a query
  157. // G.Id("Query"): G.Op("&").Qual(BSON, "M").Values(G.Dict{
  158. // G.Lit(relation.Attr + "._id"): G.Id("f").Dot("Id"),
  159. // }),
  160. // }),
  161. // G.Id(cIndex).Op("<-").Id("Models").Dot("Exist").Call(G.Id("filter")),
  162. // ).Call().Line())
  163. // }
  164. // // Adiciona as variaveis de canal
  165. // b.Add(G.Var().DefsFunc(func(b2 *G.Group) {
  166. // // Gera o case para cada relacao
  167. // for _, v := range vars {
  168. // b2.Add(v)
  169. // }
  170. // }))
  171. // // Adiciona as chamadas das rotinas que consultam a existencia de dependencia
  172. // for _, r := range rotines {
  173. // // fmt.Printf("%#v", r)
  174. // b.Add(r)
  175. // }
  176. // // Geracao do for select
  177. // b.Add(G.For(
  178. // G.Id("i").Op(":=").Lit(0),
  179. // G.Id("i").Op("<").Lit(relationCount),
  180. // G.Id("i").Op("++"),
  181. // ).Block(G.Select().BlockFunc(func(b1 *G.Group) {
  182. // // Gera o case para cada relacao
  183. // for _, case1 := range cases {
  184. // b1.Add(case1)
  185. // }
  186. // })).Line())
  187. // b.Return(G.False())
  188. // // fmt.Printf("%#v")
  189. // })
  190. // x.Add(block)
  191. // }).Line()
  192. // if {
  193. // createDepFunc = true
  194. // do.Add(G.If(G.Id(dependenceMethod).Call(
  195. // G.Id("filter"),
  196. // )).Block(
  197. // G.Id("err").Op("=").Qual(API_URL, "Error").Call(
  198. // G.Qual(API_URL, "ERR_CONFLICT"),
  199. // G.Lit(fmt.Sprintf("Ocorreu um conflito ao remover a entidade '%s'", method.Entity)),
  200. // ),
  201. // G.Return(),
  202. // ).Line())
  203. // }
  204. // ctx.Statement.Block(
  205. // G.Id(`filter := ctx.Values.Get("$filter")`).Assert(G.Op("*").Qual(API_URL, "Filter")).Line(),
  206. // G.Id("filter").Dot("DB").Op("=").Lit(dbName),
  207. // G.Id("filter").Dot("Collection").Op("=").Lit(collectionName).Line(),
  208. // // Verifica se o tem tem dependencias
  209. // G.Do(func(do *G.Statement) {
  210. // if SR.Has(method.Entity) {
  211. // createDepFunc = true
  212. // do.Add(G.If(G.Id(dependenceMethod).Call(
  213. // G.Id("filter"),
  214. // )).Block(
  215. // G.Id("err").Op("=").Qual(API_URL, "Error").Call(
  216. // G.Qual(API_URL, "ERR_CONFLICT"),
  217. // G.Lit(fmt.Sprintf("Ocorreu um conflito ao remover a entidade '%s'", method.Entity)),
  218. // ),
  219. // G.Return(),
  220. // ).Line())
  221. // }
  222. // // fmt.Println("GenerateFunc" + method.Entity + "|" + dependenceMethod)
  223. // }),
  224. // G.Do(func(s *G.Statement) {
  225. // if method.BeforePersistAction {
  226. // fnName := fmt.Sprintf("Before%s%s", strings.Title(method.ID), method.Entity)
  227. // s.Add(G.Id(fmt.Sprintf(`
  228. // // Chama uma função onde são descritas as ações executadas antes da entidade ser persistida.
  229. // if err = %s(ctx, resp); err != nil {
  230. // return
  231. // }
  232. // `, fnName)))
  233. // // part := s.Comment("").Line()
  234. // // part.If(
  235. // // G.List(G.Id("fn"), G.Id("err")).Op("=").Id(fnName).Call(G.Id("ctx"), G.Id("patchs")),
  236. // // G.Id("err").Op("!=").Id("nil"),
  237. // // ).Block(G.Return())
  238. // }
  239. // }),
  240. // // Executa a remocao do item
  241. // // G.If(
  242. // // G.List(G.Id("_"), G.Id("err")).Op("=").Id("Models").Dot("RemoveOne").Call(
  243. // // G.Id("filter"),
  244. // // ),
  245. // G.Id(`
  246. // filter.Patchs = &`).Qual(BSON, "A").Id(`{
  247. // bson.M{
  248. // "$set": bson.M{
  249. // "deleted": true,
  250. // "deletedIn": `).Qual("time", "Now").Id(`().Unix(),
  251. // },
  252. // },
  253. // }`),
  254. // generateHookCall(project, method, "beforePersist"),
  255. // G.Id(`if _, err = models.Api.PatchOne(filter), err !`),
  256. // G.Return(),
  257. // // G.Return(G.Nil()),
  258. // ).
  259. // --------------------------------------------------
  260. // G.Id("err").Op("!=").Id("nil"),
  261. // ).Block(
  262. // G.Return(G.Id("err")),
  263. // G.Return(),
  264. // ),
  265. // G.Var().Defs(
  266. // G.Id("err").Op("*").Qual(API_ERROR, "Error"),
  267. // // G.Id("entity").Op("=").Op("&").Id(method.Entity).Values(),
  268. // ).Line(),
  269. // fmt.Println("Compont:" + method.Entity)
  270. // block.Add(
  271. // x.Var().Defs(
  272. // G.Id("err").Op("*").Qual(API_ERROR, "Error"),
  273. // G.Id("entity").Op("=").Op("&").Id(method.Entity).Values(),
  274. // ),
  275. // )
  276. // vars.Defs(varList...)