fuelen
Hi all!
Just want to share a small code snippet which allows writing CASE expressions using macro which is similar to cond.
Here is an example of usage:
import Ecto.Extension.Query.API
import Ecto.Query
from users in "users",
select: %{
email: users.email,
role_label:
cond_ do
users.role == "director" -> "DIRECTOR!"
users.inserted_at < ago(6, "month") -> "OLD!"
true -> type(users.role, :string)
end
}
generated SQL:
SELECT u0."email", CASE WHEN u0."role" = 'director' THEN 'DIRECTOR!' WHEN u0."inserted_at" < $1::timestamp + (-6::decimal::numeric * interval '1 month') THEN 'OLD!' WHEN TRUE THEN u0."role"::varchar END FROM "users" AS u0
and implementation:
defmodule Ecto.Extension.Query.API do
defmacro cond_(do: block) do
bindings =
block
|> Enum.reduce([], fn
{:->, _, [[clause], branch]}, acc ->
[branch, clause | acc]
end)
|> Enum.reverse()
bindings_number = length(bindings)
sql =
IO.iodata_to_binary([
"CASE",
List.duplicate(" WHEN ? THEN ?", div(bindings_number, 2)),
" END"
])
quote do
fragment(unquote(sql), unquote_splicing(bindings))
end
end
end
I hope someone will find this useful ![]()
Trending in Guides/Tuts
You probably already know that <span>{nil}</span> in a HEEX template produces <span> </span> when rendered. I fin...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 3- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
hauleth
Super nice. Once upon a time I was thinking about doing exactly the same magic.
Small suggestion for improvement - define
frommacro in your module and then traverse the query to replace allcondwith your implementation. This should result with clearer APIaxelson
This is a neat improvement to ecto’s sql!
But the downside to this is that (if I’m following correctly) this improvement would no longer be composable with other ecto DSL improvements since only one person can define
fromfuelen
Well, this is my first attempt to implement @hauleth idea. Some kind of composability is still possible