db/heromodels/docs/mcc_models_standalone_plan.md
2025-06-27 12:11:04 +03:00

4.9 KiB

MCC Models Standalone Implementation Plan

Overview

This document outlines the plan to make the MCC models in herodb/src/models/mcc completely standalone without dependencies on the database implementation, while ensuring that examples like herodb/src/cmd/dbexample_mcc can still work.

Current Architecture Analysis

graph TD
    subgraph "Before"
        A1[MCC Models] -->|Depends on| B1[DB Implementation]
        A1 -->|Implements| C1[Model Trait]
        A1 -->|Implements| D1[Storable Trait]
        E1[dbexample_mcc] -->|Uses| A1
        E1 -->|Uses| B1
    end
    
    subgraph "After"
        A2[Standalone MCC Models] -.->|No dependency on| B2[DB Implementation]
        B2 -->|Works with| F2[Any Serializable Struct]
        B2 -->|Optional trait| G2[ModelAdapter Trait]
        E2[dbexample_mcc] -->|Uses| A2
        E2 -->|Uses| B2
    end

Implementation Plan

Phase 1: Make MCC Models Standalone

  1. For each MCC model file (calendar.rs, event.rs, mail.rs, contacts.rs, message.rs):

    • Remove use crate::db::{Model, Storable, DB, DbError, DbResult}
    • Remove impl Model for X and impl Storable for X blocks
    • Replace methods that use DB (like get_events(&self, db: &DB)) with standalone methods
  2. For mod.rs and lib.rs:

    • Remove pub use crate::db::{DB, DBBuilder, Model, Storable, DbError, DbResult}

Phase 2: Modify DB Implementation

  1. Create a new ModelAdapter trait in db/model.rs:
pub trait ModelAdapter {
    fn get_id(&self) -> u32;
    fn db_prefix() -> &'static str;
    fn db_keys(&self) -> Vec<IndexKey> { Vec::new() }
}
  1. Modify DB methods in db.rs to work with any serializable struct:
impl DB {
    // Generic set method for any serializable type
    pub fn set<T: Serialize + DeserializeOwned + 'static>(&self, item: &T, id: u32, prefix: &str) -> DbResult<()> {
        // Implementation
    }
    
    // Enhanced version for types implementing ModelAdapter
    pub fn set_model<T: Serialize + DeserializeOwned + ModelAdapter + 'static>(&self, item: &T) -> DbResult<()> {
        self.set(item, item.get_id(), T::db_prefix())
    }
    
    // Similar changes for get, delete, list methods
}
  1. Update DBBuilder to register any serializable type:
impl DBBuilder {
    pub fn register_type<T: Serialize + DeserializeOwned + 'static>(&mut self, prefix: &'static str) -> &mut Self {
        // Implementation
    }
    
    pub fn register_model<T: Serialize + DeserializeOwned + ModelAdapter + 'static>(&mut self) -> &mut Self {
        self.register_type::<T>(T::db_prefix())
    }
}

Phase 3: Update Examples and Tests

  1. Update dbexample_mcc/main.rs:
let db = DBBuilder::new(&db_path)
    .register_type::<Calendar>("calendar")
    .register_type::<Event>("event")
    // etc.
    .build()?;
  1. Create a new standalone example for MCC models similar to circle_standalone.rs

Detailed Changes Required

MCC Models Changes

calendar.rs

  • Remove database-related imports
  • Remove Model and Storable trait implementations
  • Replace get_events(&self, db: &DB) with a standalone method like:
    pub fn filter_events(&self, events: &[Event]) -> Vec<&Event> {
        events.iter()
            .filter(|event| event.calendar_id == self.id)
            .collect()
    }
    

event.rs

  • Remove database-related imports
  • Remove Model and Storable trait implementations
  • Add standalone methods for event operations

mail.rs

  • Remove database-related imports
  • Remove Model and Storable trait implementations
  • Add standalone methods for mail operations

contacts.rs

  • Remove database-related imports
  • Remove Model and Storable trait implementations
  • Add standalone methods for contact operations

message.rs

  • Remove database-related imports
  • Remove Model and Storable trait implementations
  • Add standalone methods for message operations

mod.rs and lib.rs

  • Remove re-exports of database components

DB Implementation Changes

model.rs

  • Create a new ModelAdapter trait
  • Keep existing Model and Storable traits for backward compatibility
  • Add helper methods for working with serializable structs

db.rs

  • Modify DB methods to work with any serializable struct
  • Add overloaded methods for ModelAdapter types
  • Ensure backward compatibility with existing code

DBBuilder

  • Update to register any serializable type
  • Keep existing methods for backward compatibility

Testing Strategy

  1. Ensure all existing tests pass with the modified DB implementation
  2. Create new tests for standalone MCC models
  3. Verify dbexample_mcc works with the new implementation
  4. Create a new standalone example for MCC models

Benefits

  1. MCC models become more reusable and can be used without database dependencies
  2. DB implementation becomes more flexible and can work with any serializable struct
  3. Cleaner separation of concerns between models and database operations
  4. Easier to test models in isolation