defmodule ExDets do @moduledoc """ This module is a wrapper of erlang dets makes with ExWrapper. Go to the doc of :dets erlang. Only add from :dets, for the moment: * ExDets add dets_files?/1. """ # TODO Test the utils/dets @doc ":dets.al/0 wrapper function." @spec all() :: [:dets.tab_name] def all() do :dets.all() end @doc ":dets.bchunk/2 wrapper function." @spec bchunk(name :: :dets.tab_name, continuation :: :start | :dets.cont) :: {:dets.cont, binary | tuple} | nil | {:error, term} def bchunk(name, continuation) do case :dets.bchunk(name,continuation) do {:error, _reason} = error -> ExWrapper.convert(error) {_continuation2, _data} = con_data -> con_data '$end_of_table' -> nil end end @doc ":dets.close/1 wrapper function." @spec close(name :: :dets.tab_name) :: :ok | {:error, term} def close(name) do case :dets.close(name) do :ok -> :ok error -> ExWrapper.convert(error) end end @doc ":dets.delete/2 wrapper function." @spec delete(name :: :dets.tab_name, key :: term) :: :ok | {:error, term} def delete(name, key) do case :dets.delete(name, key) do :ok -> :ok error -> ExWrapper.convert(error) end end @doc ":dets.delete_all_objects/1 wrapper function." @spec delete_all_objects(name :: :dets.tab_name) :: :ok | {:error, term} def delete_all_objects(name) do case :dets.delete_all_objects(name) do :ok -> :ok error -> ExWrapper.convert(error) end end @doc ":dets.delete_object/2 wrapper function." @spec delete_object(name :: :dets.tab_name, object :: :dets.object) :: :ok | {:error, term} def delete_object(name, object) do case :dets.delete_object(name, object) do :ok -> :ok error -> ExWrapper.convert(error) end end @doc ":dets.first/1 wrapper function." @spec first(name :: :dets.tab_name) :: term | nil def first(name) do case :dets.first(name) do '$end_of_table' -> nil key -> key end end @doc ":dets.foldl/3 wrapper function." @spec foldl(function :: (object :: :dets.object, acc_in :: term -> acc_out :: term), acc0 :: term, name :: :dets.tab_name) :: term | nil def foldl(function, acc0, name) do case :dets.foldl(function, acc0, name) do {:error, _reason} = error -> ExWrapper.convert(error) acc -> acc end end @doc ":dets.foldr/3 wrapper function." @spec foldl(function :: (object :: :dets.object, acc_in :: term -> acc_out :: term), acc0 :: term, name :: :dets.tab_name) :: term | nil def foldr(function, acc0, name) do case :dets.foldr(function, acc0, name) do {:error, _reason} = error -> ExWrapper.convert(error) acc -> acc end end @doc ":dets.from_ets/2 wrapper function." @spec from_ets(name :: :dets.tab_name, ets_tab :: :ets.tab) :: :ok | {:error, term} def from_ets(name, ets_tab) do case :dets.from_ets(name, ets_tab) do :ok -> :ok error -> ExWrapper.convert(error) end end @doc ":dets.info/1 wrapper function." @spec info(name :: :dets.tab_name) :: :dets.infolist | :undefined def info(name) do case :dets.info(name) do infolist when is_list(infolist) -> ExWrapper.convert(infolist) :undefined -> :undefined end end @doc ":dets.info/2 wrapper function." @spec info(name :: :dets.tab_name, item :: :dets.item) :: :dets.value | :undefined def info(name, item) do case :dets.info(name, item) do :undefined -> :undefined value -> ExWrapper.convert(value) end end @doc ":dets.init_table/2 wrapper function." @spec init_table(name :: :dets.tab_name, init_fun :: :dets.init_fun) :: :ok | {:error, term} def init_table(name, init_fun) do case :dets.init_table(name, init_fun) do :ok -> :ok error -> ExWrapper.convert(error) end end @doc ":dets.init_table/3 wrapper function." @spec init_table(name :: :dets.tab_name, init_fun :: :dets.init_fun, options :: :dets.options) :: :ok | {:error, term} def init_table(name, init_fun, options) do case :dets.init_table(name, init_fun, options) do :ok -> :ok error -> ExWrapper.convert(error) end end @doc ":dets.insert/2 wrapper function." @spec insert(name :: :dets.tab_name, objects :: :dets.objects) :: :ok | {:error, term} def insert(name, objects) do case :dets.insert(name, objects) do :ok -> :ok error -> ExWrapper.convert(error) end end @doc ":dets.insert_new/2 wrapper function." @spec insert_new(name :: :dets.tab_name, objects :: :dets.objects) :: boolean | {:error, term} def insert_new(name, objects) do case :dets.insert_new(name, objects) do bool when is_boolean(bool) -> bool error -> ExWrapper.convert(error) end end @doc ":dets.is_compatible_bchunk_format/2 wrapper function." @spec compatible_bchunk_format?(name :: :dets.tab_name, bchunk_format :: :dets.bchunk_format) :: boolean def compatible_bchunk_format?(name, bchunk_format) do :dets.is_compatible_bchunk_format(name, bchunk_format) end @doc ":dets.is_dets_file/1 wrapper function." @spec dets_file?(filename :: :file.name) :: boolean def dets_file?(filename) do :dets.is_dets_file(filename) end @doc """ It's an ajout from my conception, it's execute dets_file?/1 one each file in the same time with Task and check if any results is true. ## Example ExDets.open_file("my.dets", []) ExDets.open_file("other.dets", []) File.touch("otherfile") refute ExDets.dets_files?(["my.dets", "other.dets", "otherfile"]) """ @spec dets_files?(filenames :: [:file.name]) :: boolean def dets_files?(filenames) do filenames |> Enum.map(&(Task.async(fn -> dets_file?(&1) end))) |> Enum.map(&Task.await/1) |> Enum.all?(&(&1==true)) end @doc ":dets.lookup/2 wrapper function." @spec lookup(name :: :dets.tab_name, key :: term) :: :dets.objects | {:error, term} def lookup(name, key) do case :dets.lookup(name, key) do objects when is_list(objects) -> objects {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.match/1 wrapper function." @spec match(continuation :: :dets.cont) :: {[term], :dets.cont} | nil | {:error, term} def match(continuation) do case :dets.match(continuation) do {match, _continuation2} = matching when is_list(match) -> matching '$end_of_table' -> nil {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.match/2 wrapper function." @spec match(name :: :dets.tab_name, pattern :: :dets.pattern) :: [term] | {:error, term} def match(name, pattern) do case :dets.match(name, pattern) do matchs when is_list(matchs) -> matchs {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.match/3 wrapper function." @spec match(name :: :dets.tab_name, pattern :: :dets.pattern, n :: :default | integer) :: [term] | {:error, term} def match(name, pattern, n) do case :dets.match(name, pattern, n) do {matchs, _continuation} = matching when is_list(matchs) -> matching '$end_of_table' -> nil {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.match_delete/2 wrapper function." @spec match_delete(name :: :dets.tab_name, pattern :: :dets.pattern) :: :ok | {:error, term} def match_delete(name, pattern) do case :dets.match_delete(name, pattern) do :ok -> :ok {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.match_object/1 wrapper function." @spec match_object(continuation :: :dets.object_cont) :: {:dets.objects, :dets.object_cont} | nil | {:error, term} def match_object(continuation) do case :dets.match_object(continuation) do {matchs, _continuation2} = matching when is_list(matchs) -> matching '$end_of_table' -> nil {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.match_object/2 wrapper function." @spec match_object(name :: :dets.tab_name, pattern :: :dets.pattern) :: :dets.objects | {:error, term} def match_object(name, pattern) do case :dets.match_object(name, pattern) do matchs when is_list(matchs) -> matchs {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.match_object/3 wrapper function." @spec match_object(name :: :dets.tab_name, pattern :: :dets.pattern, n :: :default | integer) :: {:dets.objects, :dets.cont} | nil | {:error, term} def match_object(name, pattern, n) do case :dets.match_object(name, pattern, n) do {matchs, _continuation2} = matching when is_list(matchs) -> matching '$end_of_table' -> nil {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.member/2 wrapper function." @spec member(name :: :dets.tab_name, key :: term) :: boolean | {:error, term} def member(name, key) do case :dets.member(name, key) do bool when is_boolean(bool) -> bool {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.next/2 wrapper function." @spec next(name :: :dets.tab_name, key :: term) :: term | nil def next(name, key) do case :dets.next(name, key) do '$end_of_table' -> nil key2 -> key2 end end @doc ":dets.open_file/1 wrapper function." @spec open_file(filename :: :file.name) :: {:ok, :dets.reference} | {:error, term} def open_file(filename) do case :dets.open_file(filename) do {:ok, _reference} = ref -> ref {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.open_file/2 wrapper function." @spec open_file(name :: :dets.tab_name, args :: :dets.args) :: {:ok, :dets.tab_name} | {:error, term} def open_file(name, args) do case :dets.open_file(name, args) do {:ok, _name} = ref -> ref {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.pid2name/1 wrapper fonction." @spec pid2name(pid :: pid) :: {:ok, :dets.tab_name} | :undefined def pid2name(pid) do case :dets.pid2name(pid) do {:ok, _name} = name -> name {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.repair_continuation/2 wrapper function." @spec repair_continuation(continuation :: :dets.select_cont, match_spec :: :dets.match_spec) :: :dets.select_cont def repair_continuation(continuation, match_spec) do :dets.repair_continuation(continuation, match_spec) end @doc ":dets.safe_fixtable/2 wrapper function." @spec safe_fixtable(name :: :dets.tab_name, fix :: boolean) :: :ok def safe_fixtable(name, fix) do :dets.safe_fixtable(name, fix) end @doc ":dets.select/1 wrapper function." @spec select(continuation :: :dets.select_cont) :: {[term], :dets.select_cont} | nil | {:error, term} def select(continuation) do case :dets.select(continuation) do {selection, _continuation2} = selects when is_list(selection) -> selects '$end_of_table' -> nil {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.select/2 wrapper function." @spec select(name :: :dets.tab_name, match_spec :: :dets.match_spec) :: [term] | {:error, term} def select(name, match_spec) do case :dets.select(name, match_spec) do selection when is_list(selection) -> selection {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.select/3 wrapper function." @spec select(name :: :dets.tab_name, match_spec :: :dets.match_spec, n :: :default | integer) :: [term] | nil | {:error, term} def select(name, match_spec, n) do case :dets.select(name, match_spec, n) do selection when is_list(selection) -> selection '$end_of_table' -> nil {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.select_delete/2 wrapper function." @spec select_delete(name :: term, match_spec :: :dets.match_spec) :: integer | {:error, term} def select_delete(name, match_spec) do case :dets.select_delete(name, match_spec) do n when is_integer(n) -> n {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.slot/2 wrapper function." @spec slot(name :: :dets.tab_name, i :: non_neg_integer) :: [:dets.object] | nil | {:error, term} def slot(name, i) do case :dets.slot(name, i) do objects when is_list(objects) -> objects '$end_of_table' -> nil {:error, _reason} = error-> ExWrapper.convert(error) end end @doc ":dets.sync/1 wrapper function." @spec sync(name :: :dets.tab_name) :: :ok | {:error, term} def sync(name) do case :dets.sync(name) do :ok -> :ok {:error, _reason} = error -> ExWrapper.convert(error) end end @doc ":dets.table/1 wrapper function." @spec table(name :: :dets.tab_name) :: :dets.query_handler def table(name) do :dets.table(name) end @doc ":dets.table/2 wrapper function." @spec table(name :: :dets.tab_name, options :: [:dets.option] | :dets.option) :: :qlc.query_handler def table(name, options) do :dets.table(name, options) end @doc ":dets.to_ets/2 wrapper function." @spec to_ets(name :: :dets.tab_name, :ets.tab) :: :ets.tab | {:error, term} def to_ets(name, ets_tab) do case :dets.to_ets(name, ets_tab) do {:error, _reason} = error -> ExWrapper.convert(error) ets -> ets end end @doc ":dets.traverse/2 wrapper function." @spec traverse(name :: :dets.tab_name, fun :: (:dets.object -> (:continue | {:continue, term} | {:done, term}))) :: ([term] | term) | {:error, term} def traverse(name, fun) do case :dets.traverse(name, fun) do {:error, _reason} = error -> ExWrapper.convert(error) return -> return end end @doc ":dets.update_counter/3 wrapper function." @spec update_counter(name :: :dets.tab_name, key :: term, increment :: {integer, integer} | integer) :: integer def update_counter(name, key, increment) do :dets.update_counter(name, key, increment) end end