<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{config | get(key="title", default="") }} Database Design Document</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css">
<style>
@page {
margin: 10mm 0;
size: A4
}
body {
margin: 0;
font-size: 3.5mm;
}
.sheet {
margin: 0;
padding: 0 10mm;
overflow: hidden;
position: relative;
box-sizing: border-box;
page-break-after: always;
}
body.A4 .sheet {
width: 210mm;
min-height: 276mm
}
body.A4.landscape .sheet {
width: 297mm;
min-height: 189mm
}
body.letter .sheet {
width: 216mm;
min-height: 259mm
}
body.letter.landscape .sheet {
width: 280mm;
min-height: 195mm
}
@media screen {
body {
background: #e0e0e0
}
.sheet {
background: white;
box-shadow: 0 .5mm 2mm rgba(0, 0, 0, .3);
margin: 5mm auto;
padding-bottom: 5mm;
}
}
.break-avoid {
break-inside: avoid;
}
.frame table {
margin-left: auto;
margin-right: auto;
border-collapse: collapse;
width: 100%;
}
.frame th,
td {
border: 1px #000000 solid;
padding: 0.2em;
}
th {
text-align: center
}
.frame caption {
caption-side: top;
}
a {
color: #1a0dab;
}
@media print {
a {
color: #000000;
text-decoration: none;
}
}
pre,
p {
margin: 0.2mm;
font-family: unset;
}
.cover-title {
text-align: center;
position: absolute;
top: 8cm;
width: 100%;
}
.title {
margin-top: 1cm;
}
.footer {
text-align: center;
position: absolute;
bottom: 2cm;
width: 100%;
}
.no_frame {
margin-bottom: 4mm;
}
.narrow {
width: 8mm
}
.middle {
width: 24mm
}
.center {
text-align: center
}
.comment {
margin: 0 0 2mm;
}
.supplementary {
font-size: 80%;
text-align: right;
}
.er {
break-inside: avoid;
margin-top: 5mm;
}
.er svg {
width: 100%;
}
</style>
</head>
<body class="A4">
<section class="sheet cover1">
<div class="cover-title">
<h1 class="title1">Database Design Document</h1>
<h2 class="title2">{{config | get(key="title", default="") }}</h2>
{% if group_list | length == 1 -%}
{% if config.groups | length > 1 -%}
<h3 class="group-name">{{group_list.0.group_def.label | default(value=group_list.0.group_name) }}</h3>
{% endif -%}
{% endif -%}
<p class="created">{{date | date(format="%x", locale=locale)}}</p>
</div>
<div class="footer">
{% if config.author -%}
<p class="author">{{config.author}}</p>
{% endif -%}
</div>
</section>
{% if history | length > 0 -%}
<section class="sheet history">
<div class="frame history">
<table>
<caption>
<h3>Revision History</h3>
</caption>
<thead>
<tr>
<th class="updated">Date</th>
<th class="description">Description</th>
</tr>
</thead>
{% set_global history_idx = 0 %}
{% for row in history -%}
{% set description = row.description | history_description(
AddTable='Add a table: <a href="#table_{T}">{T}</a><br>',
DropTable='Drop a table: {T}<br>',
RenameTable='Rename a table: <a href="#table_{T}">{T}</a> ({C})<br>',
AddColumn='Add a column: <a href="#table_{T}">{T}</a> ({C})<br>',
AddColumn_Plural='Add columns: <a href="#table_{T}">{T}</a> ({C})<br>',
ChangeColumn='Change a column: <a href="#table_{T}">{T}</a> ({C})<br>',
ChangeColumn_Plural='Change columns: <a href="#table_{T}">{T}</a> ({C})<br>',
DropColumn='Drop a column: <a href="#table_{T}">{T}</a> ({C})<br>',
DropColumn_Plural='Drop columns: <a href="#table_{T}">{T}</a> ({C})<br>',
RenameColumn='Rename a column: <a href="#table_{T}">{T}</a> ({C})<br>',
RenameColumn_Plural='Rename columns: <a href="#table_{T}">{T}</a> ({C})<br>',
ChangePrimary='Change the primary key: <a href="#table_{T}">{T}</a><br>',
DropPrimary='Drop the primary key: <a href="#table_{T}">{T}</a><br>',
AddIndex='Add an index: <a href="#table_{T}">{T}</a> ({C})<br>',
AddIndex_Plural='Add indexes: <a href="#table_{T}">{T}</a> ({C})<br>',
ChangeIndex='Change an index: <a href="#table_{T}">{T}</a> ({C})<br>',
ChangeIndex_Plural='Change indexes: <a href="#table_{T}">{T}</a> ({C})<br>',
DropIndex='Drop an index: <a href="#table_{T}">{T}</a> ({C})<br>',
DropIndex_Plural='Drop indexes: <a href="#table_{T}">{T}</a> ({C})<br>',
AddForeign='Add a foreign key: <a href="#table_{T}">{T}</a> ({C})<br>',
AddForeign_Plural='Add foreign keys: <a href="#table_{T}">{T}</a> ({C})<br>',
ChangeForeign='Change a foreign key: <a href="#table_{T}">{T}</a> ({C})<br>',
ChangeForeign_Plural='Change foreign keys: <a href="#table_{T}">{T}</a> ({C})<br>',
DropForeign='Drop a foreign key: <a href="#table_{T}">{T}</a> ({C})<br>',
DropForeign_Plural='Drop foreign keys: <a href="#table_{T}">{T}</a> ({C})<br>',
) -%}
{% if description | length == 0 %}{% continue %}{% endif -%}
<tr>
<td class="updated">{{row.date | date(format="%x", locale=locale)}}</td>
<td class="description">
{{- description | safe -}}
</td>
</tr>
{% set_global history_idx = history_idx + 1 %}
{% if history_idx == history_max %}{% break %}{% endif -%}
{% endfor -%}
</table>
</div>
</section>
{% endif -%}
{% if group_list | length > 1 -%}
<section class="sheet model-group-list">
<div class="frame model-group-list">
<table>
<caption>
<h3>Model Group List</h3>
</caption>
<thead>
<tr>
<th class="no narrow">No.</th>
<th class="group-name">Name</th>
</tr>
</thead>
{% for group in group_list -%}
<tr>
<td class="no center">{{loop.index}}</td>
<td class="group-name"><a href="#sub_{{group.group_name}}">{{group.group_def.label | default(value=group.group_name)}}</a></td>
</tr>
{% endfor -%}
</table>
</div>
</section>
{%- endif -%}
{% for group in group_list -%}
<section class="sheet cover2">
<a id="sub_{{group.group_name}}"></a>
{% if group_list | length > 1 -%}
<div class="title group-name">
<h2>{{group.group_def.label | default(value=group.group_name)}}</h2>
</div>
{% endif -%}
{% if group.models -%}
<div class="frame break-avoid model-list">
<table>
<caption>
<h3>Table List</h3>
</caption>
<thead>
<tr>
<th class="no narrow">No.</th>
<th class="model-name">Name</th>
</tr>
</thead>
{% for model_name, model in group.models -%}
<tr>
<td class="no center">{{loop.index}}</td>
<td class="model-name"><a href="#model_{{group.group_name}}::{{model_name}}">{{model_name}}
{%- if model.label %} ({{model.label}}){% endif %}</a></td>
</tr>
{% endfor -%}
</table>
{% if group.er -%}
<div class="er">
<h3 class="center">ER diagram</h3>
{{group.er | safe}}
</div>
{% endif -%}
</div>
{% endif -%}
</section>
{% if group.models -%}
{% for model_name, model in group.models -%}
<section class="sheet table-info">
<a id="model_{{group.group_name}}::{{model_name}}"></a>
<a id="table_{{model.table_name}}"></a>
<div class="title">
<h3>{{loop.index}}. {{model_name}}{% if model.label %} ({{model.label}}){% endif %}</h3>
</div>
<p class="no_frame table-name">
<span>Real Table Name: </span>
<span>{{model.table_name}}</span>
</p>
{% if model.comment -%}
<div class="comment">
<pre>{{model.comment}}</pre>
</div>
{% endif -%}
<div class="frame table-columns">
<table>
<thead>
<tr>
<th class="no narrow">No.</th>
<th class="name">Logical Name</th>
<th class="name">Physical Name</th>
<th class="type">Type</th>
<th class="null narrow">Null</th>
<th class="length">Length</th>
<th class="primary narrow">Key</th>
<th class="comment">Comment</th>
</tr>
</thead>
{% for name, column in model.columns -%}
<tr>
<td class="no center">{{loop.index}}</td>
<td class="name">{{column | get(key="label", default="")}}</td>
<td class="name">{{column | get(key="column_name", default=name)}}</td>
<td class="type">{% if column.signed %}signed {% endif %}{{column.type}}</td>
<td class="null center">{% if not column.not_null %}Y{% endif %}</td>
<td class="length center">
{%- if column.length %}{{column.length}}{% endif %}
{%- if column.precision %}{{column.precision}}{% endif %}
{%- if column.scale %},{{column.scale}}{% endif %}</td>
<td class="primary center">{% if column.primary %}P{% endif %}</td>
<td class="comment">
{%- if column.enum_values -%}
<p>{% for enum in column.enum_values -%}
{%- if enum.value is defined %}
{{enum.value}}:{{enum | get(key="label", default=enum.name) }}
{%- else %}
{{enum.name}}{% if enum.label %}:{{enum.label}}{% endif %}
{%- endif %}
{%- if enum.comment %} ({{enum.comment}}){% endif %}
{%- if not loop.last %}<br />{% endif %}
{%- endfor %}</p>
{%- endif -%}
{%- if column.comment %}
<pre>{{column.comment}}</pre>{% endif -%}
</td>
</tr>
{% endfor -%}
</table>
<p class="supplementary">All numeric types including double, decimal, etc. are unsigned unless signed is
specified for the data type.</p>
</div>
{% if model.indexes -%}
<div class="frame break-avoid table-indexes">
<table>
<caption>
<h3>Index List</h3>
</caption>
<thead>
<tr>
<th class="no narrow">No.</th>
<th class="type middle">Type</th>
<th class="fields">Column Name</th>
</tr>
</thead>
{% for name, index in model.indexes -%}
<tr>
<td class="no center">{{loop.index}}</td>
<td class="type">
{%- if index %}{{index | get(key="type", default="INDEX") | upper}}
{%- else %}INDEX{% endif %}
</td>
<td class="fields">{%- if index and index.fields %}{% for name, field in index.fields -%}
{%- if field and field.query %}({{field.query}}){% else %}{{name}}{%- if field and field.length %}({{field.length}}){% endif %}{% endif %}
{%- if not loop.last %}, {% endif %}
{%- endfor %}{% else %}{{name}}{% endif %}</td>
</tr>
{% endfor -%}
</table>
</div>
{% endif -%}
{% if model.relations -%}
<div class="frame break-avoid table-relations">
<table>
<caption>
<h3>Relation List</h3>
</caption>
<thead>
<tr>
<th class="no narrow">No.</th>
<th class="name">Name</th>
<th class="local">Local Column</th>
<th class="type">Type</th>
<th class="model">Foreign Table</th>
<th class="foreign">Foreign Column</th>
<th class="on_delete">On Delete</th>
</tr>
</thead>
{% for name, relation in model.relations -%}
<tr>{% set type = relation | get(key="type") %}
<td class="no center">{{loop.index}}</td>
<td class="name">{{relation | get(key="label", default=name)}}</td>
<td class="local">{%- if relation.local %}{{relation.local | join(sep=", ")}}{% else %}
{%- if type == "has_many" or type == "has_one" %}<div style="text-align: center">-</div>{% else %}{{name}}_id{% endif %}
{%- endif %}</td>
<td class="type">{{type | upper}}</td>
<td class="model"><a href="#model_{{relation.model}}">
{{- relation.model | split(pat="::") | last}}</a></td>
<td class="foreign">{%- if relation.foreign %}{{relation.foreign | join(sep=", ")}}{% else %}
{%- if type == "has_many" %}{{model_name}}_id{% else %}<div style="text-align: center">-</div>{% endif %}
{%- endif %}</td>
<td class="on_delete">{{relation | get(key="on_delete", default="")}}</td>
</tr>
{% endfor -%}
</table>
<p class="supplementary">"-" in column indicates primary key.
{%- if config.ignore_foreign_key %} No foreign key constraint is actually set.{% endif -%}
</p>
</div>
{% endif -%}
</section>
{% endfor -%}
{% endif -%}
{% endfor -%}
</body>