Packages
kino
0.11.3
0.19.0
0.18.0
0.17.0
0.16.1
0.16.0
0.15.3
0.15.2
0.15.1
0.15.0
0.14.2
0.14.1
0.14.0
0.13.2
0.13.1
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.0
0.6.2
0.6.1
0.6.0
retired
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
Interactive widgets for Livebook
Current section
Files
Jump to
Current section
Files
lib/kino/ets.ex
defmodule Kino.ETS do
@moduledoc """
A kino for interactively viewing an ETS table.
## Examples
tid = :ets.new(:users, [:set, :public])
Kino.ETS.new(tid)
Kino.ETS.new(:elixir_config)
"""
@behaviour Kino.Table
@type t :: Kino.Table.t()
@doc """
Creates a new kino displaying the given ETS table.
Note that private tables cannot be read by an arbitrary process,
so the given table must have either public or protected access.
"""
@spec new(:ets.tid()) :: t()
def new(tid) do
case :ets.info(tid, :protection) do
:private ->
raise ArgumentError,
"the given table must be either public or protected, but a private one was given"
:undefined ->
raise ArgumentError,
"the given table identifier #{inspect(tid)} does not refer to an existing ETS table"
_ ->
:ok
end
Kino.Table.new(__MODULE__, {tid})
end
@impl true
def init({tid}) do
table_name = :ets.info(tid, :name)
name = "ETS #{inspect(table_name)}"
info = %{name: name, features: [:refetch, :pagination]}
{:ok, info, %{tid: tid}}
end
@impl true
def get_data(rows_spec, state) do
records = get_records(state.tid, rows_spec)
data = Enum.map(records, fn record -> [inspect(record)] end)
total_rows = :ets.info(state.tid, :size)
columns = [%{key: 0, label: "row", type: "tuple"}]
{:ok, %{columns: columns, data: {:rows, data}, total_rows: total_rows}, state}
end
defp get_records(tid, rows_spec) do
query = :ets.table(tid)
cursor = :qlc.cursor(query)
if rows_spec.offset > 0 do
:qlc.next_answers(cursor, rows_spec.offset)
end
records = :qlc.next_answers(cursor, rows_spec.limit)
:qlc.delete_cursor(cursor)
records
end
end