| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -3,10 +3,9 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				-behaviour(gen_server).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				-export([start_link/1, init/1, handle_cast/2, handle_call/3, terminate/2]).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				-export([get_tick/0, generate_bracket/1, print_bracket/1]).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				-export([get_tick/0]).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				-record(state, {database_file = none, database = none, tick_start = none}).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				-record(bracket, {depth = none, num = none, red = none, blue = none}).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				first_error([]) -> ok;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				first_error([ok | Rest]) -> first_error(Rest);
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -26,49 +25,6 @@ sql_begin(Database, Script) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				start_link(DatabaseFile) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  gen_server:start_link({local, ?MODULE}, ?MODULE, [DatabaseFile], []).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				higher_pow2(N) -> round(math:pow(2, ceil(math:log2(N)))).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				first_layer(BracketSize, _, N) when N > BracketSize/2 -> [];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				first_layer(BracketSize, Size, N) when BracketSize - N + 1 > Size ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  [N | first_layer(BracketSize, Size, N+1)];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				first_layer(BracketSize, Size, N) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  [{N, BracketSize - N + 1} | first_layer(BracketSize, Size, N+1)].
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				first_layer(Size) when Size > 1 ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  BracketSize = higher_pow2(Size),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  first_layer(BracketSize, Size, 1).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				merge_layer([Element], []) -> Element;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				merge_layer([], Merged) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Final = lists:reverse(Merged),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  merge_layer(Final);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				merge_layer([First | Rest], Merged) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Last = lists:last(Rest),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  List = lists:droplast(Rest),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  merge_layer(List, [{First, Last} | Merged]).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				merge_layer(List) -> merge_layer(List, []).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				label_bracket({Left, Right}, [N | Counters], Depth) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {LC, L} = label_bracket(Left, Counters, Depth+1),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {RC, R} = label_bracket(Right, LC, Depth+1),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {[N+1 | RC], #bracket{depth = Depth, num=N, red=L, blue=R}};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				label_bracket(Elem, Counters, _) -> {Counters, Elem}.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				label_bracket(Bracket, Depth) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {_, Labeled} = label_bracket(Bracket, lists:duplicate(Depth, 1), 1),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Labeled.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				generate_bracket(Size) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  label_bracket(merge_layer(first_layer(Size)), ceil(math:log2(Size))).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				print_bracket(Bracket) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  RF = fun(R,L) when R == element(1,Bracket) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          Flds = record_info(fields, bracket),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          true = (L == length(Flds)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          Flds
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  end,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  io:fwrite([io_lib_pretty:print(Bracket, RF),"\n"]).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				open_db(DatabaseFile) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {ok, DB} = sqlite3:open(event_db, [{file, DatabaseFile}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:sql_exec(DB, "PRAGMA foreign_keys = ON;"),
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -122,14 +78,22 @@ init_db(Database) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [team]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division], divisions, [division], "ON DELETE SET NULL"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, matches, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, matches, [{division, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                {type, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                {number, integer, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, type, number]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "type IN ('practice', 'qualification', 'elimination', 'final')"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "type IN ('practice', 'qualification')"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division], divisions, [division], "ON DELETE CASCADE"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, match_teams, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, match_states, [{division, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {type, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {tick, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {state, text, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, type, number, tick]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, type, number], matches, [division, type, number], "ON DELETE CASCADE"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, match_teams, [{division, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                    {type, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                    {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                    {side, text, [not_null]}, 
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -142,65 +106,84 @@ init_db(Database) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, type, number], matches, [division, type, number], "ON DELETE CASCADE"}},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[team], teams, [team], ""}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, elim_alliances, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {type, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, match_scores, [{division, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {type, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {history, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {uuid, integer, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, type, number, history]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[uuid], scores, [uuid], "ON DELETE CASCADE"}},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, type, number],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                            matches,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                            [division, type, number],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                            "ON DELETE CASCADE"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, brackets, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                 {number, integer, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, number]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division], divisions, [division], "ON DELETE CASCADE"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, bracket_states, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {side, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {anum, integer, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, type, number, side]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {tick, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {state, text, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, number, tick]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, number], brackets, [division, number], "ON DELETE CASCADE"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, elimination_alliances, [{division, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                              {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                              {side, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                              {anum, integer, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, number, side]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "side IN ('red', 'blue')"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "type == 'elimination'"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, type, number], matches, [division, type, number], "ON DELETE CASCADE"}},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, number], brackets, [division, number], "ON DELETE CASCADE"}},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, anum], alliances, [division, number], ""}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, finals_alliances, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                         {type, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                         {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                         {side, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                         {adiv, text, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, type, number, side]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, number, side]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "side IN ('red', 'blue')"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "division IS NULL"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "type == 'final'"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, type, number], matches, [division, type, number], "ON DELETE CASCADE"}},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, number], brackets, [division, number], "ON DELETE CASCADE"}},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[adiv], winners, [division], ""}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, match_scores, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {type, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {instance, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {history, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {autonomous, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {red_elevation_1, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {red_elevation_2, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {red_goal, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {red_zone, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {red_agoal, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {red_azone, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {red_1, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {red_2, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {blue_elevation_1, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {blue_elevation_2, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {blue_goal, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {blue_zone, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {blue_agoal, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {blue_azone, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {blue_1, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {blue_2, text}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, type, number, instance, history]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, bracket_scores, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {instance, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {history, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                       {uuid, integer, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, number, instance, history]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[uuid], scores, [uuid], "ON DELETE CASCADE"}},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, number],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                            brackets,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                            [division, number],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                            "ON DELETE CASCADE"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, scores, [{uuid, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {autonomous, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {red_elevation_1, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {red_elevation_2, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {red_goal, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {red_zone, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {red_agoal, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {red_azone, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {red_1, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {red_2, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {blue_elevation_1, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {blue_elevation_2, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {blue_goal, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {blue_zone, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {blue_agoal, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {blue_azone, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {blue_1, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               {blue_2, text}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [uuid]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "red_1 IS NULL OR red_1 IN ('dq', 'no show')"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "red_2 IS NULL OR red_2 IN ('dq', 'no show')"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "blue_1 IS NULL OR blue_1 IN ('dq', 'no show')"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "blue_2 IS NULL OR blue_2 IN ('dq', 'no show')"},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, type, number], matches, [division, type, number], "ON DELETE CASCADE"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, match_states, [{division, text},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {type, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {number, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {tick, integer, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                     {state, text, [not_null]}],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            [{primary_key, [division, type, number, tick]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {foreign_key, {[division, type, number], matches, [division, type, number], "ON DELETE CASCADE"}}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             {check, "blue_2 IS NULL OR blue_2 IN ('dq', 'no show')"}]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ok = sqlite3:create_table(Database, alliances, [{division, text, [not_null]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                  {number, integer, [not_null]}],
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -257,7 +240,7 @@ write_division_matches(Database, Division, Type, Matches) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    [Division, Round]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                      lists:append([io_lib:format(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                      "INSERT INTO matches(division, type, number) VALUES ('~s', '~s', ~p);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                       INSERT INTO match_teams(division, type, number, side, anum, team) VALUES ('~s', '~s', ~p, 'red',  1, '~s');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                      INSERT INTO match_teams(division, type, number, side, anum, team) VALUES ('~s', '~s', ~p, 'red',  1, '~s');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                       INSERT INTO match_teams(division, type, number, side, anum, team) VALUES ('~s', '~s', ~p, 'red',  2, '~s');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                       INSERT INTO match_teams(division, type, number, side, anum, team) VALUES ('~s', '~s', ~p, 'blue', 1, '~s');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                       INSERT INTO match_teams(division, type, number, side, anum, team) VALUES ('~s', '~s', ~p, 'blue', 2, '~s');",
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -403,42 +386,33 @@ handle_call({delete_division, Division}, _, State) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				handle_call({generate_practice, Division, Size}, _, State) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Teams = get_div_teams(State#state.database, Division),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Resp = case schedule:create(rand:uniform(10000000), Size, Teams) of
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    error -> error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Matches -> write_division_matches(State#state.database, Division, practice, Matches)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  end,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				           error -> error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				           Matches -> write_division_matches(State#state.database, Division, practice, Matches)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         end,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {reply, Resp, State};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				handle_call({generate_qualification, Division, Size}, _, State) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Teams = get_div_teams(State#state.database, Division),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Resp = case schedule:create(rand:uniform(10000000), Size, Teams) of
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    error -> error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Matches -> write_division_matches(State#state.database, Division, qualification, Matches)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  end,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				           error -> error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				           Matches -> write_division_matches(State#state.database, Division, qualification, Matches)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				         end,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {reply, Resp, State};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				handle_call({generate_elimination, Division, Size}, _, State) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  BracketSize = higher_pow2(Size),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Total = Size-1,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Bracket = schedule:generate_bracket(Size),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  SQL = lists:append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				             [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              io_lib:format("DELETE FROM alliances WHERE division = '~s'; ", [Division]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              io_lib:format("DELETE FROM matches WHERE division = '~s' AND type = 'elimination'; ", [Division]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              lists:append([io_lib:format("INSERT INTO alliances(division, number) VALUES('~s', ~p); ",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                          [Division, N])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            || N <- lists:seq(1, Total)]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              lists:append([io_lib:format("INSERT INTO matches(division, type, number)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           VALUES('~s', 'elimination', ~p);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           INSERT INTO elim_alliances(division, type, number, side, anum)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           VALUES('~s', 'elimination', ~p, 'red', ~p);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           INSERT INTO elim_alliances(division, type, number, side, anum)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           VALUES('~s', 'elimination', ~p, 'blue', ~p);",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           [Division, N, Division, N, BracketSize/2+N+1, Division, N, BracketSize/2-N])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           || N <- lists:seq(1, Size - BracketSize/2)]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              lists:append([io_lib:format("INSERT INTO elim_alliances(division, type, number, side, anum)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           VALUES('~s', 'elimination', ~p, 'red', ~p);",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                          [Division, N, BracketSize/2-N+1])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            || N <- lists:seq(Size - BracketSize/2+1, BracketSize/2)])]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				           io_lib:format("DELETE FROM alliances WHERE division = '~s'; ", [Division]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				           io_lib:format("DELETE FROM brackets WHERE division = '~s'; ", [Division]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				           lists:append([io_lib:format("INSERT INTO alliances(division, number) VALUES('~s', ~p); ",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                       [Division, N])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                         || N <- lists:seq(1, Size)]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				           lists:append([io_lib:format("INSERT INTO brackets(division, number)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                       VALUES('~s', ~p);",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           [Division, N])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                           || N <- lists:seq(1, Size-1)])]),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {reply, sql_begin(State#state.database, SQL), State};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				handle_call(generate_finals, _, State) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  [{columns, _}, {rows, [{Size}]}] = sqlite3:sql_exec(State#state.database, "SELECT COUNT(*) FROM divisions;"),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {reply, noimpl, State};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				handle_call(_, _, State) ->
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {reply, noimpl, State}.
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |