CRUD
Insert
#![allow(unused)] fn main() { use rango::prelude::*; let user = User { id: FieldUuid(uuid::Uuid::new_v4()), email: FieldEmail::new("alice@example.com")?, name: FieldVarchar::new("Alice")?, active: FieldBool(true), created_at: FieldDateTime(chrono::Utc::now()), }; let inserted = insert(&pool, user).await?; // Returns the saved model with any DB-generated values }
Get by primary key
#![allow(unused)] fn main() { let user = get::<_, User>(&pool, &SqlValue::Uuid(user_id)).await?; match user { Some(u) => println!("Found: {}", u.email), None => println!("Not found"), } }
Update
#![allow(unused)] fn main() { let mut user = get::<_, User>(&pool, &id).await?.unwrap(); user.name = FieldVarchar::new("Alice Updated")?; let updated = update(&pool, user).await?; }
Delete
#![allow(unused)] fn main() { delete(&pool, &user).await?; }
Delete is idempotent: deleting a row that does not exist (already deleted, or never inserted) is not an error and returns Ok(()). update of a missing row returns Error::NotFound.
get_or_create
Atomic — safe against race conditions:
#![allow(unused)] fn main() { let lookup = vec![("email", SqlValue::Text("alice@example.com".into()))]; let defaults = User { /* ... */ }; let (user, created) = get_or_create(&pool, lookup, defaults).await?; if created { println!("New user created"); } else { println!("Existing user found"); } }
Uses INSERT ... ON CONFLICT DO NOTHING RETURNING * in a single round-trip.
update_or_create
#![allow(unused)] fn main() { let lookup = vec![("email", SqlValue::Text("alice@example.com".into()))]; let values = User { /* ... */ }; let user = update_or_create(&pool, lookup, values).await?; }
Updates the row matching lookup (update hooks fire; the whole row is overwritten from the values of values, only the primary key is kept, so fields you did not mean to change are reset too) or inserts values (create hooks fire). It takes a pool or a transaction (&mut **tx) on every backend. The lookup and the write are two statements: wrap the call in atomic() to make them one unit.
all()
Fetch all rows (subject to the default limit):
#![allow(unused)] fn main() { let users = all::<_, User>(&pool).await?; }