diff --git a/src/content.rs b/src/content.rs index 940417f..f00a348 100644 --- a/src/content.rs +++ b/src/content.rs @@ -1,4 +1,4 @@ -use chrono::{serde::*, DateTime, Utc}; +use chrono::{serde::*, DateTime, NaiveDateTime, Utc}; use serde::{Deserialize, Serialize}; use sqlx::{types::Json, FromRow}; use uuid::Uuid; @@ -21,12 +21,9 @@ pub struct Site { pub description: Option, /// Times - #[serde(with = "ts_seconds")] - pub created_at: DateTime, - #[serde(with = "ts_seconds_option")] - pub modified_at: Option>, - #[serde(with = "ts_seconds_option")] - pub deleted_at: Option>, + pub created_at: NaiveDateTime, + pub modified_at: Option, + pub deleted_at: Option, } #[derive(Deserialize, Serialize, FromRow)] @@ -56,12 +53,9 @@ pub struct Page { pub blocks: Json>, /// Times - #[serde(with = "ts_seconds")] - pub created_at: DateTime, - #[serde(with = "ts_seconds_option")] - pub modified_at: Option>, - #[serde(with = "ts_seconds_option")] - pub deleted_at: Option>, + pub created_at: NaiveDateTime, + pub modified_at: Option, + pub deleted_at: Option, } #[derive(Deserialize, Serialize)] diff --git a/src/routes/sites.rs b/src/routes/sites.rs index 61f1d92..2628d91 100644 --- a/src/routes/sites.rs +++ b/src/routes/sites.rs @@ -1,5 +1,6 @@ use axum::{ extract::{Path, State}, + http::StatusCode, response::IntoResponse, routing::{get, post}, Json, Router, @@ -10,7 +11,6 @@ use std::sync::Arc; use crate::{ auth::http::RequireUser, - content::Site, http::{ error::{ApiError, ERR_NOT_FOUND}, extract::JsonBody, @@ -22,15 +22,22 @@ async fn get_site( State(state): State>, Path(name): Path, ) -> Result> { - let site_query = sqlx::query_as("SELECT * FROM sites WHERE name = $1").bind(name); - let site: Site = site_query - .fetch_one(&state.database) + let site = sqlx::query!( + "SELECT sites.id, sites.name, users.name as owner, title, description, sites.created_at FROM sites JOIN users ON sites.owner = users.id WHERE sites.name = $1 ", + name + ).fetch_one(&state.database) .await .map_err(|e| match e { sqlx::Error::RowNotFound => ERR_NOT_FOUND, _ => e.into(), })?; - Ok(Json(site)) + Ok(Json(json!({ + "name": site.name, + "owner": site.owner, + "title": site.title, + "description": site.description, + "created_at": site.created_at, + }))) } #[derive(Deserialize)] @@ -51,7 +58,17 @@ async fn create_site( payload.title, ) .execute(&state.database) - .await?; + .await + .map_err(|err| match err { + sqlx::Error::Database(dberr) if dberr.constraint() == Some("sites_name_key") => { + ApiError::ClientError { + status: StatusCode::CONFLICT, + code: "name-not-available", + message: "the chosen name is not available", + } + } + _ => err.into(), + })?; Ok(Json(json!({"ok": true, "url": "test"}))) }