Changed database to be passed a DB to open on launch

main
noah metz 2024-01-27 13:17:04 -07:00
parent 6682f37635
commit 61a1f8d8e0
3 changed files with 47 additions and 26 deletions

@ -2,19 +2,27 @@
-behaviour(gen_server). -behaviour(gen_server).
-export([start_link/0, init/1, handle_cast/2, handle_call/3, add_teams/1]). -export([start_link/1, init/1, handle_cast/2, handle_call/3, add_teams/1]).
-export([set_test_config/0, new/1, load/1]). -export([set_test_config/0, new/1, close/0]).
-record(division, {teams = [], practice = 0, qualification = 0}). -record(division, {teams = [], practice = 0, qualification = 0}).
-record(config, {divisions = []}). -record(config, {divisions = []}).
-record(state, {database_file = none, database = none, teams = [], config = none}). -record(state, {database_file = none, database = none, teams = [], config = none}).
start_link() -> start_link(DatabaseFile) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). gen_server:start_link({local, ?MODULE}, ?MODULE, [DatabaseFile], []).
init([]) -> init([DatabaseFile]) ->
{ok, #state{}}. Exists = filelib:is_regular(DatabaseFile),
if Exists =:= true ->
{ok, DB} = sqlite3:open(schedule_db, [{file, DatabaseFile}]),
ok = sqlite3:sql_exec(DB, "PRAGMA foreign_keys = ON;"),
{ok, #state{database_file = DatabaseFile, database = DB}};
true ->
io:format("Failed to load database ~s~n", [DatabaseFile]),
{ok, #state{database_file = none, database = none}}
end.
init_db(Database) -> init_db(Database) ->
ok = sqlite3:create_table(Database, genids, [{genid, text, [not_null]}, ok = sqlite3:create_table(Database, genids, [{genid, text, [not_null]},
@ -66,16 +74,16 @@ init_db(Database) ->
delete_teams(Database, Teams) -> delete_teams(Database, Teams) ->
SQL = lists:append(["BEGIN; ", SQL = lists:append(["BEGIN; ",
lists:append([io_lib:format("DELETE FROM teams WHERE name = ~p; ", lists:append([io_lib:format("DELETE FROM teams WHERE name = ~p; ",
[Team]) || Team <- Teams]), [Team]) || Team <- Teams]),
"COMMIT;"]), "COMMIT;"]),
first_error(sqlite3:sql_exec_script(Database, SQL)). first_error(sqlite3:sql_exec_script(Database, SQL)).
add_teams(Database, Teams) -> add_teams(Database, Teams) ->
SQL = lists:append(["BEGIN; ", SQL = lists:append(["BEGIN; ",
lists:append([io_lib:format("INSERT INTO teams(name) VALUES('~s') ON CONFLICT(name) DO NOTHING; ", lists:append([io_lib:format("INSERT INTO teams(name) VALUES('~s') ON CONFLICT(name) DO NOTHING; ",
[Team]) || Team <- Teams]), [Team]) || Team <- Teams]),
"COMMIT;"]), "COMMIT;"]),
first_error(sqlite3:sql_exec_script(Database, SQL)). first_error(sqlite3:sql_exec_script(Database, SQL)).
first_error([]) -> ok; first_error([]) -> ok;
@ -93,7 +101,7 @@ write_matches(Database, Type, Teams, Seed, Size, Round, Matches) ->
[GenID, atom_to_list(Type), Size, Seed]), [GenID, atom_to_list(Type), Size, Seed]),
lists:append([io_lib:format( lists:append([io_lib:format(
"INSERT INTO matches(genid, round, number, blue_1, blue_2, red_1, red_2) "INSERT INTO matches(genid, round, number, blue_1, blue_2, red_1, red_2)
VALUES ('~s', '~s', ~p, '~s', '~s', '~s', '~s'); ", VALUES ('~s', '~s', ~p, '~s', '~s', '~s', '~s'); ",
[GenID, atom_to_list(Round), N, B1, B2, R1, R2]) [GenID, atom_to_list(Round), N, B1, B2, R1, R2])
|| {N, [B1, B2, R1, R2]} <- lists:enumerate(Matches)]), || {N, [B1, B2, R1, R2]} <- lists:enumerate(Matches)]),
"COMMIT;"]), "COMMIT;"]),
@ -111,11 +119,17 @@ add_teams(Teams) ->
new(DatabaseFile) -> new(DatabaseFile) ->
gen_server:call(?MODULE, {new_db, DatabaseFile}). gen_server:call(?MODULE, {new_db, DatabaseFile}).
load(DatabaseFile) -> close() ->
gen_server:call(?MODULE, {load_db, DatabaseFile}). gen_server:call(?MODULE, close_db).
handle_call({set_config, Config}, _, State) when is_record(Config, config) -> handle_call({set_config, Config}, _, State) when is_record(Config, config) ->
{reply, ok, State#state{config = Config}}; {reply, ok, State#state{config = Config}};
handle_call(close_db, _, State) ->
if State#state.database =:= none -> {reply, ok, State};
true ->
ok = sqlite3:close(State#state.database),
{reply, ok, State#state{database = none, database_file = none}}
end;
handle_call({new_db, DatabaseFile}, _, State) -> handle_call({new_db, DatabaseFile}, _, State) ->
ok = if State#state.database =:= none -> ok; ok = if State#state.database =:= none -> ok;
true -> sqlite3:close(State#state.database) true -> sqlite3:close(State#state.database)
@ -150,11 +164,11 @@ handle_call({new_schedule, Division, Round, Seed}, _, State) ->
DivInfo = lists:nth(Division, State#state.config#config.divisions), DivInfo = lists:nth(Division, State#state.config#config.divisions),
Teams = DivInfo#division.teams, Teams = DivInfo#division.teams,
Size = case Round of Size = case Round of
practice when DivInfo#division.practice =/= 0 -> practice when DivInfo#division.practice =/= 0 ->
DivInfo#division.practice; DivInfo#division.practice;
qualification when DivInfo#division.qualification =/= 0-> qualification when DivInfo#division.qualification =/= 0->
DivInfo#division.qualification DivInfo#division.qualification
end, end,
Matches = schedule:create(Seed, Size, Teams), Matches = schedule:create(Seed, Size, Teams),
{ok, GenID} = write_matches(State#state.database, division, Teams, Seed, Size, Round, Matches), {ok, GenID} = write_matches(State#state.database, division, Teams, Seed, Size, Round, Matches),
{reply, GenID, State}; {reply, GenID, State};

@ -10,7 +10,14 @@
-export([start/2, stop/1]). -export([start/2, stop/1]).
start(_StartType, _StartArgs) -> start(_StartType, _StartArgs) ->
erlk_sup:start_link(). DBPath = case os:getenv("ERLK_DB") of
false ->
ConfigRoot = os:getenv("HOME", "/etc"),
io_lib:format("~s/erlk.db", [ConfigRoot]);
Value -> Value
end,
erlk_sup:start_link(DBPath).
stop(_State) -> stop(_State) ->
ok. ok.

@ -7,12 +7,12 @@
-behaviour(supervisor). -behaviour(supervisor).
-export([start_link/0]). -export([start_link/1]).
-export([init/1]). -export([init/1]).
start_link() -> start_link(DBPath) ->
supervisor:start_link(?MODULE, []). supervisor:start_link(?MODULE, [DBPath]).
%% sup_flags() = #{strategy => strategy(), % optional %% sup_flags() = #{strategy => strategy(), % optional
%% intensity => non_neg_integer(), % optional %% intensity => non_neg_integer(), % optional
@ -24,14 +24,14 @@ start_link() ->
%% type => worker(), % optional %% type => worker(), % optional
%% modules => modules()} % optional %% modules => modules()} % optional
init(_) -> init(DBPath) ->
SupFlags = #{strategy => rest_for_one}, SupFlags = #{strategy => rest_for_one},
ChildSpecs = [ ChildSpecs = [
#{id => schedule, #{id => schedule,
start => {schedule, start_link, []} start => {schedule, start_link, []}
}, },
#{id => database, #{id => database,
start => {database, start_link, []} start => {database, start_link, [DBPath]}
}, },
#{id => mqtt, #{id => mqtt,
start => {mqtt, start_link, []} start => {mqtt, start_link, []}