Merge pull request #39 from SeaQL/improve-doc-test

Improve doc test
This commit is contained in:
Chris Tsang 2021-07-13 20:14:58 +08:00 committed by GitHub
commit b5f4d69c3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 259 additions and 42 deletions

View File

@ -247,6 +247,7 @@ where
exec.await exec.await
} }
/// Delete an active model by its primary key
pub async fn delete_active_model<A, E>( pub async fn delete_active_model<A, E>(
mut am: A, mut am: A,
db: &DatabaseConnection, db: &DatabaseConnection,

View File

@ -18,7 +18,18 @@ pub trait EntityName: IdenStatic + Default {
Self::table_name(self) Self::table_name(self)
} }
} }
/// Each table in database correspond to a Entity implemented [`EntityTrait`].
///
/// This trait provides an API for you to inspect it's properties
/// - Column (implemented [`ColumnTrait`])
/// - Relation (implemented [`RelationTrait`])
/// - Primary Key (implemented [`PrimaryKeyTrait`] and [`PrimaryKeyToColumn`])
///
/// This trait also provides an API for CRUD actions
/// - Select: `find`, `find_*`
/// - Insert: `insert`, `insert_*`
/// - Update: `update`, `update_*`
/// - Delete: `delete`, `delete_*`
pub trait EntityTrait: EntityName { pub trait EntityTrait: EntityName {
type Model: ModelTrait<Entity = Self> + FromQueryResult; type Model: ModelTrait<Entity = Self> + FromQueryResult;
@ -49,16 +60,66 @@ pub trait EntityTrait: EntityName {
RelationBuilder::from_rel(RelationType::HasMany, R::to().rev()) RelationBuilder::from_rel(RelationType::HasMany, R::to().rev())
} }
/// Construct select statement to find one / all models
///
/// - To select columns, join tables and group by expressions, see [`QuerySelect`](crate::query::QuerySelect)
/// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)
/// - To apply order by expressions, see [`QueryOrder`](crate::query::QueryOrder)
///
/// # Example
///
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_query_results(vec![
/// # vec![
/// # cake::Model {
/// # id: 1,
/// # name: "New York Cheese".to_owned(),
/// # },
/// # ],
/// # vec![
/// # cake::Model {
/// # id: 1,
/// # name: "New York Cheese".to_owned(),
/// # },
/// # cake::Model {
/// # id: 2,
/// # name: "Chocolate Forest".to_owned(),
/// # },
/// # ],
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::cake}; /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// cake::Entity::find().one(&db).await; /// #
/// cake::Entity::find().all(&db).await; /// assert_eq!(
/// cake::Entity::find().one(&db).await?,
/// Some(cake::Model {
/// id: 1,
/// name: "New York Cheese".to_owned(),
/// })
/// );
///
/// assert_eq!(
/// cake::Entity::find().all(&db).await?,
/// vec![
/// cake::Model {
/// id: 1,
/// name: "New York Cheese".to_owned(),
/// },
/// cake::Model {
/// id: 2,
/// name: "Chocolate Forest".to_owned(),
/// },
/// ]
/// );
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(
@ -77,15 +138,37 @@ pub trait EntityTrait: EntityName {
} }
/// Find a model by primary key /// Find a model by primary key
///
/// # Example
///
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_query_results(vec![
/// # vec![
/// # cake::Model {
/// # id: 11,
/// # name: "Sponge Cake".to_owned(),
/// # },
/// # ],
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::cake}; /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// cake::Entity::find_by_id(11).all(&db).await; /// #
/// assert_eq!(
/// cake::Entity::find_by_id(11).all(&db).await?,
/// vec![cake::Model {
/// id: 11,
/// name: "Sponge Cake".to_owned(),
/// }]
/// );
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(
@ -97,13 +180,32 @@ pub trait EntityTrait: EntityName {
/// Find by composite key /// Find by composite key
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_query_results(vec![
/// # vec![
/// # cake_filling::Model {
/// # cake_id: 2,
/// # filling_id: 3,
/// # },
/// # ],
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::cake_filling}; /// use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// cake_filling::Entity::find_by_id((2, 3)).all(&db).await; /// #
/// assert_eq!(
/// cake_filling::Entity::find_by_id((2, 3)).all(&db).await?,
/// vec![cake_filling::Model {
/// cake_id: 2,
/// filling_id: 3,
/// }]
/// );
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(
@ -135,10 +237,22 @@ pub trait EntityTrait: EntityName {
select select
} }
/// Insert an model into database
///
/// # Example
///
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, MockExecResult, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_exec_results(vec![
/// # MockExecResult {
/// # last_insert_id: 15,
/// # rows_affected: 1,
/// # },
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::cake}; /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
/// ///
@ -147,8 +261,14 @@ pub trait EntityTrait: EntityName {
/// ..Default::default() /// ..Default::default()
/// }; /// };
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// cake::Entity::insert(apple).exec(&db).await; /// #
/// let insert_result = cake::Entity::insert(apple).exec(&db).await?;
///
/// assert_eq!(insert_result.last_insert_id, 15);
/// // assert_eq!(insert_result.rows_affected, 1);
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(
@ -164,10 +284,22 @@ pub trait EntityTrait: EntityName {
Insert::one(model) Insert::one(model)
} }
/// Insert many models into database
///
/// # Example
///
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, MockExecResult, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_exec_results(vec![
/// # MockExecResult {
/// # last_insert_id: 28,
/// # rows_affected: 2,
/// # },
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::cake}; /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
/// ///
@ -180,8 +312,14 @@ pub trait EntityTrait: EntityName {
/// ..Default::default() /// ..Default::default()
/// }; /// };
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// cake::Entity::insert_many(vec![apple, orange]).exec(&db).await; /// #
/// let insert_result = cake::Entity::insert_many(vec![apple, orange]).exec(&db).await?;
///
/// assert_eq!(insert_result.last_insert_id, 28);
/// // assert_eq!(insert_result.rows_affected, 2);
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(
@ -199,10 +337,24 @@ pub trait EntityTrait: EntityName {
Insert::many(models) Insert::many(models)
} }
/// Update an model in database
///
/// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)
///
/// # Example
///
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, MockExecResult, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_exec_results(vec![
/// # MockExecResult {
/// # last_insert_id: 0,
/// # rows_affected: 1,
/// # },
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::fruit}; /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
/// ///
@ -212,8 +364,14 @@ pub trait EntityTrait: EntityName {
/// ..Default::default() /// ..Default::default()
/// }; /// };
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// fruit::Entity::update(orange).exec(&db).await; /// #
/// assert_eq!(
/// fruit::Entity::update(orange.clone()).exec(&db).await?, // Clone here because we need to assert_eq
/// orange
/// );
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(
@ -229,19 +387,38 @@ pub trait EntityTrait: EntityName {
Update::one(model) Update::one(model)
} }
/// Update many models in database
///
/// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)
///
/// # Example
///
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, MockExecResult, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_exec_results(vec![
/// # MockExecResult {
/// # last_insert_id: 0,
/// # rows_affected: 5,
/// # },
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::fruit, sea_query::{Expr, Value}}; /// use sea_orm::{entity::*, query::*, tests_cfg::fruit, sea_query::{Expr, Value}};
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// fruit::Entity::update_many() /// #
/// let update_result = fruit::Entity::update_many()
/// .col_expr(fruit::Column::CakeId, Expr::value(Value::Null)) /// .col_expr(fruit::Column::CakeId, Expr::value(Value::Null))
/// .filter(fruit::Column::Name.contains("Apple")) /// .filter(fruit::Column::Name.contains("Apple"))
/// .exec(&db) /// .exec(&db)
/// .await; /// .await?;
///
/// assert_eq!(update_result.rows_affected, 5);
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(
@ -254,10 +431,24 @@ pub trait EntityTrait: EntityName {
Update::many(Self::default()) Update::many(Self::default())
} }
/// Delete an model from database
///
/// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)
///
/// # Example
///
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, MockExecResult, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_exec_results(vec![
/// # MockExecResult {
/// # last_insert_id: 0,
/// # rows_affected: 1,
/// # },
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::fruit}; /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
/// ///
@ -266,8 +457,13 @@ pub trait EntityTrait: EntityName {
/// ..Default::default() /// ..Default::default()
/// }; /// };
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// fruit::Entity::delete(orange).exec(&db).await; /// #
/// let delete_result = fruit::Entity::delete(orange).exec(&db).await?;
///
/// assert_eq!(delete_result.rows_affected, 1);
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(
@ -283,18 +479,37 @@ pub trait EntityTrait: EntityName {
Delete::one(model) Delete::one(model)
} }
/// Delete many models from database
///
/// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)
///
/// # Example
///
/// ``` /// ```
/// # #[cfg(feature = "mock")] /// # #[cfg(feature = "mock")]
/// # use sea_orm::{MockDatabase, Transaction}; /// # use sea_orm::{error::*, MockDatabase, MockExecResult, Transaction, tests_cfg::*};
/// # let db = MockDatabase::new().into_connection(); /// #
/// # let db = MockDatabase::new()
/// # .append_exec_results(vec![
/// # MockExecResult {
/// # last_insert_id: 0,
/// # rows_affected: 5,
/// # },
/// # ])
/// # .into_connection();
/// # /// #
/// use sea_orm::{entity::*, query::*, tests_cfg::fruit}; /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
/// ///
/// # async_std::task::block_on(async { /// # let _: Result<(), DbErr> = async_std::task::block_on(async {
/// fruit::Entity::delete_many() /// #
/// let delete_result = fruit::Entity::delete_many()
/// .filter(fruit::Column::Name.contains("Apple")) /// .filter(fruit::Column::Name.contains("Apple"))
/// .exec(&db) /// .exec(&db)
/// .await; /// .await?;
///
/// assert_eq!(delete_result.rows_affected, 5);
/// #
/// # Ok(())
/// # }); /// # });
/// ///
/// assert_eq!( /// assert_eq!(

View File

@ -66,6 +66,7 @@ macro_rules! bind_vec_func {
} }
// LINT: when the operand value does not match column type // LINT: when the operand value does not match column type
/// Wrapper of the identically named method in [`sea_query::Expr`]
pub trait ColumnTrait: IdenStatic + Iterable { pub trait ColumnTrait: IdenStatic + Iterable {
type EntityName: EntityName; type EntityName: EntityName;

View File

@ -177,9 +177,9 @@
//! Licensed under either of //! Licensed under either of
//! //!
//! - Apache License, Version 2.0 //! - Apache License, Version 2.0
//! ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) //! ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
//! - MIT license //! - MIT license
//! ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) //! ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
//! //!
//! at your option. //! at your option.
//! //!