Package com.scooterframework.orm.sqldataexpress.util

Source Code of com.scooterframework.orm.sqldataexpress.util.SqlUtil

/*
*   This software is distributed under the terms of the FSF
*   Gnu Lesser General Public License (see lgpl.txt).
*
*   This program is distributed WITHOUT ANY WARRANTY. See the
*   GNU General Public License for more details.
*/
package com.scooterframework.orm.sqldataexpress.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import com.scooterframework.common.logging.LogUtil;
import com.scooterframework.common.util.DateUtil;
import com.scooterframework.common.util.StringUtil;
import com.scooterframework.orm.sqldataexpress.config.DatabaseConfig;
import com.scooterframework.orm.sqldataexpress.object.Parameter;
import com.scooterframework.orm.sqldataexpress.object.RowData;

/**
* SqlUtil class has methods for general SQL processing and SQL related type
* conversion.
*
* @author (Fei) John Chen
*/
public class SqlUtil {
    private static final LogUtil log = LogUtil.getLogger(SqlUtil.class.getName());

    /**
     * <p>Returns a SQL data type int for a SQL data type name.</p>
     *
     * <p>Developers can add types.
     * See {@link com.scooterframework.orm.sqldataexpress.config.DatabaseConfig}
     * class for examples.</p>
     *
     * @param sqlDataTypeName data type name
     * @return SQL data type int
     */
    public static int getSqlDataTypeFromDataTypeName(String sqlDataTypeName) {
        String tname = sqlDataTypeName.toUpperCase();
        if (tname.indexOf(' ') != -1) {
            tname = tname.substring(0, tname.indexOf(' '));
        }

        Integer sqlDataType = (Integer)DatabaseConfig.getInstance().getSQLDataNameTypesMap().get(tname);
        if (sqlDataType == null) {
            log.warn("No sql data type found in sqlDataTypesMap for sql data type name " + sqlDataTypeName);
            return Parameter.UNKNOWN_SQL_DATA_TYPE;
        }

        return sqlDataType.intValue();
    }

    /**
     * Converts from SQL data type to Java class type.
     *
     * Here is a list of presumed Java class name and its corresponding SQL data type:
     * <pre>
     *  java.sql.Array         public static final int ARRAY 2003
     *  java.lang.Long         public static final int BIGINT -5
     *  byte[]                 public static final int BINARY -2
     *  java.lang.Boolean      public static final int BIT -7
     *  java.sql.Blob          public static final int BLOB 2004
     *  java.lang.Boolean      public static final int BOOLEAN 16
     *  java.lang.String       public static final int CHAR 1
     *  java.sql.Clob          public static final int CLOB 2005
     *  java.lang.Object       public static final int DATALINK 70
     *  java.sql.Timestamp     public static final int DATE 91
     *  java.lang.BigDecimal   public static final int DECIMAL 3
     *  java.lang.Object       public static final int DISTINCT 2001
     *  java.lang.Double       public static final int DOUBLE 8
     *  java.lang.Double       public static final int FLOAT 6
     *  java.lang.Integer      public static final int INTEGER 4
     *  java.lang.Object       public static final int JAVA_OBJECT 2000
     *  java.lang.String       public static final int LONGNVARCHAR -16
     *  byte[]                 public static final int LONGVARBINARY -4
     *  java.lang.String       public static final int LONGVARCHAR -1
     *  java.lang.String       public static final int NCHAR -15
     *  java.sql.Clob          public static final int NCLOB 2011
     *  java.lang.Object       public static final int NULL 0
     *  java.lang.BigDecimal   public static final int NUMERIC 2
     *  java.lang.String       public static final int NVARCHAR -9
     *  java.lang.Object       public static final int OTHER 1111
     *  java.lang.Double       public static final int REAL 7
     *  java.sql.Ref           public static final int REF 2006
     *  java.lang.Integer      public static final int ROWID -8
     *  java.lang.Integer      public static final int SMALLINT 5
     *  java.sql.String        public static final int SQLXML 2009
     *  java.sql.Struct        public static final int STRUCT 2002
     *  java.sql.Time          public static final int TIME 92
     *  java.sql.Timestamp     public static final int TIMESTAMP 93
     *  java.lang.Integer      public static final int TINYINT -6
     *  byte[]                 public static final int VARBINARY -3
     *  java.lang.String       public static final int VARCHAR 12
     * </pre>
     *
     * The following types are simply converted to "java.lang.Object":
     * <ul>
     *   <li>public static final int DATALINK 70</li>
     *   <li>public static final int DISTINCT 2001</li>
     *   <li>public static final int JAVA_OBJECT 2000</li>
     *   <li>public static final int NULL 0</li>
     *   <li>public static final int OTHER 1111</li>
     * </ul>
     *
     * <p>Default java type is "java.lang.Object".
     *
     * <p>Developers can add types.
     * See {@link com.scooterframework.orm.sqldataexpress.config.DatabaseConfig}
     * class for examples.</p>
     *
     * @param sqlDataType SQL data type from java.sql.Types
     * @return The Java class type name.
     */
    public static String getJavaType(int sqlDataType) {
        String javaClassName = null;

        switch (sqlDataType){
            case -16: //LONGNVARCHAR
            case -15: //NCHAR
            case -9: //NVARCHAR
            case -1: //LONGVARCHAR
            case  1: //CHAR
            case 12: //VARCHAR, VARCHAR2
            case 2009: //SQLXML
                javaClassName = "java.lang.String";
                break;
            case  2: //NUMERIC/NUMBER
            case  3: //DECIMAL
                javaClassName = "java.math.BigDecimal";
                break;
            case -8: //ROWID
            case -6: //TINYINT
            case  4: //INTEGER
            case  5: //SMALLINT
                javaClassName = "java.lang.Integer";
                break;
            case  6: //FLOAT
            case  7: //REAL
            case  8: //DOUBLE
                javaClassName = "java.lang.Double";
                break;
            case -5: //BIGINT
                javaClassName = "java.lang.Long";
                break;
            case 92: //TIME
                javaClassName = "java.sql.Time";
                break;
            case 91: //DATE
            case 93: //TIMESTAMP
                javaClassName = "java.sql.Timestamp";
                break;
            case -7: //BIT
            case 16: //BOOLEAN
                javaClassName = "java.lang.Boolean";
                break;
            case 2003: //ARRAY
                javaClassName = "java.sql.Array";
                break;
            case 2004: //BLOB
                javaClassName = "java.sql.Blob";
                break;
            case 2005: //CLOB
            case 2011: //NCLOB
                javaClassName = "java.sql.Clob";
                break;
            case 2006: //REF
                javaClassName = "java.sql.Ref";
                break;
            case -2: //BINARY
            case -3: //VARBINARY
            case -4: //LONGVARBINARY
                javaClassName = "byte[]";
                break;
            case 2002: //STRUCT
                javaClassName = "java.sql.Struct";
                break;
            default:
                String jname = DatabaseConfig.getInstance().getSQLTypeJavaNamesMap().get(sqlDataType);
                javaClassName = (jname != null)?jname:"java.lang.Object";
        }
        return javaClassName;
    }

