// Path: QuickProject-Core/src/main/java/chanedi/dao/complexQuery/Sort.java
// @Data
// public class Sort implements Serializable {
// 
//     private static final long serialVersionUID = 7026434198845897214L;
//     private String property;
//     private String tableAlias;
//     private String column;
//     private Direction direction;
// 
//     public Sort() {
//         super();
//         direction = Direction.ASC;
//     }
// 
//     public Sort(String property) {
//         this();
//         this.property = property;
//     }
// 
//     public Sort(String property, Direction direction) {
//         this();
//         this.property = property;
//         this.direction = direction;
//     }
// 
//     public static enum Direction {
//         ASC, DESC;
//     }
// 
// }
// 
// Path: QuickProject-Core/src/main/java/chanedi/dao/dialect/Dialect.java
// public abstract class Dialect {
// 
//     public abstract String addLimitString(String sql, int skipResults, int maxResults);
// 
//     public abstract String addSortString(String sql, List<Sort> sortList);
// 
// }
// 
// Path: QuickProject-Core/src/main/java/chanedi/dao/impl/mybatis/DialectParser.java
// public class DialectParser {
// 
//     public static Dialect parse(Configuration configuration) {
//         DBDialectType databaseType = null;
//         try {
//             databaseType = DBDialectType.valueOf(configuration.getVariables().getProperty("dialect").toUpperCase());
//         } catch (Exception e) {
//             // ignore
//         }
//         if (databaseType == null) {
//             throw new RuntimeException("the value of the dialect property in configuration.xml is not defined : " + configuration.getVariables().getProperty("dialect"));
//         }
//         Dialect dialect = null;
//         switch (databaseType) {
//             case MYSQL:
//                 dialect = new MySql5Dialect();
//                 break;
//             case ORACLE:
//                 dialect = new OracleDialect();
//                 break;
//             case H2:
//                 dialect = new H2Dialect();
//                 break;
//         }
//         return dialect;
//     }
// 
// }


import chanedi.dao.complexQuery.Sort;
import chanedi.dao.dialect.Dialect;
import chanedi.dao.impl.mybatis.DialectParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.util.List;
import java.util.Properties;
package chanedi.dao.impl.mybatis.interceptor;



/**
 * 将sortList加入sql。
 *
 * @author Chanedi
 */
@Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}) })
@Slf4j
public class SortListInterceptor implements Interceptor {
	
    private static ThreadLocal<List<Sort>> sortList = new ThreadLocal<List<Sort>>();

    public static List<Sort> getSortList() {
        List<Sort> sortList = SortListInterceptor.sortList.get();
        SortListInterceptor.sortList.remove();
        return sortList;
    }

    public static void setSortList(List<Sort> sortList) {
        SortListInterceptor.sortList.set(sortList);
    }

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
        List<Sort> sortList = getSortList();
        if (sortList == null || sortList.size() == 0) {
            return invocation.proceed();
        }

        Executor executor = (Executor) invocation.getTarget();
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        Object parameter = args[1];
        RowBounds rowBounds = (RowBounds) args[2];
        ResultHandler resultHandler = (ResultHandler) args[3];

        // 计算修改BoundSql
        BoundSql boundSql = ms.getBoundSql(parameter);
        MetaObject boundSqlHandler = MetaObject.forObject(boundSql, new DefaultObjectFactory(), new DefaultObjectWrapperFactory());
// Path: QuickProject-Core/src/main/java/chanedi/dao/complexQuery/Sort.java
// @Data
// public class Sort implements Serializable {
// 
//     private static final long serialVersionUID = 7026434198845897214L;
//     private String property;
//     private String tableAlias;
//     private String column;
//     private Direction direction;
// 
//     public Sort() {
//         super();
//         direction = Direction.ASC;
//     }
// 
//     public Sort(String property) {
//         this();
//         this.property = property;
//     }
// 
//     public Sort(String property, Direction direction) {
//         this();
//         this.property = property;
//         this.direction = direction;
//     }
// 
//     public static enum Direction {
//         ASC, DESC;
//     }
// 
// }
// 
// Path: QuickProject-Core/src/main/java/chanedi/dao/dialect/Dialect.java
// public abstract class Dialect {
// 
//     public abstract String addLimitString(String sql, int skipResults, int maxResults);
// 
//     public abstract String addSortString(String sql, List<Sort> sortList);
// 
// }
// 
// Path: QuickProject-Core/src/main/java/chanedi/dao/impl/mybatis/DialectParser.java
// public class DialectParser {
// 
//     public static Dialect parse(Configuration configuration) {
//         DBDialectType databaseType = null;
//         try {
//             databaseType = DBDialectType.valueOf(configuration.getVariables().getProperty("dialect").toUpperCase());
//         } catch (Exception e) {
//             // ignore
//         }
//         if (databaseType == null) {
//             throw new RuntimeException("the value of the dialect property in configuration.xml is not defined : " + configuration.getVariables().getProperty("dialect"));
//         }
//         Dialect dialect = null;
//         switch (databaseType) {
//             case MYSQL:
//                 dialect = new MySql5Dialect();
//                 break;
//             case ORACLE:
//                 dialect = new OracleDialect();
//                 break;
//             case H2:
//                 dialect = new H2Dialect();
//                 break;
//         }
//         return dialect;
//     }
// 
// }


// Path: QuickProject-Core/src/main/java/chanedi/dao/impl/mybatis/interceptor/SortListInterceptor.java
import chanedi.dao.complexQuery.Sort;
import chanedi.dao.dialect.Dialect;
import chanedi.dao.impl.mybatis.DialectParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.util.List;
import java.util.Properties;

package chanedi.dao.impl.mybatis.interceptor;



/**
 * 将sortList加入sql。
 *
 * @author Chanedi
 */
@Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}) })
@Slf4j
public class SortListInterceptor implements Interceptor {
	
    private static ThreadLocal<List<Sort>> sortList = new ThreadLocal<List<Sort>>();

    public static List<Sort> getSortList() {
        List<Sort> sortList = SortListInterceptor.sortList.get();
        SortListInterceptor.sortList.remove();
        return sortList;
    }

    public static void setSortList(List<Sort> sortList) {
        SortListInterceptor.sortList.set(sortList);
    }

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
        List<Sort> sortList = getSortList();
        if (sortList == null || sortList.size() == 0) {
            return invocation.proceed();
        }

        Executor executor = (Executor) invocation.getTarget();
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        Object parameter = args[1];
        RowBounds rowBounds = (RowBounds) args[2];
        ResultHandler resultHandler = (ResultHandler) args[3];

        // 计算修改BoundSql
        BoundSql boundSql = ms.getBoundSql(parameter);
        MetaObject boundSqlHandler = MetaObject.forObject(boundSql, new DefaultObjectFactory(), new DefaultObjectWrapperFactory());
        Dialect dialect = DialectParser.parse(ms.getConfiguration());