matdb 0.1.0

An experimental embedded SQL-like DBMS
Documentation
use std::collections::BTreeMap;

use matdb::{Db, Value};
use rand::{seq::IteratorRandom, SeedableRng};
use rand_chacha::ChaCha12Rng;

fn setup() -> (BTreeMap<i64, i64>, Db) {
    let mut db = Db::open_memory().unwrap();

    db.run(
        "CREATE TABLE t0 ( c0 INT PRIMARY KEY, c1 INT );",
        Vec::new(),
    )
    .unwrap();

    let mut our = BTreeMap::new();

    for (k, v) in (0..1000i64).zip((0..1000i64).rev()) {
        our.insert(k, v);
        db.run(
            &format!("INSERT INTO t0 (c0, c1) VALUES ({k}, {v});"),
            Vec::new(),
        )
        .unwrap();
    }

    (our, db)
}

fn cleanup(our: BTreeMap<i64, i64>, mut db: Db) {
    assert!(our.is_empty());
    assert!(db
        .run("SELECT c0, c1 FROM t0;", Vec::new())
        .unwrap()
        .unwrap()
        .rows
        .is_empty());
}

#[test]
fn delete_sequnetial_rising() {
    let (mut our, mut db) = setup();

    for k in 0..1000i64 {
        our.remove(&k);
        db.run(&format!("DELETE FROM t0 WHERE c0 = {k};"), Vec::new())
            .unwrap();

        for (row, our_pair) in db
            .run("SELECT c0, c1 FROM t0;", Vec::new())
            .unwrap()
            .unwrap()
            .rows
            .iter()
            .zip(our.iter())
        {
            assert_eq!(row.as_slice()[0], Value::Int(*our_pair.0));
            assert_eq!(row.as_slice()[1], Value::Int(*our_pair.1));
        }
    }

    cleanup(our, db);
}

#[test]
fn delete_sequnetial_decreasing() {
    let (mut our, mut db) = setup();

    for k in (0..1000i64).rev() {
        our.remove(&k);
        db.run(&format!("DELETE FROM t0 WHERE c0 = {k};"), Vec::new())
            .unwrap();

        for (row, our_pair) in db
            .run("SELECT c0, c1 FROM t0;", Vec::new())
            .unwrap()
            .unwrap()
            .rows
            .iter()
            .zip(our.iter())
        {
            assert_eq!(row.as_slice()[0], Value::Int(*our_pair.0));
            assert_eq!(row.as_slice()[1], Value::Int(*our_pair.1));
        }
    }

    cleanup(our, db);
}

#[test]
fn delete_seeded_random() {
    for seed in [2524, 8131, 3600, 1082, 6081, 6583] {
        let (mut our, mut db) = setup();

        let mut rng = ChaCha12Rng::seed_from_u64(seed);

        while let Some(k) = our.keys().choose(&mut rng).cloned() {
            our.remove(&k);
            db.run(&format!("DELETE FROM t0 WHERE c0 = {k};"), Vec::new())
                .unwrap();

            for (row, our_pair) in db
                .run("SELECT c0, c1 FROM t0;", Vec::new())
                .unwrap()
                .unwrap()
                .rows
                .iter()
                .zip(our.iter())
            {
                assert_eq!(row.as_slice()[0], Value::Int(*our_pair.0));
                assert_eq!(row.as_slice()[1], Value::Int(*our_pair.1));
            }
        }

        cleanup(our, db);
    }
}