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 std::time::Instant;
use tegdb::Database;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== TegDB Streaming API Integration Demo ===\n");

    // Create database with optimized streaming performance
    let mut db = Database::open("file:///tmp/demo_streaming_integration.teg")?;

    // Create test table
    println!("1. Creating test table with streaming-optimized structure...");
    db.execute(
        "CREATE TABLE large_dataset (
        id INTEGER PRIMARY KEY,
        name TEXT(32),
        category TEXT(32),
        value REAL,
        description TEXT(32)
    )",
    )?;

    // Insert test data in batches for better performance
    println!("2. Inserting test data (demonstrating streaming benefits)...");

    let batch_size = 1000;
    let total_records = 5000;

    let start_insert = Instant::now();

    for batch in 0..(total_records / batch_size) {
        let mut tx = db.begin_transaction()?;

        for i in 0..batch_size {
            let id = batch * batch_size + i + 1;
            let category = if id % 3 == 0 {
                "premium"
            } else if id % 3 == 1 {
                "standard"
            } else {
                "basic"
            };

            tx.execute(&format!(
                "INSERT INTO large_dataset (id, name, category, value, description) VALUES ({}, 'Item {}', '{}', {:.2}, 'Description for item {}')",
                id, id, category, (id as f64) * 1.5, id
            ))?;
        }

        tx.commit()?;
        println!(
            "  ✓ Inserted batch {} ({} records)",
            batch + 1,
            (batch + 1) * batch_size
        );
    }

    let insert_duration = start_insert.elapsed();
    println!("  ✓ Total insertion time: {insert_duration:?}\n");

    // Test streaming query performance
    println!("3. Testing streaming query performance...");

    // Test 1: Full table scan with streaming
    println!("\n--- Test 1: Full Table Scan (Streaming) ---");
    let start = Instant::now();
    let result = db
        .query("SELECT id, name, category, value FROM large_dataset")
        .unwrap();
    let duration = start.elapsed();

    println!("✓ Query executed in: {duration:?}");
    println!("✓ Returned {} rows", result.rows().len());
    println!("✓ Memory usage optimized through streaming execution");

    // Test 2: Filtered query with streaming benefits
    println!("\n--- Test 2: Filtered Query (Streaming Benefits) ---");
    let start = Instant::now();
    let result = db
        .query("SELECT id, name, value FROM large_dataset WHERE category = 'premium'")
        .unwrap();
    let duration = start.elapsed();

    println!("✓ Filtered query executed in: {duration:?}");
    println!("✓ Returned {} premium items", result.rows().len());
    println!("✓ Streaming allows early filtering without loading all data");

    // Test 3: Limited query (demonstrating early termination)
    println!("\n--- Test 3: Limited Query (Early Termination) ---");
    let start = Instant::now();
    let result = db
        .query("SELECT id, name, category FROM large_dataset LIMIT 10")
        .unwrap();
    let duration = start.elapsed();

    println!("✓ Limited query executed in: {duration:?}");
    println!("✓ Returned {} rows (limited)", result.rows().len());
    println!("✓ Streaming enables early termination for LIMIT queries");

    // Test 4: Complex query with streaming
    println!("\n--- Test 4: Complex Query (Streaming Processing) ---");
    let start = Instant::now();
    let result = db
        .query("SELECT id, name, category FROM large_dataset WHERE value > 1000.0")
        .unwrap();
    let duration = start.elapsed();

    println!("✓ Complex query executed in: {duration:?}");
    println!("✓ Found {} items with value > 1000.0", result.rows().len());
    println!("✓ Streaming processes filter conditions efficiently");

    // Test 5: Transaction with streaming queries
    println!("\n--- Test 5: Transaction with Streaming Queries ---");
    let mut tx = db.begin_transaction()?;

    let start = Instant::now();
    let result1 = tx
        .query("SELECT id, name FROM large_dataset WHERE category = 'standard' LIMIT 5")
        .unwrap();
    let result2 = tx
        .query("SELECT id, value FROM large_dataset WHERE category = 'premium' LIMIT 5")
        .unwrap();
    let duration = start.elapsed();

    println!("✓ Transaction queries executed in: {duration:?}");
    println!(
        "✓ Standard items sample: {} rows returned",
        result1.rows().len()
    );
    println!(
        "✓ Premium items sample: {} rows returned",
        result2.rows().len()
    );

    tx.commit()?;

    // Performance comparison summary
    println!("\n=== Streaming API Integration Summary ===");
    println!("✓ Database.query() now uses execute_plan_streaming() internally");
    println!("✓ DatabaseTransaction.query() now uses execute_plan_streaming() internally");
    println!("✓ All SELECT operations benefit from streaming execution");
    println!("✓ Memory efficiency improved for large datasets");
    println!("✓ Early termination works for LIMIT queries");
    println!("✓ Filtering happens during streaming (not after loading)");
    println!("✓ Compatible with existing Database API");
    println!("✓ Works seamlessly with transactions");

    // Architecture notes
    println!("\n=== Streaming API Architecture ===");
    println!("1. Database.query() -> QueryPlanner -> execute_plan_streaming()");
    println!("2. StreamingResult -> StreamingResultSet -> collect_rows()");
    println!("3. RowIterator provides lazy evaluation and filtering");
    println!("4. Native row format optimizes streaming performance");
    println!("5. Backward compatible with existing QueryResult interface");

    // Clean up
    std::fs::remove_file("demo_streaming_integration.db").ok();

    println!("\n🎉 Streaming API integration demonstration complete!");
    Ok(())
}