sqlb is a simple and expressive SQLBuilder for Rust for sqlx, focusing on PostgreSQL (for now).

NOTE 1: sqlb 0.3.x is designed to work with sqlx 0.6.x.
Currently, I'm working on sqlb 0.4.x for sqlx 0.7.x. However, as of sqlx 0.7.1, there's an issue affecting some application unit tests where I encounter Sqlx(PoolTimedOut) whenever max_connections is set to more than one. I'm currently in the process of isolating and investigating this issue. (Note from July 26, 2023) See similar sqlx issue #2567.

NOTE 2: SQL Builders are typically not used directly by application business logic, but rather to be wrapped in some Application Model Access Layer (e.g., DAOs or MCs - Model Controller - patterns). Even when using ORMs, it is often a good code design to wrap those access via some model access layers.

NOTE 3: sqlb has the feature runtime-tokio-rustls enabled by the sqlx crate. Do not enable a conflicting runtime feature when adding sqlx to your project.

NOTE 4: During the 0.y.z period, API changes will result in .y increments.

Goals for first 0.y.z releases:

Early API Example (just conceptual for now)

``rust //sqlx::FromRowallows to do sqlx_exec::fetch_as... //sqlb::Fieldsallows to have: // -toto.fields()(name, value)[] (only direct or NOT Not values) // -Todo::field_names()here would return["id", "title"]`

[derive(sqlx::FromRow, sqlb::Fields)]

pub struct Todo { id: i64,

title: String,
#[field(name="description")]
desc: Option<String>,

#[field(skip)]
someting_else: String,

}

[derive(sqlb::Fields)]

pub struct TodoForCreate { title: String, desc: Option,

#[field(skip)]
someting_else: String,

}

[derive(sqlb::Fields)]

pub struct TodoForUpdate { title: Option, desc: Option, }

// -- Get the field names let fieldnames = Todo::fieldnames(); // ["id", "title", "description"]

// -- Create new row let todoc = TodoForCreate { title: "title 01".tostring(), desc: "desc 01".tostring() }; // will update all fields specified in TodoForCreate let sb = sqlb::insert().table("todo").data(todoc.allfields()); let sb = sb.returning(&["id", "title"]); let (id, title) = sb.fetchone::<_, (i64, String)>(&dbpool).await?;

// -- Select let sb = sqlb::select().table("todo").columns(Todo::fieldnames()).orderby("!id"); let todos: Vec = sb.fetchasall(&db_pool).await?;

// -- Update let todou - TodoForUpdate { desc: "Updated desc 01".tostring()}; let sb = sqlb::update().table("todo").data(todou.notnonefields()).andwhereeq("id", 123); let rowaffected = sb.exec(&db_pool).await?; // will not update .title because of the use of .not_none_fields(). ```

Thanks

Open source is awesome! Feel free to enter ticket, ask questions, or do PR (concise and focused).

Happy coding!

Changelog

! breaking change, + addition, - fix.

For sqlb Dev

Start a PostgreSQL

```sh

In terminal 1 - start postges

docker run --rm --name pg -p 5432:5432 -e POSTGRES_PASSWORD=welcome postgres:15

In terminal 2 - (optional) launch psql on the Postgres instance above

docker exec -it -u postgres pg psql

In terminal 3 -

cargo test

or watch a particular test target

cargo watch -q -c -x 'test --test testsbinsert ```


sqlb github repo