feat: add Tauri v2 Rust backend with PostgreSQL support
Add Rust backend: AppState with connection pool management, TuskError handling, ConnectionConfig model, and all commands for connections, schema browsing, query execution, data CRUD, and CSV/JSON export via sqlx. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
41
src-tauri/src/models/connection.rs
Normal file
41
src-tauri/src/models/connection.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConnectionConfig {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
pub user: String,
|
||||
pub password: String,
|
||||
pub database: String,
|
||||
pub ssl_mode: Option<String>,
|
||||
pub color: Option<String>,
|
||||
}
|
||||
|
||||
impl ConnectionConfig {
|
||||
pub fn connection_url(&self) -> String {
|
||||
let ssl = self.ssl_mode.as_deref().unwrap_or("prefer");
|
||||
format!(
|
||||
"postgres://{}:{}@{}:{}/{}?sslmode={}",
|
||||
urlencoded(&self.user),
|
||||
urlencoded(&self.password),
|
||||
self.host,
|
||||
self.port,
|
||||
urlencoded(&self.database),
|
||||
ssl
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn urlencoded(s: &str) -> String {
|
||||
s.chars()
|
||||
.map(|c| match c {
|
||||
':' | '/' | '?' | '#' | '[' | ']' | '@' | '!' | '$' | '&' | '\'' | '(' | ')'
|
||||
| '*' | '+' | ',' | ';' | '=' | '%' | ' ' => {
|
||||
format!("%{:02X}", c as u8)
|
||||
}
|
||||
_ => c.to_string(),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
3
src-tauri/src/models/mod.rs
Normal file
3
src-tauri/src/models/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod connection;
|
||||
pub mod query_result;
|
||||
pub mod schema;
|
||||
23
src-tauri/src/models/query_result.rs
Normal file
23
src-tauri/src/models/query_result.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct QueryResult {
|
||||
pub columns: Vec<String>,
|
||||
pub types: Vec<String>,
|
||||
pub rows: Vec<Vec<Value>>,
|
||||
pub row_count: usize,
|
||||
pub execution_time_ms: u128,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PaginatedQueryResult {
|
||||
pub columns: Vec<String>,
|
||||
pub types: Vec<String>,
|
||||
pub rows: Vec<Vec<Value>>,
|
||||
pub row_count: usize,
|
||||
pub execution_time_ms: u128,
|
||||
pub total_rows: i64,
|
||||
pub page: u32,
|
||||
pub page_size: u32,
|
||||
}
|
||||
34
src-tauri/src/models/schema.rs
Normal file
34
src-tauri/src/models/schema.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SchemaObject {
|
||||
pub name: String,
|
||||
pub object_type: String,
|
||||
pub schema: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ColumnInfo {
|
||||
pub name: String,
|
||||
pub data_type: String,
|
||||
pub is_nullable: bool,
|
||||
pub column_default: Option<String>,
|
||||
pub ordinal_position: i32,
|
||||
pub character_maximum_length: Option<i32>,
|
||||
pub is_primary_key: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConstraintInfo {
|
||||
pub name: String,
|
||||
pub constraint_type: String,
|
||||
pub columns: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct IndexInfo {
|
||||
pub name: String,
|
||||
pub definition: String,
|
||||
pub is_unique: bool,
|
||||
pub is_primary: bool,
|
||||
}
|
||||
Reference in New Issue
Block a user