# ormkit
A compile-time safe async ORM for PostgreSQL powered by SQLx.
## Core ORM Features
- **Type-Safe Query DSL**: Compile-time checked queries with fluent API
- **Entity Derive**: `#[derive(ormkit::Entity)]` for automatic trait implementation
- **Repository Pattern**: Generic CRUD operations with type-safe IDs
- **Query Builder**: Dynamic filters and ordering with type safety
- **Pagination**: Offset and cursor-based pagination
- **Transactions**: Automatic commit/rollback with nested transaction support
## Optional Production Features
Enable with feature flags (see [Installation](#installation)):
- **Migrations** (`migrations`): Version-controlled schema migrations with CLI
- **Schema Validation** (`validate`): Runtime entity-to-database validation
- **Performance** (`performance`): Query/entity caching, parallel execution, smart pooling
- **Relationships**: BelongsTo and HasMany with N+1 prevention (basic implementation)
## Installation
```toml
[dependencies]
ormkit = "0.2"
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "postgres", "chrono", "uuid", "json"] }
```
### Feature Flags
```toml
# Core ORM only (minimal dependencies)
ormkit = { version = "0.2", features = ["orm"] }
# Core + migrations (recommended for most projects)
ormkit = { version = "0.2", features = ["orm", "migrations"] }
# Core + production features
ormkit = { version = "0.2", features = ["full"] }
# All features (default)
ormkit = { version = "0.2" }
```
## Quick Start
```rust
use ormkit::{Entity, Repository};
use ormkit::active_value::ActiveValue;
use sqlx::PgPool;
use uuid::Uuid;
// Define an Entity using the derive macro
#[derive(ormkit::Entity, Debug, Clone)]
#[ormkit(table = "users")]
struct User {
#[ormkit(id)]
id: Uuid,
email: String,
name: String,
age: i32,
created_at: chrono::DateTime<chrono::Utc>,
}
// Repository operations (CRUD)
async fn repository_example(pool: &PgPool) -> Result<(), Box<dyn std::error::Error>> {
let repo = Repository::<User>::new(pool);
// Find by ID
let user = repo.find_by_id(user_id).await?;
// Insert with ActiveModel
let mut user_model = UserActiveModel::default();
user_model.email = ActiveValue::Set("user@example.com".to_string());
user_model.name = ActiveValue::Set("John Doe".to_string());
let user = repo.insert(user_model).await?;
// Update (only changed fields are updated)
let mut user_model = user.into_active_model();
user_model.name = ActiveValue::Set("Jane Doe".to_string());
repo.update(user_model).await?;
Ok(())
}
```
## Core Features
### Type-Safe Query Builder (Recommended)
```rust
use ormkit::Entity;
// Compile-time type-safe queries
let users: Vec<User> = User::query()
.filter(User::email().eq("user@example.com"))
.filter(User::age().gte(18))
.order_by(User::created_at(), ormkit::query::Order::Desc)
.limit(10)
.fetch_all(&pool)
.await?;
```
### Dynamic Query Builder (for admin/filters)
```rust
use ormkit::{Filter, FilterOp, Order};
// Runtime query construction (for admin panels, dynamic filters)
let mut query = User::query();
if let Some(email) = email_filter {
query = query.filter("email", FilterOp::Eq, email);
}
if let Some(min_age) = min_age {
query = query.filter("age", FilterOp::Gte, min_age);
}
let users = query.fetch_all(&pool).await?;
```
### Pagination
```rust
use ormkit::pagination::PaginationRequest;
let repo = Repository::<User>::new(&pool);
let request = PaginationRequest::new(1, 25); // page 1, 25 per page
let page = repo.paginate(&request).await?;
println!("Page {} of {}", page.meta.page, page.meta.total_pages);
for user in page.items {
println!("User: {}", user.email);
}
```
### Batch Operations
```rust
use ormkit::batch::{insert_many, BatchOptions};
let new_users = vec![/* ... */];
let options = BatchOptions::new().batch_size(50);
let result = insert_many(&pool, &new_users, Some(options)).await?;
println!("Inserted {} users", result.successful);
```
### Transactions
```rust
use ormkit::transaction::transaction;
let user = repo.find_by_id(user_id).await?;
let mut user_model = user.into_active_model();
user_model.name = ActiveValue::Set("Updated Name".to_string());
repo.update(user_model).await?;
Ok::<(), Box<dyn std::error::Error>>(())
}).await?;
```
## Advanced Features
### Relationships (Prevents N+1 Queries)
```rust
use ormkit::relations::RelationBuilder;
// Load related entities in a single query
let posts_with_users = RelationBuilder::for_entities(posts)
.load::<User>(&pool)
.await?;
for loaded in posts_with_users {
println!("Post: {} by {}", loaded.entity.title, loaded.related.name);
}
```
## Project Status
**v0.2.1** - Stable core ORM with production features
### Production Ready
- Entity derive macros with compile-time type safety
- Type-safe query DSL with fluent API
- Repository CRUD operations
- Query builder with dynamic filters
- Pagination (offset and cursor-based)
- Transaction management with nested transactions
- Migration engine with CLI
- Schema validation
### Performance Characteristics
- Matches SQLx for single queries
- Can outperform naive SQLx usage in specific scenarios:
- Cached lookups (up to 2000x speedup on warm cache)
- Bulk operations with parallel execution
- N+1 query prevention
- Raw SQLx remains fastest for single, one-off queries
### In Development
- Relationship ergonomics (BelongsTo/HasMany work, API needs polish)
- One-to-one and many-to-many relationships
- Typed ActiveModel derive macro integration
### Platform Support
- **PostgreSQL**: 12, 13, 14, 15, 16
- **Rust**: 1.70+ (MSRV)
- **Tokio**: 1.x
## Documentation
### Getting Started (5-10 min read)
- [Quick Start](#quick-start) - Basic usage example
- [Core ORM Guide](CORE_GUIDE.md) - Essential features and patterns
- [API Reference](https://docs.rs/ormkit) - Complete API documentation
### In-Depth Guides
- [Relationships Guide](RELATIONSHIPS_GUIDE.md) - BelongsTo, HasMany, N+1 prevention
- [ActiveModel Guide](ACTIVEMODEL_GUIDE.md) - Typed vs HashMap change tracking
- [Type-Safe Queries](#type-safe-query-builder-recommended) - Query DSL
- [Query Builder](#dynamic-query-builder-for-adminfilters) - Dynamic queries
### Production Topics
- [Production Guide](PRODUCTION_GUIDE.md) - Migrations, validation, performance features
- [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md) - Caching, batching, benchmarks
- [Error Handling](ERROR_HANDLING.md) - Error types, retry logic, categorization
### Reference
- [Project Status](#project-status) - Feature status and platform support
- [License](#license) - MIT OR Apache-2.0
## License
MIT OR Apache-2.0
---
**Ormkit** — A compile-time safe async ORM for PostgreSQL powered by SQLx.