Casting columns as a different data type on select, insert and update (#1304)
* Cast select and value * Refactoring * Test casting Postgres citext * Fixup * Revert * Add test cases * Fixup * Rename methods
This commit is contained in:
parent
bb5dead0c8
commit
e9df3aa01d
@ -63,6 +63,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
// generate Column enum and it's ColumnTrait impl
|
// generate Column enum and it's ColumnTrait impl
|
||||||
let mut columns_enum: Punctuated<_, Comma> = Punctuated::new();
|
let mut columns_enum: Punctuated<_, Comma> = Punctuated::new();
|
||||||
let mut columns_trait: Punctuated<_, Comma> = Punctuated::new();
|
let mut columns_trait: Punctuated<_, Comma> = Punctuated::new();
|
||||||
|
let mut columns_select_as: Punctuated<_, Comma> = Punctuated::new();
|
||||||
|
let mut columns_save_as: Punctuated<_, Comma> = Punctuated::new();
|
||||||
let mut primary_keys: Punctuated<_, Comma> = Punctuated::new();
|
let mut primary_keys: Punctuated<_, Comma> = Punctuated::new();
|
||||||
let mut primary_key_types: Punctuated<_, Comma> = Punctuated::new();
|
let mut primary_key_types: Punctuated<_, Comma> = Punctuated::new();
|
||||||
let mut auto_increment = true;
|
let mut auto_increment = true;
|
||||||
@ -90,6 +92,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
let mut nullable = false;
|
let mut nullable = false;
|
||||||
let mut default_value = None;
|
let mut default_value = None;
|
||||||
let mut default_expr = None;
|
let mut default_expr = None;
|
||||||
|
let mut select_as = None;
|
||||||
|
let mut save_as = None;
|
||||||
let mut indexed = false;
|
let mut indexed = false;
|
||||||
let mut ignore = false;
|
let mut ignore = false;
|
||||||
let mut unique = false;
|
let mut unique = false;
|
||||||
@ -169,6 +173,24 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
format!("Invalid enum_name {:?}", nv.lit),
|
format!("Invalid enum_name {:?}", nv.lit),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
} else if name == "select_as" {
|
||||||
|
if let Lit::Str(litstr) = &nv.lit {
|
||||||
|
select_as = Some(litstr.value());
|
||||||
|
} else {
|
||||||
|
return Err(Error::new(
|
||||||
|
field.span(),
|
||||||
|
format!("Invalid select_as {:?}", nv.lit),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else if name == "save_as" {
|
||||||
|
if let Lit::Str(litstr) = &nv.lit {
|
||||||
|
save_as = Some(litstr.value());
|
||||||
|
} else {
|
||||||
|
return Err(Error::new(
|
||||||
|
field.span(),
|
||||||
|
format!("Invalid save_as {:?}", nv.lit),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,6 +246,23 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(select_as) = select_as {
|
||||||
|
columns_select_as.push(quote! {
|
||||||
|
Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as(
|
||||||
|
Into::<sea_orm::sea_query::SimpleExpr>::into(expr),
|
||||||
|
sea_orm::sea_query::Alias::new(&#select_as),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if let Some(save_as) = save_as {
|
||||||
|
columns_save_as.push(quote! {
|
||||||
|
Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as(
|
||||||
|
Into::<sea_orm::sea_query::SimpleExpr>::into(val),
|
||||||
|
sea_orm::sea_query::Alias::new(&#save_as),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let field_type = &field.ty;
|
let field_type = &field.ty;
|
||||||
let field_type = quote! { #field_type }
|
let field_type = quote! { #field_type }
|
||||||
.to_string() //E.g.: "Option < String >"
|
.to_string() //E.g.: "Option < String >"
|
||||||
@ -347,6 +386,20 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
#columns_trait
|
#columns_trait
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn select_as(&self, expr: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr {
|
||||||
|
match self {
|
||||||
|
#columns_select_as
|
||||||
|
_ => sea_orm::prelude::ColumnTrait::select_enum_as(self, expr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_as(&self, val: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr {
|
||||||
|
match self {
|
||||||
|
#columns_save_as
|
||||||
|
_ => sea_orm::prelude::ColumnTrait::save_enum_as(self, val),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#entity_def
|
#entity_def
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use crate::{cast_text_as_enum, EntityName, IdenStatic, IntoSimpleExpr, Iterable};
|
use crate::{EntityName, IdenStatic, IntoSimpleExpr, Iterable};
|
||||||
use sea_query::{BinOper, DynIden, Expr, SeaRc, SelectStatement, SimpleExpr, Value};
|
use sea_query::{
|
||||||
|
Alias, BinOper, DynIden, Expr, Iden, IntoIden, SeaRc, SelectStatement, SimpleExpr, Value,
|
||||||
|
};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
/// Defines a Column for an Entity
|
/// Defines a Column for an Entity
|
||||||
@ -134,7 +136,7 @@ macro_rules! bind_oper_with_enum_casting {
|
|||||||
where
|
where
|
||||||
V: Into<Value>,
|
V: Into<Value>,
|
||||||
{
|
{
|
||||||
let expr = cast_text_as_enum(Expr::val(v), self);
|
let expr = self.save_as(Expr::val(v));
|
||||||
Expr::col((self.entity_name(), *self)).binary(BinOper::$bin_op, expr)
|
Expr::col((self.entity_name(), *self)).binary(BinOper::$bin_op, expr)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -338,6 +340,42 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr {
|
|||||||
fn into_expr(self) -> Expr {
|
fn into_expr(self) -> Expr {
|
||||||
Expr::expr(self.into_simple_expr())
|
Expr::expr(self.into_simple_expr())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cast column expression used in select statement.
|
||||||
|
/// By default it only cast database enum as text.
|
||||||
|
fn select_as(&self, expr: Expr) -> SimpleExpr {
|
||||||
|
self.select_enum_as(expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cast enum column as text
|
||||||
|
fn select_enum_as(&self, expr: Expr) -> SimpleExpr {
|
||||||
|
cast_enum_as(expr, self, |col, _, col_type| {
|
||||||
|
let type_name = match col_type {
|
||||||
|
ColumnType::Array(_) => TextArray.into_iden(),
|
||||||
|
_ => Text.into_iden(),
|
||||||
|
};
|
||||||
|
col.as_enum(type_name)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cast value of a column into the correct type for database storage.
|
||||||
|
/// By default it only cast text as enum type if it's an enum column.
|
||||||
|
fn save_as(&self, val: Expr) -> SimpleExpr {
|
||||||
|
self.save_enum_as(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cast value of a enum column as enum type
|
||||||
|
fn save_enum_as(&self, val: Expr) -> SimpleExpr {
|
||||||
|
cast_enum_as(val, self, |col, enum_name, col_type| {
|
||||||
|
let type_name = match col_type {
|
||||||
|
ColumnType::Array(_) => {
|
||||||
|
Alias::new(&format!("{}[]", enum_name.to_string())).into_iden()
|
||||||
|
}
|
||||||
|
_ => enum_name,
|
||||||
|
};
|
||||||
|
col.as_enum(type_name)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColumnType {
|
impl ColumnType {
|
||||||
@ -513,6 +551,26 @@ impl From<sea_query::ColumnType> for ColumnType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Iden)]
|
||||||
|
struct Text;
|
||||||
|
|
||||||
|
#[derive(Iden)]
|
||||||
|
#[iden = "text[]"]
|
||||||
|
struct TextArray;
|
||||||
|
|
||||||
|
fn cast_enum_as<C, F>(expr: Expr, col: &C, f: F) -> SimpleExpr
|
||||||
|
where
|
||||||
|
C: ColumnTrait,
|
||||||
|
F: Fn(Expr, DynIden, &ColumnType) -> SimpleExpr,
|
||||||
|
{
|
||||||
|
let col_def = col.def();
|
||||||
|
let col_type = col_def.get_column_type();
|
||||||
|
match col_type.get_enum_name() {
|
||||||
|
Some(enum_name) => f(expr, SeaRc::clone(enum_name), col_type),
|
||||||
|
None => expr.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -1017,4 +1075,414 @@ mod tests {
|
|||||||
assert_eq!(my_entity::Column::IdentityColumn.to_string().as_str(), "id");
|
assert_eq!(my_entity::Column::IdentityColumn.to_string().as_str(), "id");
|
||||||
assert_eq!(my_entity::Column::Type.to_string().as_str(), "type");
|
assert_eq!(my_entity::Column::Type.to_string().as_str(), "type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "macros")]
|
||||||
|
fn select_as_1() {
|
||||||
|
use crate::{ActiveModelTrait, ActiveValue, Update};
|
||||||
|
|
||||||
|
mod hello_expanded {
|
||||||
|
use crate as sea_orm;
|
||||||
|
use crate::entity::prelude::*;
|
||||||
|
use crate::sea_query::{Alias, Expr, SimpleExpr};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
|
||||||
|
pub struct Entity;
|
||||||
|
|
||||||
|
impl EntityName for Entity {
|
||||||
|
fn table_name(&self) -> &str {
|
||||||
|
"hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
|
||||||
|
pub struct Model {
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(enum_name = "One1")]
|
||||||
|
pub one: i32,
|
||||||
|
pub two: i32,
|
||||||
|
#[sea_orm(enum_name = "Three3")]
|
||||||
|
pub three: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
One1,
|
||||||
|
Two,
|
||||||
|
Three3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColumnTrait for Column {
|
||||||
|
type EntityName = Entity;
|
||||||
|
|
||||||
|
fn def(&self) -> ColumnDef {
|
||||||
|
match self {
|
||||||
|
Column::Id => ColumnType::Integer.def(),
|
||||||
|
Column::One1 => ColumnType::Integer.def(),
|
||||||
|
Column::Two => ColumnType::Integer.def(),
|
||||||
|
Column::Three3 => ColumnType::Integer.def(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_as(&self, expr: Expr) -> SimpleExpr {
|
||||||
|
match self {
|
||||||
|
Self::Two => SimpleExpr::cast_as(
|
||||||
|
Into::<SimpleExpr>::into(expr),
|
||||||
|
Alias::new("integer"),
|
||||||
|
),
|
||||||
|
_ => self.select_enum_as(expr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
|
mod hello_compact {
|
||||||
|
use crate as sea_orm;
|
||||||
|
use crate::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "hello")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(enum_name = "One1")]
|
||||||
|
pub one: i32,
|
||||||
|
#[sea_orm(select_as = "integer")]
|
||||||
|
pub two: i32,
|
||||||
|
#[sea_orm(enum_name = "Three3")]
|
||||||
|
pub three: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_it<E, A>(active_model: A)
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
A: ActiveModelTrait<Entity = E>,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
E::find().build(DbBackend::Postgres).to_string(),
|
||||||
|
r#"SELECT "hello"."id", "hello"."one1", CAST("hello"."two" AS integer), "hello"."three3" FROM "hello""#,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Update::one(active_model)
|
||||||
|
.build(DbBackend::Postgres)
|
||||||
|
.to_string(),
|
||||||
|
r#"UPDATE "hello" SET "one1" = 1, "two" = 2, "three3" = 3 WHERE "hello"."id" = 1"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_it(hello_expanded::ActiveModel {
|
||||||
|
id: ActiveValue::set(1),
|
||||||
|
one: ActiveValue::set(1),
|
||||||
|
two: ActiveValue::set(2),
|
||||||
|
three: ActiveValue::set(3),
|
||||||
|
});
|
||||||
|
assert_it(hello_compact::ActiveModel {
|
||||||
|
id: ActiveValue::set(1),
|
||||||
|
one: ActiveValue::set(1),
|
||||||
|
two: ActiveValue::set(2),
|
||||||
|
three: ActiveValue::set(3),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "macros")]
|
||||||
|
fn save_as_1() {
|
||||||
|
use crate::{ActiveModelTrait, ActiveValue, Update};
|
||||||
|
|
||||||
|
mod hello_expanded {
|
||||||
|
use crate as sea_orm;
|
||||||
|
use crate::entity::prelude::*;
|
||||||
|
use crate::sea_query::{Alias, Expr, SimpleExpr};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
|
||||||
|
pub struct Entity;
|
||||||
|
|
||||||
|
impl EntityName for Entity {
|
||||||
|
fn table_name(&self) -> &str {
|
||||||
|
"hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
|
||||||
|
pub struct Model {
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(enum_name = "One1")]
|
||||||
|
pub one: i32,
|
||||||
|
pub two: i32,
|
||||||
|
#[sea_orm(enum_name = "Three3")]
|
||||||
|
pub three: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
One1,
|
||||||
|
Two,
|
||||||
|
Three3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColumnTrait for Column {
|
||||||
|
type EntityName = Entity;
|
||||||
|
|
||||||
|
fn def(&self) -> ColumnDef {
|
||||||
|
match self {
|
||||||
|
Column::Id => ColumnType::Integer.def(),
|
||||||
|
Column::One1 => ColumnType::Integer.def(),
|
||||||
|
Column::Two => ColumnType::Integer.def(),
|
||||||
|
Column::Three3 => ColumnType::Integer.def(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_as(&self, expr: Expr) -> SimpleExpr {
|
||||||
|
match self {
|
||||||
|
Self::Two => {
|
||||||
|
SimpleExpr::cast_as(Into::<SimpleExpr>::into(expr), Alias::new("text"))
|
||||||
|
}
|
||||||
|
_ => self.save_enum_as(expr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
|
mod hello_compact {
|
||||||
|
use crate as sea_orm;
|
||||||
|
use crate::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "hello")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(enum_name = "One1")]
|
||||||
|
pub one: i32,
|
||||||
|
#[sea_orm(save_as = "text")]
|
||||||
|
pub two: i32,
|
||||||
|
#[sea_orm(enum_name = "Three3")]
|
||||||
|
pub three: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_it<E, A>(active_model: A)
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
A: ActiveModelTrait<Entity = E>,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
E::find().build(DbBackend::Postgres).to_string(),
|
||||||
|
r#"SELECT "hello"."id", "hello"."one1", "hello"."two", "hello"."three3" FROM "hello""#,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Update::one(active_model)
|
||||||
|
.build(DbBackend::Postgres)
|
||||||
|
.to_string(),
|
||||||
|
r#"UPDATE "hello" SET "one1" = 1, "two" = CAST(2 AS text), "three3" = 3 WHERE "hello"."id" = 1"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_it(hello_expanded::ActiveModel {
|
||||||
|
id: ActiveValue::set(1),
|
||||||
|
one: ActiveValue::set(1),
|
||||||
|
two: ActiveValue::set(2),
|
||||||
|
three: ActiveValue::set(3),
|
||||||
|
});
|
||||||
|
assert_it(hello_compact::ActiveModel {
|
||||||
|
id: ActiveValue::set(1),
|
||||||
|
one: ActiveValue::set(1),
|
||||||
|
two: ActiveValue::set(2),
|
||||||
|
three: ActiveValue::set(3),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "macros")]
|
||||||
|
fn select_as_and_value_1() {
|
||||||
|
use crate::{ActiveModelTrait, ActiveValue, Update};
|
||||||
|
|
||||||
|
mod hello_expanded {
|
||||||
|
use crate as sea_orm;
|
||||||
|
use crate::entity::prelude::*;
|
||||||
|
use crate::sea_query::{Alias, Expr, SimpleExpr};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
|
||||||
|
pub struct Entity;
|
||||||
|
|
||||||
|
impl EntityName for Entity {
|
||||||
|
fn table_name(&self) -> &str {
|
||||||
|
"hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
|
||||||
|
pub struct Model {
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(enum_name = "One1")]
|
||||||
|
pub one: i32,
|
||||||
|
pub two: i32,
|
||||||
|
#[sea_orm(enum_name = "Three3")]
|
||||||
|
pub three: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
One1,
|
||||||
|
Two,
|
||||||
|
Three3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColumnTrait for Column {
|
||||||
|
type EntityName = Entity;
|
||||||
|
|
||||||
|
fn def(&self) -> ColumnDef {
|
||||||
|
match self {
|
||||||
|
Column::Id => ColumnType::Integer.def(),
|
||||||
|
Column::One1 => ColumnType::Integer.def(),
|
||||||
|
Column::Two => ColumnType::Integer.def(),
|
||||||
|
Column::Three3 => ColumnType::Integer.def(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_as(&self, expr: Expr) -> SimpleExpr {
|
||||||
|
match self {
|
||||||
|
Self::Two => SimpleExpr::cast_as(
|
||||||
|
Into::<SimpleExpr>::into(expr),
|
||||||
|
Alias::new("integer"),
|
||||||
|
),
|
||||||
|
_ => self.select_enum_as(expr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_as(&self, expr: Expr) -> SimpleExpr {
|
||||||
|
match self {
|
||||||
|
Self::Two => {
|
||||||
|
SimpleExpr::cast_as(Into::<SimpleExpr>::into(expr), Alias::new("text"))
|
||||||
|
}
|
||||||
|
_ => self.save_enum_as(expr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
|
mod hello_compact {
|
||||||
|
use crate as sea_orm;
|
||||||
|
use crate::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "hello")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(enum_name = "One1")]
|
||||||
|
pub one: i32,
|
||||||
|
#[sea_orm(select_as = "integer", save_as = "text")]
|
||||||
|
pub two: i32,
|
||||||
|
#[sea_orm(enum_name = "Three3")]
|
||||||
|
pub three: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_it<E, A>(active_model: A)
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
A: ActiveModelTrait<Entity = E>,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
E::find().build(DbBackend::Postgres).to_string(),
|
||||||
|
r#"SELECT "hello"."id", "hello"."one1", CAST("hello"."two" AS integer), "hello"."three3" FROM "hello""#,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Update::one(active_model)
|
||||||
|
.build(DbBackend::Postgres)
|
||||||
|
.to_string(),
|
||||||
|
r#"UPDATE "hello" SET "one1" = 1, "two" = CAST(2 AS text), "three3" = 3 WHERE "hello"."id" = 1"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_it(hello_expanded::ActiveModel {
|
||||||
|
id: ActiveValue::set(1),
|
||||||
|
one: ActiveValue::set(1),
|
||||||
|
two: ActiveValue::set(2),
|
||||||
|
three: ActiveValue::set(3),
|
||||||
|
});
|
||||||
|
assert_it(hello_compact::ActiveModel {
|
||||||
|
id: ActiveValue::set(1),
|
||||||
|
one: ActiveValue::set(1),
|
||||||
|
two: ActiveValue::set(2),
|
||||||
|
three: ActiveValue::set(3),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
cast_enum_as_text, error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, Insert,
|
error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, Insert, IntoActiveModel,
|
||||||
IntoActiveModel, Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
|
Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
|
||||||
};
|
};
|
||||||
use sea_query::{Expr, FromValueTuple, Iden, InsertStatement, IntoColumnRef, Query, ValueTuple};
|
use sea_query::{Expr, FromValueTuple, Iden, InsertStatement, IntoColumnRef, Query, ValueTuple};
|
||||||
use std::{future::Future, marker::PhantomData};
|
use std::{future::Future, marker::PhantomData};
|
||||||
@ -189,8 +189,7 @@ where
|
|||||||
let found = match db.support_returning() {
|
let found = match db.support_returning() {
|
||||||
true => {
|
true => {
|
||||||
let returning = Query::returning().exprs(
|
let returning = Query::returning().exprs(
|
||||||
<A::Entity as EntityTrait>::Column::iter()
|
<A::Entity as EntityTrait>::Column::iter().map(|c| c.select_as(Expr::col(c))),
|
||||||
.map(|c| cast_enum_as_text(Expr::col(c), &c)),
|
|
||||||
);
|
);
|
||||||
insert_statement.returning(returning);
|
insert_statement.returning(returning);
|
||||||
SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
|
SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
cast_enum_as_text, error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, IntoActiveModel,
|
error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, IntoActiveModel,
|
||||||
Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, UpdateMany, UpdateOne,
|
Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, UpdateMany, UpdateOne,
|
||||||
};
|
};
|
||||||
use sea_query::{Expr, FromValueTuple, Query, UpdateStatement};
|
use sea_query::{Expr, FromValueTuple, Query, UpdateStatement};
|
||||||
@ -95,8 +95,8 @@ where
|
|||||||
type ValueType<A> = <<Entity<A> as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType;
|
type ValueType<A> = <<Entity<A> as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType;
|
||||||
match db.support_returning() {
|
match db.support_returning() {
|
||||||
true => {
|
true => {
|
||||||
let returning = Query::returning()
|
let returning =
|
||||||
.exprs(Column::<A>::iter().map(|c| cast_enum_as_text(Expr::col(c), &c)));
|
Query::returning().exprs(Column::<A>::iter().map(|c| c.select_as(Expr::col(c))));
|
||||||
query.returning(returning);
|
query.returning(returning);
|
||||||
let db_backend = db.get_database_backend();
|
let db_backend = db.get_database_backend();
|
||||||
let found: Option<Model<A>> =
|
let found: Option<Model<A>> =
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
cast_enum_as_text, ColumnTrait, EntityTrait, IdenStatic, Iterable, QueryTrait, Select,
|
ColumnTrait, EntityTrait, IdenStatic, Iterable, QueryTrait, Select, SelectTwo, SelectTwoMany,
|
||||||
SelectTwo, SelectTwoMany,
|
|
||||||
};
|
};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
pub use sea_query::JoinType;
|
pub use sea_query::JoinType;
|
||||||
@ -149,7 +148,7 @@ where
|
|||||||
for col in <F::Column as Iterable>::iter() {
|
for col in <F::Column as Iterable>::iter() {
|
||||||
let alias = format!("{}{}", SelectB.as_str(), col.as_str());
|
let alias = format!("{}{}", SelectB.as_str(), col.as_str());
|
||||||
selector.query().expr(SelectExpr {
|
selector.query().expr(SelectExpr {
|
||||||
expr: cast_enum_as_text(col.into_expr(), &col),
|
expr: col.select_as(col.into_expr()),
|
||||||
alias: Some(SeaRc::new(Alias::new(&alias))),
|
alias: Some(SeaRc::new(Alias::new(&alias))),
|
||||||
window: None,
|
window: None,
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ColumnTrait, ColumnType, EntityTrait, Identity, IntoIdentity, IntoSimpleExpr, Iterable,
|
ColumnTrait, EntityTrait, Identity, IntoIdentity, IntoSimpleExpr, Iterable, ModelTrait,
|
||||||
ModelTrait, PrimaryKeyToColumn, RelationDef,
|
PrimaryKeyToColumn, RelationDef,
|
||||||
};
|
};
|
||||||
use sea_query::{
|
use sea_query::{
|
||||||
Alias, Expr, Iden, IntoCondition, IntoIden, LockType, SeaRc, SelectExpr, SelectStatement,
|
Alias, Expr, Iden, IntoCondition, IntoIden, LockType, SeaRc, SelectExpr, SelectStatement,
|
||||||
@ -67,7 +67,7 @@ pub trait QuerySelect: Sized {
|
|||||||
where
|
where
|
||||||
C: ColumnTrait,
|
C: ColumnTrait,
|
||||||
{
|
{
|
||||||
self.query().expr(cast_enum_as_text(col.into_expr(), &col));
|
self.query().expr(col.select_as(col.into_expr()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,49 +680,3 @@ pub(crate) fn unpack_table_alias(table_ref: &TableRef) -> Option<DynIden> {
|
|||||||
| TableRef::FunctionCall(_, alias) => Some(SeaRc::clone(alias)),
|
| TableRef::FunctionCall(_, alias) => Some(SeaRc::clone(alias)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Iden)]
|
|
||||||
struct Text;
|
|
||||||
|
|
||||||
#[derive(Iden)]
|
|
||||||
#[iden = "text[]"]
|
|
||||||
struct TextArray;
|
|
||||||
|
|
||||||
pub(crate) fn cast_enum_as_text<C>(expr: Expr, col: &C) -> SimpleExpr
|
|
||||||
where
|
|
||||||
C: ColumnTrait,
|
|
||||||
{
|
|
||||||
cast_enum_text_inner(expr, col, |col, _, col_type| {
|
|
||||||
let type_name = match col_type {
|
|
||||||
ColumnType::Array(_) => TextArray.into_iden(),
|
|
||||||
_ => Text.into_iden(),
|
|
||||||
};
|
|
||||||
col.as_enum(type_name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn cast_text_as_enum<C>(expr: Expr, col: &C) -> SimpleExpr
|
|
||||||
where
|
|
||||||
C: ColumnTrait,
|
|
||||||
{
|
|
||||||
cast_enum_text_inner(expr, col, |col, enum_name, col_type| {
|
|
||||||
let type_name = match col_type {
|
|
||||||
ColumnType::Array(_) => Alias::new(&format!("{}[]", enum_name.to_string())).into_iden(),
|
|
||||||
_ => enum_name,
|
|
||||||
};
|
|
||||||
col.as_enum(type_name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cast_enum_text_inner<C, F>(expr: Expr, col: &C, f: F) -> SimpleExpr
|
|
||||||
where
|
|
||||||
C: ColumnTrait,
|
|
||||||
F: Fn(Expr, DynIden, &ColumnType) -> SimpleExpr,
|
|
||||||
{
|
|
||||||
let col_def = col.def();
|
|
||||||
let col_type = col_def.get_column_type();
|
|
||||||
match col_type.get_enum_name() {
|
|
||||||
Some(enum_name) => f(expr, SeaRc::clone(enum_name), col_type),
|
|
||||||
None => expr.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
cast_text_as_enum, ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable,
|
ActiveModelTrait, ColumnTrait, EntityName, EntityTrait, IntoActiveModel, Iterable,
|
||||||
PrimaryKeyTrait, QueryTrait,
|
PrimaryKeyTrait, QueryTrait,
|
||||||
};
|
};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
@ -134,7 +134,7 @@ where
|
|||||||
}
|
}
|
||||||
if av_has_val {
|
if av_has_val {
|
||||||
columns.push(col);
|
columns.push(col);
|
||||||
values.push(cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col));
|
values.push(col.save_as(Expr::val(av.into_value().unwrap())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.query.columns(columns);
|
self.query.columns(columns);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
cast_enum_as_text, join_tbl_on_condition, unpack_table_ref, EntityTrait, IdenStatic, Iterable,
|
join_tbl_on_condition, unpack_table_ref, ColumnTrait, EntityTrait, IdenStatic, Iterable,
|
||||||
Linked, QuerySelect, Related, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,
|
Linked, QuerySelect, Related, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,
|
||||||
};
|
};
|
||||||
pub use sea_query::JoinType;
|
pub use sea_query::JoinType;
|
||||||
@ -100,7 +100,7 @@ where
|
|||||||
col.into_iden(),
|
col.into_iden(),
|
||||||
));
|
));
|
||||||
select_two.query().expr(SelectExpr {
|
select_two.query().expr(SelectExpr {
|
||||||
expr: cast_enum_as_text(expr, &col),
|
expr: col.select_as(expr),
|
||||||
alias: Some(SeaRc::new(Alias::new(&alias))),
|
alias: Some(SeaRc::new(Alias::new(&alias))),
|
||||||
window: None,
|
window: None,
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
use crate::{
|
use crate::{ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect, QueryTrait};
|
||||||
cast_enum_as_text, ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect,
|
|
||||||
QueryTrait,
|
|
||||||
};
|
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
pub use sea_query::JoinType;
|
pub use sea_query::JoinType;
|
||||||
@ -129,7 +126,7 @@ where
|
|||||||
|
|
||||||
fn column_list(&self) -> Vec<SimpleExpr> {
|
fn column_list(&self) -> Vec<SimpleExpr> {
|
||||||
E::Column::iter()
|
E::Column::iter()
|
||||||
.map(|col| cast_enum_as_text(col.into_expr(), &col))
|
.map(|col| col.select_as(col.into_expr()))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
cast_text_as_enum, ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn,
|
ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter,
|
||||||
QueryFilter, QueryTrait,
|
QueryTrait,
|
||||||
};
|
};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use sea_query::{Expr, IntoIden, SimpleExpr, UpdateStatement};
|
use sea_query::{Expr, IntoIden, SimpleExpr, UpdateStatement};
|
||||||
@ -109,7 +109,7 @@ where
|
|||||||
}
|
}
|
||||||
let av = self.model.get(col);
|
let av = self.model.get(col);
|
||||||
if av.is_set() {
|
if av.is_set() {
|
||||||
let expr = cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col);
|
let expr = col.save_as(Expr::val(av.into_value().unwrap()));
|
||||||
self.query.value(col, expr);
|
self.query.value(col, expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ where
|
|||||||
for col in E::Column::iter() {
|
for col in E::Column::iter() {
|
||||||
let av = model.get(col);
|
let av = model.get(col);
|
||||||
if av.is_set() {
|
if av.is_set() {
|
||||||
let expr = cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col);
|
let expr = col.save_as(Expr::val(av.into_value().unwrap()));
|
||||||
self.query.value(col, expr);
|
self.query.value(col, expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Model {
|
Model {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
name: "Collection 1".into(),
|
||||||
integers: vec![1, 2, 3],
|
integers: vec![1, 2, 3],
|
||||||
integers_opt: Some(vec![1, 2, 3]),
|
integers_opt: Some(vec![1, 2, 3]),
|
||||||
teas: vec![Tea::BreakfastTea],
|
teas: vec![Tea::BreakfastTea],
|
||||||
@ -38,6 +39,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
.await?,
|
.await?,
|
||||||
Model {
|
Model {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
name: "Collection 1".into(),
|
||||||
integers: vec![1, 2, 3],
|
integers: vec![1, 2, 3],
|
||||||
integers_opt: Some(vec![1, 2, 3]),
|
integers_opt: Some(vec![1, 2, 3]),
|
||||||
teas: vec![Tea::BreakfastTea],
|
teas: vec![Tea::BreakfastTea],
|
||||||
@ -52,6 +54,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Model {
|
Model {
|
||||||
id: 2,
|
id: 2,
|
||||||
|
name: "Collection 2".into(),
|
||||||
integers: vec![10, 9],
|
integers: vec![10, 9],
|
||||||
integers_opt: None,
|
integers_opt: None,
|
||||||
teas: vec![Tea::BreakfastTea],
|
teas: vec![Tea::BreakfastTea],
|
||||||
@ -66,6 +69,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
.await?,
|
.await?,
|
||||||
Model {
|
Model {
|
||||||
id: 2,
|
id: 2,
|
||||||
|
name: "Collection 2".into(),
|
||||||
integers: vec![10, 9],
|
integers: vec![10, 9],
|
||||||
integers_opt: None,
|
integers_opt: None,
|
||||||
teas: vec![Tea::BreakfastTea],
|
teas: vec![Tea::BreakfastTea],
|
||||||
@ -80,6 +84,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Model {
|
Model {
|
||||||
id: 3,
|
id: 3,
|
||||||
|
name: "Collection 3".into(),
|
||||||
integers: vec![],
|
integers: vec![],
|
||||||
integers_opt: Some(vec![]),
|
integers_opt: Some(vec![]),
|
||||||
teas: vec![],
|
teas: vec![],
|
||||||
@ -94,6 +99,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
.await?,
|
.await?,
|
||||||
Model {
|
Model {
|
||||||
id: 3,
|
id: 3,
|
||||||
|
name: "Collection 3".into(),
|
||||||
integers: vec![],
|
integers: vec![],
|
||||||
integers_opt: Some(vec![]),
|
integers_opt: Some(vec![]),
|
||||||
teas: vec![],
|
teas: vec![],
|
||||||
@ -128,6 +134,7 @@ pub async fn update_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
|
|
||||||
ActiveModel {
|
ActiveModel {
|
||||||
id: Unchanged(3),
|
id: Unchanged(3),
|
||||||
|
name: Set("Collection 3".into()),
|
||||||
integers: Set(vec![3, 1, 4]),
|
integers: Set(vec![3, 1, 4]),
|
||||||
integers_opt: Set(None),
|
integers_opt: Set(None),
|
||||||
teas: Set(vec![Tea::EverydayTea]),
|
teas: Set(vec![Tea::EverydayTea]),
|
||||||
|
@ -6,6 +6,12 @@ use sea_orm::entity::prelude::*;
|
|||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
|
#[sea_orm(
|
||||||
|
column_type = r#"Custom("citext".into())"#,
|
||||||
|
select_as = "text",
|
||||||
|
save_as = "citext"
|
||||||
|
)]
|
||||||
|
pub name: String,
|
||||||
pub integers: Vec<i32>,
|
pub integers: Vec<i32>,
|
||||||
pub integers_opt: Option<Vec<i32>>,
|
pub integers_opt: Option<Vec<i32>>,
|
||||||
pub teas: Vec<Tea>,
|
pub teas: Vec<Tea>,
|
||||||
|
@ -335,6 +335,12 @@ pub async fn create_json_struct_table(db: &DbConn) -> Result<ExecResult, DbErr>
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_collection_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_collection_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
|
db.execute(sea_orm::Statement::from_string(
|
||||||
|
db.get_database_backend(),
|
||||||
|
"CREATE EXTENSION IF NOT EXISTS citext".into(),
|
||||||
|
))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let stmt = sea_query::Table::create()
|
let stmt = sea_query::Table::create()
|
||||||
.table(collection::Entity)
|
.table(collection::Entity)
|
||||||
.col(
|
.col(
|
||||||
@ -344,6 +350,11 @@ pub async fn create_collection_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
.auto_increment()
|
.auto_increment()
|
||||||
.primary_key(),
|
.primary_key(),
|
||||||
)
|
)
|
||||||
|
.col(
|
||||||
|
ColumnDef::new(collection::Column::Name)
|
||||||
|
.custom(Alias::new("citext"))
|
||||||
|
.not_null(),
|
||||||
|
)
|
||||||
.col(
|
.col(
|
||||||
ColumnDef::new(collection::Column::Integers)
|
ColumnDef::new(collection::Column::Integers)
|
||||||
.array(sea_query::ColumnType::Integer)
|
.array(sea_query::ColumnType::Integer)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user