rusticx
Guides

CRUD Operations

Complete reference for all insert, find, update, and delete operations in rusticx.

All examples below use PostgresRepo but the same API applies to MySqlRepo and MongoRepo.

Insert

Single record

let user = User {
    id: Uuid::new_v4(),
    email: "alice@example.com".into(),
    name: "Alice".into(),
    bio: None,
};
repo.insert(&user).await?;

Multiple records

let users = vec![
    User { id: Uuid::new_v4(), email: "bob@example.com".into(), name: "Bob".into(), bio: None },
    User { id: Uuid::new_v4(), email: "carol@example.com".into(), name: "Carol".into(), bio: None },
];
repo.insert_many(&users).await?;

Insert or update (upsert)

save() inserts the record if the primary key doesn't exist, or updates it if it does:

repo.save(&user).await?;

Find

By primary key

let user: Option<User> = repo.find_by_id(user_id).await?;

All records

let users: Vec<User> = repo.find_all().await?;

Single record matching a filter

let user: Option<User> = repo
    .find_one()
    .where_clause("email", CondOp::Eq, "alice@example.com")
    .fetch()
    .await?;

Filtered list

let users: Vec<User> = repo
    .find()
    .where_clause("name", CondOp::Eq, "Alice")
    .order_by("created_at", Direction::Desc)
    .limit(20)
    .fetch_all()
    .await?;

Paginate

let page = repo.paginate(1, 20).await?;
// page.items: Vec<User>
// page.total: u64
// page.total_pages: u64
// page.page: u64

Count

// Total count
let total: u64 = repo.count().fetch().await?;

// Count with filter
let active: u64 = repo
    .count()
    .where_clause("bio", CondOp::IsNotNull, ())
    .fetch()
    .await?;

Update

repo.update()
    .where_clause("id", CondOp::Eq, user.id)
    .set("name", "Alice Smith")
    .set("bio", "Senior Rustacean")
    .execute()
    .await?;

Multiple .set() calls are chained — all fields update in a single query.

Delete

By primary key

repo.delete_by_id(user.id).await?;

By filter

repo.delete()
    .where_clause("email", CondOp::Eq, "alice@example.com")
    .execute()
    .await?;

Raw SQL

For queries that the builder can't express, use the underlying adapter directly:

// Execute a statement (no return value)
repo.adapter().execute_raw("DELETE FROM users WHERE created_at < NOW() - INTERVAL '1 year'", &[]).await?;

// Query rows
let rows = repo.adapter().query_raw("SELECT id, name FROM users WHERE role = $1", &[&"admin"]).await?;

Raw SQL bypasses the type-safe query builder. Validate all user-supplied input before passing it to execute_raw or query_raw.

On this page