extern crate alloc;
use remdb::platform::*;
use remdb::{
config::DbConfig, config::LogMode, config::WALConfig, time_series::CompressionType,
time_series::TimeSeriesConfig, DataType, DatabaseStatus, FieldDef, RemDb, Result, TableDef,
};
use std::sync::Mutex;
mod common;
use common::{setup_test_db, setup_test_db_with_memory};
static TEST_MUTEX: Mutex<()> = Mutex::new(());
static TEST_DB_CONFIG: std::sync::LazyLock<DbConfig> = std::sync::LazyLock::new(|| {
DbConfig {
tables: vec![],
total_memory: 1024 * 1024, low_power_mode_supported: false,
low_power_max_records: None,
default_max_records: 100000,
memory_allocator: &remdb::config::DefaultMemoryAllocator,
wal_config: WALConfig {
log_path: "./wal",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 1 * 1024 * 1024,
log_segment_size: 16 * 1024 * 1024,
max_consecutive_invalid: 100,
retained_checkpoints: 2,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
time_series_defaults: TimeSeriesConfig::DEFAULT,
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: Default::default(),
}
});
#[test]
fn test_databases_command() -> Result<()> {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
setup_test_db_with_memory(1024 * 1024);
let mut db = unsafe { remdb::init_global_db(&TEST_DB_CONFIG)? };
db.create_database("test_db")?;
let databases = db.databases()?;
assert!(!databases.is_empty());
let db_info = databases
.iter()
.find(|info| info.name == "test_db")
.expect("test_db database not found");
assert_eq!(db_info.name, "test_db");
assert_eq!(db_info.database_type, "RemDb");
assert_eq!(db_info.status, DatabaseStatus::Created);
assert!(db_info.table_count >= 0);
Ok(())
}
#[test]
fn test_database_manager_list_databases() -> Result<()> {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
setup_test_db();
let mut manager = remdb::DatabaseManager::new(10);
let db1 = manager.create_database("db1", "", None)?;
assert_eq!(db1.name, "db1");
let db2 = manager.create_database("db2", "", None)?;
assert_eq!(db2.name, "db2");
let databases = manager.list_databases()?;
assert_eq!(databases.len(), 2);
let mut db_names = databases
.iter()
.map(|info| info.name.clone())
.collect::<Vec<_>>();
db_names.sort();
assert_eq!(db_names, vec!["db1", "db2"]);
for db_info in &databases {
assert_eq!(db_info.database_type, "RemDb");
assert_eq!(db_info.status, DatabaseStatus::Created);
assert_eq!(db_info.table_count, 0);
}
Ok(())
}
#[test]
fn test_use_database_on_created_database() -> Result<()> {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
setup_test_db_with_memory(1024 * 1024);
let mut db = unsafe { remdb::init_global_db(&TEST_DB_CONFIG)? };
db.create_database("test_db")?;
db.use_database("test_db")?;
let err = db.use_database("missing").unwrap_err();
assert_eq!(err, remdb::RemDbError::DatabaseNotFound);
Ok(())
}
#[test]
fn test_create_database_duplicate_returns_exists() -> Result<()> {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
setup_test_db_with_memory(1024 * 1024);
let mut db = unsafe { remdb::init_global_db(&TEST_DB_CONFIG)? };
db.create_database("test_db")?;
let err = db.create_database("test_db").unwrap_err();
assert_eq!(err, remdb::RemDbError::DatabaseExists);
Ok(())
}