lref 0.2.0

Rust Entity Framework - An EFCore-inspired ORM for Rust
Documentation

lref

Crates.io License: MIT

Core crate for Rust Entity Framework — an EFCore-inspired ORM for Rust.

Provides the core ORM abstractions: EntityType, DbContext, DbSet, QueryBuilder, ChangeTracker, ModelBuilder, migration engine, and database provider abstraction layer.


Quick Example

use lref::prelude::*;

// Define entities
#[derive(Debug, Clone, EntityType)]
#[table("blogs")]
pub struct Blog {
    #[primary_key] #[auto_increment]
    pub blog_id: i32,
    #[required] #[max_length(200)]
    pub url: String,
    pub rating: i32,
    #[navigation] pub posts: HasMany<Post>,
}

// Build queries
let blogs = db_set.query()
    .filter_column("rating", ">", 3)
    .order_by_column("url")
    .skip(0).take(10)
    .to_list().await?;

// Aggregate
let avg = db_set.query().avg("rating").await?;
let count = db_set.query().count().await?;

// Bulk operations
db_set.query().filter_column("rating", "<", 1)
    .execute_delete().await?;

Modules

Module Description EFCore Equivalent
entity EntityType trait, EntityState, FromRow, GetKeyValues, EntitySnapshot Entity classes
db_context DbContext trait, SaveChangesResult, save_one_set() DbContext
db_set DbSet<T> — tracked entity collection DbSet<TEntity>
query QueryBuilder<T> — LINQ-style fluent queries IQueryable<T>
tracking ChangeTracker — property-level snapshots & state ChangeTracker
relations BelongsTo<T>, HasMany<T>, HasOne<T>, DeleteBehavior Navigation properties
model_builder ModelBuilder, EntityTypeBuilder, PropertyBuilder Fluent API
migration MigrationEngine, model diff, Up/Down SQL generation Migration system
provider DatabaseProvider, SqlGenerator, AsyncConnection, DbValue Provider abstraction
error LrefError enum with 12 error variants Exception hierarchy
cache DbCache — Identity Map entity cache

Traits

Core Entity Traits

pub trait EntityType: Send + Sync + 'static {
    fn entity_meta() -> EntityTypeMeta;
}

pub trait FromRow: EntityType + Sized {
    fn from_row(values: &[String]) -> LrefResult<Self>;
}

pub trait GetKeyValues: EntityType {
    fn key_values(&self) -> HashMap<String, DbValue>;
}

pub trait EntitySnapshot: EntityType {
    fn snapshot(&self) -> HashMap<String, DbValue>;
}

Session / Provider

#[async_trait]
pub trait DbContext: Send + Sync + Sized {
    type Provider: DatabaseProvider;
    fn provider(&self) -> &Self::Provider;
    fn change_tracker_mut(&mut self) -> &mut ChangeTracker;
    fn change_tracker(&self) -> &ChangeTracker;
    async fn save_changes(&mut self) -> LrefResult<SaveChangesResult>;
}

#[async_trait]
pub trait DatabaseProvider: Send + Sync {
    fn sql_generator(&self) -> Box<dyn SqlGenerator>;
    async fn get_connection(&self) -> LrefResult<Box<dyn AsyncConnection>>;
    async fn execute_migration_command(&self, sql: &str) -> LrefResult<()>;
    fn name(&self) -> &str;
}

QueryBuilder API

// Filtering
query.filter_column("col", "=", value)
     .filter_in("col", vec![1, 2, 3])
     .filter_is_null("col")
     .filter_is_not_null("col")
     .filter_between("col", low, high)

// Ordering & pagination
     .order_by_column("col")
     .order_by_desc_column("col")
     .skip(10).take(20)

// JOIN & grouping
     .inner_join("t2", "col_a", "col_b")
     .left_join("t2", "col_a", "col_b")
     .group_by(&["col"])
     .having("COUNT(*) > 1")

// Include navigation
     .include_named("posts")
     .include_with_join("posts", "posts", "blog_id", "blog_id", "LEFT")

// Terminal (execute)
     .to_list().await?       // Vec<T>
     .first().await?         // T
     .first_or_default().await?  // Option<T>
     .count().await?         // i64
     .any().await?           // bool
     .sum("col").await?      // f64
     .avg("col").await?      // f64
     .min("col").await?      // Option<String>
     .max("col").await?      // Option<String>

// Bulk operations
     .execute_update().set_column("col", value).execute().await?  // u64
     .execute_delete().await?  // u64

Database Provider Abstraction

The core crate defines traits. Provider crates implement them:

// SqlGenerator — dialect-specific SQL
trait SqlGenerator {
    fn select(&self, table: &str, columns: &[&str]) -> String;
    fn insert(&self, table: &str, columns: &[&str], returning: bool) -> String;
    fn update(&self, table: &str, set_columns: &[&str], where_clause: &str) -> String;
    fn delete(&self, table: &str, where_clause: &str) -> String;
    fn parameter_placeholder(&self, index: usize) -> String;
    fn quote_identifier(&self, identifier: &str) -> String;
    // ...
}

// AsyncConnection — typed parameter execution
#[async_trait]
trait AsyncConnection {
    async fn execute(&mut self, sql: &str, params: &[DbValue]) -> LrefResult<u64>;
    async fn query(&mut self, sql: &str, params: &[DbValue]) -> LrefResult<Vec<Vec<String>>>;
    async fn begin_transaction(&mut self) -> LrefResult<()>;
    async fn commit_transaction(&mut self) -> LrefResult<()>;
    async fn rollback_transaction(&mut self) -> LrefResult<()>;
}

License

MIT — see LICENSE