ormer 0.2.3

A minimalist ORM framework that supports SQLite, PostgreSQL, MySQL, and SqlServer
Documentation
#![cfg(any(feature = "sqlite", feature = "postgresql", feature = "mysql"))]

mod _test_common;

#[derive(Debug, Clone, ormer::Model)]
#[version(u64)]
#[table = "optimistic_lock_orders"]
struct OptimisticLockOrder {
    #[primary]
    id: i32,
    status: String,
}

async fn test_optimistic_lock_impl(
    config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
    let db = _test_common::create_db_connection(config).await?;
    _test_common::prepare_table::<OptimisticLockOrder>(&db).await?;

    let inserted = OptimisticLockOrder {
        id: 1,
        status: "draft".to_string(),
    };
    assert_eq!(inserted.version(), 1);
    db.insert(&inserted).execute().await?;

    let mut order = db
        .select::<OptimisticLockOrder>()
        .filter(|o| o.id.eq(1))
        .first()
        .await?
        .expect("inserted order should exist");
    assert_eq!(order.version(), 1);

    order.status = "approved".to_string();
    let affected = db
        .update::<OptimisticLockOrder>()
        .set_model(&order)
        .execute()
        .await?;
    assert_eq!(affected, 1);
    assert_eq!(order.version(), 2);

    let stale = OptimisticLockOrder {
        id: 1,
        status: "stale".to_string(),
    };
    assert_eq!(stale.version(), 1);

    let err = db
        .update::<OptimisticLockOrder>()
        .set_model(&stale)
        .execute()
        .await
        .expect_err("stale update should fail");
    assert!(matches!(err, ormer::OrmerError::OptimisticLock { .. }));

    let err = db
        .delete::<OptimisticLockOrder>()
        .model(&stale)
        .execute()
        .await
        .expect_err("stale delete should fail");
    assert!(matches!(err, ormer::OrmerError::OptimisticLock { .. }));

    let fresh = db
        .select::<OptimisticLockOrder>()
        .filter(|o| o.id.eq(1))
        .first()
        .await?
        .expect("order should still exist");
    assert_eq!(fresh.version(), 2);

    let deleted = db
        .delete::<OptimisticLockOrder>()
        .model(&fresh)
        .execute()
        .await?;
    assert_eq!(deleted, 1);

    _test_common::clean_table::<OptimisticLockOrder>(&db).await?;
    Ok(())
}

test_on_all_dbs_result!(test_optimistic_lock_impl);