From 24681c81c09022f584a57006f2534b5f74723414 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 30 六月 2026 09:27:31 +0800
Subject: [PATCH] 初始化项目

---
 sql/tools/convertor.py |  123 ++++++++++++++++++++++++++++++++++------
 1 files changed, 104 insertions(+), 19 deletions(-)

diff --git a/sql/tools/convertor.py b/sql/tools/convertor.py
index 3a8b9f3..f4509fd 100644
--- a/sql/tools/convertor.py
+++ b/sql/tools/convertor.py
@@ -10,6 +10,7 @@
 uv run --with simple-ddl-parser convertor.py sqlserver ../mysql/ruoyi-vue-pro.sql > ../sqlserver/ruoyi-vue-pro.sql
 uv run --with simple-ddl-parser convertor.py kingbase ../mysql/ruoyi-vue-pro.sql > ../kingbase/ruoyi-vue-pro.sql
 uv run --with simple-ddl-parser convertor.py opengauss ../mysql/ruoyi-vue-pro.sql > ../opengauss/ruoyi-vue-pro.sql
+uv run --with simple-ddl-parser convertor.py highgo ../mysql/ruoyi-vue-pro.sql > ../highgo/ruoyi-vue-pro.sql
 uv run --with simple-ddl-parser convertor.py oracle ../mysql/ruoyi-vue-pro.sql > ../oracle/ruoyi-vue-pro.sql
 uv run --with simple-ddl-parser convertor.py dm8 ../mysql/ruoyi-vue-pro.sql > ../dm/ruoyi-vue-pro-dm8.sql
 """
@@ -77,6 +78,9 @@
 
 
 class Convertor(ABC):
+    # 涓嶅悓鏁版嵁搴撶殑鍏抽敭瀛椾笉瀹屽叏涓�鑷达紱瀛愮被鎸夐渶澹版槑闇�瑕佽浆涔夌殑鍒楀悕銆�
+    reserved_column_names = set()
+
     def __init__(self, src: str, db_type) -> None:
         self.src = src
         self.db_type = db_type
@@ -179,6 +183,31 @@
         """
         return ""
 
+    def escape_column_name(self, name: str) -> str:
+        """杞箟鐩爣搴撲繚鐣欏瓧鍒楀悕锛屼緥濡� Oracle / Kingbase 鐨� level銆�"""
+
+        column_name = name.lower()
+        if column_name in self.reserved_column_names:
+            return f'"{column_name}"'
+        return column_name
+
+    def escape_insert_columns(self, insert_script: str) -> str:
+        """INSERT 鏄惧紡鍒楁竻鍗曢渶瑕佸拰 CREATE / COMMENT 浣跨敤鍚屼竴濂楀垪鍚嶈浆涔夈��"""
+
+        match = re.match(
+            r"(INSERT INTO\s+\S+\s*\()([^)]+)(\)\s+VALUES\s+[\s\S]*)",
+            insert_script,
+            flags=re.IGNORECASE,
+        )
+        if not match:
+            return insert_script
+
+        columns = [
+            self.escape_column_name(column.strip())
+            for column in match.group(2).split(",")
+        ]
+        return f"{match.group(1)}{', '.join(columns)}{match.group(3)}"
+
     @staticmethod
     def inserts(table_name: str, script_content: str) -> Generator:
         PREFIX = f"INSERT INTO `{table_name}`"
