为了快速写接口文档,利用python gui开发的小工具快速将powerdesigner的ddl语句转成markdown的入参,出参,以及Java实体类
🔔

为了快速写接口文档,利用python gui开发的小工具快速将powerdesigner的ddl语句转成markdown的入参,出参,以及Java实体类

Tags
python
效果
notion image
 
源码
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from tkinter import *
import hashlib
import re
import time

LOG_LINE_NUM = 0

jdbctype_javatype_map = {
    'BIT(1)': 'Boolean',
    'BIT': 'byte[]',
    'TINYINT': 'Integer',
    'TINYINT(1)': 'Boolean',
    'BOOLEAN': 'Boolean',
    'BOOL': 'Integer',
    'SMALLINT': 'Integer',
    'MEDIUMINT': 'Integer',
    'INT,INTEGER': 'Integer',
    'BIGINT': 'Long',
    'FLOAT': 'Float',
    'DOUBLE': 'jDouble',
    'DECIMAL': 'BigDecimal',
    'DATE': 'Date',
    'DATETIME': 'Timestamp',
    'TIMESTAMP': 'Timestamp',
    'TIME': 'Time',
    'YEAR': 'Short',
    'CHAR': 'String ',
    'VARCHAR': 'String',
    'BINARY': 'byte[]',
    'VARBINARY': 'byte[]',
    'TINYBLOB': 'byte[]',
    'TINYTEXT': 'String',
    'BLOB': 'byte[]',
    'TEXT': 'String',
    'MEDIUMBLOB': 'byte[]',
    'MEDIUMTEXT': 'String',
    'LONGBLOB': 'byte[]',
    'LONGTEXT': 'String',
    'ENUM': 'String',
    'SET': 'String'
}

# sql2md_req_match = re.compile("(\w+)\s*((\w)(?:\w+)\(?(\d*,?\d*)\)?)(?:\s*\w*)*'(.*)'.*", re.M)
sql2md_req_match = re.compile("(?P<column>\w+)\s*(?P<type>(?P<type_head>\w)(?:\w+)\(?(?P<type_length>\d*,?\d*)\)?)(?:\s*\w*)*'?(?P<comment>.*)'?.*")
# sql2md_req_match = re.compile(r"(\w+)\s*	((\w)(?:\w+) \(?(\d*,?\d*)\)?)	(?:\s*\w*)*'(.*)'.*", re.M)
# sql2md_req_des = r"|{0}|-|String|{1}{2}|&radic;|{3}|"
sql2md_req_des = r"|{column}|-|{type}|{type_head}{type_length}|&radic;|{comment}|"
md_table_req_head = "|字段名称|父节点名称|字段类型|长度|必填|备注|\n|:-----:|:---------|:-----:|:--|:-:|:--|\n"

sql2md_res_match = sql2md_req_match
sql2md_res_des = r"|{column}|-|{type}|{comment}|"
md_table_res_head = "|字段名称|父节点名称|字段类型|备注|\n|-------|:--------|:-------|:--|\n"


md2javabean_req_match = re.compile("\|(?P<field>\w+)\|(?:\w*-*)\|(?P<java_type_head>\w)(?P<java_type_body>\w+<?\w*>?)\|\w*\-*\d*\,?.?\d*\|.*\|(?P<comment>.*)\|")
md2javabean_req_des = "\r\n\t/**\r\n\t*{comment}\r\n\t**/\r\n\tprivate {java_type_head}{java_type_body} {field};"

md2javabean_res_match = re.compile("\|(?P<field>\w+)\|(?:\w*-*)\|(?P<java_type_head>\w)(?P<java_type_body>\w+<?\w*>?)\|(?P<comment>.*)\|")
md2javabean_res_des = "\r\n\t/**\r\n\t*{comment}\r\n\t**/\r\n\tprivate {java_type_head}{java_type_body} {field};"

to_java_feild_type_match = re.compile("_(\w)")


