Add Syntax to Statement

This commit is contained in:
Chris Tsang 2021-07-13 22:38:50 +08:00
parent b5f4d69c3b
commit bcd221a915
7 changed files with 102 additions and 33 deletions

View File

@ -15,7 +15,7 @@ impl EntityName for Entity {
pub struct Model {
pub id: i32,
pub name: String,
pub cake_id: Option<i32> ,
pub cake_id: Option<i32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]

View File

@ -15,7 +15,7 @@ impl EntityName for Entity {
pub struct Model {
pub id: i32,
pub name: String,
pub fruit_id: Option<i32> ,
pub fruit_id: Option<i32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]

View File

@ -1,4 +1,4 @@
use crate::{error::*, ExecResult, QueryResult, Statement};
use crate::{error::*, ExecResult, QueryResult, Statement, Syntax};
use sea_query::{
MysqlQueryBuilder, PostgresQueryBuilder, QueryStatementBuilder, SchemaStatementBuilder,
SqliteQueryBuilder,
@ -134,29 +134,49 @@ impl DatabaseConnection {
}
impl QueryBuilderBackend {
pub fn syntax(&self) -> Syntax {
match self {
Self::MySql => Syntax::MySql,
Self::Postgres => Syntax::Postgres,
Self::Sqlite => Syntax::Sqlite,
}
}
pub fn build<S>(&self, statement: &S) -> Statement
where
S: QueryStatementBuilder,
{
match self {
Self::MySql => statement.build(MysqlQueryBuilder),
Self::Postgres => statement.build(PostgresQueryBuilder),
Self::Sqlite => statement.build(SqliteQueryBuilder),
}
.into()
Statement::from_string_values_tuple(
self.syntax(),
match self {
Self::MySql => statement.build(MysqlQueryBuilder),
Self::Postgres => statement.build(PostgresQueryBuilder),
Self::Sqlite => statement.build(SqliteQueryBuilder),
},
)
}
}
impl SchemaBuilderBackend {
pub fn syntax(&self) -> Syntax {
match self {
Self::MySql => Syntax::MySql,
Self::Postgres => Syntax::Postgres,
Self::Sqlite => Syntax::Sqlite,
}
}
pub fn build<S>(&self, statement: &S) -> Statement
where
S: SchemaStatementBuilder,
{
match self {
Self::MySql => statement.build(MysqlQueryBuilder),
Self::Postgres => statement.build(PostgresQueryBuilder),
Self::Sqlite => statement.build(SqliteQueryBuilder),
}
.into()
Statement::from_string(
self.syntax(),
match self {
Self::MySql => statement.build(MysqlQueryBuilder),
Self::Postgres => statement.build(PostgresQueryBuilder),
Self::Sqlite => statement.build(SqliteQueryBuilder),
},
)
}
}

View File

@ -1,26 +1,38 @@
use sea_query::{inject_parameters, MySqlQueryBuilder, Values};
use crate::QueryBuilderWithSyntax;
use sea_query::{
inject_parameters, MysqlQueryBuilder, PostgresQueryBuilder, QueryBuilder, SqliteQueryBuilder,
Values,
};
use std::fmt;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Syntax {
MySql,
Postgres,
Sqlite,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Statement {
pub sql: String,
pub values: Option<Values>,
pub syntax: Syntax,
}
impl From<String> for Statement {
fn from(stmt: String) -> Statement {
impl Statement {
pub fn from_string(syntax: Syntax, stmt: String) -> Statement {
Statement {
sql: stmt,
values: None,
syntax,
}
}
}
impl From<(String, Values)> for Statement {
fn from(stmt: (String, Values)) -> Statement {
pub fn from_string_values_tuple(syntax: Syntax, stmt: (String, Values)) -> Statement {
Statement {
sql: stmt.0,
values: Some(stmt.1),
syntax,
}
}
}
@ -29,8 +41,11 @@ impl fmt::Display for Statement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.values {
Some(values) => {
let string =
inject_parameters(&self.sql, values.0.clone(), &MySqlQueryBuilder::default());
let string = inject_parameters(
&self.sql,
values.0.clone(),
self.syntax.get_query_builder().as_ref(),
);
write!(f, "{}", &string)
}
None => {
@ -39,3 +54,31 @@ impl fmt::Display for Statement {
}
}
}
impl Syntax {
pub fn get_query_builder(&self) -> Box<dyn QueryBuilder> {
match self {
Self::MySql => Box::new(MysqlQueryBuilder),
Self::Postgres => Box::new(PostgresQueryBuilder),
Self::Sqlite => Box::new(SqliteQueryBuilder),
}
}
}
impl QueryBuilderWithSyntax for MysqlQueryBuilder {
fn syntax(&self) -> Syntax {
Syntax::MySql
}
}
impl QueryBuilderWithSyntax for PostgresQueryBuilder {
fn syntax(&self) -> Syntax {
Syntax::Postgres
}
}
impl QueryBuilderWithSyntax for SqliteQueryBuilder {
fn syntax(&self) -> Syntax {
Syntax::Sqlite
}
}

View File

@ -1,4 +1,4 @@
use crate::Statement;
use crate::{Statement, Syntax};
use sea_query::{Value, Values};
#[derive(Debug, Clone, PartialEq)]
@ -11,10 +11,10 @@ impl Transaction {
where
I: IntoIterator<Item = Value>,
{
Self::one(Statement {
sql: sql.to_owned(),
values: Some(Values(values.into_iter().collect())),
})
Self::one(Statement::from_string_values_tuple(
Syntax::Postgres,
(sql.to_string(), Values(values.into_iter().collect())),
))
}
/// Create a Transaction with one statement

View File

@ -1,4 +1,4 @@
use crate::Statement;
use crate::{Statement, Syntax};
use sea_query::{QueryBuilder, QueryStatementBuilder};
pub trait QueryTrait {
@ -16,8 +16,12 @@ pub trait QueryTrait {
/// Build the query as [`Statement`]
fn build<B>(&self, builder: B) -> Statement
where
B: QueryBuilder,
B: QueryBuilderWithSyntax,
{
self.as_query().build(builder).into()
Statement::from_string_values_tuple(builder.syntax(), self.as_query().build(builder))
}
}
pub trait QueryBuilderWithSyntax: QueryBuilder {
fn syntax(&self) -> Syntax;
}

View File

@ -1,4 +1,4 @@
use sea_orm::{entity::*, error::*, sea_query, tests_cfg::*, DbConn};
use sea_orm::{entity::*, error::*, sea_query, tests_cfg::*, DbConn, Statement, Syntax};
mod setup;
@ -27,7 +27,9 @@ async fn setup_schema(db: &DbConn) {
.col(ColumnDef::new(cake::Column::Name).string())
.build(SqliteQueryBuilder);
let result = db.execute(stmt.into()).await;
let result = db
.execute(Statement::from_string(Syntax::Sqlite, stmt))
.await;
println!("Create table cake: {:?}", result);
}