Current section

Files

Jump to
mishka_developer_tools lib modules mnesia_assistant pagination.ex
Raw

lib/modules/mnesia_assistant/pagination.ex

defmodule MnesiaAssistant.Pagination do
alias MnesiaAssistant.{Transaction, Query}
import MnesiaAssistant, only: [eg: 1, er: 1, tuple_to_map: 4]
def infinite_scroll({_record, _cont} = output, _table, keys, strc, _limit) do
infinite_scroll(output, keys, strc)
end
def infinite_scroll(table, keys, strc, limit, spec) do
match_pattern =
if is_nil(spec) do
fields =
([table] ++ Enum.map(1..length(keys), fn _x -> :_ end))
|> List.to_tuple()
[{fields, [], er(:all)}]
else
spec
end
Transaction.activity(:async_dirty, fn -> Query.select(table, match_pattern, limit, :read) end)
|> tuple_to_map(keys, strc, [])
|> case do
[] -> []
data -> data
end
end
def infinite_scroll({_record, cont}, keys, strc) do
Transaction.activity(:async_dirty, fn -> Query.select(cont) end)
|> tuple_to_map(keys, strc, [])
|> case do
[] -> []
data -> data
end
end
def infinite_scroll(table, keys, strc, limit, page, spec) when page >= 1 do
match_pattern =
if is_nil(spec) do
fields =
([table] ++ Enum.map(1..length(keys), fn _x -> :_ end))
|> List.to_tuple()
[{fields, [], er(:all)}]
else
spec
end
Transaction.activity(:async_dirty, fn -> Query.select(table, match_pattern, limit, :read) end)
|> tuple_to_map(keys, strc, [])
|> case do
[] -> []
data when data != [] and page == 1 -> elem(data, 0)
data -> go_next_page(page, data, keys, strc)
end
end
defp go_next_page(page, {record, cont}, keys, strc) do
Enum.reduce_while(1..(page - 1), {record, cont}, fn item, acc ->
Transaction.activity(:async_dirty, fn -> Query.select(elem(acc, 1)) end)
|> tuple_to_map(keys, strc, [])
|> case do
[] ->
{:halt, []}
{new_record, new_cont} ->
if item + 1 == page, do: {:halt, new_record}, else: {:cont, {new_record, new_cont}}
end
end)
end
# mnesia:transaction(fun() -> mnesia:select(tab,
# [{{tab,'$1','_','_','_','_','_','_','_','_','_','_','_','_','_'},
# [{'andalso', {'>', '$1', 20}, {'<', '$1', 30}}], ['$_']}], 11, read)
# end).
def numerical(table, keys, strc, start: start, last: last, at: at) do
fields =
([table] ++
Enum.map(1..length(keys), fn x -> if(x === at, do: :"$1", else: :_) end))
|> List.to_tuple()
conds = [{eg(:and), {eg(:>=), :"$1", start}, {eg(:<=), :"$1", last}}]
spec = [{fields, conds, er(:all)}]
run_numerical_query(table, spec, keys, strc)
end
def numerical(table, keys, strc, page, limit, at) when page > 0 and limit > 0 do
start = page * limit - limit
fields =
([table] ++
Enum.map(1..length(keys), fn x -> if(x === at, do: :"$1", else: :_) end))
|> List.to_tuple()
conds = [{eg(:and), {eg(:>), :"$1", start}, {eg(:<=), :"$1", page * limit}}]
spec = [{fields, conds, er(:all)}]
run_numerical_query(table, spec, keys, strc)
end
defp run_numerical_query(table, spec, keys, strc) do
Transaction.transaction(fn -> Query.select(table, spec, :read) end)
|> case do
{:atomic, res} ->
tuple_to_map(res, keys, strc, [])
{:aborted, reason} ->
Transaction.transaction_error(reason, __MODULE__, "listing", :global, :database)
end
end
end