Generate zone db in static modules
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ tzdata/
|
|||||||
\#*
|
\#*
|
||||||
db/
|
db/
|
||||||
out
|
out
|
||||||
|
zones
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
-module(erldev).
|
|
||||||
%% Contains development-related functions.
|
|
||||||
|
|
||||||
%-compile([export_all]).
|
|
||||||
-export([make_app/1]).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%% "Compiles" a *.app.src file into a .app file, and places it in
|
|
||||||
%% the appropriate ebin folder
|
|
||||||
make_app([AppDirAtom]) ->
|
|
||||||
%%@todo: module name conflicts?
|
|
||||||
AppDir = atom_to_list(AppDirAtom),
|
|
||||||
Modules = get_modules(AppDir),
|
|
||||||
AppSrc = try get_app_src(AppDir)
|
|
||||||
catch error:{badmatch, _} ->
|
|
||||||
% error_logger:error_msg("Couldn't get AppSrcFile for ~p~n", [AppDir]),
|
|
||||||
erlang:halt()
|
|
||||||
end,
|
|
||||||
{application, Name, Opts} = AppSrc,
|
|
||||||
NewOpts = [ {modules, Modules} | Opts ],
|
|
||||||
AppFile = filename:join([AppDir, "ebin", atom_to_list(Name) ++ ".app"]),
|
|
||||||
ok = file:write_file(AppFile, io_lib:format("~p.~n", [{application, Name, NewOpts}])),
|
|
||||||
error_logger:info_msg("Wrote .app contents to: ~p~n", [AppFile]),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%% Returns a list of module names of all *.erl files in a given Application
|
|
||||||
%% folder (assuming OTP directory structure)
|
|
||||||
get_modules(AppDir) ->
|
|
||||||
lists:map(
|
|
||||||
fun(X)-> filename:basename(X, ".erl") end,
|
|
||||||
filelib:wildcard(
|
|
||||||
filename:join([AppDir, "src", "*.erl"])
|
|
||||||
)
|
|
||||||
).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%% Converts the contsnts of the *.app.src file into erlang terms
|
|
||||||
get_app_src(AppDir) ->
|
|
||||||
[AppSrcFile] = filelib:wildcard(filename:join([AppDir, "src", "*.app.src"])),
|
|
||||||
{ok, [AppSrc]} = file:consult(AppSrcFile),
|
|
||||||
%error_logger:info_msg("AppSrc: ~p~n", [AppSrc]),
|
|
||||||
AppSrc.
|
|
||||||
|
|
||||||
@@ -6,6 +6,5 @@
|
|||||||
kernel,
|
kernel,
|
||||||
stdlib
|
stdlib
|
||||||
]},
|
]},
|
||||||
{mod, {ezic_app, ezic_db_ets}},
|
{env, [{tzdata_dir, "priv/tzdata"}]}
|
||||||
{env, [{db_dir, "db"}, {tzdata_dir, "priv/tzdata"}]}
|
|
||||||
]}.
|
]}.
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% File : ezic_app.erl
|
|
||||||
%%% Author : aj <aj@fattie>
|
|
||||||
%%% Description :
|
|
||||||
%%%
|
|
||||||
%%% Created : 15 Nov 2010 by aj <aj@fattie>
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(ezic_app).
|
|
||||||
|
|
||||||
-behaviour(application).
|
|
||||||
|
|
||||||
%% Application callbacks
|
|
||||||
-export([start/2, stop/1]).
|
|
||||||
|
|
||||||
%%====================================================================
|
|
||||||
%% Application callbacks
|
|
||||||
%%====================================================================
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%% Function: start(Type, StartArgs) -> {ok, Pid} |
|
|
||||||
%% {ok, Pid, State} |
|
|
||||||
%% {error, Reason}
|
|
||||||
%% Description: This function is called whenever an application
|
|
||||||
%% is started using application:start/1,2, and should start the processes
|
|
||||||
%% of the application. If the application is structured according to the
|
|
||||||
%% OTP design principles as a supervision tree, this means starting the
|
|
||||||
%% top supervisor of the tree.
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
start(_Type, StartArgs) ->
|
|
||||||
case ezic_sup:start_link(StartArgs) of
|
|
||||||
{ok, Pid} ->
|
|
||||||
{ok, Pid};
|
|
||||||
Error ->
|
|
||||||
Error
|
|
||||||
end.
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%% Function: stop(State) -> void()
|
|
||||||
%% Description: This function is called whenever an application
|
|
||||||
%% has stopped. It is intended to be the opposite of Module:start/2 and
|
|
||||||
%% should do any necessary cleaning up. The return value is ignored.
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
stop(_State) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
%%====================================================================
|
|
||||||
%% Internal functions
|
|
||||||
%%====================================================================
|
|
||||||
174
src/ezic_db.erl
174
src/ezic_db.erl
@@ -1,158 +1,24 @@
|
|||||||
-module(ezic_db).
|
-module(ezic_db).
|
||||||
-include("include/ezic.hrl").
|
-include("include/ezic.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-export([flatzone/2]).
|
||||||
|
|
||||||
-behaviour(gen_server).
|
flatzone(Date, ZoneName) ->
|
||||||
|
ModuleName = ezic_zone_map:find(ZoneName),
|
||||||
|
FlatZones = ModuleName:flatzones(),
|
||||||
|
{D, #tztime{time = T, flag = F}} = Date,
|
||||||
|
DComp = {D, T},
|
||||||
|
case lists:filter(filter(DComp, F), FlatZones) of
|
||||||
|
[] -> {error, no_zone};
|
||||||
|
[FlatZone] -> FlatZone;
|
||||||
|
Matches = [_, _] -> {error, {ambiguous_zone, Matches}};
|
||||||
|
Matches -> {error, {should_not_happen, {Matches, Date, ZoneName}}}
|
||||||
|
end.
|
||||||
|
|
||||||
|
filter(DComp, u) ->
|
||||||
-export([
|
fun(#flatzone{utc_from = From, utc_to = To}) ->
|
||||||
zones/1
|
(From =< DComp) and ((DComp =< To) or (To == current))
|
||||||
, rules/1
|
end;
|
||||||
, flatzones/1
|
filter(DComp, w) ->
|
||||||
, flatzone/2
|
fun(#flatzone{wall_from = From, wall_to = To}) ->
|
||||||
%, insert/2
|
(From =< DComp) and ((DComp =< To) or (To == current))
|
||||||
, get_all/1
|
end.
|
||||||
, insert_all/1
|
|
||||||
, wipe/1
|
|
||||||
, flatten/0
|
|
||||||
, get_implementation/0
|
|
||||||
]).
|
|
||||||
|
|
||||||
-export([
|
|
||||||
start_link/1
|
|
||||||
, init/1
|
|
||||||
, code_change/3
|
|
||||||
, handle_call/3
|
|
||||||
, handle_cast/2
|
|
||||||
, handle_info/2
|
|
||||||
, terminate/2
|
|
||||||
]).
|
|
||||||
|
|
||||||
|
|
||||||
-record(state, {mod}).
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% PUBLIC API
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
|
|
||||||
zones(TzName) ->
|
|
||||||
gen_server:call(?MODULE, {zones, TzName}).
|
|
||||||
|
|
||||||
|
|
||||||
rules(TzName) ->
|
|
||||||
gen_server:call(?MODULE, {rules, TzName}).
|
|
||||||
|
|
||||||
|
|
||||||
flatzones(TzName) ->
|
|
||||||
gen_server:call(?MODULE, {flatzones, TzName}).
|
|
||||||
|
|
||||||
|
|
||||||
flatzone(Date, TzName) ->
|
|
||||||
gen_server:call(?MODULE, {flatzone, Date, TzName}).
|
|
||||||
|
|
||||||
|
|
||||||
get_all(Tab) ->
|
|
||||||
gen_server:call(?MODULE, {all, Tab}).
|
|
||||||
|
|
||||||
|
|
||||||
insert_all(Records) ->
|
|
||||||
gen_server:call(?MODULE, {insert_all, Records}).
|
|
||||||
|
|
||||||
|
|
||||||
%wipe() ->
|
|
||||||
% gen_server:call(?MODULE, {wipe}).
|
|
||||||
|
|
||||||
|
|
||||||
wipe(Tab) ->
|
|
||||||
gen_server:call(?MODULE, {wipe, Tab}).
|
|
||||||
|
|
||||||
|
|
||||||
flatten() ->
|
|
||||||
gen_server:call(?MODULE, {flatten}).
|
|
||||||
|
|
||||||
get_implementation() ->
|
|
||||||
gen_server:call(?MODULE, {implementation}).
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%% GEN_SERVER
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
|
|
||||||
start_link(StartArgs) ->
|
|
||||||
gen_server:start_link({local, ?MODULE}, ?MODULE, StartArgs, []).
|
|
||||||
|
|
||||||
|
|
||||||
%% TODO: create a db behavior
|
|
||||||
init(DbModule) when DbModule =:= ezic_db_mnesia;
|
|
||||||
DbModule=:= ezic_db_ets ->
|
|
||||||
DbModule:init(),
|
|
||||||
State = #state{mod = DbModule},
|
|
||||||
{ok, State}.
|
|
||||||
|
|
||||||
%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
%% DB Lookup
|
|
||||||
%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
|
|
||||||
handle_call({zones, Name}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Matches= Mod:zones(Name),
|
|
||||||
{reply, Matches, State};
|
|
||||||
handle_call({rules, Name}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Matches= Mod:rules(Name),
|
|
||||||
{reply, Matches, State};
|
|
||||||
handle_call({all, Tab}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Matches= Mod:get_all(Tab),
|
|
||||||
{reply, Matches, State};
|
|
||||||
handle_call({flatzones, Name}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Result= Mod:flatzones(Name),
|
|
||||||
{reply, Result, State};
|
|
||||||
handle_call({flatzone, Date, Name}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Result= Mod:flatzone(Date, Name),
|
|
||||||
{reply, Result, State};
|
|
||||||
handle_call({insert_all, Records}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Mod:insert_all(Records),
|
|
||||||
{noreply, State};
|
|
||||||
handle_call({wipe, Tab}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Result= Mod:wipe(Tab),
|
|
||||||
{reply, Result, State};
|
|
||||||
handle_call({flatten}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Zones= Mod:get_all(zone),
|
|
||||||
Rules= Mod:get_all(rule),
|
|
||||||
FlatZone= ezic_flatten:flatten(Zones, Rules),
|
|
||||||
Result= Mod:insert_all(FlatZone),
|
|
||||||
{reply, Result, State};
|
|
||||||
handle_call({implementation}, _, State) ->
|
|
||||||
Mod= State#state.mod,
|
|
||||||
Impl= Mod:implementation(),
|
|
||||||
{reply, Impl, State};
|
|
||||||
handle_call(_, _, State) ->
|
|
||||||
{noreply, State}.
|
|
||||||
|
|
||||||
|
|
||||||
%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
%% Other gen_server
|
|
||||||
%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
|
|
||||||
code_change(_, State, _) ->
|
|
||||||
{ok, State}.
|
|
||||||
|
|
||||||
|
|
||||||
handle_cast(_, State) ->
|
|
||||||
{noreply, State}.
|
|
||||||
|
|
||||||
handle_info(_, State) ->
|
|
||||||
{noreply, State}.
|
|
||||||
|
|
||||||
terminate(_, _State) ->
|
|
||||||
ok.
|
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
-module(ezic_db_ets).
|
|
||||||
-include("include/ezic.hrl").
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
|
||||||
|
|
||||||
-define(DB_FILENAME, "db.e2f").
|
|
||||||
|
|
||||||
-export([
|
|
||||||
init/0
|
|
||||||
, zones/1
|
|
||||||
, rules/1
|
|
||||||
, flatzones/1
|
|
||||||
, flatzone/2
|
|
||||||
%, insert/2
|
|
||||||
, get_all/1
|
|
||||||
, insert_all/1
|
|
||||||
, wipe/1
|
|
||||||
, implementation/0
|
|
||||||
]).
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% PUBLIC API
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
|
|
||||||
implementation() -> ?MODULE.
|
|
||||||
|
|
||||||
zones(TzName) ->
|
|
||||||
ets:select(zone, [{#zone{name=TzName, _='_'}, [], ['$_']}]).
|
|
||||||
|
|
||||||
rules(TzName) ->
|
|
||||||
ets:select(rule, [{#rule{name=TzName, _='_'}, [], ['$_']}]).
|
|
||||||
|
|
||||||
flatzones(TzName) ->
|
|
||||||
ets:select(flatzone, [{#flatzone{tzname=TzName, _='_'}, [], ['$_']}]).
|
|
||||||
|
|
||||||
|
|
||||||
flatzone(Date, TzName) ->
|
|
||||||
FlatZones= ets:select(flatzone, ezic_flatten:ms(Date, TzName)),
|
|
||||||
case length(FlatZones) of
|
|
||||||
1 ->
|
|
||||||
hd(FlatZones);
|
|
||||||
2 ->
|
|
||||||
{error, {ambiguous_zone, FlatZones}};
|
|
||||||
0 ->
|
|
||||||
{error, no_zone};
|
|
||||||
_ ->
|
|
||||||
{error, {should_not_happen, {FlatZones, Date, TzName}}}
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
get_all(Tab) ->
|
|
||||||
try ets:lookup(Tab, Tab) of X -> X
|
|
||||||
catch error:X -> {error, X}
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
insert_all(Records) ->
|
|
||||||
Zones= [ZI || ZI <- Records, ZI = #zone{}],
|
|
||||||
ets:insert(zone, Zones),
|
|
||||||
Rules= [RI || RI <- Records, RI = #rule{}],
|
|
||||||
ets:insert(rule, Rules),
|
|
||||||
FlatZones= [FZ || FZ <- Records, FZ = #flatzone{}],
|
|
||||||
ets:insert(flatzone, FlatZones).
|
|
||||||
|
|
||||||
|
|
||||||
%wipe() ->
|
|
||||||
% gen_server:call(?MODULE, {wipe}).
|
|
||||||
|
|
||||||
|
|
||||||
wipe(Tab) ->
|
|
||||||
ets:delete(Tab, Tab).
|
|
||||||
|
|
||||||
|
|
||||||
init() ->
|
|
||||||
{ok, DbDir}= application:get_env(db_dir),
|
|
||||||
Filename= filename:join(DbDir, ?DB_FILENAME),
|
|
||||||
case db_sane(Filename) of
|
|
||||||
true -> load_tabfile(Filename);
|
|
||||||
false -> create_tables(Filename)
|
|
||||||
end,
|
|
||||||
{ok, []}.
|
|
||||||
|
|
||||||
%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
%% Private functions for initializing ets
|
|
||||||
%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
|
|
||||||
%% -> true if table exists
|
|
||||||
db_sane(Filename) ->
|
|
||||||
%% @todo ensure data is present for each record type.
|
|
||||||
|
|
||||||
case ets:tabfile_info(Filename) of
|
|
||||||
{ok, _} -> true;
|
|
||||||
{error, _} -> false
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%% creates the dets table and populates it.
|
|
||||||
create_tables(Filename) ->
|
|
||||||
{ok, Zones, Rules, _, _} = ezic_record:separate(ezic_loader:load()),
|
|
||||||
|
|
||||||
ets:new(zone, [duplicate_bag, named_table]),
|
|
||||||
true = ets:insert(zone, Zones),
|
|
||||||
|
|
||||||
ets:new(rule, [duplicate_bag, named_table]),
|
|
||||||
true = ets:insert(rule, Rules),
|
|
||||||
|
|
||||||
ets:new(flatzone, [duplicate_bag, named_table]),
|
|
||||||
%% error_logger:info_msg("~p~n", [Rules]),
|
|
||||||
FlatZones = ezic_flatten:flatten(Zones, Rules),
|
|
||||||
true = ets:insert(flatzone, FlatZones),
|
|
||||||
|
|
||||||
% combine into one ets
|
|
||||||
Ets= ets:new(ezic_db_ets, [duplicate_bag]),
|
|
||||||
ets:insert(Ets, ets:lookup(zone, zone)),
|
|
||||||
ets:insert(Ets, ets:lookup(rule, rule)),
|
|
||||||
ets:insert(Ets, ets:lookup(flatzone, flatzone)),
|
|
||||||
|
|
||||||
% save to disk
|
|
||||||
ets:tab2file(Ets, Filename),
|
|
||||||
|
|
||||||
ets:delete(Ets),
|
|
||||||
|
|
||||||
ok.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%% loads or creates the dets table.
|
|
||||||
load_tabfile(Filename) ->
|
|
||||||
{ok, Ets}= ets:file2tab(Filename),
|
|
||||||
|
|
||||||
Zones= ets:lookup(Ets, zone),
|
|
||||||
ets:new(zone, [duplicate_bag, named_table]),
|
|
||||||
ets:insert(zone, Zones),
|
|
||||||
|
|
||||||
Rules= ets:lookup(Ets, rule),
|
|
||||||
ets:new(rule, [duplicate_bag, named_table]),
|
|
||||||
ets:insert(rule, Rules),
|
|
||||||
|
|
||||||
FlatZones= ets:lookup(Ets, flatzone),
|
|
||||||
ets:new(flatzone, [duplicate_bag, named_table]),
|
|
||||||
ets:insert(flatzone, FlatZones),
|
|
||||||
|
|
||||||
ets:delete(Ets),
|
|
||||||
ok.
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
-module(ezic_db_mnesia).
|
|
||||||
-include("include/ezic.hrl").
|
|
||||||
-include_lib("stdlib/include/qlc.hrl").
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
|
||||||
|
|
||||||
|
|
||||||
-export([
|
|
||||||
init/0
|
|
||||||
, zones/1
|
|
||||||
, rules/1
|
|
||||||
, flatzones/1
|
|
||||||
, flatzone/2
|
|
||||||
%, insert/2
|
|
||||||
, get_all/1
|
|
||||||
, insert_all/1
|
|
||||||
, wipe/1
|
|
||||||
, implementation/0
|
|
||||||
]).
|
|
||||||
|
|
||||||
-define(create(Record),
|
|
||||||
{atomic, ok} = mnesia:create_table(Record,
|
|
||||||
[{type, bag}
|
|
||||||
, {disc_copies, [node()]}
|
|
||||||
, {attributes, record_info(fields, Record)}
|
|
||||||
])).
|
|
||||||
|
|
||||||
|
|
||||||
implementation() -> ?MODULE.
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% READ - db reading methods
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% retrieve all zones by name
|
|
||||||
zones(Name) ->
|
|
||||||
F = fun()->
|
|
||||||
Q = qlc:q([Z || Z=#zone{name=N} <- mnesia:table(zone), N=:=Name]),
|
|
||||||
qlc:e(Q)
|
|
||||||
end,
|
|
||||||
{atomic, Zones}= mnesia:transaction(F),
|
|
||||||
Zones.
|
|
||||||
|
|
||||||
% retrieve all rules by name
|
|
||||||
rules(Name) ->
|
|
||||||
F = fun()->
|
|
||||||
Q = qlc:q([R || R=#rule{name=N} <- mnesia:table(rule), N=:=Name]),
|
|
||||||
qlc:e(Q)
|
|
||||||
end,
|
|
||||||
{atomic, Rules}= mnesia:transaction(F),
|
|
||||||
Rules.
|
|
||||||
|
|
||||||
% retrieve all flatzones by tz name
|
|
||||||
flatzones(Name) ->
|
|
||||||
F = fun()->
|
|
||||||
Q = qlc:q([Z || Z=#flatzone{tzname=N} <- mnesia:table(flatzone), N=:=Name]),
|
|
||||||
qlc:e(Q)
|
|
||||||
end,
|
|
||||||
{atomic, FlatZones}= mnesia:transaction(F),
|
|
||||||
FlatZones.
|
|
||||||
|
|
||||||
% get all records from table
|
|
||||||
get_all(Tab) when is_atom(Tab) ->
|
|
||||||
F = fun() ->
|
|
||||||
Q = qlc:q([R || R<- mnesia:table(Tab)]),
|
|
||||||
qlc:e(Q)
|
|
||||||
end,
|
|
||||||
{atomic, Ret}= mnesia:transaction(F),
|
|
||||||
Ret.
|
|
||||||
|
|
||||||
%% get a flatzone for a specific date
|
|
||||||
%% Date :: {date(), #tztime{}}
|
|
||||||
%% returns #flatzone{}
|
|
||||||
%% or throws either error:
|
|
||||||
%% * {ambiguous_zone, [Z1,Z2,...]}
|
|
||||||
%% * {no_zone}
|
|
||||||
flatzone(Date, TzName) ->
|
|
||||||
%% @todo validate Date
|
|
||||||
F = fun()->
|
|
||||||
Q = qlc:q(
|
|
||||||
[Fz || Fz=#flatzone{tzname=N} <- mnesia:table(flatzone)
|
|
||||||
, N=:=TzName
|
|
||||||
, ezic_flatten:contains_date(Fz, Date)]),
|
|
||||||
qlc:e(Q)
|
|
||||||
end,
|
|
||||||
{atomic, FlatZones}= mnesia:transaction(F),
|
|
||||||
|
|
||||||
case length(FlatZones) of
|
|
||||||
1 ->
|
|
||||||
hd(FlatZones);
|
|
||||||
2 ->
|
|
||||||
erlang:error(ambiguous_zone, FlatZones);
|
|
||||||
0 ->
|
|
||||||
erlang:error(no_zone);
|
|
||||||
_ ->
|
|
||||||
erlang:error(should_not_happen, {FlatZones, Date, TzName})
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% ADMIN - initialization and administration methods
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
|
|
||||||
% initialize the db
|
|
||||||
init() ->
|
|
||||||
create_tabs(mnesia:create_schema([node()])),
|
|
||||||
mnesia:wait_for_tables([rule, zone, link, leap, flatzone], 3000).
|
|
||||||
|
|
||||||
|
|
||||||
% WARNING: deletes all db files
|
|
||||||
%wipe() ->
|
|
||||||
% mnesia:stop(),
|
|
||||||
% mnesia:delete_schema([node()]).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% WARNING: deletes all entries in table Tab
|
|
||||||
wipe(Tab) ->
|
|
||||||
mnesia:transaction(
|
|
||||||
fun()->
|
|
||||||
mnesia:delete(Tab, '_', write)
|
|
||||||
end).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
create_tabs(ok) ->
|
|
||||||
mnesia:start(),
|
|
||||||
|
|
||||||
?create(rule),
|
|
||||||
?create(zone),
|
|
||||||
?create(link),
|
|
||||||
?create(leap),
|
|
||||||
?create(flatzone),
|
|
||||||
|
|
||||||
{ok, Zones, Rules, _, _} = ezic_record:separate(ezic_loader:load()),
|
|
||||||
insert_all(Zones),
|
|
||||||
insert_all(Rules),
|
|
||||||
FlatZones = ezic_flatten:flatten(Zones, Rules),
|
|
||||||
error_logger:info_msg("~p~n", [FlatZones]),
|
|
||||||
insert_all(FlatZones),
|
|
||||||
|
|
||||||
ok;
|
|
||||||
create_tabs({error, {_, {already_exists,_}}}) ->
|
|
||||||
mnesia:start(),
|
|
||||||
ok;
|
|
||||||
create_tabs(E) ->
|
|
||||||
?debugVal(E).
|
|
||||||
|
|
||||||
|
|
||||||
insert_all(Records) ->
|
|
||||||
mnesia:transaction(
|
|
||||||
fun() ->
|
|
||||||
lists:foreach(
|
|
||||||
fun(R)-> mnesia:write(R) end,
|
|
||||||
Records)
|
|
||||||
end).
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
%% @todo move MAXYEAR to config file
|
%% @todo move MAXYEAR to config file
|
||||||
-define(MAXYEAR, 2500). % last year to process flatzones for.
|
-define(MAXYEAR, 2050). % last year to process flatzones for.
|
||||||
|
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
|||||||
46
src/ezic_generator.erl
Normal file
46
src/ezic_generator.erl
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
-module(ezic_generator).
|
||||||
|
-export([generate/0]).
|
||||||
|
-include("include/ezic.hrl").
|
||||||
|
|
||||||
|
generate() ->
|
||||||
|
{ok, Zones, Rules, _, _} = ezic_record:separate(ezic_loader:load()),
|
||||||
|
FlatZones = ezic_flatten:flatten(Zones, Rules),
|
||||||
|
|
||||||
|
filelib:ensure_dir("zones/"),
|
||||||
|
{ok, MapFile} = file:open("zones/ezic_zone_map.erl", [write]),
|
||||||
|
file:write(MapFile, "-module(ezic_zone_map).\n"),
|
||||||
|
file:write(MapFile, "-export([find/1]).\n"),
|
||||||
|
generate_files(FlatZones, MapFile, []),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
generate_files([], MapFile, Files) ->
|
||||||
|
lists:foreach(fun({_, File}) ->
|
||||||
|
file:write(File, "]."),
|
||||||
|
file:close(File)
|
||||||
|
end, Files),
|
||||||
|
|
||||||
|
file:write(MapFile, "find(Z) -> throw({zone_not_found, Z}).\n"),
|
||||||
|
file:close(MapFile);
|
||||||
|
|
||||||
|
generate_files([FlatZone = #flatzone{tzname = Name} | Rest], MapFile, Files) ->
|
||||||
|
{File, NewFiles} = case orddict:find(Name, Files) of
|
||||||
|
error ->
|
||||||
|
IO = create_file(Name, MapFile),
|
||||||
|
{IO, orddict:store(Name, IO, Files)};
|
||||||
|
{ok, IO} ->
|
||||||
|
file:write(IO, ",\n"),
|
||||||
|
{IO, Files}
|
||||||
|
end,
|
||||||
|
file:write(File, io_lib:format("~1000p", [FlatZone])),
|
||||||
|
generate_files(Rest, MapFile, NewFiles).
|
||||||
|
|
||||||
|
create_file(ZoneName, MapFile) ->
|
||||||
|
io:format("Creating file for zone ~p~n", [ZoneName]),
|
||||||
|
ModuleName = "ezic_zone_" ++ re:replace(string:to_lower(ZoneName), "/", "_", [global, {return, list}]),
|
||||||
|
FileName = "zones" ++ "/" ++ ModuleName ++ ".erl",
|
||||||
|
{ok, File} = file:open(FileName, [write]),
|
||||||
|
file:write(File, io_lib:format("-module(~p).\n", [list_to_atom(ModuleName)])),
|
||||||
|
file:write(File, "-export([flatzones/0]).\n"),
|
||||||
|
file:write(File, "flatzones() ->\n["),
|
||||||
|
file:write(MapFile, io_lib:format("find(~p) -> ~p;\n", [ZoneName, list_to_atom(ModuleName)])),
|
||||||
|
File.
|
||||||
@@ -43,7 +43,7 @@ parse_dir(Dir) ->
|
|||||||
|
|
||||||
% returns a list of tzdata records from file
|
% returns a list of tzdata records from file
|
||||||
parse_file(File) ->
|
parse_file(File) ->
|
||||||
%% error_logger:info_msg("Parsing File: ~p~n", [File]),
|
error_logger:info_msg("Parsing File: ~p~n", [File]),
|
||||||
{ok, FD} = file:open(File, [read]),
|
{ok, FD} = file:open(File, [read]),
|
||||||
parse_lines(file:read_line(FD), FD, []).
|
parse_lines(file:read_line(FD), FD, []).
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% File : ezic_sup.erl
|
|
||||||
%%% Author : aj <aj@fattie>
|
|
||||||
%%% Description :
|
|
||||||
%%%
|
|
||||||
%%% Created : 15 Nov 2010 by aj <aj@fattie>
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(ezic_sup).
|
|
||||||
|
|
||||||
-behaviour(supervisor).
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([start_link/1]).
|
|
||||||
|
|
||||||
%% Supervisor callbacks
|
|
||||||
-export([init/1]).
|
|
||||||
|
|
||||||
-define(SERVER, ?MODULE).
|
|
||||||
|
|
||||||
%%====================================================================
|
|
||||||
%% API functions
|
|
||||||
%%====================================================================
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
|
|
||||||
%% Description: Starts the supervisor
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
start_link(StartArgs) ->
|
|
||||||
supervisor:start_link(?MODULE, StartArgs).
|
|
||||||
|
|
||||||
%%====================================================================
|
|
||||||
%% Supervisor callbacks
|
|
||||||
%%====================================================================
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%% Func: init(Args) -> {ok, {SupFlags, [ChildSpec]}} |
|
|
||||||
%% ignore |
|
|
||||||
%% {error, Reason}
|
|
||||||
%% Description: Whenever a supervisor is started using
|
|
||||||
%% supervisor:start_link/[2,3], this function is called by the new process
|
|
||||||
%% to find out about restart strategy, maximum restart frequency and child
|
|
||||||
%% specifications.
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
init(StartArgs) ->
|
|
||||||
EzicDb = {ezic_db,{ezic_db, start_link, [StartArgs]},
|
|
||||||
permanent,2000,worker,[ezic_db]},
|
|
||||||
{ok,{{one_for_all,3,30}, [EzicDb]}}.
|
|
||||||
|
|
||||||
%%====================================================================
|
|
||||||
%% Internal functions
|
|
||||||
%%====================================================================
|
|
||||||
Reference in New Issue
Block a user