Write SQL queries in a simple and composable way.

The main goal of this library is to find the best balance between write idiomatic SQL queries and manage cenarios of complex query composition. Try in a large query and you will understand what this lib can do for you.

Quick Start

```rust use sqlquerybuilder::SelectBuilder;

let mut select = SelectBuilder::new() .select("id, login") .from("users") .where_clause("login = $1");

let id = Some(123);

if let Some(id) = id { select = select.and("id = $2"); }

let query = select.as_string();

println!("{}", query); ```

Output

sql SELECT id, login FROM users WHERE login = $1 AND id = $2

In simple terms this library will not try to undestand what you are writing, for one side this is good because it's removes a lot complexity and verbosity that other libraries needs to generate a SQL query, for another side debug tends to be more dificult based on the same arguments. The lib has .debug() method to minimize the effort to debug a complex query.

How it's works

Consecutive calls to the same clause will accumulates values respecting the order of the calls, the two select produce the same SQL query

```rust use sqlquerybuilder::SelectBuilder;

let select = SelectBuilder::new() .select("id, login");

let select = SelectBuilder::new() .select("id") .select("login"); ```

Methods like limit and offset will override the previous value, the two select produce the same SQL query

```rust use sqlquerybuilder::SelectBuilder;

let select = SelectBuilder::new() .limit("123");

let select = SelectBuilder::new() .limit("1000") .limit("123"); ```

The library ignores the order between clauses so the two selects produce the same SQL query

```rust use sqlquerybuilder::SelectBuilder;

let select = SelectBuilder::new() .select("id, login") .from("users") .where_clause("login = $1");

let select = SelectBuilder::new() .from("users") .where_clause("login = $1") .select("id, login"); ```

You can dynamically add a clause mutating the select

```rust use sqlquerybuilder::SelectBuilder;

let mut select = SelectBuilder::new() .select("id, login") .from("users") .where_clause("login = $1");

let shouldIncludesAddress = true;

if shouldIncludesAddress { select = select.innerjoin("address on user.login = address.ownerlogin"); } ```

Composition

Composition is very welcome to write complex queries, this feature makes the library shine

```rust use sqlquerybuilder::SelectBuilder;

fn project(select: SelectBuilder) -> SelectBuilder { select .select("u.id, u.name as username, u.login") .select("a.name as addressname") .select("o.name as product_name") }

fn joins(select: SelectBuilder) -> SelectBuilder { select .from("users u") .innerjoin("address a ON a.userlogin = u.login") .innerjoin("orders o ON o.userlogin = u.login") }

fn conditions(select: SelectBuilder) -> SelectBuilder { select.where_clause("u.login = $1").and("o.id = $2") }

fn asstring(select: SelectBuilder) -> String { select.asstring() }

let query = Some(SelectBuilder::new()) .map(project) .map(joins) .map(conditions) .map(as_string) .unwrap();

println!("{}", query); ```

Output (indented for redability)

sql SELECT u.id, u.name as user_name, u.login, a.name as address_name, o.name as product_name FROM users u INNER JOIN address a ON a.user_login = u.login INNER JOIN orders o ON o.user_login = u.login WHERE u.login = $1 AND o.id = $2