use async_trait::async_trait;
use reinhardt_query::prelude::{
DeleteStatement, InsertStatement, SelectStatement, UpdateStatement,
};
use crate::orm::query_types::{DbBackend, QueryStatement};
pub type Row = sqlx::any::AnyRow;
pub type DbResult<T> = Result<T, reinhardt_core::exception::Error>;
#[async_trait]
pub trait ConnectionExt {
fn backend(&self) -> DbBackend;
async fn execute_statement(&self, stmt: &QueryStatement) -> DbResult<u64>;
async fn query_statement(&self, stmt: &SelectStatement) -> DbResult<Vec<Row>>;
async fn query_one_statement(&self, stmt: &SelectStatement) -> DbResult<Row>;
async fn execute_select(&self, stmt: &SelectStatement) -> DbResult<Vec<Row>> {
self.query_statement(stmt).await
}
async fn execute_insert(&self, stmt: &InsertStatement) -> DbResult<u64>;
async fn execute_update(&self, stmt: &UpdateStatement) -> DbResult<u64>;
async fn execute_delete(&self, stmt: &DeleteStatement) -> DbResult<u64>;
}
pub mod helpers {
use super::*;
use reinhardt_query::prelude::{
MySqlQueryBuilder, PostgresQueryBuilder, QueryBuilder, SqliteQueryBuilder, Values,
};
pub fn build_select(stmt: &SelectStatement, backend: DbBackend) -> (String, Values) {
match backend {
DbBackend::Postgres => PostgresQueryBuilder::new().build_select(stmt),
DbBackend::Mysql => MySqlQueryBuilder::new().build_select(stmt),
DbBackend::Sqlite => SqliteQueryBuilder::new().build_select(stmt),
}
}
pub fn build_insert(stmt: &InsertStatement, backend: DbBackend) -> (String, Values) {
match backend {
DbBackend::Postgres => PostgresQueryBuilder::new().build_insert(stmt),
DbBackend::Mysql => MySqlQueryBuilder::new().build_insert(stmt),
DbBackend::Sqlite => SqliteQueryBuilder::new().build_insert(stmt),
}
}
pub fn build_update(stmt: &UpdateStatement, backend: DbBackend) -> (String, Values) {
match backend {
DbBackend::Postgres => PostgresQueryBuilder::new().build_update(stmt),
DbBackend::Mysql => MySqlQueryBuilder::new().build_update(stmt),
DbBackend::Sqlite => SqliteQueryBuilder::new().build_update(stmt),
}
}
pub fn build_delete(stmt: &DeleteStatement, backend: DbBackend) -> (String, Values) {
match backend {
DbBackend::Postgres => PostgresQueryBuilder::new().build_delete(stmt),
DbBackend::Mysql => MySqlQueryBuilder::new().build_delete(stmt),
DbBackend::Sqlite => SqliteQueryBuilder::new().build_delete(stmt),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use reinhardt_query::prelude::{Alias, Expr, Query};
#[test]
fn test_build_select_postgres() {
use reinhardt_query::prelude::ExprTrait;
let stmt = Query::select()
.from(Alias::new("users"))
.column(Alias::new("id"))
.and_where(Expr::col(Alias::new("id")).eq(1))
.to_owned();
let (sql, values) = helpers::build_select(&stmt, DbBackend::Postgres);
assert!(sql.contains("SELECT"));
assert!(sql.contains("users"));
assert_eq!(values.0.len(), 1);
}
#[test]
fn test_build_select_mysql() {
let stmt = Query::select()
.from(Alias::new("users"))
.column(Alias::new("id"))
.to_owned();
let (sql, _) = helpers::build_select(&stmt, DbBackend::Mysql);
assert!(sql.contains("SELECT"));
assert!(sql.contains("`users`")); }
#[test]
fn test_build_select_sqlite() {
let stmt = Query::select()
.from(Alias::new("users"))
.column(Alias::new("id"))
.to_owned();
let (sql, _) = helpers::build_select(&stmt, DbBackend::Sqlite);
assert!(sql.contains("SELECT"));
assert!(sql.contains("\"users\"")); }
}