Search in sources :

Example 16 with DfProcedureColumnMeta

use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta in project dbflute-core by dbflute.

the class DfProcedureExecutionMetaExtractor method buildParameterTypeView.

protected String buildParameterTypeView(List<DfProcedureColumnMeta> columnList) {
    final StringBuilder sb = new StringBuilder();
    final String prefix = "procedureColumn";
    for (DfProcedureColumnMeta column : columnList) {
        String name = column.getProcedureColumnType().name();
        if (name.startsWith(prefix)) {
            name = name.substring(prefix.length());
        }
        if (sb.length() > 0) {
            sb.append(", ");
        }
        sb.append(name);
    }
    sb.insert(0, "{").append("}");
    return sb.toString();
}
Also used : DfProcedureColumnMeta(org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta)

Example 17 with DfProcedureColumnMeta

use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta in project dbflute-core by dbflute.

the class DfProcedureExecutionMetaExtractor method doExtractExecutionMetaData.

protected void doExtractExecutionMetaData(DataSource dataSource, DfProcedureMeta procedure) throws SQLException {
    final List<DfProcedureColumnMeta> columnList = procedure.getProcedureColumnList();
    if (!needsToCall(columnList)) {
        final String name = procedure.buildProcedureLoggingName();
        _log.info("...Skipping unneeded call: " + name + " params=" + buildParameterTypeView(columnList));
        return;
    }
    final List<Object> testValueList = DfCollectionUtil.newArrayList();
    setupTestValueList(columnList, testValueList);
    final boolean existsReturn = existsReturnValue(columnList);
    final String sql = createSql(procedure, existsReturn, true);
    Connection conn = null;
    CallableStatement cs = null;
    boolean beginTransaction = false;
    try {
        _log.info("...Calling: " + sql);
        conn = dataSource.getConnection();
        conn.setAutoCommit(false);
        beginTransaction = true;
        cs = conn.prepareCall(sql);
        final List<DfProcedureColumnMeta> boundColumnList = DfCollectionUtil.newArrayList();
        setupBindParameter(conn, cs, columnList, testValueList, boundColumnList);
        boolean executed;
        try {
            executed = cs.execute();
        } catch (SQLException e) {
            // retry without escape because Oracle sometimes hates escape
            final String retrySql = createSql(procedure, existsReturn, false);
            try {
                try {
                    cs.close();
                } catch (SQLException ignored) {
                }
                cs = conn.prepareCall(retrySql);
                setupBindParameter(conn, cs, columnList, testValueList, boundColumnList);
                executed = cs.execute();
                _log.info("  (o) retry: " + retrySql);
            } catch (SQLException ignored) {
                _log.info("  (x) retry: " + retrySql);
                throw e;
            }
        }
        if (executed) {
            int closetIndex = 0;
            do {
                ResultSet rs = null;
                try {
                    rs = cs.getResultSet();
                    if (rs == null) {
                        break;
                    }
                    final Map<String, DfColumnMeta> columnMetaInfoMap = extractColumnMetaInfoMap(rs, sql);
                    final DfProcedureNotParamResultMeta notParamResult = new DfProcedureNotParamResultMeta();
                    final String propertyName;
                    if (procedure.isCalledBySelect() && closetIndex == 0) {
                        // for example, table valued function
                        // if the procedure of this type does not have
                        // second or more result set basically
                        // but checks closetIndex just in case
                        propertyName = "returnResult";
                    } else {
                        // basically here
                        propertyName = "notParamResult" + (closetIndex + 1);
                    }
                    notParamResult.setPropertyName(propertyName);
                    notParamResult.setResultSetColumnInfoMap(columnMetaInfoMap);
                    procedure.addNotParamResult(notParamResult);
                    ++closetIndex;
                } finally {
                    closeResult(rs);
                }
            } while (cs.getMoreResults());
        }
        int index = 0;
        for (DfProcedureColumnMeta column : boundColumnList) {
            final DfProcedureColumnType columnType = column.getProcedureColumnType();
            if (DfProcedureColumnType.procedureColumnIn.equals(columnType)) {
                ++index;
                continue;
            }
            final int paramIndex = (index + 1);
            final Object obj;
            if (column.isPostgreSQLCursor()) {
                obj = _postgreSqlResultSetType.getValue(cs, paramIndex);
            } else if (column.isOracleCursor()) {
                obj = _oracleResultSetType.getValue(cs, paramIndex);
            } else {
                // as default
                obj = cs.getObject(paramIndex);
            }
            if (obj instanceof ResultSet) {
                ResultSet rs = null;
                try {
                    rs = (ResultSet) obj;
                    final Map<String, DfColumnMeta> columnMetaInfoMap = extractColumnMetaInfoMap(rs, sql);
                    column.setResultSetColumnInfoMap(columnMetaInfoMap);
                } finally {
                    closeResult(rs);
                }
            }
            ++index;
        }
    } catch (SQLException e) {
        final ExceptionMessageBuilder br = new ExceptionMessageBuilder();
        br.addNotice("Failed to execute the procedure for getting meta data.");
        br.addItem("SQL");
        br.addElement(sql);
        br.addItem("Parameter");
        for (DfProcedureColumnMeta column : columnList) {
            br.addElement(column.getColumnDisplayName());
        }
        br.addItem("Test Value");
        br.addElement(buildTestValueDisp(testValueList));
        br.addItem("Exception Message");
        br.addElement(DfJDBCException.extractMessage(e));
        final SQLException nextEx = e.getNextException();
        if (nextEx != null) {
            br.addElement(DfJDBCException.extractMessage(nextEx));
        }
        final String msg = br.buildExceptionMessage();
        final DfOutsideSqlProperties prop = getProperties().getOutsideSqlProperties();
        if (prop.hasSpecifiedExecutionMetaProcedure()) {
            throw new DfProcedureExecutionMetaGettingFailureException(msg, e);
        } else {
            // if no specified, it continues
            _continuedFailureMessageMap.put(procedure.getProcedureFullQualifiedName(), msg);
            _log.info("*Failed to call so read the warning message displayed later");
        }
    } finally {
        if (cs != null) {
            cs.close();
        }
        if (conn != null) {
            try {
                conn.rollback();
            } catch (SQLException continued) {
                // one day Oracle suddenly threw it (by socket trouble?)
                final String exp = DfJDBCException.extractMessage(continued);
                _log.info("*Failed to roll-back the procedure call but continued: " + exp);
            }
            if (beginTransaction) {
                try {
                    conn.setAutoCommit(true);
                } catch (SQLException continued) {
                    final String exp = DfJDBCException.extractMessage(continued);
                    _log.info("*Failed to set auto-commit true: " + exp);
                }
            }
        }
    }
}
Also used : DfProcedureColumnType(org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType) DfColumnMeta(org.dbflute.logic.jdbc.metadata.info.DfColumnMeta) DfOutsideSqlProperties(org.dbflute.properties.DfOutsideSqlProperties) SQLException(java.sql.SQLException) ExceptionMessageBuilder(org.dbflute.helper.message.ExceptionMessageBuilder) Connection(java.sql.Connection) DfProcedureColumnMeta(org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta) DfProcedureExecutionMetaGettingFailureException(org.dbflute.exception.DfProcedureExecutionMetaGettingFailureException) DfProcedureNotParamResultMeta(org.dbflute.logic.jdbc.metadata.info.DfProcedureNotParamResultMeta) CallableStatement(java.sql.CallableStatement) ResultSet(java.sql.ResultSet)

