use stoolap::Database;
#[test]
fn test_btree_index_sql() {
let db = Database::open("memory://btree_idx").expect("Failed to create database");
db.execute(
"CREATE TABLE test_btree (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER,
active BOOLEAN
)",
(),
)
.expect("Failed to create table");
db.execute("INSERT INTO test_btree VALUES (1, 'Alice', 30, true)", ())
.expect("Failed to insert row 1");
db.execute("INSERT INTO test_btree VALUES (2, 'Bob', 25, false)", ())
.expect("Failed to insert row 2");
db.execute("INSERT INTO test_btree VALUES (3, 'Charlie', 40, true)", ())
.expect("Failed to insert row 3");
db.execute("CREATE INDEX idx_age ON test_btree (age)", ())
.expect("Failed to create index on age");
let result = db
.query("SELECT * FROM test_btree WHERE age = 25", ())
.expect("Failed to execute query");
let mut count = 0;
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
let name: String = row.get(1).unwrap();
let age: i64 = row.get(2).unwrap();
let active: bool = row.get(3).unwrap();
count += 1;
assert_eq!(id, 2, "Expected id 2");
assert_eq!(name, "Bob", "Expected name Bob");
assert_eq!(age, 25, "Expected age 25");
assert!(!active, "Expected active false");
}
assert_eq!(count, 1, "Expected 1 row for age = 25");
db.execute("DROP INDEX idx_age ON test_btree", ())
.expect("Failed to drop index");
let result = db
.query("SELECT * FROM test_btree WHERE age = 25", ())
.expect("Failed to execute query after dropping index");
let mut post_drop_count = 0;
for _ in result {
post_drop_count += 1;
}
assert_eq!(
post_drop_count, 1,
"Expected 1 row after dropping index, got {}",
post_drop_count
);
}
#[test]
fn test_btree_index_range() {
let db = Database::open("memory://btree_range").expect("Failed to create database");
db.execute(
"CREATE TABLE range_test (
id INTEGER PRIMARY KEY,
value INTEGER
)",
(),
)
.expect("Failed to create table");
for i in 1..=10 {
db.execute(
"INSERT INTO range_test (id, value) VALUES (?, ?)",
(i, i * 10),
)
.expect("Failed to insert");
}
db.execute("CREATE INDEX idx_value ON range_test (value)", ())
.expect("Failed to create index");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM range_test WHERE value > 50", ())
.expect("Failed to count");
assert_eq!(count, 5, "Expected 5 rows with value > 50");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM range_test WHERE value < 50", ())
.expect("Failed to count");
assert_eq!(count, 4, "Expected 4 rows with value < 50");
let count: i64 = db
.query_one(
"SELECT COUNT(*) FROM range_test WHERE value BETWEEN 30 AND 70",
(),
)
.expect("Failed to count");
assert_eq!(count, 5, "Expected 5 rows with value BETWEEN 30 AND 70");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM range_test WHERE value >= 50", ())
.expect("Failed to count");
assert_eq!(count, 6, "Expected 6 rows with value >= 50");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM range_test WHERE value <= 50", ())
.expect("Failed to count");
assert_eq!(count, 5, "Expected 5 rows with value <= 50");
}
#[test]
fn test_btree_index_nulls() {
let db = Database::open("memory://btree_nulls").expect("Failed to create database");
db.execute(
"CREATE TABLE null_test (
id INTEGER PRIMARY KEY,
score INTEGER
)",
(),
)
.expect("Failed to create table");
db.execute("INSERT INTO null_test VALUES (1, 100)", ())
.unwrap();
db.execute("INSERT INTO null_test VALUES (2, 200)", ())
.unwrap();
db.execute("INSERT INTO null_test VALUES (3, NULL)", ())
.unwrap();
db.execute("INSERT INTO null_test VALUES (4, 100)", ())
.unwrap();
db.execute("INSERT INTO null_test VALUES (5, NULL)", ())
.unwrap();
db.execute("CREATE INDEX idx_score ON null_test (score)", ())
.expect("Failed to create index");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM null_test WHERE score IS NULL", ())
.expect("Failed to count");
assert_eq!(count, 2, "Expected 2 rows with NULL score");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM null_test WHERE score IS NOT NULL", ())
.expect("Failed to count");
assert_eq!(count, 3, "Expected 3 rows with non-NULL score");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM null_test WHERE score = 100", ())
.expect("Failed to count");
assert_eq!(count, 2, "Expected 2 rows with score = 100");
}
#[test]
fn test_btree_index_updates() {
let db = Database::open("memory://btree_updates").expect("Failed to create database");
db.execute(
"CREATE TABLE update_test (
id INTEGER PRIMARY KEY,
priority INTEGER
)",
(),
)
.expect("Failed to create table");
db.execute("INSERT INTO update_test VALUES (1, 1)", ())
.unwrap();
db.execute("INSERT INTO update_test VALUES (2, 1)", ())
.unwrap();
db.execute("INSERT INTO update_test VALUES (3, 2)", ())
.unwrap();
db.execute("CREATE INDEX idx_priority ON update_test (priority)", ())
.expect("Failed to create index");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM update_test WHERE priority = 1", ())
.expect("Failed to count");
assert_eq!(count, 2, "Expected 2 priority=1 rows initially");
db.execute("UPDATE update_test SET priority = 3 WHERE id = 1", ())
.expect("Failed to update");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM update_test WHERE priority = 1", ())
.expect("Failed to count");
assert_eq!(count, 1, "Expected 1 priority=1 row after update");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM update_test WHERE priority = 3", ())
.expect("Failed to count");
assert_eq!(count, 1, "Expected 1 priority=3 row after update");
}
#[test]
fn test_btree_index_deletes() {
let db = Database::open("memory://btree_deletes").expect("Failed to create database");
db.execute(
"CREATE TABLE delete_test (
id INTEGER PRIMARY KEY,
category INTEGER
)",
(),
)
.expect("Failed to create table");
db.execute("INSERT INTO delete_test VALUES (1, 10)", ())
.unwrap();
db.execute("INSERT INTO delete_test VALUES (2, 10)", ())
.unwrap();
db.execute("INSERT INTO delete_test VALUES (3, 20)", ())
.unwrap();
db.execute("INSERT INTO delete_test VALUES (4, 20)", ())
.unwrap();
db.execute("CREATE INDEX idx_category ON delete_test (category)", ())
.expect("Failed to create index");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM delete_test WHERE category = 10", ())
.expect("Failed to count");
assert_eq!(count, 2, "Expected 2 category=10 rows initially");
db.execute("DELETE FROM delete_test WHERE id = 1", ())
.expect("Failed to delete");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM delete_test WHERE category = 10", ())
.expect("Failed to count");
assert_eq!(count, 1, "Expected 1 category=10 row after delete");
db.execute("DELETE FROM delete_test WHERE category = 20", ())
.expect("Failed to delete");
let total_count: i64 = db
.query_one("SELECT COUNT(*) FROM delete_test", ())
.expect("Failed to count");
assert_eq!(total_count, 1, "Expected 1 row remaining");
}
#[test]
fn test_multiple_btree_indexes() {
let db = Database::open("memory://multi_btree").expect("Failed to create database");
db.execute(
"CREATE TABLE multi_idx (
id INTEGER PRIMARY KEY,
score INTEGER,
level INTEGER,
priority INTEGER
)",
(),
)
.expect("Failed to create table");
db.execute("INSERT INTO multi_idx VALUES (1, 100, 1, 1)", ())
.unwrap();
db.execute("INSERT INTO multi_idx VALUES (2, 200, 2, 2)", ())
.unwrap();
db.execute("INSERT INTO multi_idx VALUES (3, 100, 1, 3)", ())
.unwrap();
db.execute("INSERT INTO multi_idx VALUES (4, 300, 2, 1)", ())
.unwrap();
db.execute("CREATE INDEX idx_score ON multi_idx (score)", ())
.expect("Failed to create score index");
db.execute("CREATE INDEX idx_level ON multi_idx (level)", ())
.expect("Failed to create level index");
db.execute("CREATE INDEX idx_priority ON multi_idx (priority)", ())
.expect("Failed to create priority index");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM multi_idx WHERE score = 100", ())
.expect("Failed to count");
assert_eq!(count, 2, "Expected 2 score=100 rows");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM multi_idx WHERE level = 1", ())
.expect("Failed to count");
assert_eq!(count, 2, "Expected 2 level=1 rows");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM multi_idx WHERE priority = 1", ())
.expect("Failed to count");
assert_eq!(count, 2, "Expected 2 priority=1 rows");
let count: i64 = db
.query_one(
"SELECT COUNT(*) FROM multi_idx WHERE score = 100 AND level = 1",
(),
)
.expect("Failed to count");
assert_eq!(count, 2, "Expected 2 rows for score=100 AND level=1");
let count: i64 = db
.query_one(
"SELECT COUNT(*) FROM multi_idx WHERE score > 100 AND priority = 1",
(),
)
.expect("Failed to count");
assert_eq!(count, 1, "Expected 1 row for score > 100 AND priority=1");
}