No description
Find a file
2019-07-26 15:10:50 -07:00
examples Move main.rs to examples/postgres 2019-07-26 09:20:09 -07:00
mason-mariadb WIP: Cleanup serializations 2019-07-26 15:10:50 -07:00
src Add a single encode benchmark 2019-07-26 10:03:53 -07:00
.editorconfig Initial low-level connection interface 2019-06-07 15:34:21 -07:00
.gitignore Initial low-level connection interface 2019-06-07 15:34:21 -07:00
Cargo.toml WIP: Mariadb initial handshake packet 2019-07-26 15:10:18 -07:00
README.md mason -> sqlx 2019-06-22 20:54:43 -07:00
rust-toolchain Update Rust and dependencies 2019-07-17 22:04:38 -07:00
rustfmt.toml Remove use_small_heuristics 2019-06-28 21:35:12 -07:00

sqlx

Asynchronous and expressive database client in pure Rust

This is an experiment being worked on in stages. The first stage will be a very low-level, generic database driver (hopefully) capable of basic execution of simple queries.

Usage

What follows is experimental usage (for thinking on API design) that is not currently implemented.

#![feature(async_await)]

use sqlx::pg::Connection;

#[runtime::main]
async fn main() -> Result<(), failure::Error> {
    // this will likely be something like eventually:
    //  sqlx::Connection::<Pg>::establish(...)

    let mut conn = Connection::establish(ConnectOptions::new().user("postgres")).await?;
    // or: Connection::establish("postgres://postgres@localhost/").await?;
    // or: ConnectOptions::new().user("postgres").establish().await?;

    // Execute a "simple" query. Can consist of N statements separated by semicolons.
    // No results are returned.

    conn.execute("CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY, name TEXT NOT NULL );")
        .await?;

    // prepare() -> Statement
    //  - A `Statement` can be cached and re-bound later for improved performance
    conn.prepare("SELECT id FROM users WHERE name ilike $1")
        // bind() -> Cursor (named [Cursor] in mysql or sqlite but [Portal] in postgres)
        .bind(&["bob"])
        // execute() -> u64
        //  - execute may be used instead of fetch to ignore all results and only
        //    return the "affected" rows
        // fetch() -> Stream<Item = Row>
        .fetch()
        .collect::<Vec<Row>>()
        .await?;

    // Close is not strictly needed but this makes sure any pending writes to the connection
    // are flushed and gracefully closes the connection

    conn.close().await?;

    Ok(())
}

Notes

  • AsyncDrop - Many of the envisoned APIs would greatly benefit from something like this. There are cases where an object must be closed or it would be a memory leak (in either the client or server). I intended to provide both an async fn close() and a sync Drop impl that blocks the thread and shouts a warning.. but that is obviously not ideal.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.