tegdb 0.5.0

The name TegridyDB (short for TegDB) is inspired by the Tegridy Farm in South Park and tries to correct some of the wrong database implementations, such as null support, implicit conversion support, etc.
Documentation
use tegdb::parser::{parse_sql, Statement};

/// Test parsing BEGIN statements
#[test]
fn test_parse_begin() {
    // Test basic BEGIN
    let sql = "BEGIN";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Begin));

    // Test case insensitive
    let sql = "begin";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Begin));

    // Test with extra spaces
    let sql = "  BEGIN  ";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Begin));
}

/// Test parsing START TRANSACTION statements
#[test]
fn test_parse_start_transaction() {
    // Test START TRANSACTION
    let sql = "START TRANSACTION";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Begin));

    // Test case insensitive
    let sql = "start transaction";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Begin));

    // Test mixed case
    let sql = "Start Transaction";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Begin));

    // Test with extra spaces
    let sql = "  START    TRANSACTION  ";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Begin));
}

/// Test parsing COMMIT statements
#[test]
fn test_parse_commit() {
    // Test basic COMMIT
    let sql = "COMMIT";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Commit));

    // Test case insensitive
    let sql = "commit";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Commit));

    // Test with extra spaces
    let sql = "  COMMIT  ";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Commit));
}

/// Test parsing ROLLBACK statements
#[test]
fn test_parse_rollback() {
    // Test basic ROLLBACK
    let sql = "ROLLBACK";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Rollback));

    // Test case insensitive
    let sql = "rollback";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Rollback));

    // Test with extra spaces
    let sql = "  ROLLBACK  ";
    let result = parse_sql(sql);
    assert!(result.is_ok());
    let statement = result.unwrap();
    assert!(matches!(statement, Statement::Rollback));
}

/// Test transaction statement priority in parsing
#[test]
fn test_transaction_statement_priority() {
    // Verify that transaction statements are parsed correctly
    // even when they might conflict with other keywords

    let statements = vec!["BEGIN", "COMMIT", "ROLLBACK", "START TRANSACTION"];

    for sql in statements {
        let result = parse_sql(sql);
        assert!(result.is_ok(), "Failed to parse: {sql}");
        let statement = result.unwrap();

        match sql {
            "BEGIN" | "START TRANSACTION" => assert!(matches!(statement, Statement::Begin)),
            "COMMIT" => assert!(matches!(statement, Statement::Commit)),
            "ROLLBACK" => assert!(matches!(statement, Statement::Rollback)),
            _ => panic!("Unexpected SQL statement: {sql}"),
        }
    }
}

/// Test invalid transaction statements
#[test]
fn test_invalid_transaction_statements() {
    let invalid_statements = vec![
        "BEGINS",          // Invalid variant
        "COMMITS",         // Invalid variant
        "ROLLBACKS",       // Invalid variant
        "START",           // Incomplete
        "TRANSACTION",     // Incomplete
        "BEGIN COMMIT",    // Mixed statements
        "COMMIT ROLLBACK", // Mixed statements
    ];

    for sql in invalid_statements {
        let result = parse_sql(sql);
        // These should either fail to parse or parse as something else
        if result.is_ok() {
            // If it parses, that's unexpected for invalid statements
            panic!("Unexpected successful parse for: {sql}");
        }
        // Otherwise it failed to parse, which is expected
    }
}