-
Hello everyone, I am new to rust and want to implement some general methods, but I have encountered the following problems, I don't quite understand, I hope I can get your help~ use sqlx::{Error, MySql, Pool};
pub(crate) trait Entity {
fn entity_table_name() -> &'static str;
}
#[inline]
pub async fn find_all<DB, O>(session: Pool<MySql>) -> Result<Vec<O>, Error>
where
DB: sqlx::Database,
O: Entity + for<'r> sqlx::FromRow<'r, DB::Row>,
{
let name = O::entity_table_name();
return sqlx::query_as::<DB, O>(r#"select * from ?"#)
.bind(name)
.fetch_all()
.await;
}
output error[E0277]: the size for values of type `str` cannot be known at compilation time
--> crates/entity/src/method.rs:14:15
|
14 | .bind(name)
| ---- ^^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
= help: the trait `Sized` is not implemented for `str`
= help: the following other types implement trait `Encode<'q, DB>`:
<&'q str as Encode<'q, sqlx_core::any::database::Any>>
<&str as Encode<'_, MySql>>
<&str as Encode<'_, Postgres>>
<std::string::String as Encode<'_, MySql>>
<std::string::String as Encode<'_, Postgres>>
<std::string::String as Encode<'q, sqlx_core::any::database::Any>>
= note: required because of the requirements on the impl of `Encode<'_, DB>` for `&str`
note: required by a bound in `QueryAs::<'q, DB, O, <DB as HasArguments<'q>>::Arguments>::bind`
--> /Users/cf/.cargo/registry/src/rsproxy.cn-8f6827c7555bfaf8/sqlx-core-0.6.1/src/query_as.rs:54:32
|
54 | pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
| ^^^^^^^^^^^^^^ required by this bound in `QueryAs::<'q, DB, O, <DB as HasArguments<'q>>::Arguments>::bind` then,I tried to remove the entity logic, but it still doesn't work use sqlx::{Error, MySql, Pool};
pub(crate) trait Entity {
fn entity_table_name() -> &'static str;
}
#[inline]
pub async fn find_all<DB, O>(session: Pool<MySql>) -> Result<Vec<O>, Error>
where
DB: sqlx::Database,
O:for<'r> sqlx::FromRow<'r, DB::Row>,
{
//let name = O::entity_table_name();
return sqlx::query_as::<DB, O>(r#"select * from ?"#)
// .bind(name)
.fetch_all()
.await;
} output error[E0599]: the method `fetch_all` exists for struct `QueryAs<'_, DB, O, <DB as HasArguments<'_>>::Arguments>`, but its trait bounds were not satisfied
--> crates/entity/src/method.rs:15:10
|
15 | .fetch_all()
| ^^^^^^^^^ method cannot be called on `QueryAs<'_, DB, O, <DB as HasArguments<'_>>::Arguments>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`<DB as HasArguments<'_>>::Arguments: IntoArguments<DB>`
`O: Send`
`O: Unpin`
I think, is my where condition wrong? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I see a few issues:
I haven't used mysql in years but I think this will work for you: use sqlx::{Error, MySql, Pool};
pub trait Entity {
fn entity_table_name() -> &'static str;
}
#[inline]
pub async fn find_all<O>(session: &Pool<MySql>) -> Result<Vec<O>, Error>
where
O: Entity + for<'r> sqlx::FromRow<'r, <MySql as Database>::Row> + Unpin + Send,
{
let name = O::entity_table_name();
return sqlx::query_as::<MySql, O>(&format!("select * from `{}`", name))
.fetch_all(session)
.await;
}
#[sqlx::test]
async fn test_find_all(db: MySqlPool) {
#[derive(PartialEq, Debug, sqlx::FromRow)]
struct Prj {
id: i64,
}
impl Entity for Prj {
fn entity_table_name() -> &'static str {
"projects"
}
}
let prjs = find_all::<Prj>(&db).await.unwrap();
assert_eq!(prjs, vec![]);
} If I could offer you my opinion though, I wouldn't go this route. I think you'll find there is very little to gain from building an entity trait like this; you are barely encoding any common behavior, and really just adding indirection. Plus you'll find that with I would recommend instead using the macros like |
Beta Was this translation helpful? Give feedback.
I see a few issues:
query_as("").fetch_all()
expects an executor for executing the query. In your case, you'd pass in a reference to the pool:fetch_all(&session)
.DB
is a generic type param, you either want to make things generic overDB
everywhere or just commit to usingMySql
as you've done in the session type. For simplicity I think you should just useMySql
.O
also needs to beSend
andUnpin
.MySql as HasArguments
does not implement arguments forstr
, you'd have to useString
.