[00:00] Então vamos começar o nosso curso. Como de costume a gente vai pegar o projeto do curso anterior e vou copiar e abrir dentro do meu IntelliJ. Isso é, vou dar um file open project, ou só open, escolher o diretório onde está o meu projeto. No caso está em guilhermedatomic6. Projeto ecommerce. Eu abro o projeto aqui e a gente continua esse projeto.
[00:28] Se você já fez o projeto do curso anterior, só continuar ele, se você não fez, mas acredita que consegue pegar o curso a partir daqui, sem problemas, só baixar o projeto de acordo com as atividades.
[00:39] A gente tem aqui a aula1 até a aula5, que são as aulas do último curso. Eu vou apagar da aula1 até a aula4 e a aula5 na verdade eu vou renomear para aula1. Ele vai reclamar, eu mando corrigir para o nome adequado.
[00:55] O que a gente vai fazer? As coisas de sempre: criar produtos, criar vendas e parar por aí. Parei por aqui.
[01:04] Eu quero testar que isso está funcionando. Lembra de acompanhar? A gente vai lá, roda o nosso transactor, o transactor que é quem pode escrever no banco. Lembrando que a gente tem um transactor escrevendo no banco e pode ter outro transactor de backup para escrita também. É bem comum esse cenário. É o cenário comum aliás.
[01:24] Comecei aqui o meu Datomic. Posso rodar o meu console se eu quisesse. Não é o meu caso. Eu não vou rodar o console. Eu vou rodar o project.clj só para ter certeza que eu estou com tudo ok. Mando rodar o REPL. E aí a gente vai carregar essa aula1 para ter certeza que estamos rodando, cadastrando produtos, cadastrando categorias, vendas, variações, que está tudo ok. Vamos dar uma olhada. Vou diminuir aqui o meu código. Diminui o meu código. Carrego meu arquivo.
[01:55] Não encontrei o símbolo 1 do produto nesse contexto. Faltou um produto. O Guilherme esqueceu de escrever id um nesse arquivo. Aqui é simplesmente um nesse arquivo. Mas algum arquivo aqui que esteja com outra diferença? Não tenho certeza. Tenho que rodar e descobrir. Vamos recarregar. Recarreguei. Parece estar tudo ok.
[02:20] Posso até rodar o REPL de novo para ter certeza. Enquanto eu carrego o REPL, eu já vou mover essas vendas. Essas três primeiras vendas que eu tenho aqui eu posso mover elas para dentro do nosso cria dados de exemplo. A gente pode deixar aqui dentro dos dados de exemplo. A gente criou várias coisas: categorias, exemplo dos produtos. Eu posso criar três vendas também. Essas três vendas que eu tenho aqui. Eu adiciono uma venda, uma segunda venda, uma terceira venda.
[02:44] Claro, qual vai ser o id? Vai ser o id de algum produto. Eu posso escolher um produto, que pode ser o computador. Então eu vou adicionar três vendas aos meus computadores. Refere que eu não preciso desse def porque a gente não vai usar essas vendas. A gente não está usando isso daqui, a gente só vai executá-las, eu não estou interessado nos retornos. Então eu crio três vendas também. Criei três vendas de computadores.
[03:11] O meu computador tem um id. Vai funcionar. Ok. Então aqui tem os produtos. Eu posso pegar o produto se eu quiser ou posso simplesmente imprimir os produtos se é o meu interesse. Eu poderia ter simplesmente um pprint para imprimir os vários produtos. E vou carregar então.
[03:29] Vamos ver. db/venda. Faltou alguma coisa? Claro, porque nos exemplos a gente não está importando db/venda. Vamos lá. ecommerce, venda as db/venda. Recarrego. Está rodando. Está imprimindo os produtos.
[03:53] Estou feliz com esses produtos? Não, não estou. Eu quero gerar muito mais produtos. Eu quero conectar aquilo que a gente já trabalhou em outros cursos, que são os geradores baseados em schemas. A gente já viu geradores baseados não em schemas, baseados em coisas menores. Depois a gente viu baseados em schemas, utilizando os schemas do Plumetic. E aí depois, agora, eu quero usar isso para gerar dados para o meu banco. Eu quero gerar um monte de dado no meu banco.
[04:20] Eu queria ser capaz de gerar uma categoria. Por que uma categoria? Vamos lá no nosso modelo. Se a gente for no modelo, a gente tem a venda, a venda referencia um produto, o produto, a variação. A categoria é o mais simples. Então eu queria gerar uma categoria. Eu queria começar por aí.
[04:37] Como a gente faz isso? A gente usa aquela biblioteca de schema generator da Plumetic. Eu quero usar essa biblioteca. Como eu uso ela? Preciso referenciar ela lá no meu project.clj. Vamos lá no project.clj. Vamos adicionar como dependência essa versão. A gente já tem o schema, mas agora eu preciso do Plumetic schema generators, que vai gerar os schemas, 0.1.3. Maravilha. Então eu tenho o schema generators aqui. Vai recarregar. Eu posso dar um import changes por aqui.
[05:19] Lembrando que o REPL você tem que recarrega, você tem que dar um stop e um start.
[05:23] Além disso, a gente vai utilizar aquelas funções de teste que geram samples para a gente. As funções que geravam samples para a gente era do test.check. Então, do Clojure, test.check era a biblioteca que a gente quer também colocar. Então o test.check eu também quero importar aqui para o meu projeto. org.clojure/test.check “0.10.0”. Eu vou colocar aqui. Salvei. Ele vai perceber a diferença. Posso dar um import ou lembrando que você pode clicar em Leiningen e dar um refresh aqui.
[05:58] Vou esconder esse e vou dar um start no meu REPL agora, já com as bibliotecas carregadas. Com essas bibliotecas o que eu quero fazer? Quero começar a gerar alguns exemplos simples, usar um generator para usar alguns exemplos simples.
[06:13] Os generators que utilizam modelos são essas da Plumetic, que conectam com o nosso schema da Plumetic. Baseado no nosso schema da Plumetic, eu posso chamar um g/sample e falar qual é o nome do meu modelo. Eu posso falar: “Olha, é o schema-generators. O schema-generators vai ter o exemplo para a gente. Então eu posso pegar um schema-generators. E aí você pode definir o seu ‘g’ de generators, generate, gen. O padrão aqui está parecendo ser ‘g’, mas, se você olhar a documentação do projeto, você vai achar generator. Como não tem um padrão ainda muito claro para os schema-generators da Plumetic, vamos manter o ‘g’, que é o que padrão na página inicial.
[07:00] O meu ‘g’ aqui dele, a gente confere que o ‘g’ dele permite gerar samples sempre de acordo com o modelo. Então eu vou passar um schema, um g/sample, falar quantos que eu quero, por exemplo um, e eu quero uma categoria. Será que eu consigo criar uma categoria? Vou carregar esse arquivo inteiro, tentei carregar, ele tem que imprimir todos os produtos.
[07:25] Todos os produtos, todos os produtos. Todos os produtos. Maravilha. Model que não funcionou. Por quê? Porque a gente não está nem importando model aqui. Faltou model. ecommerce as model. Vou recarregar. Agora deu um loaded. Parece que foi. Não imprimiu porque a gente não fez um pprint. Vou rodar o meu pprint. Olha aqui, uma categoria. Uma categoria com id e nome vazio.
[07:50] Por que o nome está vazio? Gera 100 categorias. Lembra, depois os dados vão crescendo, crescendo. E o nosso sample acaba tendo nomes mais complexos. Então eu tenho aqui várias categorias.
[08:05] Se eu quiser criar categorias para utilizar em teste generativos, para utilizar onde eu quiser, eu posso usar o g/sample. Tudo que a gente estava fazendo por enquanto parece compatível.
[08:16] Tomar um cuidado. A categoria tem o id e o nome como obrigatórios. A variação tem mais. A variação tem o id, o nome e o preço. Então a gente tem que gerar mais coisas. Então a gente vai brincando com esses geradores. Então eu vou tentar gerar uma variação.
[08:37] Vou gerar uma variação. Tento rodar. Deu caca. O que é a caca? Você tem que prover um leaf-generator para o schema. E aí uma caca enorme que você não consegue ler a mensagem de erro. Bem-vindo ao mundo.
[08:54] O que está falando aqui? Está falando que não tem um gerador cadastrado para alguma coisa. Qual é a diferença entre a categoria e a variação? Isolar o problema. O problema é. A categoria tem o id e string, que claramente os generators do schema foram capazes de gerar. Aqui a gente tem o id/str e BigDecimal. BigDecimal ele não deve estar conseguindo gerar.
[09:20] Se a gente procurar Clojure schema generator BigDecimal, você vai encontrar pessoas reclamando, falando: “Não existe generator para BigDecimal”. Por que não existe? Inclusive é a resposta. E a resposta faz sentido. A resposta é a seguinte. Não vamos criar geradores para tudo na biblioteca padrão. A biblioteca tem que ter o mínimo. E aí você quer gerador para todo tipo de coisa, de tudo que existe, tem que ter uma biblioteca separada. Então BigDecimal não possui um gerador para esse tipo.
[09:54] O que acontece? O gerador, que gera valores para a gente, procura geradores de sequências, geradores de mapas. Em algum momento ele chega num gerador simples. Um gerador de mapa é um gerador de conjunto, gerador de sequência é um gerador de conjunto, gerador de tudo é gerador de conjunto. O gerador de uma string é um gerador simples, gera uma string. O gerador de um BigDecimal é para a gente gerar um BigDecimal. Quer dizer, é o finzinho de uma árvore de geração. Por isso que é um leaf-generator, é o gerador da folhinha, é bem ali na folhinha.
[10:28] Não tem esse gerador. A gente tem que cadastrar um gerador. Se a gente der uma olhada na documentação, no g/sample, em outros ‘g’s, existem variações dessa função que recebem mais argumentos. A gente pode receber mais argumentos. Que argumentos que a gente pode passar? A gente pode passar geradores próprios nossos. A gente pode cadastrar o nosso próprio leaf-generator para BigDecimal.
[11:00] Eu posso passar aqui os meus geradores. O que eu tenho que fazer? Eu tenho que definir meus geradores para um mapa vazio por enquanto. Mas esse meu mapa vai falar que, quando for para gerar um BigDecimal, eu gostaria que você usasse alguma coisa minha, algum gerador meu.
[11:25] Aqui sim eu estou falando que eu gostaria de utilizar um generator meu. Eu vou gerar um BigDecimal generator. Esse vai ser o meu generator. Então eu vou ter aqui um def BigDecimal generator, que vai fazer o quê? Que na verdade é um fmap, é uma aplicação. Ele primeiro vai gerar um double... Porque o BigDecimal é tipo um double. Já que o BigDecimal é tipo um double, o meu BigDecimal generator podia ser o generator do double, que é um Clojure test.check.generators/double. Esse é o generator de doubles. Isso aqui é um gerador de doubles.
[12:09] Eu estou falando que o meu gerador de BigDecimal é o gerador de doubles? Não. Ele não é um gerador de doubles. Ele é um fmap, ele aplica um double-para-bigdecimal. E aí a gente define essa função. Double-para-bigdecimal como uma função que recebe um valor e devolve um BigDecimal. É isso que a gente tem que fazer: devolver um BigDecimal aqui. Só isso.
[12:45] O que a gente está fazendo? Repara, a gente está usando os generators do test.check que a gente importou um test.check. Isso aqui a gente só não fez um require aqui em cima. Vamos fazer um require direitinho. E aí tem a questão que eu falei. Aqui um vai fazer ‘gen’ e o outro vai ficar ‘g’. Fica não muito bom. E não fica mesmo. Como o padrão desse aqui é ‘gen’, eu estou deixando o padrão ‘gen’ e o outro eu estou deixando ‘g’. Não fica lindo, não fica maravilhoso, eu concordo com isso. Então eu vou tirar aqui, formatar bonitinho.
[13:18] O que eu estou fazendo? Eu estou falando que é para gerar um sample de uma variação usando esses geradores se necessário. Se ele precisar ele vai procurar aqui um BigDecimal e vai achar gerador. O que esse gerador é mesmo? É um fmap, que a gente já viu, que usa esse gerador, o gen/double, e aplica essa função para transformar ele num BigDecimal.
[13:41] Por exemplo, vamos fazer aqui que para transformar um double para BigDecimal basta chamar um construtor de BigDecimal do Java com o valor 15. Eu estou forçando todos os BigDecimals serem 15 só para a gente ver funcionar. Vou carregar o arquivo. Carreguei. Tenho várias categorias. E, olha, uma variação com o preço 15. Sem variações com o preço 15.
[14:06] Aqui é só eu transformar um double para um BigDecimal. É o nosso próximo passo. A gente vai fazer daqui a pouquinho. E ver os problemas e desafios que a gente tem.