use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType in project dbflute-core by dbflute.
the class DfProcedureExtractor method adjustPostgreSQLResultSetParameter.
protected void adjustPostgreSQLResultSetParameter(DfProcedureMeta procedureMetaInfo) {
if (!isDatabasePostgreSQL()) {
return;
}
final List<DfProcedureColumnMeta> columnMetaInfoList = procedureMetaInfo.getProcedureColumnList();
boolean existsResultSetParameter = false;
boolean existsResultSetReturn = false;
int resultSetReturnIndex = 0;
String resultSetReturnName = null;
int index = 0;
for (DfProcedureColumnMeta columnMetaInfo : columnMetaInfoList) {
final DfProcedureColumnType procedureColumnType = columnMetaInfo.getProcedureColumnType();
final String dbTypeName = columnMetaInfo.getDbTypeName();
if (procedureColumnType.equals(DfProcedureColumnType.procedureColumnOut)) {
if ("refcursor".equalsIgnoreCase(dbTypeName)) {
existsResultSetParameter = true;
}
}
if (procedureColumnType.equals(DfProcedureColumnType.procedureColumnReturn)) {
if ("refcursor".equalsIgnoreCase(dbTypeName)) {
existsResultSetReturn = true;
resultSetReturnIndex = index;
resultSetReturnName = columnMetaInfo.getColumnName();
}
}
++index;
}
if (existsResultSetParameter && existsResultSetReturn) {
// It is a precondition that PostgreSQL does not allow functions to have a result set return
// when it also has result set parameters (as an out parameter).
String name = procedureMetaInfo.buildProcedureLoggingName() + "." + resultSetReturnName;
log("...Removing the result set return which is unnecessary: " + name);
columnMetaInfoList.remove(resultSetReturnIndex);
}
}
use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType 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);
}
}
}
}
}
use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType 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;
}
}
use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType 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(" ");
}
use of org.dbflute.logic.jdbc.metadata.info.DfProcedureColumnMeta.DfProcedureColumnType in project dbflute-core by dbflute.
the class DfSchemaInitializerPostgreSQL method buildProcedureArgExpression.
protected String buildProcedureArgExpression(DfProcedureMeta metaInfo) {
final List<DfProcedureColumnMeta> metaInfoList = metaInfo.getProcedureColumnList();
final StringBuilder sb = new StringBuilder();
for (DfProcedureColumnMeta columnMetaInfo : metaInfoList) {
final String dbTypeName = columnMetaInfo.getDbTypeName();
final String columnName = columnMetaInfo.getColumnName();
final DfProcedureColumnType columnType = columnMetaInfo.getProcedureColumnType();
if (DfProcedureColumnType.procedureColumnReturn.equals(columnType)) {
continue;
}
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(columnName);
if (DfProcedureColumnType.procedureColumnIn.equals(columnType)) {
sb.append(" in ");
} else if (DfProcedureColumnType.procedureColumnOut.equals(columnType)) {
sb.append(" out ");
} else if (DfProcedureColumnType.procedureColumnInOut.equals(columnType)) {
sb.append(" inout ");
} else {
sb.append(" ");
}
sb.append(dbTypeName);
}
return sb.toString();
}
Aggregations