feat: Improve database handling of model indices
- Ensure all model types always have a primary key index entry. - Simplify `get_all()` implementation by relying on primary key index. - Remove redundant code in `get_all()` for finding all object IDs. - Improve error handling and clarity in database operations.
This commit is contained in:
parent
972d0982b0
commit
d8e3d48caa
@ -323,6 +323,16 @@ where
|
||||
assigned_id
|
||||
};
|
||||
|
||||
// Always create a primary key index entry for this model type
|
||||
// This ensures get_all() can find all objects of this type, even if they have no explicit indexed fields
|
||||
let primary_index_key = format!("{}::primary", M::db_prefix());
|
||||
let mut primary_ids: HashSet<u32> =
|
||||
Self::get_tst_value(&mut index_db, &primary_index_key)?
|
||||
.unwrap_or_else(HashSet::new);
|
||||
primary_ids.insert(assigned_id);
|
||||
let raw_primary_ids = bincode::serde::encode_to_vec(&primary_ids, BINCODE_CONFIG)?;
|
||||
index_db.set(&primary_index_key, raw_primary_ids)?;
|
||||
|
||||
// Now add the new indices
|
||||
for index_key in indices_to_add {
|
||||
let key = Self::index_key(M::db_prefix(), index_key.name, &index_key.value);
|
||||
@ -420,6 +430,22 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// Also remove from the primary key index
|
||||
let primary_index_key = format!("{}::primary", M::db_prefix());
|
||||
if let Some(mut primary_ids) =
|
||||
Self::get_tst_value::<HashSet<u32>>(&mut index_db, &primary_index_key)?
|
||||
{
|
||||
primary_ids.remove(&id);
|
||||
if primary_ids.is_empty() {
|
||||
// This was the last object of this type, remove the primary index entirely
|
||||
index_db.delete(&primary_index_key)?;
|
||||
} else {
|
||||
// There are still other objects of this type, write back updated set
|
||||
let raw_primary_ids = bincode::serde::encode_to_vec(&primary_ids, BINCODE_CONFIG)?;
|
||||
index_db.set(&primary_index_key, raw_primary_ids)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally delete the object itself
|
||||
Ok(data_db.delete(id)?)
|
||||
}
|
||||
@ -428,36 +454,16 @@ where
|
||||
let mut index_db = self.index.lock().expect("can lock index DB");
|
||||
let mut data_db = self.data.lock().expect("can lock data DB");
|
||||
|
||||
let prefix = M::db_prefix();
|
||||
let mut all_object_ids: HashSet<u32> = HashSet::new();
|
||||
|
||||
// Use getall to find all index entries (values are serialized HashSet<u32>) for the given model prefix.
|
||||
match index_db.getall(prefix) {
|
||||
Ok(list_of_raw_ids_set_bytes) => {
|
||||
for raw_ids_set_bytes in list_of_raw_ids_set_bytes {
|
||||
// Each item in the list is a bincode-serialized HashSet<u32> of object IDs.
|
||||
match bincode::serde::decode_from_slice::<HashSet<u32>, _>(&raw_ids_set_bytes, BINCODE_CONFIG) {
|
||||
Ok((ids_set, _)) => { // Destructure the tuple (HashSet<u32>, usize)
|
||||
all_object_ids.extend(ids_set);
|
||||
}
|
||||
Err(e) => {
|
||||
// If deserialization of an ID set fails, propagate as a decode error.
|
||||
return Err(super::Error::Decode(e));
|
||||
}
|
||||
}
|
||||
// Look for the primary key index entry for this model type
|
||||
let primary_index_key = format!("{}::primary", M::db_prefix());
|
||||
let all_object_ids: HashSet<u32> =
|
||||
match Self::get_tst_value(&mut index_db, &primary_index_key)? {
|
||||
Some(ids) => ids,
|
||||
None => {
|
||||
// No primary index found, meaning no objects of this type exist
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
}
|
||||
Err(tst::Error::PrefixNotFound(_)) => {
|
||||
// No index entries found for this prefix, meaning no objects of this type exist.
|
||||
// Note: tst::getall might return Ok(vec![]) in this case instead of PrefixNotFound.
|
||||
// Depending on tst implementation, this arm might be redundant if getall returns empty vec.
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
Err(e) => {
|
||||
// Other TST errors.
|
||||
return Err(super::Error::DB(e));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut results: Vec<M> = Vec::with_capacity(all_object_ids.len());
|
||||
for obj_id in all_object_ids {
|
||||
|
Loading…
Reference in New Issue
Block a user