sqlutil 0.1.7

A utility library for building SQL queries
Documentation
use crate::{build_delete_sql, make_where};

pub fn make_delete(table: &str, wheres: Option<&[&str]>) -> String {
    build_delete_sql(table, wheres.map(make_where).as_deref())
}
#[cfg(test)]
mod tests {
    use super::*;

    // ── No WHERE clause ──────────────────────────────────────────────────────

    #[test]
    fn test_delete_no_where_none() {
        // None → DELETE FROM "table" with no WHERE clause
        let sql = make_delete("users", None);
        assert_eq!(sql, r#"DELETE FROM "users""#);
    }

    #[test]
    fn test_delete_no_where_empty_slice() {
        // Some(&[]) → make_where returns "" → build_delete_sql treats it as
        // a non-None but empty string, which is trimmed away
        let sql = make_delete("orders", Some(&[]));
        assert_eq!(sql, r#"DELETE FROM "orders""#);
    }

    // ── Single WHERE condition ───────────────────────────────────────────────

    #[test]
    fn test_delete_single_where() {
        let sql = make_delete("users", Some(&["id = 1"]));
        assert_eq!(sql, r#"DELETE FROM "users" WHERE id = 1"#);
    }

    #[test]
    fn test_delete_single_where_string_value() {
        let sql = make_delete("sessions", Some(&["token = 'abc123'"]));
        assert_eq!(sql, r#"DELETE FROM "sessions" WHERE token = 'abc123'"#);
    }

    // ── Multiple WHERE conditions ────────────────────────────────────────────

    #[test]
    fn test_delete_two_where_conditions() {
        let sql = make_delete("users", Some(&["active = 0", "age < 18"]));
        assert_eq!(sql, r#"DELETE FROM "users" WHERE active = 0 AND age < 18"#);
    }

    #[test]
    fn test_delete_three_where_conditions() {
        let sql = make_delete(
            "logs",
            Some(&[
                "level = 'debug'",
                "created_at < '2024-01-01'",
                "app = 'api'",
            ]),
        );
        assert_eq!(
            sql,
            r#"DELETE FROM "logs" WHERE level = 'debug' AND created_at < '2024-01-01' AND app = 'api'"#
        );
    }

    // ── Table name quoting ───────────────────────────────────────────────────

    #[test]
    fn test_delete_table_with_schema() {
        let sql = make_delete("public.users", None);
        assert_eq!(sql, r#"DELETE FROM "public.users""#);
    }

    #[test]
    fn test_delete_table_with_double_quotes_escaped() {
        // A table name that contains a double-quote should be escaped as ""
        let sql = make_delete(r#"weird"table"#, None);
        assert_eq!(sql, r#"DELETE FROM "weird""table""#);
    }

    #[test]
    fn test_delete_table_with_spaces() {
        let sql = make_delete("my table", None);
        assert_eq!(sql, r#"DELETE FROM "my table""#);
    }

    // ── WHERE clause edge cases ──────────────────────────────────────────────

    #[test]
    fn test_delete_where_whitespace_only_condition() {
        // make_where joins with AND, so a single whitespace string produces "   "
        // build_delete_sql trims and skips it
        let sql = make_delete("users", Some(&["   "]));
        assert_eq!(sql, r#"DELETE FROM "users""#);
    }

    #[test]
    fn test_delete_where_condition_with_in_clause() {
        let sql = make_delete("products", Some(&["id IN (1, 2, 3)"]));
        assert_eq!(sql, r#"DELETE FROM "products" WHERE id IN (1, 2, 3)"#);
    }

    #[test]
    fn test_delete_where_condition_with_subquery() {
        let sql = make_delete(
            "orders",
            Some(&["user_id IN (SELECT id FROM users WHERE active = 0)"]),
        );
        assert_eq!(
            sql,
            r#"DELETE FROM "orders" WHERE user_id IN (SELECT id FROM users WHERE active = 0)"#
        );
    }

    #[test]
    fn test_delete_where_is_null() {
        let sql = make_delete("events", Some(&["deleted_at IS NULL"]));
        assert_eq!(sql, r#"DELETE FROM "events" WHERE deleted_at IS NULL"#);
    }

    #[test]
    fn test_delete_where_between() {
        let sql = make_delete(
            "metrics",
            Some(&["recorded_at BETWEEN '2024-01-01' AND '2024-12-31'"]),
        );
        assert_eq!(
            sql,
            r#"DELETE FROM "metrics" WHERE recorded_at BETWEEN '2024-01-01' AND '2024-12-31'"#
        );
    }

    // ── Return type ──────────────────────────────────────────────────────────

    #[test]
    fn test_delete_returns_string() {
        // Ensure the function signature returns an owned String
        let result: String = make_delete("t", None);
        assert!(!result.is_empty());
    }

    #[test]
    fn test_delete_starts_with_delete_from() {
        let sql = make_delete("anything", None);
        assert!(sql.starts_with("DELETE FROM"));
    }
}