From a9f9599a4d3285ed46a08f55c1382c7f35584138 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Tue, 5 Oct 2021 23:03:04 +0800 Subject: [PATCH 1/6] Codegen date & time column Rust type mapping --- sea-orm-codegen/src/entity/column.rs | 40 +++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/sea-orm-codegen/src/entity/column.rs b/sea-orm-codegen/src/entity/column.rs index 532f2e915..69eb0fb6a 100644 --- a/sea-orm-codegen/src/entity/column.rs +++ b/sea-orm-codegen/src/entity/column.rs @@ -27,8 +27,6 @@ impl Column { ColumnType::Char(_) | ColumnType::String(_) | ColumnType::Text - | ColumnType::Time(_) - | ColumnType::Date | ColumnType::Custom(_) => "String", ColumnType::TinyInteger(_) => "i8", ColumnType::SmallInteger(_) => "i16", @@ -37,6 +35,8 @@ impl Column { ColumnType::Float(_) => "f32", ColumnType::Double(_) => "f64", ColumnType::Json | ColumnType::JsonBinary => "Json", + ColumnType::Date => "Date", + ColumnType::Time(_) => "Time", ColumnType::DateTime(_) | ColumnType::Timestamp(_) => "DateTime", ColumnType::TimestampWithTimeZone(_) => "DateTimeWithTimeZone", ColumnType::Decimal(_) | ColumnType::Money(_) => "Decimal", @@ -194,6 +194,11 @@ mod tests { make_col!("CAKE_FILLING_ID", ColumnType::Double(None)), make_col!("CAKE-FILLING-ID", ColumnType::Binary(None)), make_col!("CAKE", ColumnType::Boolean), + make_col!("date", ColumnType::Date), + make_col!("time", ColumnType::Time(None)), + make_col!("date_time", ColumnType::DateTime(None)), + make_col!("timestamp", ColumnType::Timestamp(None)), + make_col!("timestamp_tz", ColumnType::TimestampWithTimeZone(None)), ] } @@ -211,6 +216,11 @@ mod tests { "cake_filling_id", "cake_filling_id", "cake", + "date", + "time", + "date_time", + "timestamp", + "timestamp_tz", ]; for (col, snack_case) in columns.into_iter().zip(snack_cases) { assert_eq!(col.get_name_snake_case().to_string(), snack_case); @@ -231,6 +241,11 @@ mod tests { "CakeFillingId", "CakeFillingId", "Cake", + "Date", + "Time", + "DateTime", + "Timestamp", + "TimestampTz", ]; for (col, camel_case) in columns.into_iter().zip(camel_cases) { assert_eq!(col.get_name_camel_case().to_string(), camel_case); @@ -241,7 +256,21 @@ mod tests { fn test_get_rs_type() { let columns = setup(); let rs_types = vec![ - "String", "String", "i8", "i16", "i32", "i64", "f32", "f64", "Vec", "bool", + "String", + "String", + "i8", + "i16", + "i32", + "i64", + "f32", + "f64", + "Vec", + "bool", + "Date", + "Time", + "DateTime", + "DateTime", + "DateTimeWithTimeZone", ]; for (mut col, rs_type) in columns.into_iter().zip(rs_types) { let rs_type: TokenStream = rs_type.parse().unwrap(); @@ -271,6 +300,11 @@ mod tests { "ColumnType::Double.def()", "ColumnType::Binary.def()", "ColumnType::Boolean.def()", + "ColumnType::Date.def()", + "ColumnType::Time.def()", + "ColumnType::DateTime.def()", + "ColumnType::Timestamp.def()", + "ColumnType::TimestampWithTimeZone.def()", ]; for (mut col, col_def) in columns.into_iter().zip(col_defs) { let mut col_def: TokenStream = col_def.parse().unwrap(); From cab0f6ba6e5ef5421aa8f15e109fd93898d7336c Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 7 Oct 2021 16:35:50 +0800 Subject: [PATCH 2/6] Merge pull request #224 from SeaQL/rust-keywords Escape rust keywords with `r#` raw identifier --- sea-orm-codegen/src/entity/column.rs | 5 +- sea-orm-codegen/src/entity/writer.rs | 72 ++++++++- sea-orm-codegen/src/lib.rs | 1 + sea-orm-codegen/src/util.rs | 23 +++ sea-orm-codegen/tests/compact/rust_keyword.rs | 30 ++++ .../tests/expanded/rust_keyword.rs | 79 ++++++++++ sea-orm-macros/src/derives/active_model.rs | 10 +- sea-orm-macros/src/derives/entity_model.rs | 12 +- sea-orm-macros/src/derives/model.rs | 13 +- sea-orm-macros/src/util.rs | 36 +++++ src/tests_cfg/mod.rs | 2 + src/tests_cfg/rust_keyword.rs | 141 ++++++++++++++++++ 12 files changed, 406 insertions(+), 18 deletions(-) create mode 100644 sea-orm-codegen/src/util.rs create mode 100644 sea-orm-codegen/tests/compact/rust_keyword.rs create mode 100644 sea-orm-codegen/tests/expanded/rust_keyword.rs create mode 100644 src/tests_cfg/rust_keyword.rs diff --git a/sea-orm-codegen/src/entity/column.rs b/sea-orm-codegen/src/entity/column.rs index 69eb0fb6a..39eb340cb 100644 --- a/sea-orm-codegen/src/entity/column.rs +++ b/sea-orm-codegen/src/entity/column.rs @@ -1,3 +1,4 @@ +use crate::util::escape_rust_keyword; use heck::{CamelCase, SnakeCase}; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; @@ -14,11 +15,11 @@ pub struct Column { impl Column { pub fn get_name_snake_case(&self) -> Ident { - format_ident!("{}", self.name.to_snake_case()) + format_ident!("{}", escape_rust_keyword(self.name.to_snake_case())) } pub fn get_name_camel_case(&self) -> Ident { - format_ident!("{}", self.name.to_camel_case()) + format_ident!("{}", escape_rust_keyword(self.name.to_camel_case())) } pub fn get_rs_type(&self) -> TokenStream { diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index 59f545379..17e74130c 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -597,18 +597,85 @@ mod tests { name: "id".to_owned(), }], }, + Entity { + table_name: "rust_keyword".to_owned(), + columns: vec![ + Column { + name: "id".to_owned(), + col_type: ColumnType::Integer(Some(11)), + auto_increment: true, + not_null: true, + unique: false, + }, + Column { + name: "testing".to_owned(), + col_type: ColumnType::Integer(Some(11)), + auto_increment: false, + not_null: true, + unique: false, + }, + Column { + name: "rust".to_owned(), + col_type: ColumnType::Integer(Some(11)), + auto_increment: false, + not_null: true, + unique: false, + }, + Column { + name: "keywords".to_owned(), + col_type: ColumnType::Integer(Some(11)), + auto_increment: false, + not_null: true, + unique: false, + }, + Column { + name: "type".to_owned(), + col_type: ColumnType::Integer(Some(11)), + auto_increment: false, + not_null: true, + unique: false, + }, + Column { + name: "typeof".to_owned(), + col_type: ColumnType::Integer(Some(11)), + auto_increment: false, + not_null: true, + unique: false, + }, + Column { + name: "crate".to_owned(), + col_type: ColumnType::Integer(Some(11)), + auto_increment: false, + not_null: true, + unique: false, + }, + Column { + name: "self".to_owned(), + col_type: ColumnType::Integer(Some(11)), + auto_increment: false, + not_null: true, + unique: false, + }, + ], + relations: vec![], + conjunct_relations: vec![], + primary_keys: vec![PrimaryKey { + name: "id".to_owned(), + }], + }, ] } #[test] fn test_gen_expanded_code_blocks() -> io::Result<()> { let entities = setup(); - const ENTITY_FILES: [&str; 5] = [ + const ENTITY_FILES: [&str; 6] = [ include_str!("../../tests/expanded/cake.rs"), include_str!("../../tests/expanded/cake_filling.rs"), include_str!("../../tests/expanded/filling.rs"), include_str!("../../tests/expanded/fruit.rs"), include_str!("../../tests/expanded/vendor.rs"), + include_str!("../../tests/expanded/rust_keyword.rs"), ]; assert_eq!(entities.len(), ENTITY_FILES.len()); @@ -642,12 +709,13 @@ mod tests { #[test] fn test_gen_compact_code_blocks() -> io::Result<()> { let entities = setup(); - const ENTITY_FILES: [&str; 5] = [ + const ENTITY_FILES: [&str; 6] = [ include_str!("../../tests/compact/cake.rs"), include_str!("../../tests/compact/cake_filling.rs"), include_str!("../../tests/compact/filling.rs"), include_str!("../../tests/compact/fruit.rs"), include_str!("../../tests/compact/vendor.rs"), + include_str!("../../tests/compact/rust_keyword.rs"), ]; assert_eq!(entities.len(), ENTITY_FILES.len()); diff --git a/sea-orm-codegen/src/lib.rs b/sea-orm-codegen/src/lib.rs index 07e167bc4..5e637de19 100644 --- a/sea-orm-codegen/src/lib.rs +++ b/sea-orm-codegen/src/lib.rs @@ -1,5 +1,6 @@ mod entity; mod error; +mod util; pub use entity::*; pub use error::*; diff --git a/sea-orm-codegen/src/util.rs b/sea-orm-codegen/src/util.rs new file mode 100644 index 000000000..34c46c547 --- /dev/null +++ b/sea-orm-codegen/src/util.rs @@ -0,0 +1,23 @@ +pub(crate) fn escape_rust_keyword(string: T) -> String +where + T: ToString, +{ + let string = string.to_string(); + if RUST_KEYWORDS.iter().any(|s| s.eq(&string)) { + format!("r#{}", string) + } else if RUST_SPECIAL_KEYWORDS.iter().any(|s| s.eq(&string)) { + format!("{}_", string) + } else { + string + } +} + +pub(crate) const RUST_KEYWORDS: [&str; 49] = [ + "as", "async", "await", "break", "const", "continue", "dyn", "else", "enum", "extern", "false", + "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", "ref", + "return", "static", "struct", "super", "trait", "true", "type", "union", "unsafe", "use", + "where", "while", "abstract", "become", "box", "do", "final", "macro", "override", "priv", + "try", "typeof", "unsized", "virtual", "yield", +]; + +pub(crate) const RUST_SPECIAL_KEYWORDS: [&str; 3] = ["crate", "Self", "self"]; diff --git a/sea-orm-codegen/tests/compact/rust_keyword.rs b/sea-orm-codegen/tests/compact/rust_keyword.rs new file mode 100644 index 000000000..229eae221 --- /dev/null +++ b/sea-orm-codegen/tests/compact/rust_keyword.rs @@ -0,0 +1,30 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "rust_keyword")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub testing: i32, + pub rust: i32, + pub keywords: i32, + pub r#type: i32, + pub r#typeof: i32, + pub crate_: i32, + pub self_: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation {} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + _ => panic!("No RelationDef"), + } + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded/rust_keyword.rs b/sea-orm-codegen/tests/expanded/rust_keyword.rs new file mode 100644 index 000000000..1ab8a6275 --- /dev/null +++ b/sea-orm-codegen/tests/expanded/rust_keyword.rs @@ -0,0 +1,79 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude::*; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity; + +impl EntityName for Entity { + fn table_name(&self) -> &str { + "rust_keyword" + } +} + +#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)] +pub struct Model { + pub id: i32, + pub testing: i32, + pub rust: i32, + pub keywords: i32, + pub r#type: i32, + pub r#typeof: i32, + pub crate_: i32, + pub self_: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Testing, + Rust, + Keywords, + Type, + Typeof, + Crate, + Self_, +} + +#[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(), + Self::Testing => ColumnType::Integer.def(), + Self::Rust => ColumnType::Integer.def(), + Self::Keywords => ColumnType::Integer.def(), + Self::Type => ColumnType::Integer.def(), + Self::Typeof => ColumnType::Integer.def(), + Self::Crate => ColumnType::Integer.def(), + Self::Self_ => ColumnType::Integer.def(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + _ => panic!("No RelationDef"), + } + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-macros/src/derives/active_model.rs b/sea-orm-macros/src/derives/active_model.rs index 2227f09bd..85bdcb697 100644 --- a/sea-orm-macros/src/derives/active_model.rs +++ b/sea-orm-macros/src/derives/active_model.rs @@ -1,4 +1,4 @@ -use crate::util::field_not_ignored; +use crate::util::{escape_rust_keyword, field_not_ignored, trim_starting_raw_identifier}; use heck::CamelCase; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote, quote_spanned}; @@ -29,10 +29,10 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result) -> syn::Result { // if #[sea_orm(table_name = "foo", schema_name = "bar")] specified, create Entity struct let mut table_name = None; @@ -60,8 +60,10 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res if let Fields::Named(fields) = item_struct.fields { for field in fields.named { if let Some(ident) = &field.ident { - let mut field_name = - Ident::new(&ident.to_string().to_case(Case::Pascal), Span::call_site()); + let mut field_name = Ident::new( + &trim_starting_raw_identifier(&ident).to_case(Case::Pascal), + Span::call_site(), + ); let mut nullable = false; let mut default_value = None; @@ -168,6 +170,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res field_name = enum_name; } + field_name = Ident::new(&escape_rust_keyword(field_name), Span::call_site()); + if ignore { continue; } else { diff --git a/sea-orm-macros/src/derives/model.rs b/sea-orm-macros/src/derives/model.rs index a43b487f9..29a597b90 100644 --- a/sea-orm-macros/src/derives/model.rs +++ b/sea-orm-macros/src/derives/model.rs @@ -1,4 +1,7 @@ -use crate::{attributes::derive_attr, util::field_not_ignored}; +use crate::{ + attributes::derive_attr, + util::{escape_rust_keyword, field_not_ignored, trim_starting_raw_identifier}, +}; use heck::CamelCase; use proc_macro2::TokenStream; use quote::{format_ident, quote, quote_spanned}; @@ -43,10 +46,10 @@ impl DeriveModel { let column_idents = fields .iter() .map(|field| { - let mut ident = format_ident!( - "{}", - field.ident.as_ref().unwrap().to_string().to_camel_case() - ); + let ident = field.ident.as_ref().unwrap().to_string(); + let ident = trim_starting_raw_identifier(ident).to_camel_case(); + let ident = escape_rust_keyword(ident); + let mut ident = format_ident!("{}", &ident); for attr in field.attrs.iter() { if let Some(ident) = attr.path.get_ident() { if ident != "sea_orm" { diff --git a/sea-orm-macros/src/util.rs b/sea-orm-macros/src/util.rs index 7dda10872..379b486ca 100644 --- a/sea-orm-macros/src/util.rs +++ b/sea-orm-macros/src/util.rs @@ -24,3 +24,39 @@ pub(crate) fn field_not_ignored(field: &Field) -> bool { } true } + +pub(crate) fn trim_starting_raw_identifier(string: T) -> String +where + T: ToString, +{ + string + .to_string() + .trim_start_matches(RAW_IDENTIFIER) + .to_string() +} + +pub(crate) fn escape_rust_keyword(string: T) -> String +where + T: ToString, +{ + let string = string.to_string(); + if RUST_KEYWORDS.iter().any(|s| s.eq(&string)) { + format!("r#{}", string) + } else if RUST_SPECIAL_KEYWORDS.iter().any(|s| s.eq(&string)) { + format!("{}_", string) + } else { + string + } +} + +pub(crate) const RAW_IDENTIFIER: &str = "r#"; + +pub(crate) const RUST_KEYWORDS: [&str; 49] = [ + "as", "async", "await", "break", "const", "continue", "dyn", "else", "enum", "extern", "false", + "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", "ref", + "return", "static", "struct", "super", "trait", "true", "type", "union", "unsafe", "use", + "where", "while", "abstract", "become", "box", "do", "final", "macro", "override", "priv", + "try", "typeof", "unsized", "virtual", "yield", +]; + +pub(crate) const RUST_SPECIAL_KEYWORDS: [&str; 3] = ["crate", "Self", "self"]; diff --git a/src/tests_cfg/mod.rs b/src/tests_cfg/mod.rs index 6bc86aede..d6c80b363 100644 --- a/src/tests_cfg/mod.rs +++ b/src/tests_cfg/mod.rs @@ -7,6 +7,7 @@ pub mod cake_filling_price; pub mod entity_linked; pub mod filling; pub mod fruit; +pub mod rust_keyword; pub mod vendor; pub use cake::Entity as Cake; @@ -15,4 +16,5 @@ pub use cake_filling::Entity as CakeFilling; pub use cake_filling_price::Entity as CakeFillingPrice; pub use filling::Entity as Filling; pub use fruit::Entity as Fruit; +pub use rust_keyword::Entity as RustKeyword; pub use vendor::Entity as Vendor; diff --git a/src/tests_cfg/rust_keyword.rs b/src/tests_cfg/rust_keyword.rs new file mode 100644 index 000000000..c8662347f --- /dev/null +++ b/src/tests_cfg/rust_keyword.rs @@ -0,0 +1,141 @@ +use crate as sea_orm; +use crate::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "rust_keyword")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub testing: i32, + pub rust: i32, + pub keywords: i32, + pub r#raw_identifier: i32, + pub r#as: i32, + pub r#async: i32, + pub r#await: i32, + pub r#break: i32, + pub r#const: i32, + pub r#continue: i32, + pub crate_: i32, + pub r#dyn: i32, + pub r#else: i32, + pub r#enum: i32, + pub r#extern: i32, + pub r#false: i32, + pub r#fn: i32, + pub r#for: i32, + pub r#if: i32, + pub r#impl: i32, + pub r#in: i32, + pub r#let: i32, + pub r#loop: i32, + pub r#match: i32, + pub r#mod: i32, + pub r#move: i32, + pub r#mut: i32, + pub r#pub: i32, + pub r#ref: i32, + pub r#return: i32, + pub self_: i32, + pub r#static: i32, + pub r#struct: i32, + pub r#trait: i32, + pub r#true: i32, + pub r#type: i32, + pub r#union: i32, + pub r#unsafe: i32, + pub r#use: i32, + pub r#where: i32, + pub r#while: i32, + pub r#abstract: i32, + pub r#become: i32, + pub r#box: i32, + pub r#do: i32, + pub r#final: i32, + pub r#macro: i32, + pub r#override: i32, + pub r#priv: i32, + pub r#try: i32, + pub r#typeof: i32, + pub r#unsized: i32, + pub r#virtual: i32, + pub r#yield: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation {} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + _ => panic!("No RelationDef"), + } + } +} + +impl ActiveModelBehavior for ActiveModel {} + +#[cfg(test)] +mod tests { + use crate::tests_cfg::rust_keyword::*; + use sea_query::Iden; + + #[test] + fn test_columns() { + assert_eq!(Column::Id.to_string().as_str(), "id"); + assert_eq!(Column::Testing.to_string().as_str(), "testing"); + assert_eq!(Column::Rust.to_string().as_str(), "rust"); + assert_eq!(Column::Keywords.to_string().as_str(), "keywords"); + assert_eq!(Column::RawIdentifier.to_string().as_str(), "raw_identifier"); + assert_eq!(Column::As.to_string().as_str(), "as"); + assert_eq!(Column::Async.to_string().as_str(), "async"); + assert_eq!(Column::Await.to_string().as_str(), "await"); + assert_eq!(Column::Break.to_string().as_str(), "break"); + assert_eq!(Column::Const.to_string().as_str(), "const"); + assert_eq!(Column::Continue.to_string().as_str(), "continue"); + assert_eq!(Column::Dyn.to_string().as_str(), "dyn"); + assert_eq!(Column::Crate.to_string().as_str(), "crate"); + assert_eq!(Column::Else.to_string().as_str(), "else"); + assert_eq!(Column::Enum.to_string().as_str(), "enum"); + assert_eq!(Column::Extern.to_string().as_str(), "extern"); + assert_eq!(Column::False.to_string().as_str(), "false"); + assert_eq!(Column::Fn.to_string().as_str(), "fn"); + assert_eq!(Column::For.to_string().as_str(), "for"); + assert_eq!(Column::If.to_string().as_str(), "if"); + assert_eq!(Column::Impl.to_string().as_str(), "impl"); + assert_eq!(Column::In.to_string().as_str(), "in"); + assert_eq!(Column::Let.to_string().as_str(), "let"); + assert_eq!(Column::Loop.to_string().as_str(), "loop"); + assert_eq!(Column::Match.to_string().as_str(), "match"); + assert_eq!(Column::Mod.to_string().as_str(), "mod"); + assert_eq!(Column::Move.to_string().as_str(), "move"); + assert_eq!(Column::Mut.to_string().as_str(), "mut"); + assert_eq!(Column::Pub.to_string().as_str(), "pub"); + assert_eq!(Column::Ref.to_string().as_str(), "ref"); + assert_eq!(Column::Return.to_string().as_str(), "return"); + assert_eq!(Column::Self_.to_string().as_str(), "self"); + assert_eq!(Column::Static.to_string().as_str(), "static"); + assert_eq!(Column::Struct.to_string().as_str(), "struct"); + assert_eq!(Column::Trait.to_string().as_str(), "trait"); + assert_eq!(Column::True.to_string().as_str(), "true"); + assert_eq!(Column::Type.to_string().as_str(), "type"); + assert_eq!(Column::Union.to_string().as_str(), "union"); + assert_eq!(Column::Unsafe.to_string().as_str(), "unsafe"); + assert_eq!(Column::Use.to_string().as_str(), "use"); + assert_eq!(Column::Where.to_string().as_str(), "where"); + assert_eq!(Column::While.to_string().as_str(), "while"); + assert_eq!(Column::Abstract.to_string().as_str(), "abstract"); + assert_eq!(Column::Become.to_string().as_str(), "become"); + assert_eq!(Column::Box.to_string().as_str(), "box"); + assert_eq!(Column::Do.to_string().as_str(), "do"); + assert_eq!(Column::Final.to_string().as_str(), "final"); + assert_eq!(Column::Macro.to_string().as_str(), "macro"); + assert_eq!(Column::Override.to_string().as_str(), "override"); + assert_eq!(Column::Priv.to_string().as_str(), "priv"); + assert_eq!(Column::Try.to_string().as_str(), "try"); + assert_eq!(Column::Typeof.to_string().as_str(), "typeof"); + assert_eq!(Column::Unsized.to_string().as_str(), "unsized"); + assert_eq!(Column::Virtual.to_string().as_str(), "virtual"); + assert_eq!(Column::Yield.to_string().as_str(), "yield"); + } +} From 7c8e766e8b34022a6e97b5953dcb4bcfbdc4390b Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 9 Oct 2021 23:01:06 +0800 Subject: [PATCH 3/6] sea-orm-codegen 0.2.6 --- sea-orm-codegen/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sea-orm-codegen/Cargo.toml b/sea-orm-codegen/Cargo.toml index 0e8fa6249..9013cea46 100644 --- a/sea-orm-codegen/Cargo.toml +++ b/sea-orm-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sea-orm-codegen" -version = "0.2.5" +version = "0.2.6" authors = ["Billy Chan "] edition = "2018" description = "Code Generator for SeaORM" From 0eee2206ba14b4a6d4db1a4ac9fec956046e81bc Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 9 Oct 2021 23:01:46 +0800 Subject: [PATCH 4/6] sea-orm-cli 0.2.6 --- sea-orm-cli/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sea-orm-cli/Cargo.toml b/sea-orm-cli/Cargo.toml index 3c05d08b9..07db2e4b4 100644 --- a/sea-orm-cli/Cargo.toml +++ b/sea-orm-cli/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "sea-orm-cli" -version = "0.2.5" +version = "0.2.6" authors = [ "Billy Chan " ] edition = "2018" description = "Command line utility for SeaORM" @@ -21,7 +21,7 @@ path = "src/main.rs" clap = { version = "^2.33.3" } dotenv = { version = "^0.15" } async-std = { version = "^1.9", features = [ "attributes" ] } -sea-orm-codegen = { version = "^0.2.5", path = "../sea-orm-codegen" } +sea-orm-codegen = { version = "^0.2.6", path = "../sea-orm-codegen" } sea-schema = { version = "^0.2.9", default-features = false, features = [ "debug-print", "sqlx-mysql", From f0aea3bf105dfe1cbeb91c2608842b8ac80720c6 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 9 Oct 2021 23:15:55 +0800 Subject: [PATCH 5/6] sea-orm-macros 0.2.6 --- sea-orm-macros/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sea-orm-macros/Cargo.toml b/sea-orm-macros/Cargo.toml index 22b58c011..cde1575cf 100644 --- a/sea-orm-macros/Cargo.toml +++ b/sea-orm-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sea-orm-macros" -version = "0.2.5" +version = "0.2.6" authors = [ "Billy Chan " ] edition = "2018" description = "Derive macros for SeaORM" From bfb83044f16b55fb98f2c0634b8462c3b546ec04 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 9 Oct 2021 23:17:06 +0800 Subject: [PATCH 6/6] 0.2.6 --- CHANGELOG.md | 7 +++++++ Cargo.toml | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 693c1d0e0..ee5448310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## 0.2.6 - 2021-10-09 + +- [[#224]] [sea-orm-cli] Date & Time column type mapping +- Escape rust keywords with `r#` raw identifier + +[#224]: https://github.com/SeaQL/sea-orm/pull/224 + ## 0.2.5 - 2021-10-06 - [[#227]] Resolve "Inserting actual none value of Option results in panic" diff --git a/Cargo.toml b/Cargo.toml index a8d7a8ca6..0c8de3ef3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "sea-orm-macros", "sea-orm-codegen"] [package] name = "sea-orm" -version = "0.2.5" +version = "0.2.6" authors = ["Chris Tsang "] edition = "2018" description = "🐚 An async & dynamic ORM for Rust" @@ -29,7 +29,7 @@ futures = { version = "^0.3" } futures-util = { version = "^0.3" } log = { version = "^0.4", optional = true } rust_decimal = { version = "^1", optional = true } -sea-orm-macros = { version = "^0.2.5", path = "sea-orm-macros", optional = true } +sea-orm-macros = { version = "^0.2.6", path = "sea-orm-macros", optional = true } sea-query = { version = "^0.17.0", features = ["thread-safe"] } sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] }