Adds Adding of Games to the system.

This commit is contained in:
2025-06-27 22:08:23 +02:00
parent 3f51d52edf
commit 28f7306d57
40 changed files with 792 additions and 130 deletions

View File

@@ -1,2 +1,2 @@
[print_schema]
file = "src/schema/schema.rs"
file = "src/schema.rs"

View File

@@ -1,4 +1,4 @@
-- This file should undo anything in `up.sql`
drop table gamenight;
drop table known_games;
drop table game;

View File

@@ -6,7 +6,7 @@ CREATE TABLE gamenight (
datetime VARCHAR NOT NULL
);
CREATE TABLE known_games (
CREATE TABLE game (
id UUID NOT NULL PRIMARY KEY,
name VARCHAR UNIQUE NOT NULL
);

View File

@@ -1,6 +1,6 @@
-- This file should undo anything in `up.sql`
drop table pwd;
drop table users;
drop table client;
drop type Role;

View File

@@ -1,6 +1,6 @@
CREATE TYPE Role AS ENUM ('user', 'admin');
CREATE TABLE users (
CREATE TABLE client (
id UUID NOT NULL PRIMARY KEY,
username VARCHAR UNIQUE NOT NULL,
email VARCHAR UNIQUE NOT NULL,
@@ -10,7 +10,7 @@ CREATE TABLE users (
CREATE TABLE pwd (
user_id UUID NOT NULL PRIMARY KEY,
password VARCHAR NOT NULL,
CONSTRAINT FK_UserId FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
CONSTRAINT FK_UserId FOREIGN KEY (user_id) REFERENCES client(id) ON DELETE CASCADE
);
--Initialize default admin user, with password "gamenight!"
@@ -19,7 +19,7 @@ DO $$
DECLARE
admin_uuid uuid = uuid_generate_v4();
BEGIN
INSERT INTO users (id, username, email, role)
INSERT INTO client (id, username, email, role)
values(admin_uuid, 'admin', '', 'admin');
insert INTO pwd (user_id, password)

View File

@@ -5,7 +5,7 @@ CREATE TABLE gamenight (
name VARCHAR NOT NULL,
datetime VARCHAR NOT NULL,
owner_id UUID NOT NULL,
CONSTRAINT FK_OwnerId FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE
CONSTRAINT FK_OwnerId FOREIGN KEY (owner_id) REFERENCES client(id) ON DELETE CASCADE
);
SET session_replication_role = 'replica';

View File

@@ -4,6 +4,6 @@ create table gamenight_gamelist (
gamenight_id UUID NOT NULL,
game_id UUID NOT NULL,
CONSTRAINT FK_gamenight_id FOREIGN KEY (gamenight_id) REFERENCES gamenight(id) ON DELETE CASCADE,
CONSTRAINT FK_game_id FOREIGN KEY (game_id) REFERENCES known_games(id) ON DELETE CASCADE,
CONSTRAINT FK_game_id FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE,
PRIMARY KEY(gamenight_id, game_id)
);

View File

@@ -4,6 +4,6 @@ create table gamenight_participant (
gamenight_id UUID NOT NULL,
user_id UUID NOT NULL,
CONSTRAINT FK_gamenight_id FOREIGN KEY (gamenight_id) REFERENCES gamenight(id) ON DELETE CASCADE,
CONSTRAINT FK_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT FK_user_id FOREIGN KEY (user_id) REFERENCES client(id) ON DELETE CASCADE,
PRIMARY KEY(gamenight_id, user_id)
)

View File

@@ -0,0 +1,3 @@
-- This file should undo anything in `up.sql`
drop table owned_game;

View File

@@ -0,0 +1,9 @@
-- Your SQL goes here
create table owned_game (
user_id UUID NOT NULL,
game_id UUID NOT NULL,
CONSTRAINT FK_gamenight_id FOREIGN KEY (user_id) REFERENCES client(id) ON DELETE CASCADE,
CONSTRAINT FK_user_id FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE,
PRIMARY KEY(user_id, game_id)
)

View File

@@ -0,0 +1,21 @@
use diesel::{dsl::insert_into, Insertable, PgConnection, Queryable, RunQueryDsl};
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use crate::schema::game;
use super::error::DatabaseError;
#[derive(Serialize, Deserialize, Debug, Insertable, Queryable)]
#[diesel(table_name = game)]
pub struct Game {
pub id: Uuid,
pub name: String,
}
pub fn games(conn: &mut PgConnection) -> Result<Vec::<Game>, DatabaseError> {
Ok(game::table.load::<Game>(conn)?)
}
pub fn insert_game(conn: &mut PgConnection, game: Game) -> Result<usize, DatabaseError> {
Ok(insert_into(game::table).values(&game).execute(conn)?)
}

View File

@@ -3,6 +3,7 @@ pub mod error;
pub mod schema;
pub mod gamenight;
pub mod gamenight_participants;
pub mod game;
use diesel::r2d2::ConnectionManager;
use diesel::r2d2::ManageConnection;
@@ -17,6 +18,7 @@ pub use user::login;
pub use user::register;
pub use gamenight::gamenights;
pub use gamenight_participants::get_participants;
pub use game::games;
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
pub type DbConnection = PgConnection;

View File

@@ -6,6 +6,25 @@ pub mod sql_types {
pub struct Role;
}
diesel::table! {
use diesel::sql_types::*;
use super::sql_types::Role;
client (id) {
id -> Uuid,
username -> Varchar,
email -> Varchar,
role -> Role,
}
}
diesel::table! {
game (id) {
id -> Uuid,
name -> Varchar,
}
}
diesel::table! {
gamenight (id) {
id -> Uuid,
@@ -30,9 +49,9 @@ diesel::table! {
}
diesel::table! {
known_games (id) {
id -> Uuid,
name -> Varchar,
owned_game (user_id, game_id) {
user_id -> Uuid,
game_id -> Uuid,
}
}
@@ -53,31 +72,22 @@ diesel::table! {
}
}
diesel::table! {
use diesel::sql_types::*;
use super::sql_types::Role;
users (id) {
id -> Uuid,
username -> Varchar,
email -> Varchar,
role -> Role,
}
}
diesel::joinable!(gamenight -> users (owner_id));
diesel::joinable!(gamenight -> client (owner_id));
diesel::joinable!(gamenight_gamelist -> game (game_id));
diesel::joinable!(gamenight_gamelist -> gamenight (gamenight_id));
diesel::joinable!(gamenight_gamelist -> known_games (game_id));
diesel::joinable!(gamenight_participant -> client (user_id));
diesel::joinable!(gamenight_participant -> gamenight (gamenight_id));
diesel::joinable!(gamenight_participant -> users (user_id));
diesel::joinable!(pwd -> users (user_id));
diesel::joinable!(owned_game -> client (user_id));
diesel::joinable!(owned_game -> game (game_id));
diesel::joinable!(pwd -> client (user_id));
diesel::allow_tables_to_appear_in_same_query!(
client,
game,
gamenight,
gamenight_gamelist,
gamenight_participant,
known_games,
owned_game,
pwd,
registration_tokens,
users,
);

View File

@@ -1,83 +0,0 @@
// @generated automatically by Diesel CLI.
pub mod sql_types {
#[derive(diesel::sql_types::SqlType)]
#[diesel(postgres_type(name = "role"))]
pub struct Role;
}
diesel::table! {
gamenight (id) {
id -> Uuid,
name -> Varchar,
datetime -> Timestamptz,
owner_id -> Uuid,
}
}
diesel::table! {
gamenight_gamelist (gamenight_id, game_id) {
gamenight_id -> Uuid,
game_id -> Uuid,
}
}
diesel::table! {
gamenight_participant (gamenight_id, user_id) {
gamenight_id -> Uuid,
user_id -> Uuid,
}
}
diesel::table! {
known_games (id) {
id -> Uuid,
name -> Varchar,
}
}
diesel::table! {
pwd (user_id) {
user_id -> Uuid,
password -> Varchar,
}
}
diesel::table! {
registration_tokens (id) {
id -> Uuid,
#[max_length = 32]
token -> Bpchar,
single_use -> Bool,
expires -> Nullable<Timestamptz>,
}
}
diesel::table! {
use diesel::sql_types::*;
use super::sql_types::Role;
users (id) {
id -> Uuid,
username -> Varchar,
email -> Varchar,
role -> Role,
}
}
diesel::joinable!(gamenight -> users (owner_id));
diesel::joinable!(gamenight_gamelist -> gamenight (gamenight_id));
diesel::joinable!(gamenight_gamelist -> known_games (game_id));
diesel::joinable!(gamenight_participant -> gamenight (gamenight_id));
diesel::joinable!(gamenight_participant -> users (user_id));
diesel::joinable!(pwd -> users (user_id));
diesel::allow_tables_to_appear_in_same_query!(
gamenight,
gamenight_gamelist,
gamenight_participant,
known_games,
pwd,
registration_tokens,
users,
);

View File

@@ -13,7 +13,7 @@ use argon2::password_hash::rand_core::OsRng;
use argon2::password_hash::rand_core::RngCore;
use crate::DbConnection;
use super::schema::{pwd, users};
use super::schema::{pwd, client};
pub use super::error::DatabaseError;
@@ -26,7 +26,7 @@ struct Pwd {
}
#[derive(Serialize, Deserialize, Debug, Insertable, Queryable)]
#[diesel(table_name = users)]
#[diesel(table_name = client)]
pub struct User {
pub id: Uuid,
pub username: String,
@@ -65,10 +65,10 @@ pub struct Register {
}
pub fn login(conn: &mut DbConnection, user: LoginUser) -> Result<Option<User>, DatabaseError> {
let id: Uuid = users::table
.filter(users::username.eq(&user.username))
.or_filter(users::email.eq(&user.username))
.select(users::id)
let id: Uuid = client::table
.filter(client::username.eq(&user.username))
.or_filter(client::email.eq(&user.username))
.select(client::id)
.first(conn)?;
let pwd: String = pwd::table
@@ -82,14 +82,14 @@ pub fn login(conn: &mut DbConnection, user: LoginUser) -> Result<Option<User>, D
.verify_password(user.password.as_bytes(), &parsed_hash)
.is_ok()
{
Ok(Some(users::table.find(id).first(conn)?))
Ok(Some(client::table.find(id).first(conn)?))
} else {
Ok(None)
}
}
pub fn get_user(conn: &mut DbConnection, id: Uuid) -> Result<User, DatabaseError> {
Ok(users::table.find(id).first(conn)?)
Ok(client::table.find(id).first(conn)?)
}
pub fn register(conn: &mut DbConnection, register: Register) -> Result<(), DatabaseError> {
@@ -105,7 +105,7 @@ pub fn register(conn: &mut DbConnection, register: Register) -> Result<(), Datab
conn.transaction(|c| {
let id = Uuid::new_v4();
diesel::insert_into(users::table)
diesel::insert_into(client::table)
.values(User {
id,
username: register.username,
@@ -126,15 +126,15 @@ pub fn register(conn: &mut DbConnection, register: Register) -> Result<(), Datab
}
pub fn count_users_with_username(conn: &mut DbConnection, username: &String) -> Result<i64, DatabaseError> {
Ok(users::table
Ok(client::table
.count()
.filter(users::username.eq(username))
.filter(client::username.eq(username))
.get_result::<i64>(conn)?)
}
pub fn count_users_with_email(conn: &mut DbConnection, email: &String) -> Result<i64, DatabaseError> {
Ok(users::table
Ok(client::table
.count()
.filter(users::email.eq(email))
.filter(client::email.eq(email))
.get_result::<i64>(conn)?)
}