diff --git a/README.md b/README.md index c314c05f..ccc68b39 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,12 @@ # SeaORM -Inspired by ActiveRecord, Eloquent and TypeORM, SeaORM aims to provide you an intuitive and ergonomic +Inspired by ActiveRecord, Eloquent and TypeORM, SeaORM aims to provide you an intuitive and ergonomic API to make working with databases in Rust a first-class experience. -> This is an early WIP of SeaORM, and is not yet published. See [example](examples/sqlx-mysql/src) for demo usage. +```rust +This is an early WIP of SeaORM, and is not yet released. +``` ## Features @@ -36,3 +38,121 @@ Use mock connections to write unit tests for your logic. 4. Service oriented Quickly build services that join, filter, sort and paginate data in APIs. + +## A quick taste of SeaORM + +### Select +```rust +// find all models +let cakes: Vec = Cake::find().all(db).await?; + +// find and filter +let chocolate: Vec = Cake::find() + .filter(cake::Column::Name.contains("chocolate")) + .all(db) + .await?; + +// find one model +let cheese: Option = Cake::find_by_id(1).one(db).await?; +let cheese: cake::Model = cheese.unwrap(); + +// find related models (lazy) +let fruits: Vec = cheese.find_related(Fruit).all(db).await?; + +// find related models (eager) +let cake_with_fruits: Vec<(cake::Model, Vec)> = Cake::find() + .find_with_related(Fruit) + .all(db) + .await?; + +``` +### Insert +```rust +let apple = fruit::ActiveModel { + name: Set("Apple".to_owned()), + ..Default::default() // no need to set primary key +}; + +let pear = fruit::ActiveModel { + name: Set("Pear".to_owned()), + ..Default::default() +}; + +// insert one +let res: InsertResult = Fruit::insert(pear).exec(db).await?; + +println!("InsertResult: {}", res.last_insert_id); + +// insert many +Fruit::insert_many(vec![apple, pear]).exec(db).await?; +``` +### Update +```rust +use sea_orm::sea_query::{Expr, Value}; + +let pear: Option = Fruit::find_by_id(1).one(db).await?; +let mut pear: fruit::ActiveModel = pear.unwrap().into(); + +pear.name = Set("Sweet pear".to_owned()); + +// update one +let pear: fruit::ActiveModel = Fruit::update(pear).exec(db).await?; + +// update many: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%' +Fruit::update_many() + .col_expr(fruit::Column::CakeId, Expr::value(Value::Null)) + .filter(fruit::Column::Name.contains("Apple")) + .exec(db) + .await?; + +``` +### Save +```rust +let banana = fruit::ActiveModel { + id: Unset(None), + name: Set("Banana".to_owned()), + ..Default::default() +}; + +// create, because primary key `id` is `Unset` +let mut banana = banana.save(db).await?; + +banana.name = Set("Banana Mongo".to_owned()); + +// update, because primary key `id` is `Set` +let banana = banana.save(db).await?; + +``` +### Delete +```rust +let orange: Option = Fruit::find_by_id(1).one(db).await?; +let orange: fruit::ActiveModel = orange.unwrap().into(); + +// delete one +fruit::Entity::delete(orange).exec(db).await?; +// or simply +orange.delete(db).await?; + +// delete many: DELETE FROM "fruit" WHERE "fruit"."name" LIKE 'Orange' +fruit::Entity::delete_many() + .filter(fruit::Column::Name.contains("Orange")) + .exec(db) + .await?; + +``` +## License + +Licensed under either of + +- Apache License, Version 2.0 + ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license + ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/build-tools/generate-readme.sh b/build-tools/generate-readme.sh new file mode 100644 index 00000000..9b871ef4 --- /dev/null +++ b/build-tools/generate-readme.sh @@ -0,0 +1,3 @@ +# Run `sh develop/cargo-readme.sh` on project root to generate `README.md` from `src/lib.rs` +# cargo install cargo-readme +cargo readme --no-badges --no-indent-headings --no-license --no-template --no-title > README.md \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index ea7dc797..1678b171 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ //! API to make working with databases in Rust a first-class experience. //! //! ```ignore -//! This is an early WIP of SeaORM, and is not yet published. See [example](examples/sqlx-mysql/src) for demo usage. +//! This is an early WIP of SeaORM, and is not yet released. //! ``` //! //! ## Features @@ -39,13 +39,12 @@ //! //! Quickly build services that join, filter, sort and paginate data in APIs. //! -//! # A quick taste of SeaORM +//! ## A quick taste of SeaORM //! -//! ## Select +//! ### Select //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! // find all models //! let cakes: Vec = Cake::find().all(db).await?; //! @@ -71,11 +70,10 @@ //! # Ok(()) //! # } //! ``` -//! ## Insert +//! ### Insert //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! let apple = fruit::ActiveModel { //! name: Set("Apple".to_owned()), //! ..Default::default() // no need to set primary key @@ -90,17 +88,13 @@ //! let res: InsertResult = Fruit::insert(pear).exec(db).await?; //! //! println!("InsertResult: {}", res.last_insert_id); -//! # //! # Ok(()) //! # } -//! # //! # async fn function2(db: &DbConn) -> Result<(), DbErr> { -//! # //! # let apple = fruit::ActiveModel { //! # name: Set("Apple".to_owned()), //! # ..Default::default() // no need to set primary key //! # }; -//! # //! # let pear = fruit::ActiveModel { //! # name: Set("Pear".to_owned()), //! # ..Default::default() @@ -108,18 +102,15 @@ //! //! // insert many //! Fruit::insert_many(vec![apple, pear]).exec(db).await?; -//! # //! # Ok(()) //! # } //! ``` -//! ## Update +//! ### Update //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; -//! # //! use sea_orm::sea_query::{Expr, Value}; //! //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! let pear: Option = Fruit::find_by_id(1).one(db).await?; //! let mut pear: fruit::ActiveModel = pear.unwrap().into(); //! @@ -138,12 +129,10 @@ //! # Ok(()) //! # } //! ``` -//! ## Save +//! ### Save //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; -//! # //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! let banana = fruit::ActiveModel { //! id: Unset(None), //! name: Set("Banana".to_owned()), @@ -161,12 +150,10 @@ //! # Ok(()) //! # } //! ``` -//! ## Delete +//! ### Delete //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; -//! # //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! let orange: Option = Fruit::find_by_id(1).one(db).await?; //! let orange: fruit::ActiveModel = orange.unwrap().into(); //! @@ -185,6 +172,22 @@ //! # Ok(()) //! # } //! ``` +//! ## License +//! +//! Licensed under either of +//! +//! - Apache License, Version 2.0 +//! ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +//! - MIT license +//! ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +//! +//! at your option. +//! +//! ## Contribution +//! +//! Unless you explicitly state otherwise, any contribution intentionally submitted +//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +//! dual licensed as above, without any additional terms or conditions. #![doc( html_logo_url = "https://raw.githubusercontent.com/SeaQL/sea-query/master/docs/SeaQL icon dark.png" )]