Skip to content
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

Add mermaid renderer for Entity relations #13

Merged
merged 39 commits into from
Dec 14, 2022
Merged

Add mermaid renderer for Entity relations #13

merged 39 commits into from
Dec 14, 2022

Conversation

butschster
Copy link
Contributor

@butschster butschster commented Nov 16, 2022

#10
Usage:

use Cycle\Schema\Renderer\MermaidRenderer\MermaidRenderer;
use Cycle\ORM\SchemaInterface;

$mermaid = new MermaidRenderer();

$mermaid->render([
    'comment' => [
        SchemaInterface::DATABASE => 'default',
        SchemaInterface::TABLE => 'comment',
        SchemaInterface::PRIMARY_KEY => ['id'],
        SchemaInterface::FIND_BY_KEYS => ['id'],
        SchemaInterface::COLUMNS => [
            'id' => 'id',
            'public' => 'public',
            'content' => 'content',
            'created_at' => 'created_at',
            'updated_at' => 'updated_at',
            'published_at' => 'published_at',
            'deleted_at' => 'deleted_at',
            'user_id' => 'user_id',
            'post_id' => 'post_id',
        ],
        SchemaInterface::RELATIONS => [
            'user' => [
                Relation::TYPE => Relation::BELONGS_TO,
                Relation::TARGET => 'user',
                Relation::LOAD => Relation::LOAD_EAGER,
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::NULLABLE => false,
                    Relation::INNER_KEY => 'user_id',
                    Relation::OUTER_KEY => ['id'],
                ],
            ],
            'post' => [
                Relation::TYPE => Relation::BELONGS_TO,
                Relation::TARGET => 'post',
                Relation::LOAD => Relation::LOAD_PROMISE,
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::NULLABLE => false,
                    Relation::INNER_KEY => 'post_id',
                    Relation::OUTER_KEY => ['id'],
                ],
            ],
        ],
        SchemaInterface::TYPECAST => [
            'id' => 'int',
            'public' => 'bool',
            'created_at' => 'datetime',
            'updated_at' => 'datetime',
            'published_at' => 'datetime',
            'deleted_at' => 'datetime',
            'user_id' => 'int',
            'post_id' => 'int',
        ],
        SchemaInterface::SCHEMA => [],
    ],
    'post' => [
        SchemaInterface::DATABASE => 'default',
        SchemaInterface::TABLE => 'post',
        SchemaInterface::PRIMARY_KEY => ['id'],
        SchemaInterface::FIND_BY_KEYS => ['id'],
        SchemaInterface::COLUMNS => [
            'id' => 'id',
            'slug' => 'slug',
            'title' => 'title',
            'public' => 'public',
            'content' => 'content',
            'created_at' => 'created_at',
            'updated_at' => 'updated_at',
            'published_at' => 'published_at',
            'deleted_at' => 'deleted_at',
            'user_id' => 'user_id',
        ],
        SchemaInterface::RELATIONS => [
            'user' => [
                Relation::TYPE => Relation::BELONGS_TO,
                Relation::TARGET => 'user',
                Relation::LOAD => Relation::LOAD_PROMISE,
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::NULLABLE => false,
                    Relation::INNER_KEY => 'user_id',
                    Relation::OUTER_KEY => ['id'],
                ],
            ],
            'tags' => [
                Relation::TYPE => Relation::MANY_TO_MANY,
                Relation::TARGET => 'tag',
                Relation::COLLECTION_TYPE => 'array',
                Relation::LOAD => Relation::LOAD_PROMISE,
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::NULLABLE => false,
                    Relation::WHERE => [],
                    Relation::ORDER_BY => [],
                    Relation::INNER_KEY => ['id'],
                    Relation::OUTER_KEY => ['id'],
                    Relation::THROUGH_ENTITY => 'postTag',
                    Relation::THROUGH_INNER_KEY => 'post_id',
                    Relation::THROUGH_OUTER_KEY => 'tag_id',
                    Relation::THROUGH_WHERE => [],
                ],
            ],
            'comments' => [
                Relation::TYPE => Relation::HAS_MANY,
                Relation::TARGET => 'comment',
                Relation::COLLECTION_TYPE => 'array',
                Relation::LOAD => Relation::LOAD_PROMISE,
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::NULLABLE => false,
                    Relation::WHERE => [],
                    Relation::ORDER_BY => [],
                    Relation::INNER_KEY => ['id'],
                    Relation::OUTER_KEY => 'post_id',
                ],
            ],
            'image' => [
                Relation::TYPE => Relation::MORPHED_HAS_ONE,
                Relation::TARGET => 'image',
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::INNER_KEY => 'id',
                    Relation::OUTER_KEY => 'parentId',
                    Relation::MORPH_KEY => 'parentType',
                ],
            ],
        ],
        SchemaInterface::TYPECAST => [
            'id' => 'int',
            'public' => 'bool',
            'created_at' => 'datetime',
            'updated_at' => 'datetime',
            'published_at' => 'datetime',
            'deleted_at' => 'datetime',
            'user_id' => 'int',
        ],
        SchemaInterface::SCHEMA => [],
    ],
    'postTag' => [
        SchemaInterface::DATABASE => 'default',
        SchemaInterface::TABLE => 'post_tag',
        SchemaInterface::PRIMARY_KEY => ['id'],
        SchemaInterface::FIND_BY_KEYS => ['id'],
        SchemaInterface::COLUMNS => [
            'id' => 'id',
            'post_id' => 'post_id',
            'tag_id' => 'tag_id',
        ],
        SchemaInterface::RELATIONS => [],
        SchemaInterface::SCOPE => null,
        SchemaInterface::TYPECAST => [
            'id' => 'int',
            'post_id' => 'int',
            'tag_id' => 'int',
        ],
        SchemaInterface::SCHEMA => [],
    ],
    'tag' => [
        SchemaInterface::DATABASE => 'default',
        SchemaInterface::TABLE => 'tag',
        SchemaInterface::PRIMARY_KEY => ['id'],
        SchemaInterface::FIND_BY_KEYS => ['id'],
        SchemaInterface::COLUMNS => [
            'id' => 'id',
            'label' => 'label',
            'created_at' => 'created_at',
        ],
        SchemaInterface::RELATIONS => [
            'posts' => [
                Relation::TYPE => Relation::MANY_TO_MANY,
                Relation::TARGET => 'post',
                Relation::COLLECTION_TYPE => 'array',
                Relation::LOAD => Relation::LOAD_PROMISE,
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::NULLABLE => false,
                    Relation::WHERE => [],
                    Relation::ORDER_BY => [],
                    Relation::INNER_KEY => ['id'],
                    Relation::OUTER_KEY => ['id'],
                    Relation::THROUGH_ENTITY => 'postTag',
                    Relation::THROUGH_INNER_KEY => 'tag_id',
                    Relation::THROUGH_OUTER_KEY => 'post_id',
                    Relation::THROUGH_WHERE => [],
                ],
            ],
        ],
        SchemaInterface::SCOPE => null,
        SchemaInterface::TYPECAST => [
            'id' => 'int',
            'created_at' => 'datetime',
        ],
        SchemaInterface::SCHEMA => [],
    ],
    'user' => [
        SchemaInterface::DATABASE => 'default',
        SchemaInterface::TABLE => 'user',
        SchemaInterface::PRIMARY_KEY => ['id'],
        SchemaInterface::FIND_BY_KEYS => ['id'],
        SchemaInterface::COLUMNS => [
            'id' => 'id',
            'login' => 'login',
            'passwordHash' => 'password_hash',
            'created_at' => 'created_at',
            'updated_at' => 'updated_at',
        ],
        SchemaInterface::RELATIONS => [
            'posts' => [
                Relation::TYPE => Relation::HAS_MANY,
                Relation::TARGET => 'post',
                Relation::COLLECTION_TYPE => 'array',
                Relation::LOAD => Relation::LOAD_PROMISE,
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::NULLABLE => true,
                    Relation::WHERE => [],
                    Relation::ORDER_BY => [],
                    Relation::INNER_KEY => ['id'],
                    Relation::OUTER_KEY => 'user_id',
                ],
            ],
            'comments' => [
                Relation::TYPE => Relation::HAS_MANY,
                Relation::TARGET => 'comment',
                Relation::COLLECTION_TYPE => 'array',
                Relation::LOAD => Relation::LOAD_PROMISE,
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::NULLABLE => false,
                    Relation::WHERE => [],
                    Relation::ORDER_BY => [],
                    Relation::INNER_KEY => ['id'],
                    Relation::OUTER_KEY => 'user_id',
                ],
            ],
            'image' => [
                Relation::TYPE => Relation::MORPHED_HAS_ONE,
                Relation::TARGET => 'image',
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::INNER_KEY => 'id',
                    Relation::OUTER_KEY => 'parentId',
                    Relation::MORPH_KEY => 'parentType',
                ],
            ],
            'foo' => [
                Relation::TYPE => Relation::MORPHED_HAS_MANY,
                Relation::TARGET => 'foo',
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::INNER_KEY => 'id',
                    Relation::OUTER_KEY => 'parentId',
                    Relation::MORPH_KEY => 'parentType',
                ],
            ],
        ],
        SchemaInterface::SCOPE => null,
        SchemaInterface::TYPECAST => [
            'id' => 'int',
            'created_at' => 'datetime',
            'updated_at' => 'datetime',
        ],
        SchemaInterface::SCHEMA => [],
    ],
    'image' => [
        SchemaInterface::DATABASE => 'default',
        SchemaInterface::TABLE => 'image',
        SchemaInterface::PRIMARY_KEY => 'id',
        SchemaInterface::COLUMNS => [
            'id' => 'id',
            'parentId' => 'parent_id',
            'parentType' => 'parent_type',
            'url' => 'url',
        ],
        SchemaInterface::SCHEMA => [],
        SchemaInterface::RELATIONS => []
    ],
    'foo' => [
        SchemaInterface::MAPPER => Mapper::class,
        SchemaInterface::DATABASE => 'default',
        SchemaInterface::TABLE => 'foo',
        SchemaInterface::PRIMARY_KEY => 'id',
        SchemaInterface::COLUMNS => [
            'id' => 'id',
            'parentId' => 'parent_id',
            'parentType' => 'parent_type',
            'url' => 'url',
        ],
        SchemaInterface::SCHEMA => [],
    ],
    'bar' => [
        SchemaInterface::MAPPER => Mapper::class,
        SchemaInterface::DATABASE => 'default',
        SchemaInterface::TABLE => 'bar',
        SchemaInterface::PRIMARY_KEY => 'id',
        SchemaInterface::COLUMNS => [
            'id' => 'id',
            'title' => 'title',
            'body' => 'body',
        ],
        SchemaInterface::SCHEMA => [],
        SchemaInterface::RELATIONS => [
            'foo' => [
                Relation::TYPE => Relation::BELONGS_TO_MORPHED,
                Relation::TARGET => 'foo',
                Relation::SCHEMA => [
                    Relation::CASCADE => true,
                    Relation::INNER_KEY => 'id',
                    Relation::OUTER_KEY => 'parentId',
                    Relation::MORPH_KEY => 'parentType',
                ],
            ],
        ]
    ],
]);

