v_storage/
vstorage.rs

1use v_individual_model::onto::individual::Individual;
2use crate::common::{Storage, StorageId, StorageResult, StorageDispatcher};
3
4// ========================================================================================
5// ОПТИМИЗИРОВАННАЯ ENUM-BASED ВЕРСИЯ ДЛЯ КРИТИЧНЫХ ПО ПРОИЗВОДИТЕЛЬНОСТИ СЛУЧАЕВ
6// ========================================================================================
7
8/// Enum-based хранилище для максимальной производительности
9/// 
10/// Преимущества:
11/// - Нет vtable lookups - все вызовы статически диспетчируются
12/// - Компилятор может лучше оптимизировать код
13/// - Нет heap allocations для storage
14/// - Лучшая производительность чем trait objects
15/// 
16/// Рекомендуется для:
17/// - Горячих путей в приложении
18/// - Batch операций
19/// - Высокопроизводительных сценариев
20pub enum VStorageEnum {
21    Memory(crate::memory_storage::MemoryStorage),
22    Lmdb(crate::lmdb_storage::LMDBStorage),
23    Remote(crate::remote_storage_client::StorageROClient),
24    #[cfg(any(feature = "tt_2", feature = "tt_3"))]
25    Tarantool(crate::tt_storage::TTStorage),
26    None,
27}
28
29impl Default for VStorageEnum {
30    fn default() -> Self {
31        VStorageEnum::None
32    }
33}
34
35impl VStorageEnum {
36    /// Создает память хранилище
37    pub fn memory() -> Self {
38        VStorageEnum::Memory(crate::memory_storage::MemoryStorage::new())
39    }
40
41    /// Создает LMDB хранилище
42    pub fn lmdb(path: &str, mode: crate::common::StorageMode, max_read_counter_reopen: Option<u64>) -> Self {
43        VStorageEnum::Lmdb(crate::lmdb_storage::LMDBStorage::new(path, mode, max_read_counter_reopen))
44    }
45
46    /// Создает удаленное хранилище
47    pub fn remote(address: &str) -> Self {
48        VStorageEnum::Remote(crate::remote_storage_client::StorageROClient::new(address))
49    }
50
51    /// Создает Tarantool хранилище
52    #[cfg(any(feature = "tt_2", feature = "tt_3"))]
53    pub fn tarantool(uri: String, login: &str, password: &str) -> Self {
54        VStorageEnum::Tarantool(crate::tt_storage::TTStorage::new(uri, login, password))
55    }
56
57    /// Проверяет, пусто ли хранилище
58    pub fn is_empty(&self) -> bool {
59        matches!(self, VStorageEnum::None)
60    }
61}
62
63impl Storage for VStorageEnum {
64    fn get_individual(&mut self, storage: StorageId, id: &str, iraw: &mut Individual) -> StorageResult<()> {
65        match self {
66            VStorageEnum::Memory(s) => s.get_individual(storage, id, iraw),
67            VStorageEnum::Lmdb(s) => s.get_individual(storage, id, iraw),
68            VStorageEnum::Remote(s) => s.get_individual(storage, id, iraw),
69            #[cfg(any(feature = "tt_2", feature = "tt_3"))]
70            VStorageEnum::Tarantool(s) => s.get_individual(storage, id, iraw),
71            VStorageEnum::None => StorageResult::NotReady,
72        }
73    }
74
75    fn get_value(&mut self, storage: StorageId, key: &str) -> StorageResult<String> {
76        match self {
77            VStorageEnum::Memory(s) => s.get_value(storage, key),
78            VStorageEnum::Lmdb(s) => s.get_value(storage, key),
79            VStorageEnum::Remote(s) => s.get_value(storage, key),
80            #[cfg(any(feature = "tt_2", feature = "tt_3"))]
81            VStorageEnum::Tarantool(s) => s.get_value(storage, key),
82            VStorageEnum::None => StorageResult::NotReady,
83        }
84    }
85
86    fn get_raw_value(&mut self, storage: StorageId, key: &str) -> StorageResult<Vec<u8>> {
87        match self {
88            VStorageEnum::Memory(s) => s.get_raw_value(storage, key),
89            VStorageEnum::Lmdb(s) => s.get_raw_value(storage, key),
90            VStorageEnum::Remote(s) => s.get_raw_value(storage, key),
91            #[cfg(any(feature = "tt_2", feature = "tt_3"))]
92            VStorageEnum::Tarantool(s) => s.get_raw_value(storage, key),
93            VStorageEnum::None => StorageResult::NotReady,
94        }
95    }
96
97    fn put_value(&mut self, storage: StorageId, key: &str, val: &str) -> StorageResult<()> {
98        match self {
99            VStorageEnum::Memory(s) => s.put_value(storage, key, val),
100            VStorageEnum::Lmdb(s) => s.put_value(storage, key, val),
101            VStorageEnum::Remote(s) => s.put_value(storage, key, val),
102            #[cfg(any(feature = "tt_2", feature = "tt_3"))]
103            VStorageEnum::Tarantool(s) => s.put_value(storage, key, val),
104            VStorageEnum::None => StorageResult::NotReady,
105        }
106    }
107
108    fn put_raw_value(&mut self, storage: StorageId, key: &str, val: Vec<u8>) -> StorageResult<()> {
109        match self {
110            VStorageEnum::Memory(s) => s.put_raw_value(storage, key, val),
111            VStorageEnum::Lmdb(s) => s.put_raw_value(storage, key, val),
112            VStorageEnum::Remote(s) => s.put_raw_value(storage, key, val),
113            #[cfg(any(feature = "tt_2", feature = "tt_3"))]
114            VStorageEnum::Tarantool(s) => s.put_raw_value(storage, key, val),
115            VStorageEnum::None => StorageResult::NotReady,
116        }
117    }
118
119    fn remove_value(&mut self, storage: StorageId, key: &str) -> StorageResult<()> {
120        match self {
121            VStorageEnum::Memory(s) => s.remove_value(storage, key),
122            VStorageEnum::Lmdb(s) => s.remove_value(storage, key),
123            VStorageEnum::Remote(s) => s.remove_value(storage, key),
124            #[cfg(any(feature = "tt_2", feature = "tt_3"))]
125            VStorageEnum::Tarantool(s) => s.remove_value(storage, key),
126            VStorageEnum::None => StorageResult::NotReady,
127        }
128    }
129
130    fn count(&mut self, storage: StorageId) -> StorageResult<usize> {
131        match self {
132            VStorageEnum::Memory(s) => s.count(storage),
133            VStorageEnum::Lmdb(s) => s.count(storage),
134            VStorageEnum::Remote(s) => s.count(storage),
135            #[cfg(any(feature = "tt_2", feature = "tt_3"))]
136            VStorageEnum::Tarantool(s) => s.count(storage),
137            VStorageEnum::None => StorageResult::NotReady,
138        }
139    }
140}
141
142// ========================================================================================
143// ОСНОВНОЙ VSTORAGE - КОНТЕЙНЕР И ДИСПЕТЧЕР  
144// ========================================================================================
145
146/// Контейнер для хранилища с динамической диспетчеризацией
147/// 
148/// Ответственности:
149/// - Хранение экземпляра Storage
150/// - Диспетчеризация вызовов к хранилищу
151/// - Обработка состояния "не инициализировано"
152pub struct VStorage {
153    storage: Option<Box<dyn Storage>>,
154}
155
156impl StorageDispatcher for VStorage {
157    type Storage = Box<dyn Storage>;
158
159    fn with_storage<T, F>(&mut self, default_value: T, operation: F) -> T 
160    where 
161        F: FnOnce(&mut Self::Storage) -> T,
162    {
163        match self.storage.as_mut() {
164            Some(storage) => operation(storage),
165            None => default_value,
166        }
167    }
168}
169
170impl VStorage {
171    /// Создает пустое хранилище (не инициализированное)
172    pub fn none() -> VStorage {
173        VStorage {
174            storage: None,
175        }
176    }
177
178    /// Проверяет, пусто ли хранилище
179    pub fn is_empty(&self) -> bool {
180        self.storage.is_none()
181    }
182
183    /// Основной конструктор принимающий готовое хранилище
184    pub fn new(storage: Box<dyn Storage>) -> VStorage {
185        VStorage {
186            storage: Some(storage),
187        }
188    }
189
190    /// Получает ссылку на Builder для создания хранилищ
191    pub fn builder() -> crate::storage_factory::StorageBuilder {
192        crate::storage_factory::StorageBuilder::new()
193    }
194
195    /// Создание через конфигурацию
196    pub fn from_config(config: crate::storage_factory::StorageConfig) -> Result<VStorage, crate::storage_factory::StorageError> {
197        let storage = crate::storage_factory::DefaultStorageFactory::new()
198            .create_storage_from_config(config)?;
199        Ok(VStorage::new(storage))
200    }
201
202    // ========================================================================================
203    // ПУБЛИЧНЫЕ МЕТОДЫ API - УНИФИЦИРОВАННОЕ ИМЕНОВАНИЕ
204    // ========================================================================================
205
206    pub fn get_individual(&mut self, id: &str, iraw: &mut Individual) -> StorageResult<()> {
207        self.with_storage(StorageResult::NotReady, |s| s.get_individual(StorageId::Individuals, id, iraw))
208    }
209
210    pub fn get_individual_from_storage(&mut self, storage: StorageId, id: &str, iraw: &mut Individual) -> StorageResult<()> {
211        self.with_storage(StorageResult::NotReady, |s| s.get_individual(storage, id, iraw))
212    }
213
214    pub fn get_value(&mut self, storage: StorageId, id: &str) -> StorageResult<String> {
215        self.with_storage_value(|s| s.get_value(storage, id))
216    }
217
218    pub fn get_raw_value(&mut self, storage: StorageId, id: &str) -> StorageResult<Vec<u8>> {
219        self.with_storage_value(|s| s.get_raw_value(storage, id))
220    }
221
222    pub fn put_value(&mut self, storage: StorageId, key: &str, val: &str) -> StorageResult<()> {
223        self.with_storage_result(|s| s.put_value(storage, key, val))
224    }
225
226    pub fn put_raw_value(&mut self, storage: StorageId, key: &str, val: Vec<u8>) -> StorageResult<()> {
227        self.with_storage_result(|s| s.put_raw_value(storage, key, val))
228    }
229
230    pub fn remove_value(&mut self, storage: StorageId, key: &str) -> StorageResult<()> {
231        self.with_storage_result(|s| s.remove_value(storage, key))
232    }
233
234    pub fn count(&mut self, storage: StorageId) -> StorageResult<usize> {
235        self.with_storage_value(|s| s.count(storage))
236    }
237
238    // ========================================================================================
239    // DEPRECATED МЕТОДЫ ДЛЯ ОБРАТНОЙ СОВМЕСТИМОСТИ
240    // ========================================================================================
241
242    #[deprecated(since = "0.1.0", note = "Use get_individual_from_storage instead")]
243    pub fn get_individual_from_db(&mut self, storage: StorageId, id: &str, iraw: &mut Individual) -> StorageResult<()> {
244        self.get_individual_from_storage(storage, id, iraw)
245    }
246
247    #[deprecated(since = "0.1.0", note = "Use get_value instead")]
248    pub fn get_v(&mut self, storage: StorageId, id: &str) -> Option<String> {
249        match self.get_value(storage, id) {
250            StorageResult::Ok(value) => Some(value),
251            _ => None,
252        }
253    }
254
255    #[deprecated(since = "0.1.0", note = "Use get_raw_value instead")]
256    pub fn get_raw(&mut self, storage: StorageId, id: &str) -> Vec<u8> {
257        self.get_raw_value(storage, id).unwrap_or_default()
258    }
259
260    #[deprecated(since = "0.1.0", note = "Use put_value instead")]
261    pub fn put_kv(&mut self, storage: StorageId, key: &str, val: &str) -> bool {
262        self.put_value(storage, key, val).is_ok()
263    }
264
265    #[deprecated(since = "0.1.0", note = "Use put_raw_value instead")]
266    pub fn put_kv_raw(&mut self, storage: StorageId, key: &str, val: Vec<u8>) -> bool {
267        self.put_raw_value(storage, key, val).is_ok()
268    }
269
270    #[deprecated(since = "0.1.0", note = "Use remove_value instead")]
271    pub fn remove(&mut self, storage: StorageId, key: &str) -> bool {
272        self.remove_value(storage, key).is_ok()
273    }
274}
275
276// ========================================================================================
277// GENERIC ВЕРСИЯ - VStorageGeneric<S>
278// ========================================================================================
279
280/// Generic версия VStorage с статической диспетчеризацией
281/// 
282/// Преимущества:
283/// - Нет накладных расходов на динамическую диспетчеризацию
284/// - Нет heap allocations для storage
285/// - Лучшая производительность
286/// - Больше возможностей для оптимизации компилятором
287pub struct VStorageGeneric<S: Storage> {
288    storage: Option<S>,
289}
290
291impl<S: Storage> StorageDispatcher for VStorageGeneric<S> {
292    type Storage = S;
293
294    fn with_storage<T, F>(&mut self, default_value: T, operation: F) -> T 
295    where 
296        F: FnOnce(&mut Self::Storage) -> T,
297    {
298        match self.storage.as_mut() {
299            Some(storage) => operation(storage),
300            None => default_value,
301        }
302    }
303}
304
305impl<S: Storage> VStorageGeneric<S> {
306    /// Создает новое generic хранилище с конкретным типом
307    pub fn new(storage: S) -> Self {
308        Self {
309            storage: Some(storage),
310        }
311    }
312
313    /// Создает пустое хранилище
314    pub fn none() -> Self {
315        Self {
316            storage: None,
317        }
318    }
319
320    /// Проверяет, пусто ли хранилище
321    pub fn is_empty(&self) -> bool {
322        self.storage.is_none()
323    }
324
325    /// Берет хранилище из структуры, оставляя None
326    pub fn take_storage(mut self) -> Option<S> {
327        self.storage.take()
328    }
329
330    /// Возвращает ссылку на хранилище
331    pub fn storage(&self) -> Option<&S> {
332        self.storage.as_ref()
333    }
334
335    /// Возвращает мутабельную ссылку на хранилище
336    pub fn storage_mut(&mut self) -> Option<&mut S> {
337        self.storage.as_mut()
338    }
339
340    // ========================================================================================
341    // ПУБЛИЧНЫЕ МЕТОДЫ API - ИДЕНТИЧНЫЕ VStorage
342    // ========================================================================================
343
344    pub fn get_individual(&mut self, id: &str, iraw: &mut Individual) -> StorageResult<()> {
345        self.with_storage(StorageResult::NotReady, |s| s.get_individual(StorageId::Individuals, id, iraw))
346    }
347
348    pub fn get_individual_from_storage(&mut self, storage: StorageId, id: &str, iraw: &mut Individual) -> StorageResult<()> {
349        self.with_storage(StorageResult::NotReady, |s| s.get_individual(storage, id, iraw))
350    }
351
352    pub fn get_value(&mut self, storage: StorageId, id: &str) -> StorageResult<String> {
353        self.with_storage_value(|s| s.get_value(storage, id))
354    }
355
356    pub fn get_raw_value(&mut self, storage: StorageId, id: &str) -> StorageResult<Vec<u8>> {
357        self.with_storage_value(|s| s.get_raw_value(storage, id))
358    }
359
360    pub fn put_value(&mut self, storage: StorageId, key: &str, val: &str) -> StorageResult<()> {
361        self.with_storage_result(|s| s.put_value(storage, key, val))
362    }
363
364    pub fn put_raw_value(&mut self, storage: StorageId, key: &str, val: Vec<u8>) -> StorageResult<()> {
365        self.with_storage_result(|s| s.put_raw_value(storage, key, val))
366    }
367
368    pub fn remove_value(&mut self, storage: StorageId, key: &str) -> StorageResult<()> {
369        self.with_storage_result(|s| s.remove_value(storage, key))
370    }
371
372    pub fn count(&mut self, storage: StorageId) -> StorageResult<usize> {
373        self.with_storage_value(|s| s.count(storage))
374    }
375}
376
377// Реализация Default для случаев, когда S реализует Default
378impl<S: Storage + Default> Default for VStorageGeneric<S> {
379    fn default() -> Self {
380        Self::new(S::default())
381    }
382}
383
384// Реализация Clone для случаев, когда S реализует Clone
385impl<S: Storage + Clone> Clone for VStorageGeneric<S> {
386    fn clone(&self) -> Self {
387        Self {
388            storage: self.storage.clone(),
389        }
390    }
391}
392
393// Реализация Debug для случаев, когда S реализует Debug
394impl<S: Storage + std::fmt::Debug> std::fmt::Debug for VStorageGeneric<S> {
395    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
396        f.debug_struct("VStorageGeneric")
397            .field("storage", &self.storage)
398            .finish()
399    }
400}
401
402// ========================================================================================
403// TYPE ALIASES ДЛЯ УДОБСТВА
404// ========================================================================================
405
406pub type VMemoryStorage = VStorageGeneric<crate::memory_storage::MemoryStorage>;
407pub type VLMDBStorage = VStorageGeneric<crate::lmdb_storage::LMDBStorage>;
408pub type VRemoteStorage = VStorageGeneric<crate::remote_storage_client::StorageROClient>;
409#[cfg(any(feature = "tt_2", feature = "tt_3"))]
410pub type VTTStorage = VStorageGeneric<crate::tt_storage::TTStorage>;
411
412// ========================================================================================
413// ТЕСТЫ
414// ========================================================================================
415
416#[cfg(test)]
417mod tests {
418    use super::*;
419    use crate::storage_factory::StorageConfig;
420
421    #[test]
422    fn test_enum_storage_performance() {
423        let mut enum_storage = VStorageEnum::memory();
424        
425        // Test enum dispatch operations
426        assert!(enum_storage.put_value(StorageId::Individuals, "key1", "value1").is_ok());
427        let get_result = enum_storage.get_value(StorageId::Individuals, "key1");
428        assert!(get_result.is_ok(), "Expected Ok, got: {:?}", get_result);
429        if let StorageResult::Ok(value) = get_result {
430            assert_eq!(value, "value1");
431        }
432        
433        // Test count
434        let count_result = enum_storage.count(StorageId::Individuals);
435        assert!(count_result.is_ok(), "Expected Ok count, got: {:?}", count_result);
436        if let StorageResult::Ok(count) = count_result {
437            assert_eq!(count, 1);
438        }
439    }
440
441    #[test]
442    fn test_enum_storage_empty() {
443        let mut storage = VStorageEnum::default();
444        assert!(storage.is_empty());
445        
446        // Operations on empty storage should return NotReady
447        let get_result = storage.get_value(StorageId::Individuals, "key");
448        assert_eq!(get_result, StorageResult::NotReady, "Expected NotReady, got: {:?}", get_result);
449        
450        // Test other operations on empty storage
451        let put_result = storage.put_value(StorageId::Individuals, "key", "value");
452        assert_eq!(put_result, StorageResult::NotReady, "Expected NotReady for put, got: {:?}", put_result);
453        
454        let count_result = storage.count(StorageId::Individuals);
455        assert_eq!(count_result, StorageResult::NotReady, "Expected NotReady for count, got: {:?}", count_result);
456    }
457
458    #[test]
459    fn test_memory_storage_builder() {
460        let storage_result = VStorage::builder()
461            .memory()
462            .build();
463        
464        assert!(storage_result.is_ok(), "Failed to build storage");
465        if let Ok(storage_box) = storage_result {
466            let mut storage = VStorage::new(storage_box);
467
468            // Test new unified API
469            assert!(storage.put_value(StorageId::Individuals, "test_key", "test_value").is_ok());
470            let get_result = storage.get_value(StorageId::Individuals, "test_key");
471            assert!(get_result.is_ok(), "Expected Ok, got: {:?}", get_result);
472            if let StorageResult::Ok(value) = get_result {
473                assert_eq!(value, "test_value");
474            }
475        }
476    }
477
478    #[test]
479    fn test_storage_from_config() {
480        let config = StorageConfig::Memory;
481        let storage_result = VStorage::from_config(config);
482        
483        assert!(storage_result.is_ok(), "Failed to create storage from config");
484        if let Ok(mut storage) = storage_result {
485            // Test unified API
486            assert!(storage.put_value(StorageId::Individuals, "test_key", "test_value").is_ok());
487            let get_result = storage.get_value(StorageId::Individuals, "test_key");
488            assert!(get_result.is_ok(), "Expected Ok, got: {:?}", get_result);
489            if let StorageResult::Ok(value) = get_result {
490                assert_eq!(value, "test_value");
491            }
492        }
493    }
494
495    #[test]
496    fn test_empty_storage() {
497        let storage = VStorage::none();
498        assert!(storage.is_empty());
499    }
500
501    #[test]
502    fn test_individual_operations() {
503        let storage_box = VStorage::builder()
504            .memory()
505            .build()
506            .unwrap();
507        let mut storage = VStorage::new(storage_box);
508        let mut individual = Individual::default();
509
510        // Test with non-existent individual
511        assert_eq!(storage.get_individual("non-existent", &mut individual), StorageResult::NotFound);
512    }
513
514    #[test]
515    fn test_backward_compatibility() {
516        let storage_box = VStorage::builder()
517            .memory()
518            .build()
519            .unwrap();
520        let mut storage = VStorage::new(storage_box);
521
522        // Test deprecated methods still work
523        #[allow(deprecated)]
524        {
525            assert!(storage.put_kv(StorageId::Individuals, "key", "value"));
526            assert_eq!(storage.get_v(StorageId::Individuals, "key"), Some("value".to_string()));
527            assert!(storage.remove(StorageId::Individuals, "key"));
528        }
529    }
530
531    // ========================================================================================
532    // ТЕСТЫ ДЛЯ GENERIC ВЕРСИИ
533    // ========================================================================================
534
535    #[test]
536    fn test_generic_memory_storage() {
537        let mut storage = VMemoryStorage::new(crate::memory_storage::MemoryStorage::new());
538
539        // Test unified API
540        assert!(storage.put_value(StorageId::Individuals, "test_key", "test_value").is_ok());
541        let get_result = storage.get_value(StorageId::Individuals, "test_key");
542        assert!(get_result.is_ok(), "Expected Ok, got: {:?}", get_result);
543        if let StorageResult::Ok(value) = get_result {
544            assert_eq!(value, "test_value");
545        }
546        
547        // Test count
548        let count_result = storage.count(StorageId::Individuals);
549        assert!(count_result.is_ok(), "Expected Ok count, got: {:?}", count_result);
550        if let StorageResult::Ok(count) = count_result {
551            assert_eq!(count, 1);
552        }
553        
554        // Test remove
555        assert!(storage.remove_value(StorageId::Individuals, "test_key").is_ok());
556        let count_after_remove = storage.count(StorageId::Individuals);
557        assert!(count_after_remove.is_ok(), "Expected Ok count after remove, got: {:?}", count_after_remove);
558        if let StorageResult::Ok(count) = count_after_remove {
559            assert_eq!(count, 0);
560        }
561        
562        // Test edge case: remove non-existent key
563        let remove_result = storage.remove_value(StorageId::Individuals, "non-existent");
564        assert_eq!(remove_result, StorageResult::NotFound, "Expected NotFound for non-existent key");
565    }
566
567    #[test]
568    fn test_generic_storage_creation() {
569        // Создание через конструктор
570        let memory_storage = crate::memory_storage::MemoryStorage::new();
571        let mut generic_storage = VStorageGeneric::new(memory_storage);
572        
573        assert!(!generic_storage.is_empty());
574        assert!(generic_storage.put_value(StorageId::Individuals, "key", "value").is_ok());
575        
576        // Извлечение хранилища
577        let extracted = generic_storage.take_storage();
578        assert!(extracted.is_some());
579    }
580
581    #[test]
582    fn test_generic_storage_none() {
583        let storage: VStorageGeneric<crate::memory_storage::MemoryStorage> = VStorageGeneric::none();
584        assert!(storage.is_empty());
585    }
586
587    #[test]
588    fn test_generic_storage_individual_operations() {
589        let mut storage = VMemoryStorage::new(crate::memory_storage::MemoryStorage::new());
590        let mut individual = Individual::default();
591
592        // Test with non-existent individual
593        assert_eq!(storage.get_individual("non-existent", &mut individual), StorageResult::NotFound);
594    }
595
596    #[test]
597    fn test_unified_api_consistency() {
598        // Проверяем что все три типа хранилищ имеют одинаковый API
599        let mut dynamic_storage = VStorage::new(Box::new(crate::memory_storage::MemoryStorage::new()));
600        let mut generic_storage = VMemoryStorage::new(crate::memory_storage::MemoryStorage::new());
601        let mut enum_storage = VStorageEnum::memory();
602
603        // Одинаковые операции должны работать одинаково
604        assert!(dynamic_storage.put_value(StorageId::Individuals, "key", "value").is_ok());
605        assert!(generic_storage.put_value(StorageId::Individuals, "key", "value").is_ok());
606        assert!(enum_storage.put_value(StorageId::Individuals, "key", "value").is_ok());
607
608        let dynamic_result = dynamic_storage.get_value(StorageId::Individuals, "key");
609        let generic_result = generic_storage.get_value(StorageId::Individuals, "key");
610        let enum_result = enum_storage.get_value(StorageId::Individuals, "key");
611        
612        // Все результаты должны быть Ok
613        assert!(dynamic_result.is_ok(), "Dynamic storage should return Ok");
614        assert!(generic_result.is_ok(), "Generic storage should return Ok");
615        assert!(enum_result.is_ok(), "Enum storage should return Ok");
616        
617        // Все значения должны быть одинаковыми
618        if let (StorageResult::Ok(val1), StorageResult::Ok(val2), StorageResult::Ok(val3)) = 
619            (dynamic_result, generic_result, enum_result) {
620            assert_eq!(val1, val2, "Dynamic and generic storage values should match");
621            assert_eq!(val2, val3, "Generic and enum storage values should match");
622        }
623        
624        // Test count consistency
625        let count1 = dynamic_storage.count(StorageId::Individuals);
626        let count2 = generic_storage.count(StorageId::Individuals);
627        let count3 = enum_storage.count(StorageId::Individuals);
628        
629        assert!(count1.is_ok() && count2.is_ok() && count3.is_ok(), "All counts should be Ok");
630        if let (StorageResult::Ok(c1), StorageResult::Ok(c2), StorageResult::Ok(c3)) = (count1, count2, count3) {
631            assert_eq!(c1, c2);
632            assert_eq!(c2, c3);
633        }
634    }
635}