O mundo Elixir é funcional. Não há objetos ou instâncias. Nesse caso, eu me fiz uma pergunta.
Preciso de ORM?
Minha resposta a essa pergunta é não.
Preciso de dados. Dados puros que vêm diretamente do banco de dados. Outra pergunta que vem à minha mente.
Preciso de um DSL para consultar banco de dados?
Outra resposta negativa.
Temos uma ótima linguagem criada para consultar o banco de dados. SQL, lembra?
E se eu pudesse criar uma função Elixir que tenha um corpo SQL? E se eu pudesse usar essa função exatamente como qualquer outra função do Elixir? Seria ótimo, não é?
Podemos arquivar isso usando o sistema macro muito poderoso do Elixir. No entanto, essa também é uma boa maneira de aprender como as macros do Elixir funcionam.
Para arquivar isso, eu comecei a escrever Defql. Defql é um pacote Elixir que fornece uma maneira simples de definir funções com linguagem SQL. Como ele funciona?
Consultando banco de dados
Esse pacote fornece a macro defquery. Com ela, você pode definir a função que contém uma consulta SQL. Por exemplo:
defmodule UserQuery do use Defql defquery get_by_blocked(blocked) do "SELECT * FROM users WHERE blocked = $blocked" end end
Parece muito limpo, é fácil de ler e a melhor parte dele é que ele suporta parâmetros. Brilhante!
Chamar essa função também é muito simples.
Dependendo do parâmetro fornecido, obteremos usuários bloqueados ou desbloqueados.
UserQuery.get_user(false) # => {:ok, []} UserQuery.get_user(true) # => {:ok, []}
Agora nós podemos consultar facilmente nosso banco de dados e encontrar um resultado.
E quanto a INSERT, UPDATE e DELETE? Boa pergunta! Você pode criar essas consultas com defquery, mas há outro método.
CRUD
Esse pacote também contém outras macros. Dê uma olhada neste exemplo:
defmodule UserQuery do use Defql defselect get(conds), table: :users definsert add(params), table: :users defupdate update(params, conds), table: :users defdelete delete(conds), table: :users end
O que eles farão? Essas macros irão criar funções CRUD comuns. Então, você não precisa escrever cada consulta com o SQL. Algumas simples são criadas para você, como esta. Como posso invocá-las? Aqui está um exemplo:
UserQuery.get(id: "3") # => {:ok, [%{...}]} UserQuery.add(name: "Smbdy") # => {:ok, [%{...}]} UserQuery.update([name: "Other"],[id: "2"]) # => {:ok, [%{...}]} UserQuery.delete(id: "2") # => {:ok, [%{...}]}
Configuração
A configuração também é uma tarefa fácil. Agora mesmo você pode usá-la de duas maneiras.
Com conexão Ecto existente:
config :defql, connection: [ adapter: Defql.Adapter.Ecto.Postgres, repo: Taped.Repo ]
Como uma conexão autônoma:
CÓDIGO
O que falta?
Claro, é um estágio muito inicial, mas o suporte para postgres funciona bem. Há poucas coisas que estão faltando:
- Suporte para MySQL
- Suporte para IN com array % {id: [1,2,3]}
- Adaptador ECTO de limpeza
- Suporte para erros de banco de dados
Resumo
Usando Defql, temos uma maneira muito clara, simples e poderosa de interagir com um banco de dados.
Links
- Repositório GitHub: https://github.com/fazibear/defql
- Pacote hexadecimal: https://hex.pm/packages/defql
- Documentação: https://hexdocs.pm/defql
Espero que tenha sido útil para você. Obrigado por ler!
***
Michał Kalbarczyk faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: https://blog.fazibear.me/sql-queries-as-elixir-functions-5f8b1d67169e.