use arrow::array::{Int64Array, StringArray};
use arrow::datatypes::{DataType, Field, Schema};
use dbx_core::Database;
#[test]
fn test_basic_select() -> dbx_core::DbxResult<()> {
let db = Database::open_in_memory()?;
let schema = Schema::new(vec![
Field::new("id", DataType::Int64, false),
Field::new("name", DataType::Utf8, true),
Field::new("age", DataType::Int32, true),
]);
db.create_table("users_basic_select", schema)?;
db.execute_sql("INSERT INTO users_basic_select (id, name, age) VALUES (1, 'Alice', 25)")?;
db.execute_sql("INSERT INTO users_basic_select (id, name, age) VALUES (2, 'Bob', 30)")?;
db.execute_sql("INSERT INTO users_basic_select (id, name, age) VALUES (3, 'Charlie', 35)")?;
let results = db
.query_builder()
.select(&["id", "name"])
.from("users_basic_select")
.execute()?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].num_rows(), 3);
assert_eq!(results[0].num_columns(), 2);
Ok(())
}
#[test]
fn test_where_clause() -> dbx_core::DbxResult<()> {
let db = Database::open_in_memory()?;
let schema = Schema::new(vec![
Field::new("id", DataType::Int64, false),
Field::new("name", DataType::Utf8, true),
Field::new("age", DataType::Int32, true),
]);
db.create_table("users_where", schema)?;
db.execute_sql("INSERT INTO users_where (id, name, age) VALUES (1, 'Alice', 25)")?;
db.execute_sql("INSERT INTO users_where (id, name, age) VALUES (2, 'Bob', 30)")?;
db.execute_sql("INSERT INTO users_where (id, name, age) VALUES (3, 'Charlie', 35)")?;
let results = db
.query_builder()
.select(&["id", "name", "age"])
.from("users_where")
.where_("age", ">", "25")
.execute()?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].num_rows(), 2);
Ok(())
}
#[test]
fn test_and_or_conditions() -> dbx_core::DbxResult<()> {
let db = Database::open_in_memory()?;
let schema = Schema::new(vec![
Field::new("id", DataType::Int64, false),
Field::new("name", DataType::Utf8, true),
Field::new("age", DataType::Int32, true),
Field::new("status", DataType::Utf8, true),
]);
db.create_table("users_and_or", schema)?;
db.execute_sql(
"INSERT INTO users_and_or (id, name, age, status) VALUES (1, 'Alice', 25, 'active')",
)?;
db.execute_sql(
"INSERT INTO users_and_or (id, name, age, status) VALUES (2, 'Bob', 30, 'inactive')",
)?;
db.execute_sql(
"INSERT INTO users_and_or (id, name, age, status) VALUES (3, 'Charlie', 35, 'active')",
)?;
let results = db
.query_builder()
.select(&["id", "name"])
.from("users_and_or")
.where_("age", ">", "25")
.and("status", "=", "'active'")
.execute()?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].num_rows(), 1);
Ok(())
}
#[test]
fn test_order_by() -> dbx_core::DbxResult<()> {
let db = Database::open_in_memory()?;
let schema = Schema::new(vec![
Field::new("id", DataType::Int64, false),
Field::new("name", DataType::Utf8, true),
Field::new("age", DataType::Int32, true),
]);
db.create_table("users_order", schema)?;
db.execute_sql("INSERT INTO users_order (id, name, age) VALUES (1, 'Charlie', 35)")?;
db.execute_sql("INSERT INTO users_order (id, name, age) VALUES (2, 'Alice', 25)")?;
db.execute_sql("INSERT INTO users_order (id, name, age) VALUES (3, 'Bob', 30)")?;
let results = db
.query_builder()
.select(&["id", "name"])
.from("users_order")
.order_by("name", "ASC")
.execute()?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].num_rows(), 3);
let name_array = results[0]
.column(1)
.as_any()
.downcast_ref::<StringArray>()
.unwrap();
assert_eq!(name_array.value(0), "Alice");
assert_eq!(name_array.value(1), "Bob");
assert_eq!(name_array.value(2), "Charlie");
Ok(())
}
#[test]
fn test_limit_offset() -> dbx_core::DbxResult<()> {
let db = Database::open_in_memory()?;
let schema = Schema::new(vec![
Field::new("id", DataType::Int64, false),
Field::new("name", DataType::Utf8, true),
]);
db.create_table("users_limit", schema)?;
for i in 1..=10 {
db.execute_sql(&format!(
"INSERT INTO users_limit (id, name) VALUES ({}, 'User{}')",
i, i
))?;
}
let results = db
.query_builder()
.select(&["id", "name"])
.from("users_limit")
.limit(5)
.execute()?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].num_rows(), 5);
let results = db
.query_builder()
.select(&["id", "name"])
.from("users_limit")
.limit(3)
.offset(5)
.execute()?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].num_rows(), 3);
let id_array = results[0]
.column(0)
.as_any()
.downcast_ref::<Int64Array>()
.unwrap();
assert_eq!(id_array.value(0), 6);
assert_eq!(id_array.value(1), 7);
assert_eq!(id_array.value(2), 8);
Ok(())
}
#[test]
fn test_count_aggregate() -> dbx_core::DbxResult<()> {
let db = Database::open_in_memory()?;
let schema = Schema::new(vec![
Field::new("id", DataType::Int64, false),
Field::new("name", DataType::Utf8, true),
Field::new("status", DataType::Utf8, true),
]);
db.create_table("users_count", schema)?;
db.execute_sql("INSERT INTO users_count (id, name, status) VALUES (1, 'Alice', 'active')")?;
db.execute_sql("INSERT INTO users_count (id, name, status) VALUES (2, 'Bob', 'active')")?;
db.execute_sql("INSERT INTO users_count (id, name, status) VALUES (3, 'Charlie', 'inactive')")?;
let results = db
.query_builder()
.count("*")
.from("users_count")
.where_("status", "=", "'active'")
.execute()?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].num_rows(), 1);
let count_array = results[0]
.column(0)
.as_any()
.downcast_ref::<Int64Array>()
.unwrap();
assert_eq!(count_array.value(0), 2);
Ok(())
}
#[test]
fn test_complex_query() -> dbx_core::DbxResult<()> {
let db = Database::open_in_memory()?;
let schema = Schema::new(vec![
Field::new("id", DataType::Int64, false),
Field::new("name", DataType::Utf8, true),
Field::new("age", DataType::Int32, true),
Field::new("status", DataType::Utf8, true),
]);
db.create_table("users_complex", schema)?;
db.execute_sql(
"INSERT INTO users_complex (id, name, age, status) VALUES (1, 'Alice', 25, 'active')",
)?;
db.execute_sql(
"INSERT INTO users_complex (id, name, age, status) VALUES (2, 'Bob', 30, 'active')",
)?;
db.execute_sql(
"INSERT INTO users_complex (id, name, age, status) VALUES (3, 'Charlie', 35, 'inactive')",
)?;
db.execute_sql(
"INSERT INTO users_complex (id, name, age, status) VALUES (4, 'David', 28, 'active')",
)?;
db.execute_sql(
"INSERT INTO users_complex (id, name, age, status) VALUES (5, 'Eve', 32, 'active')",
)?;
let results = db
.query_builder()
.select(&["id", "name", "age"])
.from("users_complex")
.where_("status", "=", "'active'")
.and("age", ">", "27")
.order_by("age", "ASC")
.limit(2)
.execute()?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].num_rows(), 2);
let name_array = results[0]
.column(1)
.as_any()
.downcast_ref::<StringArray>()
.unwrap();
assert_eq!(name_array.value(0), "David");
assert_eq!(name_array.value(1), "Bob");
Ok(())
}