This commit is contained in:
@@ -1,40 +1,35 @@
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use axum::{
|
||||
Json, extract::{
|
||||
FromRequest,FromRequestParts, State, Path,
|
||||
|
||||
}, http::StatusCode, response::{IntoResponse, sse::KeepAlive}
|
||||
|
||||
Json,
|
||||
extract::{FromRequest, FromRequestParts, Path, State},
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, sse::KeepAlive},
|
||||
};
|
||||
//use axum::extract::ws::Message;
|
||||
use chrono::NaiveDateTime;
|
||||
use rusqlite::{Name, Statement, params};
|
||||
use rusqlite::OptionalExtension;
|
||||
use rusqlite::{Name, Statement, params};
|
||||
use serde::Serialize;
|
||||
use serde_json::{json, to_value};
|
||||
|
||||
use crate::chat::extractor::{
|
||||
AddUserConversationPayload, CreateConversationPayload, GetMessagesPayload, SendMessagePayload
|
||||
AddUserConversationPayload, CreateConversationPayload, GetMessagesPayload, SendMessagePayload,
|
||||
};
|
||||
use crate::utils::db_pool::{AppState};
|
||||
use crate::utils::auth::AuthClaims;
|
||||
|
||||
use crate::utils::db_pool::AppState;
|
||||
|
||||
//TODO: update conversation title
|
||||
//FIXME: make a default title if empty
|
||||
//FIXME: make a default title if empty
|
||||
pub async fn create_conversation(
|
||||
State(state): State<AppState>,
|
||||
AuthClaims {user_id, hotel_id}: AuthClaims,
|
||||
CreateConversationPayload(payload): CreateConversationPayload
|
||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||
CreateConversationPayload(payload): CreateConversationPayload,
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||
|
||||
let conn = match pool.get(){
|
||||
let conn = match pool.get() {
|
||||
Ok(conn) => conn,
|
||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error"))
|
||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error")),
|
||||
};
|
||||
|
||||
let result = conn.execute(
|
||||
@@ -47,7 +42,7 @@ pub async fn create_conversation(
|
||||
Err(err) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Error when creating the conversation: {err}")
|
||||
format!("Error when creating the conversation: {err}"),
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -55,62 +50,67 @@ pub async fn create_conversation(
|
||||
if rows == 0 {
|
||||
return (
|
||||
StatusCode::NOT_FOUND,
|
||||
"not able to create the conversation".to_string()
|
||||
"not able to create the conversation".to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
let conv_id = conn.last_insert_rowid();
|
||||
|
||||
let user_conv_rel = conn.execute(
|
||||
"INSERT INTO conversation_participants (conversation_id, user_id, name)
|
||||
VALUES (?1, ?2, ?3)",
|
||||
params![conv_id, user_id, payload.name]
|
||||
params![conv_id, user_id, payload.name],
|
||||
);
|
||||
|
||||
match user_conv_rel {
|
||||
Ok(r) => return (StatusCode::OK, format!("Created conversation {}", payload.name)),
|
||||
Err(err) => return (
|
||||
Ok(r) => {
|
||||
return (
|
||||
StatusCode::OK,
|
||||
format!("Created conversation {}", payload.name),
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Error when creating the conversation: {err}")
|
||||
)
|
||||
format!("Error when creating the conversation: {err}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// extra logic here (more queries, validations, etc.)
|
||||
|
||||
//(StatusCode::OK, format!("Created conversation {}", payload.name))
|
||||
|
||||
}
|
||||
|
||||
//FIXME: add title to conv
|
||||
pub async fn add_user_to_conv(
|
||||
State(state): State<AppState>,
|
||||
AuthClaims {user_id, hotel_id}: AuthClaims,
|
||||
AddUserConversationPayload(payload):AddUserConversationPayload
|
||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||
AddUserConversationPayload(payload): AddUserConversationPayload,
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||
|
||||
let mut conn = match pool.get(){
|
||||
let mut conn = match pool.get() {
|
||||
Ok(conn) => conn,
|
||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error"))
|
||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error")),
|
||||
};
|
||||
|
||||
let creator_name: Option<String> = match conn
|
||||
.query_row(
|
||||
"SELECT name FROM conversation WHERE creator_id = ?1 AND id = ?2",
|
||||
params![user_id, payload.conv_id],
|
||||
|row| row.get(0),
|
||||
)
|
||||
.optional() {
|
||||
Ok(name) => name,
|
||||
//Ok(None) => false,
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Creator check failed".to_string(),
|
||||
.query_row(
|
||||
"SELECT name FROM conversation WHERE creator_id = ?1 AND id = ?2",
|
||||
params![user_id, payload.conv_id],
|
||||
|row| row.get(0),
|
||||
)
|
||||
}
|
||||
.optional()
|
||||
{
|
||||
Ok(name) => name,
|
||||
//Ok(None) => false,
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Creator check failed".to_string(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let is_creator = creator_name.is_some();
|
||||
@@ -122,42 +122,36 @@ pub async fn add_user_to_conv(
|
||||
);
|
||||
}
|
||||
|
||||
//fix this
|
||||
//fix this
|
||||
let existing: HashSet<u32> = {
|
||||
let mut stmt = match conn.prepare(
|
||||
"SELECT user_id FROM conversation_participants WHERE conversation_id = ?1",
|
||||
) {
|
||||
Ok(s) => s,
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Prepare participants stmt failed".to_string(),
|
||||
)
|
||||
}
|
||||
};
|
||||
let mut stmt = match conn
|
||||
.prepare("SELECT user_id FROM conversation_participants WHERE conversation_id = ?1")
|
||||
{
|
||||
Ok(s) => s,
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Prepare participants stmt failed".to_string(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
match stmt.query_map(params![payload.conv_id], |row| row.get(0)) {
|
||||
Ok(rows) => rows.filter_map(Result::ok).collect(),
|
||||
match stmt.query_map(params![payload.conv_id], |row| row.get(0)) {
|
||||
Ok(rows) => rows.filter_map(Result::ok).collect(),
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Query participants failed".to_string(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}; // ← stmt dropped HERE
|
||||
|
||||
let payload_users: HashSet<u32> = payload.users.into_iter().collect();
|
||||
|
||||
let to_add: Vec<u32> = payload_users
|
||||
.difference(&existing)
|
||||
.copied()
|
||||
.collect();
|
||||
let to_add: Vec<u32> = payload_users.difference(&existing).copied().collect();
|
||||
|
||||
let to_remove : Vec<u32> = existing
|
||||
.difference(&payload_users)
|
||||
.copied()
|
||||
.collect();
|
||||
let to_remove: Vec<u32> = existing.difference(&payload_users).copied().collect();
|
||||
|
||||
let tx = match conn.transaction() {
|
||||
Ok(t) => t,
|
||||
@@ -165,11 +159,11 @@ pub async fn add_user_to_conv(
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Transaction start failed for update conv participants".to_string(),
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
for user_id in to_add {
|
||||
for user_id in to_add {
|
||||
if let Err(err) = tx.execute(
|
||||
"INSERT INTO conversation_participants (conversation_id, user_id, name)
|
||||
VALUES (?1, ?2, ?3)",
|
||||
@@ -202,8 +196,7 @@ for user_id in to_add {
|
||||
);
|
||||
}
|
||||
|
||||
return (StatusCode::OK, "ok".to_string());
|
||||
|
||||
return (StatusCode::OK, "ok".to_string());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -214,36 +207,44 @@ pub struct Get
|
||||
|
||||
pub async fn get_conv_users(
|
||||
State(state): State<AppState>,
|
||||
AuthClaims{user_id, hotel_id}: AuthClaims,
|
||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||
Path(conv_id): Path<(i32)>,
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||
|
||||
let conn = match pool.get (){
|
||||
Ok(c)=> c,
|
||||
Err(err)=> return (StatusCode::INTERNAL_SERVER_ERROR, format!("Error opening pol connection : {err}") )
|
||||
let conn = match pool.get() {
|
||||
Ok(c) => c,
|
||||
Err(err) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Error opening pol connection : {err}"),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let mut stmt = match conn.prepare(
|
||||
"SELECT conversation_id, name FROM conversation_participants WHERE user_id = ?1",
|
||||
) {
|
||||
let mut stmt = match conn
|
||||
.prepare("SELECT conversation_id, name FROM conversation_participants WHERE user_id = ?1")
|
||||
{
|
||||
Ok(s) => s,
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Prepare failed: {}", e)),
|
||||
Err(e) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Prepare failed: {}", e),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
//fix this
|
||||
//fix this
|
||||
let existing: HashSet<u32> = {
|
||||
let mut stmt = match conn.prepare(
|
||||
"SELECT user_id FROM conversation_participants WHERE conversation_id = ?1",
|
||||
) {
|
||||
let mut stmt = match conn
|
||||
.prepare("SELECT user_id FROM conversation_participants WHERE conversation_id = ?1")
|
||||
{
|
||||
Ok(s) => s,
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Prepare participants stmt failed".to_string(),
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -253,113 +254,123 @@ pub async fn get_conv_users(
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Query participants failed".to_string(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}; // ← stmt dropped HERE
|
||||
|
||||
let present: Vec<u32> = existing
|
||||
.into_iter()
|
||||
.collect();
|
||||
let present: Vec<u32> = existing.into_iter().collect();
|
||||
|
||||
match serde_json::to_string(&present) {
|
||||
Ok(json) => (StatusCode::OK, json),
|
||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Serialization failed: {}", e)),
|
||||
Err(e) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Serialization failed: {}", e),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_message(
|
||||
State(state): State<AppState>,
|
||||
AuthClaims {user_id, hotel_id}: AuthClaims,
|
||||
SendMessagePayload(payload):SendMessagePayload
|
||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||
SendMessagePayload(payload): SendMessagePayload,
|
||||
) -> impl IntoResponse {
|
||||
//TODO: make sur the convid is valid
|
||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||
|
||||
let conn = match pool.get(){
|
||||
let conn = match pool.get() {
|
||||
Ok(conn) => conn,
|
||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error"))
|
||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error")),
|
||||
};
|
||||
|
||||
let mut statement = match conn.prepare(
|
||||
"SELECT 1 FROM conversation_participants WHERE user_id = ?1 AND conversation_id = ?2" ,
|
||||
){
|
||||
"SELECT 1 FROM conversation_participants WHERE user_id = ?1 AND conversation_id = ?2",
|
||||
) {
|
||||
Ok(statement) => statement,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "prepare failed".to_string())
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"prepare failed".to_string(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
match statement.exists(params![user_id, payload.conv_id]) {
|
||||
Ok(true) => {
|
||||
// user is part of the conversation — continue
|
||||
}
|
||||
Ok(false) => {
|
||||
// early exit: not part of the conversation
|
||||
return (StatusCode::FORBIDDEN, "Not part of the conversation".to_string());
|
||||
}
|
||||
Err(_) => {
|
||||
// query failed
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let (message_id, sent_at): (i64, String) = match conn.query_row(
|
||||
"INSERT INTO message (sender_id, content, conversation_id)
|
||||
VALUES (?1, ?2, ?3)
|
||||
RETURNING id, sent_at",
|
||||
params![user_id, payload.message, payload.conv_id],
|
||||
|row| Ok((
|
||||
row.get::<_, i64>(0)?,
|
||||
row.get::<_, String>(1)?,
|
||||
)),
|
||||
) {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("DB insert failed: {err}"),
|
||||
);
|
||||
}
|
||||
};
|
||||
//let message_id = conn.last_insert_rowid();
|
||||
// FIXME: add sent_at and message id in the response.
|
||||
|
||||
|
||||
// --- send to conversation participants ---
|
||||
let mut stmt_participants = conn
|
||||
.prepare("SELECT user_id FROM conversation_participants WHERE conversation_id = ?1")
|
||||
.expect("prepare participants failed");
|
||||
|
||||
let participant_ids: Vec<i32> = stmt_participants
|
||||
.query_map(params![payload.conv_id], |row| row.get(0))
|
||||
.expect("query_map failed")
|
||||
.filter_map(Result::ok)
|
||||
.collect();
|
||||
|
||||
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
||||
let update_msg = serde_json::json!({
|
||||
"event_type": "chat_message",
|
||||
"conv_id": payload.conv_id,
|
||||
"sender_id": user_id,
|
||||
"content": payload.message,
|
||||
"id": message_id,
|
||||
"sent_at": sent_at,
|
||||
})
|
||||
.to_string();
|
||||
|
||||
for uid in &participant_ids {
|
||||
if let Some(sender) = hotel_users.get(uid) {
|
||||
let _ = sender.send(
|
||||
axum::extract::ws::Message::Text(update_msg.clone().into())
|
||||
Ok(true) => {
|
||||
// user is part of the conversation — continue
|
||||
}
|
||||
Ok(false) => {
|
||||
// early exit: not part of the conversation
|
||||
return (
|
||||
StatusCode::FORBIDDEN,
|
||||
"Not part of the conversation".to_string(),
|
||||
);
|
||||
}
|
||||
Err(_) => {
|
||||
// query failed
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Query failed".to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(StatusCode::OK, format!("sent message: {}, to users:{:?}", payload.message, participant_ids))
|
||||
let (message_id, sent_at): (i64, String) = match conn.query_row(
|
||||
"INSERT INTO message (sender_id, content, conversation_id)
|
||||
VALUES (?1, ?2, ?3)
|
||||
RETURNING id, sent_at",
|
||||
params![user_id, payload.message, payload.conv_id],
|
||||
|row| Ok((row.get::<_, i64>(0)?, row.get::<_, String>(1)?)),
|
||||
) {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("DB insert failed: {err}"),
|
||||
);
|
||||
}
|
||||
//Ok(_) => (StatusCode::NOT_FOUND, "Conversation not found".to_string()),
|
||||
};
|
||||
//let message_id = conn.last_insert_rowid();
|
||||
// FIXME: add sent_at and message id in the response.
|
||||
|
||||
// --- send to conversation participants ---
|
||||
let mut stmt_participants = conn
|
||||
.prepare("SELECT user_id FROM conversation_participants WHERE conversation_id = ?1")
|
||||
.expect("prepare participants failed");
|
||||
|
||||
let participant_ids: Vec<i32> = stmt_participants
|
||||
.query_map(params![payload.conv_id], |row| row.get(0))
|
||||
.expect("query_map failed")
|
||||
.filter_map(Result::ok)
|
||||
.collect();
|
||||
|
||||
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
||||
let update_msg = serde_json::json!({
|
||||
"event_type": "chat_message",
|
||||
"conv_id": payload.conv_id,
|
||||
"sender_id": user_id,
|
||||
"content": payload.message,
|
||||
"id": message_id,
|
||||
"sent_at": sent_at,
|
||||
})
|
||||
.to_string();
|
||||
|
||||
for uid in &participant_ids {
|
||||
if let Some(sender) = hotel_users.get(uid) {
|
||||
let _ = sender.send(axum::extract::ws::Message::Text(update_msg.clone().into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(
|
||||
StatusCode::OK,
|
||||
format!(
|
||||
"sent message: {}, to users:{:?}",
|
||||
payload.message, participant_ids
|
||||
),
|
||||
)
|
||||
}
|
||||
//Ok(_) => (StatusCode::NOT_FOUND, "Conversation not found".to_string()),
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct Message {
|
||||
@@ -369,16 +380,15 @@ struct Message {
|
||||
sent_at: String,
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_message(
|
||||
State(state): State<AppState>,
|
||||
AuthClaims {user_id, hotel_id}: AuthClaims,
|
||||
GetMessagesPayload(payload):GetMessagesPayload
|
||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||
GetMessagesPayload(payload): GetMessagesPayload,
|
||||
) -> Result<impl IntoResponse, (StatusCode, String)> {
|
||||
|
||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||
|
||||
let conn = pool.get()
|
||||
let conn = pool
|
||||
.get()
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()))?;
|
||||
|
||||
let from_time = match payload.timestamp.as_deref() {
|
||||
@@ -386,39 +396,51 @@ pub async fn get_message(
|
||||
Some(ts) => ts,
|
||||
};
|
||||
|
||||
let mut stmt = conn.prepare(
|
||||
"SELECT id, sender_id, content, sent_at
|
||||
let mut stmt = conn
|
||||
.prepare(
|
||||
"SELECT id, sender_id, content, sent_at
|
||||
FROM message
|
||||
WHERE conversation_id = ?1
|
||||
AND sent_at > ?2
|
||||
ORDER BY sent_at DESC
|
||||
LIMIT 50"
|
||||
).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Prepare failed".to_string()))?;
|
||||
LIMIT 50",
|
||||
)
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Prepare failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
|
||||
let messages = stmt.query_map(
|
||||
params![payload.conv_id, from_time],
|
||||
|row| {
|
||||
let messages = stmt
|
||||
.query_map(params![payload.conv_id, from_time], |row| {
|
||||
Ok(Message {
|
||||
id: row.get(0)?,
|
||||
sender_id: row.get(1)?,
|
||||
content: row.get(2)?,
|
||||
sent_at: row.get(3)?,
|
||||
})
|
||||
}
|
||||
)
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string()))?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Collect failed".to_string()))?;
|
||||
})
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Query failed".to_string(),
|
||||
)
|
||||
})?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Collect failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let response = serde_json::to_string(&messages)
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Serialisation failed"));
|
||||
|
||||
Ok((StatusCode::OK, response ))
|
||||
|
||||
Ok((StatusCode::OK, response))
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct User {
|
||||
id: i32,
|
||||
@@ -426,22 +448,30 @@ struct User {
|
||||
//display_name: String,
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_hotel_users(
|
||||
State(state): State<AppState>,
|
||||
AuthClaims { hotel_id, .. }: AuthClaims,
|
||||
) -> impl IntoResponse {
|
||||
let conn = match state.logs_pool.get() {
|
||||
Ok(c) => c,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error".to_string()),
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"DB connection error".to_string(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let mut stmt = match conn.prepare(
|
||||
"SELECT user_id, username FROM hotel_user_link WHERE hotel_id = ?1",
|
||||
) {
|
||||
Ok(s) => s,
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Prepare failed: {}", e)),
|
||||
};
|
||||
let mut stmt =
|
||||
match conn.prepare("SELECT user_id, username FROM hotel_user_link WHERE hotel_id = ?1") {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Prepare failed: {}", e),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let users_iter = match stmt.query_map(params![hotel_id], |row| {
|
||||
Ok(User {
|
||||
@@ -451,17 +481,30 @@ pub async fn get_hotel_users(
|
||||
})
|
||||
}) {
|
||||
Ok(iter) => iter,
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Query failed: {}", e)),
|
||||
Err(e) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Query failed: {}", e),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let users: Vec<User> = match users_iter.collect::<Result<Vec<_>, _>>() {
|
||||
Ok(u) => u,
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Collect failed: {}", e)),
|
||||
Err(e) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Collect failed: {}", e),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
match serde_json::to_string(&users) {
|
||||
Ok(json) => (StatusCode::OK, json),
|
||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Serialization failed: {}", e)),
|
||||
Err(e) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Serialization failed: {}", e),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,54 +518,71 @@ struct Conversation {
|
||||
pub async fn get_convs(
|
||||
State(state): State<AppState>,
|
||||
//Path((item_name, item_amount)): Path<(String, i32)>,
|
||||
AuthClaims{ user_id, hotel_id}: AuthClaims,
|
||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||
|
||||
let conn = match pool.get(){
|
||||
let conn = match pool.get() {
|
||||
Ok(conn) => conn,
|
||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error: {err}")),
|
||||
Err(err) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Pool error: {err}"),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let mut stmt = match conn.prepare(
|
||||
"SELECT conversation_id, name FROM conversation_participants WHERE user_id = ?1",
|
||||
) {
|
||||
let mut stmt = match conn
|
||||
.prepare("SELECT conversation_id, name FROM conversation_participants WHERE user_id = ?1")
|
||||
{
|
||||
Ok(s) => s,
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Prepare failed: {}", e)),
|
||||
Err(e) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Prepare failed: {}", e),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let rows = match stmt.query_map(params![user_id], |row| {
|
||||
let conversation_id: i32 = row.get(0)?;
|
||||
let name: String = row.get(1)?;
|
||||
Ok(Conversation {
|
||||
id: row.get(0)?,
|
||||
title: row.get(1)?,
|
||||
})
|
||||
id: row.get(0)?,
|
||||
title: row.get(1)?,
|
||||
})
|
||||
}) {
|
||||
Ok(rows) => rows,
|
||||
//Ok(_) => {}, IMPLEMENT NO CONV ?
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Query failed: {}", e)),
|
||||
Err(e) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Query failed: {}", e),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let convs: Vec<Conversation> = match rows.collect::<Result<Vec<_>, _>>() {
|
||||
Ok(u) => u,
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Collect failed: {}", e)),
|
||||
Err(e) => {
|
||||
return (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Collect failed: {}", e),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
//.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, Json("error".to_string())));
|
||||
|
||||
match serde_json::to_string(&convs) {
|
||||
Ok(json) => (StatusCode::OK, json),
|
||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Serialization failed: {}", e)),
|
||||
Err(e) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Serialization failed: {}", e),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
pub async fn get_convs(
|
||||
State(state): State<AppState>,
|
||||
@@ -535,18 +595,18 @@ pub async fn get_convs(
|
||||
let conn = match pool.get(){
|
||||
Ok(conn) => conn,
|
||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error: {}", err).into_response() )
|
||||
|
||||
|
||||
};
|
||||
|
||||
let mut stmt = match conn.prepare(
|
||||
"SELECT id, title FROM conversation WHERE creator_id = ?1",
|
||||
) {
|
||||
Ok(s) => s,
|
||||
Err(e) =>
|
||||
|
||||
Err(e) =>
|
||||
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, format!("Prepare failed: {}", e).into_response() )
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
let rows = match stmt.query_map(params![user_id], |row| {
|
||||
@@ -556,10 +616,10 @@ pub async fn get_convs(
|
||||
}) {
|
||||
Ok(rows) => rows,
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Query failed: {}", e).into_response() )
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
let mut map = HashMap::new();
|
||||
|
||||
// ✅ Iterate through the row results
|
||||
@@ -569,7 +629,7 @@ pub async fn get_convs(
|
||||
map.insert(title, id);
|
||||
}
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Row parsing failed: {}", e).into_response() )
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,7 +638,7 @@ pub async fn get_convs(
|
||||
Ok(c) => c,
|
||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("List unwrapping failed: {}", e).into_response() )
|
||||
};
|
||||
|
||||
|
||||
let conv_map_clean_json = serde_json::to_value(map)
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("Serialization failed: {}", e).into_response() ));
|
||||
|
||||
@@ -587,4 +647,4 @@ pub async fn get_convs(
|
||||
(StatusCode::OK, Json(conv_map_clean_json)).into_response()
|
||||
}
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user