Improve documentation for the drivers and the entity

Provide module level code example on how to create an Entity, Model, ActiveModel, Column and PrimaryKey
This commit is contained in:
Charles Chege 2021-10-30 11:15:43 +03:00
parent a1382b1b41
commit e0023611a2
6 changed files with 194 additions and 6 deletions

View File

@ -126,7 +126,7 @@ impl SqlxMySqlPoolConnection {
} }
} }
/// Bundle a set of SQL statements that execute together. /// Bundle a set of SQL statements that execute together.
pub async fn begin(&self) -> Result<DatabaseTransaction, DbErr> { pub async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
if let Ok(conn) = self.pool.acquire().await { if let Ok(conn) = self.pool.acquire().await {
DatabaseTransaction::new_mysql(conn).await DatabaseTransaction::new_mysql(conn).await

View File

@ -30,7 +30,7 @@ impl SqlxSqliteConnector {
pub fn accepts(string: &str) -> bool { pub fn accepts(string: &str) -> bool {
string.starts_with("sqlite:") && string.parse::<SqliteConnectOptions>().is_ok() string.starts_with("sqlite:") && string.parse::<SqliteConnectOptions>().is_ok()
} }
/// Add configuration options for the SQLite database /// Add configuration options for the SQLite database
pub async fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> { pub async fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {
let mut opt = options let mut opt = options
@ -129,7 +129,7 @@ impl SqlxSqlitePoolConnection {
} }
} }
/// Bundle a set of SQL statements that execute together. /// Bundle a set of SQL statements that execute together.
pub async fn begin(&self) -> Result<DatabaseTransaction, DbErr> { pub async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
if let Ok(conn) = self.pool.acquire().await { if let Ok(conn) = self.pool.acquire().await {
DatabaseTransaction::new_sqlite(conn).await DatabaseTransaction::new_sqlite(conn).await

View File

@ -55,7 +55,27 @@ where
ActiveValue::unchanged(value) ActiveValue::unchanged(value)
} }
/// Enforces a set of constraints on any type performing an Create, Update or Delete operation /// Enforces a set of constraints on any type performing an Create, Update or Delete operation.
/// The type must also implement the [EntityTrait].
/// #### Example
/// ```
/// use sea_orm::entity::prelude::*;
///
/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
/// pub struct Entity;
///
/// impl EntityName for Entity {
/// fn table_name(&self) -> &str {
/// "cake"
/// }
/// }
///
/// #[derive(Clone, Debug, PartialEq, DeriveActiveModel)]
/// pub struct Model {
/// pub id: i32,
/// pub name: Option<String> ,
/// }
/// ```
#[async_trait] #[async_trait]
pub trait ActiveModelTrait: Clone + Debug { pub trait ActiveModelTrait: Clone + Debug {
/// Enforce the type to the constraints of the [EntityTrait] /// Enforce the type to the constraints of the [EntityTrait]
@ -186,7 +206,21 @@ pub trait ActiveModelTrait: Clone + Debug {
} }
/// Enforce a set of constraints to a override the ActiveModel behavior /// Enforce a set of constraints to a override the ActiveModel behavior
/// Behaviors for users to override /// Behaviors for users to override.
/// The type must also implement the [ActiveModelTrait]
///
/// ### Example
/// ```
/// /// Derive the active
/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
/// pub struct Model {
/// pub id: i32,
/// pub name: String,
/// pub cake_id: Option<i32>,
/// }
/// ```
/// impl ActiveModelBehavior for ActiveModel {}
///
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait ActiveModelBehavior: ActiveModelTrait { pub trait ActiveModelBehavior: ActiveModelTrait {
/// Create a new ActiveModel with default values. Also used by `Default::default()`. /// Create a new ActiveModel with default values. Also used by `Default::default()`.

View File

@ -37,6 +37,7 @@ pub trait EntityName: IdenStatic + Default {
} }
} }
/// FIXME Add docs for manual impl
/// An Entity implementing `EntityTrait` represents a table in a database. /// An Entity implementing `EntityTrait` represents a table in a database.
/// ///
/// This trait provides an API for you to inspect it's properties /// This trait provides an API for you to inspect it's properties

View File

@ -1,3 +1,125 @@
//! This modules contains types and traits for an Entity, ActiveMode, Model, PrimaryKey, ForeignKey and Relations.
//!
//! // An Entity
//! A unit struct implements [EntityTrait](crate::EntityTrait) representing a table in the database.
//!
//! This trait contains the properties of an entity including
//!
//! Table Name (implemented EntityName)
//! 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_*
//!
//! #### Example for creating an Entity, Model and ActiveModel
//! ```
//! use sea_orm::entity::prelude::*;
//!
//! // Use [DeriveEntity] to derive the EntityTrait automatically
//! #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
//! pub struct Entity;
//!
//! /// The [EntityName] describes the name of a table
//! impl EntityName for Entity {
//! fn table_name(&self) -> &str {
//! "cake"
//! }
//! }
//!
//! // Create a Model for the Entity through [DeriveModel].
//! // The `Model` handles `READ` operations on a table in a database.
//! // The [DeriveActiveModel] creates a way to perform `CREATE` , `READ` and `UPDATE` operations
//! // in a database
//!
//! #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
//! pub struct Model {
//! pub id: i32,
//! pub name: Option<String> ,
//! }
//!
//! // Use the [DeriveColumn] to create a Column for an the table called Entity
//! // The [EnumIter] which creates a new type that iterates of the variants of a Column.
//! #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
//! pub enum Column {
//! Id,
//! Name,
//! }
//!
//! // Create a PrimaryKey for the Entity using the [PrimaryKeyTrait]
//! // The [EnumIter] which creates a new type that iterates of the variants of a PrimaryKey.
//! #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
//! pub enum PrimaryKey {
//! Id,
//! }
//!
//! // Or implement the [PrimaryKeyTrait] manually instead of using the macro [DerivePrimaryKey]
//! impl PrimaryKeyTrait for PrimaryKey {
//! type ValueType = i32;
//!
//! fn auto_increment() -> bool {
//! true
//! }
//! }
//!
//! // Create a Relation for the Entity
//! #[derive(Copy, Clone, Debug, EnumIter)]
//! #[sea_orm(
//! // The relation belongs to `Entity` type
//! belongs_to = "Entity",
//! from = "Column::FruitId",
//! to = "Column::Id"
//! )]
//! pub enum Relation {
//! Fruit,
//! }
//!
//! // Create the properties of a Column in an Entity ensuring that calling
//! // Column::def() yields a Column definition as defined in [ColumnDef]
//! impl ColumnTrait for Column {
//! type EntityName = Entity;
//! fn def(&self) -> ColumnDef {
//! match self {
//! Self::Id => ColumnType::Integer.def(),
//! Self::Name => ColumnType::Text.def().null(),
//! }
//! }
//! }
//!
//! // Implement the set of constraints for creating a Relation as defined in the [RelationTrait]
//! impl RelationTrait for Relation {
//! fn def(&self) -> RelationDef {
//! match self {
//! Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
//! }
//! }
//! }
//!
//! impl Related<fruit::Entity> for Entity {
//! fn to() -> RelationDef {
//! Relation::Fruit.def()
//! }
//! }
//!
//! impl Related<super::filling::Entity> for Entity {
//! fn to() -> RelationDef {
//! super::cake_filling::Relation::Filling.def()
//! }
//! fn via() -> Option<RelationDef> {
//! Some(super::cake_filling::Relation::Cake.def().rev())
//! }
//! }
//!
//! // Implement user defined operations for CREATE, UPDATE and DELETE operations
//! // to create an ActiveModel using the [ActiveModelBehavior]
//! impl ActiveModelBehavior for ActiveModel {}
//! ```
mod active_model; mod active_model;
mod base_entity; mod base_entity;
mod column; mod column;

View File

@ -4,7 +4,38 @@ use sea_query::{FromValueTuple, IntoValueTuple};
use std::fmt::Debug; use std::fmt::Debug;
//LINT: composite primary key cannot auto increment //LINT: composite primary key cannot auto increment
/// A set of constraints to be used to define a Primary Key /// A set of constraints to be used to define a Primary Key.
///
/// A primary key can be derived manually
///
/// ### Example
/// ```
/// use sea_orm::entity::prelude::*;
///
/// #[derive(Copy, Clone, Debug, EnumIter)]
/// pub enum PrimaryKey {
/// Id,
/// }
/// impl PrimaryKeyTrait for PrimaryKey {
/// type ValueType = i32;
///
/// fn auto_increment() -> bool {
/// true
/// }
/// }
/// ```
///
/// Alternatively, use derive macros to automatically implement the trait for a Primary Key
///
/// ### Example
/// ```
/// use sea_orm::entity::prelude::*;
///
/// #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
/// pub enum PrimaryKey {
/// Id,
/// }
/// ```
pub trait PrimaryKeyTrait: IdenStatic + Iterable { pub trait PrimaryKeyTrait: IdenStatic + Iterable {
#[allow(missing_docs)] #[allow(missing_docs)]
type ValueType: Sized type ValueType: Sized