...
This commit is contained in:
parent
9c7baa3b4e
commit
56f73e5802
@ -28,9 +28,13 @@ name = "rhai_demo"
|
||||
path = "examples/rhai_demo.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "dbexample2"
|
||||
path = "src/cmd/dbexample2/main.rs"
|
||||
name = "dbexample_prod"
|
||||
path = "src/cmd/dbexample_prod/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "dbexample_mcc"
|
||||
path = "src/cmd/dbexample_mcc/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "dbexample_gov"
|
||||
path = "src/cmd/dbexample_gov/main.rs"
|
||||
|
@ -7,7 +7,12 @@ A database library built on top of sled with model support.
|
||||
## example
|
||||
|
||||
```bash
|
||||
cargo run --bin dbexample2
|
||||
#test for mcc module
|
||||
cargo run --bin dbexample_mcc
|
||||
#test for governance module
|
||||
cargo run --bin dbexample_gov
|
||||
#test for products
|
||||
cargo run --bin dbexample_prod
|
||||
```
|
||||
|
||||
## Features
|
||||
|
@ -1,38 +0,0 @@
|
||||
//! Demonstrates how to use the Rhai wrappers for our models
|
||||
|
||||
use herodb::zaz::rhai::{run_script_file, run_example_script};
|
||||
use std::path::PathBuf;
|
||||
use std::fs;
|
||||
use std::time::SystemTime;
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
println!("=== RHAI MODEL WRAPPERS DEMONSTRATION ===");
|
||||
|
||||
// Run our test script that creates model objects
|
||||
let test_script_path = "src/zaz/rhai/test.rhai";
|
||||
println!("\n1. Running model creation test script: {}", test_script_path);
|
||||
run_script_file(test_script_path)?;
|
||||
|
||||
// Create temporary directory for DB example
|
||||
let temp_dir = create_temp_dir()
|
||||
.map_err(|e| format!("Failed to create temp dir: {}", e))?;
|
||||
|
||||
// Run our example script that uses the DB
|
||||
println!("\n2. Running example with database at: {:?}", temp_dir);
|
||||
run_example_script(temp_dir.to_str().unwrap())?;
|
||||
|
||||
println!("\n=== DEMONSTRATION COMPLETED SUCCESSFULLY ===");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates a simple temporary directory
|
||||
fn create_temp_dir() -> std::io::Result<PathBuf> {
|
||||
let temp_dir = std::env::temp_dir();
|
||||
let random_name = format!("rhai-demo-{}", SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis());
|
||||
let path = temp_dir.join(random_name);
|
||||
fs::create_dir_all(&path)?;
|
||||
Ok(path)
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
# HeroDB Architecture
|
||||
|
||||
This document explains the architecture of HeroDB, focusing on the separation between model definitions and database logic.
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Separation of Concerns**: The DB core should not know about specific models
|
||||
2. **Registration-Based System**: Models get registered with the DB through a factory pattern
|
||||
3. **Type-Safety**: Despite the separation, we maintain full type safety
|
||||
|
||||
## Components
|
||||
|
||||
### Core Module
|
||||
|
||||
The `core` module provides the database foundation without knowing about specific models:
|
||||
|
||||
- `SledModel` trait: Defines the interface models must implement
|
||||
- `Storable` trait: Provides serialization/deserialization capabilities
|
||||
- `SledDB<T>`: Generic database wrapper for any model type
|
||||
- `DB`: Main database manager that holds registered models
|
||||
- `DBBuilder`: Builder for creating a DB with registered models
|
||||
|
||||
### Zaz Module
|
||||
|
||||
The `zaz` module contains domain-specific models and factories:
|
||||
|
||||
- `models`: Defines specific model types like User, Company, etc.
|
||||
- `factory`: Provides functions to create a DB with zaz models registered
|
||||
|
||||
## Using the DB
|
||||
|
||||
### Option 1: Factory Function
|
||||
|
||||
The easiest way to create a DB with all zaz models is to use the factory:
|
||||
|
||||
```rust
|
||||
use herodb::zaz::create_zaz_db;
|
||||
|
||||
// Create a DB with all zaz models registered
|
||||
let db = create_zaz_db("/path/to/db")?;
|
||||
|
||||
// Use the DB with specific model types
|
||||
let user = User::new(...);
|
||||
db.set(&user)?;
|
||||
let retrieved: User = db.get(&id)?;
|
||||
```
|
||||
|
||||
### Option 2: Builder Pattern
|
||||
|
||||
For more control, use the builder pattern to register only the models you need:
|
||||
|
||||
```rust
|
||||
use herodb::core::{DBBuilder, DB};
|
||||
use herodb::zaz::models::{User, Company};
|
||||
|
||||
// Create a DB with only User and Company models
|
||||
let db = DBBuilder::new("/path/to/db")
|
||||
.register_model::<User>()
|
||||
.register_model::<Company>()
|
||||
.build()?;
|
||||
```
|
||||
|
||||
### Option 3: Dynamic Registration
|
||||
|
||||
You can also register models with an existing DB:
|
||||
|
||||
```rust
|
||||
use herodb::core::DB;
|
||||
use herodb::zaz::models::User;
|
||||
|
||||
// Create an empty DB
|
||||
let mut db = DB::new("/path/to/db")?;
|
||||
|
||||
// Register the User model
|
||||
db.register::<User>()?;
|
||||
```
|
||||
|
||||
## Benefits of this Architecture
|
||||
|
||||
1. **Modularity**: The core DB code doesn't need to change when models change
|
||||
2. **Extensibility**: New model types can be added without modifying core DB code
|
||||
3. **Flexibility**: Different modules can define and use their own models with the same DB code
|
||||
4. **Type Safety**: Full compile-time type checking is maintained
|
||||
|
||||
## Implementation Details
|
||||
|
||||
The key to this architecture is the combination of generic types and trait objects:
|
||||
|
||||
- `SledDB<T>` provides type-safe operations for specific model types
|
||||
- `AnyDbOperations` trait allows type-erased operations through a common interface
|
||||
- `TypeId` mapping enables runtime lookup of the correct DB for a given model type
|
@ -1,168 +0,0 @@
|
||||
//! Integration tests for zaz database module
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use sled;
|
||||
use bincode;
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::Path;
|
||||
use tempfile::tempdir;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Test model for database operations
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
struct User {
|
||||
id: u32,
|
||||
name: String,
|
||||
email: String,
|
||||
balance: f64,
|
||||
created_at: DateTime<Utc>,
|
||||
updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl User {
|
||||
fn new(id: u32, name: String, email: String, balance: f64) -> Self {
|
||||
let now = Utc::now();
|
||||
Self {
|
||||
id,
|
||||
name,
|
||||
email,
|
||||
balance,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Test basic CRUD operations
|
||||
#[test]
|
||||
fn test_basic_crud() {
|
||||
// Create a temporary directory for testing
|
||||
let temp_dir = tempdir().expect("Failed to create temp directory");
|
||||
println!("Created temporary directory at: {:?}", temp_dir.path());
|
||||
|
||||
// Open a sled database in the temporary directory
|
||||
let db = sled::open(temp_dir.path().join("users")).expect("Failed to open database");
|
||||
println!("Opened database at: {:?}", temp_dir.path().join("users"));
|
||||
|
||||
// CREATE a user
|
||||
let user = User::new(1, "Test User".to_string(), "test@example.com".to_string(), 100.0);
|
||||
let user_key = user.id.to_string();
|
||||
let user_value = bincode::serialize(&user).expect("Failed to serialize user");
|
||||
db.insert(user_key.as_bytes(), user_value).expect("Failed to insert user");
|
||||
db.flush().expect("Failed to flush database");
|
||||
println!("Created user: {} ({})", user.name, user.email);
|
||||
|
||||
// READ the user
|
||||
let result = db.get(user_key.as_bytes()).expect("Failed to query database");
|
||||
assert!(result.is_some(), "User should exist");
|
||||
if let Some(data) = result {
|
||||
let retrieved_user: User = bincode::deserialize(&data).expect("Failed to deserialize user");
|
||||
println!("Retrieved user: {} ({})", retrieved_user.name, retrieved_user.email);
|
||||
assert_eq!(user, retrieved_user, "Retrieved user should match original");
|
||||
}
|
||||
|
||||
// UPDATE the user
|
||||
let updated_user = User::new(1, "Updated User".to_string(), "updated@example.com".to_string(), 150.0);
|
||||
let updated_value = bincode::serialize(&updated_user).expect("Failed to serialize updated user");
|
||||
db.insert(user_key.as_bytes(), updated_value).expect("Failed to update user");
|
||||
db.flush().expect("Failed to flush database");
|
||||
println!("Updated user: {} ({})", updated_user.name, updated_user.email);
|
||||
|
||||
let result = db.get(user_key.as_bytes()).expect("Failed to query database");
|
||||
if let Some(data) = result {
|
||||
let retrieved_user: User = bincode::deserialize(&data).expect("Failed to deserialize user");
|
||||
assert_eq!(updated_user, retrieved_user, "Retrieved user should match updated version");
|
||||
} else {
|
||||
panic!("User should exist after update");
|
||||
}
|
||||
|
||||
// DELETE the user
|
||||
db.remove(user_key.as_bytes()).expect("Failed to delete user");
|
||||
db.flush().expect("Failed to flush database");
|
||||
println!("Deleted user");
|
||||
|
||||
let result = db.get(user_key.as_bytes()).expect("Failed to query database");
|
||||
assert!(result.is_none(), "User should be deleted");
|
||||
|
||||
// Clean up
|
||||
drop(db);
|
||||
temp_dir.close().expect("Failed to cleanup temporary directory");
|
||||
}
|
||||
|
||||
/// Test transaction-like behavior with multiple operations
|
||||
#[test]
|
||||
fn test_transaction_behavior() {
|
||||
// Create a temporary directory for testing
|
||||
let temp_dir = tempdir().expect("Failed to create temp directory");
|
||||
println!("Created temporary directory at: {:?}", temp_dir.path());
|
||||
|
||||
// Open a sled database in the temporary directory
|
||||
let db = sled::open(temp_dir.path().join("tx_test")).expect("Failed to open database");
|
||||
println!("Opened transaction test database at: {:?}", temp_dir.path().join("tx_test"));
|
||||
|
||||
// Create initial users
|
||||
let user1 = User::new(1, "User One".to_string(), "one@example.com".to_string(), 100.0);
|
||||
let user2 = User::new(2, "User Two".to_string(), "two@example.com".to_string(), 50.0);
|
||||
|
||||
// Insert initial users
|
||||
db.insert(user1.id.to_string().as_bytes(), bincode::serialize(&user1).unwrap()).unwrap();
|
||||
db.insert(user2.id.to_string().as_bytes(), bincode::serialize(&user2).unwrap()).unwrap();
|
||||
db.flush().unwrap();
|
||||
println!("Inserted initial users");
|
||||
|
||||
// Simulate a transaction - transfer 25.0 from user1 to user2
|
||||
println!("Starting transaction simulation: transfer 25.0 from user1 to user2");
|
||||
|
||||
// Create transaction workspace
|
||||
let mut tx_workspace = HashMap::new();
|
||||
|
||||
// Retrieve current state
|
||||
if let Some(data) = db.get(user1.id.to_string().as_bytes()).unwrap() {
|
||||
let user: User = bincode::deserialize(&data).unwrap();
|
||||
tx_workspace.insert(user1.id.to_string(), user);
|
||||
}
|
||||
|
||||
if let Some(data) = db.get(user2.id.to_string().as_bytes()).unwrap() {
|
||||
let user: User = bincode::deserialize(&data).unwrap();
|
||||
tx_workspace.insert(user2.id.to_string(), user);
|
||||
}
|
||||
|
||||
// Modify both users in the transaction
|
||||
let mut updated_user1 = tx_workspace.get(&user1.id.to_string()).unwrap().clone();
|
||||
let mut updated_user2 = tx_workspace.get(&user2.id.to_string()).unwrap().clone();
|
||||
|
||||
updated_user1.balance -= 25.0;
|
||||
updated_user2.balance += 25.0;
|
||||
|
||||
// Update the workspace
|
||||
tx_workspace.insert(user1.id.to_string(), updated_user1);
|
||||
tx_workspace.insert(user2.id.to_string(), updated_user2);
|
||||
|
||||
// Commit the transaction
|
||||
println!("Committing transaction");
|
||||
for (key, user) in tx_workspace {
|
||||
let user_bytes = bincode::serialize(&user).unwrap();
|
||||
db.insert(key.as_bytes(), user_bytes).unwrap();
|
||||
}
|
||||
db.flush().unwrap();
|
||||
|
||||
// Verify the results
|
||||
if let Some(data) = db.get(user1.id.to_string().as_bytes()).unwrap() {
|
||||
let final_user1: User = bincode::deserialize(&data).unwrap();
|
||||
assert_eq!(final_user1.balance, 75.0, "User1 balance should be 75.0");
|
||||
println!("Verified user1 balance is now {}", final_user1.balance);
|
||||
}
|
||||
|
||||
if let Some(data) = db.get(user2.id.to_string().as_bytes()).unwrap() {
|
||||
let final_user2: User = bincode::deserialize(&data).unwrap();
|
||||
assert_eq!(final_user2.balance, 75.0, "User2 balance should be 75.0");
|
||||
println!("Verified user2 balance is now {}", final_user2.balance);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
drop(db);
|
||||
temp_dir.close().expect("Failed to cleanup temporary directory");
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
// Examples for using the Zaz database
|
||||
|
||||
use crate::zaz::models::*;
|
||||
use crate::zaz::factory::create_zaz_db;
|
||||
use std::path::PathBuf;
|
||||
use chrono::Utc;
|
||||
|
||||
/// Run a simple example of the DB operations
|
||||
pub fn run_db_examples() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Running Zaz DB examples...");
|
||||
|
||||
// Create a temp DB path
|
||||
let db_path = PathBuf::from("/tmp/zaz-examples");
|
||||
std::fs::create_dir_all(&db_path)?;
|
||||
|
||||
// Create DB instance
|
||||
let db = create_zaz_db(&db_path)?;
|
||||
|
||||
// Example 1: User operations
|
||||
println!("\n--- User Examples ---");
|
||||
let user = User::new(
|
||||
1,
|
||||
"John Doe".to_string(),
|
||||
"john@example.com".to_string(),
|
||||
"secure123".to_string(),
|
||||
"Example Corp".to_string(),
|
||||
"User".to_string(),
|
||||
);
|
||||
|
||||
db.set(&user)?;
|
||||
println!("Inserted user: {}", user.name);
|
||||
|
||||
let retrieved_user = db.get::<User>(&user.id.to_string())?;
|
||||
println!("Retrieved user: {} ({})", retrieved_user.name, retrieved_user.email);
|
||||
|
||||
// Example 2: Company operations
|
||||
println!("\n--- Company Examples ---");
|
||||
let company = Company::new(
|
||||
1,
|
||||
"Example Corp".to_string(),
|
||||
"EX123456".to_string(),
|
||||
Utc::now(),
|
||||
"12-31".to_string(),
|
||||
"info@example.com".to_string(),
|
||||
"123-456-7890".to_string(),
|
||||
"www.example.com".to_string(),
|
||||
"123 Example St, Example City".to_string(),
|
||||
BusinessType::Global,
|
||||
"Technology".to_string(),
|
||||
"An example company".to_string(),
|
||||
CompanyStatus::Active,
|
||||
);
|
||||
|
||||
db.set(&company)?;
|
||||
println!("Inserted company: {}", company.name);
|
||||
|
||||
let companies = db.list::<Company>()?;
|
||||
println!("Found {} companies", companies.len());
|
||||
|
||||
// Clean up
|
||||
std::fs::remove_dir_all(db_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
//! Factory module for creating a DB with all zaz models registered
|
||||
|
||||
use crate::core::{DB, DBBuilder, SledDBResult};
|
||||
use crate::zaz::models::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Create a new DB instance with all zaz models registered
|
||||
pub fn create_zaz_db<P: Into<PathBuf>>(path: P) -> SledDBResult<DB> {
|
||||
// Using the builder pattern to register all models
|
||||
DBBuilder::new(path)
|
||||
.register_model::<User>()
|
||||
.register_model::<Company>()
|
||||
.register_model::<Meeting>()
|
||||
.register_model::<Product>()
|
||||
.register_model::<Sale>()
|
||||
.register_model::<Vote>()
|
||||
.register_model::<Shareholder>()
|
||||
.build()
|
||||
}
|
||||
|
||||
/// Register all zaz models with an existing DB instance
|
||||
pub fn register_zaz_models(db: &mut DB) -> SledDBResult<()> {
|
||||
// Dynamically register all zaz models
|
||||
db.register::<User>()?;
|
||||
db.register::<Company>()?;
|
||||
db.register::<Meeting>()?;
|
||||
db.register::<Product>()?;
|
||||
db.register::<Sale>()?;
|
||||
db.register::<Vote>()?;
|
||||
db.register::<Shareholder>()?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use chrono::{Utc, Duration};
|
||||
use herodb::db::DBBuilder;
|
||||
use herodb::models::governance::{
|
||||
use herodb::db::{DBBuilder, SledDB, SledModel};
|
||||
use herodb::models::gov::{
|
||||
Company, CompanyStatus, BusinessType,
|
||||
Shareholder, ShareholderType,
|
||||
Meeting, Attendee, MeetingStatus, AttendeeRole, AttendeeStatus,
|
||||
@ -12,11 +12,11 @@ use std::path::PathBuf;
|
||||
use std::fs;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("DB Example: Governance Module");
|
||||
println!("DB Example: Gov Module");
|
||||
println!("============================");
|
||||
|
||||
// Create a temporary directory for the database
|
||||
let db_path = PathBuf::from("/tmp/dbexample_governance");
|
||||
let db_path = PathBuf::from("/tmp/dbexample_gov");
|
||||
if db_path.exists() {
|
||||
fs::remove_dir_all(&db_path)?;
|
||||
}
|
||||
@ -54,7 +54,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
|
||||
// Insert the company
|
||||
db.insert(&company)?;
|
||||
db.set(&company)?;
|
||||
println!("Company created: {} (ID: {})", company.name, company.id);
|
||||
println!("Status: {:?}, Business Type: {:?}", company.status, company.business_type);
|
||||
|
||||
@ -90,9 +90,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
|
||||
// Insert the users
|
||||
db.insert(&user1)?;
|
||||
db.insert(&user2)?;
|
||||
db.insert(&user3)?;
|
||||
db.set(&user1)?;
|
||||
db.set(&user2)?;
|
||||
db.set(&user3)?;
|
||||
|
||||
println!("User created: {} ({})", user1.name, user1.role);
|
||||
println!("User created: {} ({})", user2.name, user2.role);
|
||||
@ -133,9 +133,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
|
||||
// Insert the shareholders
|
||||
db.insert(&shareholder1)?;
|
||||
db.insert(&shareholder2)?;
|
||||
db.insert(&shareholder3)?;
|
||||
db.set(&shareholder1)?;
|
||||
db.set(&shareholder2)?;
|
||||
db.set(&shareholder3)?;
|
||||
|
||||
println!("Shareholder created: {} ({} shares, {}%)",
|
||||
shareholder1.name, shareholder1.shares, shareholder1.percentage);
|
||||
@ -146,7 +146,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Update shareholder shares
|
||||
shareholder1.update_shares(1100.0, 44.0);
|
||||
db.insert(&shareholder1)?;
|
||||
db.set(&shareholder1)?;
|
||||
println!("Updated shareholder: {} ({} shares, {}%)",
|
||||
shareholder1.name, shareholder1.shares, shareholder1.percentage);
|
||||
|
||||
@ -194,7 +194,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
meeting.add_attendee(attendee3);
|
||||
|
||||
// Insert the meeting
|
||||
db.insert(&meeting)?;
|
||||
db.set(&meeting)?;
|
||||
println!("Meeting created: {} ({})", meeting.title, meeting.date.format("%Y-%m-%d %H:%M"));
|
||||
println!("Status: {:?}, Attendees: {}", meeting.status, meeting.attendees.len());
|
||||
|
||||
@ -205,7 +205,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if let Some(attendee) = meeting.find_attendee_by_user_id_mut(user3.id) {
|
||||
attendee.update_status(AttendeeStatus::Confirmed);
|
||||
}
|
||||
db.insert(&meeting)?;
|
||||
db.set(&meeting)?;
|
||||
|
||||
// Get confirmed attendees
|
||||
let confirmed = meeting.confirmed_attendees();
|
||||
@ -238,19 +238,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
resolution.link_to_meeting(meeting.id);
|
||||
|
||||
// Insert the resolution
|
||||
db.insert(&resolution)?;
|
||||
db.set(&resolution)?;
|
||||
println!("Resolution created: {} (Status: {:?})", resolution.title, resolution.status);
|
||||
|
||||
// Propose the resolution
|
||||
resolution.propose();
|
||||
db.insert(&resolution)?;
|
||||
db.set(&resolution)?;
|
||||
println!("Resolution proposed on {}", resolution.proposed_at.format("%Y-%m-%d"));
|
||||
|
||||
// Add approvals
|
||||
resolution.add_approval(user1.id, user1.name.clone(), true, "Approved as proposed".to_string());
|
||||
resolution.add_approval(user2.id, user2.name.clone(), true, "Financials look good".to_string());
|
||||
resolution.add_approval(user3.id, user3.name.clone(), true, "No concerns".to_string());
|
||||
db.insert(&resolution)?;
|
||||
db.set(&resolution)?;
|
||||
|
||||
// Check approval status
|
||||
println!("Approvals: {}, Rejections: {}",
|
||||
@ -259,7 +259,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Approve the resolution
|
||||
resolution.approve();
|
||||
db.insert(&resolution)?;
|
||||
db.set(&resolution)?;
|
||||
println!("Resolution approved on {}",
|
||||
resolution.approved_at.unwrap().format("%Y-%m-%d"));
|
||||
|
||||
@ -283,7 +283,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
vote.add_option("Abstain".to_string(), 0);
|
||||
|
||||
// Insert the vote
|
||||
db.insert(&vote)?;
|
||||
db.set(&vote)?;
|
||||
println!("Vote created: {} (Status: {:?})", vote.title, vote.status);
|
||||
println!("Voting period: {} to {}",
|
||||
vote.start_date.format("%Y-%m-%d"),
|
||||
@ -293,7 +293,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
vote.add_ballot(user1.id, 1, 1000); // User 1 votes "Approve" with 1000 shares
|
||||
vote.add_ballot(user2.id, 1, 750); // User 2 votes "Approve" with 750 shares
|
||||
vote.add_ballot(user3.id, 3, 750); // User 3 votes "Abstain" with 750 shares
|
||||
db.insert(&vote)?;
|
||||
db.set(&vote)?;
|
||||
|
||||
// Check voting results
|
||||
println!("Voting results:");
|
||||
@ -314,7 +314,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Link the resolution to the vote
|
||||
vote_resolution.link_to_vote(vote.id);
|
||||
vote_resolution.propose();
|
||||
db.insert(&vote_resolution)?;
|
||||
db.set(&vote_resolution)?;
|
||||
println!("Created resolution linked to vote: {}", vote_resolution.title);
|
||||
|
||||
println!("\n7. Retrieving Related Objects");
|
2161
herodb/src/cmd/dbexample_governance/Cargo.lock
generated
2161
herodb/src/cmd/dbexample_governance/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
||||
[package]
|
||||
name = "dbexample_governance"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "dbexample_governance"
|
||||
path = "main.rs"
|
||||
|
||||
[dependencies]
|
||||
herodb = { path = "../../.." }
|
||||
chrono = "0.4"
|
@ -115,7 +115,7 @@ pub mod governance;
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::db::{SledModel, Storable, SledDB, SledDBError};
|
||||
use crate::models::governance::{Meeting, Vote};
|
||||
use crate::models::gov::{Meeting, Vote};
|
||||
|
||||
/// ResolutionStatus represents the status of a resolution
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
@ -1,7 +1,7 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::db::{SledModel, Storable, SledDB, SledDBError};
|
||||
use crate::models::governance::User;
|
||||
use crate::models::gov::User;
|
||||
|
||||
/// CommitteeRole represents the role of a member in a committee
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
@ -123,8 +123,8 @@ impl Company {
|
||||
}
|
||||
|
||||
/// Get all resolutions for this company
|
||||
pub fn get_resolutions(&self, db: &SledDB<crate::models::governance::Resolution>) -> Result<Vec<crate::models::governance::Resolution>, SledDBError> {
|
||||
let all_resolutions = db.list()?;
|
||||
pub fn get_resolutions(&self, db: &crate::db::DB) -> Result<Vec<super::Resolution>, SledDBError> {
|
||||
let all_resolutions = db.list::<super::Resolution>()?;
|
||||
let company_resolutions = all_resolutions
|
||||
.into_iter()
|
||||
.filter(|resolution| resolution.company_id == self.id)
|
@ -1,7 +1,7 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::db::{SledModel, Storable, SledDB, SledDBError};
|
||||
use crate::models::governance::Company;
|
||||
use crate::models::gov::Company;
|
||||
|
||||
/// ComplianceRequirement represents a regulatory requirement
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
@ -164,8 +164,8 @@ impl Meeting {
|
||||
}
|
||||
|
||||
/// Get all resolutions discussed in this meeting
|
||||
pub fn get_resolutions(&self, db: &SledDB<crate::models::governance::Resolution>) -> Result<Vec<crate::models::governance::Resolution>, SledDBError> {
|
||||
let all_resolutions = db.list()?;
|
||||
pub fn get_resolutions(&self, db: &crate::db::DB) -> Result<Vec<super::Resolution>, SledDBError> {
|
||||
let all_resolutions = db.list::<super::Resolution>()?;
|
||||
let meeting_resolutions = all_resolutions
|
||||
.into_iter()
|
||||
.filter(|resolution| resolution.meeting_id == Some(self.id))
|
@ -1,7 +1,7 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::db::{SledModel, Storable, SledDB, SledDBError};
|
||||
use crate::models::governance::{Meeting, Vote};
|
||||
use crate::models::gov::{Meeting, Vote};
|
||||
|
||||
/// ResolutionStatus represents the status of a resolution
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@ -158,10 +158,10 @@ impl Resolution {
|
||||
}
|
||||
|
||||
/// Get the meeting associated with this resolution
|
||||
pub fn get_meeting(&self, db: &SledDB<Meeting>) -> Result<Option<Meeting>, SledDBError> {
|
||||
pub fn get_meeting(&self, db: &crate::db::DB) -> Result<Option<Meeting>, SledDBError> {
|
||||
match self.meeting_id {
|
||||
Some(meeting_id) => {
|
||||
let meeting = db.get(&meeting_id.to_string())?;
|
||||
let meeting = db.get::<Meeting>(&meeting_id.to_string())?;
|
||||
Ok(Some(meeting))
|
||||
}
|
||||
None => Ok(None),
|
||||
@ -169,10 +169,10 @@ impl Resolution {
|
||||
}
|
||||
|
||||
/// Get the vote associated with this resolution
|
||||
pub fn get_vote(&self, db: &SledDB<Vote>) -> Result<Option<Vote>, SledDBError> {
|
||||
pub fn get_vote(&self, db: &crate::db::DB) -> Result<Option<Vote>, SledDBError> {
|
||||
match self.vote_id {
|
||||
Some(vote_id) => {
|
||||
let vote = db.get(&vote_id.to_string())?;
|
||||
let vote = db.get::<Vote>(&vote_id.to_string())?;
|
||||
Ok(Some(vote))
|
||||
}
|
||||
None => Ok(None),
|
@ -128,8 +128,8 @@ impl Vote {
|
||||
}
|
||||
|
||||
/// Get the resolution associated with this vote
|
||||
pub fn get_resolution(&self, db: &SledDB<crate::models::governance::Resolution>) -> Result<Option<crate::models::governance::Resolution>, SledDBError> {
|
||||
let all_resolutions = db.list()?;
|
||||
pub fn get_resolution(&self, db: &crate::db::DB) -> Result<Option<super::Resolution>, SledDBError> {
|
||||
let all_resolutions = db.list::<super::Resolution>()?;
|
||||
let vote_resolution = all_resolutions
|
||||
.into_iter()
|
||||
.find(|resolution| resolution.vote_id == Some(self.id));
|
@ -1,4 +1,4 @@
|
||||
pub mod biz;
|
||||
pub mod mcc;
|
||||
pub mod circle;
|
||||
pub mod governance;
|
||||
pub mod gov;
|
4
herodb/tmp/dbexample2/currency/conf
Normal file
4
herodb/tmp/dbexample2/currency/conf
Normal file
@ -0,0 +1,4 @@
|
||||
segment_size: 524288
|
||||
use_compression: false
|
||||
version: 0.34
|
||||
vQÁ
|
BIN
herodb/tmp/dbexample2/currency/db
Normal file
BIN
herodb/tmp/dbexample2/currency/db
Normal file
Binary file not shown.
BIN
herodb/tmp/dbexample2/currency/snap.000000000000008A
Normal file
BIN
herodb/tmp/dbexample2/currency/snap.000000000000008A
Normal file
Binary file not shown.
4
herodb/tmp/dbexample2/product/conf
Normal file
4
herodb/tmp/dbexample2/product/conf
Normal file
@ -0,0 +1,4 @@
|
||||
segment_size: 524288
|
||||
use_compression: false
|
||||
version: 0.34
|
||||
vQÁ
|
BIN
herodb/tmp/dbexample2/product/db
Normal file
BIN
herodb/tmp/dbexample2/product/db
Normal file
Binary file not shown.
BIN
herodb/tmp/dbexample2/product/snap.0000000000000060
Normal file
BIN
herodb/tmp/dbexample2/product/snap.0000000000000060
Normal file
Binary file not shown.
4
herodb/tmp/dbexample2/sale/conf
Normal file
4
herodb/tmp/dbexample2/sale/conf
Normal file
@ -0,0 +1,4 @@
|
||||
segment_size: 524288
|
||||
use_compression: false
|
||||
version: 0.34
|
||||
vQÁ
|
BIN
herodb/tmp/dbexample2/sale/db
Normal file
BIN
herodb/tmp/dbexample2/sale/db
Normal file
Binary file not shown.
BIN
herodb/tmp/dbexample2/sale/snap.0000000000000060
Normal file
BIN
herodb/tmp/dbexample2/sale/snap.0000000000000060
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user