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.
```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.
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 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