/
mcmare
/
RustAPI
Обзор
Документация
Войти
/
mcmare
/
RustAPI
Код
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
engine/src/db/schema.rs
89 строк
3 KB
mcmare
Add multi-DB CRUD engine: pooled connections, auto table creation, create/read/list/update/delete
18 июл 2026, 16:21
18 июл 2026, 16:21
c40e4bc
Код
Авторство
О чём код?
use anyhow::{Context, Result}; use std::collections::HashMap; use super::DbPool; use crate::config::FieldType; #[derive(Clone, Copy)] enum Dialect { Postgres, MySql, Sqlite, } fn column_sql_type(dialect: Dialect, ty: &FieldType) -> &'static str { match (dialect, ty) { (_, FieldType::String) => "TEXT", (Dialect::Postgres, FieldType::Number) => "DOUBLE PRECISION", (Dialect::MySql, FieldType::Number) => "DOUBLE", (Dialect::Sqlite, FieldType::Number) => "REAL", (_, FieldType::Bool) => "BOOLEAN", (Dialect::Postgres, FieldType::Uuid) => "UUID", (Dialect::MySql, FieldType::Uuid) => "CHAR(36)", (Dialect::Sqlite, FieldType::Uuid) => "TEXT", (Dialect::Postgres, FieldType::Datetime) => "TIMESTAMPTZ", (Dialect::MySql, FieldType::Datetime) => "DATETIME", (Dialect::Sqlite, FieldType::Datetime) => "TEXT", (Dialect::Postgres, FieldType::Object | FieldType::Array(_)) => "JSONB", (Dialect::MySql, FieldType::Object | FieldType::Array(_)) => "JSON", (Dialect::Sqlite, FieldType::Object | FieldType::Array(_)) => "TEXT", } } fn quote_ident(dialect: Dialect, ident: &str) -> String { match dialect { Dialect::MySql => format!("`{ident}`"), _ => format!("\"{ident}\""), } } fn build_create_table_sql( table: &str, primary_key: &str, output: &HashMap<String, FieldType>, dialect: Dialect, ) -> String { let pk_type = output.get(primary_key).cloned().unwrap_or(FieldType::Uuid); let mut columns = vec![format!( "{} {} PRIMARY KEY", quote_ident(dialect, primary_key), column_sql_type(dialect, &pk_type) )]; for (name, ty) in output { if name == primary_key { continue; } columns.push(format!("{} {}", quote_ident(dialect, name), column_sql_type(dialect, ty))); } format!( "CREATE TABLE IF NOT EXISTS {} ({})", quote_ident(dialect, table), columns.join(", ") ) } pub async fn ensure_table( pool: &DbPool, table: &str, primary_key: &str, output: &HashMap<String, FieldType>, ) -> Result<()> { let (sql, result) = match pool { DbPool::Postgres(p) => { let sql = build_create_table_sql(table, primary_key, output, Dialect::Postgres); let r = sqlx::query(&sql).execute(p).await; (sql, r.map(|_| ())) } DbPool::MySql(p) => { let sql = build_create_table_sql(table, primary_key, output, Dialect::MySql); let r = sqlx::query(&sql).execute(p).await; (sql, r.map(|_| ())) } DbPool::Sqlite(p) => { let sql = build_create_table_sql(table, primary_key, output, Dialect::Sqlite); let r = sqlx::query(&sql).execute(p).await; (sql, r.map(|_| ())) } }; result.with_context(|| format!("executing: {sql}")) }