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