Cherry 🍒

Cherry is an asynchronous ORM, support MySQL, PostgreSQL, SQLite and SQL Server. It's lightweight and build on top of SQLx.

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

Dependency

enable one of the database features ['mysql', 'postgres', 'sqlite', 'mssql'].

And enable 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']. More details see SQLx Feature Flags.

```toml

Cargo.toml

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

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 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(())

}

pub struct Foo; pub struct Bar;

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

Model

```rust

[derive(Cherry)]

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

[derive(Cherry)]

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

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

Insert

```rust async fn insert() -> Result<(), Box> { // Insert one let user = User { id: 1, name: "Bob".toowned(), }; let result = Foo.insert(&user).execute().await?; asserteq!(result.rows_affected(), 1);

// Insert multiple
let users = [
    User { id: 2, name: "Sam".to_owned() },
    User { id: 3, name: "Jack".to_owned() }
];
let result = Foo.insert_bulk(&users).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 = Foo.delete::() .andwhereeq("id", 100) .execute() .await?;

Ok(())

} ```

Update

```rust async fn update() -> Result<(), Box> { let result = 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?;
// Or tx.rollback().await?;

Ok(())

} ```

TODO