Search in sources :

Example 1 with RelationInfo

use of org.dbflute.dbmeta.info.RelationInfo in project dbflute-core by dbflute.

the class AbstractConditionQuery method xbuildForeignCorrelatedFixedCondition.

protected String xbuildForeignCorrelatedFixedCondition(ConditionQuery subQuery, String relationPropertyName) {
    if (relationPropertyName == null) {
        return null;
    }
    final DBMeta localDBMeta = xgetLocalDBMeta();
    final RelationInfo relationInfo = localDBMeta.findRelationInfo(relationPropertyName);
    if (!relationInfo.isReferrer()) {
        return null;
    }
    if (!(relationInfo instanceof ReferrerInfo)) {
        return null;
    }
    final ReferrerInfo referrerInfo = (ReferrerInfo) relationInfo;
    return xdoBuildReferrerCorrelatedFixedCondition(subQuery, referrerInfo);
}
Also used : DBMeta(org.dbflute.dbmeta.DBMeta) RelationInfo(org.dbflute.dbmeta.info.RelationInfo) ReferrerInfo(org.dbflute.dbmeta.info.ReferrerInfo)

Example 2 with RelationInfo

use of org.dbflute.dbmeta.info.RelationInfo in project dbflute-core by dbflute.

the class AbstractBehaviorReadable method xcreateLoadReferrerCallback.

protected <// generic
LOCAL_ENTITY extends Entity, // generic
KEY, // generic
REFERRER_CB extends ConditionBean, // generic
REFERRER_ENTITY extends Entity> // return
InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY> xcreateLoadReferrerCallback(final String referrerProperty, final DBMeta dbmeta, final ReferrerInfo referrerInfo, final BehaviorReadable referrerBhv, final Set<ColumnInfo> pkColSet, final Set<ColumnInfo> fkColSet, final Map<ColumnInfo, ColumnInfo> mappingColMap) {
    return new // for compound key
    InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY>() {

        @SuppressWarnings("unchecked")
        public KEY getPKVal(LOCAL_ENTITY entity) {
            final Map<String, Object> keyMap = xnewLoadReferrerCompoundKeyMap();
            for (ColumnInfo pkCol : pkColSet) {
                // key is DB name
                keyMap.put(pkCol.getColumnDbName(), pkCol.read(entity));
            }
            return (KEY) keyMap;
        // cannot use because it might be unique key
        // return (KEY) dbmeta.extractPrimaryKeyMap(entity);
        }

        public void setRfLs(LOCAL_ENTITY entity, List<REFERRER_ENTITY> referrerList) {
            referrerInfo.write(entity, referrerList);
        }

        @SuppressWarnings("unchecked")
        public REFERRER_CB newMyCB() {
            return (REFERRER_CB) referrerBhv.newConditionBean();
        }

        public void qyFKIn(REFERRER_CB cb, final Collection<KEY> pkList) {
            // compound key doesn't use InScope so OrScopeQuery
            cb.invokeOrScopeQuery(new OrQuery<ConditionBean>() {

                public void query(ConditionBean orCB) {
                    for (final KEY pkKey : pkList) {
                        @SuppressWarnings("unchecked") final Map<String, Object> pkMap = (Map<String, Object>) pkKey;
                        orCB.invokeOrScopeQueryAndPart(new AndQuery<ConditionBean>() {

                            public void query(ConditionBean andCB) {
                                for (ColumnInfo fkCol : fkColSet) {
                                    final ColumnInfo pkCol = mappingColMap.get(fkCol);
                                    // key is DB name
                                    final Object pkValue = pkMap.get(pkCol.getColumnDbName());
                                    andCB.localCQ().invokeQueryEqual(fkCol.getColumnDbName(), pkValue);
                                }
                            }
                        });
                    }
                }
            });
        }

        public void qyOdFKAsc(REFERRER_CB cb) {
            for (ColumnInfo fkCol : fkColSet) {
                cb.localCQ().invokeOrderBy(fkCol.getColumnDbName(), true);
            }
        }

        public void spFKCol(REFERRER_CB cb) {
            for (ColumnInfo fkCol : fkColSet) {
                cb.localSp().xspecifyColumn(fkCol.getColumnDbName());
            }
        }

        public List<REFERRER_ENTITY> selRfLs(REFERRER_CB cb) {
            return referrerBhv.readList(cb);
        }

        @SuppressWarnings("unchecked")
        public KEY getFKVal(REFERRER_ENTITY entity) {
            final Map<String, Object> fkMap = xnewLoadReferrerCompoundKeyMap();
            for (ColumnInfo fkCol : fkColSet) {
                final Object fkValue = fkCol.read(entity);
                final ColumnInfo pkCol = mappingColMap.get(fkCol);
                // key is DB name
                final String mapKey = pkCol.getColumnDbName();
                final Class<?> fkType = fkCol.getObjectNativeType();
                final Class<?> pkType = pkCol.getObjectNativeType();
                final Object realValue;
                if (fkType.equals(pkType)) {
                    // basically true
                    realValue = fkValue;
                } else {
                    // different type (needs implicit conversion)
                    realValue = xconvertFK2PKImplicitly(referrerProperty, fkType, pkType, fkValue);
                }
                fkMap.put(mapKey, realValue);
            }
            return (KEY) fkMap;
        }

        public void setlcEt(REFERRER_ENTITY referrerEntity, LOCAL_ENTITY localEntity) {
            // always exists
            final RelationInfo reverseInfo = referrerInfo.getReverseRelation();
            final Object written = xconvertToRelationOptionalEntityIfNeeds(localEntity, reverseInfo);
            reverseInfo.write(referrerEntity, written);
        }

        public String getRfPrNm() {
            return referrerProperty;
        }
    };
}
Also used : ColumnInfo(org.dbflute.dbmeta.info.ColumnInfo) ConditionBean(org.dbflute.cbean.ConditionBean) RelationInfo(org.dbflute.dbmeta.info.RelationInfo) Collection(java.util.Collection) List(java.util.List) ArrayList(java.util.ArrayList) AndQuery(org.dbflute.cbean.scoping.AndQuery) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap)

