Current section
Files
Jump to
Current section
Files
lib/analytics_ex_web/queries/queries.ex
defmodule AnalyticsEx.LiveDashboard.AnalyticsPage.Queries do
import Ecto.Query
def repo do
Application.get_env(:analytics_ex, :repo)
end
def data_for_metric(metric, ignored_paths, path_search_term \\ nil)
def data_for_metric(%{name: ["weekly" | _]}, ignored_paths, path_search_term) do
from(
m in "metrics",
group_by: [fragment("date_trunc('week', ?)", m.date), m.path],
order_by: [fragment("date_trunc('week', ?)", m.date), m.path],
select: {
m.path,
sum(m.counter),
fragment("extract(epoch from date_trunc('week', ?))::integer", m.date)
}
)
|> filter(ignored_paths)
|> search(path_search_term)
|> get_and_shift_by(:week)
end
def data_for_metric(%{name: ["monthly" | _]}, ignored_paths, path_search_term) do
from(
m in "metrics",
group_by: [fragment("date_trunc('month', ?)", m.date), m.path],
order_by: [fragment("date_trunc('month', ?)", m.date), m.path],
select: {
m.path,
sum(m.counter),
fragment("extract(epoch from date_trunc('month', ?))::integer", m.date)
}
)
|> filter(ignored_paths)
|> search(path_search_term)
|> get_and_shift_by(:month)
end
def data_for_metric(_metric, ignored_paths, path_search_term) do
from(
m in "metrics",
order_by: [m.date, m.path],
select: {m.path, m.counter, fragment("extract(epoch from ?)::integer", m.date)}
)
|> filter(ignored_paths)
|> search(path_search_term)
|> get_and_shift_by(:none)
end
defp filter(query, []), do: query
defp filter(query, paths) do
filter_term = Enum.join(paths, "|")
where(query, [m], fragment(" ? !~* ?", m.path, ^filter_term))
end
defp search(query, nil), do: query
defp search(query, search_term) do
search_term = sanitize_sql_like(search_term)
search_term = "%#{search_term}%"
where(query, [m], ilike(m.path, ^search_term))
end
defp get_and_shift_by(query, shift_by) do
repo().all(query) |> Enum.map(&convert_date(&1, shift_by))
end
defp convert_date({path, counter, date}, shift_by) do
date =
case shift_by do
:month ->
# Shift the data point for a month to the end of that month
date + 30 * 24 * 60 * 60
:week ->
# Shift the data point for a week to the end of that week
date + 7 * 24 * 60 * 60
:none ->
date
end
# Convert the epoch date from seconds to microseconds
# which is the timestamp that the ChartComponent expects
{path, counter, date * 1_000_000}
end
defp sanitize_sql_like(string) do
String.replace(string, ~r/[("_"|"%"|"\\")]/, "")
end
end