sqlx-model-tools 0.1.3

sqlx model cli tools
Documentation
use sqlx::{MySql, Pool, Row};

use crate::common::{ConfigParseError, DataField, TableParseData};

#[cfg(feature = "sqlx-mysql")]
pub(crate) struct MySqlParse(Pool<MySql>);
#[cfg(feature = "sqlx-mysql")]
#[async_trait::async_trait]
impl TableParseData for MySqlParse {
    type OUT = MySqlParse;
    async fn new(uri: &str) -> Result<Self::OUT, ConfigParseError> {
        let db = sqlx::pool::PoolOptions::<sqlx::MySql>::new()
            .connect(uri)
            .await?;
        Ok(Self(db))
    }
    async fn list_tables(&self) -> Result<Vec<String>, ConfigParseError> {
        let mut tables = vec![];
        let res = sqlx::query("show tables");
        let rows = res.fetch_all(&self.0).await?;
        for row in rows {
            let tablename = row.get::<&str, _>(0).to_owned();
            tables.push(tablename);
        }
        Ok(tables)
    }
    async fn parse_table_column(
        &self,
        table_name: &str,
    ) -> Result<Vec<DataField>, ConfigParseError> {
        let mut columns = vec![];
        let sql = format!(" show full columns from {}", table_name);
        let res = sqlx::query(sql.as_str());
        let rows = res.fetch_all(&self.0).await?;
        for row in rows {
            let name = row.get::<&str, _>("Field").to_string();
            let ty = row.get::<&str, _>("Type").to_owned();
            let mut is_null = false;
            let key = row.get::<&str, _>("Null");
            if key.contains("YES") {
                is_null = true;
            }
            let mut is_pk = false;
            let key = row.get::<&str, _>("Key");
            if key.contains("PRI") {
                is_pk = true;
            }
            let def = if is_null || is_pk {
                row.try_get::<Option<&str>, _>("Default")
                    .unwrap_or_default()
                    .map(|e| e.to_owned())
            } else {
                row.try_get::<&str, _>("Default").map(|e| e.to_owned()).ok()
            };

            let comment = row.get::<&str, _>("Comment");

            let column = DataField {
                field_name: name,
                type_name: ty,
                is_null,
                default: def,
                comment: comment.to_owned(),
                is_pk,
            };
            columns.push(column.clone());
        }
        Ok(columns)
    }
}