All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onetwo.common.db.SqlUtils Maven / Gradle / Ivy

The newest version!
package org.onetwo.common.db;

import java.util.regex.Pattern;

import org.apache.commons.lang3.ArrayUtils;
import org.onetwo.common.utils.StringUtils;
import org.onetwo.dbm.exception.DbmException;
import org.springframework.util.ClassUtils;

final public class SqlUtils {
	private static final String DRUID_PARSER_CLASS = "com.alibaba.druid.sql.parser.SQLParser";
	
//	public static final String[] SQL_KEY_WORKDS = new String[]{" ", ";", ",", "(", ")", "'", "\"", "\"\"", "/", "+", "-", "#"};
	
	// 定义允许的字符模式(字母、数字、下划线)
	private static final Pattern ALLOWED_FIELD_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_\\.]*$");
	
    private final static char[] IMMUNE_SQL = { ' ' };
    
    private final static String[] HEX = new String[256];

    /**
     * Default constructor
     */
    static {
        for ( char c = 0; c < 0xFF; c++ ) {
            if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A ) {
            	HEX[c] = null;
            } else {
            	HEX[c] = Integer.toHexString(c).intern();
            }
        }
    }


    private static String getHexForNonAlphanumeric(char c) {
        if(c<0xFF)
            return HEX[c];
        return Integer.toHexString(c);
    }

    private static String encode(char[] immune, String input) {
        StringBuilder sb = new StringBuilder();
        for(int offset  = 0; offset < input.length(); ) {
            final int point = input.codePointAt(offset);
            if (Character.isBmpCodePoint(point)) {
                //We can then safely cast this to char and maintain legacy behavior.
                sb.append(encodeCharacter(immune, new Character((char) point)));
            } else {
                sb.append(encodeCharacter(immune, point));
            }
            offset += Character.charCount(point);
        }
        return sb.toString();
    }
    
    private static String encodeCharacter( char[] immune, int codePoint ) {
        String rval = "";
        if(Character.isValidCodePoint(codePoint)){
            rval = new StringBuilder().appendCodePoint(codePoint).toString();
        }
        return rval;
    }
    
    private static String encodeCharacter( char[] immune, Character c ) {
        char ch = c.charValue();

        // check for immune characters
        if ( ArrayUtils.contains(immune, ch) ) {
            return ""+ch;
        }

        // check for alphanumeric characters
        String hex = getHexForNonAlphanumeric(ch);
        if ( hex == null ) {
            return ""+ch;
        }


        return encodeCharacterMySQL(c);
    }
    

    private  static String encodeCharacterMySQL( Character c ) {
        char ch = c.charValue();
        if ( ch == 0x00 ) return "\\0";
        if ( ch == 0x08 ) return "\\b";
        if ( ch == 0x09 ) return "\\t";
        if ( ch == 0x0a ) return "\\n";
        if ( ch == 0x0d ) return "\\r";
        if ( ch == 0x1a ) return "\\Z";
        if ( ch == 0x22 ) return "\\\"";
        if ( ch == 0x25 ) return "\\%";
        if ( ch == 0x27 ) return "\\'";
        if ( ch == 0x5c ) return "\\\\";
        if ( ch == 0x5f ) return "\\_";
        return "\\" + c;
    }
    
    
    static public String encodeForSQL(String input) {
        if( input == null ) {
            return null;
        }
        return encode(IMMUNE_SQL, input);
    }

	public static void checkSQLSafeField(String fieldName) {
		if(!isSQLSafeField(fieldName)) {
			throw new DbmException("sql field is unsafe : " + fieldName);
		}
    }
	
	public static boolean isSQLSafeField(String fieldName) {
        return ALLOWED_FIELD_NAME_PATTERN.matcher(fieldName).matches();
    }

	public static String checkSqlValue(String sqlValue){
		if(StringUtils.isBlank(sqlValue)){
			return sqlValue;
		}
		
		sqlValue = encodeForSQL(sqlValue);
//		for(String str : SQL_KEY_WORKDS){
//			if(sqlValue.indexOf(str)!=-1) {
//				throw new DbmException("sql value is unsafe : " + sqlValue);
//			}
//		}
		return sqlValue;
	}
	
	public static boolean isDruidPresent(){
		return ClassUtils.isPresent(DRUID_PARSER_CLASS, ClassUtils.getDefaultClassLoader());
	}
	
	
	private SqlUtils(){
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy