From 01f9202933d3fdb3bf08f18fb9249b6b5781af71 Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Tue, 26 Apr 2022 13:12:55 +0200 Subject: [PATCH 01/13] copypaste --- Cargo.toml | 3 +- src/backend/oracle/foreign_key.rs | 79 ++ src/backend/oracle/index.rs | 64 ++ src/backend/oracle/mod.rs | 27 + src/backend/oracle/query.rs | 110 +++ src/backend/oracle/table.rs | 213 +++++ src/backend/oracle/types.rs | 137 +++ tests/oracle/foreign_key.rs | 31 + tests/oracle/index.rs | 50 ++ tests/oracle/interval.rs | 35 + tests/oracle/mod.rs | 10 + tests/oracle/query.rs | 1303 +++++++++++++++++++++++++++++ tests/oracle/table.rs | 361 ++++++++ tests/oracle/types.rs | 104 +++ 14 files changed, 2526 insertions(+), 1 deletion(-) create mode 100644 src/backend/oracle/foreign_key.rs create mode 100644 src/backend/oracle/index.rs create mode 100644 src/backend/oracle/mod.rs create mode 100644 src/backend/oracle/query.rs create mode 100644 src/backend/oracle/table.rs create mode 100644 src/backend/oracle/types.rs create mode 100644 tests/oracle/foreign_key.rs create mode 100644 tests/oracle/index.rs create mode 100644 tests/oracle/interval.rs create mode 100644 tests/oracle/mod.rs create mode 100644 tests/oracle/query.rs create mode 100644 tests/oracle/table.rs create mode 100644 tests/oracle/types.rs diff --git a/Cargo.toml b/Cargo.toml index 671c03ed6..4aa4791fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,8 @@ pretty_assertions = { version = "^1" } backend-mysql = [] backend-postgres = [] backend-sqlite = [] -default = ["derive", "backend-mysql", "backend-postgres", "backend-sqlite"] +backend-oracle = [] +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"] diff --git a/src/backend/oracle/foreign_key.rs b/src/backend/oracle/foreign_key.rs new file mode 100644 index 000000000..123703570 --- /dev/null +++ b/src/backend/oracle/foreign_key.rs @@ -0,0 +1,79 @@ +use super::*; + +impl ForeignKeyBuilder for PostgresQueryBuilder { + 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); + } + } +} diff --git a/src/backend/oracle/index.rs b/src/backend/oracle/index.rs new file mode 100644 index 000000000..be84ece2d --- /dev/null +++ b/src/backend/oracle/index.rs @@ -0,0 +1,64 @@ +use super::*; + +impl IndexBuilder for PostgresQueryBuilder { + 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, 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(); + } + } +} diff --git a/src/backend/oracle/mod.rs b/src/backend/oracle/mod.rs new file mode 100644 index 000000000..bb3d93f2e --- /dev/null +++ b/src/backend/oracle/mod.rs @@ -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 PostgresQueryBuilder; + +impl Default for PostgresQueryBuilder { + fn default() -> Self { + Self + } +} + +impl GenericBuilder for PostgresQueryBuilder {} + +impl SchemaBuilder for PostgresQueryBuilder {} + +impl QuotedBuilder for PostgresQueryBuilder { + fn quote(&self) -> char { + '"' + } +} diff --git a/src/backend/oracle/query.rs b/src/backend/oracle/query.rs new file mode 100644 index 000000000..f427a7a26 --- /dev/null +++ b/src/backend/oracle/query.rs @@ -0,0 +1,110 @@ +use super::*; +use crate::extension::postgres::*; + +impl QueryBuilder for PostgresQueryBuilder { + fn placeholder(&self) -> (&str, bool) { + ("$", true) + } + + fn if_null_function(&self) -> &str { + "COALESCE" + } + + fn write_string_quoted(&self, string: &str, buffer: &mut String) { + let escaped = escape_string(string); + let string = if escaped.find('\\').is_some() { + "E'".to_owned() + &escaped + "'" + } else { + "'".to_owned() + &escaped + "'" + }; + write!(buffer, "{}", string).unwrap() + } + + fn prepare_bin_oper( + &self, + bin_oper: &BinOper, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + match bin_oper { + BinOper::Matches => write!(sql, "@@").unwrap(), + BinOper::Contains => write!(sql, "@>").unwrap(), + BinOper::Contained => write!(sql, "<@").unwrap(), + BinOper::Concatenate => write!(sql, "||").unwrap(), + _ => self.prepare_bin_oper_common(bin_oper, sql, collector), + } + } + + fn prepare_function( + &self, + function: &Function, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + match function { + Function::PgFunction(function) => write!( + sql, + "{}", + match function { + PgFunction::ToTsquery => "TO_TSQUERY", + PgFunction::ToTsvector => "TO_TSVECTOR", + PgFunction::PhrasetoTsquery => "PHRASETO_TSQUERY", + PgFunction::PlaintoTsquery => "PLAINTO_TSQUERY", + PgFunction::WebsearchToTsquery => "WEBSEARCH_TO_TSQUERY", + PgFunction::TsRank => "TS_RANK", + PgFunction::TsRankCd => "TS_RANK_CD", + #[cfg(feature = "postgres-array")] + PgFunction::Any => "ANY", + #[cfg(feature = "postgres-array")] + PgFunction::Some => "SOME", + #[cfg(feature = "postgres-array")] + PgFunction::All => "ALL", + } + ) + .unwrap(), + _ => self.prepare_function_common(function, sql, collector), + } + } + + fn prepare_simple_expr( + &self, + simple_expr: &SimpleExpr, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + match simple_expr { + SimpleExpr::AsEnum(type_name, expr) => { + let simple_expr = expr.clone().cast_as(SeaRc::clone(type_name)); + self.prepare_simple_expr_common(&simple_expr, sql, collector); + } + _ => QueryBuilder::prepare_simple_expr_common(self, simple_expr, sql, collector), + } + } + + fn prepare_order_expr( + &self, + order_expr: &OrderExpr, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + if !matches!(order_expr.order, Order::Field(_)) { + self.prepare_simple_expr(&order_expr.expr, sql, collector); + } + write!(sql, " ").unwrap(); + self.prepare_order(order_expr, sql, collector); + match order_expr.nulls { + None => (), + Some(NullOrdering::Last) => write!(sql, " NULLS LAST").unwrap(), + Some(NullOrdering::First) => write!(sql, " NULLS FIRST").unwrap(), + } + } + + fn prepare_query_statement( + &self, + query: &SubQueryStatement, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + query.prepare_statement(self, sql, collector); + } +} diff --git a/src/backend/oracle/table.rs b/src/backend/oracle/table.rs new file mode 100644 index 000000000..0cf1e1659 --- /dev/null +++ b/src/backend/oracle/table.rs @@ -0,0 +1,213 @@ +use super::*; + +impl TableBuilder for PostgresQueryBuilder { + fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut SqlWriter) { + column_def.name.prepare(sql, self.quote()); + + self.prepare_column_type_check_auto_increment(column_def, sql); + + for column_spec in column_def.spec.iter() { + if let ColumnSpec::AutoIncrement = column_spec { + continue; + } + write!(sql, " ").unwrap(); + self.prepare_column_spec(column_spec, sql); + } + } + + fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut SqlWriter) { + write!( + sql, + "{}", + match column_type { + ColumnType::Char(length) => match length { + Some(length) => format!("char({})", length), + None => "char".into(), + }, + ColumnType::String(length) => match length { + Some(length) => format!("varchar({})", length), + None => "varchar".into(), + }, + ColumnType::Text => "text".into(), + ColumnType::TinyInteger(length) | ColumnType::TinyUnsigned(length) => + match length { + Some(length) => format!("smallint({})", length), + None => "smallint".into(), + }, + ColumnType::SmallInteger(length) | ColumnType::SmallUnsigned(length) => + match length { + Some(length) => format!("smallint({})", length), + None => "smallint".into(), + }, + ColumnType::Integer(length) | ColumnType::Unsigned(length) => match length { + Some(length) => format!("integer({})", length), + None => "integer".into(), + }, + ColumnType::BigInteger(length) | ColumnType::BigUnsigned(length) => match length { + Some(length) => format!("bigint({})", length), + None => "bigint".into(), + }, + ColumnType::Float(precision) => match precision { + Some(precision) => format!("real({})", precision), + None => "real".into(), + }, + ColumnType::Double(precision) => match precision { + Some(precision) => format!("double precision({})", precision), + None => "double precision".into(), + }, + ColumnType::Decimal(precision) => match precision { + Some((precision, scale)) => format!("decimal({}, {})", precision, scale), + None => "decimal".into(), + }, + ColumnType::DateTime(precision) => match precision { + Some(precision) => format!("timestamp({}) without time zone", precision), + None => "timestamp without time zone".into(), + }, + ColumnType::Timestamp(precision) => match precision { + Some(precision) => format!("timestamp({})", precision), + None => "timestamp".into(), + }, + ColumnType::TimestampWithTimeZone(precision) => match precision { + Some(precision) => format!("timestamp({}) with time zone", precision), + None => "timestamp with time zone".into(), + }, + ColumnType::Time(precision) => match precision { + Some(precision) => format!("time({})", precision), + None => "time".into(), + }, + ColumnType::Date => "date".into(), + ColumnType::Interval(fields, precision) => { + let mut typ = "interval".to_string(); + if let Some(fields) = fields { + typ.push_str(&format!(" {}", fields)); + } + if let Some(precision) = precision { + typ.push_str(&format!("({})", precision)); + } + typ + } + ColumnType::Binary(length) => match length { + Some(_) | None => "bytea".into(), + }, + ColumnType::Boolean => "bool".into(), + ColumnType::Money(precision) => match precision { + Some((precision, scale)) => format!("money({}, {})", precision, scale), + None => "money".into(), + }, + ColumnType::Json => "json".into(), + ColumnType::JsonBinary => "jsonb".into(), + ColumnType::Uuid => "uuid".into(), + ColumnType::Array(elem_type) => format!("{}[]", elem_type.as_ref().unwrap()), + ColumnType::Custom(iden) => iden.to_string(), + ColumnType::Enum(name, _) => name.into(), + } + ) + .unwrap() + } + + fn prepare_column_spec(&self, column_spec: &ColumnSpec, sql: &mut SqlWriter) { + match column_spec { + ColumnSpec::Null => write!(sql, "NULL"), + ColumnSpec::NotNull => write!(sql, "NOT NULL"), + ColumnSpec::Default(value) => write!(sql, "DEFAULT {}", self.value_to_string(value)), + ColumnSpec::AutoIncrement => write!(sql, ""), + ColumnSpec::UniqueKey => write!(sql, "UNIQUE"), + ColumnSpec::PrimaryKey => write!(sql, "PRIMARY KEY"), + ColumnSpec::Extra(string) => write!(sql, "{}", string), + } + .unwrap() + } + + fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut SqlWriter) { + if alter.options.is_empty() { + panic!("No alter option found") + }; + write!(sql, "ALTER TABLE ").unwrap(); + if let Some(table) = &alter.table { + table.prepare(sql, self.quote()); + write!(sql, " ").unwrap(); + } + + alter.options.iter().fold(true, |first, option| { + if !first { + write!(sql, ", ").unwrap(); + }; + match option { + TableAlterOption::AddColumn(AddColumnOption { + column, + if_not_exists, + }) => { + write!(sql, "ADD COLUMN ").unwrap(); + if *if_not_exists { + write!(sql, "IF NOT EXISTS ").unwrap(); + } + self.prepare_column_def(column, sql); + } + TableAlterOption::ModifyColumn(column_def) => { + write!(sql, "ALTER COLUMN ").unwrap(); + column_def.name.prepare(sql, self.quote()); + write!(sql, " TYPE").unwrap(); + self.prepare_column_type_check_auto_increment(column_def, sql); + for column_spec in column_def.spec.iter() { + if let ColumnSpec::AutoIncrement = column_spec { + continue; + } + write!(sql, ", ").unwrap(); + write!(sql, "ALTER COLUMN ").unwrap(); + column_def.name.prepare(sql, self.quote()); + write!(sql, " SET ").unwrap(); + self.prepare_column_spec(column_spec, sql); + } + } + TableAlterOption::RenameColumn(from_name, to_name) => { + write!(sql, "RENAME COLUMN ").unwrap(); + from_name.prepare(sql, self.quote()); + write!(sql, " TO ").unwrap(); + to_name.prepare(sql, self.quote()); + } + TableAlterOption::DropColumn(column_name) => { + write!(sql, "DROP COLUMN ").unwrap(); + column_name.prepare(sql, self.quote()); + } + } + false + }); + } + + fn prepare_table_rename_statement(&self, rename: &TableRenameStatement, sql: &mut SqlWriter) { + write!(sql, "ALTER TABLE ").unwrap(); + if let Some(from_name) = &rename.from_name { + from_name.prepare(sql, self.quote()); + } + write!(sql, " RENAME TO ").unwrap(); + if let Some(to_name) = &rename.to_name { + to_name.prepare(sql, self.quote()); + } + } +} + +impl PostgresQueryBuilder { + fn prepare_column_type_check_auto_increment( + &self, + column_def: &ColumnDef, + sql: &mut SqlWriter, + ) { + if let Some(column_type) = &column_def.types { + write!(sql, " ").unwrap(); + let is_auto_increment = column_def + .spec + .iter() + .position(|s| matches!(s, ColumnSpec::AutoIncrement)); + if is_auto_increment.is_some() { + match &column_type { + ColumnType::SmallInteger(_) => write!(sql, "smallserial").unwrap(), + ColumnType::Integer(_) => write!(sql, "serial").unwrap(), + ColumnType::BigInteger(_) => write!(sql, "bigserial").unwrap(), + _ => unimplemented!(), + } + } else { + self.prepare_column_type(column_type, sql); + } + } + } +} diff --git a/src/backend/oracle/types.rs b/src/backend/oracle/types.rs new file mode 100644 index 000000000..afae6875f --- /dev/null +++ b/src/backend/oracle/types.rs @@ -0,0 +1,137 @@ +use super::*; +use crate::extension::postgres::*; + +impl TypeBuilder for PostgresQueryBuilder { + fn prepare_type_create_statement( + &self, + create: &TypeCreateStatement, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + write!(sql, "CREATE TYPE ").unwrap(); + + if let Some(name) = &create.name { + name.prepare(sql, self.quote()); + } + + if let Some(as_type) = &create.as_type { + write!(sql, " AS ").unwrap(); + self.prepare_create_as_type(as_type, sql); + } + + if !create.values.is_empty() { + write!(sql, " (").unwrap(); + + for (count, val) in create.values.iter().enumerate() { + if count > 0 { + write!(sql, ", ").unwrap(); + } + self.prepare_value(&val.to_string().into(), sql, collector); + } + + write!(sql, ")").unwrap(); + } + } + + fn prepare_type_drop_statement( + &self, + drop: &TypeDropStatement, + sql: &mut SqlWriter, + _collector: &mut dyn FnMut(Value), + ) { + write!(sql, "DROP TYPE ").unwrap(); + + if drop.if_exists { + write!(sql, "IF EXISTS ").unwrap(); + } + + for name in drop.names.iter() { + name.prepare(sql, self.quote()); + } + + if let Some(option) = &drop.option { + write!(sql, " ").unwrap(); + self.prepare_drop_type_opt(option, sql); + } + } + + fn prepare_type_alter_statement( + &self, + alter: &TypeAlterStatement, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + write!(sql, "ALTER TYPE ").unwrap(); + + if let Some(name) = &alter.name { + name.prepare(sql, self.quote()); + } + + if let Some(option) = &alter.option { + self.prepare_alter_type_opt(option, sql, collector) + } + } +} + +impl PostgresQueryBuilder { + fn prepare_create_as_type(&self, as_type: &TypeAs, sql: &mut SqlWriter) { + write!( + sql, + "{}", + match as_type { + TypeAs::Enum => "ENUM", + } + ) + .unwrap() + } + + fn prepare_drop_type_opt(&self, opt: &TypeDropOpt, sql: &mut SqlWriter) { + write!( + sql, + "{}", + match opt { + TypeDropOpt::Cascade => "CASCADE", + TypeDropOpt::Restrict => "RESTRICT", + } + ) + .unwrap() + } + + fn prepare_alter_type_opt( + &self, + opt: &TypeAlterOpt, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + match opt { + TypeAlterOpt::Add(value, placement) => { + write!(sql, " ADD VALUE ").unwrap(); + match placement { + Some(add_option) => match add_option { + TypeAlterAddOpt::Before(before_value) => { + self.prepare_value(&value.to_string().into(), sql, collector); + write!(sql, " BEFORE ").unwrap(); + self.prepare_value(&before_value.to_string().into(), sql, collector); + } + TypeAlterAddOpt::After(after_value) => { + self.prepare_value(&value.to_string().into(), sql, collector); + write!(sql, " AFTER ").unwrap(); + self.prepare_value(&after_value.to_string().into(), sql, collector); + } + }, + None => self.prepare_value(&value.to_string().into(), sql, collector), + } + } + TypeAlterOpt::Rename(new_name) => { + write!(sql, " RENAME TO ").unwrap(); + self.prepare_value(&new_name.to_string().into(), sql, collector); + } + TypeAlterOpt::RenameValue(existing, new_name) => { + write!(sql, " RENAME VALUE ").unwrap(); + self.prepare_value(&existing.to_string().into(), sql, collector); + write!(sql, " TO ").unwrap(); + self.prepare_value(&new_name.to_string().into(), sql, collector); + } + } + } +} diff --git a/tests/oracle/foreign_key.rs b/tests/oracle/foreign_key.rs new file mode 100644 index 000000000..1710553a3 --- /dev/null +++ b/tests/oracle/foreign_key.rs @@ -0,0 +1,31 @@ +use super::*; + +#[test] +fn create_1() { + assert_eq!( + ForeignKey::create() + .name("FK_2e303c3a712662f1fc2a4d0aad6") + .from(Char::Table, Char::FontId) + .to(Font::Table, Font::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) + .to_string(PostgresQueryBuilder), + vec![ + r#"ALTER TABLE "character" ADD CONSTRAINT "FK_2e303c3a712662f1fc2a4d0aad6""#, + r#"FOREIGN KEY ("font_id") REFERENCES "font" ("id")"#, + r#"ON DELETE CASCADE ON UPDATE CASCADE"#, + ] + .join(" ") + ); +} + +#[test] +fn drop_1() { + assert_eq!( + ForeignKey::drop() + .name("FK_2e303c3a712662f1fc2a4d0aad6") + .table(Char::Table) + .to_string(PostgresQueryBuilder), + r#"ALTER TABLE "character" DROP CONSTRAINT "FK_2e303c3a712662f1fc2a4d0aad6""# + ); +} diff --git a/tests/oracle/index.rs b/tests/oracle/index.rs new file mode 100644 index 000000000..13cc341bb --- /dev/null +++ b/tests/oracle/index.rs @@ -0,0 +1,50 @@ +use super::*; + +#[test] +fn create_1() { + assert_eq!( + Index::create() + .name("idx-glyph-aspect") + .table(Glyph::Table) + .col(Glyph::Aspect) + .to_string(PostgresQueryBuilder), + r#"CREATE INDEX "idx-glyph-aspect" ON "glyph" ("aspect")"# + ); +} + +#[test] +fn create_2() { + assert_eq!( + Index::create() + .unique() + .name("idx-glyph-aspect-image") + .table(Glyph::Table) + .col(Glyph::Aspect) + .col(Glyph::Image) + .to_string(PostgresQueryBuilder), + r#"CREATE UNIQUE INDEX "idx-glyph-aspect-image" ON "glyph" ("aspect", "image")"# + ); +} + +#[test] +fn create_3() { + assert_eq!( + Index::create() + .full_text() + .name("idx-glyph-image") + .table(Glyph::Table) + .col(Glyph::Image) + .to_string(PostgresQueryBuilder), + r#"CREATE INDEX "idx-glyph-image" ON "glyph" USING GIN ("image")"# + ); +} + +#[test] +fn drop_1() { + assert_eq!( + Index::drop() + .name("idx-glyph-aspect") + .to_string(PostgresQueryBuilder), + r#"DROP INDEX "idx-glyph-aspect""# + ); +} diff --git a/tests/oracle/interval.rs b/tests/oracle/interval.rs new file mode 100644 index 000000000..a25c791f3 --- /dev/null +++ b/tests/oracle/interval.rs @@ -0,0 +1,35 @@ +use quote::{quote, ToTokens}; +use sea_query::*; + +#[test] +fn with_quote_1() { + for (interval_field, token_stream) in [ + (PgInterval::Year, quote! { PgInterval::Year }), + (PgInterval::Month, quote! { PgInterval::Month }), + (PgInterval::Day, quote! { PgInterval::Day }), + (PgInterval::Hour, quote! { PgInterval::Hour }), + (PgInterval::Minute, quote! { PgInterval::Minute }), + (PgInterval::Second, quote! { PgInterval::Second }), + (PgInterval::YearToMonth, quote! { PgInterval::YearToMonth }), + (PgInterval::DayToHour, quote! { PgInterval::DayToHour }), + (PgInterval::DayToMinute, quote! { PgInterval::DayToMinute }), + (PgInterval::DayToSecond, quote! { PgInterval::DayToSecond }), + ( + PgInterval::HourToMinute, + quote! { PgInterval::HourToMinute }, + ), + ( + PgInterval::HourToSecond, + quote! { PgInterval::HourToSecond }, + ), + ( + PgInterval::MinuteToSecond, + quote! { PgInterval::MinuteToSecond }, + ), + ] { + assert_eq!( + interval_field.into_token_stream().to_string(), + token_stream.to_string() + ); + } +} diff --git a/tests/oracle/mod.rs b/tests/oracle/mod.rs new file mode 100644 index 000000000..ee1e12d1b --- /dev/null +++ b/tests/oracle/mod.rs @@ -0,0 +1,10 @@ +use sea_query::{tests_cfg::*, *}; + +mod foreign_key; +mod index; +#[cfg(feature = "postgres-interval")] +mod interval; +#[allow(deprecated)] +mod query; +mod table; +mod types; diff --git a/tests/oracle/query.rs b/tests/oracle/query.rs new file mode 100644 index 000000000..532c0ffa0 --- /dev/null +++ b/tests/oracle/query.rs @@ -0,0 +1,1303 @@ +use super::*; +use pretty_assertions::assert_eq; + +#[test] +fn select_1() { + assert_eq!( + Query::select() + .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) + .from(Char::Table) + .limit(10) + .offset(100) + .to_string(PostgresQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" LIMIT 10 OFFSET 100"# + ); +} + +#[test] +fn select_2() { + assert_eq!( + Query::select() + .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) + .from(Char::Table) + .and_where(Expr::col(Char::SizeW).eq(3)) + .to_string(PostgresQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3"# + ); +} + +#[test] +fn select_3() { + assert_eq!( + Query::select() + .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) + .from(Char::Table) + .and_where(Expr::col(Char::SizeW).eq(3)) + .and_where(Expr::col(Char::SizeH).eq(4)) + .to_string(PostgresQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3 AND "size_h" = 4"# + ); +} + +#[test] +fn select_4() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect]) + .from_subquery( + Query::select() + .columns(vec![Glyph::Image, Glyph::Aspect]) + .from(Glyph::Table) + .take(), + Alias::new("subglyph") + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "aspect" FROM (SELECT "image", "aspect" FROM "glyph") AS "subglyph""# + ); +} + +#[test] +fn select_5() { + assert_eq!( + Query::select() + .column((Glyph::Table, Glyph::Image)) + .from(Glyph::Table) + .and_where(Expr::tbl(Glyph::Table, Glyph::Aspect).is_in(vec![3, 4])) + .to_string(PostgresQueryBuilder), + r#"SELECT "glyph"."image" FROM "glyph" WHERE "glyph"."aspect" IN (3, 4)"# + ); +} + +#[test] +fn select_6() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .exprs(vec![Expr::col(Glyph::Image).max(),]) + .from(Glyph::Table) + .group_by_columns(vec![Glyph::Aspect,]) + .and_having(Expr::col(Glyph::Aspect).gt(2)) + .to_string(PostgresQueryBuilder), + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# + ); +} + +#[test] +fn select_7() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .to_string(PostgresQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2"# + ); +} + +#[test] +fn select_8() { + assert_eq!( + Query::select() + .columns(vec![Char::Character,]) + .from(Char::Table) + .left_join( + Font::Table, + Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id) + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" LEFT JOIN "font" ON "character"."font_id" = "font"."id""# + ); +} + +#[test] +fn select_9() { + assert_eq!( + Query::select() + .columns(vec![Char::Character,]) + .from(Char::Table) + .left_join( + Font::Table, + Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id) + ) + .inner_join( + Glyph::Table, + Expr::tbl(Char::Table, Char::Character).equals(Glyph::Table, Glyph::Image) + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" LEFT JOIN "font" ON "character"."font_id" = "font"."id" INNER JOIN "glyph" ON "character"."character" = "glyph"."image""# + ); +} + +#[test] +fn select_10() { + assert_eq!( + Query::select() + .columns(vec![Char::Character,]) + .from(Char::Table) + .left_join( + Font::Table, + Expr::tbl(Char::Table, Char::FontId) + .equals(Font::Table, Font::Id) + .and(Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id)) + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" LEFT JOIN "font" ON ("character"."font_id" = "font"."id") AND ("character"."font_id" = "font"."id")"# + ); +} + +#[test] +fn select_11() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .order_by(Glyph::Image, Order::Desc) + .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) + .to_string(PostgresQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "image" DESC, "glyph"."aspect" ASC"# + ); +} + +#[test] +fn select_12() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .order_by_columns(vec![(Glyph::Id, Order::Asc), (Glyph::Aspect, Order::Desc),]) + .to_string(PostgresQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "id" ASC, "aspect" DESC"# + ); +} + +#[test] +fn select_13() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .order_by_columns(vec![ + ((Glyph::Table, Glyph::Id), Order::Asc), + ((Glyph::Table, Glyph::Aspect), Order::Desc), + ]) + .to_string(PostgresQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."id" ASC, "glyph"."aspect" DESC"# + ); +} + +#[test] +fn select_14() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Id, Glyph::Aspect,]) + .expr(Expr::col(Glyph::Image).max()) + .from(Glyph::Table) + .group_by_columns(vec![ + (Glyph::Table, Glyph::Id), + (Glyph::Table, Glyph::Aspect), + ]) + .and_having(Expr::col(Glyph::Aspect).gt(2)) + .to_string(PostgresQueryBuilder), + r#"SELECT "id", "aspect", MAX("image") FROM "glyph" GROUP BY "glyph"."id", "glyph"."aspect" HAVING "aspect" > 2"# + ); +} + +#[test] +fn select_15() { + assert_eq!( + Query::select() + .columns(vec![Char::Character]) + .from(Char::Table) + .and_where(Expr::col(Char::FontId).is_null()) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE "font_id" IS NULL"# + ); +} + +#[test] +fn select_16() { + assert_eq!( + Query::select() + .columns(vec![Char::Character]) + .from(Char::Table) + .and_where(Expr::col(Char::FontId).is_null()) + .and_where(Expr::col(Char::Character).is_not_null()) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE "font_id" IS NULL AND "character" IS NOT NULL"# + ); +} + +#[test] +fn select_17() { + assert_eq!( + Query::select() + .columns(vec![(Glyph::Table, Glyph::Image),]) + .from(Glyph::Table) + .and_where(Expr::tbl(Glyph::Table, Glyph::Aspect).between(3, 5)) + .to_string(PostgresQueryBuilder), + r#"SELECT "glyph"."image" FROM "glyph" WHERE "glyph"."aspect" BETWEEN 3 AND 5"# + ); +} + +#[test] +fn select_18() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::col(Glyph::Aspect).between(3, 5)) + .and_where(Expr::col(Glyph::Aspect).not_between(8, 10)) + .to_string(PostgresQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE ("aspect" BETWEEN 3 AND 5) AND ("aspect" NOT BETWEEN 8 AND 10)"# + ); +} + +#[test] +fn select_19() { + assert_eq!( + Query::select() + .columns(vec![Char::Character]) + .from(Char::Table) + .and_where(Expr::col(Char::Character).eq("A")) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE "character" = 'A'"# + ); +} + +#[test] +fn select_20() { + assert_eq!( + Query::select() + .column(Char::Character) + .from(Char::Table) + .and_where(Expr::col(Char::Character).like("A")) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE "character" LIKE 'A'"# + ); +} + +#[test] +fn select_21() { + assert_eq!( + Query::select() + .columns(vec![Char::Character]) + .from(Char::Table) + .or_where(Expr::col(Char::Character).like("A%")) + .or_where(Expr::col(Char::Character).like("%B")) + .or_where(Expr::col(Char::Character).like("%C%")) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE "character" LIKE 'A%' OR "character" LIKE '%B' OR "character" LIKE '%C%'"# + ); +} + +#[test] +fn select_22() { + assert_eq!( + Query::select() + .column(Char::Character) + .from(Char::Table) + .cond_where( + Cond::all() + .add( + Cond::any().add(Expr::col(Char::Character).like("C")).add( + Expr::col(Char::Character) + .like("D") + .and(Expr::col(Char::Character).like("E")) + ) + ) + .add( + Expr::col(Char::Character) + .like("F") + .or(Expr::col(Char::Character).like("G")) + ) + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE ("character" LIKE 'C' OR (("character" LIKE 'D') AND ("character" LIKE 'E'))) AND (("character" LIKE 'F') OR ("character" LIKE 'G'))"# + ); +} + +#[test] +fn select_23() { + assert_eq!( + Query::select() + .column(Char::Character) + .from(Char::Table) + .and_where_option(None) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character""# + ); +} + +#[test] +fn select_24() { + assert_eq!( + Query::select() + .column(Char::Character) + .from(Char::Table) + .conditions( + true, + |x| { + x.and_where(Expr::col(Char::FontId).eq(5)); + }, + |_| () + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE "font_id" = 5"# + ); +} + +#[test] +fn select_25() { + assert_eq!( + Query::select() + .column(Char::Character) + .from(Char::Table) + .and_where( + Expr::col(Char::SizeW) + .mul(2) + .equals(Expr::col(Char::SizeH).div(2)) + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE "size_w" * 2 = "size_h" / 2"# + ); +} + +#[test] +fn select_26() { + assert_eq!( + Query::select() + .column(Char::Character) + .from(Char::Table) + .and_where( + Expr::expr(Expr::col(Char::SizeW).add(1)) + .mul(2) + .equals(Expr::expr(Expr::col(Char::SizeH).div(2)).sub(1)) + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" FROM "character" WHERE ("size_w" + 1) * 2 = ("size_h" / 2) - 1"# + ); +} + +#[test] +fn select_27() { + assert_eq!( + Query::select() + .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) + .from(Char::Table) + .and_where(Expr::col(Char::SizeW).eq(3)) + .and_where(Expr::col(Char::SizeH).eq(4)) + .and_where(Expr::col(Char::SizeH).eq(5)) + .to_string(PostgresQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3 AND "size_h" = 4 AND "size_h" = 5"# + ); +} + +#[test] +fn select_28() { + assert_eq!( + Query::select() + .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) + .from(Char::Table) + .or_where(Expr::col(Char::SizeW).eq(3)) + .or_where(Expr::col(Char::SizeH).eq(4)) + .or_where(Expr::col(Char::SizeH).eq(5)) + .to_string(PostgresQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3 OR "size_h" = 4 OR "size_h" = 5"# + ); +} + +#[test] +#[should_panic] +fn select_29() { + assert_eq!( + Query::select() + .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) + .from(Char::Table) + .and_where(Expr::col(Char::SizeW).eq(3)) + .or_where(Expr::col(Char::SizeH).eq(4)) + .and_where(Expr::col(Char::SizeH).eq(5)) + .to_string(PostgresQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3 OR "size_h" = 4 AND "size_h" = 5"# + ); +} + +#[test] +fn select_30() { + assert_eq!( + Query::select() + .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) + .from(Char::Table) + .and_where( + Expr::col(Char::SizeW) + .mul(2) + .add(Expr::col(Char::SizeH).div(3)) + .equals(Expr::value(4)) + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" * 2) + ("size_h" / 3) = 4"# + ); +} + +#[test] +fn select_31() { + assert_eq!( + Query::select() + .expr((1..10_i32).fold(Expr::value(0), |expr, i| { expr.add(Expr::value(i)) })) + .to_string(PostgresQueryBuilder), + r#"SELECT 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9"# + ); +} + +#[test] +fn select_32() { + assert_eq!( + Query::select() + .expr_as(Expr::col(Char::Character), Alias::new("C")) + .from(Char::Table) + .to_string(PostgresQueryBuilder), + r#"SELECT "character" AS "C" FROM "character""# + ); +} + +#[test] +fn select_33() { + assert_eq!( + Query::select() + .column(Glyph::Image) + .from(Glyph::Table) + .and_where( + Expr::col(Glyph::Aspect) + .in_subquery(Query::select().expr(Expr::cust("3 + 2 * 2")).take()) + ) + .to_string(PostgresQueryBuilder), + r#"SELECT "image" FROM "glyph" WHERE "aspect" IN (SELECT 3 + 2 * 2)"# + ); +} + +#[test] +fn select_34a() { + assert_eq!( + Query::select() + .column(Glyph::Aspect) + .expr(Expr::col(Glyph::Image).max()) + .from(Glyph::Table) + .group_by_columns(vec![Glyph::Aspect,]) + .or_having( + Expr::col(Glyph::Aspect) + .gt(2) + .or(Expr::col(Glyph::Aspect).lt(8)) + ) + .or_having( + Expr::col(Glyph::Aspect) + .gt(12) + .and(Expr::col(Glyph::Aspect).lt(18)) + ) + .or_having(Expr::col(Glyph::Aspect).gt(32)) + .to_string(PostgresQueryBuilder), + vec![ + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect""#, + r#"HAVING (("aspect" > 2) OR ("aspect" < 8))"#, + r#"OR (("aspect" > 12) AND ("aspect" < 18))"#, + r#"OR "aspect" > 32"#, + ] + .join(" ") + ); +} + +#[test] +#[should_panic] +fn select_34b() { + assert_eq!( + Query::select() + .column(Glyph::Aspect) + .expr(Expr::col(Glyph::Image).max()) + .from(Glyph::Table) + .group_by_columns(vec![Glyph::Aspect,]) + .or_having( + Expr::col(Glyph::Aspect) + .gt(2) + .or(Expr::col(Glyph::Aspect).lt(8)) + ) + .and_having( + Expr::col(Glyph::Aspect) + .gt(22) + .or(Expr::col(Glyph::Aspect).lt(28)) + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect""#, + r#"HAVING (("aspect" > 2) OR ("aspect" < 8))"#, + r#"AND (("aspect" > 22) OR ("aspect" < 28))"#, + ] + .join(" ") + ); +} + +#[test] +fn select_35() { + let (statement, values) = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .and_where(Expr::col(Glyph::Aspect).is_null()) + .build(sea_query::PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE "aspect" IS NULL"# + ); + assert_eq!(values.0, vec![]); +} + +#[test] +fn select_36() { + let (statement, values) = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where(Cond::any().add(Expr::col(Glyph::Aspect).is_null())) + .build(sea_query::PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE "aspect" IS NULL"# + ); + assert_eq!(values.0, vec![]); +} + +#[test] +fn select_37() { + let (statement, values) = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where(Cond::any().add(Cond::all()).add(Cond::any())) + .build(sea_query::PostgresQueryBuilder); + + assert_eq!(statement, r#"SELECT "id" FROM "glyph""#); + assert_eq!(values.0, vec![]); +} + +#[test] +fn select_38() { + let (statement, values) = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where( + Cond::any() + .add(Expr::col(Glyph::Aspect).is_null()) + .add(Expr::col(Glyph::Aspect).is_not_null()), + ) + .build(sea_query::PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE "aspect" IS NULL OR "aspect" IS NOT NULL"# + ); + assert_eq!(values.0, vec![]); +} + +#[test] +fn select_39() { + let (statement, values) = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where( + Cond::all() + .add(Expr::col(Glyph::Aspect).is_null()) + .add(Expr::col(Glyph::Aspect).is_not_null()), + ) + .build(sea_query::PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE "aspect" IS NULL AND "aspect" IS NOT NULL"# + ); + assert_eq!(values.0, vec![]); +} + +#[test] +fn select_40() { + let statement = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where(any![ + Expr::col(Glyph::Aspect).is_null(), + all![ + Expr::col(Glyph::Aspect).is_not_null(), + Expr::col(Glyph::Aspect).lt(8) + ] + ]) + .to_string(sea_query::PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE "aspect" IS NULL OR ("aspect" IS NOT NULL AND "aspect" < 8)"# + ); +} + +#[test] +fn select_41() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect]) + .exprs(vec![Expr::col(Glyph::Image).max()]) + .from(Glyph::Table) + .group_by_columns(vec![Glyph::Aspect]) + .cond_having(any![Expr::col(Glyph::Aspect).gt(2)]) + .to_string(PostgresQueryBuilder), + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# + ); +} + +#[test] +fn select_42() { + let statement = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where( + Cond::all() + .add_option(Some(Expr::col(Glyph::Aspect).lt(8))) + .add(Expr::col(Glyph::Aspect).is_not_null()), + ) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE "aspect" < 8 AND "aspect" IS NOT NULL"# + ); +} + +#[test] +fn select_43() { + let statement = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where(Cond::all().add_option::(None)) + .to_string(PostgresQueryBuilder); + + assert_eq!(statement, r#"SELECT "id" FROM "glyph""#); +} + +#[test] +fn select_44() { + let statement = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where( + Cond::any() + .not() + .add_option(Some(Expr::col(Glyph::Aspect).lt(8))), + ) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE NOT ("aspect" < 8)"# + ); +} + +#[test] +fn select_45() { + let statement = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where( + Cond::any() + .not() + .add_option(Some(Expr::col(Glyph::Aspect).lt(8))) + .add(Expr::col(Glyph::Aspect).is_not_null()), + ) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE NOT ("aspect" < 8 OR "aspect" IS NOT NULL)"# + ); +} + +#[test] +fn select_46() { + let statement = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where( + Cond::all() + .not() + .add_option(Some(Expr::col(Glyph::Aspect).lt(8))), + ) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE NOT ("aspect" < 8)"# + ); +} + +#[test] +fn select_47() { + let statement = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where( + Cond::all() + .not() + .add_option(Some(Expr::col(Glyph::Aspect).lt(8))) + .add(Expr::col(Glyph::Aspect).is_not_null()), + ) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE NOT ("aspect" < 8 AND "aspect" IS NOT NULL)"# + ); +} + +#[test] +fn select_48() { + let statement = sea_query::Query::select() + .column(Glyph::Id) + .from(Glyph::Table) + .cond_where( + Cond::all().add_option(Some(ConditionExpression::SimpleExpr( + Expr::tuple([ + Expr::col(Glyph::Aspect).into_simple_expr(), + Expr::value(100), + ]) + .less_than(Expr::tuple([Expr::value(8), Expr::value(100)])), + ))), + ) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "id" FROM "glyph" WHERE ("aspect", 100) < (8, 100)"# + ); +} + +#[test] +fn select_49() { + let statement = sea_query::Query::select() + .expr(Expr::asterisk()) + .from(Char::Table) + .to_string(PostgresQueryBuilder); + + assert_eq!(statement, r#"SELECT * FROM "character""#); +} + +#[test] +fn select_50() { + let statement = sea_query::Query::select() + .expr(Expr::table_asterisk(Char::Table)) + .column((Font::Table, Font::Name)) + .from(Char::Table) + .inner_join( + Font::Table, + Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id), + ) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "character".*, "font"."name" FROM "character" INNER JOIN "font" ON "character"."font_id" = "font"."id""# + ) +} + +#[test] +fn select_51() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .order_by_with_nulls(Glyph::Image, Order::Desc, NullOrdering::First) + .order_by_with_nulls( + (Glyph::Table, Glyph::Aspect), + Order::Asc, + NullOrdering::Last + ) + .to_string(PostgresQueryBuilder), + [ + r#"SELECT "aspect""#, + r#"FROM "glyph""#, + r#"WHERE COALESCE("aspect", 0) > 2"#, + r#"ORDER BY "image" DESC NULLS FIRST,"#, + r#""glyph"."aspect" ASC NULLS LAST"#, + ] + .join(" ") + ); +} + +#[test] +fn select_52() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .order_by_columns_with_nulls(vec![ + (Glyph::Id, Order::Asc, NullOrdering::First), + (Glyph::Aspect, Order::Desc, NullOrdering::Last), + ]) + .to_string(PostgresQueryBuilder), + [ + r#"SELECT "aspect""#, + r#"FROM "glyph""#, + r#"WHERE COALESCE("aspect", 0) > 2"#, + r#"ORDER BY "id" ASC NULLS FIRST,"#, + r#""aspect" DESC NULLS LAST"#, + ] + .join(" ") + ); +} + +#[test] +fn select_53() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .order_by_columns_with_nulls(vec![ + ((Glyph::Table, Glyph::Id), Order::Asc, NullOrdering::First), + ( + (Glyph::Table, Glyph::Aspect), + Order::Desc, + NullOrdering::Last + ), + ]) + .to_string(PostgresQueryBuilder), + [ + r#"SELECT "aspect""#, + r#"FROM "glyph""#, + r#"WHERE COALESCE("aspect", 0) > 2"#, + r#"ORDER BY "glyph"."id" ASC NULLS FIRST,"#, + r#""glyph"."aspect" DESC NULLS LAST"#, + ] + .join(" ") + ); +} + +#[test] +fn select_54() { + let statement = sea_query::Query::select() + .expr(Expr::asterisk()) + .from(Char::Table) + .from(Font::Table) + .and_where(Expr::tbl(Font::Table, Font::Id).equals(Char::Table, Char::FontId)) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT * FROM "character", "font" WHERE "font"."id" = "character"."font_id""# + ); +} + +#[test] +fn select_55() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .order_by( + Glyph::Id, + Order::Field(Values(vec![ + Value::Int(Some(4)), + Value::Int(Some(5)), + Value::Int(Some(1)), + Value::Int(Some(3)) + ])) + ) + .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) + .to_string(PostgresQueryBuilder), + [ + r#"SELECT "aspect""#, + r#"FROM "glyph""#, + r#"WHERE COALESCE("aspect", 0) > 2"#, + r#"ORDER BY CASE"#, + r#"WHEN "id"=4 THEN 0"#, + r#"WHEN "id"=5 THEN 1"#, + r#"WHEN "id"=1 THEN 2"#, + r#"WHEN "id"=3 THEN 3"#, + r#"ELSE 4 END,"#, + r#""glyph"."aspect" ASC"#, + ] + .join(" ") + ); +} + +#[test] +fn select_56() { + assert_eq!( + Query::select() + .columns(vec![Glyph::Aspect,]) + .from(Glyph::Table) + .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) + .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) + .order_by( + Glyph::Id, + Order::Field(Values(vec![ + Value::Int(Some(4)), + Value::Int(Some(5)), + Value::Int(Some(1)), + Value::Int(Some(3)) + ])) + ) + .to_string(PostgresQueryBuilder), + [ + r#"SELECT "aspect""#, + r#"FROM "glyph""#, + r#"WHERE COALESCE("aspect", 0) > 2"#, + r#"ORDER BY "glyph"."aspect" ASC,"#, + r#"CASE WHEN "id"=4 THEN 0"#, + r#"WHEN "id"=5 THEN 1"#, + r#"WHEN "id"=1 THEN 2"#, + r#"WHEN "id"=3 THEN 3"#, + r#"ELSE 4 END"#, + ] + .join(" ") + ); +} + +#[test] +fn select_57() { + let select = SelectStatement::new() + .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) + .from(Glyph::Table) + .to_owned(); + let cte = CommonTableExpression::new() + .query(select) + .table_name(Alias::new("cte")) + .to_owned(); + let with_clause = WithClause::new().cte(cte).to_owned(); + let select = SelectStatement::new() + .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) + .from(Alias::new("cte")) + .to_owned(); + assert_eq!( + select.with(with_clause).to_string(PostgresQueryBuilder), + [ + r#"WITH "cte" AS"#, + r#"(SELECT "id", "image", "aspect""#, + r#"FROM "glyph")"#, + r#"SELECT "id", "image", "aspect" FROM "cte""#, + ] + .join(" ") + ); +} + +#[test] +fn select_58() { + let query = Query::select() + .expr_as( + CaseStatement::new() + .case( + Expr::tbl(Glyph::Table, Glyph::Aspect).gt(0), + Expr::val("positive"), + ) + .case( + Expr::tbl(Glyph::Table, Glyph::Aspect).lt(0), + Expr::val("negative"), + ) + .finally(Expr::val("zero")), + Alias::new("polarity"), + ) + .from(Glyph::Table) + .to_owned(); + + assert_eq!( + query.to_string(PostgresQueryBuilder), + r#"SELECT (CASE WHEN ("glyph"."aspect" > 0) THEN 'positive' WHEN ("glyph"."aspect" < 0) THEN 'negative' ELSE 'zero' END) AS "polarity" FROM "glyph""# + ); +} + +#[test] +#[allow(clippy::approx_constant)] +fn insert_2() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Image, Glyph::Aspect,]) + .values_panic(vec![ + "04108048005887010020060000204E0180400400".into(), + 3.1415.into(), + ]) + .to_string(PostgresQueryBuilder), + r#"INSERT INTO "glyph" ("image", "aspect") VALUES ('04108048005887010020060000204E0180400400', 3.1415)"# + ); +} + +#[test] +#[allow(clippy::approx_constant)] +fn insert_3() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Image, Glyph::Aspect,]) + .values_panic(vec![ + "04108048005887010020060000204E0180400400".into(), + 3.1415.into(), + ]) + .values_panic(vec![Value::String(None), 2.1345.into(),]) + .to_string(PostgresQueryBuilder), + r#"INSERT INTO "glyph" ("image", "aspect") VALUES ('04108048005887010020060000204E0180400400', 3.1415), (NULL, 2.1345)"# + ); +} + +#[test] +#[cfg(feature = "with-chrono")] +fn insert_4() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Image]) + .values_panic(vec![chrono::NaiveDateTime::from_timestamp(0, 0).into()]) + .to_string(PostgresQueryBuilder), + "INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')" + ); +} + +#[test] +#[cfg(feature = "with-time")] +fn insert_9() { + use time::{date, time}; + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Image]) + .values_panic(vec![date!(1970 - 01 - 01) + .with_time(time!(00:00:00)) + .into()]) + .to_string(PostgresQueryBuilder), + "INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')" + ); +} + +#[test] +#[cfg(feature = "with-uuid")] +fn insert_5() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Image]) + .values_panic(vec![uuid::Uuid::nil().into()]) + .to_string(PostgresQueryBuilder), + "INSERT INTO \"glyph\" (\"image\") VALUES ('00000000-0000-0000-0000-000000000000')" + ); +} + +#[test] +fn insert_from_select() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Aspect, Glyph::Image]) + .select_from( + Query::select() + .column(Glyph::Aspect) + .column(Glyph::Image) + .from(Glyph::Table) + .conditions( + true, + |x| { + x.and_where(Expr::col(Glyph::Image).like("%")); + }, + |x| { + x.and_where(Expr::col(Glyph::Id).eq(6)); + }, + ) + .to_owned() + ) + .unwrap() + .to_owned() + .to_string(PostgresQueryBuilder), + r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '%'"# + ); +} + +#[test] +fn insert_6() -> sea_query::error::Result<()> { + let select = SelectStatement::new() + .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) + .from(Glyph::Table) + .to_owned(); + let cte = CommonTableExpression::new() + .query(select) + .column(Glyph::Id) + .column(Glyph::Image) + .column(Glyph::Aspect) + .table_name(Alias::new("cte")) + .to_owned(); + let with_clause = WithClause::new().cte(cte).to_owned(); + let select = SelectStatement::new() + .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) + .from(Alias::new("cte")) + .to_owned(); + let mut insert = Query::insert(); + insert + .into_table(Glyph::Table) + .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) + .select_from(select)?; + let sql = insert.with(with_clause).to_string(PostgresQueryBuilder); + assert_eq!( + sql.as_str(), + [ + r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph")"#, + r#"INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#, + ].join(" ") + ); + Ok(()) +} + +#[test] +#[allow(clippy::approx_constant)] +fn insert_on_conflict_1() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Aspect, Glyph::Image]) + .values_panic(vec![ + "04108048005887010020060000204E0180400400".into(), + 3.1415.into(), + ]) + .on_conflict( + OnConflict::column(Glyph::Id) + .update_column(Glyph::Aspect) + .to_owned() + ) + .to_string(PostgresQueryBuilder), + [ + r#"INSERT INTO "glyph" ("aspect", "image")"#, + r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, + r#"ON CONFLICT ("id") DO UPDATE SET "aspect" = "excluded"."aspect""#, + ] + .join(" ") + ); +} + +#[test] +#[allow(clippy::approx_constant)] +fn insert_on_conflict_2() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Aspect, Glyph::Image]) + .values_panic(vec![ + "04108048005887010020060000204E0180400400".into(), + 3.1415.into(), + ]) + .on_conflict( + OnConflict::columns([Glyph::Id, Glyph::Aspect]) + .update_columns([Glyph::Aspect, Glyph::Image]) + .to_owned() + ) + .to_string(PostgresQueryBuilder), + [ + r#"INSERT INTO "glyph" ("aspect", "image")"#, + r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, + r#"ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = "excluded"."aspect", "image" = "excluded"."image""#, + ] + .join(" ") + ); +} + +#[test] +#[allow(clippy::approx_constant)] +fn insert_on_conflict_3() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Aspect, Glyph::Image]) + .values_panic(vec![ + "04108048005887010020060000204E0180400400".into(), + 3.1415.into(), + ]) + .on_conflict( + OnConflict::columns([Glyph::Id, Glyph::Aspect]) + .update_values([ + (Glyph::Aspect, "04108048005887010020060000204E0180400400".into()), + (Glyph::Image, 3.1415.into()), + ]) + .to_owned() + ) + .to_string(PostgresQueryBuilder), + [ + r#"INSERT INTO "glyph" ("aspect", "image")"#, + r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, + r#"ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = '04108048005887010020060000204E0180400400', "image" = 3.1415"#, + ] + .join(" ") + ); +} + +#[test] +#[allow(clippy::approx_constant)] +fn insert_on_conflict_4() { + assert_eq!( + Query::insert() + .into_table(Glyph::Table) + .columns(vec![Glyph::Aspect, Glyph::Image]) + .values_panic(vec![ + "04108048005887010020060000204E0180400400".into(), + 3.1415.into(), + ]) + .on_conflict( + OnConflict::columns([Glyph::Id, Glyph::Aspect]) + .update_expr((Glyph::Image, Expr::val(1).add(2))) + .to_owned() + ) + .to_string(PostgresQueryBuilder), + [ + r#"INSERT INTO "glyph" ("aspect", "image")"#, + r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, + r#"ON CONFLICT ("id", "aspect") DO UPDATE SET "image" = 1 + 2"#, + ] + .join(" ") + ); +} + +#[test] +fn update_1() { + assert_eq!( + Query::update() + .table(Glyph::Table) + .values(vec![ + (Glyph::Aspect, 2.1345.into()), + ( + Glyph::Image, + "24B0E11951B03B07F8300FD003983F03F0780060".into() + ), + ]) + .and_where(Expr::col(Glyph::Id).eq(1)) + .to_string(PostgresQueryBuilder), + r#"UPDATE "glyph" SET "aspect" = 2.1345, "image" = '24B0E11951B03B07F8300FD003983F03F0780060' WHERE "id" = 1"# + ); +} + +#[test] +fn update_3() { + assert_eq!( + Query::update() + .table(Glyph::Table) + .value_expr(Glyph::Aspect, Expr::cust("60 * 24 * 24")) + .values(vec![( + Glyph::Image, + "24B0E11951B03B07F8300FD003983F03F0780060".into() + ),]) + .and_where(Expr::col(Glyph::Id).eq(1)) + .to_string(PostgresQueryBuilder), + r#"UPDATE "glyph" SET "aspect" = 60 * 24 * 24, "image" = '24B0E11951B03B07F8300FD003983F03F0780060' WHERE "id" = 1"# + ); +} + +#[test] +fn delete_1() { + assert_eq!( + Query::delete() + .from_table(Glyph::Table) + .and_where(Expr::col(Glyph::Id).eq(1)) + .to_string(PostgresQueryBuilder), + r#"DELETE FROM "glyph" WHERE "id" = 1"# + ); +} diff --git a/tests/oracle/table.rs b/tests/oracle/table.rs new file mode 100644 index 000000000..0a447781f --- /dev/null +++ b/tests/oracle/table.rs @@ -0,0 +1,361 @@ +use super::*; + +#[test] +fn create_1() { + assert_eq!( + Table::create() + .table(Glyph::Table) + .col( + ColumnDef::new(Glyph::Id) + .integer() + .not_null() + .auto_increment() + .primary_key() + ) + .col(ColumnDef::new(Glyph::Aspect).double().not_null()) + .col(ColumnDef::new(Glyph::Image).text()) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "glyph" ("#, + r#""id" serial NOT NULL PRIMARY KEY,"#, + r#""aspect" double precision NOT NULL,"#, + r#""image" text"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_2() { + assert_eq!( + Table::create() + .table(Font::Table) + .col( + ColumnDef::new(Font::Id) + .integer() + .not_null() + .primary_key() + .auto_increment() + ) + .col(ColumnDef::new(Font::Name).string().not_null()) + .col(ColumnDef::new(Font::Variant).string_len(255).not_null()) + .col(ColumnDef::new(Font::Language).string_len(255).not_null()) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "font" ("#, + r#""id" serial NOT NULL PRIMARY KEY,"#, + r#""name" varchar NOT NULL,"#, + r#""variant" varchar(255) NOT NULL,"#, + r#""language" varchar(255) NOT NULL"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_3() { + assert_eq!( + Table::create() + .table(Char::Table) + .if_not_exists() + .col( + ColumnDef::new(Char::Id) + .integer() + .not_null() + .primary_key() + .auto_increment() + ) + .col(ColumnDef::new(Char::FontSize).integer().not_null()) + .col(ColumnDef::new(Char::Character).string_len(255).not_null()) + .col(ColumnDef::new(Char::SizeW).unsigned().not_null()) + .col(ColumnDef::new(Char::SizeH).unsigned().not_null()) + .col( + ColumnDef::new(Char::FontId) + .integer() + .default(Value::Int(None)) + ) + .foreign_key( + ForeignKey::create() + .name("FK_2e303c3a712662f1fc2a4d0aad6") + .from(Char::Table, Char::FontId) + .to(Font::Table, Font::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE IF NOT EXISTS "character" ("#, + r#""id" serial NOT NULL PRIMARY KEY,"#, + r#""font_size" integer NOT NULL,"#, + r#""character" varchar(255) NOT NULL,"#, + r#""size_w" integer NOT NULL,"#, + r#""size_h" integer NOT NULL,"#, + r#""font_id" integer DEFAULT NULL,"#, + r#"CONSTRAINT "FK_2e303c3a712662f1fc2a4d0aad6""#, + r#"FOREIGN KEY ("font_id") REFERENCES "font" ("id")"#, + r#"ON DELETE CASCADE ON UPDATE CASCADE"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_4() { + assert_eq!( + Table::create() + .table(Glyph::Table) + .col(ColumnDef::new(Glyph::Image).custom(Glyph::Aspect)) + .to_string(PostgresQueryBuilder), + vec![r#"CREATE TABLE "glyph" ("#, r#""image" aspect"#, r#")"#,].join(" ") + ); +} + +#[test] +fn create_5() { + assert_eq!( + Table::create() + .table(Glyph::Table) + .col(ColumnDef::new(Glyph::Image).json()) + .col(ColumnDef::new(Glyph::Aspect).json_binary()) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "glyph" ("#, + r#""image" json,"#, + r#""aspect" jsonb"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_6() { + assert_eq!( + Table::create() + .table(Glyph::Table) + .col( + ColumnDef::new(Glyph::Id) + .integer() + .not_null() + .extra("ANYTHING I WANT TO SAY".to_owned()) + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "glyph" ("#, + r#""id" integer NOT NULL ANYTHING I WANT TO SAY"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_7() { + assert_eq!( + Table::create() + .table(Glyph::Table) + .col( + ColumnDef::new(Glyph::Aspect) + .interval(None, None) + .not_null() + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "glyph" ("#, + r#""aspect" interval NOT NULL"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_8() { + assert_eq!( + Table::create() + .table(Glyph::Table) + .col( + ColumnDef::new(Glyph::Aspect) + .interval(Some(PgInterval::YearToMonth), None) + .not_null() + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "glyph" ("#, + r#""aspect" interval YEAR TO MONTH NOT NULL"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_9() { + assert_eq!( + Table::create() + .table(Glyph::Table) + .col( + ColumnDef::new(Glyph::Aspect) + .interval(None, Some(42)) + .not_null() + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "glyph" ("#, + r#""aspect" interval(42) NOT NULL"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_10() { + assert_eq!( + Table::create() + .table(Glyph::Table) + .col( + ColumnDef::new(Glyph::Aspect) + .interval(Some(PgInterval::Hour), Some(43)) + .not_null() + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "glyph" ("#, + r#""aspect" interval HOUR(43) NOT NULL"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn create_11() { + assert_eq!( + Table::create() + .table(Char::Table) + .col( + ColumnDef::new(Char::CreatedAt) + .timestamp_with_time_zone_len(0) + .not_null() + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"CREATE TABLE "character" ("#, + r#""created_at" timestamp(0) with time zone NOT NULL"#, + r#")"#, + ] + .join(" ") + ); +} + +#[test] +fn drop_1() { + assert_eq!( + Table::drop() + .table(Glyph::Table) + .table(Char::Table) + .cascade() + .to_string(PostgresQueryBuilder), + r#"DROP TABLE "glyph", "character" CASCADE"# + ); +} + +#[test] +fn truncate_1() { + assert_eq!( + Table::truncate() + .table(Font::Table) + .to_string(PostgresQueryBuilder), + r#"TRUNCATE TABLE "font""# + ); +} + +#[test] +fn alter_1() { + assert_eq!( + Table::alter() + .table(Font::Table) + .add_column( + ColumnDef::new(Alias::new("new_col")) + .integer() + .not_null() + .default(100) + ) + .to_string(PostgresQueryBuilder), + r#"ALTER TABLE "font" ADD COLUMN "new_col" integer NOT NULL DEFAULT 100"# + ); +} + +#[test] +fn alter_2() { + assert_eq!( + Table::alter() + .table(Font::Table) + .modify_column( + ColumnDef::new(Alias::new("new_col")) + .big_integer() + .default(999) + ) + .to_string(PostgresQueryBuilder), + vec![ + r#"ALTER TABLE "font""#, + r#"ALTER COLUMN "new_col" TYPE bigint,"#, + r#"ALTER COLUMN "new_col" SET DEFAULT 999"#, + ] + .join(" ") + ); +} + +#[test] +fn alter_3() { + assert_eq!( + Table::alter() + .table(Font::Table) + .rename_column(Alias::new("new_col"), Alias::new("new_column")) + .to_string(PostgresQueryBuilder), + r#"ALTER TABLE "font" RENAME COLUMN "new_col" TO "new_column""# + ); +} + +#[test] +fn alter_4() { + assert_eq!( + Table::alter() + .table(Font::Table) + .drop_column(Alias::new("new_column")) + .to_string(PostgresQueryBuilder), + r#"ALTER TABLE "font" DROP COLUMN "new_column""# + ); +} + +#[test] +fn alter_5() { + assert_eq!( + Table::rename() + .table(Font::Table, Alias::new("font_new")) + .to_string(PostgresQueryBuilder), + r#"ALTER TABLE "font" RENAME TO "font_new""# + ); +} + +#[test] +#[should_panic(expected = "No alter option found")] +fn alter_6() { + Table::alter().to_string(PostgresQueryBuilder); +} + +#[test] +fn alter_7() { + assert_eq!( + Table::alter() + .table(Font::Table) + .add_column(ColumnDef::new(Alias::new("new_col")).integer()) + .rename_column(Font::Name, Alias::new("name_new")) + .to_string(PostgresQueryBuilder), + r#"ALTER TABLE "font" ADD COLUMN "new_col" integer, RENAME COLUMN "name" TO "name_new""# + ); +} diff --git a/tests/oracle/types.rs b/tests/oracle/types.rs new file mode 100644 index 000000000..5c60cb227 --- /dev/null +++ b/tests/oracle/types.rs @@ -0,0 +1,104 @@ +use sea_query::{extension::postgres::Type, Alias, PostgresQueryBuilder}; + +use super::*; + +#[test] +fn create_1() { + assert_eq!( + Type::create() + .as_enum(Font::Table) + .values(vec![Font::Name, Font::Variant, Font::Language]) + .to_string(PostgresQueryBuilder), + r#"CREATE TYPE "font" AS ENUM ('name', 'variant', 'language')"# + ); +} + +#[test] +fn drop_1() { + assert_eq!( + Type::drop() + .if_exists() + .name(Font::Table) + .restrict() + .to_string(PostgresQueryBuilder), + r#"DROP TYPE IF EXISTS "font" RESTRICT"# + ) +} + +#[test] +fn drop_2() { + assert_eq!( + Type::drop() + .name(Font::Table) + .to_string(PostgresQueryBuilder), + r#"DROP TYPE "font""# + ); +} + +#[test] +fn drop_3() { + assert_eq!( + Type::drop() + .if_exists() + .name(Font::Table) + .cascade() + .to_string(PostgresQueryBuilder), + r#"DROP TYPE IF EXISTS "font" CASCADE"# + ); +} + +#[test] +fn alter_1() { + assert_eq!( + Type::alter() + .name(Font::Table) + .add_value(Alias::new("weight")) + .to_string(PostgresQueryBuilder), + r#"ALTER TYPE "font" ADD VALUE 'weight'"# + ) +} +#[test] +fn alter_2() { + assert_eq!( + Type::alter() + .name(Font::Table) + .add_value(Alias::new("weight")) + .before(Font::Variant) + .to_string(PostgresQueryBuilder), + r#"ALTER TYPE "font" ADD VALUE 'weight' BEFORE 'variant'"# + ) +} + +#[test] +fn alter_3() { + assert_eq!( + Type::alter() + .name(Font::Table) + .add_value(Alias::new("weight")) + .after(Font::Variant) + .to_string(PostgresQueryBuilder), + r#"ALTER TYPE "font" ADD VALUE 'weight' AFTER 'variant'"# + ) +} + +#[test] +fn alter_4() { + assert_eq!( + Type::alter() + .name(Font::Table) + .rename_to(Alias::new("typeface")) + .to_string(PostgresQueryBuilder), + r#"ALTER TYPE "font" RENAME TO 'typeface'"# + ) +} + +#[test] +fn alter_5() { + assert_eq!( + Type::alter() + .name(Font::Table) + .rename_value(Font::Variant, Font::Language) + .to_string(PostgresQueryBuilder), + r#"ALTER TYPE "font" RENAME VALUE 'variant' TO 'language'"# + ) +} From 7458d3ae0f57b777128bd40949b037dcbe6bff9a Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Tue, 26 Apr 2022 13:16:52 +0200 Subject: [PATCH 02/13] get rid of postgres for now --- Cargo.toml | 2 +- src/backend/mod.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4aa4791fd..ba00c47ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,7 @@ backend-mysql = [] backend-postgres = [] backend-sqlite = [] backend-oracle = [] -default = ["derive", "backend-mysql", "backend-postgres", "backend-sqlite", "backend-oracle"] +default = ["derive", "backend-mysql", "backend-sqlite", "backend-oracle"] derive = ["sea-query-derive"] postgres = ["bytes", "postgres-types"] postgres-chrono = ["with-chrono", "postgres-types/with-chrono-0_4"] diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 64b856e2e..83ba15591 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -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; @@ -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")] From 78e01746b5430709d8aad7f59e82291144fa96d2 Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Thu, 28 Apr 2022 00:11:57 +0200 Subject: [PATCH 03/13] select 34a done, copy-paste wip --- Cargo.toml | 7 +- src/backend/oracle/foreign_key.rs | 2 +- src/backend/oracle/index.rs | 2 +- src/backend/oracle/mod.rs | 10 +- src/backend/oracle/query.rs | 52 ++-- src/backend/oracle/table.rs | 25 +- src/backend/oracle/types.rs | 272 ++++++++++---------- src/types.rs | 9 +- tests/oracle/foreign_key.rs | 4 +- tests/oracle/index.rs | 8 +- tests/oracle/interval.rs | 64 ++--- tests/oracle/query.rs | 411 ++++++++++++------------------ tests/oracle/table.rs | 184 ++++++------- tests/oracle/types.rs | 188 +++++++------- 14 files changed, 579 insertions(+), 659 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ba00c47ae..f2da154c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,7 @@ backend-mysql = [] backend-postgres = [] backend-sqlite = [] backend-oracle = [] -default = ["derive", "backend-mysql", "backend-sqlite", "backend-oracle"] +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"] @@ -107,6 +107,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 diff --git a/src/backend/oracle/foreign_key.rs b/src/backend/oracle/foreign_key.rs index 123703570..ee38a717d 100644 --- a/src/backend/oracle/foreign_key.rs +++ b/src/backend/oracle/foreign_key.rs @@ -1,6 +1,6 @@ use super::*; -impl ForeignKeyBuilder for PostgresQueryBuilder { +impl ForeignKeyBuilder for OracleQueryBuilder { fn prepare_foreign_key_drop_statement( &self, drop: &ForeignKeyDropStatement, diff --git a/src/backend/oracle/index.rs b/src/backend/oracle/index.rs index be84ece2d..11fb88d3a 100644 --- a/src/backend/oracle/index.rs +++ b/src/backend/oracle/index.rs @@ -1,6 +1,6 @@ use super::*; -impl IndexBuilder for PostgresQueryBuilder { +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(); diff --git a/src/backend/oracle/mod.rs b/src/backend/oracle/mod.rs index bb3d93f2e..a9a4baf4e 100644 --- a/src/backend/oracle/mod.rs +++ b/src/backend/oracle/mod.rs @@ -8,19 +8,19 @@ use super::*; /// Postgres query builder. #[derive(Debug)] -pub struct PostgresQueryBuilder; +pub struct OracleQueryBuilder; -impl Default for PostgresQueryBuilder { +impl Default for OracleQueryBuilder { fn default() -> Self { Self } } -impl GenericBuilder for PostgresQueryBuilder {} +impl GenericBuilder for OracleQueryBuilder {} -impl SchemaBuilder for PostgresQueryBuilder {} +impl SchemaBuilder for OracleQueryBuilder {} -impl QuotedBuilder for PostgresQueryBuilder { +impl QuotedBuilder for OracleQueryBuilder { fn quote(&self) -> char { '"' } diff --git a/src/backend/oracle/query.rs b/src/backend/oracle/query.rs index f427a7a26..c556f1207 100644 --- a/src/backend/oracle/query.rs +++ b/src/backend/oracle/query.rs @@ -1,7 +1,7 @@ use super::*; -use crate::extension::postgres::*; +// use crate::extension::postgres::*; -impl QueryBuilder for PostgresQueryBuilder { +impl QueryBuilder for OracleQueryBuilder { fn placeholder(&self) -> (&str, bool) { ("$", true) } @@ -27,10 +27,10 @@ impl QueryBuilder for PostgresQueryBuilder { collector: &mut dyn FnMut(Value), ) { match bin_oper { - BinOper::Matches => write!(sql, "@@").unwrap(), - BinOper::Contains => write!(sql, "@>").unwrap(), - BinOper::Contained => write!(sql, "<@").unwrap(), - BinOper::Concatenate => write!(sql, "||").unwrap(), + // BinOper::Matches => write!(sql, "@@").unwrap(), + // BinOper::Contains => write!(sql, "@>").unwrap(), + // BinOper::Contained => write!(sql, "<@").unwrap(), + // BinOper::Concatenate => write!(sql, "||").unwrap(), _ => self.prepare_bin_oper_common(bin_oper, sql, collector), } } @@ -42,26 +42,26 @@ impl QueryBuilder for PostgresQueryBuilder { collector: &mut dyn FnMut(Value), ) { match function { - Function::PgFunction(function) => write!( - sql, - "{}", - match function { - PgFunction::ToTsquery => "TO_TSQUERY", - PgFunction::ToTsvector => "TO_TSVECTOR", - PgFunction::PhrasetoTsquery => "PHRASETO_TSQUERY", - PgFunction::PlaintoTsquery => "PLAINTO_TSQUERY", - PgFunction::WebsearchToTsquery => "WEBSEARCH_TO_TSQUERY", - PgFunction::TsRank => "TS_RANK", - PgFunction::TsRankCd => "TS_RANK_CD", - #[cfg(feature = "postgres-array")] - PgFunction::Any => "ANY", - #[cfg(feature = "postgres-array")] - PgFunction::Some => "SOME", - #[cfg(feature = "postgres-array")] - PgFunction::All => "ALL", - } - ) - .unwrap(), + // Function::PgFunction(function) => write!( + // sql, + // "{}", + // match function { + // PgFunction::ToTsquery => "TO_TSQUERY", + // PgFunction::ToTsvector => "TO_TSVECTOR", + // PgFunction::PhrasetoTsquery => "PHRASETO_TSQUERY", + // PgFunction::PlaintoTsquery => "PLAINTO_TSQUERY", + // PgFunction::WebsearchToTsquery => "WEBSEARCH_TO_TSQUERY", + // PgFunction::TsRank => "TS_RANK", + // PgFunction::TsRankCd => "TS_RANK_CD", + // #[cfg(feature = "postgres-array")] + // PgFunction::Any => "ANY", + // #[cfg(feature = "postgres-array")] + // PgFunction::Some => "SOME", + // #[cfg(feature = "postgres-array")] + // PgFunction::All => "ALL", + // } + // ) + // .unwrap(), _ => self.prepare_function_common(function, sql, collector), } } diff --git a/src/backend/oracle/table.rs b/src/backend/oracle/table.rs index 0cf1e1659..30ae3f3f0 100644 --- a/src/backend/oracle/table.rs +++ b/src/backend/oracle/table.rs @@ -1,6 +1,6 @@ use super::*; -impl TableBuilder for PostgresQueryBuilder { +impl TableBuilder for OracleQueryBuilder { fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut SqlWriter) { column_def.name.prepare(sql, self.quote()); @@ -76,16 +76,6 @@ impl TableBuilder for PostgresQueryBuilder { None => "time".into(), }, ColumnType::Date => "date".into(), - ColumnType::Interval(fields, precision) => { - let mut typ = "interval".to_string(); - if let Some(fields) = fields { - typ.push_str(&format!(" {}", fields)); - } - if let Some(precision) = precision { - typ.push_str(&format!("({})", precision)); - } - typ - } ColumnType::Binary(length) => match length { Some(_) | None => "bytea".into(), }, @@ -100,6 +90,17 @@ impl TableBuilder for PostgresQueryBuilder { ColumnType::Array(elem_type) => format!("{}[]", elem_type.as_ref().unwrap()), ColumnType::Custom(iden) => iden.to_string(), ColumnType::Enum(name, _) => name.into(), + _ => unimplemented!(), + // ColumnType::Interval(fields, precision) => { + // let mut typ = "interval".to_string(); + // if let Some(fields) = fields { + // typ.push_str(&format!(" {}", fields)); + // } + // if let Some(precision) = precision { + // typ.push_str(&format!("({})", precision)); + // } + // typ + // } } ) .unwrap() @@ -186,7 +187,7 @@ impl TableBuilder for PostgresQueryBuilder { } } -impl PostgresQueryBuilder { +impl OracleQueryBuilder { fn prepare_column_type_check_auto_increment( &self, column_def: &ColumnDef, diff --git a/src/backend/oracle/types.rs b/src/backend/oracle/types.rs index afae6875f..afa18fd12 100644 --- a/src/backend/oracle/types.rs +++ b/src/backend/oracle/types.rs @@ -1,137 +1,137 @@ use super::*; -use crate::extension::postgres::*; - -impl TypeBuilder for PostgresQueryBuilder { - fn prepare_type_create_statement( - &self, - create: &TypeCreateStatement, - sql: &mut SqlWriter, - collector: &mut dyn FnMut(Value), - ) { - write!(sql, "CREATE TYPE ").unwrap(); - - if let Some(name) = &create.name { - name.prepare(sql, self.quote()); - } - - if let Some(as_type) = &create.as_type { - write!(sql, " AS ").unwrap(); - self.prepare_create_as_type(as_type, sql); - } - - if !create.values.is_empty() { - write!(sql, " (").unwrap(); - - for (count, val) in create.values.iter().enumerate() { - if count > 0 { - write!(sql, ", ").unwrap(); - } - self.prepare_value(&val.to_string().into(), sql, collector); - } - - write!(sql, ")").unwrap(); - } - } - - fn prepare_type_drop_statement( - &self, - drop: &TypeDropStatement, - sql: &mut SqlWriter, - _collector: &mut dyn FnMut(Value), - ) { - write!(sql, "DROP TYPE ").unwrap(); - - if drop.if_exists { - write!(sql, "IF EXISTS ").unwrap(); - } - - for name in drop.names.iter() { - name.prepare(sql, self.quote()); - } - - if let Some(option) = &drop.option { - write!(sql, " ").unwrap(); - self.prepare_drop_type_opt(option, sql); - } - } - - fn prepare_type_alter_statement( - &self, - alter: &TypeAlterStatement, - sql: &mut SqlWriter, - collector: &mut dyn FnMut(Value), - ) { - write!(sql, "ALTER TYPE ").unwrap(); - - if let Some(name) = &alter.name { - name.prepare(sql, self.quote()); - } - - if let Some(option) = &alter.option { - self.prepare_alter_type_opt(option, sql, collector) - } - } -} - -impl PostgresQueryBuilder { - fn prepare_create_as_type(&self, as_type: &TypeAs, sql: &mut SqlWriter) { - write!( - sql, - "{}", - match as_type { - TypeAs::Enum => "ENUM", - } - ) - .unwrap() - } - - fn prepare_drop_type_opt(&self, opt: &TypeDropOpt, sql: &mut SqlWriter) { - write!( - sql, - "{}", - match opt { - TypeDropOpt::Cascade => "CASCADE", - TypeDropOpt::Restrict => "RESTRICT", - } - ) - .unwrap() - } - - fn prepare_alter_type_opt( - &self, - opt: &TypeAlterOpt, - sql: &mut SqlWriter, - collector: &mut dyn FnMut(Value), - ) { - match opt { - TypeAlterOpt::Add(value, placement) => { - write!(sql, " ADD VALUE ").unwrap(); - match placement { - Some(add_option) => match add_option { - TypeAlterAddOpt::Before(before_value) => { - self.prepare_value(&value.to_string().into(), sql, collector); - write!(sql, " BEFORE ").unwrap(); - self.prepare_value(&before_value.to_string().into(), sql, collector); - } - TypeAlterAddOpt::After(after_value) => { - self.prepare_value(&value.to_string().into(), sql, collector); - write!(sql, " AFTER ").unwrap(); - self.prepare_value(&after_value.to_string().into(), sql, collector); - } - }, - None => self.prepare_value(&value.to_string().into(), sql, collector), - } - } - TypeAlterOpt::Rename(new_name) => { - write!(sql, " RENAME TO ").unwrap(); - self.prepare_value(&new_name.to_string().into(), sql, collector); - } - TypeAlterOpt::RenameValue(existing, new_name) => { - write!(sql, " RENAME VALUE ").unwrap(); - self.prepare_value(&existing.to_string().into(), sql, collector); - write!(sql, " TO ").unwrap(); - self.prepare_value(&new_name.to_string().into(), sql, collector); - } - } - } -} +// use crate::extension::postgres::*; + +// impl TypeBuilder for OracleQueryBuilder { +// fn prepare_type_create_statement( +// &self, +// create: &TypeCreateStatement, +// sql: &mut SqlWriter, +// collector: &mut dyn FnMut(Value), +// ) { +// write!(sql, "CREATE TYPE ").unwrap(); + +// if let Some(name) = &create.name { +// name.prepare(sql, self.quote()); +// } + +// if let Some(as_type) = &create.as_type { +// write!(sql, " AS ").unwrap(); +// self.prepare_create_as_type(as_type, sql); +// } + +// if !create.values.is_empty() { +// write!(sql, " (").unwrap(); + +// for (count, val) in create.values.iter().enumerate() { +// if count > 0 { +// write!(sql, ", ").unwrap(); +// } +// self.prepare_value(&val.to_string().into(), sql, collector); +// } + +// write!(sql, ")").unwrap(); +// } +// } + +// fn prepare_type_drop_statement( +// &self, +// drop: &TypeDropStatement, +// sql: &mut SqlWriter, +// _collector: &mut dyn FnMut(Value), +// ) { +// write!(sql, "DROP TYPE ").unwrap(); + +// if drop.if_exists { +// write!(sql, "IF EXISTS ").unwrap(); +// } + +// for name in drop.names.iter() { +// name.prepare(sql, self.quote()); +// } + +// if let Some(option) = &drop.option { +// write!(sql, " ").unwrap(); +// self.prepare_drop_type_opt(option, sql); +// } +// } + +// fn prepare_type_alter_statement( +// &self, +// alter: &TypeAlterStatement, +// sql: &mut SqlWriter, +// collector: &mut dyn FnMut(Value), +// ) { +// write!(sql, "ALTER TYPE ").unwrap(); + +// if let Some(name) = &alter.name { +// name.prepare(sql, self.quote()); +// } + +// if let Some(option) = &alter.option { +// self.prepare_alter_type_opt(option, sql, collector) +// } +// } +// } + +// impl OracleQueryBuilder { +// fn prepare_create_as_type(&self, as_type: &TypeAs, sql: &mut SqlWriter) { +// write!( +// sql, +// "{}", +// match as_type { +// TypeAs::Enum => "ENUM", +// } +// ) +// .unwrap() +// } + +// fn prepare_drop_type_opt(&self, opt: &TypeDropOpt, sql: &mut SqlWriter) { +// write!( +// sql, +// "{}", +// match opt { +// TypeDropOpt::Cascade => "CASCADE", +// TypeDropOpt::Restrict => "RESTRICT", +// } +// ) +// .unwrap() +// } + +// fn prepare_alter_type_opt( +// &self, +// opt: &TypeAlterOpt, +// sql: &mut SqlWriter, +// collector: &mut dyn FnMut(Value), +// ) { +// match opt { +// TypeAlterOpt::Add(value, placement) => { +// write!(sql, " ADD VALUE ").unwrap(); +// match placement { +// Some(add_option) => match add_option { +// TypeAlterAddOpt::Before(before_value) => { +// self.prepare_value(&value.to_string().into(), sql, collector); +// write!(sql, " BEFORE ").unwrap(); +// self.prepare_value(&before_value.to_string().into(), sql, collector); +// } +// TypeAlterAddOpt::After(after_value) => { +// self.prepare_value(&value.to_string().into(), sql, collector); +// write!(sql, " AFTER ").unwrap(); +// self.prepare_value(&after_value.to_string().into(), sql, collector); +// } +// }, +// None => self.prepare_value(&value.to_string().into(), sql, collector), +// } +// } +// TypeAlterOpt::Rename(new_name) => { +// write!(sql, " RENAME TO ").unwrap(); +// self.prepare_value(&new_name.to_string().into(), sql, collector); +// } +// TypeAlterOpt::RenameValue(existing, new_name) => { +// write!(sql, " RENAME VALUE ").unwrap(); +// self.prepare_value(&existing.to_string().into(), sql, collector); +// write!(sql, " TO ").unwrap(); +// self.prepare_value(&new_name.to_string().into(), sql, collector); +// } +// } +// } +// } diff --git a/src/types.rs b/src/types.rs index e049d7870..44805f302 100644 --- a/src/types.rs +++ b/src/types.rs @@ -392,7 +392,7 @@ mod tests { ); #[cfg(feature = "backend-postgres")] assert_eq!( - query.to_string(PostgresQueryBuilder), + query.to_string(OracleQueryBuilder), r#"SELECT "hello-World_""# ); #[cfg(feature = "backend-sqlite")] @@ -414,7 +414,7 @@ mod tests { let query = Query::select().column(Alias::new("hel\"lo")).to_owned(); #[cfg(feature = "backend-postgres")] - assert_eq!(query.to_string(PostgresQueryBuilder), r#"SELECT "hel""lo""#); + assert_eq!(query.to_string(OracleQueryBuilder), r#"SELECT "hel""lo""#); } #[test] @@ -429,9 +429,6 @@ mod tests { let query = Query::select().column(Alias::new("hel\"\"lo")).to_owned(); #[cfg(feature = "backend-postgres")] - assert_eq!( - query.to_string(PostgresQueryBuilder), - r#"SELECT "hel""""lo""# - ); + assert_eq!(query.to_string(OracleQueryBuilder), r#"SELECT "hel""""lo""#); } } diff --git a/tests/oracle/foreign_key.rs b/tests/oracle/foreign_key.rs index 1710553a3..d0f523302 100644 --- a/tests/oracle/foreign_key.rs +++ b/tests/oracle/foreign_key.rs @@ -9,7 +9,7 @@ fn create_1() { .to(Font::Table, Font::Id) .on_delete(ForeignKeyAction::Cascade) .on_update(ForeignKeyAction::Cascade) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![ r#"ALTER TABLE "character" ADD CONSTRAINT "FK_2e303c3a712662f1fc2a4d0aad6""#, r#"FOREIGN KEY ("font_id") REFERENCES "font" ("id")"#, @@ -25,7 +25,7 @@ fn drop_1() { ForeignKey::drop() .name("FK_2e303c3a712662f1fc2a4d0aad6") .table(Char::Table) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"ALTER TABLE "character" DROP CONSTRAINT "FK_2e303c3a712662f1fc2a4d0aad6""# ); } diff --git a/tests/oracle/index.rs b/tests/oracle/index.rs index 13cc341bb..fd48ae1b0 100644 --- a/tests/oracle/index.rs +++ b/tests/oracle/index.rs @@ -7,7 +7,7 @@ fn create_1() { .name("idx-glyph-aspect") .table(Glyph::Table) .col(Glyph::Aspect) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"CREATE INDEX "idx-glyph-aspect" ON "glyph" ("aspect")"# ); } @@ -21,7 +21,7 @@ fn create_2() { .table(Glyph::Table) .col(Glyph::Aspect) .col(Glyph::Image) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"CREATE UNIQUE INDEX "idx-glyph-aspect-image" ON "glyph" ("aspect", "image")"# ); } @@ -34,7 +34,7 @@ fn create_3() { .name("idx-glyph-image") .table(Glyph::Table) .col(Glyph::Image) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"CREATE INDEX "idx-glyph-image" ON "glyph" USING GIN ("image")"# ); } @@ -44,7 +44,7 @@ fn drop_1() { assert_eq!( Index::drop() .name("idx-glyph-aspect") - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"DROP INDEX "idx-glyph-aspect""# ); } diff --git a/tests/oracle/interval.rs b/tests/oracle/interval.rs index a25c791f3..20d01c121 100644 --- a/tests/oracle/interval.rs +++ b/tests/oracle/interval.rs @@ -1,35 +1,35 @@ use quote::{quote, ToTokens}; use sea_query::*; -#[test] -fn with_quote_1() { - for (interval_field, token_stream) in [ - (PgInterval::Year, quote! { PgInterval::Year }), - (PgInterval::Month, quote! { PgInterval::Month }), - (PgInterval::Day, quote! { PgInterval::Day }), - (PgInterval::Hour, quote! { PgInterval::Hour }), - (PgInterval::Minute, quote! { PgInterval::Minute }), - (PgInterval::Second, quote! { PgInterval::Second }), - (PgInterval::YearToMonth, quote! { PgInterval::YearToMonth }), - (PgInterval::DayToHour, quote! { PgInterval::DayToHour }), - (PgInterval::DayToMinute, quote! { PgInterval::DayToMinute }), - (PgInterval::DayToSecond, quote! { PgInterval::DayToSecond }), - ( - PgInterval::HourToMinute, - quote! { PgInterval::HourToMinute }, - ), - ( - PgInterval::HourToSecond, - quote! { PgInterval::HourToSecond }, - ), - ( - PgInterval::MinuteToSecond, - quote! { PgInterval::MinuteToSecond }, - ), - ] { - assert_eq!( - interval_field.into_token_stream().to_string(), - token_stream.to_string() - ); - } -} +// #[test] +// fn with_quote_1() { +// for (interval_field, token_stream) in [ +// (PgInterval::Year, quote! { PgInterval::Year }), +// (PgInterval::Month, quote! { PgInterval::Month }), +// (PgInterval::Day, quote! { PgInterval::Day }), +// (PgInterval::Hour, quote! { PgInterval::Hour }), +// (PgInterval::Minute, quote! { PgInterval::Minute }), +// (PgInterval::Second, quote! { PgInterval::Second }), +// (PgInterval::YearToMonth, quote! { PgInterval::YearToMonth }), +// (PgInterval::DayToHour, quote! { PgInterval::DayToHour }), +// (PgInterval::DayToMinute, quote! { PgInterval::DayToMinute }), +// (PgInterval::DayToSecond, quote! { PgInterval::DayToSecond }), +// ( +// PgInterval::HourToMinute, +// quote! { PgInterval::HourToMinute }, +// ), +// ( +// PgInterval::HourToSecond, +// quote! { PgInterval::HourToSecond }, +// ), +// ( +// PgInterval::MinuteToSecond, +// quote! { PgInterval::MinuteToSecond }, +// ), +// ] { +// assert_eq!( +// interval_field.into_token_stream().to_string(), +// token_stream.to_string() +// ); +// } +// } diff --git a/tests/oracle/query.rs b/tests/oracle/query.rs index 532c0ffa0..0e8b9aae8 100644 --- a/tests/oracle/query.rs +++ b/tests/oracle/query.rs @@ -9,8 +9,8 @@ fn select_1() { .from(Char::Table) .limit(10) .offset(100) - .to_string(PostgresQueryBuilder), - r#"SELECT "character", "size_w", "size_h" FROM "character" LIMIT 10 OFFSET 100"# + .to_string(OracleQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" OFFSET 100 ROWS FETCH NEXT 10 ROWS ONLY"# ); } @@ -21,7 +21,7 @@ fn select_2() { .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) .from(Char::Table) .and_where(Expr::col(Char::SizeW).eq(3)) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3"# ); } @@ -34,8 +34,8 @@ fn select_3() { .from(Char::Table) .and_where(Expr::col(Char::SizeW).eq(3)) .and_where(Expr::col(Char::SizeH).eq(4)) - .to_string(PostgresQueryBuilder), - r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3 AND "size_h" = 4"# + .to_string(OracleQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" = 3 AND "size_h" = 4)"# ); } @@ -51,8 +51,8 @@ fn select_4() { .take(), Alias::new("subglyph") ) - .to_string(PostgresQueryBuilder), - r#"SELECT "aspect" FROM (SELECT "image", "aspect" FROM "glyph") AS "subglyph""# + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM (SELECT "image", "aspect" FROM "glyph") "subglyph""# ); } @@ -63,7 +63,7 @@ fn select_5() { .column((Glyph::Table, Glyph::Image)) .from(Glyph::Table) .and_where(Expr::tbl(Glyph::Table, Glyph::Aspect).is_in(vec![3, 4])) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "glyph"."image" FROM "glyph" WHERE "glyph"."aspect" IN (3, 4)"# ); } @@ -77,8 +77,8 @@ fn select_6() { .from(Glyph::Table) .group_by_columns(vec![Glyph::Aspect,]) .and_having(Expr::col(Glyph::Aspect).gt(2)) - .to_string(PostgresQueryBuilder), - r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# + .to_string(OracleQueryBuilder), + r#"SELECT "aspect", max("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# ); } @@ -89,8 +89,8 @@ fn select_7() { .columns(vec![Glyph::Aspect,]) .from(Glyph::Table) .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) - .to_string(PostgresQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2"# + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2"# ); } @@ -104,8 +104,8 @@ fn select_8() { Font::Table, Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id) ) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" FROM "character" LEFT JOIN "font" ON "character"."font_id" = "font"."id""# + .to_string(OracleQueryBuilder), + r#"SELECT "character" FROM "character" LEFT OUTER JOIN "font" ON "character"."font_id" = "font"."id""# ); } @@ -123,8 +123,8 @@ fn select_9() { Glyph::Table, Expr::tbl(Char::Table, Char::Character).equals(Glyph::Table, Glyph::Image) ) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" FROM "character" LEFT JOIN "font" ON "character"."font_id" = "font"."id" INNER JOIN "glyph" ON "character"."character" = "glyph"."image""# + .to_string(OracleQueryBuilder), + r#"SELECT "character" FROM "character" LEFT OUTER JOIN "font" ON "character"."font_id" = "font"."id" JOIN "glyph" ON "character"."character" = "glyph"."image""# ); } @@ -140,8 +140,8 @@ fn select_10() { .equals(Font::Table, Font::Id) .and(Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id)) ) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" FROM "character" LEFT JOIN "font" ON ("character"."font_id" = "font"."id") AND ("character"."font_id" = "font"."id")"# + .to_string(OracleQueryBuilder), + r#"SELECT "character" FROM "character" LEFT OUTER JOIN "font" ON ("character"."font_id" = "font"."id" AND "character"."font_id" = "font"."id")"# ); } @@ -154,8 +154,8 @@ fn select_11() { .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) .order_by(Glyph::Image, Order::Desc) .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) - .to_string(PostgresQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "image" DESC, "glyph"."aspect" ASC"# + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "image" DESC, "glyph"."aspect" ASC"# ); } @@ -167,8 +167,8 @@ fn select_12() { .from(Glyph::Table) .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) .order_by_columns(vec![(Glyph::Id, Order::Asc), (Glyph::Aspect, Order::Desc),]) - .to_string(PostgresQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "id" ASC, "aspect" DESC"# + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "id" ASC, "aspect" DESC"# ); } @@ -183,8 +183,8 @@ fn select_13() { ((Glyph::Table, Glyph::Id), Order::Asc), ((Glyph::Table, Glyph::Aspect), Order::Desc), ]) - .to_string(PostgresQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."id" ASC, "glyph"."aspect" DESC"# + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "glyph"."id" ASC, "glyph"."aspect" DESC"# ); } @@ -200,8 +200,8 @@ fn select_14() { (Glyph::Table, Glyph::Aspect), ]) .and_having(Expr::col(Glyph::Aspect).gt(2)) - .to_string(PostgresQueryBuilder), - r#"SELECT "id", "aspect", MAX("image") FROM "glyph" GROUP BY "glyph"."id", "glyph"."aspect" HAVING "aspect" > 2"# + .to_string(OracleQueryBuilder), + r#"SELECT "id", "aspect", max("image") FROM "glyph" GROUP BY "glyph"."id", "glyph"."aspect" HAVING "aspect" > 2"# ); } @@ -212,7 +212,7 @@ fn select_15() { .columns(vec![Char::Character]) .from(Char::Table) .and_where(Expr::col(Char::FontId).is_null()) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "character" FROM "character" WHERE "font_id" IS NULL"# ); } @@ -225,8 +225,8 @@ fn select_16() { .from(Char::Table) .and_where(Expr::col(Char::FontId).is_null()) .and_where(Expr::col(Char::Character).is_not_null()) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" FROM "character" WHERE "font_id" IS NULL AND "character" IS NOT NULL"# + .to_string(OracleQueryBuilder), + r#"SELECT "character" FROM "character" WHERE ("font_id" IS NULL AND "character" IS NOT NULL)"# ); } @@ -237,7 +237,7 @@ fn select_17() { .columns(vec![(Glyph::Table, Glyph::Image),]) .from(Glyph::Table) .and_where(Expr::tbl(Glyph::Table, Glyph::Aspect).between(3, 5)) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "glyph"."image" FROM "glyph" WHERE "glyph"."aspect" BETWEEN 3 AND 5"# ); } @@ -250,8 +250,8 @@ fn select_18() { .from(Glyph::Table) .and_where(Expr::col(Glyph::Aspect).between(3, 5)) .and_where(Expr::col(Glyph::Aspect).not_between(8, 10)) - .to_string(PostgresQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE ("aspect" BETWEEN 3 AND 5) AND ("aspect" NOT BETWEEN 8 AND 10)"# + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE ("aspect" BETWEEN 3 AND 5 AND "aspect" NOT BETWEEN 8 AND 10)"# ); } @@ -262,7 +262,7 @@ fn select_19() { .columns(vec![Char::Character]) .from(Char::Table) .and_where(Expr::col(Char::Character).eq("A")) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "character" FROM "character" WHERE "character" = 'A'"# ); } @@ -274,7 +274,7 @@ fn select_20() { .column(Char::Character) .from(Char::Table) .and_where(Expr::col(Char::Character).like("A")) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "character" FROM "character" WHERE "character" LIKE 'A'"# ); } @@ -288,8 +288,8 @@ fn select_21() { .or_where(Expr::col(Char::Character).like("A%")) .or_where(Expr::col(Char::Character).like("%B")) .or_where(Expr::col(Char::Character).like("%C%")) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" FROM "character" WHERE "character" LIKE 'A%' OR "character" LIKE '%B' OR "character" LIKE '%C%'"# + .to_string(OracleQueryBuilder), + r#"SELECT "character" FROM "character" WHERE ("character" LIKE 'A%' OR "character" LIKE '%B' OR "character" LIKE '%C%')"# ); } @@ -314,8 +314,8 @@ fn select_22() { .or(Expr::col(Char::Character).like("G")) ) ) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" FROM "character" WHERE ("character" LIKE 'C' OR (("character" LIKE 'D') AND ("character" LIKE 'E'))) AND (("character" LIKE 'F') OR ("character" LIKE 'G'))"# + .to_string(OracleQueryBuilder), + r#"SELECT "character" FROM "character" WHERE (("character" LIKE 'C' OR ("character" LIKE 'D' AND "character" LIKE 'E')) AND ("character" LIKE 'F' OR "character" LIKE 'G'))"# ); } @@ -326,7 +326,7 @@ fn select_23() { .column(Char::Character) .from(Char::Table) .and_where_option(None) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "character" FROM "character""# ); } @@ -344,7 +344,7 @@ fn select_24() { }, |_| () ) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "character" FROM "character" WHERE "font_id" = 5"# ); } @@ -360,26 +360,26 @@ fn select_25() { .mul(2) .equals(Expr::col(Char::SizeH).div(2)) ) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" FROM "character" WHERE "size_w" * 2 = "size_h" / 2"# + .to_string(OracleQueryBuilder), + r#"SELECT "character" FROM "character" WHERE ("size_w" * 2) = ("size_h" / 2)"# ); } -#[test] -fn select_26() { - assert_eq!( - Query::select() - .column(Char::Character) - .from(Char::Table) - .and_where( - Expr::expr(Expr::col(Char::SizeW).add(1)) - .mul(2) - .equals(Expr::expr(Expr::col(Char::SizeH).div(2)).sub(1)) - ) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" FROM "character" WHERE ("size_w" + 1) * 2 = ("size_h" / 2) - 1"# - ); -} +// #[test] +// fn select_26() { +// assert_eq!( +// Query::select() +// .column(Char::Character) +// .from(Char::Table) +// .and_where( +// Expr::expr(Expr::col(Char::SizeW).add(1)) +// .mul(2) +// .equals(Expr::expr(Expr::col(Char::SizeH).div(2)).sub(1)) +// ) +// .to_string(OracleQueryBuilder), +// r#"SELECT "character" FROM "character" WHERE ("size_w" + 1) * 2 = ("size_h" / 2) - 1"# +// ); +// } #[test] fn select_27() { @@ -390,8 +390,8 @@ fn select_27() { .and_where(Expr::col(Char::SizeW).eq(3)) .and_where(Expr::col(Char::SizeH).eq(4)) .and_where(Expr::col(Char::SizeH).eq(5)) - .to_string(PostgresQueryBuilder), - r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3 AND "size_h" = 4 AND "size_h" = 5"# + .to_string(OracleQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" = 3 AND "size_h" = 4 AND "size_h" = 5)"# ); } @@ -404,8 +404,8 @@ fn select_28() { .or_where(Expr::col(Char::SizeW).eq(3)) .or_where(Expr::col(Char::SizeH).eq(4)) .or_where(Expr::col(Char::SizeH).eq(5)) - .to_string(PostgresQueryBuilder), - r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3 OR "size_h" = 4 OR "size_h" = 5"# + .to_string(OracleQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" = 3 OR "size_h" = 4 OR "size_h" = 5)"# ); } @@ -419,37 +419,37 @@ fn select_29() { .and_where(Expr::col(Char::SizeW).eq(3)) .or_where(Expr::col(Char::SizeH).eq(4)) .and_where(Expr::col(Char::SizeH).eq(5)) - .to_string(PostgresQueryBuilder), - r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" = 3 OR "size_h" = 4 AND "size_h" = 5"# - ); -} - -#[test] -fn select_30() { - assert_eq!( - Query::select() - .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) - .from(Char::Table) - .and_where( - Expr::col(Char::SizeW) - .mul(2) - .add(Expr::col(Char::SizeH).div(3)) - .equals(Expr::value(4)) - ) - .to_string(PostgresQueryBuilder), - r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" * 2) + ("size_h" / 3) = 4"# - ); -} - -#[test] -fn select_31() { - assert_eq!( - Query::select() - .expr((1..10_i32).fold(Expr::value(0), |expr, i| { expr.add(Expr::value(i)) })) - .to_string(PostgresQueryBuilder), - r#"SELECT 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9"# - ); -} + .to_string(OracleQueryBuilder), + r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" = 3 OR ("size_h" = 4 AND "size_h" = 5))"# + ); +} + +// #[test] +// fn select_30() { +// assert_eq!( +// Query::select() +// .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) +// .from(Char::Table) +// .and_where( +// Expr::col(Char::SizeW) +// .mul(2) +// .add(Expr::col(Char::SizeH).div(3)) +// .equals(Expr::value(4)) +// ) +// .to_string(OracleQueryBuilder), +// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" * 2) + ("size_h" / 3) = 4"# +// ); +// } + +// #[test] +// fn select_31() { +// assert_eq!( +// Query::select() +// .expr((1..10_i32).fold(Expr::value(0), |expr, i| { expr.add(Expr::value(i)) })) +// .to_string(OracleQueryBuilder), +// r#"SELECT 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9"# +// ); +// } #[test] fn select_32() { @@ -457,25 +457,25 @@ fn select_32() { Query::select() .expr_as(Expr::col(Char::Character), Alias::new("C")) .from(Char::Table) - .to_string(PostgresQueryBuilder), - r#"SELECT "character" AS "C" FROM "character""# + .to_string(OracleQueryBuilder), + r#"SELECT "character" "C" FROM "character""# ); } -#[test] -fn select_33() { - assert_eq!( - Query::select() - .column(Glyph::Image) - .from(Glyph::Table) - .and_where( - Expr::col(Glyph::Aspect) - .in_subquery(Query::select().expr(Expr::cust("3 + 2 * 2")).take()) - ) - .to_string(PostgresQueryBuilder), - r#"SELECT "image" FROM "glyph" WHERE "aspect" IN (SELECT 3 + 2 * 2)"# - ); -} +// #[test] +// fn select_33() { +// assert_eq!( +// Query::select() +// .column(Glyph::Image) +// .from(Glyph::Table) +// .and_where( +// Expr::col(Glyph::Aspect) +// .in_subquery(Query::select().expr(Expr::cust("3 + 2 * 2")).take()) +// ) +// .to_string(OracleQueryBuilder), +// r#"SELECT "image" FROM "glyph" WHERE "aspect" IN (SELECT 3 + 2 * 2)"# +// ); +// } #[test] fn select_34a() { @@ -496,14 +496,8 @@ fn select_34a() { .and(Expr::col(Glyph::Aspect).lt(18)) ) .or_having(Expr::col(Glyph::Aspect).gt(32)) - .to_string(PostgresQueryBuilder), - vec![ - r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect""#, - r#"HAVING (("aspect" > 2) OR ("aspect" < 8))"#, - r#"OR (("aspect" > 12) AND ("aspect" < 18))"#, - r#"OR "aspect" > 32"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"SELECT "aspect", max("image") FROM "glyph" GROUP BY "aspect" HAVING ("aspect" > 2 OR "aspect" < 8 OR ("aspect" > 12 AND "aspect" < 18) OR "aspect" > 32)"#, ); } @@ -526,13 +520,8 @@ fn select_34b() { .gt(22) .or(Expr::col(Glyph::Aspect).lt(28)) ) - .to_string(PostgresQueryBuilder), - vec![ - r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect""#, - r#"HAVING (("aspect" > 2) OR ("aspect" < 8))"#, - r#"AND (("aspect" > 22) OR ("aspect" < 28))"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING (("aspect" > 2) OR ("aspect" < 8)) AND (("aspect" > 22) OR ("aspect" < 28))"#, ); } @@ -542,7 +531,7 @@ fn select_35() { .column(Glyph::Id) .from(Glyph::Table) .and_where(Expr::col(Glyph::Aspect).is_null()) - .build(sea_query::PostgresQueryBuilder); + .build(sea_query::OracleQueryBuilder); assert_eq!( statement, @@ -557,7 +546,7 @@ fn select_36() { .column(Glyph::Id) .from(Glyph::Table) .cond_where(Cond::any().add(Expr::col(Glyph::Aspect).is_null())) - .build(sea_query::PostgresQueryBuilder); + .build(sea_query::OracleQueryBuilder); assert_eq!( statement, @@ -572,7 +561,7 @@ fn select_37() { .column(Glyph::Id) .from(Glyph::Table) .cond_where(Cond::any().add(Cond::all()).add(Cond::any())) - .build(sea_query::PostgresQueryBuilder); + .build(sea_query::OracleQueryBuilder); assert_eq!(statement, r#"SELECT "id" FROM "glyph""#); assert_eq!(values.0, vec![]); @@ -588,7 +577,7 @@ fn select_38() { .add(Expr::col(Glyph::Aspect).is_null()) .add(Expr::col(Glyph::Aspect).is_not_null()), ) - .build(sea_query::PostgresQueryBuilder); + .build(sea_query::OracleQueryBuilder); assert_eq!( statement, @@ -607,7 +596,7 @@ fn select_39() { .add(Expr::col(Glyph::Aspect).is_null()) .add(Expr::col(Glyph::Aspect).is_not_null()), ) - .build(sea_query::PostgresQueryBuilder); + .build(sea_query::OracleQueryBuilder); assert_eq!( statement, @@ -628,7 +617,7 @@ fn select_40() { Expr::col(Glyph::Aspect).lt(8) ] ]) - .to_string(sea_query::PostgresQueryBuilder); + .to_string(sea_query::OracleQueryBuilder); assert_eq!( statement, @@ -645,7 +634,7 @@ fn select_41() { .from(Glyph::Table) .group_by_columns(vec![Glyph::Aspect]) .cond_having(any![Expr::col(Glyph::Aspect).gt(2)]) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# ); } @@ -660,7 +649,7 @@ fn select_42() { .add_option(Some(Expr::col(Glyph::Aspect).lt(8))) .add(Expr::col(Glyph::Aspect).is_not_null()), ) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!( statement, @@ -674,7 +663,7 @@ fn select_43() { .column(Glyph::Id) .from(Glyph::Table) .cond_where(Cond::all().add_option::(None)) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!(statement, r#"SELECT "id" FROM "glyph""#); } @@ -689,7 +678,7 @@ fn select_44() { .not() .add_option(Some(Expr::col(Glyph::Aspect).lt(8))), ) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!( statement, @@ -708,7 +697,7 @@ fn select_45() { .add_option(Some(Expr::col(Glyph::Aspect).lt(8))) .add(Expr::col(Glyph::Aspect).is_not_null()), ) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!( statement, @@ -726,7 +715,7 @@ fn select_46() { .not() .add_option(Some(Expr::col(Glyph::Aspect).lt(8))), ) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!( statement, @@ -745,7 +734,7 @@ fn select_47() { .add_option(Some(Expr::col(Glyph::Aspect).lt(8))) .add(Expr::col(Glyph::Aspect).is_not_null()), ) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!( statement, @@ -767,7 +756,7 @@ fn select_48() { .less_than(Expr::tuple([Expr::value(8), Expr::value(100)])), ))), ) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!( statement, @@ -780,7 +769,7 @@ fn select_49() { let statement = sea_query::Query::select() .expr(Expr::asterisk()) .from(Char::Table) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!(statement, r#"SELECT * FROM "character""#); } @@ -795,7 +784,7 @@ fn select_50() { Font::Table, Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id), ) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!( statement, @@ -816,15 +805,8 @@ fn select_51() { Order::Asc, NullOrdering::Last ) - .to_string(PostgresQueryBuilder), - [ - r#"SELECT "aspect""#, - r#"FROM "glyph""#, - r#"WHERE COALESCE("aspect", 0) > 2"#, - r#"ORDER BY "image" DESC NULLS FIRST,"#, - r#""glyph"."aspect" ASC NULLS LAST"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "image" DESC NULLS FIRST, "glyph"."aspect" ASC NULLS LAST"#, ); } @@ -839,15 +821,8 @@ fn select_52() { (Glyph::Id, Order::Asc, NullOrdering::First), (Glyph::Aspect, Order::Desc, NullOrdering::Last), ]) - .to_string(PostgresQueryBuilder), - [ - r#"SELECT "aspect""#, - r#"FROM "glyph""#, - r#"WHERE COALESCE("aspect", 0) > 2"#, - r#"ORDER BY "id" ASC NULLS FIRST,"#, - r#""aspect" DESC NULLS LAST"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "id" ASC NULLS FIRST, "aspect" DESC NULLS LAST"#, ); } @@ -866,15 +841,8 @@ fn select_53() { NullOrdering::Last ), ]) - .to_string(PostgresQueryBuilder), - [ - r#"SELECT "aspect""#, - r#"FROM "glyph""#, - r#"WHERE COALESCE("aspect", 0) > 2"#, - r#"ORDER BY "glyph"."id" ASC NULLS FIRST,"#, - r#""glyph"."aspect" DESC NULLS LAST"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."id" ASC NULLS FIRST, "glyph"."aspect" DESC NULLS LAST"#, ); } @@ -885,7 +853,7 @@ fn select_54() { .from(Char::Table) .from(Font::Table) .and_where(Expr::tbl(Font::Table, Font::Id).equals(Char::Table, Char::FontId)) - .to_string(PostgresQueryBuilder); + .to_string(OracleQueryBuilder); assert_eq!( statement, @@ -910,20 +878,8 @@ fn select_55() { ])) ) .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) - .to_string(PostgresQueryBuilder), - [ - r#"SELECT "aspect""#, - r#"FROM "glyph""#, - r#"WHERE COALESCE("aspect", 0) > 2"#, - r#"ORDER BY CASE"#, - r#"WHEN "id"=4 THEN 0"#, - r#"WHEN "id"=5 THEN 1"#, - r#"WHEN "id"=1 THEN 2"#, - r#"WHEN "id"=3 THEN 3"#, - r#"ELSE 4 END,"#, - r#""glyph"."aspect" ASC"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY CASE WHEN "id"=4 THEN 0 WHEN "id"=5 THEN 1 WHEN "id"=1 THEN 2 WHEN "id"=3 THEN 3 ELSE 4 END, "glyph"."aspect" ASC"# ); } @@ -944,19 +900,8 @@ fn select_56() { Value::Int(Some(3)) ])) ) - .to_string(PostgresQueryBuilder), - [ - r#"SELECT "aspect""#, - r#"FROM "glyph""#, - r#"WHERE COALESCE("aspect", 0) > 2"#, - r#"ORDER BY "glyph"."aspect" ASC,"#, - r#"CASE WHEN "id"=4 THEN 0"#, - r#"WHEN "id"=5 THEN 1"#, - r#"WHEN "id"=1 THEN 2"#, - r#"WHEN "id"=3 THEN 3"#, - r#"ELSE 4 END"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."aspect" ASC, CASE WHEN "id"=4 THEN 0 WHEN "id"=5 THEN 1 WHEN "id"=1 THEN 2 WHEN "id"=3 THEN 3 ELSE 4 END"#, ); } @@ -976,14 +921,8 @@ fn select_57() { .from(Alias::new("cte")) .to_owned(); assert_eq!( - select.with(with_clause).to_string(PostgresQueryBuilder), - [ - r#"WITH "cte" AS"#, - r#"(SELECT "id", "image", "aspect""#, - r#"FROM "glyph")"#, - r#"SELECT "id", "image", "aspect" FROM "cte""#, - ] - .join(" ") + select.with(with_clause).to_string(OracleQueryBuilder), + r#"WITH "cte" AS (SELECT "id", "image", "aspect" FROM "glyph") SELECT "id", "image", "aspect" FROM "cte""#, ); } @@ -1007,7 +946,7 @@ fn select_58() { .to_owned(); assert_eq!( - query.to_string(PostgresQueryBuilder), + query.to_string(OracleQueryBuilder), r#"SELECT (CASE WHEN ("glyph"."aspect" > 0) THEN 'positive' WHEN ("glyph"."aspect" < 0) THEN 'negative' ELSE 'zero' END) AS "polarity" FROM "glyph""# ); } @@ -1023,7 +962,7 @@ fn insert_2() { "04108048005887010020060000204E0180400400".into(), 3.1415.into(), ]) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"INSERT INTO "glyph" ("image", "aspect") VALUES ('04108048005887010020060000204E0180400400', 3.1415)"# ); } @@ -1040,7 +979,7 @@ fn insert_3() { 3.1415.into(), ]) .values_panic(vec![Value::String(None), 2.1345.into(),]) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"INSERT INTO "glyph" ("image", "aspect") VALUES ('04108048005887010020060000204E0180400400', 3.1415), (NULL, 2.1345)"# ); } @@ -1053,7 +992,7 @@ fn insert_4() { .into_table(Glyph::Table) .columns(vec![Glyph::Image]) .values_panic(vec![chrono::NaiveDateTime::from_timestamp(0, 0).into()]) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), "INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')" ); } @@ -1069,7 +1008,7 @@ fn insert_9() { .values_panic(vec![date!(1970 - 01 - 01) .with_time(time!(00:00:00)) .into()]) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), "INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')" ); } @@ -1082,7 +1021,7 @@ fn insert_5() { .into_table(Glyph::Table) .columns(vec![Glyph::Image]) .values_panic(vec![uuid::Uuid::nil().into()]) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), "INSERT INTO \"glyph\" (\"image\") VALUES ('00000000-0000-0000-0000-000000000000')" ); } @@ -1111,7 +1050,7 @@ fn insert_from_select() { ) .unwrap() .to_owned() - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '%'"# ); } @@ -1139,13 +1078,10 @@ fn insert_6() -> sea_query::error::Result<()> { .into_table(Glyph::Table) .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) .select_from(select)?; - let sql = insert.with(with_clause).to_string(PostgresQueryBuilder); + let sql = insert.with(with_clause).to_string(OracleQueryBuilder); assert_eq!( sql.as_str(), - [ - r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph")"#, - r#"INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#, - ].join(" ") + r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#, ); Ok(()) } @@ -1166,13 +1102,8 @@ fn insert_on_conflict_1() { .update_column(Glyph::Aspect) .to_owned() ) - .to_string(PostgresQueryBuilder), - [ - r#"INSERT INTO "glyph" ("aspect", "image")"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON CONFLICT ("id") DO UPDATE SET "aspect" = "excluded"."aspect""#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id") DO UPDATE SET "aspect" = "excluded"."aspect""#, ); } @@ -1192,13 +1123,8 @@ fn insert_on_conflict_2() { .update_columns([Glyph::Aspect, Glyph::Image]) .to_owned() ) - .to_string(PostgresQueryBuilder), - [ - r#"INSERT INTO "glyph" ("aspect", "image")"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = "excluded"."aspect", "image" = "excluded"."image""#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = "excluded"."aspect", "image" = "excluded"."image""#, ); } @@ -1216,18 +1142,16 @@ fn insert_on_conflict_3() { .on_conflict( OnConflict::columns([Glyph::Id, Glyph::Aspect]) .update_values([ - (Glyph::Aspect, "04108048005887010020060000204E0180400400".into()), + ( + Glyph::Aspect, + "04108048005887010020060000204E0180400400".into() + ), (Glyph::Image, 3.1415.into()), ]) .to_owned() ) - .to_string(PostgresQueryBuilder), - [ - r#"INSERT INTO "glyph" ("aspect", "image")"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = '04108048005887010020060000204E0180400400', "image" = 3.1415"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = '04108048005887010020060000204E0180400400', "image" = 3.1415"#, ); } @@ -1247,13 +1171,8 @@ fn insert_on_conflict_4() { .update_expr((Glyph::Image, Expr::val(1).add(2))) .to_owned() ) - .to_string(PostgresQueryBuilder), - [ - r#"INSERT INTO "glyph" ("aspect", "image")"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON CONFLICT ("id", "aspect") DO UPDATE SET "image" = 1 + 2"#, - ] - .join(" ") + .to_string(OracleQueryBuilder), + r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "image" = 1 + 2"#, ); } @@ -1270,7 +1189,7 @@ fn update_1() { ), ]) .and_where(Expr::col(Glyph::Id).eq(1)) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"UPDATE "glyph" SET "aspect" = 2.1345, "image" = '24B0E11951B03B07F8300FD003983F03F0780060' WHERE "id" = 1"# ); } @@ -1286,7 +1205,7 @@ fn update_3() { "24B0E11951B03B07F8300FD003983F03F0780060".into() ),]) .and_where(Expr::col(Glyph::Id).eq(1)) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"UPDATE "glyph" SET "aspect" = 60 * 24 * 24, "image" = '24B0E11951B03B07F8300FD003983F03F0780060' WHERE "id" = 1"# ); } @@ -1297,7 +1216,7 @@ fn delete_1() { Query::delete() .from_table(Glyph::Table) .and_where(Expr::col(Glyph::Id).eq(1)) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"DELETE FROM "glyph" WHERE "id" = 1"# ); } diff --git a/tests/oracle/table.rs b/tests/oracle/table.rs index 0a447781f..bf07f95aa 100644 --- a/tests/oracle/table.rs +++ b/tests/oracle/table.rs @@ -14,7 +14,7 @@ fn create_1() { ) .col(ColumnDef::new(Glyph::Aspect).double().not_null()) .col(ColumnDef::new(Glyph::Image).text()) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![ r#"CREATE TABLE "glyph" ("#, r#""id" serial NOT NULL PRIMARY KEY,"#, @@ -41,7 +41,7 @@ fn create_2() { .col(ColumnDef::new(Font::Name).string().not_null()) .col(ColumnDef::new(Font::Variant).string_len(255).not_null()) .col(ColumnDef::new(Font::Language).string_len(255).not_null()) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![ r#"CREATE TABLE "font" ("#, r#""id" serial NOT NULL PRIMARY KEY,"#, @@ -84,7 +84,7 @@ fn create_3() { .on_delete(ForeignKeyAction::Cascade) .on_update(ForeignKeyAction::Cascade) ) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![ r#"CREATE TABLE IF NOT EXISTS "character" ("#, r#""id" serial NOT NULL PRIMARY KEY,"#, @@ -108,7 +108,7 @@ fn create_4() { Table::create() .table(Glyph::Table) .col(ColumnDef::new(Glyph::Image).custom(Glyph::Aspect)) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![r#"CREATE TABLE "glyph" ("#, r#""image" aspect"#, r#")"#,].join(" ") ); } @@ -120,7 +120,7 @@ fn create_5() { .table(Glyph::Table) .col(ColumnDef::new(Glyph::Image).json()) .col(ColumnDef::new(Glyph::Aspect).json_binary()) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![ r#"CREATE TABLE "glyph" ("#, r#""image" json,"#, @@ -142,7 +142,7 @@ fn create_6() { .not_null() .extra("ANYTHING I WANT TO SAY".to_owned()) ) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![ r#"CREATE TABLE "glyph" ("#, r#""id" integer NOT NULL ANYTHING I WANT TO SAY"#, @@ -152,85 +152,85 @@ fn create_6() { ); } -#[test] -fn create_7() { - assert_eq!( - Table::create() - .table(Glyph::Table) - .col( - ColumnDef::new(Glyph::Aspect) - .interval(None, None) - .not_null() - ) - .to_string(PostgresQueryBuilder), - vec![ - r#"CREATE TABLE "glyph" ("#, - r#""aspect" interval NOT NULL"#, - r#")"#, - ] - .join(" ") - ); -} +// #[test] +// fn create_7() { +// assert_eq!( +// Table::create() +// .table(Glyph::Table) +// .col( +// ColumnDef::new(Glyph::Aspect) +// .interval(None, None) +// .not_null() +// ) +// .to_string(OracleQueryBuilder), +// vec![ +// r#"CREATE TABLE "glyph" ("#, +// r#""aspect" interval NOT NULL"#, +// r#")"#, +// ] +// .join(" ") +// ); +// } -#[test] -fn create_8() { - assert_eq!( - Table::create() - .table(Glyph::Table) - .col( - ColumnDef::new(Glyph::Aspect) - .interval(Some(PgInterval::YearToMonth), None) - .not_null() - ) - .to_string(PostgresQueryBuilder), - vec![ - r#"CREATE TABLE "glyph" ("#, - r#""aspect" interval YEAR TO MONTH NOT NULL"#, - r#")"#, - ] - .join(" ") - ); -} +// #[test] +// fn create_8() { +// assert_eq!( +// Table::create() +// .table(Glyph::Table) +// .col( +// ColumnDef::new(Glyph::Aspect) +// .interval(Some(PgInterval::YearToMonth), None) +// .not_null() +// ) +// .to_string(OracleQueryBuilder), +// vec![ +// r#"CREATE TABLE "glyph" ("#, +// r#""aspect" interval YEAR TO MONTH NOT NULL"#, +// r#")"#, +// ] +// .join(" ") +// ); +// } -#[test] -fn create_9() { - assert_eq!( - Table::create() - .table(Glyph::Table) - .col( - ColumnDef::new(Glyph::Aspect) - .interval(None, Some(42)) - .not_null() - ) - .to_string(PostgresQueryBuilder), - vec![ - r#"CREATE TABLE "glyph" ("#, - r#""aspect" interval(42) NOT NULL"#, - r#")"#, - ] - .join(" ") - ); -} +// #[test] +// fn create_9() { +// assert_eq!( +// Table::create() +// .table(Glyph::Table) +// .col( +// ColumnDef::new(Glyph::Aspect) +// .interval(None, Some(42)) +// .not_null() +// ) +// .to_string(OracleQueryBuilder), +// vec![ +// r#"CREATE TABLE "glyph" ("#, +// r#""aspect" interval(42) NOT NULL"#, +// r#")"#, +// ] +// .join(" ") +// ); +// } -#[test] -fn create_10() { - assert_eq!( - Table::create() - .table(Glyph::Table) - .col( - ColumnDef::new(Glyph::Aspect) - .interval(Some(PgInterval::Hour), Some(43)) - .not_null() - ) - .to_string(PostgresQueryBuilder), - vec![ - r#"CREATE TABLE "glyph" ("#, - r#""aspect" interval HOUR(43) NOT NULL"#, - r#")"#, - ] - .join(" ") - ); -} +// #[test] +// fn create_10() { +// assert_eq!( +// Table::create() +// .table(Glyph::Table) +// .col( +// ColumnDef::new(Glyph::Aspect) +// .interval(Some(PgInterval::Hour), Some(43)) +// .not_null() +// ) +// .to_string(OracleQueryBuilder), +// vec![ +// r#"CREATE TABLE "glyph" ("#, +// r#""aspect" interval HOUR(43) NOT NULL"#, +// r#")"#, +// ] +// .join(" ") +// ); +// } #[test] fn create_11() { @@ -242,7 +242,7 @@ fn create_11() { .timestamp_with_time_zone_len(0) .not_null() ) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![ r#"CREATE TABLE "character" ("#, r#""created_at" timestamp(0) with time zone NOT NULL"#, @@ -259,7 +259,7 @@ fn drop_1() { .table(Glyph::Table) .table(Char::Table) .cascade() - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"DROP TABLE "glyph", "character" CASCADE"# ); } @@ -269,7 +269,7 @@ fn truncate_1() { assert_eq!( Table::truncate() .table(Font::Table) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"TRUNCATE TABLE "font""# ); } @@ -285,7 +285,7 @@ fn alter_1() { .not_null() .default(100) ) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"ALTER TABLE "font" ADD COLUMN "new_col" integer NOT NULL DEFAULT 100"# ); } @@ -300,7 +300,7 @@ fn alter_2() { .big_integer() .default(999) ) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), vec![ r#"ALTER TABLE "font""#, r#"ALTER COLUMN "new_col" TYPE bigint,"#, @@ -316,7 +316,7 @@ fn alter_3() { Table::alter() .table(Font::Table) .rename_column(Alias::new("new_col"), Alias::new("new_column")) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"ALTER TABLE "font" RENAME COLUMN "new_col" TO "new_column""# ); } @@ -327,7 +327,7 @@ fn alter_4() { Table::alter() .table(Font::Table) .drop_column(Alias::new("new_column")) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"ALTER TABLE "font" DROP COLUMN "new_column""# ); } @@ -337,7 +337,7 @@ fn alter_5() { assert_eq!( Table::rename() .table(Font::Table, Alias::new("font_new")) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"ALTER TABLE "font" RENAME TO "font_new""# ); } @@ -345,7 +345,7 @@ fn alter_5() { #[test] #[should_panic(expected = "No alter option found")] fn alter_6() { - Table::alter().to_string(PostgresQueryBuilder); + Table::alter().to_string(OracleQueryBuilder); } #[test] @@ -355,7 +355,7 @@ fn alter_7() { .table(Font::Table) .add_column(ColumnDef::new(Alias::new("new_col")).integer()) .rename_column(Font::Name, Alias::new("name_new")) - .to_string(PostgresQueryBuilder), + .to_string(OracleQueryBuilder), r#"ALTER TABLE "font" ADD COLUMN "new_col" integer, RENAME COLUMN "name" TO "name_new""# ); } diff --git a/tests/oracle/types.rs b/tests/oracle/types.rs index 5c60cb227..ea73604f3 100644 --- a/tests/oracle/types.rs +++ b/tests/oracle/types.rs @@ -1,104 +1,102 @@ -use sea_query::{extension::postgres::Type, Alias, PostgresQueryBuilder}; +// use sea_query::{extension::postgres::Type, Alias, OracleQueryBuilder}; -use super::*; +// use super::*; -#[test] -fn create_1() { - assert_eq!( - Type::create() - .as_enum(Font::Table) - .values(vec![Font::Name, Font::Variant, Font::Language]) - .to_string(PostgresQueryBuilder), - r#"CREATE TYPE "font" AS ENUM ('name', 'variant', 'language')"# - ); -} +// #[test] +// fn create_1() { +// assert_eq!( +// Type::create() +// .as_enum(Font::Table) +// .values(vec![Font::Name, Font::Variant, Font::Language]) +// .to_string(OracleQueryBuilder), +// r#"CREATE TYPE "font" AS ENUM ('name', 'variant', 'language')"# +// ); +// } -#[test] -fn drop_1() { - assert_eq!( - Type::drop() - .if_exists() - .name(Font::Table) - .restrict() - .to_string(PostgresQueryBuilder), - r#"DROP TYPE IF EXISTS "font" RESTRICT"# - ) -} +// #[test] +// fn drop_1() { +// assert_eq!( +// Type::drop() +// .if_exists() +// .name(Font::Table) +// .restrict() +// .to_string(OracleQueryBuilder), +// r#"DROP TYPE IF EXISTS "font" RESTRICT"# +// ) +// } -#[test] -fn drop_2() { - assert_eq!( - Type::drop() - .name(Font::Table) - .to_string(PostgresQueryBuilder), - r#"DROP TYPE "font""# - ); -} +// #[test] +// fn drop_2() { +// assert_eq!( +// Type::drop().name(Font::Table).to_string(OracleQueryBuilder), +// r#"DROP TYPE "font""# +// ); +// } -#[test] -fn drop_3() { - assert_eq!( - Type::drop() - .if_exists() - .name(Font::Table) - .cascade() - .to_string(PostgresQueryBuilder), - r#"DROP TYPE IF EXISTS "font" CASCADE"# - ); -} +// #[test] +// fn drop_3() { +// assert_eq!( +// Type::drop() +// .if_exists() +// .name(Font::Table) +// .cascade() +// .to_string(OracleQueryBuilder), +// r#"DROP TYPE IF EXISTS "font" CASCADE"# +// ); +// } -#[test] -fn alter_1() { - assert_eq!( - Type::alter() - .name(Font::Table) - .add_value(Alias::new("weight")) - .to_string(PostgresQueryBuilder), - r#"ALTER TYPE "font" ADD VALUE 'weight'"# - ) -} -#[test] -fn alter_2() { - assert_eq!( - Type::alter() - .name(Font::Table) - .add_value(Alias::new("weight")) - .before(Font::Variant) - .to_string(PostgresQueryBuilder), - r#"ALTER TYPE "font" ADD VALUE 'weight' BEFORE 'variant'"# - ) -} +// #[test] +// fn alter_1() { +// assert_eq!( +// Type::alter() +// .name(Font::Table) +// .add_value(Alias::new("weight")) +// .to_string(OracleQueryBuilder), +// r#"ALTER TYPE "font" ADD VALUE 'weight'"# +// ) +// } +// #[test] +// fn alter_2() { +// assert_eq!( +// Type::alter() +// .name(Font::Table) +// .add_value(Alias::new("weight")) +// .before(Font::Variant) +// .to_string(OracleQueryBuilder), +// r#"ALTER TYPE "font" ADD VALUE 'weight' BEFORE 'variant'"# +// ) +// } -#[test] -fn alter_3() { - assert_eq!( - Type::alter() - .name(Font::Table) - .add_value(Alias::new("weight")) - .after(Font::Variant) - .to_string(PostgresQueryBuilder), - r#"ALTER TYPE "font" ADD VALUE 'weight' AFTER 'variant'"# - ) -} +// #[test] +// fn alter_3() { +// assert_eq!( +// Type::alter() +// .name(Font::Table) +// .add_value(Alias::new("weight")) +// .after(Font::Variant) +// .to_string(OracleQueryBuilder), +// r#"ALTER TYPE "font" ADD VALUE 'weight' AFTER 'variant'"# +// ) +// } -#[test] -fn alter_4() { - assert_eq!( - Type::alter() - .name(Font::Table) - .rename_to(Alias::new("typeface")) - .to_string(PostgresQueryBuilder), - r#"ALTER TYPE "font" RENAME TO 'typeface'"# - ) -} +// #[test] +// fn alter_4() { +// assert_eq!( +// Type::alter() +// .name(Font::Table) +// .rename_to(Alias::new("typeface")) +// .to_string(OracleQueryBuilder), +// r#"ALTER TYPE "font" RENAME TO 'typeface'"# +// ) +// } -#[test] -fn alter_5() { - assert_eq!( - Type::alter() - .name(Font::Table) - .rename_value(Font::Variant, Font::Language) - .to_string(PostgresQueryBuilder), - r#"ALTER TYPE "font" RENAME VALUE 'variant' TO 'language'"# - ) -} +// #[test] +// fn alter_5() { +// assert_eq!( +// Type::alter() +// .name(Font::Table) +// .rename_value(Font::Variant, Font::Language) +// .to_string(OracleQueryBuilder), +// r#"ALTER TYPE "font" RENAME VALUE 'variant' TO 'language'"# +// ) +// } From f18e7793a7ab2ed664184bbd08f422a964ffa9cb Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Thu, 28 Apr 2022 00:17:36 +0200 Subject: [PATCH 04/13] select_57 done --- tests/oracle/query.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/oracle/query.rs b/tests/oracle/query.rs index 0e8b9aae8..32409aac3 100644 --- a/tests/oracle/query.rs +++ b/tests/oracle/query.rs @@ -521,7 +521,7 @@ fn select_34b() { .or(Expr::col(Glyph::Aspect).lt(28)) ) .to_string(OracleQueryBuilder), - r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING (("aspect" > 2) OR ("aspect" < 8)) AND (("aspect" > 22) OR ("aspect" < 28))"#, + r#"SELECT "aspect", max("image") FROM "glyph" GROUP BY "aspect" HAVING (("aspect" > 2 OR "aspect" < 8) AND ("aspect" > 22 OR "aspect" < 28))"#, ); } @@ -581,7 +581,7 @@ fn select_38() { assert_eq!( statement, - r#"SELECT "id" FROM "glyph" WHERE "aspect" IS NULL OR "aspect" IS NOT NULL"# + r#"SELECT "id" FROM "glyph" WHERE ("aspect" IS NULL OR "aspect" IS NOT NULL)"# ); assert_eq!(values.0, vec![]); } @@ -600,7 +600,7 @@ fn select_39() { assert_eq!( statement, - r#"SELECT "id" FROM "glyph" WHERE "aspect" IS NULL AND "aspect" IS NOT NULL"# + r#"SELECT "id" FROM "glyph" WHERE ("aspect" IS NULL AND "aspect" IS NOT NULL)"# ); assert_eq!(values.0, vec![]); } @@ -621,7 +621,7 @@ fn select_40() { assert_eq!( statement, - r#"SELECT "id" FROM "glyph" WHERE "aspect" IS NULL OR ("aspect" IS NOT NULL AND "aspect" < 8)"# + r#"SELECT "id" FROM "glyph" WHERE ("aspect" IS NULL OR ("aspect" IS NOT NULL AND "aspect" < 8))"# ); } @@ -635,7 +635,7 @@ fn select_41() { .group_by_columns(vec![Glyph::Aspect]) .cond_having(any![Expr::col(Glyph::Aspect).gt(2)]) .to_string(OracleQueryBuilder), - r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# + r#"SELECT "aspect", max("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# ); } @@ -653,7 +653,7 @@ fn select_42() { assert_eq!( statement, - r#"SELECT "id" FROM "glyph" WHERE "aspect" < 8 AND "aspect" IS NOT NULL"# + r#"SELECT "id" FROM "glyph" WHERE ("aspect" < 8 AND "aspect" IS NOT NULL)"# ); } From 0be4c1695c1e9a6167c5550d8e61b849917d505c Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Thu, 28 Apr 2022 00:17:56 +0200 Subject: [PATCH 05/13] select_57 done --- tests/oracle/query.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/oracle/query.rs b/tests/oracle/query.rs index 32409aac3..b2b3352f1 100644 --- a/tests/oracle/query.rs +++ b/tests/oracle/query.rs @@ -701,7 +701,7 @@ fn select_45() { assert_eq!( statement, - r#"SELECT "id" FROM "glyph" WHERE NOT ("aspect" < 8 OR "aspect" IS NOT NULL)"# + r#"SELECT "id" FROM "glyph" WHERE NOT (("aspect" < 8 OR "aspect" IS NOT NULL))"# ); } @@ -738,7 +738,7 @@ fn select_47() { assert_eq!( statement, - r#"SELECT "id" FROM "glyph" WHERE NOT ("aspect" < 8 AND "aspect" IS NOT NULL)"# + r#"SELECT "id" FROM "glyph" WHERE NOT (("aspect" < 8 AND "aspect" IS NOT NULL))"# ); } @@ -760,7 +760,7 @@ fn select_48() { assert_eq!( statement, - r#"SELECT "id" FROM "glyph" WHERE ("aspect", 100) < (8, 100)"# + r#"SELECT "id" FROM "glyph" WHERE ("aspect" <= 8 AND ("aspect" < 8 OR ("aspect" = 8 AND 100 < 100)))"# ); } @@ -788,7 +788,7 @@ fn select_50() { assert_eq!( statement, - r#"SELECT "character".*, "font"."name" FROM "character" INNER JOIN "font" ON "character"."font_id" = "font"."id""# + r#"SELECT "character".*, "font"."name" FROM "character" JOIN "font" ON "character"."font_id" = "font"."id""# ) } @@ -806,7 +806,7 @@ fn select_51() { NullOrdering::Last ) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "image" DESC NULLS FIRST, "glyph"."aspect" ASC NULLS LAST"#, + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "image" DESC NULLS FIRST, "glyph"."aspect" ASC NULLS LAST"#, ); } @@ -822,7 +822,7 @@ fn select_52() { (Glyph::Aspect, Order::Desc, NullOrdering::Last), ]) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "id" ASC NULLS FIRST, "aspect" DESC NULLS LAST"#, + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "id" ASC NULLS FIRST, "aspect" DESC NULLS LAST"#, ); } @@ -842,7 +842,7 @@ fn select_53() { ), ]) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."id" ASC NULLS FIRST, "glyph"."aspect" DESC NULLS LAST"#, + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "glyph"."id" ASC NULLS FIRST, "glyph"."aspect" DESC NULLS LAST"#, ); } @@ -879,7 +879,7 @@ fn select_55() { ) .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY CASE WHEN "id"=4 THEN 0 WHEN "id"=5 THEN 1 WHEN "id"=1 THEN 2 WHEN "id"=3 THEN 3 ELSE 4 END, "glyph"."aspect" ASC"# + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY CASE WHEN "id" = 4 THEN 0 WHEN "id" = 5 THEN 1 WHEN "id" = 1 THEN 2 WHEN "id" = 3 THEN 3 ELSE 4 END, "glyph"."aspect" ASC"# ); } @@ -901,7 +901,7 @@ fn select_56() { ])) ) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."aspect" ASC, CASE WHEN "id"=4 THEN 0 WHEN "id"=5 THEN 1 WHEN "id"=1 THEN 2 WHEN "id"=3 THEN 3 ELSE 4 END"#, + r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "glyph"."aspect" ASC, CASE WHEN "id" = 4 THEN 0 WHEN "id" = 5 THEN 1 WHEN "id" = 1 THEN 2 WHEN "id" = 3 THEN 3 ELSE 4 END"#, ); } From 1a3f0ef337ed49e213b25878b15f931134ef9a04 Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Thu, 28 Apr 2022 00:55:50 +0200 Subject: [PATCH 06/13] limit and offset --- Cargo.toml | 5 +- src/backend/query_builder.rs | 29 +- tests/oracle/query.rs | 568 ++++++++++++++++++----------------- 3 files changed, 321 insertions(+), 281 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f2da154c9..8b5db7454 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,10 @@ pretty_assertions = { version = "^1" } backend-mysql = [] backend-postgres = [] backend-sqlite = [] -backend-oracle = [] +backend-oracle = ["oracle-overrides"] + +oracle-overrides = [] + default = ["derive", "backend-mysql", "backend-postgres", "backend-sqlite", "backend-oracle"] derive = ["sea-query-derive"] postgres = ["bytes", "postgres-types"] diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index 963be5f0f..baaabd041 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -140,15 +140,28 @@ pub trait QueryBuilder: QuotedBuilder { false }); } + // OVERRIDE + if cfg!(feature = "oracle-overrides") { + if let Some(offset) = &select.offset { + write!(sql, " OFFSET ").unwrap(); + self.prepare_value(offset, sql, collector); + write!(sql, " ROWS ").unwrap(); + } + if let Some(limit) = &select.limit { + write!(sql, " FETCH NEXT ").unwrap(); + self.prepare_value(limit, sql, collector); + write!(sql, " ROWS ONLY ").unwrap(); + } + } else { + if let Some(limit) = &select.limit { + write!(sql, " LIMIT ").unwrap(); + self.prepare_value(limit, sql, collector); + } - if let Some(limit) = &select.limit { - write!(sql, " LIMIT ").unwrap(); - self.prepare_value(limit, sql, collector); - } - - if let Some(offset) = &select.offset { - write!(sql, " OFFSET ").unwrap(); - self.prepare_value(offset, sql, collector); + if let Some(offset) = &select.offset { + write!(sql, " OFFSET ").unwrap(); + self.prepare_value(offset, sql, collector); + } } if let Some(lock) = &select.lock { diff --git a/tests/oracle/query.rs b/tests/oracle/query.rs index b2b3352f1..4992704fb 100644 --- a/tests/oracle/query.rs +++ b/tests/oracle/query.rs @@ -3,6 +3,7 @@ use pretty_assertions::assert_eq; #[test] fn select_1() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) @@ -10,7 +11,7 @@ fn select_1() { .limit(10) .offset(100) .to_string(OracleQueryBuilder), - r#"SELECT "character", "size_w", "size_h" FROM "character" OFFSET 100 ROWS FETCH NEXT 10 ROWS ONLY"# + r#"SELECT "character", "size_w", "size_h" FROM "character" OFFSET 100 ROWS FETCH NEXT 10 ROWS ONLY "# ); } @@ -28,6 +29,7 @@ fn select_2() { #[test] fn select_3() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) @@ -41,6 +43,7 @@ fn select_3() { #[test] fn select_4() { + // FIXME assert_eq!( Query::select() .columns(vec![Glyph::Aspect]) @@ -78,7 +81,7 @@ fn select_6() { .group_by_columns(vec![Glyph::Aspect,]) .and_having(Expr::col(Glyph::Aspect).gt(2)) .to_string(OracleQueryBuilder), - r#"SELECT "aspect", max("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# ); } @@ -90,12 +93,13 @@ fn select_7() { .from(Glyph::Table) .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2"# + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2"# ); } #[test] fn select_8() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character,]) @@ -111,6 +115,7 @@ fn select_8() { #[test] fn select_9() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character,]) @@ -130,6 +135,7 @@ fn select_9() { #[test] fn select_10() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character,]) @@ -155,7 +161,7 @@ fn select_11() { .order_by(Glyph::Image, Order::Desc) .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "image" DESC, "glyph"."aspect" ASC"# + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "image" DESC, "glyph"."aspect" ASC"# ); } @@ -168,7 +174,7 @@ fn select_12() { .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2)) .order_by_columns(vec![(Glyph::Id, Order::Asc), (Glyph::Aspect, Order::Desc),]) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "id" ASC, "aspect" DESC"# + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "id" ASC, "aspect" DESC"# ); } @@ -184,7 +190,7 @@ fn select_13() { ((Glyph::Table, Glyph::Aspect), Order::Desc), ]) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "glyph"."id" ASC, "glyph"."aspect" DESC"# + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."id" ASC, "glyph"."aspect" DESC"# ); } @@ -201,7 +207,7 @@ fn select_14() { ]) .and_having(Expr::col(Glyph::Aspect).gt(2)) .to_string(OracleQueryBuilder), - r#"SELECT "id", "aspect", max("image") FROM "glyph" GROUP BY "glyph"."id", "glyph"."aspect" HAVING "aspect" > 2"# + r#"SELECT "id", "aspect", MAX("image") FROM "glyph" GROUP BY "glyph"."id", "glyph"."aspect" HAVING "aspect" > 2"# ); } @@ -219,6 +225,7 @@ fn select_15() { #[test] fn select_16() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character]) @@ -244,6 +251,7 @@ fn select_17() { #[test] fn select_18() { + // FIXME assert_eq!( Query::select() .columns(vec![Glyph::Aspect,]) @@ -281,6 +289,7 @@ fn select_20() { #[test] fn select_21() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character]) @@ -295,6 +304,7 @@ fn select_21() { #[test] fn select_22() { + // FIXME assert_eq!( Query::select() .column(Char::Character) @@ -351,6 +361,7 @@ fn select_24() { #[test] fn select_25() { + // FIXME assert_eq!( Query::select() .column(Char::Character) @@ -383,6 +394,7 @@ fn select_25() { #[test] fn select_27() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) @@ -397,6 +409,7 @@ fn select_27() { #[test] fn select_28() { + // FIXME assert_eq!( Query::select() .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) @@ -453,6 +466,7 @@ fn select_29() { #[test] fn select_32() { + // FIXME assert_eq!( Query::select() .expr_as(Expr::col(Char::Character), Alias::new("C")) @@ -479,6 +493,7 @@ fn select_32() { #[test] fn select_34a() { + // FIXME assert_eq!( Query::select() .column(Glyph::Aspect) @@ -497,7 +512,7 @@ fn select_34a() { ) .or_having(Expr::col(Glyph::Aspect).gt(32)) .to_string(OracleQueryBuilder), - r#"SELECT "aspect", max("image") FROM "glyph" GROUP BY "aspect" HAVING ("aspect" > 2 OR "aspect" < 8 OR ("aspect" > 12 AND "aspect" < 18) OR "aspect" > 32)"#, + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING ("aspect" > 2 OR "aspect" < 8 OR ("aspect" > 12 AND "aspect" < 18) OR "aspect" > 32)"#, ); } @@ -521,7 +536,7 @@ fn select_34b() { .or(Expr::col(Glyph::Aspect).lt(28)) ) .to_string(OracleQueryBuilder), - r#"SELECT "aspect", max("image") FROM "glyph" GROUP BY "aspect" HAVING (("aspect" > 2 OR "aspect" < 8) AND ("aspect" > 22 OR "aspect" < 28))"#, + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING (("aspect" > 2 OR "aspect" < 8) AND ("aspect" > 22 OR "aspect" < 28))"#, ); } @@ -569,6 +584,7 @@ fn select_37() { #[test] fn select_38() { + // FIXME let (statement, values) = sea_query::Query::select() .column(Glyph::Id) .from(Glyph::Table) @@ -588,6 +604,7 @@ fn select_38() { #[test] fn select_39() { + // FIXME let (statement, values) = sea_query::Query::select() .column(Glyph::Id) .from(Glyph::Table) @@ -607,6 +624,7 @@ fn select_39() { #[test] fn select_40() { + // FIXME let statement = sea_query::Query::select() .column(Glyph::Id) .from(Glyph::Table) @@ -635,12 +653,13 @@ fn select_41() { .group_by_columns(vec![Glyph::Aspect]) .cond_having(any![Expr::col(Glyph::Aspect).gt(2)]) .to_string(OracleQueryBuilder), - r#"SELECT "aspect", max("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# + r#"SELECT "aspect", MAX("image") FROM "glyph" GROUP BY "aspect" HAVING "aspect" > 2"# ); } #[test] fn select_42() { + // FIXME let statement = sea_query::Query::select() .column(Glyph::Id) .from(Glyph::Table) @@ -688,6 +707,7 @@ fn select_44() { #[test] fn select_45() { + // FIXME let statement = sea_query::Query::select() .column(Glyph::Id) .from(Glyph::Table) @@ -725,6 +745,7 @@ fn select_46() { #[test] fn select_47() { + // FIXME let statement = sea_query::Query::select() .column(Glyph::Id) .from(Glyph::Table) @@ -744,6 +765,7 @@ fn select_47() { #[test] fn select_48() { + // FIXME let statement = sea_query::Query::select() .column(Glyph::Id) .from(Glyph::Table) @@ -776,6 +798,7 @@ fn select_49() { #[test] fn select_50() { + // FIXME let statement = sea_query::Query::select() .expr(Expr::table_asterisk(Char::Table)) .column((Font::Table, Font::Name)) @@ -806,7 +829,7 @@ fn select_51() { NullOrdering::Last ) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "image" DESC NULLS FIRST, "glyph"."aspect" ASC NULLS LAST"#, + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "image" DESC NULLS FIRST, "glyph"."aspect" ASC NULLS LAST"#, ); } @@ -822,7 +845,7 @@ fn select_52() { (Glyph::Aspect, Order::Desc, NullOrdering::Last), ]) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "id" ASC NULLS FIRST, "aspect" DESC NULLS LAST"#, + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "id" ASC NULLS FIRST, "aspect" DESC NULLS LAST"#, ); } @@ -842,7 +865,7 @@ fn select_53() { ), ]) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "glyph"."id" ASC NULLS FIRST, "glyph"."aspect" DESC NULLS LAST"#, + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."id" ASC NULLS FIRST, "glyph"."aspect" DESC NULLS LAST"#, ); } @@ -879,7 +902,7 @@ fn select_55() { ) .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY CASE WHEN "id" = 4 THEN 0 WHEN "id" = 5 THEN 1 WHEN "id" = 1 THEN 2 WHEN "id" = 3 THEN 3 ELSE 4 END, "glyph"."aspect" ASC"# + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY CASE WHEN "id"=4 THEN 0 WHEN "id"=5 THEN 1 WHEN "id"=1 THEN 2 WHEN "id"=3 THEN 3 ELSE 4 END, "glyph"."aspect" ASC"# ); } @@ -901,7 +924,7 @@ fn select_56() { ])) ) .to_string(OracleQueryBuilder), - r#"SELECT "aspect" FROM "glyph" WHERE coalesce("aspect", 0) > 2 ORDER BY "glyph"."aspect" ASC, CASE WHEN "id" = 4 THEN 0 WHEN "id" = 5 THEN 1 WHEN "id" = 1 THEN 2 WHEN "id" = 3 THEN 3 ELSE 4 END"#, + r#"SELECT "aspect" FROM "glyph" WHERE COALESCE("aspect", 0) > 2 ORDER BY "glyph"."aspect" ASC, CASE WHEN "id"=4 THEN 0 WHEN "id"=5 THEN 1 WHEN "id"=1 THEN 2 WHEN "id"=3 THEN 3 ELSE 4 END"#, ); } @@ -928,6 +951,7 @@ fn select_57() { #[test] fn select_58() { + // FIXME let query = Query::select() .expr_as( CaseStatement::new() @@ -947,276 +971,276 @@ fn select_58() { assert_eq!( query.to_string(OracleQueryBuilder), - r#"SELECT (CASE WHEN ("glyph"."aspect" > 0) THEN 'positive' WHEN ("glyph"."aspect" < 0) THEN 'negative' ELSE 'zero' END) AS "polarity" FROM "glyph""# + r#"SELECT CASE WHEN "glyph"."aspect" > 0 THEN 'positive' WHEN "glyph"."aspect" < 0 THEN 'negative' ELSE 'zero' END "polarity" FROM "glyph""# ); } -#[test] -#[allow(clippy::approx_constant)] -fn insert_2() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Image, Glyph::Aspect,]) - .values_panic(vec![ - "04108048005887010020060000204E0180400400".into(), - 3.1415.into(), - ]) - .to_string(OracleQueryBuilder), - r#"INSERT INTO "glyph" ("image", "aspect") VALUES ('04108048005887010020060000204E0180400400', 3.1415)"# - ); -} +// #[test] +// #[allow(clippy::approx_constant)] +// fn insert_2() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Image, Glyph::Aspect,]) +// .values_panic(vec![ +// "04108048005887010020060000204E0180400400".into(), +// 3.1415.into(), +// ]) +// .to_string(OracleQueryBuilder), +// r#"INSERT INTO "glyph" ("image", "aspect") VALUES ('04108048005887010020060000204E0180400400', 3.1415)"# +// ); +// } -#[test] -#[allow(clippy::approx_constant)] -fn insert_3() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Image, Glyph::Aspect,]) - .values_panic(vec![ - "04108048005887010020060000204E0180400400".into(), - 3.1415.into(), - ]) - .values_panic(vec![Value::String(None), 2.1345.into(),]) - .to_string(OracleQueryBuilder), - r#"INSERT INTO "glyph" ("image", "aspect") VALUES ('04108048005887010020060000204E0180400400', 3.1415), (NULL, 2.1345)"# - ); -} +// #[test] +// #[allow(clippy::approx_constant)] +// fn insert_3() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Image, Glyph::Aspect,]) +// .values_panic(vec![ +// "04108048005887010020060000204E0180400400".into(), +// 3.1415.into(), +// ]) +// .values_panic(vec![Value::String(None), 2.1345.into(),]) +// .to_string(OracleQueryBuilder), +// r#"INSERT INTO "glyph" ("image", "aspect") VALUES ('04108048005887010020060000204E0180400400', 3.1415), (NULL, 2.1345)"# +// ); +// } -#[test] -#[cfg(feature = "with-chrono")] -fn insert_4() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Image]) - .values_panic(vec![chrono::NaiveDateTime::from_timestamp(0, 0).into()]) - .to_string(OracleQueryBuilder), - "INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')" - ); -} +// #[test] +// #[cfg(feature = "with-chrono")] +// fn insert_4() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Image]) +// .values_panic(vec![chrono::NaiveDateTime::from_timestamp(0, 0).into()]) +// .to_string(OracleQueryBuilder), +// "INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')" +// ); +// } -#[test] -#[cfg(feature = "with-time")] -fn insert_9() { - use time::{date, time}; - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Image]) - .values_panic(vec![date!(1970 - 01 - 01) - .with_time(time!(00:00:00)) - .into()]) - .to_string(OracleQueryBuilder), - "INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')" - ); -} +// #[test] +// #[cfg(feature = "with-time")] +// fn insert_9() { +// use time::{date, time}; +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Image]) +// .values_panic(vec![date!(1970 - 01 - 01) +// .with_time(time!(00:00:00)) +// .into()]) +// .to_string(OracleQueryBuilder), +// "INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')" +// ); +// } -#[test] -#[cfg(feature = "with-uuid")] -fn insert_5() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Image]) - .values_panic(vec![uuid::Uuid::nil().into()]) - .to_string(OracleQueryBuilder), - "INSERT INTO \"glyph\" (\"image\") VALUES ('00000000-0000-0000-0000-000000000000')" - ); -} +// #[test] +// #[cfg(feature = "with-uuid")] +// fn insert_5() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Image]) +// .values_panic(vec![uuid::Uuid::nil().into()]) +// .to_string(OracleQueryBuilder), +// "INSERT INTO \"glyph\" (\"image\") VALUES ('00000000-0000-0000-0000-000000000000')" +// ); +// } -#[test] -fn insert_from_select() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Aspect, Glyph::Image]) - .select_from( - Query::select() - .column(Glyph::Aspect) - .column(Glyph::Image) - .from(Glyph::Table) - .conditions( - true, - |x| { - x.and_where(Expr::col(Glyph::Image).like("%")); - }, - |x| { - x.and_where(Expr::col(Glyph::Id).eq(6)); - }, - ) - .to_owned() - ) - .unwrap() - .to_owned() - .to_string(OracleQueryBuilder), - r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '%'"# - ); -} +// #[test] +// fn insert_from_select() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Aspect, Glyph::Image]) +// .select_from( +// Query::select() +// .column(Glyph::Aspect) +// .column(Glyph::Image) +// .from(Glyph::Table) +// .conditions( +// true, +// |x| { +// x.and_where(Expr::col(Glyph::Image).like("%")); +// }, +// |x| { +// x.and_where(Expr::col(Glyph::Id).eq(6)); +// }, +// ) +// .to_owned() +// ) +// .unwrap() +// .to_owned() +// .to_string(OracleQueryBuilder), +// r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '%'"# +// ); +// } -#[test] -fn insert_6() -> sea_query::error::Result<()> { - let select = SelectStatement::new() - .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) - .from(Glyph::Table) - .to_owned(); - let cte = CommonTableExpression::new() - .query(select) - .column(Glyph::Id) - .column(Glyph::Image) - .column(Glyph::Aspect) - .table_name(Alias::new("cte")) - .to_owned(); - let with_clause = WithClause::new().cte(cte).to_owned(); - let select = SelectStatement::new() - .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) - .from(Alias::new("cte")) - .to_owned(); - let mut insert = Query::insert(); - insert - .into_table(Glyph::Table) - .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) - .select_from(select)?; - let sql = insert.with(with_clause).to_string(OracleQueryBuilder); - assert_eq!( - sql.as_str(), - r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#, - ); - Ok(()) -} +// #[test] +// fn insert_6() -> sea_query::error::Result<()> { +// let select = SelectStatement::new() +// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) +// .from(Glyph::Table) +// .to_owned(); +// let cte = CommonTableExpression::new() +// .query(select) +// .column(Glyph::Id) +// .column(Glyph::Image) +// .column(Glyph::Aspect) +// .table_name(Alias::new("cte")) +// .to_owned(); +// let with_clause = WithClause::new().cte(cte).to_owned(); +// let select = SelectStatement::new() +// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) +// .from(Alias::new("cte")) +// .to_owned(); +// let mut insert = Query::insert(); +// insert +// .into_table(Glyph::Table) +// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect]) +// .select_from(select)?; +// let sql = insert.with(with_clause).to_string(OracleQueryBuilder); +// assert_eq!( +// sql.as_str(), +// r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#, +// ); +// Ok(()) +// } -#[test] -#[allow(clippy::approx_constant)] -fn insert_on_conflict_1() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Aspect, Glyph::Image]) - .values_panic(vec![ - "04108048005887010020060000204E0180400400".into(), - 3.1415.into(), - ]) - .on_conflict( - OnConflict::column(Glyph::Id) - .update_column(Glyph::Aspect) - .to_owned() - ) - .to_string(OracleQueryBuilder), - r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id") DO UPDATE SET "aspect" = "excluded"."aspect""#, - ); -} +// #[test] +// #[allow(clippy::approx_constant)] +// fn insert_on_conflict_1() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Aspect, Glyph::Image]) +// .values_panic(vec![ +// "04108048005887010020060000204E0180400400".into(), +// 3.1415.into(), +// ]) +// .on_conflict( +// OnConflict::column(Glyph::Id) +// .update_column(Glyph::Aspect) +// .to_owned() +// ) +// .to_string(OracleQueryBuilder), +// r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id") DO UPDATE SET "aspect" = "excluded"."aspect""#, +// ); +// } -#[test] -#[allow(clippy::approx_constant)] -fn insert_on_conflict_2() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Aspect, Glyph::Image]) - .values_panic(vec![ - "04108048005887010020060000204E0180400400".into(), - 3.1415.into(), - ]) - .on_conflict( - OnConflict::columns([Glyph::Id, Glyph::Aspect]) - .update_columns([Glyph::Aspect, Glyph::Image]) - .to_owned() - ) - .to_string(OracleQueryBuilder), - r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = "excluded"."aspect", "image" = "excluded"."image""#, - ); -} +// #[test] +// #[allow(clippy::approx_constant)] +// fn insert_on_conflict_2() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Aspect, Glyph::Image]) +// .values_panic(vec![ +// "04108048005887010020060000204E0180400400".into(), +// 3.1415.into(), +// ]) +// .on_conflict( +// OnConflict::columns([Glyph::Id, Glyph::Aspect]) +// .update_columns([Glyph::Aspect, Glyph::Image]) +// .to_owned() +// ) +// .to_string(OracleQueryBuilder), +// r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = "excluded"."aspect", "image" = "excluded"."image""#, +// ); +// } -#[test] -#[allow(clippy::approx_constant)] -fn insert_on_conflict_3() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Aspect, Glyph::Image]) - .values_panic(vec![ - "04108048005887010020060000204E0180400400".into(), - 3.1415.into(), - ]) - .on_conflict( - OnConflict::columns([Glyph::Id, Glyph::Aspect]) - .update_values([ - ( - Glyph::Aspect, - "04108048005887010020060000204E0180400400".into() - ), - (Glyph::Image, 3.1415.into()), - ]) - .to_owned() - ) - .to_string(OracleQueryBuilder), - r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = '04108048005887010020060000204E0180400400', "image" = 3.1415"#, - ); -} +// #[test] +// #[allow(clippy::approx_constant)] +// fn insert_on_conflict_3() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Aspect, Glyph::Image]) +// .values_panic(vec![ +// "04108048005887010020060000204E0180400400".into(), +// 3.1415.into(), +// ]) +// .on_conflict( +// OnConflict::columns([Glyph::Id, Glyph::Aspect]) +// .update_values([ +// ( +// Glyph::Aspect, +// "04108048005887010020060000204E0180400400".into() +// ), +// (Glyph::Image, 3.1415.into()), +// ]) +// .to_owned() +// ) +// .to_string(OracleQueryBuilder), +// r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "aspect" = '04108048005887010020060000204E0180400400', "image" = 3.1415"#, +// ); +// } -#[test] -#[allow(clippy::approx_constant)] -fn insert_on_conflict_4() { - assert_eq!( - Query::insert() - .into_table(Glyph::Table) - .columns(vec![Glyph::Aspect, Glyph::Image]) - .values_panic(vec![ - "04108048005887010020060000204E0180400400".into(), - 3.1415.into(), - ]) - .on_conflict( - OnConflict::columns([Glyph::Id, Glyph::Aspect]) - .update_expr((Glyph::Image, Expr::val(1).add(2))) - .to_owned() - ) - .to_string(OracleQueryBuilder), - r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "image" = 1 + 2"#, - ); -} +// #[test] +// #[allow(clippy::approx_constant)] +// fn insert_on_conflict_4() { +// assert_eq!( +// Query::insert() +// .into_table(Glyph::Table) +// .columns(vec![Glyph::Aspect, Glyph::Image]) +// .values_panic(vec![ +// "04108048005887010020060000204E0180400400".into(), +// 3.1415.into(), +// ]) +// .on_conflict( +// OnConflict::columns([Glyph::Id, Glyph::Aspect]) +// .update_expr((Glyph::Image, Expr::val(1).add(2))) +// .to_owned() +// ) +// .to_string(OracleQueryBuilder), +// r#"INSERT INTO "glyph" ("aspect", "image") VALUES ('04108048005887010020060000204E0180400400', 3.1415) ON CONFLICT ("id", "aspect") DO UPDATE SET "image" = 1 + 2"#, +// ); +// } -#[test] -fn update_1() { - assert_eq!( - Query::update() - .table(Glyph::Table) - .values(vec![ - (Glyph::Aspect, 2.1345.into()), - ( - Glyph::Image, - "24B0E11951B03B07F8300FD003983F03F0780060".into() - ), - ]) - .and_where(Expr::col(Glyph::Id).eq(1)) - .to_string(OracleQueryBuilder), - r#"UPDATE "glyph" SET "aspect" = 2.1345, "image" = '24B0E11951B03B07F8300FD003983F03F0780060' WHERE "id" = 1"# - ); -} +// #[test] +// fn update_1() { +// assert_eq!( +// Query::update() +// .table(Glyph::Table) +// .values(vec![ +// (Glyph::Aspect, 2.1345.into()), +// ( +// Glyph::Image, +// "24B0E11951B03B07F8300FD003983F03F0780060".into() +// ), +// ]) +// .and_where(Expr::col(Glyph::Id).eq(1)) +// .to_string(OracleQueryBuilder), +// r#"UPDATE "glyph" SET "aspect" = 2.1345, "image" = '24B0E11951B03B07F8300FD003983F03F0780060' WHERE "id" = 1"# +// ); +// } -#[test] -fn update_3() { - assert_eq!( - Query::update() - .table(Glyph::Table) - .value_expr(Glyph::Aspect, Expr::cust("60 * 24 * 24")) - .values(vec![( - Glyph::Image, - "24B0E11951B03B07F8300FD003983F03F0780060".into() - ),]) - .and_where(Expr::col(Glyph::Id).eq(1)) - .to_string(OracleQueryBuilder), - r#"UPDATE "glyph" SET "aspect" = 60 * 24 * 24, "image" = '24B0E11951B03B07F8300FD003983F03F0780060' WHERE "id" = 1"# - ); -} +// #[test] +// fn update_3() { +// assert_eq!( +// Query::update() +// .table(Glyph::Table) +// .value_expr(Glyph::Aspect, Expr::cust("60 * 24 * 24")) +// .values(vec![( +// Glyph::Image, +// "24B0E11951B03B07F8300FD003983F03F0780060".into() +// ),]) +// .and_where(Expr::col(Glyph::Id).eq(1)) +// .to_string(OracleQueryBuilder), +// r#"UPDATE "glyph" SET "aspect" = 60 * 24 * 24, "image" = '24B0E11951B03B07F8300FD003983F03F0780060' WHERE "id" = 1"# +// ); +// } -#[test] -fn delete_1() { - assert_eq!( - Query::delete() - .from_table(Glyph::Table) - .and_where(Expr::col(Glyph::Id).eq(1)) - .to_string(OracleQueryBuilder), - r#"DELETE FROM "glyph" WHERE "id" = 1"# - ); -} +// #[test] +// fn delete_1() { +// assert_eq!( +// Query::delete() +// .from_table(Glyph::Table) +// .and_where(Expr::col(Glyph::Id).eq(1)) +// .to_string(OracleQueryBuilder), +// r#"DELETE FROM "glyph" WHERE "id" = 1"# +// ); +// } From 8a63fd012390ef1726238d66d2fc84a48e73b3cf Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Thu, 28 Apr 2022 01:07:54 +0200 Subject: [PATCH 07/13] this should work for me --- src/backend/query_builder.rs | 79 +++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index baaabd041..f3076175f 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -496,14 +496,23 @@ pub trait QueryBuilder: QuotedBuilder { } None => {} }; - - match &select_expr.alias { - Some(alias) => { - write!(sql, " AS ").unwrap(); - alias.prepare(sql, self.quote()); - } - None => {} - }; + if cfg!(feature = "oracle-overrides") { + match &select_expr.alias { + Some(alias) => { + write!(sql, " ").unwrap(); + alias.prepare(sql, self.quote()); + } + None => {} + }; + } else { + match &select_expr.alias { + Some(alias) => { + write!(sql, " AS ").unwrap(); + alias.prepare(sql, self.quote()); + } + None => {} + }; + } } /// Translate [`JoinExpr`] into SQL statement. @@ -588,11 +597,19 @@ pub trait QueryBuilder: QuotedBuilder { alias.prepare(sql, self.quote()); } TableRef::SubQuery(query, alias) => { - write!(sql, "(").unwrap(); - self.prepare_select_statement(query, sql, collector); - write!(sql, ")").unwrap(); - write!(sql, " AS ").unwrap(); - alias.prepare(sql, self.quote()); + if cfg!(feature = "oracle-overrides") { + write!(sql, "(").unwrap(); + self.prepare_select_statement(query, sql, collector); + write!(sql, ")").unwrap(); + write!(sql, " ").unwrap(); + alias.prepare(sql, self.quote()); + } else { + write!(sql, "(").unwrap(); + self.prepare_select_statement(query, sql, collector); + write!(sql, ")").unwrap(); + write!(sql, " AS ").unwrap(); + alias.prepare(sql, self.quote()); + } } } } @@ -921,17 +938,31 @@ pub trait QueryBuilder: QuotedBuilder { sql: &mut SqlWriter, _collector: &mut dyn FnMut(Value), ) { - write!( - sql, - "{}", - match join_type { - JoinType::Join => "JOIN", - JoinType::InnerJoin => "INNER JOIN", - JoinType::LeftJoin => "LEFT JOIN", - JoinType::RightJoin => "RIGHT JOIN", - } - ) - .unwrap() + if cfg!(feature = "oracle-overrides") { + write!( + sql, + "{}", + match join_type { + JoinType::Join => "JOIN", + JoinType::InnerJoin => "JOIN", + JoinType::LeftJoin => "LEFT OUTER JOIN", + JoinType::RightJoin => "RIGHT JOIN", + } + ) + .unwrap() + } else { + write!( + sql, + "{}", + match join_type { + JoinType::Join => "JOIN", + JoinType::InnerJoin => "INNER JOIN", + JoinType::LeftJoin => "LEFT JOIN", + JoinType::RightJoin => "RIGHT JOIN", + } + ) + .unwrap() + } } /// Translate [`OrderExpr`] into SQL statement. From 27a07f2b2a56cc304ce6165f02cf6fd121bb4aba Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Thu, 28 Apr 2022 21:28:48 +0200 Subject: [PATCH 08/13] impl to-sql --- Cargo.toml | 6 ++--- src/value.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8b5db7454..713d2cac1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ uuid = { version = "^0", optional = true } proc-macro2 = { version = "1", optional = true } quote = { version = "^1", optional = true } time = { version = "^0.2", optional = true } - +r2d2-oracle = {version = "0.5.0", optional = true, features = ["chrono"] } [dev-dependencies] criterion = { version = "0.3", features = ["html_reports"] } pretty_assertions = { version = "^1" } @@ -60,9 +60,9 @@ backend-postgres = [] backend-sqlite = [] backend-oracle = ["oracle-overrides"] -oracle-overrides = [] +oracle-overrides = ["r2d2-oracle"] -default = ["derive", "backend-mysql", "backend-postgres", "backend-sqlite", "backend-oracle"] +default = ["derive", "backend-mysql", "backend-sqlite", "backend-oracle", "with-chrono"] derive = ["sea-query-derive"] postgres = ["bytes", "postgres-types"] postgres-chrono = ["with-chrono", "postgres-types/with-chrono-0_4"] diff --git a/src/value.rs b/src/value.rs index 0cab56eeb..3ec4c224e 100644 --- a/src/value.rs +++ b/src/value.rs @@ -105,6 +105,76 @@ pub enum Value { Array(Option>>), } +#[cfg(feature = "oracle-overrides")] +pub mod oracle_overrides { + use super::*; + use r2d2_oracle::oracle::sql_type::ToSql; + + // /// 2021-07-14T23:59:59 + // const CLIENT_DATETIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S"; + // const DB_DATETIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S"; + + // pub fn to_oracle_format(time: chrono::NaiveDateTime) -> String { + // format!( + // r#"to_date('{time}', 'YYYY-MM-DD HH24:MI:SS')"#, + // time = time.format(DB_DATETIME_FORMAT), + // ) + // } + + impl ToSql for Value { + fn oratype( + &self, + conn: &r2d2_oracle::oracle::Connection, + ) -> r2d2_oracle::oracle::Result { + match self { + Value::Bool(v) => v.oratype(conn), + Value::TinyInt(v) => v.oratype(conn), + Value::SmallInt(v) => v.oratype(conn), + Value::Int(v) => v.oratype(conn), + Value::BigInt(v) => v.oratype(conn), + Value::TinyUnsigned(v) => v.oratype(conn), + Value::SmallUnsigned(v) => v.oratype(conn), + Value::Unsigned(v) => v.oratype(conn), + Value::BigUnsigned(v) => v.oratype(conn), + Value::Float(v) => v.oratype(conn), + Value::Double(v) => v.oratype(conn), + Value::String(v) => v.as_ref().map(|v| v.as_ref().clone()).oratype(conn), + Value::Bytes(v) => v.as_ref().map(|v| v.as_ref().clone()).oratype(conn), + // #[cfg(feature = "with-json")] + // Value::Json(v) => v.map(|v| v.as_ref().clone()).oratype(conn), + Value::ChronoDate(v) => v.as_ref().map(|v| *v.as_ref()).oratype(conn), + // Value::ChronoTime(v) => v.map(|v| v.as_ref().clone()).oratype(conn), + Value::ChronoDateTime(v) => v.as_ref().map(|v| *v.as_ref()).oratype(conn), + Value::ChronoDateTimeUtc(v) => v.as_ref().map(|v| *v.as_ref()).oratype(conn), + Value::ChronoDateTimeLocal(v) => v.as_ref().map(|v| *v.as_ref()).oratype(conn), + Value::ChronoDateTimeWithTimeZone(v) => { + v.as_ref().map(|v| *v.as_ref()).oratype(conn) + } + // Value::TimeDate(v) => v.map(|v| v.as_ref().clone()).oratype(conn), + // Value::TimeTime(v) => v.map(|v| v.as_ref().clone()).oratype(conn), + // Value::TimeDateTime(v) => v.map(|v| v.as_ref().clone()).oratype(conn), + // Value::TimeDateTimeWithTimeZone(v) => v.map(|v| v.as_ref().clone()).oratype(conn), + // Value::Uuid(v) => v.map(|v| v.as_ref().clone()).oratype(conn), + // #[cfg(feature = "with-rust_decimal")] + // Value::Decimal(v) => v.map(|v| v.as_ref().clone().into()).oratype(conn), + #[cfg(feature = "with-bigdecimal")] + Value::BigDecimal(v) => v + .as_ref() + .map(|v| v.as_ref().clone().to_string()) // TODO: this is probably wrong + .oratype(conn), + v => unimplemented!("{v:?}"), + } + } + + fn to_sql( + &self, + val: &mut r2d2_oracle::oracle::SqlValue, + ) -> r2d2_oracle::oracle::Result<()> { + todo!() + } + } +} + pub trait ValueType: Sized { fn try_from(v: Value) -> Result; From 966d48937120f5d77fbf40a20dd741c1f8679b15 Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Thu, 28 Apr 2022 21:30:55 +0200 Subject: [PATCH 09/13] fix features --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 713d2cac1..e622350a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,9 +60,9 @@ backend-postgres = [] backend-sqlite = [] backend-oracle = ["oracle-overrides"] -oracle-overrides = ["r2d2-oracle"] +oracle-overrides = ["r2d2-oracle", "with-chrono"] -default = ["derive", "backend-mysql", "backend-sqlite", "backend-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"] From 4bb416856638cc18b00129d2782db4de36e594b0 Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Thu, 28 Apr 2022 21:44:35 +0200 Subject: [PATCH 10/13] add to-sql impl --- src/value.rs | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/value.rs b/src/value.rs index 3ec4c224e..2707ed156 100644 --- a/src/value.rs +++ b/src/value.rs @@ -168,9 +168,46 @@ pub mod oracle_overrides { fn to_sql( &self, - val: &mut r2d2_oracle::oracle::SqlValue, + conn: &mut r2d2_oracle::oracle::SqlValue, ) -> r2d2_oracle::oracle::Result<()> { - todo!() + match self { + Value::Bool(v) => v.to_sql(conn), + Value::TinyInt(v) => v.to_sql(conn), + Value::SmallInt(v) => v.to_sql(conn), + Value::Int(v) => v.to_sql(conn), + Value::BigInt(v) => v.to_sql(conn), + Value::TinyUnsigned(v) => v.to_sql(conn), + Value::SmallUnsigned(v) => v.to_sql(conn), + Value::Unsigned(v) => v.to_sql(conn), + Value::BigUnsigned(v) => v.to_sql(conn), + Value::Float(v) => v.to_sql(conn), + Value::Double(v) => v.to_sql(conn), + Value::String(v) => v.as_ref().map(|v| v.as_ref().clone()).to_sql(conn), + Value::Bytes(v) => v.as_ref().map(|v| v.as_ref().clone()).to_sql(conn), + // #[cfg(feature = "with-json")] + // Value::Json(v) => v.map(|v| v.as_ref().clone()).to_sql(conn), + Value::ChronoDate(v) => v.as_ref().map(|v| *v.as_ref()).to_sql(conn), + // Value::ChronoTime(v) => v.map(|v| v.as_ref().clone()).to_sql(conn), + Value::ChronoDateTime(v) => v.as_ref().map(|v| *v.as_ref()).to_sql(conn), + Value::ChronoDateTimeUtc(v) => v.as_ref().map(|v| *v.as_ref()).to_sql(conn), + Value::ChronoDateTimeLocal(v) => v.as_ref().map(|v| *v.as_ref()).to_sql(conn), + Value::ChronoDateTimeWithTimeZone(v) => { + v.as_ref().map(|v| *v.as_ref()).to_sql(conn) + } + // Value::TimeDate(v) => v.map(|v| v.as_ref().clone()).to_sql(conn), + // Value::TimeTime(v) => v.map(|v| v.as_ref().clone()).to_sql(conn), + // Value::TimeDateTime(v) => v.map(|v| v.as_ref().clone()).to_sql(conn), + // Value::TimeDateTimeWithTimeZone(v) => v.map(|v| v.as_ref().clone()).to_sql(conn), + // Value::Uuid(v) => v.map(|v| v.as_ref().clone()).to_sql(conn), + // #[cfg(feature = "with-rust_decimal")] + // Value::Decimal(v) => v.map(|v| v.as_ref().clone().into()).to_sql(conn), + #[cfg(feature = "with-bigdecimal")] + Value::BigDecimal(v) => v + .as_ref() + .map(|v| v.as_ref().clone().to_string()) // TODO: this is probably wrong + .to_sql(conn), + v => unimplemented!("{v:?}"), + } } } } From 8c9311dcd4c9a7a4e831d40e2ef785db4c0708cc Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Fri, 29 Apr 2022 20:46:35 +0200 Subject: [PATCH 11/13] use dev version of rust-oracle to use proc macros --- Cargo.toml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e622350a3..4c1e1268a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,11 +49,18 @@ uuid = { version = "^0", optional = true } proc-macro2 = { version = "1", optional = true } quote = { version = "^1", optional = true } time = { version = "^0.2", optional = true } -r2d2-oracle = {version = "0.5.0", optional = true, features = ["chrono"] } + +[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 = [] From 16f513496cba1566b74049e56b10d3007b83b1c3 Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Fri, 29 Apr 2022 21:04:07 +0200 Subject: [PATCH 12/13] oracle placeholder updated --- src/backend/oracle/query.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/oracle/query.rs b/src/backend/oracle/query.rs index c556f1207..70d800caa 100644 --- a/src/backend/oracle/query.rs +++ b/src/backend/oracle/query.rs @@ -3,7 +3,7 @@ use super::*; impl QueryBuilder for OracleQueryBuilder { fn placeholder(&self) -> (&str, bool) { - ("$", true) + (":", true) } fn if_null_function(&self) -> &str { From 329dbfe7748815cf30b5260a4da6d7a622874aea Mon Sep 17 00:00:00 2001 From: niedzwiedzw Date: Sat, 7 May 2022 00:22:34 +0200 Subject: [PATCH 13/13] non-destructive overrides --- src/backend/oracle/query.rs | 210 +++++++++++++++++++++++++++++++++++ src/backend/query_builder.rs | 108 ++++++------------ src/value.rs | 2 + 3 files changed, 244 insertions(+), 76 deletions(-) diff --git a/src/backend/oracle/query.rs b/src/backend/oracle/query.rs index 70d800caa..f61157f94 100644 --- a/src/backend/oracle/query.rs +++ b/src/backend/oracle/query.rs @@ -107,4 +107,214 @@ impl QueryBuilder for OracleQueryBuilder { ) { query.prepare_statement(self, sql, collector); } + + /// Translate [`SelectExpr`] into oracle SQL statement. + fn prepare_select_expr( + &self, + select_expr: &SelectExpr, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + self.prepare_simple_expr(&select_expr.expr, sql, collector); + match &select_expr.window { + Some(WindowSelectType::Name(name)) => { + write!(sql, " OVER ").unwrap(); + name.prepare(sql, self.quote()) + } + Some(WindowSelectType::Query(window)) => { + write!(sql, " OVER ").unwrap(); + write!(sql, "( ").unwrap(); + self.prepare_window_statement(window, sql, collector); + write!(sql, " ) ").unwrap(); + } + None => {} + }; + // oracle override + match &select_expr.alias { + Some(alias) => { + write!(sql, " ").unwrap(); + alias.prepare(sql, self.quote()); + } + None => {} + }; + } + + /// Translate [`SelectStatement`] into oracle SQL statement. + fn prepare_select_statement( + &self, + select: &SelectStatement, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + write!(sql, "SELECT ").unwrap(); + + if let Some(distinct) = &select.distinct { + write!(sql, " ").unwrap(); + self.prepare_select_distinct(distinct, sql, collector); + write!(sql, " ").unwrap(); + } + + select.selects.iter().fold(true, |first, expr| { + if !first { + write!(sql, ", ").unwrap() + } + self.prepare_select_expr(expr, sql, collector); + false + }); + + if !select.from.is_empty() { + write!(sql, " FROM ").unwrap(); + select.from.iter().fold(true, |first, table_ref| { + if !first { + write!(sql, ", ").unwrap() + } + backend::query_builder::QueryBuilder::prepare_table_ref( + self, table_ref, sql, collector, + ); + false + }); + } + + if !select.join.is_empty() { + for expr in select.join.iter() { + write!(sql, " ").unwrap(); + self.prepare_join_expr(expr, sql, collector); + } + } + + self.prepare_condition(&select.r#where, "WHERE", sql, collector); + + if !select.groups.is_empty() { + write!(sql, " GROUP BY ").unwrap(); + select.groups.iter().fold(true, |first, expr| { + if !first { + write!(sql, ", ").unwrap() + } + self.prepare_simple_expr(expr, sql, collector); + false + }); + } + + self.prepare_condition(&select.having, "HAVING", sql, collector); + + if !select.unions.is_empty() { + select.unions.iter().for_each(|(union_type, query)| { + match union_type { + UnionType::Distinct => write!(sql, " UNION ").unwrap(), + UnionType::All => write!(sql, " UNION ALL ").unwrap(), + } + self.prepare_select_statement(query, sql, collector); + }); + } + + if !select.orders.is_empty() { + write!(sql, " ORDER BY ").unwrap(); + select.orders.iter().fold(true, |first, expr| { + if !first { + write!(sql, ", ").unwrap() + } + self.prepare_order_expr(expr, sql, collector); + false + }); + } + + // oracle override - requires oracle 11c or later! + if let Some(offset) = &select.offset { + write!(sql, " OFFSET ").unwrap(); + self.prepare_value(offset, sql, collector); + write!(sql, " ROWS ").unwrap(); + } + + if let Some(limit) = &select.limit { + write!(sql, " FETCH NEXT ").unwrap(); + self.prepare_value(limit, sql, collector); + write!(sql, " ROWS ONLY ").unwrap(); + } + + if let Some(lock) = &select.lock { + write!(sql, " ").unwrap(); + self.prepare_select_lock(lock, sql, collector); + } + + if let Some((name, query)) = &select.window { + write!(sql, " WINDOW ").unwrap(); + name.prepare(sql, self.quote()); + write!(sql, " AS ").unwrap(); + self.prepare_window_statement(query, sql, collector); + } + } + /// Oracle override. + fn prepare_table_ref_common( + &self, + table_ref: &TableRef, + sql: &mut SqlWriter, + collector: &mut dyn FnMut(Value), + ) { + match table_ref { + TableRef::Table(iden) => { + iden.prepare(sql, self.quote()); + } + TableRef::SchemaTable(schema, table) => { + schema.prepare(sql, self.quote()); + write!(sql, ".").unwrap(); + table.prepare(sql, self.quote()); + } + TableRef::DatabaseSchemaTable(database, schema, table) => { + database.prepare(sql, self.quote()); + write!(sql, ".").unwrap(); + schema.prepare(sql, self.quote()); + write!(sql, ".").unwrap(); + table.prepare(sql, self.quote()); + } + TableRef::TableAlias(iden, alias) => { + iden.prepare(sql, self.quote()); + write!(sql, " AS ").unwrap(); + alias.prepare(sql, self.quote()); + } + TableRef::SchemaTableAlias(schema, table, alias) => { + schema.prepare(sql, self.quote()); + write!(sql, ".").unwrap(); + table.prepare(sql, self.quote()); + write!(sql, " AS ").unwrap(); + alias.prepare(sql, self.quote()); + } + TableRef::DatabaseSchemaTableAlias(database, schema, table, alias) => { + database.prepare(sql, self.quote()); + write!(sql, ".").unwrap(); + schema.prepare(sql, self.quote()); + write!(sql, ".").unwrap(); + table.prepare(sql, self.quote()); + write!(sql, " AS ").unwrap(); + alias.prepare(sql, self.quote()); + } + TableRef::SubQuery(query, alias) => { + // oracle override + write!(sql, "(").unwrap(); + self.prepare_select_statement(query, sql, collector); + write!(sql, ")").unwrap(); + write!(sql, " ").unwrap(); + alias.prepare(sql, self.quote()); + } + } + } + + /// Translate [`JoinType`] into oracle SQL statement. + fn prepare_join_type( + &self, + join_type: &JoinType, + sql: &mut SqlWriter, + _collector: &mut dyn FnMut(Value), + ) { + write!( + sql, + "{}", + match join_type { + JoinType::Join => "JOIN", + JoinType::InnerJoin => "JOIN", + JoinType::LeftJoin => "LEFT OUTER JOIN", + JoinType::RightJoin => "RIGHT JOIN", + } + ) + .unwrap() + } } diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index f3076175f..963be5f0f 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -140,28 +140,15 @@ pub trait QueryBuilder: QuotedBuilder { false }); } - // OVERRIDE - if cfg!(feature = "oracle-overrides") { - if let Some(offset) = &select.offset { - write!(sql, " OFFSET ").unwrap(); - self.prepare_value(offset, sql, collector); - write!(sql, " ROWS ").unwrap(); - } - if let Some(limit) = &select.limit { - write!(sql, " FETCH NEXT ").unwrap(); - self.prepare_value(limit, sql, collector); - write!(sql, " ROWS ONLY ").unwrap(); - } - } else { - if let Some(limit) = &select.limit { - write!(sql, " LIMIT ").unwrap(); - self.prepare_value(limit, sql, collector); - } - if let Some(offset) = &select.offset { - write!(sql, " OFFSET ").unwrap(); - self.prepare_value(offset, sql, collector); - } + if let Some(limit) = &select.limit { + write!(sql, " LIMIT ").unwrap(); + self.prepare_value(limit, sql, collector); + } + + if let Some(offset) = &select.offset { + write!(sql, " OFFSET ").unwrap(); + self.prepare_value(offset, sql, collector); } if let Some(lock) = &select.lock { @@ -496,23 +483,14 @@ pub trait QueryBuilder: QuotedBuilder { } None => {} }; - if cfg!(feature = "oracle-overrides") { - match &select_expr.alias { - Some(alias) => { - write!(sql, " ").unwrap(); - alias.prepare(sql, self.quote()); - } - None => {} - }; - } else { - match &select_expr.alias { - Some(alias) => { - write!(sql, " AS ").unwrap(); - alias.prepare(sql, self.quote()); - } - None => {} - }; - } + + match &select_expr.alias { + Some(alias) => { + write!(sql, " AS ").unwrap(); + alias.prepare(sql, self.quote()); + } + None => {} + }; } /// Translate [`JoinExpr`] into SQL statement. @@ -597,19 +575,11 @@ pub trait QueryBuilder: QuotedBuilder { alias.prepare(sql, self.quote()); } TableRef::SubQuery(query, alias) => { - if cfg!(feature = "oracle-overrides") { - write!(sql, "(").unwrap(); - self.prepare_select_statement(query, sql, collector); - write!(sql, ")").unwrap(); - write!(sql, " ").unwrap(); - alias.prepare(sql, self.quote()); - } else { - write!(sql, "(").unwrap(); - self.prepare_select_statement(query, sql, collector); - write!(sql, ")").unwrap(); - write!(sql, " AS ").unwrap(); - alias.prepare(sql, self.quote()); - } + write!(sql, "(").unwrap(); + self.prepare_select_statement(query, sql, collector); + write!(sql, ")").unwrap(); + write!(sql, " AS ").unwrap(); + alias.prepare(sql, self.quote()); } } } @@ -938,31 +908,17 @@ pub trait QueryBuilder: QuotedBuilder { sql: &mut SqlWriter, _collector: &mut dyn FnMut(Value), ) { - if cfg!(feature = "oracle-overrides") { - write!( - sql, - "{}", - match join_type { - JoinType::Join => "JOIN", - JoinType::InnerJoin => "JOIN", - JoinType::LeftJoin => "LEFT OUTER JOIN", - JoinType::RightJoin => "RIGHT JOIN", - } - ) - .unwrap() - } else { - write!( - sql, - "{}", - match join_type { - JoinType::Join => "JOIN", - JoinType::InnerJoin => "INNER JOIN", - JoinType::LeftJoin => "LEFT JOIN", - JoinType::RightJoin => "RIGHT JOIN", - } - ) - .unwrap() - } + write!( + sql, + "{}", + match join_type { + JoinType::Join => "JOIN", + JoinType::InnerJoin => "INNER JOIN", + JoinType::LeftJoin => "LEFT JOIN", + JoinType::RightJoin => "RIGHT JOIN", + } + ) + .unwrap() } /// Translate [`OrderExpr`] into SQL statement. diff --git a/src/value.rs b/src/value.rs index 2707ed156..00ea755b3 100644 --- a/src/value.rs +++ b/src/value.rs @@ -111,6 +111,7 @@ pub mod oracle_overrides { use r2d2_oracle::oracle::sql_type::ToSql; // /// 2021-07-14T23:59:59 + // this works in my project, no idea if this helps anyone // const CLIENT_DATETIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S"; // const DB_DATETIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S"; @@ -122,6 +123,7 @@ pub mod oracle_overrides { // } impl ToSql for Value { + /// I've commented out values I didn't know how to handle fn oratype( &self, conn: &r2d2_oracle::oracle::Connection,