| defmodule Plausible.Stats.Imported.SQL.WhereBuilder do |
| @moduledoc """ |
| A module for building an ecto where clause of a query out of a query for Imported tables. |
| """ |
|
|
| import Ecto.Query |
|
|
| alias Plausible.Stats.Query |
|
|
| @db_field_mappings %{ |
| referrer_source: :source, |
| screen_size: :device, |
| screen: :device, |
| os: :operating_system, |
| os_version: :operating_system_version, |
| country_code: :country, |
| subdivision1_code: :region, |
| city_geoname_id: :city, |
| entry_page_hostname: :hostname, |
| pathname: :page, |
| url: :link_url |
| } |
|
|
| def build(%Query{filters: []}), do: true |
|
|
| def build(query) do |
| query.filters |
| |> Enum.map(&add_filter(query, &1)) |
| |> Enum.reduce(fn condition, acc -> dynamic([], ^acc and ^condition) end) |
| end |
|
|
| defp add_filter(query, [:ignore_in_totals_query, filter]) do |
| add_filter(query, filter) |
| end |
|
|
| defp add_filter(query, [:not, filter]) do |
| dynamic([i], not (^add_filter(query, filter))) |
| end |
|
|
| defp add_filter(query, [:and, filters]) do |
| filters |
| |> Enum.map(&add_filter(query, &1)) |
| |> Enum.reduce(fn condition, acc -> dynamic([], ^acc and ^condition) end) |
| end |
|
|
| defp add_filter(query, [:or, filters]) do |
| filters |
| |> Enum.map(&add_filter(query, &1)) |
| |> Enum.reduce(fn condition, acc -> dynamic([], ^acc or ^condition) end) |
| end |
|
|
| defp add_filter(query, [_operation, dimension, _clauses | _rest] = filter) do |
| db_field = Plausible.Stats.Filters.without_prefix(dimension) |
|
|
| if db_field == :goal do |
| Plausible.Stats.Goals.add_filter(query, filter, imported?: true) |
| else |
| mapped_db_field = Map.get(@db_field_mappings, db_field, db_field) |
|
|
| Plausible.Stats.SQL.WhereBuilder.build_condition(mapped_db_field, filter) |
| end |
| end |
| end |
|
|