Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

typed_sqlx_client

Crates.io Documentation License

A type-safe, extensible Rust library for managing multiple SQL databases and tables with sqlx. Build robust database applications with automatic CRUD operations, flexible queries, and compile-time safety.

✨ Key Features

  • 🚀 Automatic CRUD: #[derive(CrudOpsRef)] generates full CRUD operations
  • 🛡️ Type Safety: Compile-time prevention of database/table mix-ups
  • 🗄️ Multi-Database: MySQL, PostgreSQL, and SQLite with a unified API
  • 🔍 Flexible Queries: Type-safe & JSON SELECTs with safe parameter binding

🚀 Quick Start

[dependencies]
typed_sqlx_client = "0.2.4"
sqlx = { version = "0.8", features = ["postgres", "runtime-tokio"] }
use typed_sqlx_client::{CrudOpsRef, SqlDB, SelectOnlyQuery};
use sqlx::{PgPool, FromRow};

#[derive(FromRow, CrudOpsRef, Debug)]
#[crud(table = "users", db = "postgres")]
struct User {
    #[crud(primary_key)]
    id: Option<i64>,
    name: String,
    email: String,
}

struct MainDB;

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = PgPool::connect("postgres://...").await?;
    let db = SqlDB::from_pool::<MainDB>(pool);
    let users = db.get_table::<User>();

    // CRUD (auto-generated)
    let user = User { id: None, name: "Alice".into(), email: "alice@example.com".into() };
    users.insert(&user).await?;
    let found = users.get_by_id(&1).await?;

    // Table name accessor
    let table_name = users.table_name();

    // Typed queries
    let all: Vec<User> = users.execute_select_as_only::<User>("SELECT * FROM users").await?;

    // Parameterized queries (safe binding)
    let by_name: Vec<User> = users
        .execute_select_as_query(
            sqlx::query_as::<sqlx::Postgres, User>("SELECT * FROM users WHERE name = $1")
                .bind("Alice"),
        )
        .await?;

    Ok(())
}

🏷️ Attributes

Attribute Level Description
#[crud(table = "...")] struct Table name (defaults to struct name)
#[crud(db = "...")] struct mysql / postgres / sqlite
#[crud(primary_key)] field Mark primary key (defaults to first field)
#[crud(rename = "...")] field Map field to a column name
#[crud(encode_json)] field Auto Json() wrap on insert/update

🔍 Query API

SelectOnlyQuery is implemented directly on SqlTable. Only SELECT statements are allowed; prefer .bind() over format! interpolation for safe parameter binding.

Method Input Output
execute_select_only(&str) raw SQL Vec<serde_json::Value>
execute_select_as_only::<T>(&str) raw SQL Vec<T>
execute_select_query(Query) sqlx::query(...).bind(...) Vec<serde_json::Value>
execute_select_as_query(QueryAs) sqlx::query_as::<DB, T>(...).bind(...) Vec<T>

🗄️ Multi-Database

struct MainDB;
struct AnalyticsDB;

let main = SqlDB::from_pool::<MainDB>(pg_pool);
let analytics = SqlDB::from_pool::<AnalyticsDB>(mysql_pool);

let users = main.get_table::<User>();          // ✅
let events = analytics.get_table::<Event>();   // ✅
// let wrong = main.get_table::<Event>();      // ❌ compile error

📖 Documentation

🤝 Contributing

Contributions are welcome! Feel free to open an issue or submit a Pull Request.

📄 License

MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages