From 4e0e86e362dc32691c36ee772e23d3ed81b68191 Mon Sep 17 00:00:00 2001 From: "Kalle (Sendou)" <38327916+Sendouc@users.noreply.github.com> Date: Mon, 8 Nov 2021 18:24:38 +0200 Subject: [PATCH] Seed tournaments with faker --- postgraphile/migrations/0001_initial.sql | 41 +++++++---- postgraphile/package-lock.json | 26 +++++++ postgraphile/package.json | 2 + postgraphile/scripts/seed.js | 86 ++++++++++++++++++++---- 4 files changed, 129 insertions(+), 26 deletions(-) diff --git a/postgraphile/migrations/0001_initial.sql b/postgraphile/migrations/0001_initial.sql index d375d2e01..1b5c9d76c 100644 --- a/postgraphile/migrations/0001_initial.sql +++ b/postgraphile/migrations/0001_initial.sql @@ -1,7 +1,9 @@ --- dev only +-- 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; @@ -17,6 +19,7 @@ $$ language plpgsql; -- 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, @@ -28,23 +31,10 @@ create table sendou_ink.account ( updated_at timestamp default now() ); -comment on table sendou_ink.account is 'User containing all information automatically fetched on log in.'; -comment on column sendou_ink.account.id is 'The primary unique identifier for the user.'; -comment on column sendou_ink.account.discord_username is 'User’s username on Discord.'; -comment on column sendou_ink.account.discord_discriminator is 'User’s discriminator on Discord. (e.g. "0043")'; -comment on column sendou_ink.account.discord_avatar is 'User’s Discord avatar hash.'; -comment on column sendou_ink.account.twitch is 'User’s username on Twitch.'; -comment on column sendou_ink.account.twitter is 'User’s username on Twitter.'; -comment on column sendou_ink.account.youtube_id is 'User’s id on YouTube.'; -comment on column sendou_ink.account.youtube_name is 'User’s name on YouTube (YouTube partners only).'; -comment on column sendou_ink.account.created_at is 'The time this user was created.'; - 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; -comment on function sendou_ink.account_discord_full_username(sendou_ink.account) is 'A user’s full username on Discord consisting of username and discriminator joined together with #.'; - create trigger account_updated_at before update on sendou_ink.account for each row @@ -140,3 +130,26 @@ create table sendou_ink.map_pool ( 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); diff --git a/postgraphile/package-lock.json b/postgraphile/package-lock.json index 5edaaaf7a..2f3f67f2d 100644 --- a/postgraphile/package-lock.json +++ b/postgraphile/package-lock.json @@ -13,7 +13,9 @@ "postgres-migrations": "^5.3.0" }, "devDependencies": { + "@types/faker": "^5.5.9", "dotenv": "^10.0.0", + "faker": "^5.5.3", "jest": "^27.3.1", "pg": "^8.7.1", "ts-node-dev": "^1.1.8" @@ -1269,6 +1271,12 @@ "@babel/types": "^7.3.0" } }, + "node_modules/@types/faker": { + "version": "5.5.9", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.5.9.tgz", + "integrity": "sha512-uCx6mP3UY5SIO14XlspxsGjgaemrxpssJI0Ol+GfhxtcKpv9pgRZYsS4eeKeHVLje6Qtc8lGszuBI461+gVZBA==", + "dev": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -2449,6 +2457,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==", + "dev": true + }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", @@ -7927,6 +7941,12 @@ "@babel/types": "^7.3.0" } }, + "@types/faker": { + "version": "5.5.9", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.5.9.tgz", + "integrity": "sha512-uCx6mP3UY5SIO14XlspxsGjgaemrxpssJI0Ol+GfhxtcKpv9pgRZYsS4eeKeHVLje6Qtc8lGszuBI461+gVZBA==", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -8874,6 +8894,12 @@ } } }, + "faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==", + "dev": true + }, "fast-decode-uri-component": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", diff --git a/postgraphile/package.json b/postgraphile/package.json index 65761b72b..37bd75242 100644 --- a/postgraphile/package.json +++ b/postgraphile/package.json @@ -7,7 +7,9 @@ "postgres-migrations": "^5.3.0" }, "devDependencies": { + "@types/faker": "^5.5.9", "dotenv": "^10.0.0", + "faker": "^5.5.3", "jest": "^27.3.1", "pg": "^8.7.1", "ts-node-dev": "^1.1.8" diff --git a/postgraphile/scripts/seed.js b/postgraphile/scripts/seed.js index 17ce87638..b6c7a4f4c 100644 --- a/postgraphile/scripts/seed.js +++ b/postgraphile/scripts/seed.js @@ -1,5 +1,6 @@ require("dotenv").config(); const { Client } = require("pg"); +const faker = require("faker"); const stages = [ "The Reef", @@ -35,8 +36,8 @@ async function main() { try { await client.connect(); await client.query(` - insert into sendou_ink.account (discord_username, discord_discriminator, discord_avatar, twitch, twitter, youtube_id, youtube_name) - values ('Sendou', '0043', 'fcfd65a3bea598905abb9ca25296816b', 'Sendou', 'Sendouc', 'UCWbJLXByvsfQvTcR4HLPs5Q', 'Sendou'); + insert into sendou_ink.account (discord_username, discord_discriminator, discord_avatar, twitch, twitter, youtube_id, youtube_name, discord_id) + values ('Sendou', '0043', 'fcfd65a3bea598905abb9ca25296816b', 'Sendou', 'Sendouc', 'UCWbJLXByvsfQvTcR4HLPs5Q', 'Sendou', '79237403620945920'); `); await client.query(` insert into sendou_ink.organization (identifier, name, discord_invite_code, twitter, owner_id) @@ -56,21 +57,82 @@ async function main() { } } - const ids = Array.from( - new Set(new Array(24).fill(null).map(() => getRandomInt(115))) - ); - - for (const id of ids) { - await client.query(` - insert into sendou_ink.map_pool (tournament_identifier, map_mode_id) - values ('in-the-zone-x', '${id}'); - `); - } + await mapPool(client); + await fakeUsers(client); + await fakeTournamentTeams(client); } finally { client.end(); } } +async function mapPool(client) { + const ids = Array.from( + new Set(new Array(24).fill(null).map(() => getRandomInt(115))) + ); + + for (const id of ids) { + await client.query(` + insert into sendou_ink.map_pool (tournament_identifier, map_mode_id) + values ('in-the-zone-x', '${id}'); + `); + } +} + +async function fakeUsers(client) { + for (let index = 0; index < 200; index++) { + const name = faker.name.firstName(); + const discordDiscriminator = Array(4) + .fill(null) + .map(() => faker.datatype.number(9)) + .join(""); + const discordId = Array(17) + .fill(null) + .map(() => faker.datatype.number(9)) + .join(""); + + await client.query(` + insert into sendou_ink.account (discord_username, discord_discriminator, discord_id) + values ('${name}', '${discordDiscriminator}', '${discordId}'); + `); + } +} + +async function fakeTournamentTeams(client) { + const randomIds = faker.helpers.shuffle( + Array(201) + .fill(null) + .map((_, i) => i) + ); + + for (let index = 0; index < 24; index++) { + const name = faker.address.cityName(); + const captainId = randomIds.pop(); + + const { + rows: [tournamentTeam], + } = await client.query(` + insert into sendou_ink.tournament_team (name, tournament_identifier) + values ('${name}', 'in-the-zone-x') + returning *; + `); + + await client.query(` + insert into sendou_ink.tournament_team_roster (member_id, tournament_team_id, captain) + values ('${captainId}', '${tournamentTeam.id}', true) + returning *; + `); + + for (let index = 0; index < faker.datatype.number(6); index++) { + const memberId = randomIds.pop(); + await client.query(` + insert into sendou_ink.tournament_team_roster (member_id, tournament_team_id) + values ('${memberId}', '${tournamentTeam.id}') + returning *; + `); + } + } +} + function getRandomInt(maxInclusive) { let result = -1;