#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量修复SELECT *问题
将SELECT *替换为明确的字段列表
"""

import os
import re
from pathlib import Path
from xml.etree import ElementTree as ET

def extract_fields_from_resultMap(xml_file):
    """从XML文件中提取resultMap定义的字段"""
    try:
        tree = ET.parse(xml_file)
        root = tree.getroot()
        
        fields = []
        # 查找resultMap下的所有result和id元素
        for result_map in root.findall('.//resultMap'):
            for result in result_map.findall('result'):
                column = result.get('column')
                if column:
                    fields.append(column)
            for id_elem in result_map.findall('id'):
                column = id_elem.get('column')
                if column:
                    fields.insert(0, column)
        
        return fields
    except Exception as e:
        print(f"  解析XML失败: {e}")
        return []

def fix_select_star_in_file(file_path):
    """修复单个XML文件中的SELECT *"""
    with open(file_path, 'r', encoding='utf-8') as f:
        content = f.read()
    
    original_content = content
    
    # 检查是否有SELECT *
    if 'SELECT *' not in content.upper():
        return False
    
    # 提取字段列表
    fields = extract_fields_from_resultMap(file_path)
    
    if not fields:
        print(f"  [SKIP] 无法提取字段: {file_path}")
        return False
    
    field_str = ', '.join(fields)
    
    # 替换SELECT *为明确的字段列表
    # 匹配SELECT * FROM (不区分大小写)
    pattern = r'SELECT\s+\*\s+FROM'
    replacement = f'SELECT {field_str} FROM'
    
    new_content = re.sub(pattern, replacement, content, flags=re.IGNORECASE)
    
    if new_content != content:
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(new_content)
        print(f"  [OK] 已修复: {file_path}")
        return True
    
    return False

def fix_select_star_in_java(file_path):
    """修复Java文件中的@Select注解里的SELECT *"""
    with open(file_path, 'r', encoding='utf-8') as f:
        content = f.read()
    
    original_content = content
    
    # 检查是否有SELECT *
    if 'SELECT *' not in content.upper():
        return False
    
    # 对于Java文件，我们需要更谨慎地处理
    # 这里我们只是记录，因为需要知道具体的表结构
    print(f"  [MANUAL] 需要手动修复: {file_path}")
    return False

def main():
    """主函数"""
    services_dir = Path('D:/FzxBDSH/services')
    fixed_count = 0
    
    # 遍历所有XML文件
    for xml_file in services_dir.rglob('*.xml'):
        # 跳过target目录
        if 'target' in str(xml_file):
            continue
        
        try:
            if fix_select_star_in_file(str(xml_file)):
                fixed_count += 1
        except Exception as e:
            print(f"  [FAIL] 修复失败: {xml_file}, 错误: {e}")
    
    # 遍历Java文件中的@Select注解
    for java_file in services_dir.rglob('*.java'):
        if 'target' in str(java_file):
            continue
        
        try:
            if fix_select_star_in_java(str(java_file)):
                fixed_count += 1
        except Exception as e:
            print(f"  [FAIL] 修复失败: {java_file}, 错误: {e}")
    
    print(f"\n总计修复文件数: {fixed_count}")

if __name__ == '__main__':
    main()
