use of org.dbflute.dbmeta.DBMeta in project dbflute-core by dbflute.
the class AbstractConditionQuery method doInvokeQuery.
protected void doInvokeQuery(String colName, String ckey, Object value, ConditionOption option) {
assertStringNotNullAndNotTrimmedEmpty("columnFlexibleName", colName);
assertStringNotNullAndNotTrimmedEmpty("conditionKeyName", ckey);
final boolean noArg = Srl.equalsIgnoreCase(ckey, "IsNull", "IsNotNull", "IsNullOrEmpty", "EmptyString");
if (!noArg && (value == null || "".equals(value))) {
if (xgetSqlClause().isNullOrEmptyQueryChecked()) {
// as default
String msg = "The conditionValue is required but null or empty: column=" + colName + " value=" + value;
throw new IllegalConditionBeanOperationException(msg);
} else {
// e.g. when cb.ignoreNullOrEmptyQuery()
return;
}
}
final PropertyNameCQContainer container = xhelpExtractingPropertyNameCQContainer(colName);
final String flexibleName = container.getFlexibleName();
final ConditionQuery cq = container.getConditionQuery();
final DBMeta dbmeta = findDBMeta(cq.asTableDbName());
final ColumnInfo columnInfo;
try {
columnInfo = dbmeta.findColumnInfo(flexibleName);
} catch (RuntimeException e) {
throwConditionInvokingColumnFindFailureException(colName, ckey, value, option, e);
// unreachable (to avoid compile error)
return;
}
final String columnCapPropName = initCap(columnInfo.getPropertyName());
final boolean rangeOf = Srl.equalsIgnoreCase(ckey, "RangeOf");
final boolean fromTo = Srl.equalsIgnoreCase(ckey, "FromTo", "DateFromTo");
final boolean inScope = Srl.equalsIgnoreCase(ckey, "InScope");
if (!noArg) {
try {
// convert type
value = columnInfo.convertToObjectNativeType(value);
} catch (RuntimeException e) {
throwConditionInvokingValueConvertFailureException(colName, ckey, value, option, e);
}
}
final String methodName = xbuildQuerySetMethodName(ckey, columnCapPropName);
final List<Class<?>> typeList = newArrayListSized(4);
final Class<?> propertyType = columnInfo.getObjectNativeType();
if (fromTo) {
if (LocalDate.class.isAssignableFrom(propertyType)) {
// #date_parade
typeList.add(propertyType);
typeList.add(propertyType);
} else if (LocalDateTime.class.isAssignableFrom(propertyType)) {
typeList.add(propertyType);
typeList.add(propertyType);
} else {
// fixedly util.Date
typeList.add(Date.class);
typeList.add(Date.class);
}
} else if (rangeOf) {
typeList.add(propertyType);
typeList.add(propertyType);
} else {
if (!noArg) {
final Class<?> instanceType = value.getClass();
if (inScope && Collection.class.isAssignableFrom(instanceType)) {
// double check just in case
// inScope's argument is fixed type
typeList.add(Collection.class);
} else {
typeList.add(instanceType);
}
}
}
if (option != null) {
typeList.add(option.getClass());
}
final List<Class<?>> filteredTypeList = newArrayListSized(typeList.size());
for (Class<?> parameterType : typeList) {
filteredTypeList.add(xfilterInvokeQueryParameterType(colName, ckey, parameterType));
}
final Class<?>[] parameterTypes = filteredTypeList.toArray(new Class<?>[filteredTypeList.size()]);
final Method method = xhelpGettingCQMethod(cq, methodName, parameterTypes);
if (method == null) {
throwConditionInvokingSetMethodNotFoundException(colName, ckey, value, option, methodName, parameterTypes);
}
try {
final List<Object> argList = newArrayList();
if (fromTo || rangeOf) {
if (!(value instanceof List<?>)) {
// check type
throwConditionInvokingDateFromToValueInvalidException(colName, ckey, value, option, methodName, parameterTypes);
}
argList.addAll((List<?>) value);
} else {
if (!noArg) {
argList.add(value);
}
}
if (option != null) {
argList.add(option);
}
final List<Object> filteredArgList = newArrayListSized(argList.size());
for (Object arg : argList) {
filteredArgList.add(xfilterInvokeQueryParameterValue(colName, ckey, arg));
}
xhelpInvokingCQMethod(cq, method, filteredArgList.toArray());
} catch (ReflectionFailureException e) {
throwConditionInvokingSetReflectionFailureException(colName, ckey, value, option, methodName, parameterTypes, e);
}
}
use of org.dbflute.dbmeta.DBMeta in project dbflute-core by dbflute.
the class AbstractConditionQuery method doRegisterQueryDerivedReferrer.
protected void doRegisterQueryDerivedReferrer(String function, final ConditionQuery subQuery, String columnDbName, String relatedColumnDbName, String propertyName, String referrerPropertyName, String operand, Object value, String parameterPropertyName, DerivedReferrerOption option) {
assertFunctionNotNull("QueryDerivedReferrer", columnDbName, function);
assertSubQueryNotNull("QueryDerivedReferrer", columnDbName, subQuery);
option.xacceptBaseCB(xgetBaseCB());
if (isDerivedReferrerSelectAllPossible(subQuery, option)) {
createCBExThrower().throwQueryDerivedReferrerSelectAllPossibleException(function, subQuery);
}
final SubQueryPath subQueryPath = new SubQueryPath(xgetLocation(propertyName));
final GeneralColumnRealNameProvider localRealNameProvider = new GeneralColumnRealNameProvider();
final int subQueryLevel = subQuery.xgetSqlClause().getSubQueryLevel();
final SqlClause subQueryClause = subQuery.xgetSqlClause();
final String subQueryIdentity = propertyName + "[" + subQueryLevel + "]";
final ColumnSqlNameProvider subQuerySqlNameProvider = dbName -> subQuery.toColumnSqlName(dbName);
final DBMeta subQueryDBMeta = findDBMeta(subQuery.asTableDbName());
final GearedCipherManager cipherManager = xgetSqlClause().getGearedCipherManager();
final String mainSubQueryIdentity = propertyName + "[" + subQueryLevel + ":subquerymain]";
final String parameterPath = xgetLocation(parameterPropertyName);
final QueryDerivedReferrer derivedReferrer = option.createQueryDerivedReferrer(subQueryPath, localRealNameProvider, subQuerySqlNameProvider, subQueryLevel, subQueryClause, subQueryIdentity, subQueryDBMeta, cipherManager, mainSubQueryIdentity, operand, value, parameterPath);
xregisterParameterOption(option);
final String correlatedFixedCondition = xbuildReferrerCorrelatedFixedCondition(subQuery, referrerPropertyName);
final String clause = derivedReferrer.buildDerivedReferrer(function, columnDbName, relatedColumnDbName, correlatedFixedCondition, option);
// /= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// is null or null-revived conversion (coalesce) -> no way to be inner
//
// for example, the following SQL is no way to be inner
// (suppose if PURCHASE refers WITHDRAWAL)
//
// select mb.MEMBER_ID, mb.MEMBER_NAME
// , mb.MEMBER_STATUS_CODE, wd.MEMBER_ID as WD_MEMBER_ID
// from MEMBER mb
// left outer join MEMBER_WITHDRAWAL wd on mb.MEMBER_ID = wd.MEMBER_ID
// where (select max(pc.PURCHASE_PRICE)
// from PURCHASE pc
// where pc.MEMBER_ID = wd.MEMBER_ID -- may null
// ) is null
// order by mb.MEMBER_ID
//
// and using coalesce means it may select records that have null value
// so using coalesce is no way in spite of operand
// = = = = = = = = = =/
final boolean noWayInner = HpQDRParameter.isOperandIsNull(operand) || option.mayNullRevived();
registerWhereClause(clause, noWayInner);
}
use of org.dbflute.dbmeta.DBMeta in project dbflute-core by dbflute.
the class AbstractConditionQuery method registerInScopeRelation.
// *unsupported ExistsReferrer as in-line because it's (or was) so dangerous
// ===================================================================================
// InScopeRelation
// ===============
// {Modified at DBFlute-0.7.5}
protected void registerInScopeRelation(final ConditionQuery subQuery, String columnDbName, String relatedColumnDbName, String propertyName, String relationPropertyName, boolean notInScope) {
assertSubQueryNotNull("InScopeRelation", columnDbName, subQuery);
final SubQueryPath subQueryPath = new SubQueryPath(xgetLocation(propertyName));
final GeneralColumnRealNameProvider localRealNameProvider = new GeneralColumnRealNameProvider();
final int subQueryLevel = subQuery.xgetSqlClause().getSubQueryLevel();
final SqlClause subQueryClause = subQuery.xgetSqlClause();
final String subQueryIdentity = propertyName + "[" + subQueryLevel + "]";
final ColumnSqlNameProvider subQuerySqlNameProvider = dbName -> subQuery.toColumnSqlName(dbName);
final DBMeta subQueryDBMeta = findDBMeta(subQuery.asTableDbName());
final GearedCipherManager cipherManager = xgetSqlClause().getGearedCipherManager();
final boolean suppressLocalAliasName = isInScopeRelationSuppressLocalAliasName();
final InScopeRelation inScopeRelation = new InScopeRelation(subQueryPath, localRealNameProvider, subQuerySqlNameProvider, subQueryLevel, subQueryClause, subQueryIdentity, subQueryDBMeta, cipherManager, suppressLocalAliasName);
final String correlatedFixedCondition = xbuildForeignCorrelatedFixedCondition(subQuery, relationPropertyName);
final String inScopeOption = notInScope ? "not" : null;
final String clause = inScopeRelation.buildInScopeRelation(columnDbName, relatedColumnDbName, correlatedFixedCondition, inScopeOption);
registerWhereClause(clause);
}
use of org.dbflute.dbmeta.DBMeta in project dbflute-core by dbflute.
the class AbstractConditionQuery method xbuildReferrerCorrelatedFixedCondition.
protected String xbuildReferrerCorrelatedFixedCondition(ConditionQuery subQuery, String referrerPropertyName) {
if (referrerPropertyName == null) {
return null;
}
final DBMeta localDBMeta = xgetLocalDBMeta();
if (!localDBMeta.hasReferrer(referrerPropertyName)) {
// one-to-one referrer
return null;
}
final ReferrerInfo referrerInfo = localDBMeta.findReferrerInfo(referrerPropertyName);
return xdoBuildReferrerCorrelatedFixedCondition(subQuery, referrerInfo);
}
use of org.dbflute.dbmeta.DBMeta in project dbflute-core by dbflute.
the class AbstractConditionBean method enablePagingSelectAndQuerySplit.
/**
* Enable that it splits the SQL execute select and query of paging. <br>
* You should confirm that the executed SQL on log matches with your expectation. <br>
* It is very difficult internal logic so it also has simplistic logic. Be careful!
* <pre>
* Cannot use this:
* o if no PK or compound PK table (exception is thrown)
* o if SpecifiedDerivedOrderBy or not Paging (but no exception)
*
* Automatically Changed:
* o disable PagingCountLater (to suppress rows calculation)
* </pre>
* @deprecated This is rare handling for performance tuning so don't use this easily.
*/
public void enablePagingSelectAndQuerySplit() {
assertOptionThatBadTiming("enablePagingSelectAndQuerySplit()");
final DBMeta dbmeta = asDBMeta();
if (!dbmeta.hasPrimaryKey() || dbmeta.getPrimaryInfo().isCompoundKey()) {
String msg = "The PagingSelectAndQuerySplit needs only-one column key table: " + asTableDbName();
throw new IllegalConditionBeanOperationException(msg);
}
// MySQL's rows calculation is not fit with this function
// e.g.
// paging : select PK only by business condition with sql_calc_found_rows
// paging : select business data by PK without no sql_calc_found_rows
// count : select found_rows() -> returns latest count, why?
disablePagingCountLater();
_pagingSelectAndQuerySplit = true;
}
Aggregations