New features: - #[soft_delete] attribute with delete/restore/hard_delete methods - #[created_at] auto-set on insert (milliseconds timestamp) - #[updated_at] auto-set on every update (milliseconds timestamp) - insert_many(&pool, &[entities]) for batch inserts - upsert(&pool) / insert_or_update(&pool) for ON CONFLICT handling - Page<T> struct with paginate() method for pagination - find_partial() for selecting specific columns - transaction! macro for ergonomic transaction handling - PageRequest struct with offset/limit helpers Technical changes: - Added pagination.rs and transaction.rs modules - Extended EntityField with is_soft_delete, is_created_at, is_updated_at - Added generate_soft_delete_impl for delete/restore/hard_delete methods - Upsert uses ON DUPLICATE KEY UPDATE (MySQL), ON CONFLICT DO UPDATE (Postgres/SQLite) - Index hints supported in pagination and find_partial (MySQL) All three database backends (MySQL, PostgreSQL, SQLite) tested and working. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| .claude/skills | ||
| mcp | ||
| scripts | ||
| sqlx-record-ctl | ||
| sqlx-record-derive | ||
| src | ||
| .gitignore | ||
| CLAUDE.md | ||
| Cargo.toml | ||
| Makefile | ||
| README.md | ||
README.md
sqlx-record
Entity CRUD and change tracking for SQL databases with SQLx.
A Rust library that provides derive macros for automatic CRUD operations and comprehensive audit trails for SQL entities. Track who changed what, when, and why with actor, session, and change set metadata.
Features
#[derive(Entity)]generates complete CRUD operations- Type-safe query building with composable filters
- Change tracking with WHO, WHAT, WHEN, and WHERE metadata
- Version fields for optimistic locking
- Diff detection between model states
- CLI tool for managing audit tables
- Supports MySQL, PostgreSQL, and SQLite
Installation
Add to your Cargo.toml:
[dependencies]
sqlx-record = { version = "0.1", features = ["mysql", "derive"] }
# or for PostgreSQL:
# sqlx-record = { version = "0.1", features = ["postgres", "derive"] }
# or for SQLite:
# sqlx-record = { version = "0.1", features = ["sqlite", "derive"] }
Usage
use sqlx_record::prelude::*;
use sqlx::FromRow;
#[derive(Entity, FromRow)]
#[table_name = "users"]
struct User {
#[primary_key]
id: Uuid,
name: String,
email: String,
#[version]
version: u32,
}
// Insert
let id = user.insert(&pool).await?;
// Query with filters
let users = User::find(&pool, filters![("active", true)], None).await?;
// Update with diff tracking
let mut form = User::update_form().with_name("New Name".into());
let diff = form.db_diff(&id, &pool).await?;
user.update(&pool, form).await?;
License
MIT