From 9bf6d822f85358780770a71d8c51525e3f27ca1c Mon Sep 17 00:00:00 2001 From: Forest Anderson Date: Wed, 18 Jan 2023 06:09:01 -0500 Subject: [PATCH] Add JsonBinary attribute (#1346) * Add JsonBinary attribute to column * Add Postgres test section, test binary json * Added expanded entity format test * Fixed unit test --- sea-orm-codegen/src/entity/column.rs | 1 + sea-orm-codegen/src/entity/writer.rs | 113 ++++++++++++++++++ sea-orm-codegen/tests/postgres/binary_json.rs | 21 ++++ .../tests/postgres/binary_json_expanded.rs | 65 ++++++++++ 4 files changed, 200 insertions(+) create mode 100644 sea-orm-codegen/tests/postgres/binary_json.rs create mode 100644 sea-orm-codegen/tests/postgres/binary_json_expanded.rs diff --git a/sea-orm-codegen/src/entity/column.rs b/sea-orm-codegen/src/entity/column.rs index bcc1932b3a..fecb71fa44 100644 --- a/sea-orm-codegen/src/entity/column.rs +++ b/sea-orm-codegen/src/entity/column.rs @@ -94,6 +94,7 @@ impl Column { ColumnType::Decimal(Some((p, s))) => Some(format!("Decimal(Some(({}, {})))", p, s)), ColumnType::Money(Some((p, s))) => Some(format!("Money(Some({}, {}))", p, s)), ColumnType::Text => Some("Text".to_owned()), + ColumnType::JsonBinary => Some("JsonBinary".to_owned()), ColumnType::Custom(iden) => { Some(format!("Custom(\"{}\".to_owned())", iden.to_string())) } diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index 21568380b2..e14883e154 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -1957,4 +1957,117 @@ mod tests { Ok(expected.to_string()) } + + #[test] + fn test_gen_postgres() -> io::Result<()> { + let entities = vec![ + // This tests that the JsonBinary column type is annotated + // correctly in compact entity form. More information can be found + // in this issue: + // + // https://github.com/SeaQL/sea-orm/issues/1344 + Entity { + table_name: "task".to_owned(), + columns: vec![ + Column { + name: "id".to_owned(), + col_type: ColumnType::Integer, + auto_increment: true, + not_null: true, + unique: false, + }, + Column { + name: "payload".to_owned(), + col_type: ColumnType::Json, + auto_increment: false, + not_null: true, + unique: false, + }, + Column { + name: "payload_binary".to_owned(), + col_type: ColumnType::JsonBinary, + auto_increment: false, + not_null: true, + unique: false, + }, + ], + relations: vec![], + conjunct_relations: vec![], + primary_keys: vec![PrimaryKey { + name: "id".to_owned(), + }], + }, + ]; + const ENTITY_FILES: [&str; 1] = [include_str!("../../tests/postgres/binary_json.rs")]; + + const ENTITY_FILES_EXPANDED: [&str; 1] = + [include_str!("../../tests/postgres/binary_json_expanded.rs")]; + + assert_eq!(entities.len(), ENTITY_FILES.len()); + + for (i, entity) in entities.iter().enumerate() { + assert_eq!( + parse_from_file(ENTITY_FILES[i].as_bytes())?.to_string(), + EntityWriter::gen_compact_code_blocks( + entity, + &crate::WithSerde::None, + &crate::DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + ) + .into_iter() + .skip(1) + .fold(TokenStream::new(), |mut acc, tok| { + acc.extend(tok); + acc + }) + .to_string() + ); + assert_eq!( + parse_from_file(ENTITY_FILES[i].as_bytes())?.to_string(), + EntityWriter::gen_compact_code_blocks( + entity, + &crate::WithSerde::None, + &crate::DateTimeCrate::Chrono, + &Some("public".to_owned()), + false, + false, + &TokenStream::new(), + &TokenStream::new(), + ) + .into_iter() + .skip(1) + .fold(TokenStream::new(), |mut acc, tok| { + acc.extend(tok); + acc + }) + .to_string() + ); + assert_eq!( + parse_from_file(ENTITY_FILES_EXPANDED[i].as_bytes())?.to_string(), + EntityWriter::gen_expanded_code_blocks( + entity, + &crate::WithSerde::None, + &crate::DateTimeCrate::Chrono, + &Some("schema_name".to_owned()), + false, + false, + &TokenStream::new(), + &TokenStream::new(), + ) + .into_iter() + .skip(1) + .fold(TokenStream::new(), |mut acc, tok| { + acc.extend(tok); + acc + }) + .to_string() + ); + } + + Ok(()) + } } diff --git a/sea-orm-codegen/tests/postgres/binary_json.rs b/sea-orm-codegen/tests/postgres/binary_json.rs new file mode 100644 index 0000000000..3d7cf95075 --- /dev/null +++ b/sea-orm-codegen/tests/postgres/binary_json.rs @@ -0,0 +1,21 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 +//! +//! This file tests that the JsonBinary column type is annotated correctly is +//! compact entity form. More information can be found in this issue: +//! +//! https://github.com/SeaQL/sea-orm/issues/1344 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "task")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub payload: Json, + #[sea_orm(column_type = "JsonBinary")] + pub payload_binary: Json, +} +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/postgres/binary_json_expanded.rs b/sea-orm-codegen/tests/postgres/binary_json_expanded.rs new file mode 100644 index 0000000000..543e77f1f6 --- /dev/null +++ b/sea-orm-codegen/tests/postgres/binary_json_expanded.rs @@ -0,0 +1,65 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 +//! +//! This file tests that the JsonBinary column type is annotated correctly is +//! expanded entity form. More information can be found in this issue: +//! +//! https://github.com/SeaQL/sea-orm/issues/1344 + +use sea_orm::entity::prelude::*; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity; +impl EntityName for Entity { + fn schema_name(&self) -> Option< &str > { + Some("schema_name") + } + fn table_name(&self) -> &str { + "task" + } +} + +#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)] +pub struct Model { + pub id: i32, + pub payload: Json, + pub payload_binary: Json, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Payload, + PayloadBinary, +} + +#[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)] +pub enum Relation {} +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + // This is the part that is being tested. + Self::Payload => ColumnType::Json.def(), + Self::PayloadBinary => ColumnType::JsonBinary.def(), + } + } +} +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + panic!("No RelationDef") + } +} +impl ActiveModelBehavior for ActiveModel {}