use stoolap::Database;
fn setup_like_table(db: &Database) {
db.execute(
"CREATE TABLE fruits (
id INTEGER PRIMARY KEY,
name TEXT
)",
(),
)
.expect("Failed to create table");
db.execute("INSERT INTO fruits (id, name) VALUES (1, 'apple')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (2, 'banana')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (3, 'pineapple')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (4, 'grape')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (5, 'grapefruit')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (6, 'orange')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (7, 'strawberry')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (8, 'blueberry')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (9, 'blackberry')", ())
.unwrap();
db.execute("INSERT INTO fruits (id, name) VALUES (10, 'cranberry')", ())
.unwrap();
}
#[test]
fn test_like_exact_match() {
let db = Database::open("memory://like_exact").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE 'apple' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(ids, vec![1], "Expected only 'apple' (id=1)");
}
#[test]
fn test_like_contains() {
let db = Database::open("memory://like_contains").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE '%berry%' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(ids, vec![7, 8, 9, 10], "Expected all berries");
}
#[test]
fn test_like_starts_with() {
let db = Database::open("memory://like_starts").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE 'grape%' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(ids, vec![4, 5], "Expected grape and grapefruit");
}
#[test]
fn test_like_ends_with() {
let db = Database::open("memory://like_ends").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE '%apple' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(ids, vec![1, 3], "Expected apple and pineapple");
}
#[test]
fn test_like_single_char() {
let db = Database::open("memory://like_single").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE '_range' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(ids, vec![6], "Expected orange");
}
#[test]
fn test_like_match_any() {
let db = Database::open("memory://like_any").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query("SELECT id FROM fruits WHERE name LIKE '%' ORDER BY id", ())
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(
ids,
vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"Expected all fruits"
);
}
#[test]
fn test_like_no_match() {
let db = Database::open("memory://like_none").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE 'mango' ORDER BY id",
(),
)
.expect("Failed to query");
let mut count = 0;
for _ in result {
count += 1;
}
assert_eq!(count, 0, "Expected no matches for mango");
}
#[test]
fn test_like_start_end() {
let db = Database::open("memory://like_start_end").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE 'b%y' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(ids, vec![8, 9], "Expected blueberry and blackberry");
}
#[test]
fn test_not_like() {
let db = Database::open("memory://not_like").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name NOT LIKE '%berry' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(ids, vec![1, 2, 3, 4, 5, 6], "Expected non-berry fruits");
}
#[test]
fn test_ilike_case_insensitive() {
let db = Database::open("memory://ilike_case").expect("Failed to create database");
db.execute("CREATE TABLE mixed_case (id INTEGER, name TEXT)", ())
.expect("Failed to create table");
db.execute("INSERT INTO mixed_case VALUES (1, 'Apple')", ())
.unwrap();
db.execute("INSERT INTO mixed_case VALUES (2, 'BANANA')", ())
.unwrap();
db.execute("INSERT INTO mixed_case VALUES (3, 'orange')", ())
.unwrap();
let result = db
.query(
"SELECT id FROM mixed_case WHERE LOWER(name) LIKE 'apple' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(
ids,
vec![1],
"Expected 'Apple' to match 'apple' case-insensitively"
);
}
#[test]
fn test_like_with_null() {
let db = Database::open("memory://like_null").expect("Failed to create database");
db.execute("CREATE TABLE nullable (id INTEGER, name TEXT)", ())
.expect("Failed to create table");
db.execute("INSERT INTO nullable VALUES (1, 'apple')", ())
.unwrap();
db.execute("INSERT INTO nullable VALUES (2, NULL)", ())
.unwrap();
db.execute("INSERT INTO nullable VALUES (3, 'banana')", ())
.unwrap();
let result = db
.query(
"SELECT id FROM nullable WHERE name LIKE '%a%' ORDER BY id",
(),
)
.expect("Failed to query");
let mut ids: Vec<i64> = Vec::new();
for row in result {
let row = row.expect("Failed to get row");
let id: i64 = row.get(0).unwrap();
ids.push(id);
}
assert_eq!(ids, vec![1, 3], "NULL should not match LIKE pattern");
}
#[test]
fn test_like_double_quoted_patterns() {
let db = Database::open("memory://like_dq").expect("Failed to create database");
setup_like_table(&db);
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE \"apple\" ORDER BY id",
(),
)
.expect("Failed to query");
let ids: Vec<i64> = result
.into_iter()
.map(|r| r.unwrap().get::<i64>(0).unwrap())
.collect();
assert_eq!(ids, vec![1], "Double-quoted exact LIKE");
let result = db
.query(
"SELECT id FROM fruits WHERE name LIKE \"%berry\" ORDER BY id",
(),
)
.expect("Failed to query");
let ids: Vec<i64> = result
.into_iter()
.map(|r| r.unwrap().get::<i64>(0).unwrap())
.collect();
assert_eq!(ids, vec![7, 8, 9, 10], "Double-quoted LIKE '%berry'");
let result = db
.query(
"SELECT id FROM fruits WHERE name NOT LIKE \"%berry\" ORDER BY id",
(),
)
.expect("Failed to query");
let ids: Vec<i64> = result
.into_iter()
.map(|r| r.unwrap().get::<i64>(0).unwrap())
.collect();
assert_eq!(
ids,
vec![1, 2, 3, 4, 5, 6],
"Double-quoted NOT LIKE '%berry'"
);
let result = db
.query(
"SELECT id FROM fruits WHERE name ILIKE \"APPLE\" ORDER BY id",
(),
)
.expect("Failed to query");
let ids: Vec<i64> = result
.into_iter()
.map(|r| r.unwrap().get::<i64>(0).unwrap())
.collect();
assert_eq!(ids, vec![1], "Double-quoted ILIKE 'APPLE'");
let result = db
.query(
"SELECT id FROM fruits WHERE name ILIKE \"GR%\" ORDER BY id",
(),
)
.expect("Failed to query");
let ids: Vec<i64> = result
.into_iter()
.map(|r| r.unwrap().get::<i64>(0).unwrap())
.collect();
assert_eq!(ids, vec![4, 5], "Double-quoted ILIKE 'GR%'");
}