Packages
exosql
0.2.68
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/utils.ex
require Logger
defmodule ExoSQL.Utils do
@moduledoc """
Various assorted utility functions.
"""
def to_number(nil), do: {:error, nil}
def to_number(n) when is_number(n), do: {:ok, n}
# Weak typing
def to_number(n) when is_binary(n) do
{n, rem} =
if String.contains?(n, ".") do
Float.parse(n)
else
Integer.parse(n)
end
if rem == "" do
{:ok, n}
else
{:error, :bad_number}
end
end
def to_number!(n) do
{:ok, number} = to_number(n)
number
end
# Maybe better way??
def to_float(n) when is_number(n), do: {:ok, n + 0.0}
# Weak typing
def to_float(n) when is_binary(n) do
{n, rem} = Float.parse(n)
if rem == "" do
{:ok, n}
else
{:error, :bad_number}
end
end
def to_float!(n) do
{:ok, number} = to_float(n)
number
end
def format_result(res) do
s =
for {h, n} <- Enum.with_index(res.columns) do
case h do
{db, table, column} ->
"#{db}.#{table}.#{column}"
str when is_binary(str) ->
str
_ ->
"?COL#{n + 1}"
end
end
widths = Enum.map(s, &String.length/1)
s = [s |> Enum.join(" | ")]
s = [s, "\n"]
totalw = Enum.count(s) * 3 + Enum.reduce(widths, 0, &(&1 + &2))
# Logger.debug("#{inspect widths} #{inspect totalw}")
s = [s, String.duplicate("-", totalw)]
s = [s, "\n"]
widths = Enum.drop(widths, -1) ++ [0]
data =
for r <- res.rows do
c =
Enum.join(
Enum.map(Enum.zip(widths, r), fn {w, r} ->
r =
case r do
r when is_list(r) -> "[#{Enum.join(r, ", ")}]"
nil -> "NULL"
other -> other
end
String.pad_trailing(to_string(r), w)
end),
" | "
)
[c, "\n"]
end
s = [s, data]
# Logger.debug(inspect s)
to_string(s)
end
@doc ~S"""
Fron an initial input value, can generate a list.
The function receives a value and returns either:
* :halt
* {generated_value, next_input}
All the generated values are returned in order to the caller when :halt is
received.
"""
def generate(input, func) do
case func.(input) do
:halt -> []
{value, next} -> [value | generate(next, func)]
end
end
end