axum_sql_viewer/database/traits.rs
1//! Database provider trait
2//!
3//! This trait defines the interface that all database implementations must provide.
4
5use crate::schema::{CountResponse, QueryResult, RowQuery, RowsResponse, TableInfo, TableSchema};
6use async_trait::async_trait;
7use thiserror::Error;
8
9/// Database provider trait for schema discovery and data access
10///
11/// Implementations of this trait provide database-specific logic for
12/// discovering schema information and fetching data.
13#[async_trait]
14pub trait DatabaseProvider: Send + Sync + 'static {
15 /// List all table names in the database
16 ///
17 /// # Returns
18 ///
19 /// A vector of table information, optionally including row counts
20 async fn list_tables(&self) -> Result<Vec<TableInfo>, DatabaseError>;
21
22 /// Get schema information for a specific table
23 ///
24 /// # Arguments
25 ///
26 /// * `table` - Name of the table
27 ///
28 /// # Returns
29 ///
30 /// Complete schema information including columns, keys, and indexes
31 async fn get_table_schema(&self, table: &str) -> Result<TableSchema, DatabaseError>;
32
33 /// Fetch rows with pagination, sorting, and filtering
34 ///
35 /// # Arguments
36 ///
37 /// * `table` - Name of the table
38 /// * `query` - Query parameters (pagination, sorting, filters)
39 ///
40 /// # Returns
41 ///
42 /// Paginated rows with metadata
43 async fn get_rows(&self, table: &str, query: RowQuery) -> Result<RowsResponse, DatabaseError>;
44
45 /// Get total row count for a table (with optional filters)
46 ///
47 /// # Arguments
48 ///
49 /// * `table` - Name of the table
50 /// * `query` - Query parameters (filters)
51 ///
52 /// # Returns
53 ///
54 /// Total row count
55 async fn count_rows(&self, table: &str, query: &RowQuery) -> Result<CountResponse, DatabaseError>;
56
57 /// Execute a raw SQL query
58 ///
59 /// # Security Warning
60 ///
61 /// This allows executing any SQL statement including INSERT, UPDATE, DELETE.
62 /// Only use in development environments!
63 ///
64 /// # Arguments
65 ///
66 /// * `sql` - SQL query to execute
67 ///
68 /// # Returns
69 ///
70 /// Query results with execution metadata
71 async fn execute_query(&self, sql: &str) -> Result<QueryResult, DatabaseError>;
72}
73
74/// Database error type
75#[derive(Debug, Error)]
76pub enum DatabaseError {
77 /// Generic database error
78 #[error("Database error: {0}")]
79 Query(String),
80
81 /// Table not found
82 #[error("Table not found: {0}")]
83 TableNotFound(String),
84
85 /// Invalid column name
86 #[error("Invalid column: {0}")]
87 InvalidColumn(String),
88
89 /// Query timeout
90 #[error("Query timeout exceeded")]
91 Timeout,
92
93 /// Result set too large
94 #[error("Result set too large (max {0} rows)")]
95 TooManyRows(u64),
96
97 /// Serialization error
98 #[error("Serialization error: {0}")]
99 Serialization(String),
100}
101
102impl From<sqlx::Error> for DatabaseError {
103 fn from(error: sqlx::Error) -> Self {
104 DatabaseError::Query(error.to_string())
105 }
106}