Elixir - Como fazer determinadas operações com a biblioteca Ecto (Parte 2)

wesleymorais

Wesley de Morais

Posted on January 27, 2023

Elixir - Como fazer determinadas operações com a biblioteca Ecto (Parte 2)

Vamos para segunda parte do nosso artigo, agora vamos as operações propriamente ditas.

Fazendo Operações no banco de dados

Todas as operações que iremos fazer será usando o shell que o elixir nos oferece, então digite no terminal:

iex -S mix
Enter fullscreen mode Exit fullscreen mode

Operações sem usar Ecto.Schema

Algumas vezes será necessário fazer operações de banco de dados sem a utilização do Ecto.Schema, e apenas usar as tabelas associadas, porém mesmo sem a utilização do Ecto.Schema não vamos necessitar criar o SQL bruto.

Busca

A primeira operação que vamos fazer será a de busca, com o seguinte comando podemos criar uma query para verificar todos os clientes inseridos no nosso banco de dados:

import Ecto.Query
alias PizzariaEcto.Repo
query = from("clients", select: [:name, :phone])
Repo.all(query)
Enter fullscreen mode Exit fullscreen mode

O código acima vai criar o seguinte sql e executa-lo:

SELECT name, phone FROM clients
Enter fullscreen mode Exit fullscreen mode

Como eu falei a um tempo quando criamos a query ela não será executada, pois o Ecto usa o padrão repositório, ou seja, apenas funções do repositório poderá operar em cima do banco de dados. Assim, essa função Repo.all() irá receber uma query(Uma struct Ecto.Query) e retornar uma lista de mapas contendo as informações no banco, mas como não temos nada no banco será retornado uma lista vazia, então vamos inserir algo no banco de dados.

Inserção

data = [
    %{name: "Bruno Santos", phone: "999878767"},
  %{name: "Maria Pereira", phone: "994657876"},
  %{name: "Fábio Bio", phone: "999870900"}
]
Repo.insert_all("clients", data)
#=> {3, nil}
Enter fullscreen mode Exit fullscreen mode

Com esse código inserirmos 3 clientes na nossa base de dados, então podemos novamente executar o comando de busca para ver esses clientes.

Busca específica

Afim de poder executar uma operação de busca específica podemos executar:

import Ecto.Query
alias PizzariaEcto.Repo
query = from(c in "clients", where: c.name == "Bruno Santos", select: [:name, :phone])
Repo.all(query)
Enter fullscreen mode Exit fullscreen mode

Remoção

Afim de poder executar uma operação de remoção de dados podemos executar:

import Ecto.Query
alias PizzariaEcto.Repo
from(c in "clients", where: c.name == "Bruno Santos") |> Repo.delete_all
Enter fullscreen mode Exit fullscreen mode

Atualização

Podemos fazer atualizações também ainda sem usar schemas:

import Ecto.Query
alias PizzariaEcto.Repo
from(c in "clients", where: c.name == "Fábio Bio") |> Repo.update_all
Enter fullscreen mode Exit fullscreen mode

Operações usando o Ecto.Schema

Com os schemas em mãos podemos fazer a mesma coisa que fazermos sem os schemas, porém o retorno dessas operações vão está em estruturas elixir.

Busca

As buscas usando Ecto.Schema é a mesma coisa de sem usa essa estrutura, mas o retorno da função será uma lista de estruturas elixir populadas.

import Ecto.Query
alias PizzariaEcto.{Repo, Client}
query = from(Client)
Repo.all(query)
#=> [%PizzariaEcto.Client{...},...]
Enter fullscreen mode Exit fullscreen mode

Buscas específicas

Podemos fazer retornos em estruturas elixir usando a função Repo.get_by().

import Ecto.Query
alias PizzariaEcto.{Repo, Client}

Repo.get_by(Client, name: "Maria Pereira")
#=> %PizzariaEcto.Client{...}
Enter fullscreen mode Exit fullscreen mode

Ecto.Changeset

Antes de fazermos operações com inserção e atualização de dados usando as estruturas elixir, podemos falar sobre a estrutura Ecto.Changeset. Esta estrutura nos permite criar casts e validações para dados que são inseridos pelo usuário.

alias PizzariaEcto.Client
import Ecto.Changeset
params = %{name: "Mariana Bom", phone: "999808909", email: "mariana@gmail.com"}
changeset = cast(Client, params, [:name, :phone])
Repo.insert(changeset)
Enter fullscreen mode Exit fullscreen mode

A função cast permiti filtrar quais chaves vão poder serem usadas para criação da estrutura PizzariaEcto.Client, e assim usando a função insert inserir no banco de dados. O ecto tem funções de validação como o validate_length que recebe um changeset e retorna um novo changeset com essa validação aplicada, então podemos melhorar o nosso código:

alias PizzariaEcto.Client
import Ecto.Changeset
params = %{name: "Mariana Bom", phone: "999808909", email: "mariana@gmail.com"}
changeset = cast(%Client{}, params, [:name, :phone]) |> validate_length(:phone, min: 9)
Repo.insert(changeset)
Enter fullscreen mode Exit fullscreen mode

O código acima permite inserir apenas os dados de name e phone que tenha no mínimo 9 dígitos, caso alguma validação não ocorra a inserção não funcionará.

Podemos fazer atualizações usando changeset, o seguinte código vai procurar um cliente chamado “Maria Bom”, criar um changeset com base nesse retorno e mandar para a função update para atualizar o banco.

alias PizzariaEcto.{Repo,Client}
import Ecto.Changeset
client = Repo.get_by(Client, name: "Mariana Bom")
changeset = change(client, name: "Mariana Ruim")
Repo.update(changeset)
#=> {:ok, struct_com_cliente_atualizado}
Enter fullscreen mode Exit fullscreen mode

Conclusão

No presente artigo vimos como a ferramenta Ecto nos possibilita fazer operações no banco de dados de nossa preferência. O uso do Ecto também se dá principalmente junto ao framework Phoenix que nos permite criar aplicações web poderosas, afim de resolver alguns problemas existentes.

Referências

Ecto Site Oficial

Programming Ecto - Build Database Apps in Elixir for Scalability and Performance

💖 💪 🙅 🚩
wesleymorais
Wesley de Morais

Posted on January 27, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

What was your win this week?
weeklyretro What was your win this week?

November 29, 2024

Where GitOps Meets ClickOps
devops Where GitOps Meets ClickOps

November 29, 2024