list and delete users

This commit is contained in:
Greg Shuflin 2025-02-01 04:20:50 -08:00
parent 880ff11bb4
commit 745c7f0a63
3 changed files with 119 additions and 26 deletions

View File

@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO users (id, username, email, display_name, created_at)\n VALUES (?1, ?2, ?3, ?4, ?5)\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 5
},
"nullable": []
},
"hash": "120b948148309b9e3eeb964f89f098163ceceaf8b1f2c76d81fab2811c362a63"
}

View File

@ -0,0 +1,44 @@
{
"db_name": "SQLite",
"query": "\n SELECT \n id as \"id: Uuid\",\n username,\n email,\n display_name,\n created_at as \"created_at: chrono::DateTime<chrono::Utc>\"\n FROM users\n ",
"describe": {
"columns": [
{
"name": "id: Uuid",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "username",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "email",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "display_name",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "created_at: chrono::DateTime<chrono::Utc>",
"ordinal": 4,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
true,
true,
false
]
},
"hash": "3577e56d051f360866f893491584cccae7d2e985742ca78be06011e6c6640fc2"
}

View File

@ -1,12 +1,12 @@
#[macro_use] extern crate rocket; #[macro_use]
extern crate rocket;
use rocket::serde::{Serialize, json::Json, Deserialize};
use rocket_dyn_templates::{Template, context};
use rocket::fs::FileServer; use rocket::fs::FileServer;
use rocket_db_pools::{sqlx, Database, Connection};
use uuid::Uuid;
use rocket::http::Status; use rocket::http::Status;
use rocket::serde::{json::Json, Deserialize, Serialize};
use rocket_db_pools::{sqlx, Connection, Database};
use rocket_dyn_templates::{context, Template};
use uuid::Uuid;
#[derive(Database)] #[derive(Database)]
#[database("rss_data")] #[database("rss_data")]
@ -53,7 +53,7 @@ struct NewUser {
fn message() -> Json<Message> { fn message() -> Json<Message> {
Json(Message { Json(Message {
a: -4, a: -4,
b: "Hallo".to_string() b: "Hallo".to_string(),
}) })
} }
@ -63,13 +63,12 @@ fn index() -> Template {
} }
#[post("/users", data = "<new_user>")] #[post("/users", data = "<new_user>")]
async fn create_user(mut db: Connection<Db>, new_user: Json<NewUser>) -> Result<Json<User>, Status> { async fn create_user(
mut db: Connection<Db>,
new_user: Json<NewUser>,
) -> Result<Json<User>, Status> {
let new_user = new_user.into_inner(); let new_user = new_user.into_inner();
let user = User::new( let user = User::new(new_user.username, new_user.email, new_user.display_name);
new_user.username,
new_user.email,
new_user.display_name,
);
let query = sqlx::query("INSERT INTO users (id, username, email, display_name, created_at) VALUES (?1, ?2, ?3, ?4, ?5)") let query = sqlx::query("INSERT INTO users (id, username, email, display_name, created_at) VALUES (?1, ?2, ?3, ?4, ?5)")
.bind(user.id.to_string()) .bind(user.id.to_string())
@ -81,6 +80,37 @@ async fn create_user(mut db: Connection<Db>, new_user: Json<NewUser>) -> Result<
match query { match query {
Ok(_) => Ok(Json(user)), Ok(_) => Ok(Json(user)),
Err(e) => {
eprintln!("Database error: {}", e);
match e {
sqlx::Error::Database(db_err) if db_err.is_unique_violation() => {
Err(Status::Conflict)
}
_ => Err(Status::InternalServerError),
}
}
}
}
#[get("/users")]
async fn get_users(mut db: Connection<Db>) -> Result<Json<Vec<User>>, Status> {
let query = sqlx::query_as!(
User,
r#"
SELECT
id as "id: Uuid",
username,
email,
display_name,
created_at as "created_at: chrono::DateTime<chrono::Utc>"
FROM users
"#
)
.fetch_all(&mut **db)
.await;
match query {
Ok(users) => Ok(Json(users)),
Err(e) => { Err(e) => {
eprintln!("Database error: {}", e); eprintln!("Database error: {}", e);
Err(Status::InternalServerError) Err(Status::InternalServerError)
@ -88,10 +118,41 @@ async fn create_user(mut db: Connection<Db>, new_user: Json<NewUser>) -> Result<
} }
} }
#[delete("/users/<user_id>")]
async fn delete_user(mut db: Connection<Db>, user_id: &str) -> Status {
// Validate UUID format
let uuid = match Uuid::parse_str(user_id) {
Ok(uuid) => uuid,
Err(_) => return Status::BadRequest,
};
let query = sqlx::query("DELETE FROM users WHERE id = ?")
.bind(uuid.to_string())
.execute(&mut **db)
.await;
match query {
Ok(result) => {
if result.rows_affected() > 0 {
Status::NoContent
} else {
Status::NotFound
}
}
Err(e) => {
eprintln!("Database error: {}", e);
Status::InternalServerError
}
}
}
#[launch] #[launch]
fn rocket() -> _ { fn rocket() -> _ {
rocket::build() rocket::build()
.mount("/", routes![index, message, create_user]) .mount(
"/",
routes![index, message, create_user, get_users, delete_user],
)
.mount("/static", FileServer::from("static")) .mount("/static", FileServer::from("static"))
.attach(Template::fairing()) .attach(Template::fairing())
.attach(Db::init()) .attach(Db::init())