diff --git a/Cargo.toml b/Cargo.toml index eddec045..19a57689 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,13 +2,17 @@ name = "seaography" version = "0.1.0" edition = "2021" +authors = ["Panagiotis Karatakis "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] seaography_generator = { path = "./generator" } -clap = { version = "3.2.6", features = ["derive"] } +seaography_derive = { path = "./derive" } +clap = { version = "3.2.20", features = ["derive"] } async-std = { version = "1.12.0", features = [ "attributes", "tokio1" ] } +async-graphql = { version = "4.0.12", features = [ "decimal", "chrono", "dataloader" ] } +sea-orm = '0.9.2' [workspace] members = [ diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 542f1e11..a89cffb9 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -2,6 +2,7 @@ name = "seaography_derive" version = "0.1.0" edition = "2021" +authors = ["Panagiotis Karatakis "] [lib] proc-macro = true @@ -9,8 +10,8 @@ proc-macro = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -quote = "1.0.18" +quote = "1.0.21" syn = { version = "1.0.99" } -proc-macro2 = "1.0.37" +proc-macro2 = "1.0.43" bae = "0.1.7" heck = "0.4.0" \ No newline at end of file diff --git a/derive/src/filter.rs b/derive/src/filter.rs index 7926f95d..a4ce16f4 100644 --- a/derive/src/filter.rs +++ b/derive/src/filter.rs @@ -74,7 +74,7 @@ pub fn filter_struct( || type_literal.starts_with("Vec") { quote! { - crate::TypeFilter<#ty> + seaography::TypeFilter<#ty> } } else { let ident = format_ident!("{}EnumFilter", type_literal); @@ -128,7 +128,7 @@ pub fn order_by_struct( .iter() .map(|(ident, _)| { quote! { - #ident: Option + #ident: Option } }) .collect(); @@ -158,8 +158,8 @@ pub fn order_by_fn(fields: &Vec) -> Result stmt.order_by(Column::#column, sea_orm::query::Order::Asc), - crate::OrderByEnum::Desc => stmt.order_by(Column::#column, sea_orm::query::Order::Desc), + seaography::OrderByEnum::Asc => stmt.order_by(Column::#column, sea_orm::query::Order::Asc), + seaography::OrderByEnum::Desc => stmt.order_by(Column::#column, sea_orm::query::Order::Desc), } } else { stmt diff --git a/discoverer/Cargo.toml b/discoverer/Cargo.toml index 79ed0355..0a79582e 100644 --- a/discoverer/Cargo.toml +++ b/discoverer/Cargo.toml @@ -2,15 +2,14 @@ name = "seaography_discoverer" version = "0.1.0" edition = "2021" +authors = ["Panagiotis Karatakis "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] async-std = { version = "1.12.0", features = [ "attributes", "tokio1" ] } -serde_json = "1.0.81" -serde = "1.0.137" -sea-schema = { version = "^0.9.3", default-features = false, features = ["sqlx-sqlite", "sqlx-mysql", "sqlx-postgres", "runtime-async-std-native-tls", "discovery", "writer" ] } -sqlx = { version = "0.6.0", features = [ "sqlite", "mysql", "postgres", "runtime-async-std-native-tls" ] } +sea-schema = { version = "0.9.3", default-features = false, features = ["sqlx-sqlite", "sqlx-mysql", "sqlx-postgres", "runtime-async-std-native-tls", "discovery", "writer" ] } +sqlx = { version = "0.6.1", features = [ "sqlite", "mysql", "postgres", "runtime-async-std-native-tls", "all-types" ] } itertools = "0.10.3" heck = "0.4.0" url = "2.2.2" \ No newline at end of file diff --git a/discoverer/src/error.rs b/discoverer/src/error.rs index 7ef0b54c..670ae7bd 100644 --- a/discoverer/src/error.rs +++ b/discoverer/src/error.rs @@ -2,7 +2,6 @@ pub enum Error { SqlxError(sqlx::Error), Error(String), - SerdeJson(serde_json::Error), } impl From for Error { @@ -17,10 +16,4 @@ impl From<&str> for Error { } } -impl From for Error { - fn from(err: serde_json::Error) -> Self { - Self::SerdeJson(err) - } -} - pub type Result = std::result::Result; diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 8001e827..90233adf 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -2,53 +2,22 @@ edition = '2021' name = 'generated' version = '0.1.0' -[dependencies.async-graphql] -version = '4.0.10' -features = [ - 'decimal', - 'chrono', - 'dataloader', -] -[dependencies.async-graphql-poem] -version = '4.0.10' - -[dependencies.async-trait] -version = '0.1.53' - -[dependencies.heck] -version = '0.4.0' - -[dependencies.itertools] -version = '0.10.3' - -[dependencies.poem] -version = '1.3.29' - -[dependencies.sea-orm] -version = '0.7.0' -features = [ - 'sqlx-sqlite', - 'runtime-async-std-native-tls', -] - -[dependencies.seaography_derive] -path = '../../derive' - -[dependencies.tokio] -version = '1.17.0' -features = [ - 'macros', - 'rt-multi-thread', -] - -[dependencies.tracing] -version = '0.1.34' - -[dependencies.tracing-subscriber] -version = '0.3.11' -[dev-dependencies.serde_json] -version = '1.0.82' +[dependencies] +async-graphql = { version = "4.0.10", features = ["decimal", "chrono", "dataloader"] } +async-graphql-poem = { version = "4.0.10" } +async-trait = { version = "0.1.53" } +heck = { version = "0.4.0" } +itertools = { version = "0.10.3" } +poem = { version = "1.3.29" } +sea-orm = { version = "0.7.0", features = ["sqlx-sqlite", "runtime-async-std-native-tls"] } +seaography = { path = "../../" } # TODO before production place version here +tokio = { version = "1.17.0", features = ["macros", "rt-multi-thread"] } +tracing = { version = "0.1.34" } +tracing-subscriber = { version = "0.3.11" } + +[dev-dependencies] +serde_json = { version = '1.0.82' } [workspace] -members = [] +members = [] \ No newline at end of file diff --git a/examples/sqlite/src/entities/albums.rs b/examples/sqlite/src/entities/albums.rs index bda12d69..8804b0a5 100644 --- a/examples/sqlite/src/entities/albums.rs +++ b/examples/sqlite/src/entities/albums.rs @@ -1,75 +1,39 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "albums" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "albums")] #[graphql(complex)] #[graphql(name = "Albums")] pub struct Model { + #[sea_orm(column_name = "AlbumId", primary_key)] pub album_id: i32, - pub title: String, - pub artist_id: i32, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "AlbumId")] - AlbumId, #[sea_orm(column_name = "Title")] - Title, + pub title: String, #[sea_orm(column_name = "ArtistId")] - ArtistId, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - AlbumId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub artist_id: i32, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm( + belongs_to = "super::artists::Entity", + from = "Column::ArtistId", + to = "super::artists::Column::ArtistId", + on_update = "NoAction", + on_delete = "NoAction" + )] Artists, + #[sea_orm(has_many = "super::tracks::Entity")] Tracks, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::AlbumId => ColumnType::Integer.def(), - Self::Title => ColumnType::String(None).def(), - Self::ArtistId => ColumnType::Integer.def(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::Artists => Entity::belongs_to(super::artists::Entity) - .from(Column::ArtistId) - .to(super::artists::Column::ArtistId) - .into(), - Self::Tracks => Entity::has_many(super::tracks::Entity).into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Artists.def() diff --git a/examples/sqlite/src/entities/artists.rs b/examples/sqlite/src/entities/artists.rs index e9bd6aab..9eb8b12d 100644 --- a/examples/sqlite/src/entities/artists.rs +++ b/examples/sqlite/src/entities/artists.rs @@ -1,66 +1,29 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "artists" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "artists")] #[graphql(complex)] #[graphql(name = "Artists")] pub struct Model { + #[sea_orm(column_name = "ArtistId", primary_key)] pub artist_id: i32, - pub name: Option, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "ArtistId")] - ArtistId, #[sea_orm(column_name = "Name")] - Name, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - ArtistId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub name: Option, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm(has_many = "super::albums::Entity")] Albums, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::ArtistId => ColumnType::Integer.def(), - Self::Name => ColumnType::String(None).def().null(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::Albums => Entity::has_many(super::albums::Entity).into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Albums.def() diff --git a/examples/sqlite/src/entities/customers.rs b/examples/sqlite/src/entities/customers.rs index b29886e8..7a3938e7 100644 --- a/examples/sqlite/src/entities/customers.rs +++ b/examples/sqlite/src/entities/customers.rs @@ -1,115 +1,59 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "customers" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "customers")] #[graphql(complex)] #[graphql(name = "Customers")] pub struct Model { + #[sea_orm(column_name = "CustomerId", primary_key)] pub customer_id: i32, - pub first_name: String, - pub last_name: String, - pub company: Option, - pub address: Option, - pub city: Option, - pub state: Option, - pub country: Option, - pub postal_code: Option, - pub phone: Option, - pub fax: Option, - pub email: String, - pub support_rep_id: Option, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "CustomerId")] - CustomerId, #[sea_orm(column_name = "FirstName")] - FirstName, + pub first_name: String, #[sea_orm(column_name = "LastName")] - LastName, + pub last_name: String, #[sea_orm(column_name = "Company")] - Company, + pub company: Option, #[sea_orm(column_name = "Address")] - Address, + pub address: Option, #[sea_orm(column_name = "City")] - City, + pub city: Option, #[sea_orm(column_name = "State")] - State, + pub state: Option, #[sea_orm(column_name = "Country")] - Country, + pub country: Option, #[sea_orm(column_name = "PostalCode")] - PostalCode, + pub postal_code: Option, #[sea_orm(column_name = "Phone")] - Phone, + pub phone: Option, #[sea_orm(column_name = "Fax")] - Fax, + pub fax: Option, #[sea_orm(column_name = "Email")] - Email, + pub email: String, #[sea_orm(column_name = "SupportRepId")] - SupportRepId, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - CustomerId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub support_rep_id: Option, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm( + belongs_to = "super::employees::Entity", + from = "Column::SupportRepId", + to = "super::employees::Column::EmployeeId", + on_update = "NoAction", + on_delete = "NoAction" + )] Employees, + #[sea_orm(has_many = "super::invoices::Entity")] Invoices, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::CustomerId => ColumnType::Integer.def(), - Self::FirstName => ColumnType::String(None).def(), - Self::LastName => ColumnType::String(None).def(), - Self::Company => ColumnType::String(None).def().null(), - Self::Address => ColumnType::String(None).def().null(), - Self::City => ColumnType::String(None).def().null(), - Self::State => ColumnType::String(None).def().null(), - Self::Country => ColumnType::String(None).def().null(), - Self::PostalCode => ColumnType::String(None).def().null(), - Self::Phone => ColumnType::String(None).def().null(), - Self::Fax => ColumnType::String(None).def().null(), - Self::Email => ColumnType::String(None).def(), - Self::SupportRepId => ColumnType::Integer.def().null(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::Employees => Entity::belongs_to(super::employees::Entity) - .from(Column::SupportRepId) - .to(super::employees::Column::EmployeeId) - .into(), - Self::Invoices => Entity::has_many(super::invoices::Entity).into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Employees.def() diff --git a/examples/sqlite/src/entities/employees.rs b/examples/sqlite/src/entities/employees.rs index 799de01f..1d54fab8 100644 --- a/examples/sqlite/src/entities/employees.rs +++ b/examples/sqlite/src/entities/employees.rs @@ -1,123 +1,63 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "employees" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "employees")] #[graphql(complex)] #[graphql(name = "Employees")] pub struct Model { + #[sea_orm(column_name = "EmployeeId", primary_key)] pub employee_id: i32, - pub last_name: String, - pub first_name: String, - pub title: Option, - pub reports_to: Option, - pub birth_date: Option, - pub hire_date: Option, - pub address: Option, - pub city: Option, - pub state: Option, - pub country: Option, - pub postal_code: Option, - pub phone: Option, - pub fax: Option, - pub email: Option, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "EmployeeId")] - EmployeeId, #[sea_orm(column_name = "LastName")] - LastName, + pub last_name: String, #[sea_orm(column_name = "FirstName")] - FirstName, + pub first_name: String, #[sea_orm(column_name = "Title")] - Title, + pub title: Option, #[sea_orm(column_name = "ReportsTo")] - ReportsTo, + pub reports_to: Option, #[sea_orm(column_name = "BirthDate")] - BirthDate, + pub birth_date: Option, #[sea_orm(column_name = "HireDate")] - HireDate, + pub hire_date: Option, #[sea_orm(column_name = "Address")] - Address, + pub address: Option, #[sea_orm(column_name = "City")] - City, + pub city: Option, #[sea_orm(column_name = "State")] - State, + pub state: Option, #[sea_orm(column_name = "Country")] - Country, + pub country: Option, #[sea_orm(column_name = "PostalCode")] - PostalCode, + pub postal_code: Option, #[sea_orm(column_name = "Phone")] - Phone, + pub phone: Option, #[sea_orm(column_name = "Fax")] - Fax, + pub fax: Option, #[sea_orm(column_name = "Email")] - Email, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - EmployeeId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub email: Option, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm( + belongs_to = "Entity", + from = "Column::ReportsTo", + to = "Column::EmployeeId", + on_update = "NoAction", + on_delete = "NoAction" + )] SelfRef, + #[sea_orm(has_many = "super::customers::Entity")] Customers, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::EmployeeId => ColumnType::Integer.def(), - Self::LastName => ColumnType::String(None).def(), - Self::FirstName => ColumnType::String(None).def(), - Self::Title => ColumnType::String(None).def().null(), - Self::ReportsTo => ColumnType::Integer.def().null(), - Self::BirthDate => ColumnType::DateTime.def().null(), - Self::HireDate => ColumnType::DateTime.def().null(), - Self::Address => ColumnType::String(None).def().null(), - Self::City => ColumnType::String(None).def().null(), - Self::State => ColumnType::String(None).def().null(), - Self::Country => ColumnType::String(None).def().null(), - Self::PostalCode => ColumnType::String(None).def().null(), - Self::Phone => ColumnType::String(None).def().null(), - Self::Fax => ColumnType::String(None).def().null(), - Self::Email => ColumnType::String(None).def().null(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::SelfRef => Entity::belongs_to(Entity) - .from(Column::ReportsTo) - .to(Column::EmployeeId) - .into(), - Self::Customers => Entity::has_many(super::customers::Entity).into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Customers.def() diff --git a/examples/sqlite/src/entities/genres.rs b/examples/sqlite/src/entities/genres.rs index 94fac5d7..28a5b216 100644 --- a/examples/sqlite/src/entities/genres.rs +++ b/examples/sqlite/src/entities/genres.rs @@ -1,66 +1,29 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "genres" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "genres")] #[graphql(complex)] #[graphql(name = "Genres")] pub struct Model { + #[sea_orm(column_name = "GenreId", primary_key)] pub genre_id: i32, - pub name: Option, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "GenreId")] - GenreId, #[sea_orm(column_name = "Name")] - Name, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - GenreId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub name: Option, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm(has_many = "super::tracks::Entity")] Tracks, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::GenreId => ColumnType::Integer.def(), - Self::Name => ColumnType::String(None).def().null(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::Tracks => Entity::has_many(super::tracks::Entity).into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Tracks.def() diff --git a/examples/sqlite/src/entities/invoice_items.rs b/examples/sqlite/src/entities/invoice_items.rs index 3ae182d1..55034a2c 100644 --- a/examples/sqlite/src/entities/invoice_items.rs +++ b/examples/sqlite/src/entities/invoice_items.rs @@ -1,86 +1,49 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "invoice_items" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "invoice_items")] #[graphql(complex)] #[graphql(name = "InvoiceItems")] pub struct Model { + #[sea_orm(column_name = "InvoiceLineId", primary_key)] pub invoice_line_id: i32, - pub invoice_id: i32, - pub track_id: i32, - pub unit_price: f64, - pub quantity: i32, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "InvoiceLineId")] - InvoiceLineId, #[sea_orm(column_name = "InvoiceId")] - InvoiceId, + pub invoice_id: i32, #[sea_orm(column_name = "TrackId")] - TrackId, + pub track_id: i32, #[sea_orm(column_name = "UnitPrice")] - UnitPrice, + pub unit_price: f64, #[sea_orm(column_name = "Quantity")] - Quantity, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - InvoiceLineId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub quantity: i32, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm( + belongs_to = "super::tracks::Entity", + from = "Column::TrackId", + to = "super::tracks::Column::TrackId", + on_update = "NoAction", + on_delete = "NoAction" + )] Tracks, + #[sea_orm( + belongs_to = "super::invoices::Entity", + from = "Column::InvoiceId", + to = "super::invoices::Column::InvoiceId", + on_update = "NoAction", + on_delete = "NoAction" + )] Invoices, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::InvoiceLineId => ColumnType::Integer.def(), - Self::InvoiceId => ColumnType::Integer.def(), - Self::TrackId => ColumnType::Integer.def(), - Self::UnitPrice => ColumnType::Double.def(), - Self::Quantity => ColumnType::Integer.def(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::Tracks => Entity::belongs_to(super::tracks::Entity) - .from(Column::TrackId) - .to(super::tracks::Column::TrackId) - .into(), - Self::Invoices => Entity::belongs_to(super::invoices::Entity) - .from(Column::InvoiceId) - .to(super::invoices::Column::InvoiceId) - .into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Tracks.def() diff --git a/examples/sqlite/src/entities/invoices.rs b/examples/sqlite/src/entities/invoices.rs index d43d0414..1f22163d 100644 --- a/examples/sqlite/src/entities/invoices.rs +++ b/examples/sqlite/src/entities/invoices.rs @@ -1,99 +1,51 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "invoices" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "invoices")] #[graphql(complex)] #[graphql(name = "Invoices")] pub struct Model { + #[sea_orm(column_name = "InvoiceId", primary_key)] pub invoice_id: i32, - pub customer_id: i32, - pub invoice_date: DateTime, - pub billing_address: Option, - pub billing_city: Option, - pub billing_state: Option, - pub billing_country: Option, - pub billing_postal_code: Option, - pub total: f64, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "InvoiceId")] - InvoiceId, #[sea_orm(column_name = "CustomerId")] - CustomerId, + pub customer_id: i32, #[sea_orm(column_name = "InvoiceDate")] - InvoiceDate, + pub invoice_date: DateTime, #[sea_orm(column_name = "BillingAddress")] - BillingAddress, + pub billing_address: Option, #[sea_orm(column_name = "BillingCity")] - BillingCity, + pub billing_city: Option, #[sea_orm(column_name = "BillingState")] - BillingState, + pub billing_state: Option, #[sea_orm(column_name = "BillingCountry")] - BillingCountry, + pub billing_country: Option, #[sea_orm(column_name = "BillingPostalCode")] - BillingPostalCode, + pub billing_postal_code: Option, #[sea_orm(column_name = "Total")] - Total, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - InvoiceId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub total: f64, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm( + belongs_to = "super::customers::Entity", + from = "Column::CustomerId", + to = "super::customers::Column::CustomerId", + on_update = "NoAction", + on_delete = "NoAction" + )] Customers, + #[sea_orm(has_many = "super::invoice_items::Entity")] InvoiceItems, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::InvoiceId => ColumnType::Integer.def(), - Self::CustomerId => ColumnType::Integer.def(), - Self::InvoiceDate => ColumnType::DateTime.def(), - Self::BillingAddress => ColumnType::String(None).def().null(), - Self::BillingCity => ColumnType::String(None).def().null(), - Self::BillingState => ColumnType::String(None).def().null(), - Self::BillingCountry => ColumnType::String(None).def().null(), - Self::BillingPostalCode => ColumnType::String(None).def().null(), - Self::Total => ColumnType::Double.def(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::Customers => Entity::belongs_to(super::customers::Entity) - .from(Column::CustomerId) - .to(super::customers::Column::CustomerId) - .into(), - Self::InvoiceItems => Entity::has_many(super::invoice_items::Entity).into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Customers.def() diff --git a/examples/sqlite/src/entities/media_types.rs b/examples/sqlite/src/entities/media_types.rs index b0df65b0..a4d5c64d 100644 --- a/examples/sqlite/src/entities/media_types.rs +++ b/examples/sqlite/src/entities/media_types.rs @@ -1,66 +1,29 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "media_types" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "media_types")] #[graphql(complex)] #[graphql(name = "MediaTypes")] pub struct Model { + #[sea_orm(column_name = "MediaTypeId", primary_key)] pub media_type_id: i32, - pub name: Option, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "MediaTypeId")] - MediaTypeId, #[sea_orm(column_name = "Name")] - Name, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - MediaTypeId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub name: Option, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm(has_many = "super::tracks::Entity")] Tracks, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::MediaTypeId => ColumnType::Integer.def(), - Self::Name => ColumnType::String(None).def().null(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::Tracks => Entity::has_many(super::tracks::Entity).into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Tracks.def() diff --git a/examples/sqlite/src/entities/mod.rs b/examples/sqlite/src/entities/mod.rs index 113dfbe9..ad15bf06 100644 --- a/examples/sqlite/src/entities/mod.rs +++ b/examples/sqlite/src/entities/mod.rs @@ -1,4 +1,4 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] pub mod albums; pub mod artists; pub mod customers; diff --git a/examples/sqlite/src/entities/playlist_track.rs b/examples/sqlite/src/entities/playlist_track.rs index 21303dd2..4d34f3e0 100644 --- a/examples/sqlite/src/entities/playlist_track.rs +++ b/examples/sqlite/src/entities/playlist_track.rs @@ -1,75 +1,43 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "playlist_track" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "playlist_track")] #[graphql(complex)] #[graphql(name = "PlaylistTrack")] pub struct Model { + #[sea_orm(column_name = "PlaylistId", primary_key, auto_increment = false)] pub playlist_id: i32, + #[sea_orm(column_name = "TrackId", primary_key, auto_increment = false)] pub track_id: i32, } -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "PlaylistId")] - PlaylistId, - #[sea_orm(column_name = "TrackId")] - TrackId, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - PlaylistId, - TrackId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = (i32, i32); - fn auto_increment() -> bool { - false - } -} -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm( + belongs_to = "super::tracks::Entity", + from = "Column::TrackId", + to = "super::tracks::Column::TrackId", + on_update = "NoAction", + on_delete = "NoAction" + )] Tracks, + #[sea_orm( + belongs_to = "super::playlists::Entity", + from = "Column::PlaylistId", + to = "super::playlists::Column::PlaylistId", + on_update = "NoAction", + on_delete = "NoAction" + )] Playlists, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::PlaylistId => ColumnType::Integer.def(), - Self::TrackId => ColumnType::Integer.def(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::Tracks => Entity::belongs_to(super::tracks::Entity) - .from(Column::TrackId) - .to(super::tracks::Column::TrackId) - .into(), - Self::Playlists => Entity::belongs_to(super::playlists::Entity) - .from(Column::PlaylistId) - .to(super::playlists::Column::PlaylistId) - .into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::Tracks.def() diff --git a/examples/sqlite/src/entities/playlists.rs b/examples/sqlite/src/entities/playlists.rs index e9559604..c9ce6e21 100644 --- a/examples/sqlite/src/entities/playlists.rs +++ b/examples/sqlite/src/entities/playlists.rs @@ -1,66 +1,29 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "playlists" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "playlists")] #[graphql(complex)] #[graphql(name = "Playlists")] pub struct Model { + #[sea_orm(column_name = "PlaylistId", primary_key)] pub playlist_id: i32, - pub name: Option, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "PlaylistId")] - PlaylistId, #[sea_orm(column_name = "Name")] - Name, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - PlaylistId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub name: Option, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm(has_many = "super::playlist_track::Entity")] PlaylistTrack, } -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::PlaylistId => ColumnType::Integer.def(), - Self::Name => ColumnType::String(None).def().null(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::PlaylistTrack => Entity::has_many(super::playlist_track::Entity).into(), - } - } -} impl Related for Entity { fn to() -> RelationDef { Relation::PlaylistTrack.def() diff --git a/examples/sqlite/src/entities/prelude.rs b/examples/sqlite/src/entities/prelude.rs index 37225337..c1c18f91 100644 --- a/examples/sqlite/src/entities/prelude.rs +++ b/examples/sqlite/src/entities/prelude.rs @@ -1,4 +1,4 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] pub use super::albums::Entity as Albums; pub use super::artists::Entity as Artists; pub use super::customers::Entity as Customers; diff --git a/examples/sqlite/src/entities/tracks.rs b/examples/sqlite/src/entities/tracks.rs index 84fd9375..04edba2f 100644 --- a/examples/sqlite/src/entities/tracks.rs +++ b/examples/sqlite/src/entities/tracks.rs @@ -1,110 +1,68 @@ -#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.1"] +#![doc = " SeaORM Entity. Generated by sea-orm-codegen 0.9.2"] use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity)] -pub struct Entity; -impl EntityName for Entity { - fn table_name(&self) -> &str { - "tracks" - } -} #[derive( Clone, Debug, PartialEq, - DeriveModel, - DeriveActiveModel, + DeriveEntityModel, async_graphql :: SimpleObject, - seaography_derive :: Filter, + seaography :: macros :: Filter, )] #[sea_orm(table_name = "tracks")] #[graphql(complex)] #[graphql(name = "Tracks")] pub struct Model { + #[sea_orm(column_name = "TrackId", primary_key)] pub track_id: i32, - pub name: String, - pub album_id: Option, - pub media_type_id: i32, - pub genre_id: Option, - pub composer: Option, - pub milliseconds: i32, - pub bytes: Option, - pub unit_price: f64, -} -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - #[sea_orm(column_name = "TrackId")] - TrackId, #[sea_orm(column_name = "Name")] - Name, + pub name: String, #[sea_orm(column_name = "AlbumId")] - AlbumId, + pub album_id: Option, #[sea_orm(column_name = "MediaTypeId")] - MediaTypeId, + pub media_type_id: i32, #[sea_orm(column_name = "GenreId")] - GenreId, + pub genre_id: Option, #[sea_orm(column_name = "Composer")] - Composer, + pub composer: Option, #[sea_orm(column_name = "Milliseconds")] - Milliseconds, + pub milliseconds: i32, #[sea_orm(column_name = "Bytes")] - Bytes, + pub bytes: Option, #[sea_orm(column_name = "UnitPrice")] - UnitPrice, -} -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - TrackId, -} -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - fn auto_increment() -> bool { - true - } + pub unit_price: f64, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive( + Copy, Clone, Debug, EnumIter, DeriveRelation, seaography :: macros :: RelationsCompact, +)] pub enum Relation { + #[sea_orm( + belongs_to = "super::media_types::Entity", + from = "Column::MediaTypeId", + to = "super::media_types::Column::MediaTypeId", + on_update = "NoAction", + on_delete = "NoAction" + )] MediaTypes, + #[sea_orm( + belongs_to = "super::genres::Entity", + from = "Column::GenreId", + to = "super::genres::Column::GenreId", + on_update = "NoAction", + on_delete = "NoAction" + )] Genres, + #[sea_orm( + belongs_to = "super::albums::Entity", + from = "Column::AlbumId", + to = "super::albums::Column::AlbumId", + on_update = "NoAction", + on_delete = "NoAction" + )] Albums, - PlaylistTrack, + #[sea_orm(has_many = "super::invoice_items::Entity")] InvoiceItems, -} -impl ColumnTrait for Column { - type EntityName = Entity; - fn def(&self) -> ColumnDef { - match self { - Self::TrackId => ColumnType::Integer.def(), - Self::Name => ColumnType::String(None).def(), - Self::AlbumId => ColumnType::Integer.def().null(), - Self::MediaTypeId => ColumnType::Integer.def(), - Self::GenreId => ColumnType::Integer.def().null(), - Self::Composer => ColumnType::String(None).def().null(), - Self::Milliseconds => ColumnType::Integer.def(), - Self::Bytes => ColumnType::Integer.def().null(), - Self::UnitPrice => ColumnType::Double.def(), - } - } -} -#[seaography_derive::relation] -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - match self { - Self::MediaTypes => Entity::belongs_to(super::media_types::Entity) - .from(Column::MediaTypeId) - .to(super::media_types::Column::MediaTypeId) - .into(), - Self::Genres => Entity::belongs_to(super::genres::Entity) - .from(Column::GenreId) - .to(super::genres::Column::GenreId) - .into(), - Self::Albums => Entity::belongs_to(super::albums::Entity) - .from(Column::AlbumId) - .to(super::albums::Column::AlbumId) - .into(), - Self::PlaylistTrack => Entity::has_many(super::playlist_track::Entity).into(), - Self::InvoiceItems => Entity::has_many(super::invoice_items::Entity).into(), - } - } + #[sea_orm(has_many = "super::playlist_track::Entity")] + PlaylistTrack, } impl Related for Entity { fn to() -> RelationDef { @@ -121,14 +79,14 @@ impl Related for Entity { Relation::Albums.def() } } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::PlaylistTrack.def() + Relation::InvoiceItems.def() } } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::InvoiceItems.def() + Relation::PlaylistTrack.def() } } impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/sqlite/src/lib.rs b/examples/sqlite/src/lib.rs index 9d2784c4..e03cb964 100644 --- a/examples/sqlite/src/lib.rs +++ b/examples/sqlite/src/lib.rs @@ -5,38 +5,3 @@ pub use query_root::QueryRoot; pub struct OrmDataloader { pub db: DatabaseConnection, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, async_graphql :: Enum)] -pub enum OrderByEnum { - Asc, - Desc, -} -pub type BinaryVector = Vec; -#[derive(async_graphql :: InputObject, Debug)] -#[graphql(concrete(name = "StringFilter", params(String)))] -#[graphql(concrete(name = "TinyIntegerFilter", params(i8)))] -#[graphql(concrete(name = "SmallIntegerFilter", params(i16)))] -#[graphql(concrete(name = "IntegerFilter", params(i32)))] -#[graphql(concrete(name = "BigIntegerFilter", params(i64)))] -#[graphql(concrete(name = "TinyUnsignedFilter", params(u8)))] -#[graphql(concrete(name = "SmallUnsignedFilter", params(u16)))] -#[graphql(concrete(name = "UnsignedFilter", params(u32)))] -#[graphql(concrete(name = "BigUnsignedFilter", params(u64)))] -#[graphql(concrete(name = "FloatFilter", params(f32)))] -#[graphql(concrete(name = "DoubleFilter", params(f64)))] -#[graphql(concrete(name = "DateFilter", params(Date)))] -#[graphql(concrete(name = "DateTimeFilter", params(DateTime)))] -#[graphql(concrete(name = "DateTimeUtcFilter", params(DateTimeUtc)))] -#[graphql(concrete(name = "DecimalFilter", params(Decimal)))] -#[graphql(concrete(name = "BinaryFilter", params(BinaryVector)))] -#[graphql(concrete(name = "BooleanFilter", params(bool)))] -pub struct TypeFilter { - pub eq: Option, - pub ne: Option, - pub gt: Option, - pub gte: Option, - pub lt: Option, - pub lte: Option, - pub is_in: Option>, - pub is_not_in: Option>, - pub is_null: Option, -} diff --git a/examples/sqlite/src/query_root.rs b/examples/sqlite/src/query_root.rs index dad069fe..4e36a7d0 100644 --- a/examples/sqlite/src/query_root.rs +++ b/examples/sqlite/src/query_root.rs @@ -1,13 +1,13 @@ -#[derive(Debug, seaography_derive :: QueryRoot)] -#[seaography(entity = "crate::entities::artists")] +#[derive(Debug, seaography :: macros :: QueryRoot)] +#[seaography(entity = "crate::entities::playlist_track")] +#[seaography(entity = "crate::entities::invoice_items")] +#[seaography(entity = "crate::entities::genres")] #[seaography(entity = "crate::entities::tracks")] +#[seaography(entity = "crate::entities::media_types")] +#[seaography(entity = "crate::entities::artists")] #[seaography(entity = "crate::entities::customers")] #[seaography(entity = "crate::entities::invoices")] -#[seaography(entity = "crate::entities::genres")] -#[seaography(entity = "crate::entities::playlist_track")] -#[seaography(entity = "crate::entities::invoice_items")] -#[seaography(entity = "crate::entities::employees")] #[seaography(entity = "crate::entities::playlists")] -#[seaography(entity = "crate::entities::media_types")] +#[seaography(entity = "crate::entities::employees")] #[seaography(entity = "crate::entities::albums")] pub struct QueryRoot; diff --git a/generator/Cargo.toml b/generator/Cargo.toml index 1242f5a1..fb8cf4a2 100644 --- a/generator/Cargo.toml +++ b/generator/Cargo.toml @@ -2,18 +2,16 @@ name = "seaography_generator" version = "0.1.0" edition = "2021" +authors = ["Panagiotis Karatakis "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -quote = "1.0.18" +quote = "1.0.21" url = "2.2.2" -proc-macro2 = "1.0.37" +proc-macro2 = "1.0.43" syn = { version = "1.0.99", features = ["full"] } heck = "0.4.0" -toml = "0.5.9" -serde = { version = "1.0.137", features = ["derive"] } -clap = { version = "3.2.6", features = ["derive"] } itertools = "0.10.3" -sea-orm-codegen = { version = "^0.9.2"} +sea-orm-codegen = { version = "0.9.2"} seaography_discoverer = { path = "../discoverer" } \ No newline at end of file diff --git a/generator/src/_Cargo.toml b/generator/src/_Cargo.toml new file mode 100644 index 00000000..783d5de1 --- /dev/null +++ b/generator/src/_Cargo.toml @@ -0,0 +1,24 @@ +[package] +edition = '2021' +name = '' +version = '0.1.0' + +[dependencies] +async-graphql = { version = "4.0.10", features = ["decimal", "chrono", "dataloader"] } +async-graphql-poem = { version = "4.0.10" } +async-trait = { version = "0.1.53" } +heck = { version = "0.4.0" } +itertools = { version = "0.10.3" } +poem = { version = "1.3.29" } +sea-orm = { version = "0.7.0", features = ["", "runtime-async-std-native-tls"] } +seaography = { path = "../../" } # TODO before production place version here +tokio = { version = "1.17.0", features = ["macros", "rt-multi-thread"] } +tracing = { version = "0.1.34" } +tracing-subscriber = { version = "0.3.11" } +dotenv = "0.15.0" + +[dev-dependencies] +serde_json = { version = '1.0.82' } + +[workspace] +members = [] \ No newline at end of file diff --git a/generator/src/inject_graphql.rs b/generator/src/inject_graphql.rs index 4ec648fa..81064584 100644 --- a/generator/src/inject_graphql.rs +++ b/generator/src/inject_graphql.rs @@ -16,7 +16,7 @@ pub fn inject_graphql( .map(|item| -> syn::Item { if let syn::Item::Enum(enumeration) = item { let derive_attr: syn::Attribute = syn::parse_quote! { - #[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Eq, Copy, async_graphql::Enum, seaography_derive::EnumFilter)] + #[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Eq, Copy, async_graphql::Enum, seaography::macros::EnumFilter)] }; syn::Item::Enum( syn::ItemEnum { @@ -57,7 +57,7 @@ pub fn inject_graphql( attributes[0] = syn::Attribute { tokens: format!( - "{}, async_graphql::SimpleObject, seaography_derive::Filter)", + "{}, async_graphql::SimpleObject, seaography::macros::Filter)", derives ) .parse() @@ -107,7 +107,7 @@ pub fn inject_graphql( attributes[0] = syn::Attribute { tokens: format!( - "{}, seaography_derive::RelationsCompact)", + "{}, seaography::macros::RelationsCompact)", derives ) .parse() @@ -128,7 +128,7 @@ pub fn inject_graphql( && expanded_format => { let relation_macro_attr: syn::Attribute = - syn::parse_quote! { #[seaography_derive::relation] }; + syn::parse_quote! { #[seaography::macros::relation] }; syn::Item::Impl(syn::ItemImpl { attrs: vec![relation_macro_attr], diff --git a/generator/src/lib.rs b/generator/src/lib.rs index 7141127a..e8f47350 100644 --- a/generator/src/lib.rs +++ b/generator/src/lib.rs @@ -4,9 +4,10 @@ pub mod error; pub use error::{Error, Result}; pub mod inject_graphql; pub mod sea_orm_codegen; -pub mod toml; pub mod writer; +mod util; + /** * Most code depends from here * https://github.com/SeaQL/sea-orm/blob/master/sea-orm-cli/src/commands.rs @@ -73,15 +74,18 @@ pub async fn write_project>( db_url: &str, crate_name: &str, expanded_format: bool, + depth_limit: Option, + complexity_limit: Option, ) -> Result<()> { let database_url = parse_database_url(db_url)?; let (tables, sql_version) = seaography_discoverer::extract_database_metadata(&database_url).await?; + std::fs::create_dir_all(&path.as_ref().join("src/entities"))?; + writer::write_cargo_toml(path, crate_name, &sql_version)?; - std::fs::create_dir_all(&path.as_ref().join("src/entities"))?; let src_path = &path.as_ref().join("src"); @@ -93,9 +97,16 @@ pub async fn write_project>( writer::write_query_root(src_path, &entities_hashmap).unwrap(); writer::write_lib(src_path)?; - writer::write_main(src_path, db_url, crate_name)?; + writer::write_main(src_path, crate_name)?; + writer::write_env(&path.as_ref(), db_url, depth_limit, complexity_limit)?; + + sea_orm_codegen::write_entities(&src_path.join("entities"), entities_hashmap.clone()).unwrap(); - sea_orm_codegen::write_entities(&src_path.join("entities"), entities_hashmap).unwrap(); + std::process::Command::new("cargo") + .arg("fmt") + .current_dir(&path) + .spawn()? + .wait()?; Ok(()) } diff --git a/generator/src/sea_orm_codegen.rs b/generator/src/sea_orm_codegen.rs index 8094ff61..596d9294 100644 --- a/generator/src/sea_orm_codegen.rs +++ b/generator/src/sea_orm_codegen.rs @@ -1,3 +1,5 @@ +use crate::util::add_line_break; + pub type EntityHashMap = std::collections::HashMap; pub fn generate_entities( @@ -36,7 +38,7 @@ pub fn write_entities>( ) -> crate::Result<()> { for (name, content) in entities_hashmap.iter() { let file_path = path.as_ref().join(name); - std::fs::write(file_path, content.to_string().as_bytes())?; + std::fs::write(file_path, add_line_break(content.clone()))?; } Ok(()) diff --git a/generator/src/toml.rs b/generator/src/toml.rs deleted file mode 100644 index 852f3006..00000000 --- a/generator/src/toml.rs +++ /dev/null @@ -1,159 +0,0 @@ -use std::collections::BTreeMap; - -use seaography_discoverer::SqlVersion; -use serde::Serialize; - -#[derive(Serialize)] -pub struct TomlStructure { - package: BTreeMap, - dependencies: BTreeMap, - #[serde(rename(serialize = "dev-dependencies"))] - dev: BTreeMap, - workspace: WorkspaceInfo, -} - -#[derive(Serialize)] -pub struct DependencyInfo { - pub version: Option, - pub path: Option, - pub features: Option>, -} - -#[derive(Serialize)] -pub struct WorkspaceInfo { - members: Vec, -} - -impl TomlStructure { - /// - /// Used to contract a new rust toml project configuration - /// - pub fn new(crate_name: &str, sql_version: &SqlVersion) -> Self { - let mut package: BTreeMap = BTreeMap::new(); - - package.insert("name".into(), crate_name.into()); - package.insert("version".into(), "0.1.0".into()); - package.insert("edition".into(), "2021".into()); - - let sqlx_driver = match sql_version { - SqlVersion::Sqlite => "sqlx-sqlite", - SqlVersion::Mysql => "sqlx-mysql", - SqlVersion::Postgres => "sqlx-postgres", - }; - - let mut dependencies: BTreeMap = BTreeMap::new(); - dependencies.insert( - "sea-orm".into(), - DependencyInfo { - path: None, - version: Some("0.7.0".into()), - features: Some(vec![ - sqlx_driver.into(), - "runtime-async-std-native-tls".into(), - ]), - }, - ); - dependencies.insert( - "async-graphql".into(), - DependencyInfo { - path: None, - version: Some("4.0.10".into()), - features: Some(vec!["decimal".into(), "chrono".into(), "dataloader".into()]), - }, - ); - dependencies.insert( - "async-graphql-poem".into(), - DependencyInfo { - path: None, - version: Some("4.0.10".into()), - features: None, - }, - ); - dependencies.insert( - "heck".into(), - DependencyInfo { - path: None, - version: Some("0.4.0".into()), - features: None, - }, - ); - dependencies.insert( - "tokio".into(), - DependencyInfo { - path: None, - version: Some("1.17.0".into()), - features: Some(vec!["macros".into(), "rt-multi-thread".into()]), - }, - ); - dependencies.insert( - "poem".into(), - DependencyInfo { - path: None, - version: Some("1.3.29".into()), - features: None, - }, - ); - - dependencies.insert( - "async-trait".into(), - DependencyInfo { - path: None, - version: Some("0.1.53".into()), - features: None, - }, - ); - - dependencies.insert( - "tracing".into(), - DependencyInfo { - path: None, - version: Some("0.1.34".into()), - features: None, - }, - ); - - dependencies.insert( - "tracing-subscriber".into(), - DependencyInfo { - path: None, - version: Some("0.3.11".into()), - features: None, - }, - ); - - dependencies.insert( - "itertools".into(), - DependencyInfo { - path: None, - version: Some("0.10.3".into()), - features: None, - }, - ); - - dependencies.insert( - "seaography_derive".into(), - DependencyInfo { - version: None, - features: None, - path: Some("../../derive".into()), - }, - ); - - let mut dev: BTreeMap = BTreeMap::new(); - dev.insert( - "serde_json".into(), - DependencyInfo { - path: None, - version: Some("1.0.82".into()), - features: None, - }, - ); - - Self { - package, - dependencies, - dev, - workspace: WorkspaceInfo { members: vec![] }, - } - } -} diff --git a/generator/src/util.rs b/generator/src/util.rs new file mode 100644 index 00000000..04aeaf2e --- /dev/null +++ b/generator/src/util.rs @@ -0,0 +1,38 @@ +use quote::ToTokens; + +pub(crate) fn add_line_break(content: proc_macro2::TokenStream) -> String { + let file_parsed: syn::File = syn::parse2(content).unwrap(); + let blocks: Vec = + file_parsed + .items + .iter() + .enumerate() + .fold(Vec::new(), |mut acc, (i, item)| { + let mut s = item.into_token_stream().to_string(); + if !acc.is_empty() && no_line_break_in_between(&file_parsed.items[i - 1], item) { + let last = acc.swap_remove(acc.len() - 1); + s = format!("{}{}", last, s); + } + acc.push(s); + acc + }); + replace_fully_qualified_spaces(blocks.join("\n\n")) +} + +pub(crate) fn no_line_break_in_between(this: &syn::Item, that: &syn::Item) -> bool { + match (this, that) { + (syn::Item::Mod(_), syn::Item::Mod(_)) | (syn::Item::Use(_), syn::Item::Use(_)) => true, + _ => false, + } +} + +pub(crate) fn replace_fully_qualified_spaces(mut str: String) -> String { + let targets = [ + ("seaography :: macros :: ", "seaography::macros::"), + ("async_graphql :: ", "async_graphql::"), + ]; + for (from, to) in targets { + str = str.replace(from, to); + } + str +} diff --git a/generator/src/writer.rs b/generator/src/writer.rs index 4a48aa99..10d62eff 100644 --- a/generator/src/writer.rs +++ b/generator/src/writer.rs @@ -2,6 +2,8 @@ use proc_macro2::TokenStream; use quote::quote; use seaography_discoverer::SqlVersion; +use crate::util::add_line_break; + pub fn generate_query_root( entities_hashmap: &crate::sea_orm_codegen::EntityHashMap, ) -> Result { @@ -20,7 +22,7 @@ pub fn generate_query_root( .collect(); Ok(quote! { - #[derive(Debug, seaography_derive::QueryRoot)] + #[derive(Debug, seaography::macros::QueryRoot)] #(#[seaography(entity = #items)])* pub struct QueryRoot; }) @@ -34,7 +36,7 @@ pub fn write_query_root>( let file_name = path.as_ref().join("query_root.rs"); - std::fs::write(file_name, tokens.to_string())?; + std::fs::write(file_name, add_line_break(tokens))?; Ok(()) } @@ -46,9 +48,20 @@ pub fn write_cargo_toml>( ) -> std::io::Result<()> { let file_path = path.as_ref().join("Cargo.toml"); - let data = crate::toml::TomlStructure::new(crate_name, sql_version); + let content = std::fs::read_to_string("./generator/src/_Cargo.toml")?; + + let content = content.replace("", crate_name); + + let sql_library = match sql_version { + seaography_discoverer::SqlVersion::Sqlite => "sqlx-sqlite", + seaography_discoverer::SqlVersion::Mysql => "sqlx-mysql", + seaography_discoverer::SqlVersion::Postgres => "sqlx-postgres", + }; + + + let content = content.replace("", sql_library); - std::fs::write(file_path, toml::to_string_pretty(&data).unwrap())?; + std::fs::write(file_path, content.as_bytes())?; Ok(()) } @@ -68,51 +81,6 @@ pub fn generate_lib() -> TokenStream { pub struct OrmDataloader { pub db: DatabaseConnection, } - - #[derive(Debug, Clone, Copy, PartialEq, Eq, async_graphql::Enum)] - pub enum OrderByEnum { - Asc, - Desc, - } - - pub type BinaryVector = Vec; - - #[derive(async_graphql::InputObject, Debug)] - #[graphql(concrete(name = "StringFilter", params(String)))] - #[graphql(concrete(name = "TinyIntegerFilter", params(i8)))] - #[graphql(concrete(name = "SmallIntegerFilter", params(i16)))] - #[graphql(concrete(name = "IntegerFilter", params(i32)))] - #[graphql(concrete(name = "BigIntegerFilter", params(i64)))] - #[graphql(concrete(name = "TinyUnsignedFilter", params(u8)))] - #[graphql(concrete(name = "SmallUnsignedFilter", params(u16)))] - #[graphql(concrete(name = "UnsignedFilter", params(u32)))] - #[graphql(concrete(name = "BigUnsignedFilter", params(u64)))] - #[graphql(concrete(name = "FloatFilter", params(f32)))] - #[graphql(concrete(name = "DoubleFilter", params(f64)))] - // TODO #[graphql(concrete(name = "JsonFilter", params()))] - // TODO #[graphql(concrete(name = "DateFilter", params()))] - // TODO #[graphql(concrete(name = "TimeFilter", params()))] - #[graphql(concrete(name = "DateFilter", params(Date)))] - #[graphql(concrete(name = "DateTimeFilter", params(DateTime)))] - #[graphql(concrete(name = "DateTimeUtcFilter", params(DateTimeUtc)))] - // TODO #[graphql(concrete(name = "TimestampFilter", params()))] - // TODO #[graphql(concrete(name = "TimestampWithTimeZoneFilter", params()))] - #[graphql(concrete(name = "DecimalFilter", params(Decimal)))] - // TODO #[graphql(concrete(name = "UuidFilter", params(uuid::Uuid)))] - #[graphql(concrete(name = "BinaryFilter", params(BinaryVector)))] - #[graphql(concrete(name = "BooleanFilter", params(bool)))] - // TODO #[graphql(concrete(name = "EnumFilter", params()))] - pub struct TypeFilter { - pub eq: Option, - pub ne: Option, - pub gt: Option, - pub gte: Option, - pub lt: Option, - pub lte: Option, - pub is_in: Option>, - pub is_not_in: Option>, - pub is_null: Option, - } } } @@ -121,7 +89,7 @@ pub fn write_lib>(path: &P) -> std::io::Result<()> { let file_name = path.as_ref().join("lib.rs"); - std::fs::write(file_name, tokens.to_string())?; + std::fs::write(file_name, add_line_break(tokens))?; Ok(()) } @@ -129,17 +97,20 @@ pub fn write_lib>(path: &P) -> std::io::Result<()> { /// /// Used to generate project/src/main.rs file content /// -pub fn generate_main(db_url: &str, crate_name: &str) -> TokenStream { +pub fn generate_main(crate_name: &str) -> TokenStream { let crate_name_token: TokenStream = crate_name.parse().unwrap(); quote! { use async_graphql::{ + dataloader::DataLoader, http::{playground_source, GraphQLPlaygroundConfig}, - EmptyMutation, EmptySubscription, Schema, dataloader::DataLoader + EmptyMutation, EmptySubscription, Schema, }; use async_graphql_poem::GraphQL; + use dotenv::dotenv; use poem::{get, handler, listener::TcpListener, web::Html, IntoResponse, Route, Server}; use sea_orm::Database; + use std::env; use #crate_name_token::*; @@ -147,34 +118,54 @@ pub fn generate_main(db_url: &str, crate_name: &str) -> TokenStream { async fn graphql_playground() -> impl IntoResponse { Html(playground_source(GraphQLPlaygroundConfig::new("/"))) } - #[tokio::main] async fn main() { + dotenv().ok(); + + let db_url = env::var("DATABASE_URL").expect("DATABASE_URL environment variable not set"); + + let depth_limit = env::var("DEPTH_LIMIT") + .map(|data| data.parse::().expect("DEPTH_LIMIT is not a number")) + .map_or(None, |data| Some(data)); + + let complexity_limit = env::var("COMPLEXITY_LIMIT") + .map(|data| { + data.parse::() + .expect("COMPLEXITY_LIMIT is not a number") + }) + .map_or(None, |data| Some(data)); + tracing_subscriber::fmt() .with_max_level(tracing::Level::DEBUG) .with_test_writer() .init(); - - // TODO: use .env file to configure url - let database = Database::connect(#db_url).await.unwrap(); - - // TODO use environment variables to configure dataloader batch size + let database = Database::connect(db_url).await.unwrap(); let orm_dataloader: DataLoader = DataLoader::new( OrmDataloader { - db: database.clone() + db: database.clone(), }, - tokio::spawn - ) ; - + tokio::spawn, + ); let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription) .data(database) - .data(orm_dataloader) - .finish(); + .data(orm_dataloader); - let app = Route::new().at("/", get(graphql_playground).post(GraphQL::new(schema))); + let schema = if let Some(depth) = depth_limit { + schema.limit_depth(depth) + } else { + schema + }; - println!("Playground: http://localhost:8000"); + let schema = if let Some(complexity) = complexity_limit { + schema.limit_complexity(complexity) + } else { + schema + }; + let schema = schema.finish(); + + let app = Route::new().at("/", get(graphql_playground).post(GraphQL::new(schema))); + println!("Playground: http://localhost:8000"); Server::new(TcpListener::bind("0.0.0.0:8000")) .run(app) .await @@ -186,14 +177,36 @@ pub fn generate_main(db_url: &str, crate_name: &str) -> TokenStream { pub fn write_main>( path: &P, - db_url: &str, crate_name: &str, ) -> std::io::Result<()> { - let tokens = generate_main(db_url, crate_name); + let tokens = generate_main(crate_name); let file_name = path.as_ref().join("main.rs"); - std::fs::write(file_name, tokens.to_string())?; + std::fs::write(file_name, add_line_break(tokens))?; + + Ok(()) +} + +pub fn write_env>( + path: &P, + db_url: &str, + depth_limit: Option, + complexity_limit: Option, +) -> std::io::Result<()> { + let depth_limit = depth_limit.map_or("".into(), |value| value.to_string()); + let complexity_limit = complexity_limit.map_or("".into(), |value| value.to_string()); + + let tokens = [ + format!(r#"DATABASE_URL="{}""#, db_url), + format!(r#"# COMPLEXITY_LIMIT={}"#, depth_limit), + format!(r#"# DEPTH_LIMIT={}"#, complexity_limit), + ] + .join("\n"); + + let file_name = path.as_ref().join(".env"); + + std::fs::write(file_name, tokens)?; Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 233d6a47..c5ffb6a0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +pub use seaography_derive as macros; + #[derive(clap::Parser)] #[clap(author, version, about, long_about = None)] pub struct Args { @@ -9,4 +11,58 @@ pub struct Args { #[clap(value_parser)] pub destination: String, + + #[clap(short, long)] + pub expanded_format: Option, + + #[clap(short, long)] + pub depth_limit: Option, + + #[clap(short, long)] + pub complexity_limit: Option, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, async_graphql::Enum)] +pub enum OrderByEnum { + Asc, + Desc, +} + +pub type BinaryVector = Vec; + +#[derive(Debug, async_graphql::InputObject)] +#[graphql(concrete(name = "StringFilter", params(String)))] +#[graphql(concrete(name = "TinyIntegerFilter", params(i8)))] +#[graphql(concrete(name = "SmallIntegerFilter", params(i16)))] +#[graphql(concrete(name = "IntegerFilter", params(i32)))] +#[graphql(concrete(name = "BigIntegerFilter", params(i64)))] +#[graphql(concrete(name = "TinyUnsignedFilter", params(u8)))] +#[graphql(concrete(name = "SmallUnsignedFilter", params(u16)))] +#[graphql(concrete(name = "UnsignedFilter", params(u32)))] +#[graphql(concrete(name = "BigUnsignedFilter", params(u64)))] +#[graphql(concrete(name = "FloatFilter", params(f32)))] +#[graphql(concrete(name = "DoubleFilter", params(f64)))] +// TODO #[graphql(concrete(name = "JsonFilter", params()))] +// TODO #[graphql(concrete(name = "DateFilter", params()))] +// TODO #[graphql(concrete(name = "TimeFilter", params()))] +#[graphql(concrete(name = "DateFilter", params(sea_orm::prelude::Date)))] +#[graphql(concrete(name = "DateTimeFilter", params(sea_orm::prelude::DateTime)))] +#[graphql(concrete(name = "DateTimeUtcFilter", params(sea_orm::prelude::DateTimeUtc)))] +// TODO #[graphql(concrete(name = "TimestampFilter", params()))] +// TODO #[graphql(concrete(name = "TimestampWithTimeZoneFilter", params()))] +#[graphql(concrete(name = "DecimalFilter", params(sea_orm::prelude::Decimal)))] +// TODO #[graphql(concrete(name = "UuidFilter", params(uuid::Uuid)))] +#[graphql(concrete(name = "BinaryFilter", params(BinaryVector)))] +#[graphql(concrete(name = "BooleanFilter", params(bool)))] +// TODO #[graphql(concrete(name = "EnumFilter", params()))] +pub struct TypeFilter { + pub eq: Option, + pub ne: Option, + pub gt: Option, + pub gte: Option, + pub lt: Option, + pub lte: Option, + pub is_in: Option>, + pub is_not_in: Option>, + pub is_null: Option, } diff --git a/src/main.rs b/src/main.rs index 1a49a8db..ccc35850 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,11 +7,14 @@ async fn main() { let path = std::path::Path::new(&args.destination); - let expanded_format = false; - - let db_url = &args.database_url; - - write_project(&path, db_url, &args.crate_name, expanded_format) + write_project( + &path, + &args.database_url, + &args.crate_name, + args.expanded_format.unwrap_or(false), + args.depth_limit, + args.complexity_limit + ) .await .unwrap(); }