Skip to main content

yggdrasil/api/database/
schema.rs

1#![allow(clippy::unused_unit, deprecated)]
2
3//! SQL 补全用 schema 拉取(供 CodeMirror lang-sql 表/列补全)。
4
5use dioxus::prelude::*;
6
7// admin 鉴权 + DB 查询仅在 server 构建里被 server function 体引用。
8#[cfg(feature = "server")]
9use crate::api::auth::get_current_admin_user;
10#[cfg(feature = "server")]
11use crate::api::error::AppError;
12#[cfg(feature = "server")]
13use crate::db::pool::get_conn;
14// SqlSchema 是两端共享的纯数据类型(server function 返回值 DTO,定义在 models);
15// SqlTable 只在下面的 server 构建分支里构造,故单独 cfg 门控,避免 web 构建 unused_imports。
16use crate::models::sql_schema::SqlSchema;
17#[cfg(feature = "server")]
18use crate::models::sql_schema::SqlTable;
19
20/// 拉取数据库 schema(表名 + 列名),供 CodeMirror SQL 补全。
21#[server(GetDbSchema, "/api")]
22pub async fn get_db_schema() -> Result<SqlSchema, ServerFnError> {
23    let _user = get_current_admin_user().await?;
24
25    #[cfg(feature = "server")]
26    {
27        let client = get_conn().await.map_err(AppError::db_conn)?;
28        let rows = client
29            .query(
30                "SELECT t.table_name, \
31                 string_agg(c.column_name, ',' ORDER BY c.ordinal_position) \
32                 FROM information_schema.tables t \
33                 JOIN information_schema.columns c USING (table_schema, table_name) \
34                 WHERE t.table_schema = 'public' AND t.table_type = 'BASE TABLE' \
35                 GROUP BY t.table_name ORDER BY t.table_name",
36                &[],
37            )
38            .await
39            .map_err(AppError::query)?;
40        let tables = rows
41            .into_iter()
42            .map(|r| {
43                let cols: String = r.get(1);
44                SqlTable {
45                    name: r.get(0),
46                    columns: cols.split(',').map(|s| s.to_string()).collect(),
47                }
48            })
49            .collect();
50        Ok(SqlSchema { tables })
51    }
52    #[cfg(not(feature = "server"))]
53    {
54        Ok(SqlSchema::default())
55    }
56}