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

Partial oracle support #321

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
18 changes: 17 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,26 @@ proc-macro2 = { version = "1", optional = true }
quote = { version = "^1", optional = true }
time = { version = "^0.2", optional = true }

[dependencies.r2d2-oracle] # override
git = "https://github.com/Niedzwiedzw/r2d2-oracle"
features = ["chrono"]
optional = true

[dev-dependencies]
criterion = { version = "0.3", features = ["html_reports"] }
pretty_assertions = { version = "^1" }



[features]
backend-mysql = []
backend-postgres = []
backend-sqlite = []
default = ["derive", "backend-mysql", "backend-postgres", "backend-sqlite"]
backend-oracle = ["oracle-overrides"]

oracle-overrides = ["r2d2-oracle", "with-chrono"]

default = ["derive", "backend-mysql", "backend-postgres", "backend-sqlite", "backend-oracle"]
derive = ["sea-query-derive"]
postgres = ["bytes", "postgres-types"]
postgres-chrono = ["with-chrono", "postgres-types/with-chrono-0_4"]
Expand Down Expand Up @@ -106,6 +117,11 @@ name = "test-sqlite"
path = "tests/sqlite/mod.rs"
required-features = ["backend-sqlite"]

[[test]]
name = "test-oracle"
path = "tests/oracle/mod.rs"
required-features = ["backend-oracle"]

[[bench]]
name = "basic"
harness = false
5 changes: 5 additions & 0 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ use crate::*;
#[cfg(feature = "backend-mysql")]
#[cfg_attr(docsrs, doc(cfg(feature = "backend-mysql")))]
mod mysql;
#[cfg(feature = "backend-oracle")]
#[cfg_attr(docsrs, doc(cfg(feature = "backend-oracle")))]
mod oracle;
#[cfg(feature = "backend-postgres")]
#[cfg_attr(docsrs, doc(cfg(feature = "backend-postgres")))]
mod postgres;
Expand All @@ -14,6 +17,8 @@ mod sqlite;

#[cfg(feature = "backend-mysql")]
pub use mysql::*;
#[cfg(feature = "backend-oracle")]
pub use oracle::*;
#[cfg(feature = "backend-postgres")]
pub use postgres::*;
#[cfg(feature = "backend-sqlite")]
Expand Down
79 changes: 79 additions & 0 deletions src/backend/oracle/foreign_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use super::*;

impl ForeignKeyBuilder for OracleQueryBuilder {
fn prepare_foreign_key_drop_statement(
&self,
drop: &ForeignKeyDropStatement,
sql: &mut SqlWriter,
) {
write!(sql, "ALTER TABLE ").unwrap();
if let Some(table) = &drop.table {
table.prepare(sql, self.quote());
}

write!(sql, " DROP CONSTRAINT ").unwrap();
if let Some(name) = &drop.foreign_key.name {
write!(sql, "\"{}\"", name).unwrap();
}
}

fn prepare_foreign_key_create_statement_internal(
&self,
create: &ForeignKeyCreateStatement,
sql: &mut SqlWriter,
inside_table_creation: bool,
) {
if !inside_table_creation {
write!(sql, "ALTER TABLE ").unwrap();
if let Some(table) = &create.foreign_key.table {
table.prepare(sql, self.quote());
}
write!(sql, " ADD ").unwrap();
}

if let Some(name) = &create.foreign_key.name {
write!(sql, "CONSTRAINT ").unwrap();
write!(sql, "\"{}\" ", name).unwrap();
}

write!(sql, "FOREIGN KEY (").unwrap();
create.foreign_key.columns.iter().fold(true, |first, col| {
if !first {
write!(sql, ", ").unwrap();
}
col.prepare(sql, self.quote());
false
});
write!(sql, ")").unwrap();

write!(sql, " REFERENCES ").unwrap();
if let Some(ref_table) = &create.foreign_key.ref_table {
ref_table.prepare(sql, self.quote());
}
write!(sql, " ").unwrap();

write!(sql, "(").unwrap();
create
.foreign_key
.ref_columns
.iter()
.fold(true, |first, col| {
if !first {
write!(sql, ", ").unwrap();
}
col.prepare(sql, self.quote());
false
});
write!(sql, ")").unwrap();

if let Some(foreign_key_action) = &create.foreign_key.on_delete {
write!(sql, " ON DELETE ").unwrap();
self.prepare_foreign_key_action(foreign_key_action, sql);
}

if let Some(foreign_key_action) = &create.foreign_key.on_update {
write!(sql, " ON UPDATE ").unwrap();
self.prepare_foreign_key_action(foreign_key_action, sql);
}
}
}
64 changes: 64 additions & 0 deletions src/backend/oracle/index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use super::*;

impl IndexBuilder for OracleQueryBuilder {
fn prepare_table_index_expression(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) {
if create.index.name.is_some() {
write!(sql, "CONSTRAINT ").unwrap();
self.prepare_index_name(&create.index.name, sql);
write!(sql, " ").unwrap();
}

self.prepare_index_prefix(create, sql);

self.prepare_index_columns(&create.index.columns, sql);
}

fn prepare_index_create_statement(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) {
write!(sql, "CREATE ").unwrap();
self.prepare_index_prefix(create, sql);
write!(sql, "INDEX ").unwrap();

self.prepare_index_name(&create.index.name, sql);

write!(sql, " ON ").unwrap();
if let Some(table) = &create.table {
table.prepare(sql, self.quote());
}

self.prepare_index_type(&create.index_type, sql);

self.prepare_index_columns(&create.index.columns, sql);
}

fn prepare_index_drop_statement(&self, drop: &IndexDropStatement, sql: &mut SqlWriter) {
write!(sql, "DROP INDEX ").unwrap();
if let Some(name) = &drop.index.name {
write!(sql, "\"{}\"", name).unwrap();
}
}

fn prepare_index_type(&self, col_index_type: &Option<IndexType>, sql: &mut SqlWriter) {
if let Some(index_type) = col_index_type {
write!(
sql,
" USING {}",
match index_type {
IndexType::BTree => "BTREE".to_owned(),
IndexType::FullText => "GIN".to_owned(),
IndexType::Hash => "HASH".to_owned(),
IndexType::Custom(custom) => custom.to_string(),
}
)
.unwrap();
}
}

fn prepare_index_prefix(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) {
if create.primary {
write!(sql, "PRIMARY KEY ").unwrap();
}
if create.unique {
write!(sql, "UNIQUE ").unwrap();
}
}
}
27 changes: 27 additions & 0 deletions src/backend/oracle/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pub(crate) mod foreign_key;
pub(crate) mod index;
pub(crate) mod query;
pub(crate) mod table;
pub(crate) mod types;

use super::*;

/// Postgres query builder.
#[derive(Debug)]
pub struct OracleQueryBuilder;

impl Default for OracleQueryBuilder {
fn default() -> Self {
Self
}
}

impl GenericBuilder for OracleQueryBuilder {}

impl SchemaBuilder for OracleQueryBuilder {}

impl QuotedBuilder for OracleQueryBuilder {
fn quote(&self) -> char {
'"'
}
}
Loading