#rusqlite #async-executor #thread #async-task #async-context #tiny #closures

async-rusqlite

A tiny executor agnostic wrapper around rusqlite to make calls to it async

3 releases (breaking)

0.4.0 Aug 30, 2023
0.3.0 May 7, 2023
0.1.0 May 1, 2023

#1769 in Database interfaces

Download history 5/week @ 2024-07-20 85/week @ 2024-07-27 20/week @ 2024-08-03 130/week @ 2024-08-10 148/week @ 2024-08-17 147/week @ 2024-08-24 140/week @ 2024-08-31 62/week @ 2024-09-07 126/week @ 2024-09-14 67/week @ 2024-09-21 57/week @ 2024-09-28 121/week @ 2024-10-05 115/week @ 2024-10-12 86/week @ 2024-10-19 384/week @ 2024-10-26 209/week @ 2024-11-02

851 downloads per month
Used in sqliter

MIT license

18KB
242 lines

async-rusqlite

A tiny, executor agnostic library for using rusqlite in async contexts. This essentially just spawns an rusqlite onto a long lived thread and sends closures to that thread to operate on it.

This library is inspired by tokio-rusqlite, but with the following design differences:

  • Executor agnostic; can be used with tokio, async-std or whatever else.
  • Bounded channels; tokio-rusqlite uses an unbounded channel to send messages to the rusqlite thread. This library uses bounded channels to allow backpressure to propagate back to the async task if the database is unable to keep up with the calls made to it.
  • Fewer dependencies; aside from rusqlite, the tree of additional dependencies bought in is 1 (asyncified, which in itself is very small).

If you don't care about the above, prefer tokio-rusqlite, which is more heavily battle tested and relies on the venerable crossbeam-channel rather than my own fairly naive channel implementations in asyncified.

use async_rusqlite::Connection;

#[derive(Debug)]
struct Person {
    id: i32,
    name: String,
    data: Option<Vec<u8>>,
}

let conn = Connection::open_in_memory().await?;

conn.call(|conn| {
    conn.execute(
        "CREATE TABLE person (
            id   INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            data BLOB
        )",
        (),
    )
}).await?;

let me = Person {
    id: 0,
    name: "Steven".to_string(),
    data: None,
};

conn.call(move |conn| {
    conn.execute(
        "INSERT INTO person (name, data) VALUES (?1, ?2)",
        (&me.name, &me.data),
    )
}).await?;

Dependencies

~22MB
~424K SLoC