Crate edgedb_tokio

source ·
Expand description

EdgeDB client for Tokio

👉 New! Check out the new EdgeDB client tutorial. 👈

The main way to use EdgeDB bindings is to use the Client. It encompasses connection pool to the database that is transparent for user. Individual queries can be made via methods on the client. Correlated queries are done via transactions.

To create a client, use the create_client function (it gets a database connection configuration from environment). You can also use a Builder to build custom Config and create a client using that config.

§Example

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let conn = edgedb_tokio::create_client().await?;
    let val = conn.query_required_single::<i64, _>(
        "SELECT 7*8",
        &(),
    ).await?;
    println!("7*8 is: {}", val);
    Ok(())
}

More examples on github

§Nice Error Reporting

We use miette crate for including snippets in your error reporting code.

To make it work, first you need enable fancy feature in your top-level crate’s Cargo.toml:

[dependencies]
miette = { version="5.3.0", features=["fancy"] }
edgedb-tokio = { version="*", features=["miette-errors"] }

Then if you use miette all the way through your application, it just works:

#[tokio::main]
async fn main() -> miette::Result<()> {
    let conn = edgedb_tokio::create_client().await?;
    conn.query::<String, _>("SELECT 1+2)", &()).await?;
    Ok(())
}

However, if you use some boxed error container (e.g. anyhow), you might need to downcast error for printing:

async fn do_something() -> anyhow::Result<()> {
    let conn = edgedb_tokio::create_client().await?;
    conn.query::<String, _>("SELECT 1+2)", &()).await?;
    Ok(())
}

#[tokio::main]
async fn main() {
    match do_something().await {
        Ok(res) => res,
        Err(e) => {
            e.downcast::<edgedb_tokio::Error>()
                .map(|e| eprintln!("{:?}", miette::Report::new(e)))
                .unwrap_or_else(|e| eprintln!("{:#}", e));
            std::process::exit(1);
        }
    }
}

In some cases, where parts of your code use miette::Result or miette::Report before converting to the boxed (anyhow) container, you might want a little bit more complex downcasting:

#[tokio::main]
async fn main() {
    match do_something().await {
        Ok(res) => res,
        Err(e) => {
            e.downcast::<edgedb_tokio::Error>()
                .map(|e| eprintln!("{:?}", miette::Report::new(e)))
                .or_else(|e| e.downcast::<miette::Report>()
                    .map(|e| eprintln!("{:?}", e)))
                .unwrap_or_else(|e| eprintln!("{:#}", e));
            std::process::exit(1);
        }
    }
}

Note that last two examples do hide error contexts from anyhow and do not pretty print if source() of the error is edgedb_errors::Error but not the top-level one. We leave those more complex cases as an excersize to the reader.

Re-exports§

Modules§

  • Connection state modification utilities
  • EdgeDB Rust client tutorial

Structs§

Enums§

Functions§

  • Create a connection to the database with default parameters

Derive Macros§