    /**
     * Builds a string of SQL like string.
     *
     * Example:
     *      original string: "lower(category) like $keyword$"
     *         words string: "dog, cat, fish"
     *            joinType: OR
     *     converted string: "lower(category) like '%dog%' OR lower(category) like '%cat%' OR lower(category) like '%fish%'"
     *
     * @param words a string of words separated by either space or comma
     * @return string of SQL like type
     */
    public static String buildDynamicSQLJoinStringForLike(String original, String words, String joinType) {
        if (original == null || original.indexOf(REPLACEMENT_KEY) == -1 ||
            words == null || "".equals(words)) return "";

        List<String> list = new ArrayList<String>();
        StringTokenizer st = new StringTokenizer(words, ", ");
        while (st.hasMoreTokens()) {
            list.add(st.nextToken());
        }
        return buildDynamicSQLJoinStringForLike(original, list, joinType);
    }

    /**
     * Builds a string of SQL like string.
     *
     * Example:
     *      original string: "lower(category) like $keyword$"
     *           words list: "{dog, cat, fish}"
     *            joinType: OR
     *     converted string: "lower(category) like '%dog%' OR lower(category) like '%cat%' OR lower(category) like '%fish%'"
     *
     * @param words a string of words separated by either space or comma
     * @return string of SQL like type
     */
    public static String buildDynamicSQLJoinStringForLike(String original, List<String> words, String joinType) {
        if (original == null || original.indexOf(REPLACEMENT_KEY) == -1 ||
            words == null || words.size() == 0) return "";

        //find the keyword
        String keyword = "";
        StringTokenizer st = new StringTokenizer(original, ", ");
        while(st.hasMoreTokens()) {
            String token = st.nextToken();
            if (token.startsWith(REPLACEMENT_KEY) &&
                token.endsWith(REPLACEMENT_KEY)) keyword = token;
        }

        String converted = "";
        StringBuilder sb = new StringBuilder();
        int size = words.size();
        for (int i=0; i<size; i++) {
            String sqlLikeWord = "'%" + words.get(i) + "%'";
            converted = StringUtil.replace(original, keyword, sqlLikeWord);
            sb.append(converted).append(joinType);
        }

        converted = sb.toString();

        if (converted.endsWith(joinType))
            converted = converted.substring(0, converted.lastIndexOf(joinType));

        return converted;
    }

