Bem-vindo a mais um curso de Datomic. Nesse quarto curso a gente vai falar sobre muita coisa legal. A gente vai falar sobre alguns tipos de queries que são importantes no dia a dia com coleções. Superimportante de repente a gente procurar valores que estão dentro de determinadas coleções. A gente começa o curso falando disso. A gente vai falar sobre mais questões levantadas no momento de atualização de dados.
Uma vez que o Datomic, assim como várias ferramentas de ORM, como o Hibernate ou outras ferramentas em outras linguagens, tomam a decisão que o processo de salvar é um processo genérico e às vezes ele faz um insert ou um update. Diferente do SQL, que é muito claro quando é um insert, quando é um update, as ferramentas de ORM e o Datomic tratam o insert e o update de uma maneira uniforme, através de uma interface uniforme de comunicação, uma função única para esses dois, um (xx- dbrt -xx) ou uma entidade que eu passo.
Isso traz um superpoder, que a gente pode passar só trechos das nossas entidades para serem atualizados. Por outro lado, talvez não fosse isso que a gente quisesse. Talvez a gente quisesse garantir certas coisas. Então a gente vai correr atrás dessas garantias. Como é que eu garanto que, quando eu vou atualizar um valor, aquele valor não tenha sido atualizado por outra pessoa antes? Se eu quero aumentar cinco no preço de um produto, como é que eu garanto que outra pessoa não alterou o produto enquanto eu estava fazendo alguma coisa?
Se eu quero alterar o nome de um usuário, como é que eu garanto que outra pessoa não alterou o nome desse usuário ao mesmo tempo. Diversas questões do gênero a gente vai ver. E isso envolve transações a serem feitas dentro do nosso transactor. Claro, o transactor do Datomic é quem executa as transações, mas a gente envolve agora certas verificações, certas validações que vão ser feitas dentro do nosso transactor. Então o transactor vai ter que dar uma olhada agora e comparar valores.
E isso é feito de uma maneira que a gente chama uma função lá dentro do transactor. Então a gente vai ver funções que o transactor dispõe para a gente, além do (xx- dbrt -xx) e o (xx- dbrtret -xx), que permitem fazer isso, como o (xx- cas -xx).
A gente vai ver também como que a gente pode adicionar componentes. Um componente é fazer um tipo de relacionamento, como a gente fez de produto e categoria. Eu posso fazer de produto e variações desse produto. Mas diferentemente de uma categoria uma variação só existe se aquele produto existir. Então vai lembrar o cascade do SQL e suas variações. Só existe se o outro existe, os elementos de uma tabela só existem se os elementos da outra tabela no SQL existirem.
Mas que também traz implicações quando a gente vai remover uma dessas entidades. Então existe também uma função do transactor (retract change), que vai ter implicações quando a gente trabalha com componentes. A gente vai falar quando usar e quando não usar componentes.
A gente vai voltar a discutir a questão de campos que são muito atualizados e a questão do histórico desses campos: quando armazenar, quando não armazenar, como a gente pode trabalhar com isso. E com campos grandes.
A gente vai falar que no final... pegar tudo isso que a gente fez e perceber que a gente queria ter uma função lá no transactor para garantir o que a gente precisa garantir dentro da nossa transação. Então eu preciso garantir que o valor não foi atualizado. Mas não só isso. De repente precisa atualizar esse valor com determinada regra. Isso eu só consigo fazer se eu tiver uma autonomicidade ali dentro, não me importa quantas máquinas estão rodando esse código.
Então eu preciso jogar isso para dentro do transactor, um ponto único, e nesse gargalo que é um ponto único eu coloco esse código. Então a gente vai ver como criar nossas próprias funções e jogar funções para o nosso transactor, para que a gente possa invocar essas funções remotamente.
Para quem vem do mundo do SQL vai lembrar de novo de storage procedure. Lembra, essas analogias são só lembranças, para que cutuque um pouquinho a gente, a gente fale que é esse o caminho. Mas lembrando que, assim como storage procedure, código executado no nosso banco é código tomando CPU do banco. Se o transactor só permite uma transação por vez, isso cria um gargalo, que é importante a gente estar atento.
E a gente vai discutir tudo isso nesse curso. Se você já fez os cursos anteriores, bora continuar. Se você ainda não fez e acredita que conhece todo o conhecimento anterior, não tem problema, durante o curso você pode carregar a versão do projeto no início do curso e começa a partir de lá. Bons estudos.
Vamos começar o nosso curso. O projeto vai ser utilizando o IntelliJ. A gente vai continuar o conteúdo do curso anterior. Eu tenho aqui o curso anterior, o código. Se você terminou, maravilha, se você está pegando esse curso a partir daqui e você tem um conhecimento prévio do que foi ensinado nos outros cursos, você pode ir no GitHub desse curso, baixar os arquivos, vai ter lá a aula0, que é o que a gente precisa para começar a aula1.
Não se preocupa. Você pode fazer isso lá. Tem o link nas atividades. Vamos ver lá?
Eu vou copiar isso aqui para o meu diretório que eu vou colocar o meu projeto. Então diretor ecommerce. Está copiado. Dentro do IntelliJ basta mandar abrir esse projeto. Então eu vou dar um open, escolher esse diretório aqui, ecommerce, onde eu tenho esse meu projeto e ele vai abrir o projeto para mim.
Agora que eu estou com o projeto aberto, eu tenho aqui as várias aulas do curso anterior e eu posso trabalhar com elas. Lembrando, eu tenho um modelo, que é o meu modelo em Clojure, representação do meu modelo em Clojure, onde eu tenho produtos e categorias. Categorias tem diversas definições: o nome, o slug, o preço, palavra-chave, categoria, estoque, atual. As categorias. O produto tem slug, preço, palavra-chave, mais de uma possivelmente ou zero, categoria, uma só, se tiver, lembrando que são opcionais essas chaves, estoque, se ele é digital, se ele é um produto digital ou não. A categoria tem um nome. Ambos possuem ids, que são os UUID.
Eu dou as funções de ajuda para criar categorias e produtos que a gente utilizou. A gente discutiu se fazia sentido ter essas funções ou não, a gente decidiu ir pelo caminho de manter essas funções. Vou apagar esses comentários porque a gente discutiu isso nos cursos anteriores. Vou apagar daqui e deixar dessa maneira que elas estão aqui. Lembrando que tem vantagens e desvantagens de qualquer abordagem.
A gente tem também os nossos modelos na parte do banco. Isso é, pensando no Datomic, a gente tem lá o nosso esquema dos produtos, o esquema das categorias e das transações. Lembrando que categoria/, produto/ não é alto necessariamente que agrupe todos eles, não, é só uma coincidência. Todo mundo que quer produto vai ter várias dessas coisas que um produto tem. É só coincidência.
Eu poderia ter colocado, por exemplo, um db/ident que é um dono/usuário. Então tem o criador, o dono, alguma coisa do gênero, que é o dono do produto ou dono da categoria, criador do produto, criador da categoria, seja lá o que for. E eu posso usar esse aqui, eu crio uma única vez esse cara no esquema e utilizo ele em vários. Não também problema nenhum. Isso daqui é só um identificador.
Uma entidade pode ter vários atributos, não importa quais são esses atributos. Lembra que o Datomic não tem essa regra.
Aqueles exemplos de datoms que a gente estava usando, também está usando agora no dia a dia supertranquilo. Não tem problema. E, claro, tem muitas funções aqui. Nesse curso a gente vai usar só algumas delas, mas eu vou deixar por aqui por enquanto. Vou pegar um modelo e o banco. O core não tem nada. E a gente tem as aulas.
Claro, eu vou remover as aulas antigas, vou ficar só com a aula5, que é o código da última aula que a gente estava escrevendo. Vou entrar aqui nela e vou renomear para aula1. Vou salvar esse arquivo. Ele vai renomear aqui também. Refactor.
No Mac é Option+Enter. Eu chamo todas as teclas do Mac de Ctrl. Quando eu mudei para o Mac dez anos atrás, eu não aprendi as teclas, tudo virou Ctrl para mim.
Apago o banco, abro a conexão, crio o esquema, adiciono dados de exemplo. Até aí como a gente estava acostumado a trabalhar. Posso imprimir todos os produtos, como a gente estava acostumado a trabalhar. Tudo isso é tranquilo de eu executar.
Como eu faço isso? Vou no meu terminal, aumento a fonte, entro no meu diretório de trabalho, no caso é Documentos/Guilherme/datomic4-xp-aps-datomicpro. Se eu procurar lá eu tenho no meu Datomic pro o transactor. Aqui eu estava rodando o meu transactor. Então eu tenho o meu Datomic rodando. Aqui eu vou poder conectar com ele. Como? Abrindo e rodando o REPL do meu projeto. Vou rodar o REPL do meu projeto.
Meu Datomic já está rodando, como a gente fez lá no primeiro curso. E o REPL vai abrir aqui daqui a pouquinho. Assim que ele abrir, eu posso executar todo esse código que está aqui e começar a fazer algumas queries diferentes que eu gostaria de fazer. Gostaria de fazer duas queries diferentes aqui.
Vou carregar esse arquivo, Command+Shift+L para recarregar o arquivo. Vai recarregar o arquivo aqui. Não executou. Não achei Datomic para entidade em disc-contact. O que está acontecendo? Se a gente for lá no db/clj, o Datomic para entidades está definido depois do um produto. Datomic para entidade. O transformador para entidade está depois. A gente tem que trazer essas duas funções, porque eu vou usar uma ou outra, para antes. Acho que elas podem ser bem aqui em cima porque elas não usam mais nada, uma não depende de nada fora do que está aqui. Só o prewalk, que está lá no nosso require.
Por que antes funcionava? Lembra que a gente já tinha isso carregado no nosso arquivo? Como a gente já tinha carregado antes no nosso REPL, recarregar funcionava. Por isso que é importante você dar um stop e start se você está desenvolvendo no REPL. É por isso que eu defendo o REPL como uma maneira de explorar algumas coisas, mas, se você tem algum projeto que tem outros pontos de interação, por exemplo um projeto web, no final você precisa testar pela interface web, pela interface final de uso do seu sistema, dando um stop e start completo no seu programa, mesmo que seja no REPL.
Por quê? Porque daí a gente pega outros tipos de erros quando o código não está carregado. O REPL vicia a gente porque ele já tem código carregado. Esse é o segrego que eu comento em alguns cursos. Recarreguei esse arquivo. Não fui esperto. Recarreguei agora esse.
Ele vai definir que vai utilizar esquema aqui dentro, apagar o banco, inserir tudo, etc. Ele traz os produtos para a gente. Tem o produto com as categorias. Estamos felizes. Estoque digital.
Eu queria fazer uma query diferente agora. Eu queria trazer os produtos... A gente tem todos os produtos. E tem lá para baixo outras variações: produtos vendáveis, etc. Eu queria trazer todos os produtos de determinadas categorias. Por exemplo, eu queria trazer todos os eletrônicos e todos os de categoria alimentação. Vamos tentar fazer essa query.
Eu queria um pprint, db/todos-os-produtos-nas-categorias. E aí eu vou passar uma série de categorias. Eu vou passar a variação, o momento do banco que eu quero e vou falar quais são as categorias. Eu gostaria da categoria... Que categoria que eu queria mesmo? Eletrônicos e alimentação. Lembrando, eu não tenho nenhum produto com alimentação.
Isso aqui vai trazer só os eletrônicos. Deveria. A gente tem que fazer a query funcionar. Depois que a gente fizer ela funcionar, eu vou testar ela com eletrônicos e esporte, porque esporte a gente sabe que tem coisa. Depois que ela funcionar, a gente testa ela só com esporte para ver se ela funciona. Tem que trazer só o que é de exposição. Depois que funcionou, tem que funcionar também se eu passar vazio. Se eu passar vazio tem que trazer nada, nenhum produto, porque eu estou falando para trazer de uma categoria que não tem nenhuma. Então nenhum.
Se eu colocar só uma categoria que não existe também tem que trazer nenhum. São diversas variações que eu quero usar dessa query. É uma query que busca dentro de uma coleção. Isso a gente nunca fez. Repara que eu dou um Option+Enter aqui, criar função, create function.
O primeiro parâmetro nosso é o banco, db. O segundo parâmetro nosso são as categorias. As categorias a gente sabe. O que é mesmo? É uma série de strings. Cuidado, porque a gente está trabalhando com strings aqui. A gente está passando como parâmetro strings puras. Só strings. s/defn. Legal. Todos os produtos.
A query é muito parecida com todos os produtos. Vamos procurar a query de todos os produtos. Está aqui. Datomic para entidade. Várias coisas. Todos os produtos deu uma série de produtos. Então devolve agora sim uma sequência de model/produto. O Datomic para entidade, o que ele fazia? Trazia um pull de todos os produtos, tudo que tem no meu produto. Where. Entidade. Produto/nome.
Não é só isso que eu quero. Eu quero colocar um parâmetro de entrada, não só do db, eu quero passar também como entrada as categorias. Então aqui no in é uma coisa que a gente já trabalhou antes. A gente já trabalhou com parâmetros. O parâmetro que eu vou ter é o banco, primeiro, de entrada, e o segundo é o nome-da-categoria.
Por que nome-da-categoria? Vamos pensar no singular. O que eu vou querer fazer? Além desse where, eu vou querer que essa entidade... Essa entidade é um produto. Vamos chamar de produto. Esse produto tenha, além de ter produto/nome, eu quero que ele tenha... Não, eu não quero que ele tenha. Eu preciso saber qual é a categoria dele. Se eu colocar aqui produto/categoria, aqui eu preciso do id interno do banco da categoria ou de alguma maneira a categoria em si.
Eu quero uma referência para a categoria em si, que é o id interno. Eu não tenho. O que eu tenho é o nome da categoria, é uma string, o nome da categoria. Como é que eu transformo o nome da categoria nisso? Poderia fazer uma outra query, mas mais fácil. É só falar que, antes de pegar todos os produtos, descobre quem são essas categorias. Isso é, categoria é quem tem categoria/nome e o nome da categoria.
Eu descobri quem é essa entidade. Peguei essa entidade. Então vamos supor que você passou três parâmetros para mim. Eu tenho essas três entidades. Agora que eu tenho essas três entidades, eu vou varrer os produtos, procurando todos os produtos, todas as entidades, quem tem nome. Achei quem tem aqui, esses datoms, quem tem nome. Achei. Bindingei o produto. Agora eu procuro quem tem o produto/categoria igual a isso aqui.
Repara, antes a gente estava usando isso aqui só para dizer que para mim produto é todo mundo, todas as entidades, que tem produto/nome. Se todo produto tem que ter categoria, se para a gente na verdade só vai retornar que quem tem categoria, então não preciso mais desse, o de baixo já garante que é um produto, porque tem um produto/categoria para a minha definição de produto. Se você tem produto/categoria, eu considerá-lo-ei como um produto.
Para mim é o suficiente agora. Eu busco a categoria que eu quero e aí eu trago aqui um produto que tem essa categoria.
Isso se você tivesse só um nome de categoria, se a gente estivesse passando uma string solta, que nem a gente fez com número, que nem a gente fez com outras coisas antes. A gente fez com preço lá para trás. Então a gente já fez várias queries com valores fixos, com números, strings, coisas que entram. Mas agora não é um número, agora é uma coleção, é uma sequência.
Então o meu binding agora, se a gente for lá no Datomic binding, as regras de binding podem ser de um escalar, um único valor, que nem a gente trabalhou até agora. Mas tem outras maneiras de fazer o binding. A que a gente quer utilizar chama coleção. A gente quer passar uma coleção porque a gente quer procurar com qualquer um desses valores.
Tem outras formas também de trabalhar. Tuple, relação. Tem outras formas de trabalhar. A mais comum é a coleção. É com ela que a gente vai trabalhar aqui.
Eu quero agora um binding de coleção, collection binding. O que eu quero fazer aqui, collection binding, é esse aqui. Colchetes e reticências, ...], no final. Eu estou recebendo vários nomes de categoria. Aqui são vários nomes de categoria que eu estou recebendo, diversos nomes de categoria, mas eu vou trabalhar um a um, eu vou procurar para cada um deles. É como se fosse um in no SQL. Where, nome de categoria, in... esses valores. É isso que a gente está fazendo aqui.
O collection é equivalente meio que a esse in. Se eu não errei nada, esse é o código que a gente deveria ter. Vou recarregar esse arquivo. Não precisa recarregar, só executar esse último. Vamos limpar aqui. Ele deveria trazer para a gente somente eletrônicos e alimentação. A gente sabe que não tem nenhum de alimentação, então só eletrônicos. Eletrônico, eletrônico, eletrônico. Acabou. Nenhum de esporte, só trouxe eletrônicos. Funcionou.
Esse segundo aqui, eletrônicos e esporte. Agora vamos rodar esse segundo. Rodei só o segundo. Tem esporte, eletrônicos, eletrônicos, eletrônicos. Trouxe ambos. Se eu testar só o de esporte. Vamos testar só esporte. É in“esporte”. Ele trouxe um de esporte. Se eu buscar nenhuma. Quer dizer, tem que ser in vazio. Não trouxe nada. Até porque aqui logo de cara ele bate e fala que não achou nenhuma categoria.
Nem tem por que ir para a segunda condição, de afirmação, que a gente está passando. Na primeira afirmação não achou nenhuma, parou por aí. Aqui também deveria trazer nada. Se a gente executar tudo, tem todo o resultado dessas queries, mas é o que a gente esperava.
Aprendi esse binding de collection. Será que dá para passar outros parâmetros? Vamos passar outros parâmetros, que aí a gente entra em outros casos só para a gente ver a sintaxe nos casos em que a sintaxe pode não ficar tão clara. É importante ver isso. O ...] é uma query que está dizendo meio que esse in no SQL, um SQL equivalente a um in.
Vamos fazer uma variação desse, do esporte. Todos os produtos nas categorias e digital. Eu gostaria que ele fosse digital. Sim ou não. Somente os digitais, somente os não-digitais. True e false. Vamos de novo lá. Option+Enter, create function. Criou a função para mim. Vou receber o banco de dados.
Vou receber as categorias, que a gente sabe que é um s/Str. Vamos receber também se é digital. Se ele é digital é o quê? É um Bool, booleano, true ou false. E vai devolver para a gente, a gente sabe, um model/produto. E a query? Igual? Vamos ver. Quase igual.
Vamos copiar o Datomic para a entidade. Vamos buscar o produto com a categoria, feliz e contente, $, nome da categoria. Opa. A gente tem que passar mais parâmetro aqui. Se ele é digital?. Ele é digital? Então aqui a gente vai receber se ele... Lembra que eu prefiro usar nomes distintos? Se ele é digital. Se ele é digital, por mais que o ? diga isso, eu prefiro usar nomes distintos, eu estou indo para o caminho de nomes distintos.
Se você definir que na sua empresa, no seu padrão, no seu coração... Eu prefiro que “no seu coração” você converse com o resto da equipe definir que todo mundo é o mesmo valor, toca para a frente.
Produto/categoria, categoria. E eu quero que o produto seja ou não digital. Isso é, produto tenha produto digital com esse valor.
Mas você precisou entrar com esse parâmetro. Foi só digitar aqui? Sim, é só digitar aqui. Repara que não foi digitar aqui dentro do [. Por isso que eu falei o cuidado da sintaxe. A gente está passando aqui. O que significa? Significa que no in a gente está renda db/categorias e digital. Repara, se a gente colocasse aqui dentro, isso tudo era o categorias, que é uma sintaxe que nem existe.
?a, que é esse daqui, ..., alguma coisa depois do ...? Não, não, não. Está falando que não pode depois do ..., então é fora. Por isso que eu citei que existe essa questão da sintaxe.
Vamos testar o código. Vou limpar aqui, a gente testa o primeiro. Todos os produtos. Vai recarregar o arquivo. Recarrega. Errei alguma coisa aqui. s/defn. Sempre que eu vejo macro expanding, é alguma macro que eu estou utilizando, que eu errei a sintaxe. 99% das vezes eu esqueci de colocar o ‘s’ do schema. Então eu recarrego. Às vezes não é, mas muitas vezes é.
Esporte. Com true. Não trouxe nada. Não tem nenhum esporte digital. E esporte com false? Esporte com false tem: o tabuleiro de xadrez. Tabuleiro de xadrez não é digital.
Vamos ver o eletrônicos com digital. Eu peguei um com digital aqui, true. Vou rodar. Ele trouxe. Lembra que a gente tinha um jogo online, que era digital. Está aqui o meu jogo online digital. Com isso a gente fechou essas duas questões.
Eu queria reforçar rapidinho com vocês uma questão em relação a umas queries, na medida em que a gente vai executando muitas queries. A gente falou que uma maneira que a gente pode refatorar o nosso código quando a gente tem algumas condições comuns é criando regras. A gente extrai isso para regras.
Se esse tipo de condição, de categoria específica, fosse algo comum, então produtos numa categoria, seria interessante a gente extrair isso para uma regra, produto na categoria. Eu posso pegar essas duas condições aqui, jogar nas minhas regras de produtos e aí invoco somente elas. Então vou tirar essas duas daqui e eu vou chamar uma outra.
Lembra, para chamar (). Então (produto-na-categoria). A gente passa um produto que não está bindeado e o nome da categoria, que está bindeado. Bindeou já porque a gente já recebeu.
Produto na categoria é uma regra que a gente vai adicionar aqui. Produto-na-categoria. A gente vai receber o produto e o nome da categoria, pode estar bindeado ou não, e o que a gente faz são essas duas condições. Categoria, a gente vai definir, assumindo que está bindeado como estava, pega essa categoria e encontra o produto.
Então a gente tem que usar essas regras no in. Lembra, a gente tem que receber as regras no in. Como é que eu recebo regra? Por padrão é %. Eu passaria as regras e o %. Com isso eu tirei esse Copy+Paste aí do miolo. Esse miolo aqui ficou simplesmente produto-na-categoria, ?produto ?nome-da-categoria. Recarreguei esse arquivo. Faltou passar as regras também.
Recarreguei esse arquivo. Vou limpar e vou executar. Todos os eletrônicos digitais, tinha que trazer só um, nos esportes digitais, nenhum, esporte não-digital tem um. Então deve estar tudo ok. A gente pode limpar tudo e executar por exemplo só os eletrônicos. A gente vê que a gente só tem eletrônico, eletrônico, eletrônico.
Então as regras é aquela sacada de a gente poder extrair refatorando o nosso código. Mesmo assim, você vai dar uma olhada que existem algumas coisinhas que são repetidas e razoavelmente longas. Então um outro exemplo de repeteco que a gente tem aqui bastante é esse pull do produto. Esse pull do produto nosso é um pull que a gente faz bastante. Será que não dá para a gente extrair ele?
Então a gente pode tentar extrair esse cara daqui de alguma maneira. Uma outra coisa que eu gostaria de conversar sobre as queries é que a legibilidade delas não é maravilhosa. Você vê que por padrão da formatação é comum que é where fique aqui nessa linha. Você vai ver sempre o pessoal fazendo assim. Se você for olhar aqui na documentação, você vai ver muitas assim, o where começando na próxima linha ou na mesma linha e o próximo, da linha seguinte, está alinhadinho, bonitinho.
O problema é que a ideia por padrão, quando você formata, não faz isso. Você tem que você mesmo empurrar lá para a direita. Quando você formata de novo, você perde isso. Esse que é o problema.
Por que isso acontece? Porque esse código que a gente está digitando aqui, da query, não é um código Clojure, ele é um código escapado. Como está escapado não segue às regras de alinhamento que a (xx-IDE-xx) tem para a gente. As regras de alinhamento são para código Clojure, onde você terminou o parâmetro anterior no mesmo nível começa o próximo. Isso funcionaria normal.
Se eu estou aqui dentro, terminei, d/q e digito alguma coisa, é na mesma linha do d/q. Não tem problema. Se eu estou na linha anterior e dou um Enter, é na mesma linha do anterior. Não tem problema. Mas aqui não. Aqui a gente está dentro de um escape. Dentro de um escape pode ser qualquer regra porque pode ser a regra do Datomic, de uma query do Datomic, pode ser a regra de formatação de qualquer lugar. É feioso isso aqui do where, não vai ficar muito lindo para a gente.
Aqui também tem. Essa parametrização assim não tem. Alinho o que com o quê? O que eu alinho aqui? Eu alinho aqui o in? E se eu jogar o in aqui para depois para ficar pertinho do que realmente está entrando? Porque o que realmente está entrando é o db, as regras, as categorias e o digital. Posso colocar fora de ordem? Carrego o arquivo. Carreguei o arquivo. E aí rodo só esse último para a gente ver.
O último é digital. Foi ele que eu formatei. Ele trouxe um resultado para a gente. Então a ordem do in não fez diferença. Ficou mais próximo aqui. Esse é o banco, essas são as regras, as categorias, esse é o digital. Find, where, in. Esse é o padrão que você encontra em muitas linguagens. Por quê? Porque você escreva na sua query o que você quer procurar e onde e depois você faz os binds internos de parâmetros.
É muito comum isso. Às vezes é (xx-postfix-xx) essas coisas, às vezes elas são em fix. Não é tão comum em fix bem no local mesmo, onde você vai usar. Não é muito comum esse in fix aqui, bem no meio, e não no local exato onde você vai usar. Esse não é o mais comum.
Está vendo? A formatação fica super estranha. Eu errei alguma coisa nessa formatação? Eu acho que eu errei alguma coisa. Eu fechei aqui antes da hora. Esse cara aqui... Por isso que está mais estranho. Era para fechar aqui.
Então esse é o padrão que você vai ver em todo lugar: o in aqui no meio. E fica distante e aí começa a ter muita coisa. Faz parte. Infelizmente é o que a gente pode fazer. Dá para ir tentar refatorar sempre para melhorar o máximo que você puder, mas fique sempre atento a isso.
Você pode decidir que você vai usar , aqui para usar , lá embaixo, para também ficar claro, no find, padrões no find. Pode definir o que faz sentido para você que deixe mais claro o seu código na tua empresa.
O curso Datomic: Bindings, transaction functions e filters possui 128 minutos de vídeos, em um total de 27 atividades. Gostou? Conheça nossos outros cursos de NoSQL em Data Science, ou leia nossos artigos de Data Science.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.