Skip to content

Commit

Permalink
add some traceback abilities
Browse files Browse the repository at this point in the history
  • Loading branch information
xuecan authored May 28, 2024
1 parent 0ea1f31 commit 072ef0c
Showing 1 changed file with 137 additions and 63 deletions.
200 changes: 137 additions & 63 deletions mysql-workbench-plugin-doc-generating.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,101 @@
# -*- coding: utf-8 -*-
# MySQL Workbench Plugin
# Written in MySQL Workbench 6.3.10
# Written in MySQL Workbench 8.0.36
#
# Original Author: Hieu Le
# Author: Yao Lei <[email protected]>
# Xue Can <[email protected]>

import time
from wb import *
import traceback

import grt
import mforms

from wb import *

G = {
"LAST_CHANGE_DATE" : [], # tables last change time; type: int(timestamp)
"DEFAULT_DATABASE" : None,

"LAST_CHANGE_DATE": [], # tables last change time; type: int(timestamp)
"DEFAULT_DATABASE": None,
"STATUS_TEXT": "",
}
ModuleInfo = DefineModule("ModelDocumentation", author="NETPAS Developers", version="1.2.0",
description="Generate Markdown documentation from a model")
ModuleInfo = DefineModule(
"ModelDocumentation",
author="NETPAS Developers",
version="1.2.0",
description="Generate Markdown documentation from a model",
)


# This plugin takes no arguments
@ModuleInfo.plugin("Netpas", caption="Generate documentation (Markdown)",
description="description", input=[wbinputs.currentDiagram()], pluginMenu="Utilities")
@ModuleInfo.plugin(
"Netpas",
caption="Generate documentation (Markdown)",
description="description",
input=[wbinputs.currentDiagram()],
pluginMenu="Utilities",
)
@ModuleInfo.export(grt.INT, grt.classes.db_Catalog)
def documentation(diagram):
G["DEFAULT_DATABASE"] = [figure for figure in diagram.figures if hasattr(figure, "table")][0].table.owner
db_obj = G["DEFAULT_DATABASE"]
# db name
title_text = "# {}\n\n".format(db_obj.name)
table_text = ""
view_text = ""

for figure in diagram.figures:
if hasattr(figure, "table") and figure.table:
table_text += writeTableDoc(figure.table)
if hasattr(figure,"view") and figure.view:
view_text += writeViewDoc(figure.view)
if view_text:
view_text = "# *Views*\n\n" + view_text
# db comment
title_text += "*{}*\n\n".format(nl2br(db_obj.comment)) if db_obj.comment else "\n\n"
# db last change date
last_change_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(max(G["LAST_CHANGE_DATE"])))
title_text += "{} *{}*\n\n".format("Automatically generate documents. The latest form of document changes by"
, last_change_time)
# Database Structure
title_text += "![Database Structure](./{}.db.png)\n\n".format(db_obj.name)
# merge text
text = title_text + table_text + view_text
mforms.Utilities.set_clipboard_text(text)
mforms.App.get().set_status_text("Documentation generated into the clipboard. Paste it to your editor.")
print("Documentation is copied to the clipboard.")
output("Generating documentation...", reset=True)
try:
G["DEFAULT_DATABASE"] = [
figure for figure in diagram.figures if hasattr(figure, "table")
][0].table.owner
db_obj = G["DEFAULT_DATABASE"]
# db name
title_text = "# {}\n\n".format(db_obj.name)
table_text = ""
view_text = ""

for figure in diagram.figures:
if hasattr(figure, "table") and figure.table:
table_text += writeTableDoc(figure.table)
if hasattr(figure, "view") and figure.view:
view_text += writeViewDoc(figure.view)
if view_text:
view_text = "# *Views*\n\n" + view_text

# db comment
title_text += (
"*{}*\n\n".format(nl2br(db_obj.comment)) if db_obj.comment else "\n\n"
)
# db last change date
last_change_time = time.strftime(
"%Y-%m-%d %H:%M:%S", time.localtime(max(G["LAST_CHANGE_DATE"]))
)
title_text += "{} *{}*\n\n".format(
"Automatically generate documents. The latest form of document changes by",
last_change_time,
)
# Database Structure
title_text += "![Database Structure](./{}.db.png)\n\n".format(db_obj.name)

# merge text
text = title_text + table_text + view_text
set_clipboard_text(text)
output(
"Documentation generated into the clipboard. Paste it to your editor.",
reset=True,
)
print("Documentation is copied to the clipboard.")
except Exception as exc:
output(f"Oops! {exc}. See the clipboard for more information.", reset=True)
details = traceback.format_exc()
set_clipboard_text(details)
return 0


