package com.taobao.tddl.matrix.jdbc.utils;
import java.sql.SQLException;
import java.util.regex.Pattern;
import com.taobao.tddl.common.model.SqlType;
import com.taobao.tddl.common.utils.TStringUtil;
/**
* 解析SQL语句,得到这条语句的类型
*
* @author yangzhu
*/
public class PreParser {
// private static final ParserCache globalCache = ParserCache.instance();
/**
* 用于判断是否是一个select ... for update的sql
*/
private static final Pattern SELECT_FOR_UPDATE_PATTERN = Pattern.compile("^select\\s+.*\\s+for\\s+update.*$",
Pattern.CASE_INSENSITIVE);
/**
* 获得SQL语句种类
*
* @param sql SQL语句
* @throws SQLException 当SQL语句不是SELECT、INSERT、UPDATE、DELETE语句时,抛出异常。
*/
public static SqlType getSqlType(String sql) throws SQLException {
// #bug 2011-11-24,modify by junyu,先不走缓存,否则sql变化巨大,缓存换入换出太多,gc太明显
// SqlType sqlType = globalCache.getSqlType(sql);
// if (sqlType == null) {
SqlType sqlType = null;
// #bug 2011-12-8,modify by junyu ,this code use huge cpu resource,and
// most
// sql have no comment,so first simple look for there whether have the
// comment
String noCommentsSql = sql;
if (sql.contains("/*")) {
noCommentsSql = TStringUtil.stripComments(sql, "'\"", "'\"", true, false, true, true).trim();
}
if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "select")) {
// #bug 2011-12-9,this select-for-update regex has low
// performance,so
// first judge this sql whether have ' for ' string.
if (noCommentsSql.toLowerCase().contains(" for ")
&& SELECT_FOR_UPDATE_PATTERN.matcher(noCommentsSql).matches()) {
sqlType = SqlType.SELECT_FOR_UPDATE;
} else {
sqlType = SqlType.SELECT;
}
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "show")) {
// ??show 不支持?
// sqlType = SqlType.SHOW;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "insert")) {
sqlType = SqlType.INSERT;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "update")) {
sqlType = SqlType.UPDATE;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "delete")) {
sqlType = SqlType.DELETE;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "replace")) {
sqlType = SqlType.REPLACE;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "truncate")) {
sqlType = SqlType.TRUNCATE;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "create")) {
sqlType = SqlType.CREATE;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "drop")) {
sqlType = SqlType.DROP;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "load")) {
sqlType = SqlType.LOAD;
} else if (TStringUtil.startsWithIgnoreCaseAndWs(noCommentsSql, "merge")) {
sqlType = SqlType.MERGE;
} else {
throw new SQLException("only select, insert, update, delete,replace,truncate,create,drop,load,merge sql is supported");
}
// sqlType = globalCache.setSqlTypeIfAbsent(sql, sqlType);
// }
return sqlType;
}
}