package com.ruoyi.framework.aspectj;


import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.tenantdatassource.TenantDataSource;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;

import java.sql.Connection;
import java.util.Properties;

/**
 * AOP 拦截SQL处理
 *
 * @author hzh
 */
@Intercepts({
        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class SqlInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable, TenantDataSource {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        String sql = statementHandler.getBoundSql().getSql();
        // 修改SQL语句
        String modifiedSql = BeforeSQL(sql);
        if (modifiedSql.equals("error")) {
            // 终止程序
            return AjaxResult.error("当前用户没有数据源信息！");
        } else {
            // 将修改后的SQL语句设置回StatementHandler
            ReflectUtils.setFieldValue(statementHandler.getBoundSql(), "sql", modifiedSql);
            invocation.proceed();
            ReflectUtils.setFieldValue(statementHandler.getBoundSql(), "sql", sql);
            return invocation.proceed();
        }
    }

    private String BeforeSQL(String sql) {
        try {
            SecurityUtils.getDatabaseType();
        } catch (Exception e) {
            return "error";
        }
        if (SecurityUtils.getDatabaseType().equals("sqlserver"))
            return "USE `" + SecurityUtils.getDatabaseName() + "`; ";
        if (SecurityUtils.getDatabaseType().equals("dm"))
            return "set schema " + SecurityUtils.getDatabaseName() + "; ";
        if (SecurityUtils.getDatabaseType().equals("mysql"))
            return "USE `" + SecurityUtils.getDatabaseName() + "`; ";
        return "error";
    }


    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}