Example 3 with RelationInfo

use of org.dbflute.dbmeta.info.RelationInfo in project dbflute-core by dbflute.

the class AbstractConditionQuery method xdoBuildReferrerCorrelatedFixedCondition.

protected String xdoBuildReferrerCorrelatedFixedCondition(ConditionQuery subQuery, ReferrerInfo referrerInfo) {
    final RelationInfo reverseRelation = referrerInfo.getReverseRelation();
    if (reverseRelation == null) {
        return null;
    }
    if (!(reverseRelation instanceof ForeignInfo)) {
        String msg = "The reverse relation (referrer's reverse) should be foreign info: " + referrerInfo;
        throw new IllegalStateException(msg);
    }
    final ForeignInfo foreignInfo = (ForeignInfo) reverseRelation;
    final String fixedCondition = foreignInfo.getFixedCondition();
    if (fixedCondition == null || fixedCondition.trim().length() == 0) {
        return null;
    }
    final FixedConditionResolver resolver = createReferrerFixedConditionResolver(subQuery);
    return resolver.resolveVariable(fixedCondition, false);
}
Also used : ForeignInfo(org.dbflute.dbmeta.info.ForeignInfo) FixedConditionResolver(org.dbflute.cbean.sqlclause.join.FixedConditionResolver) RelationInfo(org.dbflute.dbmeta.info.RelationInfo)

Example 4 with RelationInfo

use of org.dbflute.dbmeta.info.RelationInfo in project dbflute-core by dbflute.

the class AbstractBehaviorReadable method xdoBuildReferrerCorrelatedFixedCondition.

protected String xdoBuildReferrerCorrelatedFixedCondition(ConditionBean cb, ReferrerInfo referrerInfo) {
    final RelationInfo reverseRelation = referrerInfo.getReverseRelation();
    if (reverseRelation == null) {
        return null;
    }
    if (!(reverseRelation instanceof ForeignInfo)) {
        String msg = "The reverse relation (referrer's reverse) should be foreign info: " + referrerInfo;
        throw new IllegalStateException(msg);
    }
    final ForeignInfo foreignInfo = (ForeignInfo) reverseRelation;
    final String fixedCondition = foreignInfo.getFixedCondition();
    if (fixedCondition == null || fixedCondition.trim().length() == 0) {
        return null;
    }
    final String localAliasMark = HpFixedConditionQueryResolver.LOCAL_ALIAS_MARK;
    final String basePointAliasName = cb.getSqlClause().getBasePointAliasName();
    return Srl.replace(fixedCondition, localAliasMark, basePointAliasName);
}
Also used : ForeignInfo(org.dbflute.dbmeta.info.ForeignInfo) RelationInfo(org.dbflute.dbmeta.info.RelationInfo)

Example 5 with RelationInfo

use of org.dbflute.dbmeta.info.RelationInfo in project dbflute-core by dbflute.

the class AbstractBehaviorReadable method helpPulloutInternally.

