1use sea_orm::{ConnectionTrait, DatabaseConnection};
6use serde::{Deserialize, Serialize};
7use thiserror::Error;
8use tracing::{error, info};
9
10#[derive(Error, Debug)]
12pub enum SchemaError {
13 #[error("数据库查询失败: {0}")]
14 QueryFailed(String),
15 #[error("Schema 操作失败: {0}")]
16 OperationFailed(String),
17 #[error("Schema 不存在: {0}")]
18 SchemaNotFound(String),
19 #[error("Schema 已存在: {0}")]
20 SchemaExists(String),
21 #[error("无效的输入: {0}")]
22 InvalidInput(String),
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct SchemaInfo {
28 pub schema_name: String,
30 pub schema_owner: Option<String>,
32 pub schema_comment: Option<String>,
34}
35
36pub struct SchemaService;
38
39impl SchemaService {
40 pub async fn list_schemas(db: &DatabaseConnection) -> Result<Vec<SchemaInfo>, SchemaError> {
53 let backend = db.get_database_backend();
55 if backend != sea_orm::DatabaseBackend::Postgres {
56 return Err(SchemaError::QueryFailed(
57 format!("当前仅支持 PostgreSQL 数据库,当前数据库类型: {:?}", backend)
58 ));
59 }
60
61 let _ = db.execute_unprepared("SELECT 1").await.map_err(|e| {
63 SchemaError::QueryFailed(format!("数据库连接不可用: {}", e))
64 })?;
65
66 Err(SchemaError::QueryFailed(
69 "Schema 列表查询功能需要 sqlx 连接池支持。\
70 建议:1) 使用 sqlx 连接池直接查询,或 2) 通过数据库管理工具查询".to_string(),
71 ))
72 }
73
74 pub async fn get_schema_info(
85 db: &DatabaseConnection,
86 schema_name: &str,
87 ) -> Result<SchemaInfo, SchemaError> {
88 if schema_name.is_empty() {
90 return Err(SchemaError::InvalidInput("Schema 名称不能为空".to_string()));
91 }
92
93 let backend = db.get_database_backend();
95 if backend != sea_orm::DatabaseBackend::Postgres {
96 return Err(SchemaError::QueryFailed(
97 format!("当前仅支持 PostgreSQL 数据库,当前数据库类型: {:?}", backend)
98 ));
99 }
100
101 let _ = db.execute_unprepared("SELECT 1").await.map_err(|e| {
103 SchemaError::QueryFailed(format!("数据库连接不可用: {}", e))
104 })?;
105
106 Err(SchemaError::QueryFailed(
109 format!(
110 "Schema 信息查询功能需要 sqlx 连接池支持。\
111 建议:1) 使用 sqlx 连接池直接查询,或 2) 通过数据库管理工具查询。\
112 要查询的 Schema: {}",
113 schema_name
114 )
115 ))
116 }
117
118 pub async fn schema_exists(
120 db: &DatabaseConnection,
121 schema_name: &str,
122 ) -> Result<bool, SchemaError> {
123 match Self::get_schema_info(db, schema_name).await {
124 Ok(_) => Ok(true),
125 Err(SchemaError::SchemaNotFound(_)) => Ok(false),
126 Err(e) => Err(e),
127 }
128 }
129
130 pub async fn create_schema(
132 db: &DatabaseConnection,
133 schema_name: &str,
134 if_not_exists: bool,
135 ) -> Result<(), SchemaError> {
136 if Self::schema_exists(db, schema_name).await? {
138 if if_not_exists {
139 info!("Schema {} 已存在,跳过创建", schema_name);
140 return Ok(());
141 } else {
142 return Err(SchemaError::SchemaExists(format!(
143 "Schema {} 已存在",
144 schema_name
145 )));
146 }
147 }
148
149 let sql = format!("CREATE SCHEMA IF NOT EXISTS {}", schema_name);
150 db.execute_unprepared(sql.as_str()).await.map_err(|e| {
151 error!("创建 Schema 失败: {}", e);
152 SchemaError::OperationFailed(format!("创建 Schema 失败: {}", e))
153 })?;
154
155 info!("✓ 成功创建 Schema: {}", schema_name);
156 Ok(())
157 }
158
159 pub async fn drop_schema(
164 db: &DatabaseConnection,
165 schema_name: &str,
166 if_exists: bool,
167 cascade: bool,
168 ) -> Result<(), SchemaError> {
169 if !Self::schema_exists(db, schema_name).await? {
171 if if_exists {
172 info!("Schema {} 不存在,跳过删除", schema_name);
173 return Ok(());
174 } else {
175 return Err(SchemaError::SchemaNotFound(format!(
176 "Schema {} 不存在",
177 schema_name
178 )));
179 }
180 }
181
182 let cascade_str = if cascade { " CASCADE" } else { "" };
183 let sql = format!("DROP SCHEMA IF EXISTS {}{}", schema_name, cascade_str);
184 db.execute_unprepared(sql.as_str()).await.map_err(|e| {
185 error!("删除 Schema 失败: {}", e);
186 SchemaError::OperationFailed(format!("删除 Schema 失败: {}", e))
187 })?;
188
189 info!("✓ 成功删除 Schema: {}", schema_name);
190 Ok(())
191 }
192
193 pub async fn set_schema_comment(
195 db: &DatabaseConnection,
196 schema_name: &str,
197 comment: &str,
198 ) -> Result<(), SchemaError> {
199 if !Self::schema_exists(db, schema_name).await? {
201 return Err(SchemaError::SchemaNotFound(format!(
202 "Schema {} 不存在",
203 schema_name
204 )));
205 }
206
207 let sql = format!("COMMENT ON SCHEMA {} IS '{}'", schema_name, comment);
208 db.execute_unprepared(sql.as_str()).await.map_err(|e| {
209 error!("设置 Schema 注释失败: {}", e);
210 SchemaError::OperationFailed(format!("设置 Schema 注释失败: {}", e))
211 })?;
212
213 info!("✓ 成功设置 Schema {} 的注释", schema_name);
214 Ok(())
215 }
216}
217
218#[cfg(test)]
219mod tests {
220 use super::*;
221
222 #[test]
223 fn test_schema_info_serialization() {
224 let info = SchemaInfo {
225 schema_name: "test_schema".to_string(),
226 schema_owner: Some("postgres".to_string()),
227 schema_comment: Some("测试 Schema".to_string()),
228 };
229
230 let json = serde_json::to_string(&info).unwrap();
231 assert!(json.contains("test_schema"));
232 }
233}