use reifydb_core::key::{
dictionary::{DictionaryEntryIndexKey, DictionaryEntryKey, DictionaryKey, DictionarySequenceKey},
namespace_dictionary::NamespaceDictionaryKey,
};
use reifydb_transaction::transaction::{Transaction, admin::AdminTransaction};
use reifydb_type::value::dictionary::DictionaryId;
use crate::{CatalogStore, Result};
impl CatalogStore {
pub(crate) fn drop_dictionary(txn: &mut AdminTransaction, dictionary: DictionaryId) -> Result<()> {
if let Some(dictionary_def) = Self::find_dictionary(&mut Transaction::Admin(&mut *txn), dictionary)? {
txn.remove(&NamespaceDictionaryKey::encoded(dictionary_def.namespace, dictionary))?;
}
let entry_range = DictionaryEntryKey::full_scan(dictionary);
let mut entry_stream = txn.range(entry_range, 1024)?;
let mut entry_keys = Vec::new();
for entry in entry_stream.by_ref() {
entry_keys.push(entry?.key.clone());
}
drop(entry_stream);
for key in entry_keys {
txn.remove(&key)?;
}
let index_range = DictionaryEntryIndexKey::full_scan(dictionary);
let mut index_stream = txn.range(index_range, 1024)?;
let mut index_keys = Vec::new();
for entry in index_stream.by_ref() {
index_keys.push(entry?.key.clone());
}
drop(index_stream);
for key in index_keys {
txn.remove(&key)?;
}
txn.remove(&DictionarySequenceKey::encoded(dictionary))?;
txn.remove(&DictionaryKey::encoded(dictionary))?;
Ok(())
}
}
#[cfg(test)]
pub mod tests {
use reifydb_core::{
encoded::row::EncodedRow,
key::dictionary::{DictionaryEntryIndexKey, DictionaryEntryKey},
};
use reifydb_engine::test_harness::create_test_admin_transaction;
use reifydb_transaction::transaction::Transaction;
use reifydb_type::{
fragment::Fragment,
util::cowvec::CowVec,
value::{dictionary::DictionaryId, r#type::Type},
};
use crate::{CatalogStore, store::dictionary::create::DictionaryToCreate, test_utils::ensure_test_namespace};
#[test]
fn test_drop_dictionary() {
let mut txn = create_test_admin_transaction();
let namespace = ensure_test_namespace(&mut txn);
let created = CatalogStore::create_dictionary(
&mut txn,
DictionaryToCreate {
namespace: namespace.id(),
name: Fragment::internal("test_dict"),
value_type: Type::Utf8,
id_type: Type::Uint2,
},
)
.unwrap();
let found = CatalogStore::find_dictionary(&mut Transaction::Admin(&mut txn), created.id).unwrap();
assert!(found.is_some());
CatalogStore::drop_dictionary(&mut txn, created.id).unwrap();
let found = CatalogStore::find_dictionary(&mut Transaction::Admin(&mut txn), created.id).unwrap();
assert!(found.is_none());
}
#[test]
fn test_drop_nonexistent_dictionary() {
let mut txn = create_test_admin_transaction();
let non_existent = DictionaryId(999999);
let result = CatalogStore::drop_dictionary(&mut txn, non_existent);
assert!(result.is_ok());
}
#[test]
fn test_drop_dictionary_cleans_up_entries() {
let mut txn = create_test_admin_transaction();
let namespace = ensure_test_namespace(&mut txn);
let dict_def = CatalogStore::create_dictionary(
&mut txn,
DictionaryToCreate {
namespace: namespace.id(),
name: Fragment::internal("entry_dict"),
value_type: Type::Utf8,
id_type: Type::Uint2,
},
)
.unwrap();
let dummy_hash: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
let dummy_value = vec![42u8, 43u8];
let next_id: u128 = 1;
let mut entry_value = Vec::with_capacity(16 + dummy_value.len());
entry_value.extend_from_slice(&next_id.to_be_bytes());
entry_value.extend_from_slice(&dummy_value);
txn.set(&DictionaryEntryKey::encoded(dict_def.id, dummy_hash), EncodedRow(CowVec::new(entry_value)))
.unwrap();
txn.set(
&DictionaryEntryIndexKey::encoded(dict_def.id, next_id as u64),
EncodedRow(CowVec::new(dummy_value)),
)
.unwrap();
let found = txn.get(&DictionaryEntryKey::encoded(dict_def.id, dummy_hash)).unwrap();
assert!(found.is_some());
let found = txn.get(&DictionaryEntryIndexKey::encoded(dict_def.id, 1u64)).unwrap();
assert!(found.is_some());
CatalogStore::drop_dictionary(&mut txn, dict_def.id).unwrap();
let found = txn.get(&DictionaryEntryKey::encoded(dict_def.id, dummy_hash)).unwrap();
assert!(found.is_none());
let found = txn.get(&DictionaryEntryIndexKey::encoded(dict_def.id, 1u64)).unwrap();
assert!(found.is_none());
let found = CatalogStore::find_dictionary(&mut Transaction::Admin(&mut txn), dict_def.id).unwrap();
assert!(found.is_none());
}
}