sqlutil 0.1.5

A utility library for building SQL queries
Documentation
use crate::{build_select_sql, make_column, make_order, make_table, make_where};

pub fn make_query(
    tables: &[&str],
    columns: Option<&[&str]>,
    wheres: Option<&[&str]>,
    orders: Option<&[&str]>,
    offset: Option<i64>,
    limit: Option<i64>,
) -> String {
    let table_sql = make_table(tables);
    let column_sql = columns.map(make_column);
    let where_sql = wheres.map(make_where);
    let order_sql = orders.map(make_order);

    build_select_sql(
        &table_sql,
        column_sql.as_deref(),
        where_sql.as_deref(),
        order_sql.as_deref(),
        offset,
        limit,
    )
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_make_query_all_defaults() {
        let sql = make_query(&["users"], None, None, None, None, None);
        assert_eq!(sql, "SELECT * FROM \"users\"");
    }

    #[test]
    fn test_make_query_with_columns() {
        let sql = make_query(&["users"], Some(&["id", "name", "email"]), None, None, None, None);
        assert_eq!(sql, "SELECT id , name , email FROM \"users\"");
    }

    #[test]
    fn test_make_query_with_single_column() {
        let sql = make_query(&["users"], Some(&["id"]), None, None, None, None);
        assert_eq!(sql, "SELECT id FROM \"users\"");
    }

    #[test]
    fn test_make_query_with_explicit_wildcard() {
        let sql = make_query(&["users"], Some(&["*"]), None, None, None, None);
        assert_eq!(sql, "SELECT * FROM \"users\"");
    }

    #[test]
    fn test_make_query_with_single_where() {
        let sql = make_query(&["users"], None, Some(&["active = 1"]), None, None, None);
        assert_eq!(sql, "SELECT * FROM \"users\" WHERE active = 1");
    }

    #[test]
    fn test_make_query_with_multiple_where() {
        let sql = make_query(
            &["users"],
            None,
            Some(&["active = 1", "age > 18"]),
            None,
            None,
            None,
        );
        assert_eq!(sql, "SELECT * FROM \"users\" WHERE active = 1 AND age > 18");
    }

    #[test]
    fn test_make_query_with_three_where_conditions() {
        let sql = make_query(
            &["users"],
            None,
            Some(&["active = 1", "age > 18", "role = 'admin'"]),
            None,
            None,
            None,
        );
        assert_eq!(
            sql,
            "SELECT * FROM \"users\" WHERE active = 1 AND age > 18 AND role = 'admin'"
        );
    }

    #[test]
    fn test_make_query_with_order() {
        let sql = make_query(&["users"], None, None, Some(&["created_at DESC"]), None, None);
        assert_eq!(sql, "SELECT * FROM \"users\" ORDER BY created_at DESC");
    }

    #[test]
    fn test_make_query_with_multiple_orders() {
        let sql = make_query(
            &["users"],
            None,
            None,
            Some(&["created_at DESC", "id ASC"]),
            None,
            None,
        );
        assert_eq!(sql, "SELECT * FROM \"users\" ORDER BY created_at DESC , id ASC");
    }

    #[test]
    fn test_make_query_with_limit_only() {
        let sql = make_query(&["users"], None, None, None, None, Some(10));
        assert_eq!(sql, "SELECT * FROM \"users\" LIMIT 10");
    }

    #[test]
    fn test_make_query_with_offset_only() {
        let sql = make_query(&["users"], None, None, None, Some(20), None);
        assert_eq!(sql, "SELECT * FROM \"users\" OFFSET 20");
    }

    #[test]
    fn test_make_query_with_offset_and_limit() {
        let sql = make_query(&["users"], None, None, None, Some(10), Some(5));
        assert_eq!(sql, "SELECT * FROM \"users\" OFFSET 10 LIMIT 5");
    }

    #[test]
    fn test_make_query_zero_offset_zero_limit() {
        let sql = make_query(&["users"], None, None, None, Some(0), Some(0));
        assert_eq!(sql, "SELECT * FROM \"users\" OFFSET 0 LIMIT 0");
    }

    #[test]
    fn test_make_query_full() {
        let sql = make_query(
            &["orders"],
            Some(&["id", "total", "status"]),
            Some(&["user_id = 42", "status != 'cancelled'"]),
            Some(&["created_at DESC", "id ASC"]),
            Some(0),
            Some(25),
        );
        assert_eq!(
            sql,
            "SELECT id , total , status FROM \"orders\" WHERE user_id = 42 AND status != 'cancelled' ORDER BY created_at DESC , id ASC OFFSET 0 LIMIT 25"
        );
    }

    #[test]
    fn test_make_query_multiple_tables() {
        // make_table joins with " , " so the combined string is quoted as one identifier
        let sql = make_query(&["users", "orders"], None, None, None, None, None);
        assert_eq!(sql, "SELECT * FROM \"users , orders\"");
    }

    #[test]
    fn test_make_query_empty_where_slice() {
        // empty wheres slice → make_where returns "" → build_select_sql skips WHERE
        let sql = make_query(&["users"], None, Some(&[]), None, None, None);
        assert_eq!(sql, "SELECT * FROM \"users\"");
    }

    #[test]
    fn test_make_query_empty_order_slice() {
        // empty orders slice → make_order returns "" → build_select_sql skips ORDER BY
        let sql = make_query(&["users"], None, None, Some(&[]), None, None);
        assert_eq!(sql, "SELECT * FROM \"users\"");
    }

    #[test]
    fn test_make_query_columns_and_where() {
        let sql = make_query(
            &["products"],
            Some(&["id", "name", "price"]),
            Some(&["price > 100"]),
            None,
            None,
            None,
        );
        assert_eq!(
            sql,
            "SELECT id , name , price FROM \"products\" WHERE price > 100"
        );
    }

    #[test]
    fn test_make_query_where_and_order() {
        let sql = make_query(
            &["users"],
            None,
            Some(&["active = 1"]),
            Some(&["name ASC"]),
            None,
            None,
        );
        assert_eq!(
            sql,
            "SELECT * FROM \"users\" WHERE active = 1 ORDER BY name ASC"
        );
    }

    #[test]
    fn test_make_query_order_and_limit() {
        let sql = make_query(
            &["posts"],
            None,
            None,
            Some(&["published_at DESC"]),
            None,
            Some(5),
        );
        assert_eq!(
            sql,
            "SELECT * FROM \"posts\" ORDER BY published_at DESC LIMIT 5"
        );
    }
}