// ===================================================================================
// Pull out Relation
// =================
protected <LOCAL_ENTITY extends Entity, FOREIGN_ENTITY extends Entity> List<FOREIGN_ENTITY> helpPulloutInternally(List<LOCAL_ENTITY> localEntityList, String foreignPropertyName) {
    assertObjectNotNull("localEntityList", localEntityList);
    assertObjectNotNull("foreignPropertyName", foreignPropertyName);
    final DBMeta dbmeta = asDBMeta();
    final ForeignInfo foreignInfo = dbmeta.findForeignInfo(foreignPropertyName);
    final RelationInfo reverseInfo = foreignInfo.getReverseRelation();
    final boolean existsReferrer = reverseInfo != null;
    final RelationOptionalFactory optionalFactory = xgetROpFactory();
    final Map<Integer, FOREIGN_ENTITY> foreignBasicMap = new LinkedHashMap<Integer, FOREIGN_ENTITY>();
    // lazy-loaded
    Map<Integer, List<FOREIGN_ENTITY>> foreignCollisionMap = null;
    final Map<FOREIGN_ENTITY, List<LOCAL_ENTITY>> foreignReferrerMap = new LinkedHashMap<FOREIGN_ENTITY, List<LOCAL_ENTITY>>();
    for (LOCAL_ENTITY localEntity : localEntityList) {
        final FOREIGN_ENTITY foreignEntity = xextractPulloutForeignEntity(foreignInfo, reverseInfo, optionalFactory, localEntity);
        if (foreignEntity == null) {
            continue;
        }
        // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        // basically mapped foreign entities are unique instances
        // but according to circumstances, same PK different instance (rare case)
        // 
        // e.g. normal pattern (no problem)
        // A - M - X
        // B - M - X
        // C - N - X
        // D - O - Y
        // 
        // e.g. when OverRelation, might be following pattern
        // A - M - X
        // B - M - Y *same relation but different nested relation
        // C - N - X
        // D - O - Y
        // 
        // when the latter pattern, the instance of A's M is different from the one of B's M
        // so it need to handle the unique as instance (don't use overridden equals() of entity)
        // _/_/_/_/_/_/_/_/_/_/
        foreignCollisionMap = xsavePulloutForeignEntity(foreignBasicMap, foreignCollisionMap, foreignEntity);
        if (existsReferrer) {
            if (!foreignReferrerMap.containsKey(foreignEntity)) {
                foreignReferrerMap.put(foreignEntity, new ArrayList<LOCAL_ENTITY>());
            }
            foreignReferrerMap.get(foreignEntity).add(localEntity);
        }
    }
    if (existsReferrer) {
        for (Entry<FOREIGN_ENTITY, List<LOCAL_ENTITY>> entry : foreignReferrerMap.entrySet()) {
            final FOREIGN_ENTITY foreignEntity = entry.getKey();
            final List<LOCAL_ENTITY> mappedLocalList = entry.getValue();
            final Object writtenObj = xextractPulloutReverseWrittenObject(foreignInfo, reverseInfo, optionalFactory, mappedLocalList);
            reverseInfo.write(foreignEntity, writtenObj);
        }
    }
    return xpreparePulloutResultList(foreignBasicMap, foreignCollisionMap);
}
Also used : RelationOptionalFactory(org.dbflute.optional.RelationOptionalFactory) LinkedHashMap(java.util.LinkedHashMap) ForeignInfo(org.dbflute.dbmeta.info.ForeignInfo) DBMeta(org.dbflute.dbmeta.DBMeta) RelationInfo(org.dbflute.dbmeta.info.RelationInfo) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

RelationInfo (org.dbflute.dbmeta.info.RelationInfo)6 ArrayList (java.util.ArrayList)3 List (java.util.List)3 ForeignInfo (org.dbflute.dbmeta.info.ForeignInfo)3 Collection (java.util.Collection)2 LinkedHashMap (java.util.LinkedHashMap)2 DBMeta (org.dbflute.dbmeta.DBMeta)2 Map (java.util.Map)1 ConditionBean (org.dbflute.cbean.ConditionBean)1 AndQuery (org.dbflute.cbean.scoping.AndQuery)1 FixedConditionResolver (org.dbflute.cbean.sqlclause.join.FixedConditionResolver)1 ColumnInfo (org.dbflute.dbmeta.info.ColumnInfo)1 ReferrerInfo (org.dbflute.dbmeta.info.ReferrerInfo)1 RelationOptionalFactory (org.dbflute.optional.RelationOptionalFactory)1