mirror of
https://github.com/haexhub/haex-hub.git
synced 2025-12-18 23:10:51 +01:00
refactored permission system and error handling
This commit is contained in:
@ -156,9 +156,8 @@ pub fn select(
|
||||
|
||||
// Stelle sicher, dass es eine Query ist
|
||||
if !matches!(statement, Statement::Query(_)) {
|
||||
return Err(DatabaseError::UnsupportedStatement {
|
||||
statement_type: "Non-Query".to_string(),
|
||||
description: "Only SELECT statements are allowed in select function".to_string(),
|
||||
return Err(DatabaseError::StatementError {
|
||||
reason: "Only SELECT statements are allowed in select function".to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
// src-tauri/src/database/error.rs
|
||||
|
||||
use crate::crdt::trigger::CrdtSetupError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use ts_rs::TS;
|
||||
|
||||
use crate::crdt::trigger::CrdtSetupError;
|
||||
|
||||
#[derive(Error, Debug, Serialize, Deserialize, TS)]
|
||||
#[ts(export)]
|
||||
#[serde(tag = "type", content = "details")]
|
||||
@ -13,14 +12,21 @@ pub enum DatabaseError {
|
||||
/// Der SQL-Code konnte nicht geparst werden.
|
||||
#[error("Failed to parse SQL: {reason} - SQL: {sql}")]
|
||||
ParseError { reason: String, sql: String },
|
||||
|
||||
/// Parameter-Fehler (falsche Anzahl, ungültiger Typ, etc.)
|
||||
#[error("Parameter error: {reason} (expected: {expected}, provided: {provided})")]
|
||||
ParamError {
|
||||
reason: String,
|
||||
#[error("Parameter count mismatch: SQL has {expected} placeholders but {provided} provided. SQL Statement: {sql}")]
|
||||
ParameterMismatchError {
|
||||
expected: usize,
|
||||
provided: usize,
|
||||
sql: String,
|
||||
},
|
||||
|
||||
#[error("No table provided in SQL Statement: {sql}")]
|
||||
NoTableError { sql: String },
|
||||
|
||||
#[error("Statement Error: {reason}")]
|
||||
StatementError { reason: String },
|
||||
|
||||
#[error("Failed to prepare statement: {reason}")]
|
||||
PrepareError { reason: String },
|
||||
|
||||
@ -28,7 +34,7 @@ pub enum DatabaseError {
|
||||
DatabaseError { reason: String },
|
||||
|
||||
/// Ein Fehler ist während der Ausführung in der Datenbank aufgetreten.
|
||||
#[error("Execution error on table {}: {} - SQL: {}", table.as_deref().unwrap_or("unknown"), reason, sql)]
|
||||
#[error("Execution error on table {table:?}: {reason} - SQL: {sql}")]
|
||||
ExecutionError {
|
||||
sql: String,
|
||||
reason: String,
|
||||
@ -37,34 +43,36 @@ pub enum DatabaseError {
|
||||
/// Ein Fehler ist beim Verwalten der Transaktion aufgetreten.
|
||||
#[error("Transaction error: {reason}")]
|
||||
TransactionError { reason: String },
|
||||
|
||||
/// Ein SQL-Statement wird vom Proxy nicht unterstützt.
|
||||
#[error("Unsupported statement type '{statement_type}': {description}")]
|
||||
UnsupportedStatement {
|
||||
statement_type: String,
|
||||
description: String,
|
||||
},
|
||||
#[error("Unsupported statement. '{reason}'. - SQL: {sql}")]
|
||||
UnsupportedStatement { reason: String, sql: String },
|
||||
|
||||
/// Fehler im HLC-Service
|
||||
#[error("HLC error: {reason}")]
|
||||
HlcError { reason: String },
|
||||
|
||||
/// Fehler beim Sperren der Datenbankverbindung
|
||||
#[error("Lock error: {reason}")]
|
||||
LockError { reason: String },
|
||||
|
||||
/// Fehler bei der Datenbankverbindung
|
||||
#[error("Connection error: {reason}")]
|
||||
ConnectionError { reason: String },
|
||||
|
||||
/// Fehler bei der JSON-Serialisierung
|
||||
#[error("Serialization error: {reason}")]
|
||||
SerializationError { reason: String },
|
||||
|
||||
#[error("Permission error for extension '{extension_id}': {reason} (operation: {}, resource: {})",
|
||||
operation.as_deref().unwrap_or("unknown"),
|
||||
resource.as_deref().unwrap_or("unknown"))]
|
||||
/// Permission-bezogener Fehler für Extensions
|
||||
#[error("Permission error for extension '{extension_id}': {reason} (operation: {operation:?}, resource: {resource:?})")]
|
||||
PermissionError {
|
||||
extension_id: String,
|
||||
operation: Option<String>,
|
||||
resource: Option<String>,
|
||||
reason: String,
|
||||
},
|
||||
|
||||
#[error("Query error: {reason}")]
|
||||
QueryError { reason: String },
|
||||
|
||||
@ -111,7 +119,43 @@ impl From<CrdtSetupError> for DatabaseError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::extension::database::ExtensionDatabaseError> for DatabaseError {
|
||||
impl DatabaseError {
|
||||
/// Extract extension ID if this error is related to an extension
|
||||
pub fn extension_id(&self) -> Option<&str> {
|
||||
match self {
|
||||
DatabaseError::PermissionError { extension_id, .. } => Some(extension_id.as_str()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if this is a permission-related error
|
||||
pub fn is_permission_error(&self) -> bool {
|
||||
matches!(self, DatabaseError::PermissionError { .. })
|
||||
}
|
||||
|
||||
/// Get operation if available
|
||||
pub fn operation(&self) -> Option<&str> {
|
||||
match self {
|
||||
DatabaseError::PermissionError {
|
||||
operation: Some(op),
|
||||
..
|
||||
} => Some(op.as_str()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get resource if available
|
||||
pub fn resource(&self) -> Option<&str> {
|
||||
match self {
|
||||
DatabaseError::PermissionError {
|
||||
resource: Some(res),
|
||||
..
|
||||
} => Some(res.as_str()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
/* impl From<crate::extension::database::ExtensionDatabaseError> for DatabaseError {
|
||||
fn from(err: crate::extension::database::ExtensionDatabaseError) -> Self {
|
||||
match err {
|
||||
crate::extension::database::ExtensionDatabaseError::Permission { source } => {
|
||||
@ -156,4 +200,4 @@ impl From<crate::extension::database::ExtensionDatabaseError> for DatabaseError
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
@ -13,13 +13,10 @@ use tauri::{path::BaseDirectory, AppHandle, Manager, State};
|
||||
|
||||
use crate::crdt::hlc::HlcService;
|
||||
use crate::database::error::DatabaseError;
|
||||
use crate::table_names::TABLE_CRDT_CONFIGS;
|
||||
use crate::AppState;
|
||||
pub struct DbConnection(pub Arc<Mutex<Option<Connection>>>);
|
||||
|
||||
pub struct AppState {
|
||||
pub db: DbConnection,
|
||||
pub hlc: Mutex<HlcService>, // Kein Arc hier nötig, da der ganze AppState von Tauri in einem Arc verwaltet wird.
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn sql_select(
|
||||
sql: String,
|
||||
@ -166,25 +163,33 @@ pub fn create_encrypted_database(
|
||||
reason: format!("Fehler beim Schließen der Quelldatenbank: {}", e),
|
||||
})?;
|
||||
|
||||
let new_conn = core::open_and_init_db(&path, &key, false)?;
|
||||
initialize_session(&app_handle, &path, &key, &state)?;
|
||||
|
||||
/* let new_conn = core::open_and_init_db(&path, &key, false)?;
|
||||
|
||||
// Aktualisieren der Datenbankverbindung im State
|
||||
let mut db = state.db.0.lock().map_err(|e| DatabaseError::LockError {
|
||||
reason: e.to_string(),
|
||||
})?;
|
||||
|
||||
*db = Some(new_conn);
|
||||
*db = Some(new_conn); */
|
||||
|
||||
Ok(format!("Verschlüsselte CRDT-Datenbank erstellt",))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn open_encrypted_database(
|
||||
//app_handle: AppHandle,
|
||||
app_handle: AppHandle,
|
||||
path: String,
|
||||
key: String,
|
||||
state: State<'_, AppState>,
|
||||
) -> Result<String, DatabaseError> {
|
||||
if !Path::new(&path).exists() {
|
||||
return Err(DatabaseError::IoError {
|
||||
path,
|
||||
reason: "Database file not found.".to_string(),
|
||||
});
|
||||
}
|
||||
/* let vault_path = app_handle
|
||||
.path()
|
||||
.resolve(format!("vaults/{}", path), BaseDirectory::AppLocalData)
|
||||
@ -196,12 +201,48 @@ pub fn open_encrypted_database(
|
||||
return Err(format!("File not found {}", path).into());
|
||||
} */
|
||||
|
||||
let conn = core::open_and_init_db(&path, &key, false)
|
||||
/* let conn = core::open_and_init_db(&path, &key, false)
|
||||
.map_err(|e| format!("Error during open: {}", e))?;
|
||||
|
||||
let mut db = state.db.0.lock().map_err(|e| e.to_string())?;
|
||||
|
||||
*db = Some(conn);
|
||||
*db = Some(conn); */
|
||||
|
||||
initialize_session(&app_handle, &path, &key, &state)?;
|
||||
|
||||
Ok(format!("success"))
|
||||
}
|
||||
|
||||
/// Opens the DB, initializes the HLC service, and stores both in the AppState.
|
||||
fn initialize_session(
|
||||
app_handle: &AppHandle,
|
||||
path: &str,
|
||||
key: &str,
|
||||
state: &State<'_, AppState>,
|
||||
) -> Result<(), DatabaseError> {
|
||||
// 1. Establish the raw database connection
|
||||
let conn = core::open_and_init_db(path, key, false)?;
|
||||
|
||||
// 2. Initialize the HLC service
|
||||
let hlc_service = HlcService::try_initialize(&conn, app_handle).map_err(|e| {
|
||||
// We convert the HlcError into a DatabaseError
|
||||
DatabaseError::ExecutionError {
|
||||
sql: "HLC Initialization".to_string(),
|
||||
reason: e.to_string(),
|
||||
table: Some(TABLE_CRDT_CONFIGS.to_string()),
|
||||
}
|
||||
})?;
|
||||
|
||||
// 3. Store everything in the global AppState
|
||||
let mut db_guard = state.db.0.lock().map_err(|e| DatabaseError::LockError {
|
||||
reason: e.to_string(),
|
||||
})?;
|
||||
*db_guard = Some(conn);
|
||||
|
||||
let mut hlc_guard = state.hlc.lock().map_err(|e| DatabaseError::LockError {
|
||||
reason: e.to_string(),
|
||||
})?;
|
||||
*hlc_guard = hlc_service;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user