def writeTableDoc(table):
# table last change date
last_change_date = time.mktime(time.strptime(table.owner.lastChangeDate, "%Y-%m-%d %H:%M"))
last_change_date = time.mktime(
time.strptime(table.owner.lastChangeDate, "%Y-%m-%d %H:%M")
)
G["LAST_CHANGE_DATE"].append(int(last_change_date))
text = ""
if G["DEFAULT_DATABASE"].name == table.owner.name:
text = "## **<a id='{}'></a>{}**\n\n".format(table.name.lower().replace("_", "-"), table.name.lower())
text = "## **<a id='{}'></a>{}**\n\n".format(
table.name.lower().replace("_", "-"), table.name.lower()
)
text += "---\n\n"
text += "### *Description:*\n\n"
text += table.comment + "\n\n"
Expand All @@ -70,7 +106,9 @@ def writeTableDoc(table):
text += "\n\n"
if len(table.indices):
text += "### *Indices:*\n\n"
text += "| Name | Columns | Type | Description |\n| --- | --- | --- | --- |\n"
text += (
"| Name | Columns | Type | Description |\n| --- | --- | --- | --- |\n"
)
for index in table.indices:
text += writeIndexDoc(index)
text += "\n\n"
Expand Down Expand Up @@ -106,13 +144,13 @@ def writeColumnDoc(column, table):
# column type name
if column.simpleType:
text += " | " + column.simpleType.name
if 'UNSIGNED' in column.flags:
text += ' '+ 'UNSIGNED'
if "UNSIGNED" in column.flags:
text += " " + "UNSIGNED"
# column max lenght if any
if column.length != -1:
text += "(" + str(column.length) + ")"
if column.collationName.endswith("_bin"):
text +=' ' + 'BINARY'
if column.collationName.endswith("_bin"):
text += " " + "BINARY"
else:
text += " | "
text += " | "
Expand All @@ -130,38 +168,54 @@ def writeColumnDoc(column, table):
attribs.append("Unique")
text += ", ".join(attribs)
# column default value
text += " | " + (("`" + column.defaultValue.replace("\'","") + "`") if column.defaultValue else " ")
text += " | " + (
("`" + column.defaultValue.replace("'", "") + "`")
if column.defaultValue
else " "
)
# column description
text += " | " + (nl2br(column.comment) if column.comment else " ")
if 'ENUM' in column.formattedType:
if "ENUM" in column.formattedType:
# text+=str(column.formattedType[4:])
text += "( "
values = column.formattedType[4:][2:-2]
values = values.replace("','","`, `")
values = '`' + values + '`'
values = values.replace("','", "`, `")
values = "`" + values + "`"
text += values
text += " )"
# value.replace()
if 'SET' in column.formattedType:
# value.replace()
if "SET" in column.formattedType:
text += "( "
values = column.formattedType[3:][2:-2]
values = values.replace("','","`, `")
values = '`' + values + '`'
values = values.replace("','", "`, `")
values = "`" + values + "`"
text += values
text += " )"
# foreign key
for fk in table.foreignKeys:
if len(fk.columns) == 0:
raise RuntimeError(f"Foreign key {fk.name} has no columns")
if fk.columns[0].name == column.name:
# redirect label a
fk_filed = fk.referencedColumns[0].name.lower()
rep_fk_filed = fk.referencedColumns[0].name.lower().replace("_", "-")
fk_table_name = fk.referencedColumns[0].owner.name.lower()
rep_fk_table_name = fk.referencedColumns[0].owner.name.lower().replace("_", "-")
text += ("<br /><br />" if column.comment else "") +"REFERENCES" + " " + "[**{}**](#{}) ".format(fk_table_name, rep_fk_table_name) + "(" + "[**{}**](#{}-{})".format(fk_filed,fk_table_name,rep_fk_filed) + ")"
if fk.updateRule != 'RESTRICT':
text += ' ' + 'ON UPDATE' + ' ' + fk.updateRule
if fk.deleteRule != 'RESTRICT':
text += ' ' + 'ON DELETE' + ' ' + fk.deleteRule
rep_fk_table_name = (
fk.referencedColumns[0].owner.name.lower().replace("_", "-")
)
text += (
("<br /><br />" if column.comment else "")
+ "REFERENCES"
+ " "
+ "[**{}**](#{}) ".format(fk_table_name, rep_fk_table_name)
+ "("
+ "[**{}**](#{}-{})".format(fk_filed, fk_table_name, rep_fk_filed)
+ ")"
)
if fk.updateRule != "RESTRICT":
text += " " + "ON UPDATE" + " " + fk.updateRule
if fk.deleteRule != "RESTRICT":
text += " " + "ON DELETE" + " " + fk.deleteRule
break
# finish
text += " |" + "\n"
Expand All @@ -172,7 +226,9 @@ def writeIndexDoc(index):
# index name
text = "| " + index.name
# index columns
text += " | " + ", ".join(map(lambda x: "`" + x.referencedColumn.name + "`", index.columns))
text += " | " + ", ".join(
map(lambda x: "`" + x.referencedColumn.name + "`", index.columns)
)
# index type
text += " | " + index.indexType
# index description
Expand All @@ -185,14 +241,32 @@ def writeIndexDoc(index):
def writeViewDoc(view):
text = ""
if G["DEFAULT_DATABASE"].name == view.owner.name:
text = "## **<a id='{}'></a>{}**\n\n".format(view.name.lower().replace("_", "-"), view.name.lower())
text = "## **<a id='{}'></a>{}**\n\n".format(
view.name.lower().replace("_", "-"), view.name.lower()
)
text += "---\n\n"
text += "### *Description:*\n\n"
text += view.comment + "\n\n"
text += "### *Sql:*\n\n"
text += "```sql" + "\n" + view.sqlDefinition + "\n" + "```" + "\n"
return text
text += "### *Sql:*\n\n"
text += "```sql" + "\n" + view.sqlDefinition + "\n" + "```" + "\n"
return text


def nl2br(text):
return "<br />".join(map(lambda x: x.strip(), text.split("\n")))


def set_clipboard_text(text):
mforms.Utilities.set_clipboard_text(text)


def set_status_text(text):
mforms.App.get().set_status_text(text)


def output(text, reset=False):
if reset:
G["STATUS_TEXT"] = text
else:
G["STATUS_TEXT"] = text + " | " + G["STATUS_TEXT"]
set_status_text(G["STATUS_TEXT"])

0 comments on commit 072ef0c

Please sign in to comment.