Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Database & ORM Guide

Complete guide to using the Oxidite ORM for database operations.

Installation

[dependencies]
oxidite = { version = "1.0", features = ["database"] }

Setup

Database Connection

Create .env file:

DATABASE_URL=postgresql://user:password@localhost/mydb

Connect in your app (src/main.rs):

use oxidite::prelude::*;
use oxidite_db::Database;
use std::sync::Arc;

#[derive(Clone)]
struct AppState {
    db: Arc<Database>,
}

#[tokio::main]
async fn main() -> Result<()> {
    // Load config
    dotenv::dotenv().ok();

    // Connect to database
    let db = Arc::new(Database::connect(&std::env::var("DATABASE_URL")?).await?);

    let state = AppState { db };

    // ... your app setup
    let app = Router::new().with_state(state);
    // ...
    Ok(())
}

Defining Models

#![allow(unused)]
fn main() {
use oxidite_db::Model;
use serde::{Serialize, Deserialize};
use chrono::{DateTime, Utc};

#[derive(Model, Serialize, Deserialize, Clone, Default)]
#[table_name = "users"]
pub struct User {
    pub id: i64,
    pub name: String,
    pub email: String,
    pub password_hash: String,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}
}

CRUD Operations

Create

#![allow(unused)]
fn main() {
let mut user = User {
    name: "Alice".to_string(),
    email: "alice@example.com".to_string(),
    password_hash: hash_password("password")?,
    ..Default::default()
};

user.save(&db).await?;
}

Read

#![allow(unused)]
fn main() {
// Find by ID
let user = User::find(1, &db).await?;

// Find all
let users = User::all(&db).await?;

// Where clause
let user = User::query()
    .where_("email", "=", "alice@example.com")
    .first(&db)
    .await?;

// Multiple conditions
let users = User::query()
    .where_("active", "=", true)
    .where_("created_at", ">", yesterday)
    .limit(10)
    .get_all(&db)
    .await?;
}

Update

#![allow(unused)]
fn main() {
let mut user = User::find(1, &db).await?;
user.name = "Alice Smith".to_string();
user.save(&db).await?;
}

Delete

#![allow(unused)]
fn main() {
let user = User::find(1, &db).await?;
user.delete(&db).await?;
}

Relationships

Has Many

#![allow(unused)]
fn main() {
#[derive(Model)]
#[table_name = "posts"]
pub struct Post {
    pub id: i64,
    pub user_id: i64,
    pub title: String,
    pub content: String,
}

// Load user's posts
let user = User::find(1, &db).await?;
let posts = user.has_many::<Post>("user_id", &db).await?;
}

Belongs To

#![allow(unused)]
fn main() {
// Load post's author
let post = Post::find(1, &db).await?;
let user = post.belongs_to::<User>("user_id", &db).await?;
}

Migrations

Create Migration

Using CLI:

oxidite migrate create create_users_table

This will create a new SQL file in the migrations directory.

Run Migrations

oxidite migrate run

Or programmatically:

#![allow(unused)]
fn main() {
use oxidite_db::Migration;

Migration::run_all(&db).await?;
}

Rollback

oxidite migrate revert

Transactions

#![allow(unused)]
fn main() {
let tx = db.begin().await?;

// Perform operations
user.save(&tx).await?;
post.save(&tx).await?;

// Commit
tx.commit().await?;

// Or rollback on error
tx.rollback().await?;
}