Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapter postgres url scheme #201

Closed
wants to merge 16 commits into from
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
target
Cargo.lock
*.sublime*
.vscode
.vscode
.idea/
2 changes: 1 addition & 1 deletion sea-orm-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async fn run_generate_command(matches: &ArgMatches<'_>) -> Result<(), Box<dyn Er
.filter(|schema| filter_hidden_tables(&schema.info.name))
.map(|schema| schema.write())
.collect()
} else if url.starts_with("postgres://") {
} else if url.starts_with("postgres://") || url.starts_with("postgresql://") {
use sea_schema::postgres::discovery::SchemaDiscovery;
use sqlx::PgPool;

Expand Down
39 changes: 20 additions & 19 deletions src/database/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,32 @@ pub enum DatabaseConnection {

pub type DbConn = DatabaseConnection;

pub trait IntoDbBackend {
fn build(&self, statement: &impl StatementBuilder) -> Statement;

fn get_query_builder(&self) -> Box<dyn QueryBuilder>;
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum DatabaseBackend {
pub enum DbBackend {
MySql,
Postgres,
Sqlite,
}

pub type DbBackend = DatabaseBackend;
impl IntoDbBackend for DbBackend {
fn build(&self, statement: &impl StatementBuilder) -> Statement {
statement.build(self)
}

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 Default for DatabaseConnection {
fn default() -> Self {
Expand Down Expand Up @@ -128,23 +146,6 @@ impl DatabaseConnection {
}
}

impl DbBackend {
pub fn build<S>(&self, statement: &S) -> Statement
where
S: StatementBuilder,
{
statement.build(self)
}

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),
}
}
}

#[cfg(test)]
mod tests {
use crate::DatabaseConnection;
Expand Down
11 changes: 11 additions & 0 deletions src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ pub use transaction::*;

use crate::DbErr;

#[derive(Debug)]
pub struct DbScheme;

impl DbScheme {
pub fn starts_with(base_url: &str) -> bool {
base_url.starts_with("postgres://")
|| base_url.starts_with("postgresql://")
|| base_url.starts_with("mysql://")
}
}

#[derive(Debug, Default)]
pub struct Database;

Expand Down
2 changes: 1 addition & 1 deletion src/database/statement.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::DbBackend;
use crate::{DbBackend, IntoDbBackend};
use sea_query::{inject_parameters, MysqlQueryBuilder, PostgresQueryBuilder, SqliteQueryBuilder};
pub use sea_query::{Value, Values};
use std::fmt;
Expand Down
4 changes: 2 additions & 2 deletions src/driver/sqlx_mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use sqlx::{
sea_query::sea_query_driver_mysql!();
use sea_query_driver_mysql::bind_query;

use crate::{debug_print, error::*, executor::*, DatabaseConnection, Statement};
use crate::{debug_print, error::*, executor::*, DatabaseConnection, DbScheme, Statement};

use super::sqlx_common::*;

Expand All @@ -20,7 +20,7 @@ pub struct SqlxMySqlPoolConnection {

impl SqlxMySqlConnector {
pub fn accepts(string: &str) -> bool {
string.starts_with("mysql://")
DbScheme::starts_with(string)
}

pub async fn connect(string: &str) -> Result<DatabaseConnection, DbErr> {
Expand Down
4 changes: 2 additions & 2 deletions src/driver/sqlx_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use sqlx::{
sea_query::sea_query_driver_postgres!();
use sea_query_driver_postgres::bind_query;

use crate::{debug_print, error::*, executor::*, DatabaseConnection, Statement};
use crate::{debug_print, error::*, executor::*, DatabaseConnection, DbScheme, Statement};

use super::sqlx_common::*;

Expand All @@ -20,7 +20,7 @@ pub struct SqlxPostgresPoolConnection {

impl SqlxPostgresConnector {
pub fn accepts(string: &str) -> bool {
string.starts_with("postgres://")
DbScheme::starts_with(string)
}

pub async fn connect(string: &str) -> Result<DatabaseConnection, DbErr> {
Expand Down
10 changes: 2 additions & 8 deletions src/entity/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,14 +438,8 @@ mod tests {
impl ActiveModelBehavior for ActiveModel {}
}

assert_eq!(
hello::Column::One.def(),
ColumnType::Integer.def()
);
assert_eq!(
hello::Column::Two.def(),
ColumnType::Integer.def().unique()
);
assert_eq!(hello::Column::One.def(), ColumnType::Integer.def());
assert_eq!(hello::Column::Two.def(), ColumnType::Integer.def().unique());
assert_eq!(
hello::Column::Three.def(),
ColumnType::Integer.def().indexed()
Expand Down
3 changes: 2 additions & 1 deletion src/executor/delete.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
error::*, ActiveModelTrait, DatabaseConnection, DeleteMany, DeleteOne, EntityTrait, Statement,
error::*, ActiveModelTrait, DatabaseConnection, DeleteMany, DeleteOne, EntityTrait,
IntoDbBackend, Statement,
};
use sea_query::DeleteStatement;
use std::future::Future;
Expand Down
4 changes: 2 additions & 2 deletions src/executor/insert.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
error::*, ActiveModelTrait, DatabaseConnection, EntityTrait, Insert, PrimaryKeyTrait,
Statement, TryFromU64,
error::*, ActiveModelTrait, DatabaseConnection, EntityTrait, Insert, IntoDbBackend,
PrimaryKeyTrait, Statement, TryFromU64,
};
use sea_query::InsertStatement;
use std::{future::Future, marker::PhantomData};
Expand Down
4 changes: 2 additions & 2 deletions src/executor/paginator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{error::*, DatabaseConnection, SelectorTrait};
use crate::{error::*, DatabaseConnection, IntoDbBackend, SelectorTrait};
use async_stream::stream;
use futures::Stream;
use sea_query::{Alias, Expr, SelectStatement};
Expand Down Expand Up @@ -159,7 +159,7 @@ where
mod tests {
use crate::entity::prelude::*;
use crate::tests_cfg::*;
use crate::{DatabaseConnection, DbBackend, MockDatabase, Transaction};
use crate::{DatabaseConnection, DbBackend, IntoDbBackend, MockDatabase, Transaction};
use futures::TryStreamExt;
use sea_query::{Alias, Expr, SelectStatement, Value};

Expand Down
6 changes: 3 additions & 3 deletions src/executor/select.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
error::*, DatabaseConnection, EntityTrait, FromQueryResult, IdenStatic, Iterable, JsonValue,
ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectA, SelectB, SelectTwo,
SelectTwoMany, Statement,
error::*, DatabaseConnection, EntityTrait, FromQueryResult, IdenStatic, IntoDbBackend,
Iterable, JsonValue, ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectA,
SelectB, SelectTwo, SelectTwoMany, Statement,
};
use sea_query::SelectStatement;
use std::marker::PhantomData;
Expand Down
3 changes: 2 additions & 1 deletion src/executor/update.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
error::*, ActiveModelTrait, DatabaseConnection, EntityTrait, Statement, UpdateMany, UpdateOne,
error::*, ActiveModelTrait, DatabaseConnection, EntityTrait, IntoDbBackend, Statement,
UpdateMany, UpdateOne,
};
use sea_query::UpdateStatement;
use std::future::Future;
Expand Down
114 changes: 113 additions & 1 deletion src/query/traits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{DbBackend, Statement};
use crate::{DatabaseConnection, DbBackend, IntoDbBackend, Statement};
use sea_query::QueryStatementBuilder;

pub trait QueryTrait {
Expand All @@ -22,3 +22,115 @@ pub trait QueryTrait {
)
}
}

#[derive(Debug)]
pub struct DebugQuery<'a, Q, T> {
pub query: &'a Q,
pub value: T,
}

impl<'a, Q> DebugQuery<'a, Q, DbBackend>
where
Q: QueryTrait,
{
pub fn build(&self) -> Statement {
self.query.build(self.value)
}
}

impl<'a, Q> DebugQuery<'a, Q, &DatabaseConnection>
where
Q: QueryTrait,
{
pub fn build(&self) -> Statement {
self.query.build(self.value.get_database_backend())
}
}

impl<'a, Q> DebugQuery<'a, Q, DatabaseConnection>
where
Q: QueryTrait,
{
pub fn build(&self) -> Statement {
self.query.build(self.value.get_database_backend())
}
}

/// Make get raw_sql becomes simply. It does not need to specify a specific `DbBackend`,
/// but can be obtained through `get_database_backend` with `DatabaseConnection`.
/// Return a Statement type.
///
///
/// # Example
///
/// ```
/// # #[cfg(feature = "mock")]
/// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
/// #
/// # let conn = MockDatabase::new(DbBackend::Postgres)
/// # .into_connection();
/// #
/// use sea_orm::{entity::*, query::*, tests_cfg::cake,gen_statement};
///
/// let c = cake::Entity::insert(
/// cake::ActiveModel {
/// id: ActiveValue::set(1),
/// name: ActiveValue::set("Apple Pie".to_owned()),
/// });
///
/// let raw_sql = gen_statement!(&c,&conn).to_string();
/// assert_eq!(raw_sql,r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#);
///
/// let raw_sql = gen_statement!(&c,conn).to_string();
/// assert_eq!(raw_sql,r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#);
///
/// let raw_sql = gen_statement!(&c,DbBackend::MySql).to_string();
/// assert_eq!(raw_sql,r#"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')"#);
///
/// ```
#[macro_export]
macro_rules! gen_statement {
($query:expr,$value:expr) => {
$crate::DebugQuery {
query: $query,
value: $value,
}
.build();
};
}

/// Use `debug_query` macro get raw_sql.
///
/// # Example
///
/// ```
/// # #[cfg(feature = "mock")]
/// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
/// #
/// # let conn = MockDatabase::new(DbBackend::Postgres)
/// # .into_connection();
/// #
/// use sea_orm::{entity::*, query::*, tests_cfg::cake,debug_query};
///
/// let c = cake::Entity::insert(
/// cake::ActiveModel {
/// id: ActiveValue::set(1),
/// name: ActiveValue::set("Apple Pie".to_owned()),
/// });
///
/// let raw_sql = debug_query!(&c,&conn);
/// assert_eq!(raw_sql,r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#);
///
/// let raw_sql = debug_query!(&c,conn);
/// assert_eq!(raw_sql,r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#);
///
/// let raw_sql = debug_query!(&c,DbBackend::Sqlite);
/// assert_eq!(raw_sql,r#"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')"#);
///
/// ```
#[macro_export]
macro_rules! debug_query {
($query:expr,$value:expr) => {
$crate::gen_statement!($query, $value).to_string();
};
}
2 changes: 1 addition & 1 deletion tests/basic.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub mod common;

pub use sea_orm::{entity::*, error::*, sea_query, tests_cfg::*, Database, DbConn};
pub use sea_orm::{entity::*, error::*, sea_query, tests_cfg::*, Database, DbConn, IntoDbBackend};

// cargo test --features sqlx-sqlite,runtime-async-std-native-tls --test basic
#[sea_orm_macros::test]
Expand Down
14 changes: 7 additions & 7 deletions tests/common/setup/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use sea_orm::{Database, DatabaseBackend, DatabaseConnection, Statement};
use sea_orm::{Database, DatabaseConnection, DbBackend, Statement};
pub mod schema;
pub use schema::*;

Expand All @@ -8,14 +8,14 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {
let db = Database::connect(&url).await.unwrap();
let _drop_db_result = db
.execute(Statement::from_string(
DatabaseBackend::MySql,
DbBackend::MySql,
format!("DROP DATABASE IF EXISTS `{}`;", db_name),
))
.await;

let _create_db_result = db
.execute(Statement::from_string(
DatabaseBackend::MySql,
DbBackend::MySql,
format!("CREATE DATABASE `{}`;", db_name),
))
.await;
Expand All @@ -27,14 +27,14 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {
let db = Database::connect(&url).await.unwrap();
let _drop_db_result = db
.execute(Statement::from_string(
DatabaseBackend::Postgres,
DbBackend::Postgres,
format!("DROP DATABASE IF EXISTS \"{}\";", db_name),
))
.await;

let _create_db_result = db
.execute(Statement::from_string(
DatabaseBackend::Postgres,
DbBackend::Postgres,
format!("CREATE DATABASE \"{}\";", db_name),
))
.await;
Expand Down Expand Up @@ -63,7 +63,7 @@ pub async fn tear_down(base_url: &str, db_name: &str) {
let db = Database::connect(&url).await.unwrap();
let _ = db
.execute(Statement::from_string(
DatabaseBackend::MySql,
DbBackend::MySql,
format!("DROP DATABASE IF EXISTS \"{}\";", db_name),
))
.await;
Expand All @@ -72,7 +72,7 @@ pub async fn tear_down(base_url: &str, db_name: &str) {
let db = Database::connect(&url).await.unwrap();
let _ = db
.execute(Statement::from_string(
DatabaseBackend::Postgres,
DbBackend::Postgres,
format!("DROP DATABASE IF EXISTS \"{}\";", db_name),
))
.await;
Expand Down
Loading