I’m implementing some pagination logic in Absinthe with Ecto 3(DB is MySQL), but Ecto 3 seems not to have a way to query SELECT FOUND_ROWS()
except to call Ecto.Adapters.SQL.query!(Repo, "SELECT FOUND_ROWS()")
As a workaround, I’ve written a logic which query SQL_CALC_FOUND_ROWS
and SELECT FOUND_ROWS()
like this.
def get_result_count() do
query =
from(
q in Question,
select: {q.id, q.title, q.body, q.user_id, q.inserted_at, q.updated_at},
order_by: [asc: q.id]
)
{:ok, [result, count]} = Repo.transaction fn ->
{sql, values} = Repo.to_sql(:all, query)
calc_sql =
sql
|> String.replace_prefix("SELECT ", "SELECT SQL_CALC_FOUND_ROWS ")
raw_result = Ecto.Adapters.SQL.query!(Repo, calc_sql, values).rows
result =
raw_result
|> Enum.map(fn(x) ->
[id, title, body, user_id, inserted_at, updated_at] = x
key = %{id: id, body: body, title: title, user_id: user_id, inserted_at: inserted_at, updated_at: updated_at}
true = Question.changeset(%Question{}, key).valid?
Map.merge(%Question{}, key)
end)
[[count]] = Ecto.Adapters.SQL.query!(Repo, "SELECT FOUND_ROWS()").rows
[result, count]
end
end
It’s worked correctly, but I have a feeling that the logic is not elegant and it might be vulnerable to Ecto’s specification change.
Are there any better ways to implement SQL_CALC_FOUND_ROWS
and SELECT FOUND_ROWS()
or any improvement for the logic?