Upgrading mysql_async to latest version

This version comes with the benefit of having much more concise exec_map functionality among other things

This commit and the following ones also move db-lib to using a more 'try' based approach
This commit is contained in:
shockrah 2021-03-30 21:38:16 -07:00
parent f7d90e4a09
commit d88948385d

View File

@ -1,11 +1,10 @@
use mysql_async::{params, Pool, Conn}; use mysql_async::{params, Pool};
use mysql_async::prelude::Queryable; use mysql_async::prelude::Queryable;
use mysql_async::error::Error as SqlError; use mysql_async::Error as SqlError;
use crate::{Response, no_conn, sql_err};
use crate::{UBigInt, Integer, VarChar}; use crate::{UBigInt, Integer, VarChar};
use crate::{PublicMember, Member}; use crate::{PublicMember, Member, Response};
use rand::RngCore; use rand::RngCore;
@ -14,74 +13,46 @@ pub const STATUS_ONLINE: Integer = 0;
pub const STATUS_OFFLINE: Integer = 1; pub const STATUS_OFFLINE: Integer = 1;
pub const STATUS_AWAY: Integer = 2; pub const STATUS_AWAY: Integer = 2;
pub const STATUS_DO_NOT_DISTURB: Integer = 3; pub const STATUS_DO_NOT_DISTURB: Integer = 3;
/*
*
* conn = getconn
* result = conn.query
* return response based on result
*
*/
impl Member { impl Member {
pub async fn get(p: &Pool, id: UBigInt) -> Response<Self> { pub async fn get(p: &Pool, id: UBigInt) -> Result<Response<Self>, SqlError> {
//! @returns Row on success //! @returns Row on success
//! @returns Other on failure //! @returns Other on failure
if let Ok(conn) = p.get_conn().await { let mut conn = p.get_conn().await?;
let q = "SELECT secret, name, status, permissions FROM members WHERE id = :id"; let q = "SELECT secret, name, status, permissions FROM members WHERE id = :id";
type Row = Option<(VarChar, VarChar, Integer, UBigInt)>; let params = params!{"id" => id};
let db_res : Result<(Conn, Row), SqlError>
= conn.first_exec(q, params!{"id" => id}).await; let row: Option<(VarChar, VarChar, Integer, UBigInt)> =
if let Ok((_, row)) = db_res { conn.exec_first(q, params).await?;
return match row { if let Some((secret, name, status, permissions)) = row {
Some(row) => Response::Row(Self { Ok(Response::Row(Member {
id, id, secret, name, status, permissions
secret: row.0, }))
name: row.1, } else {
status: row.2, Ok(Response::Empty)
permissions: row.3
}),
None => Response::Empty
} }
} }
return Response::Other(sql_err!("Fetch failed"));
}
return Response::Other(no_conn!("Member::FromDB::get"));
}
pub async fn filter(p: &Pool, status: Integer) -> Response<Self> { pub async fn filter(p: &Pool, status: Integer) -> Result<Response<PublicMember>, SqlError> {
//! @params status //! @params status i32
return match (p.get_conn().await, status) { //! @returns Response::Set(PublicMember)
(Ok(conn), STATUS_ONLINE) | (Ok(conn), STATUS_OFFLINE) | if !(status == STATUS_ONLINE || status == STATUS_AWAY || status == STATUS_OFFLINE || status == STATUS_DO_NOT_DISTURB) {
(Ok(conn), STATUS_AWAY) | (Ok(conn), STATUS_DO_NOT_DISTURB) => { Ok(Response::RestrictedInput(format!("Invalid status")))
// TODO: Allow people to query somewhere in the middle of this set } else {
// i.e. we should be able to get user 100 -> 150 instead of just the let mut conn = p.get_conn().await?;
// first 1000 people
let q = let q =
"SELECT id, name, status, permissions FROM members "SELECT id, name, status, permissions FROM members
WHERE status = :stat LIMIT 100"; // high limit for now WHERE status = :stat LIMIT 100"; // high limit for now
if let Ok(query) = conn.prep_exec(q, params!{"stat" => status}).await {
let mapping_r = query.map_and_drop(|row| {
let (id, name, status, permissions): (UBigInt, VarChar, Integer, UBigInt) =
mysql_async::from_row(row);
Member { let params = params!{"stat" => status};
id, let members = conn.exec_map(q, params, |(id, name , status, permissions)| {
secret: "".into(), // no show for obv reasons PublicMember {
name, id, name, status, permissions
status,
permissions
} }
}).await; }).await?;
match mapping_r { Ok(Response::Set(members))
Ok((_, members)) => Response::Set(members),
Err(_) => Response::Other(sql_err!("db::Members::filter"))
}
}
else {
Response::Other(sql_err!("Initial query faile: db::Members::filter"))
}
}
_ => Response::Other(sql_err!("err"))
} }
} }
pub async fn add(p: &Pool, name: &str, secret: &str, perms: u64) -> Result<Response<Self>, SqlError> { pub async fn add(p: &Pool, name: &str, secret: &str, perms: u64) -> Result<Response<Self>, SqlError> {
@ -93,10 +64,10 @@ impl Member {
//! @returns : on_succes => Ok(Response<Member>) //! @returns : on_succes => Ok(Response<Member>)
//! @returns : on_partial_succes => Ok(Response<Member>) //! @returns : on_partial_succes => Ok(Response<Member>)
//! @returns : on_failure => Err(SomeBS) //! @returns : on_failure => Err(SomeBS)
let conn = p.get_conn().await?; let mut conn = p.get_conn().await?;
let id: u64 = rand::rngs::OsRng.next_u64(); let id: u64 = rand::rngs::OsRng.next_u64();
conn.drop_exec( conn.exec_drop(
"INSERT INTO members(secret, name, status, permissions) "INSERT INTO members(secret, name, status, permissions)
VALUES(:id, :secret, :name, :status, :permissions)", VALUES(:id, :secret, :name, :status, :permissions)",
mysql_async::params!{ mysql_async::params!{
@ -119,8 +90,8 @@ impl Member {
pub async fn update_perms(p: &Pool, uid: UBigInt, permissions: UBigInt) -> Result<UBigInt, SqlError> { pub async fn update_perms(p: &Pool, uid: UBigInt, permissions: UBigInt) -> Result<UBigInt, SqlError> {
//! @return on_sucess Ok(NewPermisionsMask) //! @return on_sucess Ok(NewPermisionsMask)
//! @throws Err(SqlError) //! @throws Err(SqlError)
let conn = p.get_conn().await?; let mut conn = p.get_conn().await?;
conn.drop_exec( conn.exec_drop(
"UPDATE members SET permissions = :perms WHERE id = :id", "UPDATE members SET permissions = :perms WHERE id = :id",
params!{ params!{
"id" => uid, "id" => uid,
@ -131,9 +102,9 @@ impl Member {
} }
pub async fn update_nick(p: &Pool, uid: UBigInt, new_nick: &str) -> Result<(), SqlError> { pub async fn update_nick(p: &Pool, uid: UBigInt, new_nick: &str) -> Result<(), SqlError> {
let conn = p.get_conn().await?; let mut conn = p.get_conn().await?;
conn.drop_exec( conn.exec_drop(
"UPDATE members SET name = :nick WHERE id = id", "UPDATE members SET name = :nick WHERE id = id",
params!{ params!{
"id" => uid, "id" => uid,
@ -154,21 +125,17 @@ impl PublicMember {
if !valid_status { if !valid_status {
return Ok(Response::RestrictedInput(format!("Invalid status value"))); return Ok(Response::RestrictedInput(format!("Invalid status value")));
} else { } else {
let conn = p.get_conn().await?; let mut conn = p.get_conn().await?;
let q = "SELECT id, name, permissions FROM members let q = "SELECT id, name, permissions FROM members
WHERE status = :status LIMIT 1000"; WHERE status = :status LIMIT 1000";
let result = conn.prep_exec(q, params!{"status" => status}).await?; let params = params!{"status" => status};
let (_, data): (_, Vec<PublicMember>) = result.map_and_drop(|row| { let members = conn.exec_map(q, params, |(id, name, permissions)| {
let (id, name, permissions): (UBigInt, VarChar, UBigInt) =
mysql_async::from_row(row);
PublicMember { id, name, permissions, status } PublicMember { id, name, permissions, status }
}).await?; }).await?;
return Ok(Response::Set(data)); return Ok(Response::Set(members));
} }
} }
} }