Execute interface

This commit is contained in:
Chris Tsang 2021-05-26 19:05:43 +08:00
parent c414928255
commit fcff91c0e4
4 changed files with 101 additions and 11 deletions

51
src/connector/executor.rs Normal file
View File

@ -0,0 +1,51 @@
use sqlx::mysql::MySqlQueryResult;
use std::{error::Error, fmt};
#[derive(Debug)]
pub struct ExecResult {
pub(crate) result: ExecResultHolder,
}
#[derive(Debug)]
pub(crate) enum ExecResultHolder {
SqlxMySql(MySqlQueryResult),
}
#[derive(Debug)]
pub struct ExecErr;
// ExecResult //
impl ExecResult {
pub fn last_insert_id(&self) -> u64 {
match &self.result {
ExecResultHolder::SqlxMySql(result) => {
result.last_insert_id()
}
}
}
pub fn rows_affected(&self) -> u64 {
match &self.result {
ExecResultHolder::SqlxMySql(result) => {
result.rows_affected()
}
}
}
}
// ExecErr //
impl Error for ExecErr {}
impl fmt::Display for ExecErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl From<sqlx::Error> for ExecErr {
fn from(_: sqlx::Error) -> ExecErr {
ExecErr
}
}

View File

@ -1,5 +1,7 @@
mod executor;
mod select;
pub use executor::*;
pub use select::*;
use crate::{DatabaseConnection, QueryResult, Statement, TypeErr};
@ -15,6 +17,8 @@ pub trait Connector {
#[async_trait]
pub trait Connection {
async fn execute(&self, stmt: Statement) -> Result<ExecResult, ExecErr>;
async fn query_one(&self, stmt: Statement) -> Result<QueryResult, QueryErr>;
async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, QueryErr>;

View File

@ -3,25 +3,32 @@ use std::fmt;
pub struct Statement {
pub sql: String,
pub values: Values,
pub values: Option<Values>,
}
impl From<(String, Values)> for Statement {
fn from(stmt: (String, Values)) -> Statement {
Statement {
sql: stmt.0,
values: stmt.1,
values: Some(stmt.1),
}
}
}
impl fmt::Display for Statement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let string = inject_parameters(
&self.sql,
self.values.0.clone(),
&MySqlQueryBuilder::default(),
);
write!(f, "{}", &string)
match &self.values {
Some(values) => {
let string = inject_parameters(
&self.sql,
values.0.clone(),
&MySqlQueryBuilder::default(),
);
write!(f, "{}", &string)
}
None => {
write!(f, "{}", &self.sql)
}
}
}
}

View File

@ -1,5 +1,5 @@
use async_trait::async_trait;
use sqlx::{mysql::MySqlRow, MySqlPool};
use sqlx::{mysql::{MySqlRow, MySqlArguments, MySqlQueryResult}, MySql, MySqlPool};
sea_query::sea_query_driver_mysql!();
use sea_query_driver_mysql::bind_query;
@ -31,10 +31,22 @@ impl Connector for SqlxMySqlConnector {
#[async_trait]
impl Connection for &SqlxMySqlPoolConnection {
async fn execute(&self, stmt: Statement) -> Result<ExecResult, ExecErr> {
debug_print!("{}", stmt);
let query = sqlx_query(&stmt);
if let Ok(conn) = &mut self.pool.acquire().await {
if let Ok(res) = query.execute(conn).await {
return Ok(res.into());
}
}
Err(ExecErr)
}
async fn query_one(&self, stmt: Statement) -> Result<QueryResult, QueryErr> {
debug_print!("{}", stmt);
let query = bind_query(sqlx::query(&stmt.sql), &stmt.values);
let query = sqlx_query(&stmt);
if let Ok(conn) = &mut self.pool.acquire().await {
if let Ok(row) = query.fetch_one(conn).await {
return Ok(row.into());
@ -46,7 +58,7 @@ impl Connection for &SqlxMySqlPoolConnection {
async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, QueryErr> {
debug_print!("{}", stmt);
let query = bind_query(sqlx::query(&stmt.sql), &stmt.values);
let query = sqlx_query(&stmt);
if let Ok(conn) = &mut self.pool.acquire().await {
if let Ok(rows) = query.fetch_all(conn).await {
return Ok(rows.into_iter().map(|r| r.into()).collect());
@ -63,3 +75,19 @@ impl From<MySqlRow> for QueryResult {
}
}
}
impl From<MySqlQueryResult> for ExecResult {
fn from(result: MySqlQueryResult) -> ExecResult {
ExecResult {
result: ExecResultHolder::SqlxMySql(result),
}
}
}
fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, MySqlArguments> {
let mut query = sqlx::query(&stmt.sql);
if let Some(values) = &stmt.values {
query = bind_query(query, values);
}
query
}