protected RelationKey CreateRelationKey(IDataReader reader, IRelationPropertyType rpt , System.Collections.IList columnNames, System.Collections.Hashtable relKeyValues , Map <String, int?> selectIndexMap) { System.Collections.ArrayList keyList = new System.Collections.ArrayList(); IBeanMetaData bmd = rpt.BeanMetaData; for (int i = 0; i < rpt.KeySize; ++i) { IValueType valueType = null; IPropertyType pt = rpt.BeanMetaData.GetPropertyTypeByColumnName(rpt.GetYourKey(i)); String relationNoSuffix = BuildRelationNoSuffix(rpt); String columnName = RemoveQuoteIfExists(pt.ColumnName) + relationNoSuffix; if (columnNames.Contains(columnName)) { valueType = pt.ValueType; } else { // basically unreachable // because the referred column (basically PK or FK) must exist // if the relation's select clause is specified return(null); } Object value; if (selectIndexMap != null) { value = GetValue(reader, columnName, valueType, selectIndexMap); } else { value = valueType.GetValue(reader, columnName); } if (value == null) { // reachable when the referred column data is null // (treated as no relation data) return(null); } relKeyValues[columnName] = value; keyList.Add(value); } if (keyList.Count > 0) { object[] keys = keyList.ToArray(); return(new RelationKey(keys)); } else { return(null); } }
protected override void SetupProperty(Type beanType, IDatabaseMetaData dbMetaData, IDbms dbms) { if (!IsEntity(beanType)) { base.SetupProperty(beanType, dbMetaData, dbms); return; } Entity entity = (Entity)ClassUtil.NewInstance(beanType); DBMeta dbmeta = entity.DBMeta; foreach (PropertyInfo pi in beanType.GetProperties()) { IPropertyType pt = null; RelnoAttribute relnoAttr = _beanAnnotationReader.GetRelnoAttribute(pi); if (relnoAttr != null) { if (!_relation) { IRelationPropertyType rpt = CreateRelationPropertyType(beanType, pi, relnoAttr, dbMetaData, dbms); AddRelationPropertyType(rpt); } } else { if (pi.CanWrite) { pt = CreatePropertyTypeExtension(pi, dbmeta); if (pt != null) { AddPropertyType(pt); if (pt.IsPrimaryKey) { _primaryKeyList.add(pt); } } } } if (IdentifierGenerator == null) { IDAttribute idAttr = _beanAnnotationReader.GetIdAttribute(pi, dbms); if (idAttr != null) { _identifierGenerator = Seasar.Dao.Id.IdentifierGeneratorFactory.CreateIdentifierGenerator(pi.Name, dbms, idAttr); if (pt != null) { _primaryKeys = new string[] { pt.ColumnName }; pt.IsPrimaryKey = true; } } } } }
protected override void SetupRelationKeyValue(RelationRowCreationResource res) { IRelationPropertyType rpt = res.RelationPropertyType; IBeanMetaData bmd = rpt.BeanMetaData; DBMeta dbmeta = FindDBMeta(bmd.BeanType, bmd.TableName); for (int i = 0; i < rpt.KeySize; ++i) { String columnName = rpt.GetMyKey(i) + res.BaseSuffix; if (!res.ContainsColumnName(columnName)) { continue; } if (!res.HasRowInstance()) { Object row; if (dbmeta != null) { row = dbmeta.NewEntity(); } else { row = NewRelationRow(rpt); } res.Row = row; } if (!res.ContainsRelKeyValueIfExists(columnName)) { continue; } Object value = res.ExtractRelKeyValue(columnName); if (value == null) { // basically no way // because this is not called if the referred value // is null (then it must be no relation key) // @see InternalBeanListMetaDataResultSetHandler continue; } String yourKey = rpt.GetYourKey(i); IPropertyType pt = bmd.GetPropertyTypeByColumnName(yourKey); PropertyInfo pi = pt.PropertyInfo; pi.SetValue(res.Row, value, null); continue; } }
protected void Handle(IDataReader dataReader, System.Collections.IList list) { // Lazy initialization because if the result is zero, the resources are unused. System.Collections.IList columnNames = null; IColumnMetaData[] columns = null; IDictionary <String, IDictionary <String, IPropertyType> > relationPropertyCache = null; RelationRowCache relRowCache = null; int relSize = BeanMetaData.RelationPropertyTypeSize; bool hasCB = HasConditionBean(); bool skipRelationLoop; { bool emptyRelation = IsSelectedForeignInfoEmpty(); bool hasOSC = HasOutsideSqlContext(); bool specifiedOutsideSql = IsSpecifiedOutsideSql(); // If it has condition-bean that has no relation to get // or it has outside-sql context that is specified-outside-sql, // they are unnecessary to do relation loop! skipRelationLoop = (hasCB && emptyRelation) || (hasOSC && specifiedOutsideSql); } bool canCache = hasCB && CanRelationMappingCache(); Map <String, int?> selectIndexMap = GetSelectIndexMap(); while (dataReader.Read()) { if (columnNames == null) { columnNames = CreateColumnNames(dataReader.GetSchemaTable()); } if (columns == null) { columns = CreateColumnMetaData(columnNames); } // Create row instance of base table by row property cache. Object row = CreateRow(dataReader, columns); if (skipRelationLoop) { PostCreateRow(row, BeanMetaData); list.Add(row); continue; } if (relationPropertyCache == null) { relationPropertyCache = CreateRelationPropertyCache(columnNames); } if (relRowCache == null) { relRowCache = new RelationRowCache(relSize); } for (int i = 0; i < relSize; ++i) { IRelationPropertyType rpt = BeanMetaData.GetRelationPropertyType(i); if (rpt == null) { continue; } // Do only selected foreign property for performance if condition-bean exists. if (hasCB && !HasSelectedForeignInfo(BuildRelationNoSuffix(rpt))) { continue; } Object relationRow = null; System.Collections.Hashtable relKeyValues = new System.Collections.Hashtable(); RelationKey relKey = CreateRelationKey(dataReader, rpt, columnNames, relKeyValues, selectIndexMap); if (relKey != null) { relationRow = GetCachedRelationRow(relRowCache, i, relKey, canCache); if (relationRow == null) { relationRow = CreateRelationRow(dataReader, rpt, columnNames, relKeyValues, relationPropertyCache); if (relationRow != null) { AddRelationRowCache(relRowCache, i, relKey, relationRow, canCache); PostCreateRow(relationRow, rpt.BeanMetaData); } } } if (relationRow != null) { PropertyInfo pi = rpt.PropertyInfo; pi.SetValue(row, relationRow, null); } } PostCreateRow(row, BeanMetaData); list.Add(row); } }
protected String BuildRelationNoSuffix(IRelationPropertyType rpt) { return("_" + rpt.RelationNo); }
protected virtual Object CreateRelationRow(IRelationPropertyType rpt) { return(ClassUtil.NewInstance(rpt.PropertyInfo.PropertyType)); }
protected virtual Object CreateRelationRow(IDataReader reader, IRelationPropertyType rpt, System.Collections.IList columnNames, System.Collections.Hashtable relKeyValues, IDictionary <String, IDictionary <String, IPropertyType> > relationColumnMetaDataCache) { return(_relationRowCreator.CreateRelationRow(reader, rpt, columnNames, relKeyValues, relationColumnMetaDataCache)); }