| Crates.io | lume |
| lib.rs | lume |
| version | 0.1.2 |
| created_at | 2025-08-15 12:11:56.458481+00 |
| updated_at | 2025-09-25 09:09:59.745083+00 |
| description | A simple and intuitive Query Builder inspired by Drizzle |
| homepage | |
| repository | https://github.com/guru901/lume |
| max_upload_size | |
| id | 1796647 |
| size | 127,401 |
A type-safe, ergonomic schema builder and ORM for SQL databases, inspired by Drizzle ORM.
Add Lume to your Cargo.toml:
[dependencies]
lume = "0.1"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
use lume::define_schema;
use lume::schema::Schema;
// Define your database schema
define_schema! {
Users {
id: i32 [primary_key().not_null()],
username: String [not_null()],
email: String,
age: i32,
is_active: bool [default_value(true)],
created_at: i64 [not_null()],
}
Posts {
id: i32 [primary_key().not_null()],
title: String [not_null()],
content: String,
author_id: i32 [not_null()],
published: bool [default_value(false)],
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Connect to your MySQL database
let db = Database::connect("mysql://user:password@localhost/database").await?;
// Create tables (if they don't exist)
Users::ensure_registered();
Posts::ensure_registered();
// Type-safe queries
let users = db
.query::<Users>()
.filter(lume::filter::Filter::eq("username", "john_doe"))
.execute()
.await?;
for user in users {
let username: Option<String> = user.get(Users::username());
let age: Option<i32> = user.get(Users::age());
println!("User: {} (age: {})", username.unwrap_or_default(), age.unwrap_or(0));
}
Ok(())
}
Lume provides a powerful macro system for defining database schemas:
define_schema! {
Product {
id: i32 [primary_key().not_null()],
name: String [not_null().unique()],
description: String,
price: f64 [not_null()],
stock: i32 [default_value(0)],
category_id: i32 [not_null().indexed()],
created_at: i64 [not_null()],
updated_at: i64 [not_null()],
}
}
String → VARCHAR(255)i32 → INTEGERi64 → BIGINTf32 → FLOATf64 → DOUBLEbool → BOOLEANprimary_key() - Sets the column as primary keynot_null() - Makes the column NOT NULLunique() - Adds a UNIQUE constraintindexed() - Creates an index on the columndefault_value(value) - Sets a default value// Filter by equality
let active_users = db
.query::<Users>()
.filter(Filter::eq("is_active", true))
.execute()
.await?;
// Multiple filters
let young_active_users = db
.query::<Users>()
.filter(Filter::eq("is_active", true))
.filter(Filter::lt("age", 25))
.execute()
.await?;
// Access row data type-safely
for user in young_active_users {
let id: Option<i32> = user.get(Users::id());
let username: Option<String> = user.get(Users::username());
let email: Option<String> = user.get(Users::email());
println!("User {}: {} ({})", id.unwrap_or(0), username.unwrap_or_default(), email.unwrap_or_default());
}
define_schema! {
Settings {
id: i32 [primary_key().not_null()],
theme: String [default_value("dark".to_string())],
notifications: bool [default_value(true)],
max_connections: i32 [default_value(10)],
}
}
define_schema! {
Author {
id: i32 [primary_key().not_null()],
name: String [not_null()],
email: String [not_null().unique()],
}
Book {
id: i32 [primary_key().not_null()],
title: String [not_null()],
author_id: i32 [not_null()], // References Author.id
published_year: i32,
isbn: String [unique()],
}
}
Lume provides comprehensive error handling:
use lume::database::DatabaseError;
match db.query::<Users>().execute().await {
Ok(users) => {
println!("Found {} users", users.len());
}
Err(DatabaseError::ConnectionFailed) => {
eprintln!("Failed to connect to database");
}
Err(DatabaseError::QueryFailed) => {
eprintln!("Query execution failed");
}
Err(e) => {
eprintln!("Unexpected error: {:?}", e);
}
}
Lume includes comprehensive unit tests:
cargo test
Run specific test categories:
cargo test schema # Schema definition tests
cargo test row # Row manipulation tests
cargo test value # Value conversion tests
cargo test registry # Table registry tests
Contributions are welcome! Please read our contributing guidelines and submit pull requests for any improvements.
This project is licensed under the MIT License - see the LICENSE file for details.
See CHANGELOG.md for a detailed list of changes and improvements.