mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-07-15 07:43:44 -05:00
156 lines
5.8 KiB
PL/PgSQL
156 lines
5.8 KiB
PL/PgSQL
-- todo dev only
|
||
drop schema if exists sendou_ink cascade;
|
||
drop schema if exists sendou_ink_private cascade;
|
||
|
||
create extension if not exists "uuid-ossp";
|
||
|
||
create schema sendou_ink;
|
||
create schema sendou_ink_private;
|
||
|
||
create function sendou_ink_private.set_updated_at() returns trigger as $$
|
||
begin
|
||
new.updated_at := current_timestamp;
|
||
return new;
|
||
end;
|
||
$$ language plpgsql;
|
||
|
||
-- ACCOUNT
|
||
|
||
-- no checks because this data is not provided by user but with the log in event
|
||
create table sendou_ink.account (
|
||
id serial primary key,
|
||
discord_id text not null,
|
||
discord_username text not null,
|
||
discord_discriminator text not null,
|
||
discord_avatar text,
|
||
twitch text,
|
||
twitter text,
|
||
youtube_id text,
|
||
youtube_name text,
|
||
created_at timestamp default now(),
|
||
updated_at timestamp default now()
|
||
);
|
||
|
||
create function sendou_ink.account_discord_full_username(account sendou_ink.account) returns text as $$
|
||
select account.discord_username || '#' || account.discord_discriminator
|
||
$$ language sql stable;
|
||
|
||
create trigger account_updated_at before update
|
||
on sendou_ink.account
|
||
for each row
|
||
execute procedure sendou_ink_private.set_updated_at();
|
||
|
||
-- ORGANIZATION
|
||
|
||
create table sendou_ink.organization (
|
||
identifier text primary key
|
||
check (identifier ~ '^[a-z0-9-]{2,50}$'),
|
||
name text not null
|
||
check (char_length(name) < 51),
|
||
discord_invite_code text not null
|
||
check (char_length(discord_invite_code) < 51),
|
||
twitter text
|
||
check (twitter ~ '^[a-zA-Z0-9_]{4,15}$'),
|
||
created_at timestamp default now(),
|
||
updated_at timestamp default now(),
|
||
owner_id integer not null references sendou_ink.account(id)
|
||
);
|
||
|
||
create function sendou_ink.organization_twitter_url(organization sendou_ink.organization) returns text as $$
|
||
select 'https://twitter.com/' || organization.twitter
|
||
$$ language sql stable;
|
||
|
||
create function sendou_ink.organization_discord_invite_url(organization sendou_ink.organization) returns text as $$
|
||
select 'https://discord.com/invite/' || organization.discord_invite_code
|
||
$$ language sql stable;
|
||
|
||
create index organization_owner_id on sendou_ink.organization (owner_id);
|
||
|
||
create trigger organization_updated_at before update
|
||
on sendou_ink.organization
|
||
for each row
|
||
execute procedure sendou_ink_private.set_updated_at();
|
||
|
||
-- TOURNAMENT
|
||
|
||
create table sendou_ink.tournament (
|
||
identifier text primary key
|
||
check (identifier ~ '^[a-z0-9-]{2,50}$'),
|
||
name text not null
|
||
check (char_length(name) < 51),
|
||
description text
|
||
check (char_length(description) < 5000),
|
||
start_time timestamp not null
|
||
check (start_time > now()),
|
||
check_in_time timestamp,
|
||
-- TODO check
|
||
banner_background text not null,
|
||
banner_text_hsl_args text not null
|
||
check (banner_text_hsl_args ~ '^[0-9]{1,3} [0-9]{1,3}% [0-9]{1,3}%$'),
|
||
created_at timestamp default now(),
|
||
updated_at timestamp default now(),
|
||
organization_identifier text not null references sendou_ink.organization(identifier),
|
||
CHECK (check_in_time < start_time)
|
||
);
|
||
|
||
-- create function sendou_ink.tournament_text_color(tournament sendou_ink.tournament) returns text as $$
|
||
-- select 'hsl(' || tournament.banner_text_hsl_args || ')'
|
||
-- $$ language sql stable;
|
||
|
||
create index tournament_organization_identifier on sendou_ink.tournament(organization_identifier);
|
||
|
||
create trigger tournament_updated_at before update
|
||
on sendou_ink.tournament
|
||
for each row
|
||
execute procedure sendou_ink_private.set_updated_at();
|
||
|
||
create table sendou_ink.mode_enum (
|
||
name text primary key
|
||
);
|
||
comment on table sendou_ink.mode_enum is E'@enum';
|
||
insert into sendou_ink.mode_enum (name) values
|
||
('TW'),
|
||
('SZ'),
|
||
('TC'),
|
||
('RM'),
|
||
('CB');
|
||
|
||
create table sendou_ink.map_mode (
|
||
id serial primary key,
|
||
stage text not null,
|
||
game_mode text not null references sendou_ink.mode_enum(name),
|
||
unique (stage, game_mode)
|
||
);
|
||
|
||
create table sendou_ink.map_pool (
|
||
tournament_identifier text not null references sendou_ink.tournament(identifier),
|
||
map_mode_id integer not null references sendou_ink.map_mode(id),
|
||
unique (tournament_identifier, map_mode_id)
|
||
);
|
||
|
||
create index map_pool_tournament_identifier on sendou_ink.map_pool(tournament_identifier);
|
||
create index map_pool_map_mode_id on sendou_ink.map_pool(map_mode_id);
|
||
|
||
create table sendou_ink.tournament_team (
|
||
id serial primary key,
|
||
name text not null
|
||
check (char_length(name) < 51),
|
||
checked_in boolean not null default false,
|
||
tournament_identifier text not null references sendou_ink.tournament(identifier),
|
||
-- todo restrict access
|
||
invite_code uuid not null unique default uuid_generate_v1mc(),
|
||
unique (name, tournament_identifier)
|
||
);
|
||
|
||
create index tournament_team_tournament_identifier on sendou_ink.tournament_team(tournament_identifier);
|
||
|
||
create table sendou_ink.tournament_team_roster (
|
||
member_id integer not null references sendou_ink.account(id),
|
||
tournament_team_id integer not null references sendou_ink.tournament_team(id),
|
||
captain boolean not null default false,
|
||
unique (member_id, tournament_team_id)
|
||
);
|
||
|
||
create index tournament_team_roster_member_id on sendou_ink.tournament_team_roster(member_id);
|
||
create index tournament_team_roster_tournament_team_id on sendou_ink.tournament_team_roster(tournament_team_id);
|