/* * 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.parser; import java.sql.ParameterMetaData; import java.sql.SQLException; import java.util.List; import java.util.StringTokenizer; import com.scooterframework.orm.sqldataexpress.exception.BaseSQLException; import com.scooterframework.orm.sqldataexpress.object.JdbcStatement; import com.scooterframework.orm.sqldataexpress.object.JdbcStatementParameter; import com.scooterframework.orm.sqldataexpress.object.Parameter; /** * ParameterMetaDataLoader class. * * @author (Fei) John Chen */ public class ParameterMetaDataLoader extends JdbcStatementHelper { public ParameterMetaDataLoader(ParameterMetaData pmd, JdbcStatement st) { this.pmd = pmd; this.st = st; parseJdbcStatementParameters(); } /** * load some parameter properties from ParameterMetaData. * * Do not use this method if the underlying database driver does not support * ParameterMetaData feature, such as Oracle. */ public void loadParameterMetaData() { try { int pcount = pmd.getParameterCount(); List<Parameter> parameters = st.getParameters(); if (pcount != parameters.size()) throw new BaseSQLException("ParameterMetaData size is " + pcount + " while statement parameters size is " + parameters.size() + "."); for (int i = 1; i <= pcount; i++) { Parameter p = parameters.get(i-1); log.debug("i=" + i); log.debug("getParameterClassName : " + pmd.getParameterClassName(i)); log.debug("getParameterMode : " + pmd.getParameterMode(i)); log.debug("getParameterType : " + pmd.getParameterType(i)); log.debug("getParameterTypeName : " + pmd.getParameterTypeName(i)); log.debug("getPrecision : " + pmd.getPrecision(i)); log.debug("getScale : " + pmd.getScale(i)); log.debug("isNullable : " + pmd.isNullable(i)); log.debug("isSigned : " + pmd.isSigned(i)); //log.debug("parameterModeIn : " + pmd.parameterModeIn); //log.debug("parameterModeInOut : " + pmd.parameterModeInOut); //log.debug("parameterModeOut : " + pmd.parameterModeOut); //log.debug("parameterModeUnknown : " + pmd.parameterModeUnknown); //log.debug("parameterNoNulls : " + pmd.parameterNoNulls); //log.debug("parameterNullable : " + pmd.parameterNullable); //log.debug("parameterNullableUnknown : " + pmd.parameterNullableUnknown); p.setJavaClassName(pmd.getParameterClassName(i)); p.setSqlDataType(pmd.getParameterType(i)); p.setSqlDataTypeName(pmd.getParameterTypeName(i)); } st.setLoadedParameterMetaData(true); } catch(SQLException ex) { log.error("Error loading parametermetadata: " + ex.getMessage()); } } /** * counts parameters (? marks) */ private void parseJdbcStatementParameters() { if (st == null) return; String jdbcStatementString = st.getOriginalJdbcStatementString(); //no need to parse if there is no dynamic parameter if (jdbcStatementString.indexOf('?') == -1) { return; } //if ( jdbcStatementString.startsWith("INSERT") && // jdbcStatementString.indexOf("SELECT") == -1 ) //{ // This is a pure insert statement. // parseInsertStatement(); // return; //} // // find all strings starting with ? // // step 1: convert the alias to regular table names String sql = jdbcStatementString; String modifiedSql = resetAlias(sql); //StringTokenizer sti = new StringTokenizer(modifiedSql, " ,><=(){}"); StringTokenizer sti = new StringTokenizer(modifiedSql, " ,|><=(){}+-*/"); int totalTokens = sti.countTokens(); String[] tokens = new String[totalTokens]; int i = 0; while(sti.hasMoreTokens()) { tokens[i] = sti.nextToken(); i = i + 1; } // step 2: get the column name for each question mark int qmarkIndex = 1; for ( int j = 0; j < totalTokens; j++ ) { String token = tokens[j]; if (token.startsWith("?")) { JdbcStatementParameter param = new JdbcStatementParameter(); param.setIndex(qmarkIndex); param.setName(getNameFromToken(qmarkIndex, token)); st.addParameter(param); qmarkIndex = qmarkIndex + 1; } } } private ParameterMetaData pmd; private JdbcStatement st; }