-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
feat: bust a move
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
-- We don't need the current_fen_id column anymore for games | ||
ALTER TABLE games DROP COLUMN current_fen_id; | ||
-- We don't need the fen_id column anymore for moves | ||
ALTER TABLE moves DROP COLUMN fen_id; | ||
|
||
-- We dont need the fens table anymore | ||
DROP TABLE fens; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
-- ALTER THE MOVES TABLE | ||
|
||
-- Drop Unique constraint on moves (game_id, move_number) | ||
ALTER TABLE moves DROP CONSTRAINT moves_game_id_move_number_key; | ||
|
||
-- Drop our index on moves (game_id) | ||
DROP INDEX idx_moves_game_id; | ||
|
||
-- Drop the game_id, move, and move_number columns | ||
ALTER TABLE moves DROP COLUMN game_id; | ||
ALTER TABLE moves DROP COLUMN move_number; | ||
ALTER TABLE moves DROP COLUMN move; | ||
|
||
-- Insert just a plain fen column that should be unique | ||
ALTER TABLE moves ADD COLUMN board TEXT UNIQUE NOT NULL; | ||
|
||
-- RENAME THE MOVES TABLE TO POSITIONS | ||
|
||
-- Rename the entire moves table to positions | ||
-- This will describe every unqiue position that a game has been in | ||
ALTER TABLE moves RENAME TO positions; | ||
|
||
-- CREATE A NEW MOVES TABLE | ||
|
||
-- Create a new table, also called moves, to track moves made in a game | ||
CREATE TABLE IF NOT EXISTS moves ( | ||
id UUID PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), | ||
-- The game id | ||
game_id UUID NOT NULL REFERENCES games(id) ON DELETE CASCADE, | ||
-- The position of the game and the last move made | ||
position_id UUID NOT NULL REFERENCES positions(id) ON DELETE CASCADE, | ||
-- TODO: do we need this? This information is available within the FEN of the position | ||
-- The move number of the game | ||
move_number INTEGER NOT NULL, | ||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
-- enforce uniqueness on point in a game. also implement an index | ||
UNIQUE (game_id, move_number) | ||
); |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use askama::Template; | ||
use axum::{ | ||
extract::{Path, State}, | ||
response::{IntoResponse, Response}, | ||
Form, | ||
}; | ||
use sqlx::types::Uuid; | ||
|
||
use crate::api::models::ApiBoard; | ||
use crate::database::models::{Game, GameError}; | ||
use crate::AppState; | ||
|
||
#[derive(serde::Deserialize)] | ||
pub struct MakeMoveRequest { | ||
#[serde(rename = "uciMove")] | ||
uci_move: String, | ||
} | ||
|
||
pub async fn handler( | ||
State(state): State<AppState>, | ||
Path(game_id): Path<Uuid>, | ||
Form(request): Form<MakeMoveRequest>, | ||
) -> Result<impl IntoResponse, ReadBoardError> { | ||
let uci_move = request.uci_move; | ||
let mut conn = state.database().begin().await?; | ||
let maybe_board = Game::make_move(&mut conn, game_id, &uci_move).await; | ||
let board = match maybe_board { | ||
Ok(board) => board, | ||
Err(e) => match e { | ||
GameError::InvalidMove(_, board) => board, | ||
_ => return Err(e.into()), | ||
}, | ||
}; | ||
// If we got here, then either we made a valid move | ||
// or no changes were made to the database (invalid move) | ||
conn.commit().await?; | ||
|
||
let api_board = ApiBoard { | ||
board, | ||
game_id: game_id.to_string(), | ||
}; | ||
|
||
Ok(TemplateApiBoard { api_board }) | ||
} | ||
|
||
#[derive(Template)] | ||
#[template(path = "board.html")] | ||
struct TemplateApiBoard { | ||
api_board: ApiBoard, | ||
} | ||
|
||
#[derive(Debug, thiserror::Error)] | ||
pub enum ReadBoardError { | ||
#[error("sqlx error: {0}")] | ||
Sqlx(#[from] sqlx::Error), | ||
#[error("game error: {0}")] | ||
Game(#[from] GameError), | ||
} | ||
|
||
impl IntoResponse for ReadBoardError { | ||
fn into_response(self) -> Response { | ||
let body = format!("{}", self); | ||
(axum::http::StatusCode::INTERNAL_SERVER_ERROR, body).into_response() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod board; | ||
pub mod create_game; | ||
pub mod make_move; | ||
pub mod read_all_games; | ||
pub mod read_game; |