pub mod error;
pub mod row;
pub mod row_vec;
pub mod schema;
pub mod types;
pub mod value;
pub use error::{Error, Result};
pub use row::Row;
pub use row_vec::{RowIdVec, RowVec};
pub use schema::{ForeignKeyConstraint, Schema, SchemaBuilder, SchemaColumn};
pub use types::{DataType, ForeignKeyAction, IndexEntry, IndexType, IsolationLevel, Operator};
pub use value::{parse_timestamp, Value, NULL_VALUE};
use ahash::{AHashMap, AHashSet};
pub type ValueMap<V> = AHashMap<Value, V>;
pub type ValueSet = AHashSet<Value>;
#[cfg(test)]
mod integration_tests {
use super::*;
use chrono::Datelike;
#[test]
fn test_schema_row_integration() {
let schema = SchemaBuilder::new("users")
.add_primary_key("id", DataType::Integer)
.add("name", DataType::Text)
.add_nullable("email", DataType::Text)
.add("active", DataType::Boolean)
.build();
let row = Row::from_values(vec![
Value::integer(1),
Value::text("Alice"),
Value::text("alice@example.com"),
Value::boolean(true),
]);
assert!(row.validate(&schema).is_ok());
let row = Row::from_values(vec![
Value::integer(2),
Value::text("Bob"),
Value::null(DataType::Text),
Value::boolean(false),
]);
assert!(row.validate(&schema).is_ok());
let row = Row::from_values(vec![
Value::integer(3),
Value::null(DataType::Text), Value::null(DataType::Text),
Value::boolean(true),
]);
assert!(row.validate(&schema).is_err());
}
#[test]
fn test_value_comparison_integration() {
assert!(Value::integer(1).compare(&Value::integer(2)).unwrap() == std::cmp::Ordering::Less);
assert!(Value::text("a").compare(&Value::text("b")).unwrap() == std::cmp::Ordering::Less);
assert!(Value::integer(1).compare(&Value::float(1.5)).unwrap() == std::cmp::Ordering::Less);
assert!(
Value::float(2.5).compare(&Value::integer(2)).unwrap() == std::cmp::Ordering::Greater
);
assert!(Value::null(DataType::Integer)
.compare(&Value::integer(0))
.is_err());
}
#[test]
fn test_value_conversion_integration() {
let v = Value::integer(42);
assert_eq!(v.as_int64(), Some(42));
assert_eq!(v.as_float64(), Some(42.0));
assert_eq!(v.as_string(), Some("42".to_string()));
assert_eq!(v.as_boolean(), Some(true));
let v = Value::float(3.5);
assert_eq!(v.as_int64(), Some(3)); assert_eq!(v.as_float64(), Some(3.5));
let v = Value::boolean(true);
assert_eq!(v.as_int64(), Some(1));
assert_eq!(v.as_float64(), Some(1.0));
assert_eq!(v.as_string(), Some("true".to_string()));
let v = Value::text("42");
assert_eq!(v.as_int64(), Some(42));
assert_eq!(v.as_float64(), Some(42.0));
let v = Value::text("2024-01-15T10:30:00Z");
assert!(v.as_timestamp().is_some());
}
#[test]
fn test_timestamp_integration() {
use chrono::TimeZone;
let ts1 = parse_timestamp("2024-01-15T10:30:00Z").unwrap();
let ts2 = parse_timestamp("2024-01-15 10:30:00").unwrap();
let ts3 = parse_timestamp("2024-01-15").unwrap();
assert_eq!(ts1.year(), 2024);
assert_eq!(ts2.year(), 2024);
assert_eq!(ts3.year(), 2024);
let v = Value::timestamp(ts1);
assert_eq!(v.data_type(), DataType::Timestamp);
assert!(v.as_timestamp().is_some());
let v1 = Value::timestamp(ts1);
let v2 = Value::timestamp(chrono::Utc.with_ymd_and_hms(2024, 1, 15, 11, 0, 0).unwrap());
assert!(v1.compare(&v2).unwrap() == std::cmp::Ordering::Less);
}
#[test]
fn test_error_integration() {
let err = Error::not_null_constraint("email");
assert!(err.is_constraint_violation());
assert!(!err.is_not_found());
let err = Error::TableNotFound(String::new());
assert!(err.is_not_found());
assert!(!err.is_constraint_violation());
let err = Error::TransactionAborted;
assert!(err.is_transaction_error());
}
#[test]
fn test_schema_operations_integration() {
let mut schema = SchemaBuilder::new("products")
.add_primary_key("id", DataType::Integer)
.add("name", DataType::Text)
.build();
schema
.add_column(SchemaColumn::nullable(2, "description", DataType::Text))
.unwrap();
assert_eq!(schema.column_count(), 3);
schema.rename_column("name", "product_name").unwrap();
assert!(schema.has_column("product_name"));
assert!(!schema.has_column("name"));
schema
.modify_column("description", None, Some(false))
.unwrap();
assert!(!schema.get_column_by_name("description").unwrap().nullable);
schema.remove_column("description").unwrap();
assert_eq!(schema.column_count(), 2);
}
#[test]
fn test_row_creation_integration() {
let empty = Row::new();
assert!(empty.is_empty());
let row = Row::from_values(vec![
Value::integer(1),
Value::text("hello"),
Value::boolean(true),
Value::float(3.5),
]);
assert_eq!(row.len(), 4);
assert_eq!(row[0], Value::integer(1));
assert_eq!(row[1], Value::text("hello"));
assert_eq!(row[2], Value::boolean(true));
assert_eq!(row[3], Value::float(3.5));
}
}