Current section
Files
Jump to
Current section
Files
lib/wobserver/util/table.ex
defmodule Wobserver.Table do
@moduledoc ~S"""
Table (ets) information and listing.
"""
import Wobserver.Util.Helper, only: [string_to_module: 1]
@doc ~S"""
Lists all tables with basic information.
Note: data is not included.
"""
@spec list :: list(map)
def list do
:ets.all()
|> Enum.map(&info/1)
end
@doc """
Creates an overview of table information based on the given `table` atom or number.
If `include_data` is set to `true`, it will also contain the table data.
"""
@spec info(table :: :ets.table(), include_data :: boolean) :: map
def info(table, include_data \\ false)
def info(table, false) do
%{
id: table,
name: :ets.info(table, :name) |> otherwise(:code),
type: :ets.info(table, :type) |> otherwise(:set),
size: :ets.info(table, :size),
memory: :ets.info(table, :memory),
owner: :ets.info(table, :owner),
protection: :ets.info(table, :protection) |> otherwise(:private),
meta: %{
read_concurrency: :ets.info(table, :read_concurrency) |> otherwise(false),
write_concurrency: :ets.info(table, :write_concurrency) |> otherwise(false),
compressed: :ets.info(table, :compressed) |> otherwise(false)
}
}
end
def info(table, true) do
table
|> info(false)
|> Map.put(:data, data(table))
end
@doc ~S"""
Sanitizes a `table` name and returns either the table id or name.
Example:
```bash
iex> Wobserver.Table.sanitize :code
:code
```
```bash
iex> Wobserver.Table.sanitize 1
1
```
```bash
iex> Wobserver.Table.sanitize "code"
:code
```
```bash
iex> Wobserver.Table.sanitize "1"
1
```
"""
@spec sanitize(table :: atom | integer | String.t()) :: atom | integer
def sanitize(table) when is_atom(table), do: table
def sanitize(table) when is_integer(table), do: table
def sanitize(table) when is_binary(table) do
case Integer.parse(table) do
{nr, ""} -> nr
_ -> table |> string_to_module()
end
end
# Helpers
defp otherwise(value1, value2) do
case value1 do
:undefined -> value2
_ -> value1
end
end
defp data(table) do
case :ets.info(table, :protection) do
:undefined ->
[]
:private ->
[]
_ ->
table
|> :ets.match(:"$1")
|> Enum.map(&data_row/1)
end
end
defp data_row([row]) do
row
|> Tuple.to_list()
|> Enum.map(&to_string(:io_lib.format("~tp", [&1])))
end
end