Packages
exosql
0.2.8
0.2.88
0.2.87
0.2.86
0.2.85
0.2.84
0.2.83
0.2.82
0.2.81
0.2.80
0.2.79
0.2.78
0.2.77
0.2.76
0.2.75
0.2.74
0.2.73
0.2.72
0.2.71
0.2.70
0.2.69
0.2.68
0.2.67
0.2.65
0.2.64
0.2.63
0.2.62
0.2.60
0.2.59
0.2.58
0.2.57
0.2.56
0.2.55
0.2.54
0.2.53
0.2.51
0.2.50
0.2.49
0.2.48
0.2.47
0.2.46
0.2.45
0.2.44
0.2.43
0.2.42
0.2.41
0.2.40
0.2.39
0.2.38
0.2.37
0.2.36
0.2.35
0.2.33
0.2.32
0.2.31
0.2.30
0.2.29
0.2.28
0.2.26
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
Universal SQL engine for Elixir. This library implements the SQL logic to perform queries on user provided databases using a simple interface based on Foreign Data Wrappers from PostgreSQL.
Current section
Files
Jump to
Current section
Files
lib/builtins.ex
require Logger
defmodule ExoSQL.Builtins do
@moduledoc """
Builtin functions.
There are two categories, normal functions and aggregate functions. Aggregate
functions receive as first parameter a ExoSQL.Result with a full table,
and the rest of parameters are the function calling parameters, unsolved.
These expressions must be first simplified with
`ExoSQL.executor.simplify_expr_columns` and then executed on the rows with
`ExoSQL.Expr.run_expr`.
"""
import ExoSQL.Utils, only: [to_number: 1, to_float: 1]
def round(n, r) do
{:ok, n} = to_float(n)
{:ok, r} = to_number(r)
Float.round(n, r)
end
def concat(a, b) do
a = to_string(a)
b = to_string(b)
a <> b
end
def not_(a) do
not bool(a)
end
def bool(nil), do: false
def bool(0), do: false
def bool(""), do: false
def bool(false), do: false
def bool(_), do: true
def lower(s), do: String.downcase(s)
def upper(s), do: String.upcase(s)
def to_string_(%DateTime{} = d), do: DateTime.to_iso8601(d)
def to_string_(s), do: to_string(s)
def now(), do: DateTime.utc_now()
def to_datetime(other), do: ExoSQL.DateTime.to_datetime(other)
def to_timestamp(%DateTime{} = d), do: DateTime.to_unix(d)
@doc ~S"""
Convert datetime to string.
If no format is given, it is as to_string, which returns the ISO 8601.
Format allows these substitutions (subset from SQLITE):
%d day of month: 00
%H hour: 00-24
%m month: 01-12
%M minute: 00-59
%s seconds since 1970-01-01
%S seconds: 00-59
%Y year: 0000-9999
%i ISO 8601 format
%% %
"""
def strftime(%DateTime{} = d), do: to_string_(d)
def strftime(%DateTime{} = d, format), do: ExoSQL.DateTime.strftime(d, format)
def strftime(other, format), do: strftime(to_datetime(other), format)
### Aggregate functions
def is_aggregate("count"), do: true
def is_aggregate("avg"), do: true
def is_aggregate("sum"), do: true
def is_aggregate(_other), do: false
def count(data, _) do
# Logger.debug("Count #{inspect data}")
Enum.count(data.rows)
end
def avg(data, expr) do
# Logger.debug("Avg of #{inspect data} by #{inspect expr}")
sum(data, expr) / count(data, nil)
end
def sum(data, expr) do
# Logger.debug("Sum of #{inspect data} by #{inspect expr}")
expr = ExoSQL.Executor.simplify_expr_columns(expr, data.columns, nil)
# Logger.debug("Simplified expression #{inspect expr}")
Enum.reduce(data.rows, 0, fn row, acc ->
n = ExoSQL.Expr.run_expr(expr, row)
{:ok, n} = ExoSQL.Utils.to_number(n)
acc + n
end)
end
end