Search in sources :

Example 6 with PreparedSQL

use of com.github.drinkjava2.jdbpro.inline.PreparedSQL in project jSqlBox by drinkjava2.

the class BasicSqlTemplate method doRender.

/**
 * Render a template with
 *
 * @param template
 *            A SQL Template String
 * @param paramMap
 *            A Map stored SQL parameters
 * @param startDelimiter
 *            Start Delimiter of SQL Template
 * @param endDelimiter
 *            End Delimiter of SQL Template
 * @return A PreparedSQL instance
 */
protected static PreparedSQL doRender(String template, Map<String, Object> paramMap, String startDelimiter, String endDelimiter, Set<String> directReplaceNamesSet) {
    if (template == null)
        throw new NullPointerException("Template can not be null");
    StringBuilder sql = new StringBuilder();
    StringBuilder keyNameSB = new StringBuilder();
    List<Object> paramList = new ArrayList<Object>();
    char[] chars = ("   " + template + "   ").toCharArray();
    int lg = startDelimiter.length();
    char start1 = startDelimiter.charAt(0);
    char start2 = '\u0000';
    if (lg == 2)
        start2 = startDelimiter.charAt(1);
    char e = endDelimiter.charAt(0);
    int drlg = DIRECT_REPLACE_START_DELIMITER.length();
    char drst1 = DIRECT_REPLACE_START_DELIMITER.charAt(0);
    char drst2 = '\u0000';
    if (drlg == 2)
        drst2 = DIRECT_REPLACE_START_DELIMITER.charAt(1);
    char eDirect = DIRECT_REPLACE_END_DELIMITER.charAt(0);
    // - - # { - - - } - - - $ { - - - } - -
    // 0 0 1 1 2 2 2 3 0 0 0 1 1 2 2 2 3 0 0
    // - - - - - - - - - - - D D D D D - - -
    // 0:normal 1:start-delimiter 2:inside 3: end-delimiter
    int status = 0;
    // direct replace tag
    boolean directRep = false;
    for (int i = 3; i < chars.length - 2; i++) {
        char c = chars[i];
        char c1 = chars[i + 1];
        char cm1 = chars[i - 1];
        char cm2 = chars[i - 2];
        if (status == 0 && ((lg == 1 && c == start1) || (lg == 2 && c == start1 && c1 == start2))) {
            status = 1;
            keyNameSB.setLength(0);
            directRep = false;
        } else if (status == 0 && ((drlg == 1 && c == drst1) || (drlg == 2 && c == drst1 && c1 == drst2))) {
            status = 1;
            keyNameSB.setLength(0);
            directRep = true;
        } else if (status == 1 && ((lg == 1 && cm1 == start1) || (lg == 2 && (cm2 == start1 && cm1 == start2)))) {
            status = 2;
        } else if (status == 1 && ((drlg == 1 && cm1 == drst1) || (drlg == 2 && (cm2 == drst1 && cm1 == drst2)))) {
            status = 2;
        } else if (status == 2 && (((c == e) && !directRep) || ((c == eDirect) && directRep))) {
            status = 3;
            if (keyNameSB.length() == 0)
                throwEX("Empty parameter name '" + startDelimiter + endDelimiter + "' found in template: " + template);
            String key = keyNameSB.toString();
            if (key.indexOf('.') >= 0) {
                // JavaBean
                String beanName = substringBefore(key, ".");
                String propertyName = substringAfter(key, ".");
                if (isEmpty(beanName) || isEmpty(propertyName))
                    throwEX("illegal parameter name '" + key + "' found in template: " + template);
                boolean directReplaceType = isDirectReplaceTypeParameter(template, paramMap, directReplaceNamesSet, directRep, beanName);
                boolean hasValue = paramMap.containsKey(beanName);
                if (!hasValue)
                    throwEX("Not found bean '" + beanName + "' when render template: " + template);
                Object bean = paramMap.get(beanName);
                PropertyDescriptor pd = null;
                try {
                    pd = new PropertyDescriptor(propertyName, bean.getClass());
                } catch (IntrospectionException e1) {
                    throwEX("IntrospectionException happen when get bean property '" + key + "' in template: " + template, e1);
                }
                Method method = pd.getReadMethod();
                Object beanProperty = null;
                try {
                    beanProperty = method.invoke(bean);
                } catch (Exception e1) {
                    throwEX("Exception happen when read bean property '" + key + "' in template: " + template, e1);
                }
                if (directReplaceType) {
                    sql.append(beanProperty);
                } else {
                    sql.append("?");
                    paramList.add(beanProperty);
                }
            } else {
                boolean directReplaceType = isDirectReplaceTypeParameter(template, paramMap, directReplaceNamesSet, directRep, key);
                boolean hasValue = paramMap.containsKey(key);
                if (!hasValue)
                    throwEX("No parameter found for '" + key + "' in template: " + template + ". Current params=" + paramMap);
                if (directReplaceType) {
                    sql.append(paramMap.get(key));
                } else {
                    sql.append("?");
                    paramList.add(paramMap.get(key));
                }
            }
            keyNameSB.setLength(0);
        } else if (status == 3 && cm1 == e) {
            status = 0;
        }
        if (status == 0)
            sql.append(c);
        else if (status == 2)
            keyNameSB.append(c);
    }
    if (status != 0)
        throwEX("Missing end delimiter '" + endDelimiter + "' in template: " + template);
    PreparedSQL sp = new PreparedSQL();
    sql.setLength(sql.length() - 1);
    sp.setSql(sql.toString());
    sp.setParams(paramList.toArray(new Object[paramList.size()]));
    return sp;
}
Also used : PreparedSQL(com.github.drinkjava2.jdbpro.inline.PreparedSQL) PropertyDescriptor(java.beans.PropertyDescriptor) ArrayList(java.util.ArrayList) IntrospectionException(java.beans.IntrospectionException) Method(java.lang.reflect.Method) IntrospectionException(java.beans.IntrospectionException)

Aggregations

PreparedSQL (com.github.drinkjava2.jdbpro.inline.PreparedSQL)6 Method (java.lang.reflect.Method)5 SqlBoxException (com.github.drinkjava2.jsqlbox.SqlBoxException)1 Sql (com.github.drinkjava2.jsqlbox.annotation.Sql)1 EntityListHandler (com.github.drinkjava2.jsqlbox.handler.EntityListHandler)1 IntrospectionException (java.beans.IntrospectionException)1 PropertyDescriptor (java.beans.PropertyDescriptor)1 Annotation (java.lang.annotation.Annotation)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 ResultSetHandler (org.apache.commons.dbutils.ResultSetHandler)1 SQLResult (org.beetl.sql.core.SQLResult)1 SQLScript (org.beetl.sql.core.SQLScript)1 SQLParameter (org.beetl.sql.core.engine.SQLParameter)1