Example 18 with DfProcedureColumnMeta

use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta in project dbflute-core by dbflute.

the class DfProcedureExecutionMetaExtractor method setupBindParameter.

protected void setupBindParameter(Connection conn, CallableStatement cs, List<DfProcedureColumnMeta> columnList, List<Object> testValueList, List<DfProcedureColumnMeta> boundColumnList) throws SQLException {
    boundColumnList.clear();
    int index = 0;
    int testValueIndex = 0;
    for (DfProcedureColumnMeta column : columnList) {
        if (!column.isBindParameter()) {
            // must be no increment
            continue;
        }
        final int paramIndex = (index + 1);
        final DfProcedureColumnType columnType = column.getProcedureColumnType();
        final int jdbcDefType = column.getJdbcDefType();
        if (DfProcedureColumnType.procedureColumnReturn.equals(columnType)) {
            registerOutParameter(conn, cs, paramIndex, jdbcDefType, column);
            boundColumnList.add(column);
        } else if (DfProcedureColumnType.procedureColumnIn.equals(columnType)) {
            bindObject(conn, cs, paramIndex, jdbcDefType, testValueList.get(testValueIndex), column);
            ++testValueIndex;
            boundColumnList.add(column);
        } else if (DfProcedureColumnType.procedureColumnOut.equals(columnType)) {
            registerOutParameter(conn, cs, paramIndex, jdbcDefType, column);
            boundColumnList.add(column);
        } else if (DfProcedureColumnType.procedureColumnInOut.equals(columnType)) {
            registerOutParameter(conn, cs, paramIndex, jdbcDefType, column);
            bindObject(conn, cs, paramIndex, jdbcDefType, testValueList.get(testValueIndex), column);
            ++testValueIndex;
            boundColumnList.add(column);
        }
        ++index;
    }
}
Also used : DfProcedureColumnMeta(org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta) DfProcedureColumnType(org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType)

