thenrio
Dynamic and ordered list of expressions in ecto query from user input, each input maps to a field or fragment
I have a products api, database is postgresql, I use ecto.
curl "localhost:4000/products?brand=AZN&limit=1&fields=ean,date,brand"
{"data":[{"brand":"AZN","date":"2019-09-01T02:00:00Z","ean":"9783423214254"}]}
Accept can be text/csv, and then
- format of date is milliseconds from epoch.
- fields MUST be in order
curl "localhost:4000/products?brand=AZN&limit=1&fields=ean,date,brand" -H accept:text/csv
9783423214254,1567303200000,AZN
I do not know how to achieve that using select and select_merge.
When I add expression to select, one at a time using select_merge:
q = from p in Product, select: %{}
q = from p in q, select_merge: map(p, [:ean])
q = from p in q, select_merge: %{date: fragment("extract(epoch from ?)*1000", p.date)}
q = from p in q, select_merge: map(p, [:brand])
Repo.to_sql(:all, q)
{"SELECT p0.\"ean\", p0.\"brand\", extract(epoch from p0.\"date\")*1000 FROM \"products\" AS p0",
[]}
Then order is not preserved: ean, brand, date. I need ean, date, brand.
How would you do that?
Cheers.
Most Liked
LostKobrakai
Maps in elixir are not ordered, therefore you probably shouldn’t expect an ecto query producing a map to do so. Any ordering you might observe is an implementation detail, you shouldn’t rely on.
q = from p in Product, select: [
p.ean,
fragment("extract(epoch from ?)*1000", p.date),
p.brand
]
Last Post!
thenrio
Ideed, for user input fields=ean,date,brand the query from p in Product, select: [p.ean, fragment("extract(epoch from ?)*1000", p.date), p.brand] yields fields in desired order.
But I need to map user fields to selected expressions. When fields=ean,price,date then I should case to from p in Product, select: [p.ean, p.price, fragment("extract(epoch from ?)*1000", p.date)].
I would like to start with select: [] and reduce user inputs to expressions on query to build the equivalent queries above.
Popular in Questions
Other popular topics
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
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #hex
- #security









