sea-schema-sync 0.17.0-rc.16

🌿 SQL schema definition and discovery
Documentation
use sea_query::{MysqlQueryBuilder, SelectStatement};
use sea_query_sqlx::SqlxBinder;
use sqlx::MySqlPool;

use crate::{
    Connection, debug_print,
    rusqlite_types::{Row, RusqliteError, RusqliteRow, mysql::MySqlRow},
};

pub struct Executor {
    pool: MySqlPool,
}

pub trait IntoExecutor {
    fn into_executor(self) -> Executor;
}

impl IntoExecutor for MySqlPool {
    fn into_executor(self) -> Executor {
        Executor { pool: self }
    }
}

pub trait GetMySqlValue {
    fn get_string(&self, idx: usize) -> String;

    fn get_string_opt(&self, idx: usize) -> Option<String>;
}

impl GetMySqlValue for MySqlRow {
    fn get_string(&self, idx: usize) -> String {
        String::from_utf8(self.get::<Vec<u8>, _>(idx)).unwrap()
    }

    fn get_string_opt(&self, idx: usize) -> Option<String> {
        self.get::<Option<Vec<u8>>, _>(idx)
            .map(|v| String::from_utf8(v).unwrap())
    }
}

impl Connection for Executor {
    fn query_all(&self, select: SelectStatement) -> Result<Vec<RusqliteRow>, RusqliteError> {
        let (sql, values) = select.build_sqlx(MysqlQueryBuilder);
        debug_print!("{}, {:?}", sql, values);

        Ok(sqlx::query_with(&sql, values)
            .fetch_all(&mut *self.pool.acquire()?)?
            .into_iter()
            .map(RusqliteRow::MySql)
            .collect())
    }

    fn query_all_raw(&self, sql: String) -> Result<Vec<RusqliteRow>, RusqliteError> {
        debug_print!("{}", sql);

        Ok(sqlx::query(&sql)
            .fetch_all(&mut *self.pool.acquire()?)?
            .into_iter()
            .map(RusqliteRow::MySql)
            .collect())
    }
}