ssw 0.1.1

ssw is sql simple wrapper
Documentation

SSW (Simple Smart Wrapper)

Rust Version License Crates.io

A lightweight, type-safe Rust ORM library built on top of rbatis


๐Ÿš€ Features

  • โœ… Type-safe SQL generation - Compile-time query validation
  • โœ… Wrapper pattern - Fluent API for building complex queries
  • โœ… DaoTrait - Standard CRUD operations out of the box
  • โœ… Macro support - Minimal boilerplate with impl_model_trait! and impl_dao_trait!
  • โœ… Async/await - Native async support with tokio
  • โœ… Multi-database support - PostgreSQL, SQLite, MySQL via rbatis
  • โœ… Pagination - Built-in PageResult with metadata
  • โœ… Aggregate functions - count, max, min, sum, avg, exists

๐Ÿ“ฆ Installation

Add to your Cargo.toml:

[dependencies]

ssw = "0.1.1"



# For PostgreSQL

rbdc-pg = "4.9"



# For SQLite

rbdc-sqlite = "4.8"



# For MySQL

rbdc-mysql = "4.8"



# Common dependencies

serde = { version = "1.0", features = ["derive"] }

lazy_static = "1.5"


๐Ÿ”ฅ Quick Start

1. Define Your Model

use serde::{Deserialize, Serialize};
use ssw::{ModelTrait, DaoTrait, impl_model_trait, impl_dao_trait};
use ssw::QueryWrapper;

#[derive(Debug, Clone, Serialize, Deserialize)]
struct User {
    id: Option<i64>,       // SERIAL PRIMARY KEY โ†’ Option<i64>
    username: Option<String>,
    email: Option<String>,
    status: Option<i32>,
    created_at: Option<i64>, // TIMESTAMP โ†’ Option<i64> (Unix ms)
}

// Implement ModelTrait (required)
impl_model_trait!(User, "users");

2. Initialize RBatis

use rbatis::RBatis;
use rbdc_pg::PgDriver;
use lazy_static::lazy_static;

lazy_static! {
    static ref RB: RBatis = RBatis::new();
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize with PostgreSQL connection string
    RB.init(PgDriver {}, "postgres://postgres:123456@127.0.0.1:5432/tt").unwrap();
    
    println!("โœ… Database connected!");
    Ok(())
}

3. Implement DaoTrait

// Use macro (recommended)
impl_dao_trait!(User, User, &RB);

// Or implement manually
impl DaoTrait for User {
    type T = User;
    
    fn rb_ref() -> &'static RBatis {
        &RB
    }
}

4. Use CRUD Operations

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // ===== INSERT =====
    let user = User {
        id: None,
        username: Some("alice".to_string()),
        email: Some("alice@example.com".to_string()),
        status: Some(1),
        created_at: None,
    };
    
    let result = User::try_save(&user).await?;
    println!("Inserted {} rows", result.rows_affected);
    
    // ===== SELECT =====
    let users = User::select_by_column("status", 1).await;
    println!("Found {} active users", users.len());
    
    // ===== UPDATE =====
    let user = User {
        id: None,
        username: None,
        email: Some("alice_new@example.com".to_string()),
        status: Some(2),
        created_at: None,
    };
    
    let result = User::try_update_by_column(&user, "username", "alice").await?;
    println!("Updated {} rows", result.rows_affected);
    
    // ===== DELETE =====
    let result = User::try_delete_by_column("username", "alice").await?;
    println!("Deleted {} rows", result.rows_affected);
    
    Ok(())
}

5. Pagination (Optional)

use ssw::Page;

// Create a Page (recommended: use ::new())
let page = Page::new(1, 10);  // Page 1, 10 records per page

let wrapper = QueryWrapper::new()
    .table("users")
    .order_by(Order::Desc("id"));

let page_result = User::select_page(wrapper, page).await;

println!("Total: {}", page_result.total);
println!("Total pages: {}", page_result.total_pages);
println!("Data: {:?}", page_result.list);

๐Ÿ“š Documentation

๐Ÿ“– Full documentation: See skills/SKILL.md for:

  • Complete API reference
  • Advanced usage examples
  • Best practices
  • Troubleshooting guide
  • Migration guide

๐Ÿงช Examples: See integration tests for complete working examples:


๐Ÿงช Testing

# Run unit tests

cargo test --lib --tests


# Run integration tests (requires database)

# PostgreSQL

cd examples/rbatis_test/pgsql_test

cargo run


# SQLite

cd examples/rbatis_test/sqlite_test

cargo run


# MySQL

cd examples/rbatis_test/mysql_test

cargo run


# Check code coverage (optional)

cargo tarpaulin --out html


โš ๏ธ Safety Warnings

try_delete_all() - EXTREME DANGER!

// โš ๏ธ WARNING: This will DELETE ALL RECORDS in the table!
let result = User::try_delete_all().await?;

Never use try_delete_all() in production! Always add WHERE conditions:

// โœ… Safe: Delete with condition
User::try_delete_by_column("id", user_id).await?;

๐Ÿค Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone the repo

git clone https://github.com/yourusername/ssw.git

cd ssw


# Run tests

cargo test --lib --tests


# Run integration tests (requires database)

# PostgreSQL

cd examples/rbatis_test/pgsql_test

cargo run


# SQLite

cd examples/rbatis_test/sqlite_test

cargo run


# MySQL

cd examples/rbatis_test/mysql_test

cargo run


๐Ÿ“„ License

Licensed under either of:

at your option.


๐Ÿ™ Acknowledgments

  • rbatis - The underlying Rust ORM framework
  • serde - Serialization framework
  • tokio - Async runtime

๐Ÿ“ง Contact


Made with โค๏ธ in Rust