Cherry

WARNING: This crate is under development and not fully tested (mysql is partial tested at the moment).

Cherry is a lightweight asynchronous ORM, which is build on top of SQLx.

Dependency

Must enable one of the database features: ['mysql', 'postgres', 'sqlite', 'mssql']. And only one database enable allowed at the same moment.

One of the features ['runtime-actix-native-tls', 'runtime-async-std-native-tls', 'runtime-tokio-native-tls', 'runtime-actix-rustls', 'runtime-async-std-rustls', 'runtime-tokio-rustls'] must be enabled. More details see Cargo Feature Flags.

```toml

Cargo.toml

[dependencies] cherry = { version = "0.2.0", features = ["mysql", "runtime-async-std-rustls"] } cherry-derive = "0.2.0" ```

DataSource

You can set multiple DataSources as you need.

```rust use std::any::Any; use std::error::Error;

use cherry::connection::{self, PoolConfig}; use cherry::DataSource;

pub struct Foo; pub struct Bar;

impl DataSource for Foo {} impl DataSource for Bar {}

pub async fn setup() -> Result<(), Box> { let config = [ (Foo.typeid(), PoolConfig { url: "mysql://root:12345678@localhost:3306/foo".toowned(), ..Default::default() }), (Bar.typeid(), PoolConfig { url: "mysql://root:12345678@localhost:3306/bar".toowned(), ..Default::default() }), ];

// Setup the database connection pools.
connection::setup_pools(config).await?;
Ok(())

} ```

Model

```rust // lib.rs/main.rs need this.

[macro_use]

extern crate cherry_derive;

[derive(Cherry)]

[cherry(table = "my_user")] // Change the default table name.

pub struct User { pub id: u64, pub name: String, }

[derive(Cherry)]

pub struct Book { pub id: u64, pub name: String, } ```

Insert

```rust use cherry::sqlx::MySqlQueryResult;

async fn insert() -> Result<(), Box> { let user = User { id: 1, name: "Bob".to_owned(), };

// Insert one
let result: MySqlQueryResult = Foo.insert(&user).execute().await?;
assert_eq!(result.rows_affected(), 1);

let user1 = User { id: 2, name: "Sam".to_owned() };
let user2 = User { id: 3, name: "Jack".to_owned() };

let result: MySqlQueryResult = Foo.insert_bulk(&[user1, user2]).execute().await?;
assert_eq!(result.rows_affected(), 2);

Ok(())

} `` Also support other insertion such as:insert replace,insert ignore` ...

Delete

```rust async fn delete() -> Result<(), Box> { let result: MySqlQueryResult = Foo.delete::() .andwhereeq("id", 100) .execute() .await?;

Ok(())

} ```

Update

```rust async fn update() -> Result<(), Box> { let result: MySqlQueryResult = Foo.update::() .set("name", "New Name") .orwherelt("id", 100) .orwheregt("id", 200) .execute() .await?;

Ok(())

} ```

Select

```rust async fn select() -> Result<(), Box> { // Select optional one. let result: Option = Foo.select() .andwhereeq("id", 123) .fetch() .await?;

// Select list.
let result: Vec<User> = Foo.select()
    .and_where_between("id", 100, 200)
    .and_where_ne("name", "Jack")
    .fetch_all()
    .await?;

Ok(())

} ```

Transaction

```rust use cherry::types::Transaction;

async fn transaction() -> Result<(), Box> { let users = [ User { id: 1, name: "Henry".toowned() }, User { id: 2, name: "Jane".toowned() } ];

let books = [
    Book { id: 1, name: "Book name 1".to_owned() },
    Book { id: 2, name: "Book name 2".to_owned() }
];

// Without transaction
Foo.insert_bulk(&users).execute().await?;

// Auto transaction
Foo.insert_bulk(&users).execute_tx().await?;

// Manual transaction
let mut tx: Transaction = Foo.begin().await?;
Foo.insert_bulk(&users).execute_with(&mut tx).await?;
Foo.insert_bulk(&books).execute_with(&mut tx).await?;
tx.commit().await?;

Ok(())

} ```

TODO