본문 바로가기
WIKI 기술 지식 베이스

Toasty + Turso

원문 보기 위키 갱신

Toasty는 Tokio 프로젝트가 만드는 비동기 ORM인데요, 네이티브 Turso 드라이버를 함께 제공하기 때문에 로컬 Turso 데이터베이스 파일이나 인메모리 데이터베이스에 바로 연결할 수 있어요. ORM 스타일로 모델을 정의하고 싶은 분들에게 딱 맞는 조합이에요.

출처: 문서

본문

Toasty는 Tokio 프로젝트가 관리하는 Rust용 비동기 ORM이에요. 네이티브 Turso 드라이버(toasty-driver-turso)를 함께 제공해서, 로컬 Turso 데이터베이스 파일이나 인메모리 데이터베이스에 연결할 수 있어요. 바로 turso crate에서 쓰는 것과 같은 엔진이에요.

참고로, Toasty의 Turso 드라이버는 현재 로컬 및 인메모리 데이터베이스를 대상으로 해요. Turso Cloud와 동기화하려면 turso crate를 직접 사용하는 방식으로 내려가야 해요.

Prerequisites

  • Rust 1.95 이상(Toasty가 지원하는 최소 버전)
  • Rust 프로젝트(cargo init)
  • 비동기 런타임으로 Tokio

Install Toasty with the Turso driver

cargo add toasty --features turso
cargo add tokio --features full
cargo add uuid

Define your models

Toasty는 평범한 Rust 구조체만으로 스키마, 쿼리, 관계를 도출해 줘요:

#[derive(Debug, toasty::Model)]
struct User {
    #[key]
    #[auto]
    id: uuid::Uuid,

    name: String,

    #[unique]
    email: String,

    #[has_many]
    todos: toasty::Deferred<Vec<Todo>>,
}

#[derive(Debug, toasty::Model)]
struct Todo {
    #[key]
    #[auto]
    id: uuid::Uuid,

    #[index]
    user_id: uuid::Uuid,

    #[belongs_to(key = user_id, references = id)]
    user: toasty::Deferred<User>,

    title: String,
}

Connect to Turso

Db::builder에 turso: URL을 넘기면 돼요. 인메모리 데이터베이스든 파일 경로든 원하는 방식을 고르세요.

In-memory

let db = toasty::Db::builder()
    .models(toasty::models!(crate::*))
    .connect("turso::memory:")
    .await?;

File-backed

let db = toasty::Db::builder()
    .models(toasty::models!(crate::*))
    .connect("turso:./app.db")
    .await?;

With concurrent writes (MVCC)

Turso의 MVCC 저널을 켜서 여러 writer가 동시에 동작하도록 하려면, 드라이버를 명시적으로 만들어서 build()에 넘기면 돼요:

use toasty_driver_turso::Turso;

let driver = Turso::file("app.db").concurrent_writes();

let db = toasty::Db::builder()
    .models(toasty::models!(crate::*))
    .build(driver)
    .await?;

concurrent_writes()를 활성화하면 쓰기-쓰기 충돌이 serialization failure로 표면에 나타나요. err.is_serialization_failure()를 확인하고 트랜잭션을 다시 시도하면 된답니다.

Create the schema and query

#[tokio::main]
async fn main() -> toasty::Result<()> {
    let mut db = toasty::Db::builder()
        .models(toasty::models!(crate::*))
        .connect("turso:./app.db")
        .await?;

    db.push_schema().await?;

    let user = toasty::create!(User {
        name: "Ada Lovelace",
        email: "[email protected]",
    })
    .exec(&mut db)
    .await?;

    toasty::create!(in user.todos() { title: "ship Toasty + Turso" })
        .exec(&mut db)
        .await?;

    let reloaded = User::get_by_email(&mut db, &user.email).await?;
    println!("{reloaded:#?}");

    Ok(())
}

Where to go next

  • Toasty 가이드에서 모델, 관계, 트랜잭션, 마이그레이션을 다뤄요.
  • Toasty 가이드의 Turso 챕터는 연결 URL 형식, concurrent_writes() 플래그, Turso 엔진 기능의 experimental_* 토글을 문서화하고 있어요.
  • turso crate 퀵스타트는 ORM 없이 Turso Database를 직접 쓰는 방법, Turso Cloud와의 동기화까지 보여줘요.

더 알아보기 (Learn more)