    public static java.sql.Date convertStringToSQLDate(String dateStr) {
        java.util.Date date = DateUtil.parseDate(dateStr);
        return (date == null)?null:(new java.sql.Date(date.getTime()));
    }

    public static java.sql.Time convertStringToSQLTime(String dateStr) {
        java.util.Date date = DateUtil.parseDate(dateStr);
        return (date == null)?null:(new java.sql.Time(date.getTime()));
    }

    public static java.sql.Timestamp convertStringToSQLTimestamp(String dateStr) {
        java.util.Date date = DateUtil.parseDate(dateStr);
        return (date == null)?null:(new java.sql.Timestamp(date.getTime()));
    }

    /**
     * Converts to upper case except for characters inside single quote.
     *
     * @param sql original SQL query string
     * @return String in upper case
     */
    public static String convertToUpperCase(String sql) {
        int length = sql.length();
        int countQuote = 0;
        StringBuilder sb = new StringBuilder(length);
        for (int i=0; i<length; i++) {
            char c = sql.charAt(i);
            if (c == '\'') {
                if (countQuote == 0) {
                    countQuote = 1;
                }
                else {
                    countQuote = 0;
                }
                sb.append(c);
                continue;
            }

            if (countQuote == 1) {
                sb.append(c);
            }
            else {
                sb.append(Character.toUpperCase(c));
            }
        }
        return sb.toString();
    }

    /**
     * copies data from one row to another
     */
    public static void copyData(RowData fromRowData, RowData toRowData) {
        if ( fromRowData != null ) {
            if (toRowData == null)
                toRowData = new RowData(fromRowData.getRowInfo(), null);

            Object[] currentData = fromRowData.getFields();
            if ( currentData != null ) {
                int dataLength = currentData.length;
                Object[] newObjectAry = new Object[dataLength];
                System.arraycopy(fromRowData.getFields(),0,newObjectAry,0,dataLength);
                toRowData.setFields(newObjectAry);
            }
        }
    }

    /**
     * Constructs <tt>ORDER BY</tt> clause in a SQL statement. Empty string
     * is returned if there is no options for this clause.
     *
     * @param options
   * @return a SQL fragment
     */
    public static String getOrderBy(Map<String, ?> options) {
        String orderByClause = "";
       
        if (options != null && options.size() > 0) {
            String order_by = (String)options.get(SqlConstants.key_order_by);
            String sort = (String)options.get(SqlConstants.key_sort);
            String order = (String)options.get(SqlConstants.key_order);
            if (order_by == null || "".equals(order_by)) {
                if (sort != null && !"".equals(sort)) {
                    orderByClause += " ORDER BY " + sort;
                    if (order != null && "down".equalsIgnoreCase(order)) {
                        orderByClause += " DESC";
                    }
                }
            }
            else {
                orderByClause += " ORDER BY " + order_by;
            }
        }
       
        return orderByClause;
    }
   
    /**
     * Constructs <tt>GROUP BY</tt> clause in a SQL statement. Empty string
     * is returned if there is no options for this clause.
     *
     * @param options
   * @return a SQL fragment
     */
    public static String getGroupBy(Map<String, String> options) {
        String groupByClause = "";
       
        if (options != null && options.size() > 0) {
            String group_by = options.get(SqlConstants.key_group_by);
            if (group_by != null && !"".equals(group_by)) {
                groupByClause += " GROUP BY " + group_by;
            }
        }
       
        return groupByClause;
    }
   
    /**
     * Constructs <tt>HAVING</tt> clause in a SQL statement. Empty string
     * is returned if there is no options for this clause.
     *
     * @param options
   * @return a SQL fragment
     */
    public static String getHaving(Map<String, String> options) {
        String havingClause = "";
       
        if (options != null && options.size() > 0) {
            String having = options.get(SqlConstants.key_having);
            if (having != null && !"".equals(having)) {
                havingClause += " HAVING " + having;
            }
        }
       
        return havingClause;
    }

    public static final String REPLACE_PART_START = "#";

    public static final String REPLACE_PART_END = "#";

    public static final String JOIN_RELATION_OR = " OR ";

    public static final String JOIN_RELATION_AND = " AND ";

    public static final String REPLACEMENT_KEY = "$";
}
TOP

Related Classes of com.scooterframework.orm.sqldataexpress.util.SqlUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.