diff --git a/sea-orm-codegen/src/entity/base_entity.rs b/sea-orm-codegen/src/entity/base_entity.rs index f261f22e4..c6d24c4f9 100644 --- a/sea-orm-codegen/src/entity/base_entity.rs +++ b/sea-orm-codegen/src/entity/base_entity.rs @@ -15,9 +15,14 @@ pub struct Entity { pub(crate) relations: Vec, pub(crate) conjunct_relations: Vec, pub(crate) primary_keys: Vec, + pub(crate) comment: Option, } impl Entity { + pub fn get_table_comment(&self) -> Option<&String> { + self.comment.as_ref() + } + pub fn get_table_name_snake_case(&self) -> String { self.table_name.to_snake_case() } @@ -318,6 +323,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, } } diff --git a/sea-orm-codegen/src/entity/transformer.rs b/sea-orm-codegen/src/entity/transformer.rs index 20f8047cb..40401611f 100644 --- a/sea-orm-codegen/src/entity/transformer.rs +++ b/sea-orm-codegen/src/entity/transformer.rs @@ -117,12 +117,14 @@ impl EntityTransformer { .collect::>() }), ); + let comment = table_create.get_comment().cloned(); let entity = Entity { table_name: table_name.clone(), columns, relations: relations.clone(), conjunct_relations: vec![], primary_keys, + comment, }; entities.insert(table_name.clone(), entity.clone()); for mut rel in relations.into_iter() { diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index 099a96797..678964f0a 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -785,6 +785,7 @@ impl EntityWriter { }, None => quote! {}, }; + let extra_derive = with_serde.extra_derive(); quote! { @@ -882,9 +883,11 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, Entity { table_name: "_cake_filling_".to_owned(), + comment: None, columns: vec![ Column { name: "cake_id".to_owned(), @@ -980,6 +983,7 @@ mod tests { name: "filling_id".to_owned(), }, ], + comment: None, }, Entity { table_name: "filling".to_owned(), @@ -1007,6 +1011,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, Entity { table_name: "fruit".to_owned(), @@ -1061,6 +1066,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, Entity { table_name: "vendor".to_owned(), @@ -1102,6 +1108,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, Entity { table_name: "rust_keyword".to_owned(), @@ -1259,6 +1266,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, Entity { table_name: "cake_with_float".to_owned(), @@ -1303,6 +1311,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, Entity { table_name: "cake_with_double".to_owned(), @@ -1347,6 +1356,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, Entity { table_name: "collection".to_owned(), @@ -1378,6 +1388,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, Entity { table_name: "collection_float".to_owned(), @@ -1409,6 +1420,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, ] } @@ -1770,6 +1782,7 @@ mod tests { fn test_gen_with_seaography() -> io::Result<()> { let cake_entity = Entity { table_name: "cake".to_owned(), + comment: None, columns: vec![ Column { name: "id".to_owned(), @@ -2225,6 +2238,7 @@ mod tests { primary_keys: vec![PrimaryKey { name: "id".to_owned(), }], + comment: None, }, ]; const ENTITY_FILES: [&str; 1] = [include_str!("../../tests/postgres/binary_json.rs")]; @@ -2308,6 +2322,7 @@ mod tests { let entities = vec![ Entity { table_name: "tea_pairing".to_owned(), + comment: None, columns: vec![ Column { name: "id".to_owned(), @@ -2351,6 +2366,7 @@ mod tests { }, Entity { table_name: "tea_pairing_with_size".to_owned(), + comment: None, columns: vec![ Column { name: "id".to_owned(), diff --git a/sea-orm-macros/src/derives/attributes.rs b/sea-orm-macros/src/derives/attributes.rs index 0b51945b0..9c0c24c4b 100644 --- a/sea-orm-macros/src/derives/attributes.rs +++ b/sea-orm-macros/src/derives/attributes.rs @@ -11,6 +11,7 @@ pub mod derive_attr { pub relation: Option, pub schema_name: Option, pub table_name: Option, + pub comment: Option, pub table_iden: Option<()>, } } diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index bea168ac3..6c4f8f272 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -10,6 +10,7 @@ use syn::{ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Result { // if #[sea_orm(table_name = "foo", schema_name = "bar")] specified, create Entity struct let mut table_name = None; + let mut comment = quote! {None}; let mut schema_name = quote! { None }; let mut table_iden = false; attrs @@ -17,7 +18,10 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res .filter(|attr| attr.path().is_ident("sea_orm")) .try_for_each(|attr| { attr.parse_nested_meta(|meta| { - if meta.path.is_ident("table_name") { + if meta.path.is_ident("comment") { + let name: Lit = meta.value()?.parse()?; + comment = quote! { Some(#name) }; + } else if meta.path.is_ident("table_name") { table_name = Some(meta.value()?.parse::()?); } else if meta.path.is_ident("schema_name") { let name: Lit = meta.value()?.parse()?; @@ -51,6 +55,10 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res fn table_name(&self) -> &str { #table_name } + + fn comment(&self) -> Option<&str> { + #comment + } } } }) @@ -90,6 +98,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res let mut nullable = false; let mut default_value = None; + let mut comment = None; let mut default_expr = None; let mut select_as = None; let mut save_as = None; @@ -134,6 +143,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res meta.error(format!("Invalid auto_increment = {:?}", lit)) ); } + } else if meta.path.is_ident("comment") { + comment = Some(meta.value()?.parse::()?); } else if meta.path.is_ident("default_value") { default_value = Some(meta.value()?.parse::()?); } else if meta.path.is_ident("default_expr") { @@ -274,9 +285,13 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res if let Some(default_value) = default_value { match_row = quote! { #match_row.default_value(#default_value) }; } + if let Some(comment) = comment { + match_row = quote! { #match_row.comment(#comment) }; + } if let Some(default_expr) = default_expr { match_row = quote! { #match_row.default(#default_expr) }; } + // match_row = quote! { #match_row.comment() }; columns_trait.push(match_row); } } diff --git a/sea-orm-macros/src/derives/model.rs b/sea-orm-macros/src/derives/model.rs index b28c62cf2..688409818 100644 --- a/sea-orm-macros/src/derives/model.rs +++ b/sea-orm-macros/src/derives/model.rs @@ -182,7 +182,6 @@ impl DeriveModel { /// Method to derive an ActiveModel pub fn expand_derive_model(input: syn::DeriveInput) -> syn::Result { let ident_span = input.ident.span(); - match DeriveModel::new(input) { Ok(model) => model.expand(), Err(Error::InputNotStruct) => Ok(quote_spanned! { diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs index 5f7422e33..6cd8b1052 100644 --- a/src/entity/base_entity.rs +++ b/src/entity/base_entity.rs @@ -20,6 +20,11 @@ pub trait EntityName: IdenStatic + Default { None } + /// Method to get the comment for the schema, defaults to [Option::None] if not set + fn comment(&self) -> Option<&str> { + None + } + /// Get the name of the table fn table_name(&self) -> &str; diff --git a/src/entity/column.rs b/src/entity/column.rs index 2117182be..54e73c35e 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -16,6 +16,7 @@ pub struct ColumnDef { pub(crate) unique: bool, pub(crate) indexed: bool, pub(crate) default: Option, + pub(crate) comment: Option, } macro_rules! bind_oper { @@ -312,6 +313,7 @@ impl ColumnTypeTrait for ColumnType { unique: false, indexed: false, default: None, + comment: None, } } @@ -344,6 +346,11 @@ impl ColumnDef { self.unique = true; self } + /// Set column comment + pub fn comment(mut self, v: &str) -> Self { + self.comment = Some(v.into()); + self + } /// Mark the column as nullable pub fn null(self) -> Self { diff --git a/src/schema/entity.rs b/src/schema/entity.rs index f6e9ead01..5e42d7b13 100644 --- a/src/schema/entity.rs +++ b/src/schema/entity.rs @@ -163,6 +163,10 @@ where { let mut stmt = TableCreateStatement::new(); + if let Some(comment) = entity.comment() { + stmt.comment(comment); + } + for column in E::Column::iter() { let mut column_def = column_def_from_entity_column::(column, backend); stmt.col(&mut column_def); @@ -213,6 +217,9 @@ where if let Some(default) = orm_column_def.default { column_def.default(default); } + if let Some(comment) = orm_column_def.comment { + column_def.comment(comment); + } for primary_key in E::PrimaryKey::iter() { if column.to_string() == primary_key.into_column().to_string() { if E::PrimaryKey::auto_increment() { diff --git a/tests/common/features/applog.rs b/tests/common/features/applog.rs index 98fd18690..f103d2de9 100644 --- a/tests/common/features/applog.rs +++ b/tests/common/features/applog.rs @@ -1,12 +1,15 @@ use sea_orm::entity::prelude::*; #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] -#[sea_orm(table_name = "applog")] +#[sea_orm(table_name = "applog", comment = "app logs")] pub struct Model { - #[sea_orm(primary_key)] + #[sea_orm(primary_key, comment = "ID")] pub id: i32, + #[sea_orm(comment = "action")] pub action: String, + #[sea_orm(comment = "action data")] pub json: Json, + #[sea_orm(comment = "create time")] pub created_at: DateTimeWithTimeZone, } diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index 0fb15cf02..e74614c70 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -67,19 +67,32 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> { pub async fn create_log_table(db: &DbConn) -> Result { let stmt = sea_query::Table::create() .table(applog::Entity) + .comment("app logs") .col( ColumnDef::new(applog::Column::Id) .integer() .not_null() + .comment("ID") .auto_increment() .primary_key(), ) - .col(ColumnDef::new(applog::Column::Action).string().not_null()) - .col(ColumnDef::new(applog::Column::Json).json().not_null()) + .col( + ColumnDef::new(applog::Column::Action) + .string() + .not_null() + .comment("action"), + ) + .col( + ColumnDef::new(applog::Column::Json) + .json() + .not_null() + .comment("action data"), + ) .col( ColumnDef::new(applog::Column::CreatedAt) .timestamp_with_time_zone() - .not_null(), + .not_null() + .comment("create time"), ) .to_owned();