Packages
tzdata
1.0.0
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc.1
1.0.0-rc.0
0.5.22
0.5.21
0.5.20
0.5.19
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.1.201805
0.1.201605
0.1.201603
0.1.201601
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.2
0.0.1
Tzdata is a parser and library for the tz database.
Current section
Files
Jump to
Current section
Files
lib/tzdata/ets_holder.ex
defmodule Tzdata.EtsHolder do
@moduledoc false
require Logger
use GenServer
alias Tzdata.DataBuilder
alias Tzdata.Util
@file_version 2
def start_link() do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
make_sure_a_release_is_on_file()
create_current_release_ets_table()
{:ok, release_name} = load_release()
{:ok, release_name}
end
def new_release_has_been_downloaded do
GenServer.cast(__MODULE__, :new_release_has_been_downloaded)
end
def handle_cast(:new_release_has_been_downloaded, state) do
{:ok, new_release_name} = load_release()
if state != new_release_name do
Logger.info("Tzdata has updated the release from #{state} to #{new_release_name}")
delete_ets_table_for_version(state)
delete_ets_file_for_version(state)
end
{:noreply, new_release_name}
end
defp delete_ets_table_for_version(release_version) do
Logger.debug("Tzdata deleting ETS table for version #{release_version}")
release_version
|> DataBuilder.ets_table_name_for_release_version()
|> :ets.delete()
end
defp delete_ets_file_for_version(release_version) do
Logger.debug("Tzdata deleting ETS table file for version #{release_version}")
release_version
|> DataBuilder.ets_file_name_for_release_version()
|> File.rm()
end
defp load_release do
release_name = newest_release_on_file()
load_ets_table(release_name)
set_current_release(release_name)
{:ok, release_name}
end
defp load_ets_table(release_name) do
file_name = "#{release_dir()}/#{release_name}.v#{@file_version}.ets"
{:ok, _table} = :ets.file2tab(:erlang.binary_to_list(file_name))
end
defp create_current_release_ets_table do
table = :ets.new(:tzdata_current_release, [:set, :named_table])
{:ok, table}
end
defp set_current_release(release_version) do
# Logger.debug "Tzdata setting current release version to #{release_version}"
:ets.insert(:tzdata_current_release, {:release_version, release_version})
end
defp make_sure_a_release_is_on_file do
make_sure_a_release_dir_exists()
cond do
release_files() == [] and Util.custom_data_dir_configured? ->
Logger.info("No tzdata release files found in custom data dir. Copying release file from tzdata priv dir.")
copy_release_dir_from_priv()
release_files() == [] and not Util.custom_data_dir_configured? ->
Logger.error("No tzdata release files found!")
true ->
nil
end
end
defp copy_release_dir_from_priv() do
custom_destination_dir = Tzdata.Util.data_dir() <> "/release_ets"
priv_release_ets_dir = Application.app_dir(:tzdata, "priv") <> "/release_ets"
priv_release_ets_dir
|> release_files_for_dir
|> Enum.each(fn file ->
File.copy!(priv_release_ets_dir <> "/" <> file, custom_destination_dir <> "/" <> file)
end)
end
defp make_sure_a_release_dir_exists do
File.mkdir_p(release_dir())
end
defp newest_release_on_file do
release_files()
|> List.last()
|> String.replace(".v#{@file_version}.ets", "")
end
defp release_files do
release_dir()
|> release_files_for_dir()
end
defp release_files_for_dir(dir) do
dir
|> File.ls!()
|> Enum.filter(&Regex.match?(~r/^2\d{3}[a-z]\.v#{@file_version}\.ets/, &1))
|> Enum.sort()
end
defp release_dir do
Tzdata.Util.data_dir() <> "/release_ets"
end
@doc """
Returns the file version number used by the current version of Tzdata for the ETS files.
"""
@spec file_version() :: non_neg_integer()
def file_version do
@file_version
end
end