Example 19 with DfProcedureColumnMeta

use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta in project dbflute-core by dbflute.

the class DfProcedurePmbSetupper method setupProcedure.

// ===================================================================================
// Set up
// ======
public void setupProcedure() throws SQLException {
    if (!getOutsideSqlProperties().isGenerateProcedureParameterBean()) {
        return;
    }
    _log.info(" ");
    _log.info("...Setting up procedures for generating parameter-beans");
    final List<DfProcedureMeta> procedureList = getAvailableProcedureList();
    _log.info("");
    _log.info("/= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
    for (DfProcedureMeta procedure : procedureList) {
        final Map<String, String> propertyNameTypeMap = DfCollectionUtil.newLinkedHashMap();
        final Map<String, String> propertyNameOptionMap = DfCollectionUtil.newLinkedHashMap();
        final Map<String, String> propertyNameColumnNameMap = DfCollectionUtil.newLinkedHashMap();
        final Map<String, DfProcedureColumnMeta> propertyNameColumnInfoMap = DfCollectionUtil.newLinkedHashMap();
        final List<DfProcedureColumnMeta> procedureColumnList = procedure.getProcedureColumnList();
        final List<DfProcedureNotParamResultMeta> notParamResultList = procedure.getNotParamResultList();
        final String pmbName = convertProcedureNameToPmbName(procedure.getProcedureName());
        {
            final String procDisp = procedure.buildProcedureLoggingName();
            final DfProcedureType procType = procedure.getProcedureType();
            _log.info("[" + pmbName + "]: " + procDisp + " // " + procType);
            if (procedureColumnList.isEmpty() && notParamResultList.isEmpty()) {
                _log.info("    *No Parameter");
            }
        }
        boolean refCustomizeEntity = false;
        // Procedure Parameter handling
        int index = 0;
        for (DfProcedureColumnMeta column : procedureColumnList) {
            if (!column.isBindParameter()) {
                continue;
            }
            final String columnName;
            {
                final String plainColumnName = column.getColumnName();
                if (Srl.is_NotNull_and_NotTrimmedEmpty(plainColumnName)) {
                    columnName = resolveVendorColumnNameHeadable(plainColumnName);
                } else {
                    columnName = "arg" + (index + 1);
                }
            }
            final String propertyName;
            {
                propertyName = convertColumnNameToPropertyName(columnName);
            }
            // procedure's overload is unsupported because of this (override property)
            propertyNameColumnInfoMap.put(propertyName, column);
            final ProcedurePropertyInfo propertyInfo = processProcedureProperty(pmbName, column, propertyName);
            final String propertyType = propertyInfo.getPropertyType();
            if (propertyInfo.isRefCustomizeEntity()) {
                refCustomizeEntity = true;
            }
            propertyNameTypeMap.put(propertyName, propertyType);
            final DfProcedureColumnType procedureColumnType = column.getProcedureColumnType();
            propertyNameOptionMap.put(propertyName, procedureColumnType.toString());
            propertyNameColumnNameMap.put(propertyName, columnName);
            String msg = "    " + propertyType + " " + propertyName + ";";
            msg = msg + " // " + column.getProcedureColumnType();
            msg = msg + "(" + column.getJdbcDefType() + ", " + column.getDbTypeName() + ")";
            _log.info(msg);
            ++index;
        }
        // NotParamResult handling
        for (DfProcedureNotParamResultMeta result : notParamResultList) {
            final String propertyName = result.getPropertyName();
            final String propertyType;
            if (result.hasResultSetColumnInfo()) {
                final String entityName = convertProcedurePmbNameToEntityName(pmbName, propertyName);
                _entityInfoMap.put(entityName, createEntityInfo(entityName, result.getResultSetColumnInfoMap()));
                propertyType = convertProcedureListPropertyType(entityName);
                refCustomizeEntity = true;
            } else {
                propertyType = getProcedureDefaultResultSetPropertyType();
            }
            propertyNameTypeMap.put(propertyName, propertyType);
            propertyNameOptionMap.put(propertyName, DfProcedureColumnType.procedureColumnResult.toString());
            propertyNameColumnNameMap.put(propertyName, propertyName);
            String msg = "    " + propertyType + " " + propertyName + ";";
            msg = msg + " // " + DfProcedureColumnType.procedureColumnResult;
            _log.info(msg);
        }
        final DfPmbMetaData parameterBeanMetaData = new DfPmbMetaData();
        parameterBeanMetaData.setClassName(pmbName);
        parameterBeanMetaData.setPropertyNameTypeMap(propertyNameTypeMap);
        parameterBeanMetaData.setPropertyNameOptionMap(propertyNameOptionMap);
        parameterBeanMetaData.setProcedureName(procedure.buildProcedureSqlName());
        parameterBeanMetaData.setPropertyNameColumnNameMap(propertyNameColumnNameMap);
        parameterBeanMetaData.setPropertyNameColumnInfoMap(propertyNameColumnInfoMap);
        parameterBeanMetaData.setProcedureCalledBySelect(procedure.isCalledBySelect());
        parameterBeanMetaData.setProcedureRefCustomizeEntity(refCustomizeEntity);
        _pmbMetaDataMap.put(pmbName, parameterBeanMetaData);
    }
    _log.info("= = = = = = = = = =/");
    _log.info(" ");
}
Also used : DfProcedureColumnType(org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType) DfProcedureColumnMeta(org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta) DfProcedureNotParamResultMeta(org.dbflute.logic.jdbc.metadata.info.DfProcedureNotParamResultMeta) DfProcedureMeta(org.dbflute.logic.jdbc.metadata.info.DfProcedureMeta) DfProcedureType(org.dbflute.logic.jdbc.metadata.info.DfProcedureMeta.DfProcedureType)

Example 20 with DfProcedureColumnMeta

use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta in project dbflute-core by dbflute.

the class DfPmbMetaData method needsPostgreSQLOidHandling.

public boolean needsPostgreSQLOidHandling(String propertyName) {
    assertArgumentPmbMetaDataPropertyName(propertyName);
    final DfProcedureColumnMeta metaInfo = getProcedureColumnInfo(propertyName);
    return metaInfo != null && _columnHandler.isPostgreSQLOid(metaInfo.getDbTypeName());
}
Also used : DfProcedureColumnMeta(org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta)

Aggregations

DfProcedureColumnMeta (org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta)27 DfProcedureColumnType (org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType)5 DfProcedureMeta (org.dbflute.logic.jdbc.metadata.info.DfProcedureMeta)5 LinkedHashSet (java.util.LinkedHashSet)2 DfProcedureNotParamResultMeta (org.dbflute.logic.jdbc.metadata.info.DfProcedureNotParamResultMeta)2 CallableStatement (java.sql.CallableStatement)1 Connection (java.sql.Connection)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 HashSet (java.util.HashSet)1 UnifiedSchema (org.apache.torque.engine.database.model.UnifiedSchema)1 DfProcedureExecutionMetaGettingFailureException (org.dbflute.exception.DfProcedureExecutionMetaGettingFailureException)1 ExceptionMessageBuilder (org.dbflute.helper.message.ExceptionMessageBuilder)1 DfColumnMeta (org.dbflute.logic.jdbc.metadata.info.DfColumnMeta)1 DfProcedureArgumentInfo (org.dbflute.logic.jdbc.metadata.info.DfProcedureArgumentInfo)1 DfProcedureType (org.dbflute.logic.jdbc.metadata.info.DfProcedureMeta.DfProcedureType)1 DfTypeArrayInfo (org.dbflute.logic.jdbc.metadata.info.DfTypeArrayInfo)1 DfTypeStructInfo (org.dbflute.logic.jdbc.metadata.info.DfTypeStructInfo)1 DfPmbMetaData (org.dbflute.logic.sql2entity.pmbean.DfPmbMetaData)1 DfOutsideSqlProperties (org.dbflute.properties.DfOutsideSqlProperties)1