extern crate alloc;
use remdb::{
config::{DbConfig, DefaultMemoryAllocator, LogMode, WALConfig},
RemDb,
};
use std::sync::Mutex;
static TEST_MUTEX: Mutex<()> = Mutex::new(());
static mut DB_MEMORY1: [u8; 32 * 1024 * 1024] = [0; 32 * 1024 * 1024]; static mut DB_MEMORY2: [u8; 32 * 1024 * 1024] = [0; 32 * 1024 * 1024]; static mut DB_MEMORY3: [u8; 32 * 1024 * 1024] = [0; 32 * 1024 * 1024]; static mut DB_MEMORY4: [u8; 32 * 1024 * 1024] = [0; 32 * 1024 * 1024]; static mut DB_MEMORY5: [u8; 32 * 1024 * 1024] = [0; 32 * 1024 * 1024]; static mut DB_MEMORY6: [u8; 32 * 1024 * 1024] = [0; 32 * 1024 * 1024]; static mut DB_MEMORY7: [u8; 32 * 1024 * 1024] = [0; 32 * 1024 * 1024];
#[test]
fn test_drop_table_basic() {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
unsafe {
DB_MEMORY1.fill(0);
}
unsafe {
remdb::memory::allocator::init_global_allocator(DB_MEMORY1.as_mut_ptr(), DB_MEMORY1.len())
.unwrap();
}
static DB_CONFIG: DbConfig = DbConfig {
total_memory: 32 * 1024 * 1024, default_max_records: 100,
low_power_mode_supported: false,
low_power_max_records: Some(50),
wal_config: WALConfig {
log_path: "",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 16 * 1024 * 1024,
max_consecutive_invalid: 100,
retained_checkpoints: 1,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
tables: Vec::new(),
memory_allocator: &DefaultMemoryAllocator,
time_series_defaults: remdb::time_series::TimeSeriesConfig {
partition_duration_secs: 3600,
retention_period_secs: 86400,
max_partitions: 100,
compression: remdb::time_series::CompressionType::None,
},
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: remdb::config::ModelWorkerConfig::DEFAULT,
};
let mut db = RemDb::new(&DB_CONFIG);
db.init().unwrap();
db.create_table(
"test_table",
&[("id", remdb::DataType::Int64, 0, None, None)],
Some(vec![0]),
)
.unwrap();
let table_index = db
.get_all_tables()
.iter()
.position(|table_opt| {
if let Some(table) = table_opt {
table.def.name == "test_table"
} else {
false
}
})
.unwrap();
let table = db.get_table(table_index).unwrap();
assert_eq!(table.def.name, "test_table");
db.drop_table("test_table", false, false).unwrap();
let result = db.get_table(table_index);
assert!(result.is_err());
}
#[test]
fn test_drop_table_vector_with_if_exists() {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
unsafe {
DB_MEMORY7.fill(0);
}
unsafe {
remdb::memory::allocator::init_global_allocator(DB_MEMORY7.as_mut_ptr(), DB_MEMORY7.len())
.unwrap();
}
static DB_CONFIG: DbConfig = DbConfig {
total_memory: 32 * 1024 * 1024, default_max_records: 100,
low_power_mode_supported: false,
low_power_max_records: Some(50),
wal_config: WALConfig {
log_path: "",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 16 * 1024 * 1024,
max_consecutive_invalid: 100,
retained_checkpoints: 1,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
tables: Vec::new(),
memory_allocator: &DefaultMemoryAllocator,
time_series_defaults: remdb::time_series::TimeSeriesConfig {
partition_duration_secs: 3600,
retention_period_secs: 86400,
max_partitions: 100,
compression: remdb::time_series::CompressionType::None,
},
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: remdb::config::ModelWorkerConfig::DEFAULT,
};
let mut db = RemDb::new(&DB_CONFIG);
db.init().unwrap();
let create_sql = "CREATE TABLE IF NOT EXISTS test_vector (id INTEGER PRIMARY KEY AUTOINCREMENT, value VECTOR(3) WITH DISTANCE=L2);";
let create_query = remdb::sql::parse_sql_query(create_sql).unwrap();
remdb::sql::execute_query(&mut db, &create_query).unwrap();
let table_index = db
.get_all_tables()
.iter()
.position(|table_opt| {
if let Some(table) = table_opt {
table.def.name == "test_vector"
} else {
false
}
})
.unwrap();
let table = db.get_table(table_index).unwrap();
assert_eq!(table.def.name, "test_vector");
let drop_sql = "DROP TABLE IF EXISTS test_vector;";
let drop_query = remdb::sql::parse_sql_query(drop_sql).unwrap();
remdb::sql::execute_query(&mut db, &drop_query).unwrap();
let result = db.get_table(table_index);
assert!(result.is_err());
let drop_sql2 = "DROP TABLE IF EXISTS test_vector;";
let drop_query2 = remdb::sql::parse_sql_query(drop_sql2).unwrap();
let result2 = remdb::sql::execute_query(&mut db, &drop_query2);
assert!(result2.is_ok());
}
#[test]
fn test_drop_table_if_exists() {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
unsafe {
DB_MEMORY2.fill(0);
}
unsafe {
remdb::memory::allocator::init_global_allocator(DB_MEMORY2.as_mut_ptr(), DB_MEMORY2.len())
.unwrap();
}
static DB_CONFIG: DbConfig = DbConfig {
total_memory: 32 * 1024 * 1024, default_max_records: 100,
low_power_mode_supported: false,
low_power_max_records: Some(50),
wal_config: WALConfig {
log_path: "",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 16 * 1024 * 1024,
max_consecutive_invalid: 100,
retained_checkpoints: 1,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
tables: Vec::new(),
memory_allocator: &DefaultMemoryAllocator,
time_series_defaults: remdb::time_series::TimeSeriesConfig {
partition_duration_secs: 3600,
retention_period_secs: 86400,
max_partitions: 100,
compression: remdb::time_series::CompressionType::None,
},
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: remdb::config::ModelWorkerConfig::DEFAULT,
};
let mut db = RemDb::new(&DB_CONFIG);
db.init().unwrap();
let result = db.drop_table("non_existent_table", true, false);
assert!(result.is_ok());
let result = db.drop_table("non_existent_table", false, false);
assert!(result.is_err());
}
#[test]
fn test_drop_table_sql() {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
unsafe {
DB_MEMORY3.fill(0);
}
unsafe {
remdb::memory::allocator::init_global_allocator(DB_MEMORY3.as_mut_ptr(), DB_MEMORY3.len())
.unwrap();
}
static DB_CONFIG: DbConfig = DbConfig {
total_memory: 32 * 1024 * 1024, default_max_records: 100,
low_power_mode_supported: false,
low_power_max_records: Some(50),
wal_config: WALConfig {
log_path: "",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 16 * 1024 * 1024,
retained_checkpoints: 1,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
max_consecutive_invalid: 100,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
tables: Vec::new(),
memory_allocator: &DefaultMemoryAllocator,
time_series_defaults: remdb::time_series::TimeSeriesConfig {
partition_duration_secs: 3600,
retention_period_secs: 86400,
max_partitions: 100,
compression: remdb::time_series::CompressionType::None,
},
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: remdb::config::ModelWorkerConfig::DEFAULT,
};
let mut db = RemDb::new(&DB_CONFIG);
db.init().unwrap();
let create_sql = "CREATE TABLE test_table (id INT PRIMARY KEY, name VARCHAR);";
let create_query = remdb::sql::parse_sql_query(create_sql).unwrap();
remdb::sql::execute_query(&mut db, &create_query).unwrap();
let table_index = db
.get_all_tables()
.iter()
.position(|table_opt| {
if let Some(table) = table_opt {
table.def.name == "test_table"
} else {
false
}
})
.unwrap();
let table = db.get_table(table_index).unwrap();
assert_eq!(table.def.name, "test_table");
let drop_sql = "DROP TABLE test_table;";
let drop_query = remdb::sql::parse_sql_query(drop_sql).unwrap();
remdb::sql::execute_query(&mut db, &drop_query).unwrap();
let result = db.get_table(table_index);
assert!(result.is_err());
}
#[test]
fn test_drop_table_sql_if_exists() {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
unsafe {
DB_MEMORY4.fill(0);
}
unsafe {
remdb::memory::allocator::init_global_allocator(DB_MEMORY4.as_mut_ptr(), DB_MEMORY4.len())
.unwrap();
}
static DB_CONFIG: DbConfig = DbConfig {
total_memory: 32 * 1024 * 1024, default_max_records: 100,
low_power_mode_supported: false,
low_power_max_records: Some(50),
wal_config: WALConfig {
log_path: "",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 16 * 1024 * 1024,
retained_checkpoints: 1,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
max_consecutive_invalid: 100,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
tables: Vec::new(),
memory_allocator: &DefaultMemoryAllocator,
time_series_defaults: remdb::time_series::TimeSeriesConfig {
partition_duration_secs: 3600,
retention_period_secs: 86400,
max_partitions: 100,
compression: remdb::time_series::CompressionType::None,
},
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: remdb::config::ModelWorkerConfig::DEFAULT,
};
let mut db = RemDb::new(&DB_CONFIG);
db.init().unwrap();
let drop_sql = "DROP TABLE IF EXISTS non_existent_table;";
let drop_query = remdb::sql::parse_sql_query(drop_sql).unwrap();
let result = remdb::sql::execute_query(&mut db, &drop_query);
assert!(result.is_ok());
}
#[test]
fn test_drop_table_in_transaction() {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
unsafe {
DB_MEMORY5.fill(0);
}
unsafe {
remdb::memory::allocator::init_global_allocator(DB_MEMORY5.as_mut_ptr(), DB_MEMORY5.len())
.unwrap();
}
static DB_CONFIG: DbConfig = DbConfig {
total_memory: 32 * 1024 * 1024, default_max_records: 100,
low_power_mode_supported: false,
low_power_max_records: Some(50),
wal_config: WALConfig {
log_path: "",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 16 * 1024 * 1024,
retained_checkpoints: 1,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
max_consecutive_invalid: 100,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
tables: Vec::new(),
memory_allocator: &DefaultMemoryAllocator,
time_series_defaults: remdb::time_series::TimeSeriesConfig {
partition_duration_secs: 3600,
retention_period_secs: 86400,
max_partitions: 100,
compression: remdb::time_series::CompressionType::None,
},
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: remdb::config::ModelWorkerConfig::DEFAULT,
};
let mut db = RemDb::new(&DB_CONFIG);
db.init().unwrap();
db.create_table(
"test_table",
&[("id", remdb::DataType::Int64, 0, None, None)],
Some(vec![0]),
)
.unwrap();
let table_index = db
.get_all_tables()
.iter()
.position(|table_opt| {
if let Some(table) = table_opt {
table.def.name == "test_table"
} else {
false
}
})
.unwrap();
let table = db.get_table(table_index).unwrap();
assert_eq!(table.def.name, "test_table");
db.drop_table("test_table", false, false).unwrap();
let result = db.get_table(table_index);
assert!(result.is_err());
}
#[test]
fn test_drop_table_memory_recovery() {
let _guard = TEST_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
unsafe {
DB_MEMORY6.fill(0);
}
unsafe {
remdb::memory::allocator::init_global_allocator(DB_MEMORY6.as_mut_ptr(), DB_MEMORY6.len())
.unwrap();
}
static DB_CONFIG: DbConfig = DbConfig {
total_memory: 32 * 1024 * 1024, default_max_records: 100,
low_power_mode_supported: false,
low_power_max_records: Some(50),
wal_config: WALConfig {
log_path: "",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 16 * 1024 * 1024,
retained_checkpoints: 1,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
max_consecutive_invalid: 100,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
tables: Vec::new(),
memory_allocator: &DefaultMemoryAllocator,
time_series_defaults: remdb::time_series::TimeSeriesConfig {
partition_duration_secs: 3600,
retention_period_secs: 86400,
max_partitions: 100,
compression: remdb::time_series::CompressionType::None,
},
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: remdb::config::ModelWorkerConfig::DEFAULT,
};
let mut db = RemDb::new(&DB_CONFIG);
db.init().unwrap();
db.create_table(
"test_table",
&[
("id", remdb::DataType::Int64, 0, None, None),
("name", remdb::DataType::VarChar, 0, None, None),
],
Some(vec![0]),
)
.unwrap();
let table_index = db
.get_all_tables()
.iter()
.position(|table_opt| {
if let Some(table) = table_opt {
table.def.name == "test_table"
} else {
false
}
})
.unwrap();
db.drop_table("test_table", false, false).unwrap();
let result = db.get_table(table_index);
assert!(result.is_err());
}