@@ -204,17 +233,54 @@
             Generator[str]: create index 璇彞
         """
 
-        def generate_columns(columns):
-            keys = [
-                f"{col['name'].lower()}{' ' + col['order'].lower() if col['order'] != 'ASC' else ''}"
-                for col in columns[0]
-            ]
-            return ", ".join(keys)
-
-        for no, index in enumerate(ddl["index"], 1):
-            columns = generate_columns(index["columns"])
+        for no, index in enumerate(ddl.get("index", []), 1):
+            columns = ", ".join(Convertor.index_columns(index.get("columns", [])))
+            if not columns:
+                continue
             table_name = ddl["table_name"].lower()
             yield f"CREATE INDEX idx_{table_name}_{no:02d} ON {table_name} ({columns})"
+
+    @staticmethod
+    def index_columns(columns) -> list:
+        """鍏煎 simple-ddl-parser 涓嶅悓鐗堟湰鐨勭储寮曞垪缁撴瀯銆�"""
+
+        keys = []
+
+        def append(name, order="ASC"):
+            if not name:
+                return
+            column_name = str(name).strip("`").lower()
+            column_order = str(order or "ASC").upper()
+            if column_order == "DESC":
+                keys.append(f"{column_name} desc")
+            else:
+                keys.append(column_name)
+
+        def visit(value):
+            # 鏅�氱储寮曞父瑙佺粨鏋勶細[[{'name': 'user_id', 'order': 'ASC'}]]
+            if isinstance(value, (list, tuple)):
+                for item in value:
+                    visit(item)
+                return
+            if isinstance(value, dict):
+                name = value.get("name")
+                if isinstance(name, (dict, list, tuple)):
+                    visit(name)
+                    return
+                append(name, value.get("order", "ASC"))
+                return
+            # 鍞竴绱㈠紩鍦ㄩ儴鍒嗙増鏈腑浼氳瑙f瀽鎴� ['mobile', 'ASC', 'tenant_id', 'ASC']銆�
+            if isinstance(value, str):
+                token = value.strip("`")
+                order = token.upper()
+                if order in ("ASC", "DESC"):
+                    if order == "DESC" and keys and not keys[-1].endswith(" desc"):
+                        keys[-1] = f"{keys[-1]} desc"
+                    return
+                append(token)
+
+        visit(columns)
+        return keys
 
     @staticmethod
     def unique_index(ddl: Dict) -> Generator:
@@ -223,7 +289,9 @@
             for uk in uk_list:
                 table_name = ddl["table_name"]
                 uk_name = uk["constraint_name"]
-                uk_columns = uk["columns"]
+                uk_columns = Convertor.index_columns(uk["columns"])
+                if not uk_columns:
+                    continue
                 yield table_name, uk_name, uk_columns
 
     @staticmethod
@@ -381,7 +449,7 @@
                 )
             nullable = "NULL" if col["nullable"] else "NOT NULL"
             default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
-            return f"{name} {full_type} {nullable} {default}"
+            return f"{self.escape_column_name(name)} {full_type} {nullable} {default}"
 
         table_name = ddl["table_name"].lower()
         columns = [f"{_generate_column(col).strip()}" for col in ddl["columns"]]
@@ -406,7 +474,7 @@
         for column in table_ddl["columns"]:
             table_comment = column["comment"]
             script += (
-                f"COMMENT ON COLUMN {table_ddl['table_name']}.{column['name']} IS '{table_comment}';"
+                f"COMMENT ON COLUMN {table_ddl['table_name']}.{self.escape_column_name(column['name'])} IS '{table_comment}';"
                 + "\n"
             )
 
@@ -435,6 +503,7 @@
         """鐢熸垚 insert 璇彞锛屼互鍙婃牴鎹渶鍚庣殑 insert id+1 鐢熸垚 Sequence"""
 
         inserts = list(Convertor.inserts(table_name, self.content))
+        inserts = [self.escape_insert_columns(s) for s in inserts]
         # 杞崲 MySQL 瀛楃涓茶浆涔変负 PostgreSQL 鏍煎紡锛歕\ -> \锛孿' -> ''
         inserts = [re.sub(r"\\\\|\\'", lambda m: "\\" if m.group() == "\\\\" else "''", s) for s in inserts]
         ## 鐢熸垚 insert 鑴氭湰
@@ -482,6 +551,8 @@
 
 
 class OracleConvertor(Convertor):
+    reserved_column_names = {"level", "size"}
+
     def __init__(self, src):
         super().__init__(src, "Oracle")
 
@@ -526,10 +597,8 @@
             # Oracle鐨� INSERT '' 涓嶈兘閫氳繃NOT NULL鏍¢獙锛屽洜姝ゅ鏂囧瓧绫诲瀷瀛楁瑕嗗啓涓� NULL
             nullable = "NULL" if type in ("varchar", "text", "longtext") else nullable
             default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
-            # Oracle 涓� size 涓嶈兘浣滀负瀛楁鍚�
-            field_name = '"size"' if name == "size" else name
             # Oracle DEFAULT 瀹氫箟鍦� NULLABLE 涔嬪墠
-            return f"{field_name} {full_type} {default} {nullable}"
+            return f"{self.escape_column_name(name)} {full_type} {default} {nullable}"
 
         table_name = ddl["table_name"].lower()
         columns = [f"{generate_column(col).strip()}" for col in ddl["columns"]]
@@ -554,7 +623,7 @@
         for column in table_ddl["columns"]:
             table_comment = column["comment"]
             script += (
-                f"COMMENT ON COLUMN {table_ddl['table_name']}.{column['name']} IS '{table_comment}';"
+                f"COMMENT ON COLUMN {table_ddl['table_name']}.{self.escape_column_name(column['name'])} IS '{table_comment}';"
                 + "\n"
             )
 
@@ -586,6 +655,7 @@
         """鎷疯礉 INSERT 璇彞"""
         inserts = []
         for insert_script in Convertor.inserts(table_name, self.content):
+            insert_script = self.escape_insert_columns(insert_script)
             # 瀵规棩鏈熸暟鎹坊鍔� TO_DATE 杞崲
             insert_script = re.sub(
                 r"('\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}')",
@@ -801,7 +871,9 @@
         type = type.lower()
 
         if type == "varchar":
-            return f"varchar({size})"
+            # MySQL varchar(n) is character-oriented. DM8 may treat varchar(n)
+            # as bytes, so use explicit CHAR semantics for generated scripts.
+            return f"varchar({size} char)"
         if type in ("int", "int unsigned"):
             return "int"
         if type in ("bigint", "bigint unsigned"):
@@ -907,6 +979,8 @@
 
 
 class KingbaseConvertor(PostgreSQLConvertor):
+    reserved_column_names = {"level"}
+
     def __init__(self, src):
         super().__init__(src)
         self.db_type = "Kingbase"
@@ -925,7 +999,7 @@
             if full_type == "text":
                 nullable = "NULL"
             default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
-            return f"{name} {full_type} {nullable} {default}"
+            return f"{self.escape_column_name(name)} {full_type} {nullable} {default}"
 
         table_name = ddl["table_name"].lower()
         columns = [f"{_generate_column(col).strip()}" for col in ddl["columns"]]
@@ -945,9 +1019,17 @@
 
 
 class OpengaussConvertor(KingbaseConvertor):
+    reserved_column_names = set()
+
     def __init__(self, src):
         super().__init__(src)
         self.db_type = "OpenGauss"
+
+
+class HighGoConvertor(PostgreSQLConvertor):
+    def __init__(self, src):
+        super().__init__(src)
+        self.db_type = "HighGo"
 
 
 def main():
@@ -956,12 +1038,13 @@
         "type",
         type=str,
         help="鐩爣鏁版嵁搴撶被鍨�",
-        choices=["postgres", "oracle", "sqlserver", "dm8", "kingbase", "opengauss"],
+        choices=["postgres", "oracle", "sqlserver", "dm8", "kingbase", "opengauss", "highgo"],
     )
     parser.add_argument(
         "path",
         type=str,
         help="婧愭暟鎹簱鑴氭湰璺緞",
+        nargs="?",
         default="../mysql/ruoyi-vue-pro.sql"
     )
     args = parser.parse_args()
@@ -980,6 +1063,8 @@
         convertor = KingbaseConvertor(sql_file)
     elif args.type == "opengauss":
         convertor = OpengaussConvertor(sql_file)
+    elif args.type == "highgo":
+        convertor = HighGoConvertor(sql_file)
     else:
         raise NotImplementedError(f"涓嶆敮鎸佺洰鏍囨暟鎹簱绫诲瀷: {args.type}")
 

--
Gitblit v1.9.3