baichun-framework-db 0.1.0

Database module for Baichun-Rust framework
Documentation
use sqlx::MySqlPool;
use std::time::Duration;

const TEST_DB_URL: &str = "mysql://root:1qaz!QAZ@localhost:3306/mysql";

async fn setup_test_db() -> anyhow::Result<MySqlPool> {
    let pool_options = sqlx::mysql::MySqlPoolOptions::new()
        .max_connections(5)
        .min_connections(1)
        .acquire_timeout(Duration::from_secs(30))
        .connect(TEST_DB_URL)
        .await?;

    Ok(pool_options)
}

#[tokio::test]
async fn test_database_connection() -> anyhow::Result<()> {
    let pool = setup_test_db().await?;

    // Test simple query
    let result: (i64,) = sqlx::query_as("SELECT 1").fetch_one(&pool).await?;

    assert_eq!(result.0, 1);
    Ok(())
}

#[tokio::test]
async fn test_executor_operations() -> anyhow::Result<()> {
    let pool = setup_test_db().await?;

    // Test select from user table
    let users = sqlx::query_as::<_, User>(
        "SELECT User as name, Host as host FROM mysql.user WHERE User = 'root' LIMIT 1",
    )
    .fetch_all(&pool)
    .await?;

    assert!(!users.is_empty(), "Root user should exist");
    assert_eq!(users[0].name, "root");

    Ok(())
}

#[tokio::test]
async fn test_transaction() -> anyhow::Result<()> {
    let pool = setup_test_db().await?;

    // Test transaction - read only operations
    let mut tx = pool.begin().await?;

    let count = sqlx::query_as::<_, (i64,)>("SELECT COUNT(*) FROM mysql.user")
        .fetch_one(&mut *tx)
        .await?;
    assert!(count.0 > 0, "Should have at least one user");

    let root_count =
        sqlx::query_as::<_, (i64,)>("SELECT COUNT(*) FROM mysql.user WHERE User = 'root'")
            .fetch_one(&mut *tx)
            .await?;
    assert!(root_count.0 > 0, "Should have root user");

    tx.commit().await?;
    Ok(())
}

#[tokio::test]
async fn test_error_handling() -> anyhow::Result<()> {
    let pool = setup_test_db().await?;

    // Test not found error
    let result = sqlx::query_as::<_, User>(
        "SELECT User as name, Host as host FROM mysql.user WHERE User = ?",
    )
    .bind("nonexistent_user")
    .fetch_one(&pool)
    .await;

    assert!(result.is_err());

    // Test invalid query error
    let result = sqlx::query("SELECT * FROM nonexistent_table")
        .execute(&pool)
        .await;

    assert!(result.is_err());

    Ok(())
}

#[derive(Debug, sqlx::FromRow)]
struct User {
    name: String,
}