-
-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Add seaography documentation #41
Merged
Merged
Changes from 12 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
c3a39fd
WIP: Add Seaography documentation
karatakis a4e2abf
WIP: Add Seaography documentation
karatakis e557749
WIP: Add Seaography documentation
karatakis a61205c
WIP: Add Seaography documentation
karatakis 97acb72
WIP: Add Seaography documentation
karatakis aa0bc4d
WIP: Add Seaography documentation
karatakis d0080e7
WIP: Add Seaography documentation
karatakis e799b0c
WIP: Add Seaography documentation
karatakis 521e803
WIP: Add Seaography documentation
karatakis f6a584d
WIP: Add Seaography documentation
karatakis 95011b8
Add running an exaple page
karatakis 2afefd5
Update exaple project instructions
karatakis 7c294cc
Update examples page
karatakis 4578115
Update documentation
karatakis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Dependencies | ||
/node_modules | ||
|
||
# Production | ||
/build | ||
|
||
# Generated files | ||
.docusaurus | ||
.cache-loader | ||
|
||
# Misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Website | ||
|
||
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. | ||
|
||
### Installation | ||
|
||
``` | ||
$ yarn | ||
``` | ||
|
||
### Local Development | ||
|
||
``` | ||
$ yarn start | ||
``` | ||
|
||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. | ||
|
||
### Build | ||
|
||
``` | ||
$ yarn build | ||
``` | ||
|
||
This command generates static content into the `build` directory and can be served using any static contents hosting service. | ||
|
||
### Deployment | ||
|
||
Using SSH: | ||
|
||
``` | ||
$ USE_SSH=true yarn deploy | ||
``` | ||
|
||
Not using SSH: | ||
|
||
``` | ||
$ GIT_USER=<Your GitHub username> yarn deploy | ||
``` | ||
|
||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')], | ||
}; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Getting started | ||
|
||
|
||
## Installing CLI | ||
```bash | ||
cargo install seaography | ||
``` | ||
|
||
## CLI parameters | ||
|
||
```bash | ||
seaography <database_url> <crate_name> <output_folder> | ||
``` | ||
|
||
* **database_url:** a valid URL pointing to the database. | ||
examples: `mysql://user:pass@127.0.0.1:1235/database_name`, `sqlite://my_db.db`, `pgsql://user:pass@127.0.0.1/base_name` | ||
* **crate_name:** the cargo crate name of the generated project | ||
* **output_folder:** path pointing to the output folder, it will create it if does not exist | ||
|
||
## Prerequisites | ||
|
||
In order to understand how the generated code works its recommended to study the following resources: | ||
|
||
1. [async-graphql](https://docs.rs/async-graphql/latest/async_graphql/) | ||
|
||
Is a server side GraphQL library for Rust. | ||
|
||
2. [sea-orm](https://docs.rs/sea-orm/latest/sea_orm/) | ||
|
||
SeaORM is a relational ORM to help you build web services in Rust with the familiarity of dynamic languages. | ||
|
||
3. [poem](https://docs.rs/crate/poem/latest) | ||
|
||
A full-featured and easy-to-use web framework with the Rust programming language. | ||
|
||
4. [tokio*](https://docs.rs/tokio/latest/tokio/) | ||
|
||
A runtime for writing reliable, asynchronous, and slim applications with the Rust programming language. | ||
|
||
5. [itertools*](https://docs.rs/itertools/latest/itertools/) | ||
|
||
Extra iterator adaptors, functions and macros. | ||
|
||
* Recommended to study, but not required | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
# Tool internals | ||
|
||
Here we will describe the internals of the CLI tool. Firstly, we will study the tool itself, and how its structured. Then, we will focus on the generator sub-crate and study the different generator modes. | ||
|
||
## Internal crates | ||
|
||
The project depends on 3 sub-crates (`types`, `discovery`, `generator`). This helps with separation of logic into simpler modules which are easier to maintain, extend and debug. | ||
|
||
### `types` | ||
|
||
The `types` sub-crate contains all required types and utilities that are shared between the other sub-crates. | ||
|
||
* `schema_meta`: holds database metadata (type, version, url), table metadata, and enumeration metadata | ||
* `table_meta`: holds table metadata (name, columns, relations) | ||
* `relationship_meta`: holds tables relationship metadata (source/destination table names, source/destination columns) | ||
* `column_meta`: holds table column metadata (name, type, nullable, is_primary) | ||
* `enum_meta`: holds enumeration metadata (name, values) | ||
* `column_type`: column type enumeration | ||
|
||
### `discoverer` | ||
|
||
The `discoverer` sub-crate contains all required functions to read any database (sqlite, mysql, pgsql) and convert it to `schema_meta`. | ||
|
||
* `lib`: contains the main function that receives database url, check that is correct and exports `schema_meta` | ||
* `utils`: contains all function to convert table crate statements into `schema_meta` | ||
* `mysql`: contains a function that connects to mysql db and returns table create statements | ||
* `sqlite`: contains a function that connects to sqlite db and returns table create statements | ||
* `pgsql`: contains a function that connects to pgsql db and returns table create statements | ||
|
||
### `generator` | ||
|
||
The `generator` sub-crate contains functions to generate GraphQL compatible entities. | ||
|
||
* `toml`: generate rust crate toml specification | ||
* `lib`: generate for main.rs file | ||
* `root_node`: generate GraphQL root node with queries for all entities | ||
* `type_filter`: generate TypeFilter GraphQL type | ||
* `orm_dataloader`: generate OrmDataloader utility type | ||
* `enumeration`: generator for GraphQL enumerations | ||
* `entity`: generator for GraphQL entities (field getters, relationship getters, Filter data type, dataloader load functions) | ||
|
||
### CLI tool | ||
|
||
The core of the tool, coordinates all sub-crates. | ||
|
||
* `main`: the main CLI program | ||
* `lib`: contains functions used from main and are responsible for generating ORM & GraphQL entities | ||
|
||
## Generators | ||
|
||
The generators are responsible for generating the Rust code. It is the main point where the core features we provide reside. Currently the project only implements the expanded code generator. A procedural macro based generator is WIP and will depend on the expanded format generator to generate code with fewer lines of code but same functionality. | ||
|
||
All examples are based on https://dev.mysql.com/doc/sakila/en/ database. | ||
|
||
### Expanded mode | ||
|
||
The expanded generator produce all Rust code. Its easier to modify, but harder to maintain long term. In case a new version of the generator exists you have to regenerate the whole project and apply the your custom modifications again. | ||
|
||
#### Example entity | ||
|
||
```rust | ||
use crate::graphql::*; | ||
pub use crate::orm::category::*; | ||
use sea_orm::prelude::*; | ||
#[async_graphql::Object(name = "Category")] | ||
impl Model { | ||
pub async fn category_id(&self) -> &u8 { | ||
&self.category_id | ||
} | ||
pub async fn name(&self) -> &String { | ||
&self.name | ||
} | ||
pub async fn last_update(&self) -> &DateTimeUtc { | ||
&self.last_update | ||
} | ||
pub async fn category_film_category<'a>( | ||
&self, | ||
ctx: &async_graphql::Context<'a>, | ||
) -> Vec<crate::orm::film_category::Model> { | ||
let data_loader = ctx | ||
.data::<async_graphql::dataloader::DataLoader<OrmDataloader>>() | ||
.unwrap(); | ||
let key = CategoryFilmCategoryFK(self.category_id.clone()); | ||
let data: Option<_> = data_loader.load_one(key).await.unwrap(); | ||
data.unwrap_or(vec![]) | ||
} | ||
} | ||
#[derive(async_graphql :: InputObject, Debug)] | ||
#[graphql(name = "CategoryFilter")] | ||
pub struct Filter { | ||
pub or: Option<Vec<Box<Filter>>>, | ||
pub and: Option<Vec<Box<Filter>>>, | ||
pub category_id: Option<TypeFilter<u8>>, | ||
pub name: Option<TypeFilter<String>>, | ||
pub last_update: Option<TypeFilter<DateTimeUtc>>, | ||
} | ||
#[derive(Clone, Eq, PartialEq, Hash, Debug)] | ||
pub struct CategoryFilmCategoryFK(u8); | ||
#[async_trait::async_trait] | ||
impl async_graphql::dataloader::Loader<CategoryFilmCategoryFK> for OrmDataloader { | ||
type Value = Vec<crate::orm::film_category::Model>; | ||
type Error = std::sync::Arc<sea_orm::error::DbErr>; | ||
async fn load( | ||
&self, | ||
keys: &[CategoryFilmCategoryFK], | ||
) -> Result<std::collections::HashMap<CategoryFilmCategoryFK, Self::Value>, Self::Error> { | ||
let filter = sea_orm::Condition::all().add(sea_orm::sea_query::SimpleExpr::Binary( | ||
Box::new(sea_orm::sea_query::SimpleExpr::Tuple(vec![ | ||
sea_orm::sea_query::Expr::col( | ||
crate::orm::film_category::Column::CategoryId.as_column_ref(), | ||
) | ||
.into_simple_expr(), | ||
])), | ||
sea_orm::sea_query::BinOper::In, | ||
Box::new(sea_orm::sea_query::SimpleExpr::Tuple( | ||
keys.iter() | ||
.map(|tuple| { | ||
sea_orm::sea_query::SimpleExpr::Values(vec![tuple.0.clone().into()]) | ||
}) | ||
.collect(), | ||
)), | ||
)); | ||
use itertools::Itertools; | ||
Ok(crate::orm::film_category::Entity::find() | ||
.filter(filter) | ||
.all(&self.db) | ||
.await? | ||
.into_iter() | ||
.map(|model| { | ||
let key = CategoryFilmCategoryFK(model.category_id.clone()); | ||
(key, model) | ||
}) | ||
.into_group_map()) | ||
} | ||
} | ||
``` | ||
|
||
#### Example enum | ||
|
||
```rust | ||
use crate::orm::sea_orm_active_enums; | ||
use async_graphql::*; | ||
use sea_orm::entity::prelude::*; | ||
#[derive(Debug, Copy, Clone, Eq, PartialEq, EnumIter, DeriveActiveEnum, Enum)] | ||
#[graphql(remote = "sea_orm_active_enums::Rating")] | ||
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "Rating")] | ||
pub enum Rating { | ||
#[sea_orm(string_value = "G")] | ||
G, | ||
#[sea_orm(string_value = "PG")] | ||
Pg, | ||
#[sea_orm(string_value = "PG-13")] | ||
Pg13, | ||
#[sea_orm(string_value = "R")] | ||
R, | ||
#[sea_orm(string_value = "NC-17")] | ||
Nc17, | ||
} | ||
``` | ||
|
||
### Procedural macro mode | ||
TODO: WIP | ||
|
||
Based on https://www.sea-ql.org/SeaORM/docs/generate-entity/entity-structure |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
*
makes this line being interpreted as a list. Consider escaping it :)