Will return something like this...

erDiagram
post {
    int id
    string slug
    bool public
    string content
    datetime created_at
    datetime updated_at
    datetime published_at
    datetime deleted_at
    int user_id
}
post ||--|| student : "BT author"
post ||--|{ postTag : many_to_many
tag ||--|{ postTag : many_to_many
postTag {
    int id
    int post_id
    int tag_id
}

tag {
    int id
    string label
    datetime created_at
}
tag ||--|{ postTag : many_to_many
post ||--|{ postTag : many_to_many
identity {
    int id
    datetime created_at
    datetime updated_at
}
user {
    int id
    string login
    string password_hash
}
identity ||--o{ user : "STI"
user ||--o{ admin : "JTI [id:id]"
user ||--o{ student : "JTI [id:id]"
admin ||--o{ teacher : "JTI [id:id]"
admin {
    int id
    string email
}
student {
    int id
    int iq
}
teacher {
    int id
    bool salary
}
message {
    int id
    string title
}
student ||--o{ post : "HM posts > student"
Loading

@roxblnfk
Copy link
Member

roxblnfk commented Dec 2, 2022

Why didn't phpunit actions start?

@butschster butschster changed the title Add mermaid renderer Add mermaid renderer for Entity relations Dec 5, 2022
@codecov
Copy link

codecov bot commented Dec 5, 2022

Codecov Report

Merging #13 (e4bea89) into 1.x (c733781) will increase coverage by 0.76%.
The diff coverage is 98.68%.

@@             Coverage Diff              @@
##                1.x      #13      +/-   ##
============================================
+ Coverage     96.42%   97.18%   +0.76%     
- Complexity      156      235      +79     
============================================
  Files            21       51      +30     
  Lines           447      676     +229     
============================================
+ Hits            431      657     +226     
- Misses           16       19       +3     
Impacted Files Coverage Δ
src/MermaidRenderer/MermaidRenderer.php 96.93% <96.93%> (ø)
src/MermaidRenderer/Annotation.php 100.00% <100.00%> (ø)
src/MermaidRenderer/Column.php 100.00% <100.00%> (ø)
src/MermaidRenderer/Entity/EntityRelation.php 100.00% <100.00%> (ø)
src/MermaidRenderer/Entity/EntityTable.php 100.00% <100.00%> (ø)
src/MermaidRenderer/Method.php 100.00% <100.00%> (ø)
src/MermaidRenderer/Method/BelongsToMethod.php 100.00% <100.00%> (ø)
.../MermaidRenderer/Method/BelongsToMorphedMethod.php 100.00% <100.00%> (ø)
src/MermaidRenderer/Method/EmbeddedMethod.php 100.00% <100.00%> (ø)
src/MermaidRenderer/Method/HasManyMethod.php 100.00% <100.00%> (ø)
... and 20 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@butschster butschster requested a review from roxblnfk December 8, 2022 12:04
@butschster butschster merged commit a9995e0 into 1.x Dec 14, 2022
@butschster butschster deleted the feature/mermaid branch December 14, 2022 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:feature New feature.
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants