Add User Handling to CoveDb
and.. - Add Delete SqlPart - Cleanup imports
This commit is contained in:
parent
5fedceb383
commit
c62bb41cd4
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -75,7 +75,6 @@ dependencies = [
|
|||||||
"cove-db",
|
"cove-db",
|
||||||
"cove-net-common",
|
"cove-net-common",
|
||||||
"cove-net-server",
|
"cove-net-server",
|
||||||
"scc",
|
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
@ -191,6 +190,7 @@ name = "cove-db"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"async-trait",
|
||||||
"cove-db-macros",
|
"cove-db-macros",
|
||||||
"cove-net-common",
|
"cove-net-common",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@ -10,4 +10,3 @@ tokio.workspace = true
|
|||||||
cove-db.workspace = true
|
cove-db.workspace = true
|
||||||
sqlx.workspace = true
|
sqlx.workspace = true
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
scc.workspace = true
|
|
||||||
@ -2,14 +2,11 @@ use cove_net_server::message::middleware::auth::AuthTokenMiddleware;
|
|||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
use std::sync::{Arc};
|
use std::sync::{Arc};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use sqlx::{Execute, Executor};
|
|
||||||
use sqlx::postgres::PgQueryResult;
|
|
||||||
use sqlx::types::time::OffsetDateTime;
|
use sqlx::types::time::OffsetDateTime;
|
||||||
use cove_db::{CoveDB, CoveDBImpl};
|
use cove_db::CoveDB;
|
||||||
use cove_db::part::{BindQueryBuilder, SqlPart};
|
use cove_db::query::user::UserQueries;
|
||||||
use cove_db::part::condition::ConditionType;
|
use cove_db::rows::PartialTableRow;
|
||||||
use cove_db::rows::{InsertableRow, SelectableRow, TableRow, WhereRow};
|
use cove_db::rows::user::UserRow;
|
||||||
use cove_db::rows::user::{PartialUserRow, UserRow};
|
|
||||||
use cove_db::types::user_status::UserStatus;
|
use cove_db::types::user_status::UserStatus;
|
||||||
use cove_net_common::id::message_type::MessageType;
|
use cove_net_common::id::message_type::MessageType;
|
||||||
use cove_net_common::id::SnowflakeID;
|
use cove_net_common::id::SnowflakeID;
|
||||||
@ -27,55 +24,59 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||||||
db.run_migrations().await?;
|
db.run_migrations().await?;
|
||||||
db.run_system_migrations().await?;
|
db.run_system_migrations().await?;
|
||||||
|
|
||||||
// let user_row = UserRow {
|
let user_row = UserRow {
|
||||||
// id: SnowflakeID::new_random_hex_loc(MessageType::User, "beefcafe")?,
|
id: SnowflakeID::new_random_hex_loc(MessageType::User, "beefcafe")?,
|
||||||
// username: "CanadianBacon".to_string(),
|
username: "CanadianBacon".to_string(),
|
||||||
// discriminator: "0001".to_string(),
|
discriminator: "0001".to_string(),
|
||||||
// avatar_hash: None,
|
avatar_hash: None,
|
||||||
// email: "bc.bacon.bits@gmail.com".to_string(),
|
email: "bc.bacon.bits@gmail.com".to_string(),
|
||||||
// email_verified: true,
|
email_verified: true,
|
||||||
// password_hash: "1802vgu12890n7b489127".to_string(),
|
password_hash: "1802vgu12890n7b489127".to_string(),
|
||||||
// mfa_enabled: false,
|
mfa_enabled: false,
|
||||||
// mfa_secret: None,
|
mfa_secret: None,
|
||||||
// status: UserStatus::Online,
|
status: UserStatus::Online,
|
||||||
// public_flags: 0,
|
public_flags: 0,
|
||||||
// locale: "en-US".to_string(),
|
locale: "en-US".to_string(),
|
||||||
// premium_since: Some(OffsetDateTime::now_utc() + Duration::from_hours(1)),
|
premium_since: Some(OffsetDateTime::now_utc() + Duration::from_hours(1)),
|
||||||
// premium_end: Some(OffsetDateTime::now_utc() + Duration::from_hours(24)),
|
premium_end: Some(OffsetDateTime::now_utc() + Duration::from_hours(24)),
|
||||||
// bot: false,
|
bot: false,
|
||||||
// bot_oauth_scopes: Default::default(),
|
bot_oauth_scopes: Default::default(),
|
||||||
// preferences: Default::default(),
|
preferences: Default::default(),
|
||||||
// created_at: OffsetDateTime::now_utc(),
|
created_at: OffsetDateTime::now_utc(),
|
||||||
// updated_at: OffsetDateTime::now_utc(),
|
updated_at: OffsetDateTime::now_utc(),
|
||||||
// };
|
|
||||||
//
|
|
||||||
// let mut query_builder = BindQueryBuilder::new();
|
|
||||||
// user_row.insert().encode(&mut query_builder)?;
|
|
||||||
//
|
|
||||||
// let query = query_builder.to_query();
|
|
||||||
// let query = user_row.bind(query)?;
|
|
||||||
//
|
|
||||||
// let res = db.run_query::<PgQueryResult>(query.sql_query).await?;
|
|
||||||
// println!("{} rows affected", res.rows_affected());
|
|
||||||
|
|
||||||
let request_row: <UserRow as TableRow>::PartialRow = PartialUserRow {
|
|
||||||
username: Some("CanadianBacon".to_string()),
|
|
||||||
..Default::default()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut query_builder = BindQueryBuilder::new();
|
match db.create_user(user_row).await {
|
||||||
request_row.select(vec!["id", "username"]).encode(&mut query_builder)?;
|
Ok(result) => {
|
||||||
let sql_where = request_row.wheres(|w|{
|
println!("Create User: {} rows affected", result.result().as_ref().unwrap().rows_affected());
|
||||||
w.cond_and::<String>("username", ConditionType::Equal(false))
|
match db.get_user_by_name_and_discrim("CanadianBacon", "0001").await {
|
||||||
})?;
|
Ok(partial_user) => {
|
||||||
sql_where.encode(&mut query_builder)?;
|
match partial_user.value().get_full(&db).await {
|
||||||
|
Ok(full_user) => {
|
||||||
let query = request_row.bind(sql_where, query_builder.to_query())?;
|
match db.delete_user_by_id(full_user.id).await {
|
||||||
|
Ok(result) => {
|
||||||
println!("{}", query.sql_query.sql());
|
println!("Delete User: {} rows affected", result.result().as_ref().unwrap().rows_affected());
|
||||||
let out_partial_row: <UserRow as TableRow>::PartialRow = db.get_pool().fetch_one(query.sql_query).await?.into();
|
println!("{:?}", result.value());
|
||||||
|
}
|
||||||
println!("{:?}, {:?}, {:?}", out_partial_row.id, out_partial_row.username, out_partial_row.email);
|
Err(err) => {
|
||||||
|
println!("Failed to delete user: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
println!("Failed to get full user: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
println!("Failed to get user: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
println!("Failed to create user: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
http_testing(db).await?;
|
http_testing(db).await?;
|
||||||
|
|
||||||
|
|||||||
@ -8,5 +8,6 @@ sqlx.workspace = true
|
|||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
cove-db-macros.workspace = true
|
cove-db-macros.workspace = true
|
||||||
|
async-trait.workspace = true
|
||||||
|
|
||||||
cove-net-common.workspace = true
|
cove-net-common.workspace = true
|
||||||
@ -148,6 +148,10 @@ fn impl_derive_table_row(ast: DeriveInput) -> TokenStream {
|
|||||||
impl crate::rows::SelectableRow for #partial_name {}
|
impl crate::rows::SelectableRow for #partial_name {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let impl_deletable_row = quote! {
|
||||||
|
impl crate::rows::DeletableRow for #partial_name {}
|
||||||
|
};
|
||||||
|
|
||||||
let impl_where_row = {
|
let impl_where_row = {
|
||||||
let match_body = {
|
let match_body = {
|
||||||
let mut ret = quote!();
|
let mut ret = quote!();
|
||||||
@ -163,7 +167,26 @@ fn impl_derive_table_row(ast: DeriveInput) -> TokenStream {
|
|||||||
ret
|
ret
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let where_all_body = {
|
||||||
|
let mut ret = quote!();
|
||||||
|
for field in fields.named.iter() {
|
||||||
|
let name = field.ident.as_ref().unwrap();
|
||||||
|
let quoted_name = format!("{}", name);
|
||||||
|
let ty = &field.ty;
|
||||||
|
ret.extend(
|
||||||
quote! {
|
quote! {
|
||||||
|
if self.#name.is_some() {
|
||||||
|
wheres = wheres.cond_and::<#ty>(#quoted_name, ConditionType::Equal(false)).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
use crate::part::condition::ConditionType;
|
||||||
|
use crate::part::sql_where::SqlWhere;
|
||||||
impl crate::rows::WhereRow for #partial_name {
|
impl crate::rows::WhereRow for #partial_name {
|
||||||
fn bind<'a>(&'a self, wheres: crate::part::sql_where::SqlWhere, query: crate::part::BindQuery<'a>) -> Result<crate::part::BindQuery<'a>, Self::Error> {
|
fn bind<'a>(&'a self, wheres: crate::part::sql_where::SqlWhere, query: crate::part::BindQuery<'a>) -> Result<crate::part::BindQuery<'a>, Self::Error> {
|
||||||
let mut query = query;
|
let mut query = query;
|
||||||
@ -175,9 +198,13 @@ fn impl_derive_table_row(ast: DeriveInput) -> TokenStream {
|
|||||||
}
|
}
|
||||||
Ok(query)
|
Ok(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn where_all(&self) -> SqlWhere {
|
||||||
|
let mut wheres = SqlWhere::new();
|
||||||
|
#where_all_body
|
||||||
|
wheres
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -247,7 +274,9 @@ fn impl_derive_table_row(ast: DeriveInput) -> TokenStream {
|
|||||||
ret.extend(struct_partial_row);
|
ret.extend(struct_partial_row);
|
||||||
ret.extend(impl_table_row);
|
ret.extend(impl_table_row);
|
||||||
ret.extend(impl_partial_table_row);
|
ret.extend(impl_partial_table_row);
|
||||||
|
// ret.extend(impl_deletable_row);
|
||||||
ret.extend(impl_insertable_row);
|
ret.extend(impl_insertable_row);
|
||||||
|
ret.extend(impl_deletable_row);
|
||||||
ret.extend(impl_selectable_row);
|
ret.extend(impl_selectable_row);
|
||||||
ret.extend(impl_where_row);
|
ret.extend(impl_where_row);
|
||||||
ret.extend(impl_try_from_pgrow_for_full);
|
ret.extend(impl_try_from_pgrow_for_full);
|
||||||
|
|||||||
@ -4,6 +4,7 @@ pub mod part;
|
|||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use async_trait::async_trait;
|
||||||
use sqlx::{PgConnection, PgPool, Postgres};
|
use sqlx::{PgConnection, PgPool, Postgres};
|
||||||
use sqlx::migrate::Migrator;
|
use sqlx::migrate::Migrator;
|
||||||
use sqlx::postgres::{PgArguments, PgConnectOptions, PgPoolOptions, PgQueryResult};
|
use sqlx::postgres::{PgArguments, PgConnectOptions, PgPoolOptions, PgQueryResult};
|
||||||
@ -65,6 +66,7 @@ impl CoveDBImpl for CoveDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
pub trait CoveDBImpl {
|
pub trait CoveDBImpl {
|
||||||
fn get_pool(&self) -> &PgPool;
|
fn get_pool(&self) -> &PgPool;
|
||||||
|
|
||||||
|
|||||||
21
cove-db/src/part/delete.rs
Normal file
21
cove-db/src/part/delete.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::part::{BindQueryBuilder, SqlPart};
|
||||||
|
|
||||||
|
pub struct SqlDelete {
|
||||||
|
table_name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SqlDelete {
|
||||||
|
pub fn with_table(table_name: impl Into<String>) -> SqlDelete {
|
||||||
|
SqlDelete {table_name: table_name.into()}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SqlPart for SqlDelete {
|
||||||
|
fn encode(&self, query_builder: &mut BindQueryBuilder) -> Result<(), anyhow::Error> {
|
||||||
|
query_builder.push("DELETE FROM ");
|
||||||
|
query_builder.push(&self.table_name);
|
||||||
|
query_builder.push(" ");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ pub mod condition;
|
|||||||
pub mod select;
|
pub mod select;
|
||||||
pub mod sql_where;
|
pub mod sql_where;
|
||||||
pub mod insert;
|
pub mod insert;
|
||||||
|
pub mod delete;
|
||||||
|
|
||||||
pub trait SqlPart {
|
pub trait SqlPart {
|
||||||
fn encode(&self, arg_buffer: &mut BindQueryBuilder) -> Result<(), anyhow::Error>;
|
fn encode(&self, arg_buffer: &mut BindQueryBuilder) -> Result<(), anyhow::Error>;
|
||||||
|
|||||||
@ -4,6 +4,9 @@ use sqlx::{Encode, Postgres, Type};
|
|||||||
use crate::part::condition::{ConditionJoin, ConditionType, SqlCondition};
|
use crate::part::condition::{ConditionJoin, ConditionType, SqlCondition};
|
||||||
use crate::part::{BindQueryBuilder, SqlPart};
|
use crate::part::{BindQueryBuilder, SqlPart};
|
||||||
|
|
||||||
|
unsafe impl Send for SqlWhere {}
|
||||||
|
unsafe impl Sync for SqlWhere {}
|
||||||
|
|
||||||
pub struct SqlWhere {
|
pub struct SqlWhere {
|
||||||
selected_scope: Arc<Mutex<SqlWhereScope>>,
|
selected_scope: Arc<Mutex<SqlWhereScope>>,
|
||||||
pub indexed_placeholders: Vec<(usize, String)>,
|
pub indexed_placeholders: Vec<(usize, String)>,
|
||||||
|
|||||||
@ -1 +1,48 @@
|
|||||||
pub mod text;
|
use sqlx::postgres::PgQueryResult;
|
||||||
|
use crate::rows::{PartialTableRow, TableRow};
|
||||||
|
|
||||||
|
pub mod user;
|
||||||
|
|
||||||
|
pub struct PartialQueryResult<T: PartialTableRow> {
|
||||||
|
value: T,
|
||||||
|
pg_query_result: Option<PgQueryResult>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: PartialTableRow> PartialQueryResult<T> {
|
||||||
|
pub fn new(value: T, pg_query_result: Option<PgQueryResult>) -> Self {
|
||||||
|
PartialQueryResult {
|
||||||
|
value,
|
||||||
|
pg_query_result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self) -> &T {
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn result(&self) -> &Option<PgQueryResult> {
|
||||||
|
&self.pg_query_result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct QueryResult<T: TableRow> {
|
||||||
|
value: T,
|
||||||
|
pg_query_result: Option<PgQueryResult>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: TableRow> QueryResult<T> {
|
||||||
|
pub fn new(value: T, pg_query_result: Option<PgQueryResult>) -> Self {
|
||||||
|
QueryResult {
|
||||||
|
value,
|
||||||
|
pg_query_result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self) -> &T {
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn result(&self) -> &Option<PgQueryResult> {
|
||||||
|
&self.pg_query_result
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,59 +0,0 @@
|
|||||||
use anyhow::{Error};
|
|
||||||
use sqlx::{Execute};
|
|
||||||
use sqlx::postgres::{ PgQueryResult};
|
|
||||||
use cove_net_common::id::message_type::MessageType;
|
|
||||||
use cove_net_common::id::SnowflakeID;
|
|
||||||
use cove_net_common::id::types::text::TextMessageType;
|
|
||||||
use cove_net_common::message::c2s::text::text::{TextEmbed, TextMessage};
|
|
||||||
use crate::{CoveDB, CoveDBImpl};
|
|
||||||
use crate::part::{BindQueryBuilder, SqlPart};
|
|
||||||
use crate::part::insert::SqlInsert;
|
|
||||||
|
|
||||||
pub trait TextQueries: CoveDBImpl + Send + Sync {
|
|
||||||
async fn create_message(
|
|
||||||
&self, user_id: SnowflakeID,
|
|
||||||
message: TextMessage, mentions: Option<Vec<SnowflakeID>>, mention_everyone: bool,
|
|
||||||
message_type: &TextMessageType
|
|
||||||
) -> Result<PgQueryResult, Error> {
|
|
||||||
println!("creating message");
|
|
||||||
let message_id = SnowflakeID::new_random_hex_loc(
|
|
||||||
MessageType::Text(TextMessageType::Text), "beefcafe"
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let mut query_builder = BindQueryBuilder::new();
|
|
||||||
|
|
||||||
SqlInsert::with_table("messages")
|
|
||||||
.col::<SnowflakeID>("id")
|
|
||||||
.col::<SnowflakeID>("channel_id")
|
|
||||||
.col::<SnowflakeID>("guild_id")
|
|
||||||
.col::<SnowflakeID>("author_id")
|
|
||||||
.col::<String>("content")
|
|
||||||
.col::<bool>("tts")
|
|
||||||
.col::<bool>("mention_everyone")
|
|
||||||
.col::<TextMessageType>("message_type")
|
|
||||||
.opt_arr_col::<SnowflakeID>("mentions")
|
|
||||||
.opt_arr_col::<TextEmbed>("embeds")
|
|
||||||
.opt_arr_col::<SnowflakeID>("attachments")
|
|
||||||
.encode(&mut query_builder)?;
|
|
||||||
|
|
||||||
let query = query_builder.to_query().build()
|
|
||||||
.bind(message_id)
|
|
||||||
.bind(message.channel_id)
|
|
||||||
.bind(message.guild_id)
|
|
||||||
.bind(user_id)
|
|
||||||
.bind(message.content)
|
|
||||||
.bind(message.tts)
|
|
||||||
.bind(mention_everyone)
|
|
||||||
.bind(message_type)
|
|
||||||
.bind(mentions)
|
|
||||||
.bind(message.embeds)
|
|
||||||
.bind(message.attachments);
|
|
||||||
|
|
||||||
println!("{:?}", query.sql());
|
|
||||||
let res: PgQueryResult = self.run_query(query).await?;
|
|
||||||
println!("Rows Affected: {}", res.rows_affected());
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextQueries for CoveDB {}
|
|
||||||
91
cove-db/src/query/user.rs
Normal file
91
cove-db/src/query/user.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
use sqlx::Executor;
|
||||||
|
use sqlx::postgres::PgQueryResult;
|
||||||
|
use cove_net_common::id::SnowflakeID;
|
||||||
|
use crate::{CoveDB, CoveDBImpl};
|
||||||
|
use crate::part::{BindQueryBuilder, SqlPart};
|
||||||
|
use crate::query::{PartialQueryResult, QueryResult};
|
||||||
|
use crate::rows::{DeletableRow, InsertableRow, SelectableRow, TableRow, WhereRow};
|
||||||
|
use crate::rows::user::{PartialUserRow, UserRow};
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait UserQueries: CoveDBImpl {
|
||||||
|
async fn create_user(&self, user_row: UserRow) -> Result<QueryResult<UserRow>, anyhow::Error> {
|
||||||
|
let mut query_builder = BindQueryBuilder::new();
|
||||||
|
user_row.insert().encode(&mut query_builder)?;
|
||||||
|
|
||||||
|
let query = query_builder.to_query();
|
||||||
|
let query = user_row.bind(query)?;
|
||||||
|
|
||||||
|
let res = self.run_query::<PgQueryResult>(query.sql_query).await?;
|
||||||
|
|
||||||
|
Ok(QueryResult::new(user_row, Some(res)))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_user_by_name_and_discrim(&self, name: impl Into<String> + Send, discriminator: impl Into<String> + Send) -> Result<PartialQueryResult<PartialUserRow>, anyhow::Error> {
|
||||||
|
let user_request_row = PartialUserRow {
|
||||||
|
username: Some(name.into()),
|
||||||
|
discriminator: Some(discriminator.into()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut query_builder = BindQueryBuilder::new();
|
||||||
|
user_request_row.select(vec!["id", "username", "discriminator"]).encode(&mut query_builder)?;
|
||||||
|
let sql_where = user_request_row.where_all();
|
||||||
|
sql_where.encode(&mut query_builder)?;
|
||||||
|
|
||||||
|
let query = user_request_row.bind(sql_where, query_builder.to_query())?;
|
||||||
|
|
||||||
|
let out_partial_row: <UserRow as TableRow>::PartialRow = self.get_pool().fetch_one(query.sql_query).await?.into();
|
||||||
|
|
||||||
|
Ok(PartialQueryResult::new(out_partial_row, None))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_user_by_id(&self, user_id: SnowflakeID) -> Result<PartialQueryResult<PartialUserRow>, anyhow::Error> {
|
||||||
|
let user_request_row = PartialUserRow {
|
||||||
|
id: Some(user_id),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut query_builder = BindQueryBuilder::new();
|
||||||
|
user_request_row.select(vec!["id", "username", "discriminator"]).encode(&mut query_builder)?;
|
||||||
|
let sql_where = user_request_row.where_all();
|
||||||
|
sql_where.encode(&mut query_builder)?;
|
||||||
|
|
||||||
|
let query = user_request_row.bind(sql_where, query_builder.to_query())?;
|
||||||
|
|
||||||
|
let out_partial_row: <UserRow as TableRow>::PartialRow = self.get_pool().fetch_one(query.sql_query).await?.into();
|
||||||
|
|
||||||
|
Ok(PartialQueryResult::new(out_partial_row, None))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn delete_user_by_id(&self, user_id: SnowflakeID) -> Result<QueryResult<UserRow>, anyhow::Error> {
|
||||||
|
let user_delete_row = PartialUserRow {
|
||||||
|
id: Some(user_id),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut query_builder = BindQueryBuilder::new();
|
||||||
|
user_delete_row.select(vec!["*"]).encode(&mut query_builder)?;
|
||||||
|
let sql_where = user_delete_row.where_all();
|
||||||
|
sql_where.encode(&mut query_builder)?;
|
||||||
|
let query = user_delete_row.bind(sql_where, query_builder.to_query())?;
|
||||||
|
|
||||||
|
let out_val: UserRow = self.get_pool().fetch_one(query.sql_query).await?.try_into()?;
|
||||||
|
|
||||||
|
let mut query_builder = BindQueryBuilder::new();
|
||||||
|
|
||||||
|
user_delete_row.delete().encode(&mut query_builder)?;
|
||||||
|
let sql_where = user_delete_row.where_all();
|
||||||
|
sql_where.encode(&mut query_builder)?;
|
||||||
|
|
||||||
|
let query = user_delete_row.bind(sql_where, query_builder.to_query())?;
|
||||||
|
|
||||||
|
let res = self.run_query::<PgQueryResult>(query.sql_query).await?;
|
||||||
|
|
||||||
|
Ok(QueryResult::new(out_val, Some(res)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl UserQueries for CoveDB {}
|
||||||
@ -1,4 +1,9 @@
|
|||||||
use crate::part::BindQuery;
|
use async_trait::async_trait;
|
||||||
|
use sqlx::Executor;
|
||||||
|
use sqlx::postgres::PgRow;
|
||||||
|
use crate::{CoveDB, CoveDBImpl};
|
||||||
|
use crate::part::{BindQuery, BindQueryBuilder, SqlPart};
|
||||||
|
use crate::part::delete::SqlDelete;
|
||||||
use crate::part::insert::SqlInsert;
|
use crate::part::insert::SqlInsert;
|
||||||
use crate::part::select::SqlSelect;
|
use crate::part::select::SqlSelect;
|
||||||
use crate::part::sql_where::SqlWhere;
|
use crate::part::sql_where::SqlWhere;
|
||||||
@ -17,12 +22,33 @@ pub trait TableRow {
|
|||||||
fn get_table_name() -> &'static str;
|
fn get_table_name() -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
pub trait PartialTableRow {
|
pub trait PartialTableRow {
|
||||||
type Error;
|
type Error;
|
||||||
type FullTableRow: TableRow;
|
type FullTableRow: TableRow;
|
||||||
fn get_table_name() -> &'static str {
|
fn get_table_name() -> &'static str {
|
||||||
Self::FullTableRow::get_table_name()
|
Self::FullTableRow::get_table_name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_full(&self, db: &CoveDB) -> Result<Self::FullTableRow, Self::Error> where
|
||||||
|
Self: SelectableRow + WhereRow,
|
||||||
|
<Self as PartialTableRow>::Error: From<anyhow::Error>,
|
||||||
|
Self::FullTableRow: TryFrom<PgRow>,
|
||||||
|
<<Self as PartialTableRow>::FullTableRow as TryFrom<PgRow>>::Error: Into<anyhow::Error>
|
||||||
|
{
|
||||||
|
let mut query_builder = BindQueryBuilder::new();
|
||||||
|
self.select(vec!["*"]).encode(&mut query_builder)?;
|
||||||
|
let sql_where = self.where_all();
|
||||||
|
sql_where.encode(&mut query_builder)?;
|
||||||
|
|
||||||
|
let query = self.bind(sql_where, query_builder.to_query())?;
|
||||||
|
|
||||||
|
let out_full_row: Self::FullTableRow = db.get_pool()
|
||||||
|
.fetch_one(query.sql_query).await.map_err(|e|e.into())?
|
||||||
|
.try_into().map_err(|e: <Self::FullTableRow as TryFrom<PgRow>>::Error | e.into())?;
|
||||||
|
|
||||||
|
Ok(out_full_row)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InsertableRow: TableRow {
|
pub trait InsertableRow: TableRow {
|
||||||
@ -40,12 +66,20 @@ pub trait SelectableRow: PartialTableRow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait DeletableRow: PartialTableRow {
|
||||||
|
fn delete(&'_ self) -> SqlDelete {
|
||||||
|
SqlDelete::with_table(Self::get_table_name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait WhereRow: PartialTableRow {
|
pub trait WhereRow: PartialTableRow {
|
||||||
fn wheres(&'_ self, where_fn: impl Fn(SqlWhere) -> Result<SqlWhere, Self::Error>) -> Result<SqlWhere, Self::Error> {
|
fn wheres(&'_ self, where_fn: impl Fn(SqlWhere) -> Result<SqlWhere, Self::Error> + Send + Sync) -> Result<SqlWhere, Self::Error> {
|
||||||
let wheres = SqlWhere::new();
|
let wheres = SqlWhere::new();
|
||||||
let wheres = where_fn(wheres)?;
|
let wheres = where_fn(wheres)?;
|
||||||
Ok(wheres)
|
Ok(wheres)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn where_all(&'_ self) -> SqlWhere;
|
||||||
|
|
||||||
fn bind<'a>(&'a self, wheres: SqlWhere, query: BindQuery<'a>) -> Result<BindQuery<'a>, Self::Error>;
|
fn bind<'a>(&'a self, wheres: SqlWhere, query: BindQuery<'a>) -> Result<BindQuery<'a>, Self::Error>;
|
||||||
}
|
}
|
||||||
@ -4,7 +4,7 @@ use cove_db_macros::DeriveTableRow;
|
|||||||
use cove_net_common::id::SnowflakeID;
|
use cove_net_common::id::SnowflakeID;
|
||||||
use crate::types::user_status::UserStatus;
|
use crate::types::user_status::UserStatus;
|
||||||
|
|
||||||
#[derive(DeriveTableRow)]
|
#[derive(DeriveTableRow, Debug)]
|
||||||
#[table_name("users")]
|
#[table_name("users")]
|
||||||
pub struct UserRow {
|
pub struct UserRow {
|
||||||
pub id: SnowflakeID,
|
pub id: SnowflakeID,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use sqlx::encode::IsNull;
|
|||||||
use sqlx::error::BoxDynError;
|
use sqlx::error::BoxDynError;
|
||||||
use sqlx::postgres::PgTypeInfo;
|
use sqlx::postgres::PgTypeInfo;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum UserStatus {
|
pub enum UserStatus {
|
||||||
Online,
|
Online,
|
||||||
Idle,
|
Idle,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
pub mod message;
|
pub mod message;
|
||||||
|
|
||||||
use cove_db::CoveDB;
|
use cove_db::CoveDB;
|
||||||
use std::any::{Any, TypeId};
|
use std::any::Any;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::net::{IpAddr, SocketAddr};
|
use std::net::{IpAddr, SocketAddr};
|
||||||
use http_body_util::{BodyExt, Full};
|
use http_body_util::{BodyExt, Full};
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
use hyper::body::Buf;
|
|
||||||
use http_body_util::BodyExt;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response};
|
use hyper::Response;
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use cove_net_common::message::c2s::account::login::LoginMessage;
|
use cove_net_common::message::c2s::account::login::LoginMessage;
|
||||||
use cove_net_common::message::c2s::ClientToServerMessage;
|
use cove_net_common::message::c2s::ClientToServerMessage;
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
use hyper::body::Buf;
|
|
||||||
use http_body_util::BodyExt;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response};
|
use hyper::Response;
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use cove_net_common::message::c2s::account::register::RegisterMessage;
|
use cove_net_common::message::c2s::account::register::RegisterMessage;
|
||||||
use cove_net_common::message::c2s::ClientToServerMessage;
|
use cove_net_common::message::c2s::ClientToServerMessage;
|
||||||
|
|||||||
@ -2,8 +2,8 @@ use std::collections::VecDeque;
|
|||||||
use anyhow::{Error};
|
use anyhow::{Error};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response};
|
use hyper::Response;
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use cove_net_common::message::c2s::ClientToServerMessage;
|
use cove_net_common::message::c2s::ClientToServerMessage;
|
||||||
use crate::message::handlers::base::middleware::{AssociatedDataMap};
|
use crate::message::handlers::base::middleware::{AssociatedDataMap};
|
||||||
|
|||||||
@ -2,8 +2,8 @@ use std::any::{Any, TypeId};
|
|||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response};
|
use hyper::Response;
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use crate::message::StdHashMap;
|
use crate::message::StdHashMap;
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
use std::any::{Any, TypeId};
|
use std::any::TypeId;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response};
|
use hyper::Response;
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use scc::HashMap;
|
use scc::HashMap;
|
||||||
use crate::message::handlers::base::handler::CoveRequestHandler;
|
use crate::message::handlers::base::handler::CoveRequestHandler;
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
use hyper::body::Buf;
|
|
||||||
use http_body_util::BodyExt;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response};
|
use hyper::Response;
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use cove_net_common::message::c2s::ClientToServerMessage;
|
use cove_net_common::message::c2s::ClientToServerMessage;
|
||||||
use cove_net_common::message::c2s::text::attachment::AttachmentMessage;
|
use cove_net_common::message::c2s::text::attachment::AttachmentMessage;
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
use hyper::body::Buf;
|
|
||||||
use http_body_util::BodyExt;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response};
|
use hyper::Response;
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use cove_net_common::message::c2s::ClientToServerMessage;
|
use cove_net_common::message::c2s::ClientToServerMessage;
|
||||||
use cove_net_common::message::c2s::text::reaction::ReactionMessage;
|
use cove_net_common::message::c2s::text::reaction::ReactionMessage;
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
use hyper::body::Buf;
|
|
||||||
use http_body_util::BodyExt;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response};
|
use hyper::Response;
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use cove_net_common::message::c2s::ClientToServerMessage;
|
use cove_net_common::message::c2s::ClientToServerMessage;
|
||||||
use cove_net_common::message::c2s::text::text::TextMessage;
|
use cove_net_common::message::c2s::text::text::TextMessage;
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
use std::any::TypeId;
|
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use hyper::body::{Bytes, Incoming};
|
use hyper::body::Bytes;
|
||||||
use hyper::{Request, Response, StatusCode};
|
use hyper::{Response, StatusCode};
|
||||||
use hyper::http::request::Parts;
|
use hyper::http::request::Parts;
|
||||||
use cove_net_common::id::message_type::MessageType;
|
use cove_net_common::id::message_type::MessageType;
|
||||||
use cove_net_common::id::SnowflakeID;
|
use cove_net_common::id::SnowflakeID;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user