This commit is contained in:
Chris Tsang 2021-07-01 17:41:16 +08:00
parent 3a0ea8146f
commit 1b43ffc987
3 changed files with 148 additions and 22 deletions

122
README.md
View File

@ -17,7 +17,9 @@
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::Model> = Cake::find().all(db).await?;
// find and filter
let chocolate: Vec<cake::Model> = Cake::find()
.filter(cake::Column::Name.contains("chocolate"))
.all(db)
.await?;
// find one model
let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;
let cheese: cake::Model = cheese.unwrap();
// find related models (lazy)
let fruits: Vec<fruit::Model> = cheese.find_related(Fruit).all(db).await?;
// find related models (eager)
let cake_with_fruits: Vec<(cake::Model, Vec<fruit::Model>)> = 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::Model> = 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::Model> = 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.

View File

@ -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

View File

@ -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::Model> = 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::Model> = 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::Model> = 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"
)]