class MY_GUI():
    def __init__(self, init_window_name):
        self.init_window_name = init_window_name

    # 设置窗口
    def set_init_window(self):
        self.init_window_name.title("Markdown 小工具_v1.1")  # 窗口名
        # self.init_window_name.geometry('320x160+10+10')                         #290 160为窗口大小,+10 +10 定义窗口弹出时的默认展示位置
        self.init_window_name.geometry('1068x681+10+10')
        # self.init_window_name["bg"] = "pink"                                    #窗口背景色,其他背景色见:blog.csdn.net/chl0000/article/details/7657887
        # self.init_window_name.attributes("-alpha",0.9)                          #虚化,值越小虚化程度越高
        # 标签
        self.init_data_label = Label(self.init_window_name, text="待处理数据")
        self.init_data_label.grid(row=0, column=0)
        self.result_data_label = Label(self.init_window_name, text="输出结果")
        self.result_data_label.grid(row=0, column=14)
        self.log_label = Label(self.init_window_name, text="日志")
        self.log_label.grid(row=12, column=0)
        # 文本框
        self.init_data_Text = Text(self.init_window_name, width=67, height=35)  # 原始数据录入框
        self.init_data_Text.grid(row=1, column=0, rowspan=10, columnspan=10)
        self.result_data_Text = Text(self.init_window_name, width=70, height=49)  # 处理结果展示
        self.result_data_Text.grid(row=1, column=14, rowspan=15, columnspan=10)
        self.log_data_Text = Text(self.init_window_name, width=66, height=9)  # 日志框
        self.log_data_Text.grid(row=13, column=0, columnspan=10)
        # 按钮 2 md5
        self.column_to_md_button = Button(self.init_window_name, text="转md5", bg="lightblue", width=10,
                                          command=self.str_trans_to_md5)  # 调用内部方法  ()为直接调用
        # self.column_to_md_button.grid(row=1, column=11)
        # 按钮 2 md table
        self.sql_ddl_2_md_table_button = Button(self.init_window_name, text="ddl转md表格", bg="lightblue", width=20,
                                                command=self.DB_column_to_md)  # 调用内部方法  ()为直接调用
        self.sql_ddl_2_md_table_button.grid(row=2, column=11)
        # 按钮 2 java table
        self.md_table_to_java_field_button = Button(self.init_window_name, text="md 转java field", bg="lightblue",
                                                    width=20,
                                                    command=self.md_table_to_java_field)  # 调用内部方法  ()为直接调用
        self.md_table_to_java_field_button.grid(row=3, column=11)

        self.style = StringVar()
        self.style.set('req')
        self.req = Radiobutton(self.init_window_name, text='请求样式', variable=self.style, value='req')
        self.req.grid(row=4, column=11)
        self.res = Radiobutton(self.init_window_name, text='响应样式', variable=self.style, value='res')
        self.res.grid(row=4, column=12)


    def DB_column_to_md(self):
        src = self.init_data_Text.get(1.0, END).strip()
        if src:
            style = self.style.get()
            template = sql2md_req_des
            matcher = sql2md_req_match
            md_table_head = md_table_req_head
            if style == 'res':
                template = sql2md_res_des
                matcher = sql2md_res_match
                md_table_head = md_table_res_head
            src.replace('`', '')
            result = self.conversion(src, matcher, template, md_table_head=md_table_head)
            self.result_data_Text.insert(3.0, result + '\n')
            self.write_log_to_Text("INFO:trans success")
        else:
            self.write_log_to_Text("ERROR:input is none")

    def md_table_to_java_field(self):
        src = self.init_data_Text.get(1.0, END).strip()
        if src:
            style = self.style.get()
            template = md2javabean_req_des
            matcher = md2javabean_req_match
            if style == 'res':
                template = md2javabean_res_des
                matcher = md2javabean_res_match
            result = self.conversion(src, matcher, template, False)
            self.result_data_Text.insert(1.0, result + '\n')
            self.write_log_to_Text("INFO:trans success")
        else:
            self.write_log_to_Text("ERROR:input is none")

    def conversion(self, src, matcher, template, to_md=True, md_table_head=None):
        try:
            result = ''
            line_context = src.split("\n")
            self.result_data_Text.delete(1.0, END)
            if to_md:
                self.result_data_Text.insert(1.0, md_table_head)
            for i, context in enumerate(line_context):
                sources_match = matcher.fullmatch(context.strip())
                if sources_match:
                    match_dic = sources_match.groupdict()
                    if to_md:
                        self.mapping_java_type(match_dic)
                    des = template.format_map(match_dic)
                    # 输出到界面
                    result = result+des+"\n"
            return result
        except:
            self.result_data_Text.delete(1.0, END)
            self.write_log_to_Text.insert(1.0, "trans fail")

    def mapping_java_type(self, match_dic):
        type = match_dic.get("type")
        java_type = jdbctype_javatype_map.get(type.upper())
        if java_type is None:
            type_matcher = re.findall("[a-zA-Z]+", type.strip().upper())
            if type_matcher:
                java_type = jdbctype_javatype_map.get(type_matcher[0])
        match_dic["type"] = java_type
        column = match_dic.get("column")
        column = re.sub("_(?P<value>\w)", self.to_head_up, column)
        match_dic["column"] = column

    def str_trans_to_md5(self):
        """
        String to MD5
        :return:
        """
        src = self.init_data_Text.get(1.0, END).strip().replace("\n", "").encode()
        # print("src =",src)
        if src:
            try:
                myMd5 = hashlib.md5()
                myMd5.update(src)
                myMd5_Digest = myMd5.hexdigest()
                # print(myMd5_Digest)
                # 输出到界面
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, myMd5_Digest)
                self.write_log_to_Text("INFO:str_trans_to_md5 success")
            except:
                self.result_data_Text.delete(1.0, END)
                self.result_data_Text.insert(1.0, "字符串转MD5失败")
        else:
            self.write_log_to_Text("ERROR:str_trans_to_md5 failed")

    @staticmethod
    def to_head_up(matched):
        return matched.group('value').upper()

    # 获取当前时间
    def get_current_time(self):
        current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        return current_time

    # 日志动态打印
    def write_log_to_Text(self, logmsg):
        global LOG_LINE_NUM
        current_time = self.get_current_time()
        logmsg_in = str(current_time) + " " + str(logmsg) + "\n"  # 换行
        if LOG_LINE_NUM <= 7:
            self.log_data_Text.insert(END, logmsg_in)
            LOG_LINE_NUM = LOG_LINE_NUM + 1
        else:
            self.log_data_Text.delete(1.0, 2.0)
            self.log_data_Text.insert(END, logmsg_in)


def gui_start():
    init_window = Tk()  # 实例化出一个父窗口
    ZMJ_PORTAL = MY_GUI(init_window)
    # 设置根窗口默认属性
    ZMJ_PORTAL.set_init_window()

    init_window.mainloop()  # 父窗口进入事件循环,可以理解为保持窗口运行,否则界面不展示


gui_start()


##pyinstaller -n Markdownkit预览版-1.1 -w -F tk_test1.py
 
 

Loading Comments...