Mercurial > pub > bltoolkit
diff Extensions/JointureAddOn/DataAccess/FullSqlQueryBase.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Extensions/JointureAddOn/DataAccess/FullSqlQueryBase.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,280 @@ +using System; +using System.Collections; +using System.Linq; +using System.Reflection; +using System.Text; +using BLToolkit.Aspects; +using BLToolkit.Data; +using BLToolkit.Data.DataProvider; +using BLToolkit.Mapping; +using BLToolkit.TypeBuilder; + +namespace BLToolkit.DataAccess +{ + public abstract class FullSqlQueryBase : SqlQueryBase + { + private readonly bool _ignoreLazyLoad; + + #region Constructors + + protected FullSqlQueryBase(DbManager dbManager, bool ignoreLazyLoad = false, MappingOrder mappingOrder = MappingOrder.ByColumnIndex) + : base(dbManager) + { + dbManager.MappingSchema = new FullMappingSchema(dbManager, mappingOrder: mappingOrder); + + _ignoreLazyLoad = ignoreLazyLoad; + } + + #endregion + + #region Overrides + + [NoInterception] + protected override SqlQueryInfo CreateSqlText(DbManager db, Type type, string actionName) + { + switch (actionName) + { + case "SelectByKey": + return CreateSelectFullByKeySqlText(db, type); + case "SelectAll": + return CreateSelectAllFullSqlText(db, type); + default: + return base.CreateSqlText(db, type, actionName); + } + } + + protected override void AppendTableName(StringBuilder sb, DbManager db, Type type) + { + var database = GetDatabaseName(type); + var owner = GetOwnerName(type); + var name = base.GetTableName(type); + + db.DataProvider.CreateSqlProvider().BuildTableName(sb, + database == null ? null : db.DataProvider.Convert(database, ConvertType.NameToDatabase).ToString(), + owner == null ? null : db.DataProvider.Convert(owner, ConvertType.NameToOwner).ToString(), + name == null ? null : db.DataProvider.Convert(name, ConvertType.NameToQueryTable).ToString()); + + //TODO Override OracleSqlProvider in order to avoid this mess... + string alias = GetTableName(type); + sb.Append(" " + alias); + sb.AppendLine(); + } + + protected override string GetTableName(Type type) + { + //bool isSet; + //return MappingSchema.MetadataProvider.GetTableName(type, Extensions, out isSet); + + return type.Name; + } + + #endregion + + private SqlQueryInfo CreateSelectAllFullSqlText(DbManager db, Type type) + { + var sb = new StringBuilder(); + var query = new FullSqlQueryInfo(); + + sb.Append("SELECT\n"); + + var mainMapper = (FullObjectMapper)db.MappingSchema.GetObjectMapper(type); ; + BuildSelectSQL(mainMapper, sb, db); + + sb.Remove(sb.Length - 2, 1); + + sb.Append("FROM\n\t"); + + AppendTableName(sb, db, type); + + AppendJoinTableName(sb, db, type); + + query.QueryText = sb.ToString(); + + return query; + } + + private SqlQueryInfo CreateSelectFullByKeySqlText(DbManager db, Type type) + { + var sb = new StringBuilder(); + var query = new FullSqlQueryInfo(); + + sb.Append("SELECT\n"); + + var mainMapper = (FullObjectMapper)db.MappingSchema.GetObjectMapper(type); + + BuildSelectSQL(mainMapper, sb, db); + + sb.Remove(sb.Length - 2, 1); + + sb.Append("FROM\n\t"); + + AppendTableName(sb, db, type); + + AppendJoinTableName(sb, db, type); + + AddWherePK(db, query, sb, -1, mainMapper); + + query.QueryText = sb.ToString(); + + return query; + } + + private void BuildSelectSQL(IPropertiesMapping mapper, StringBuilder sb, DbManager db) + { + foreach (IMapper mapField in mapper.PropertiesMapping) + { + if (mapField is ValueMapper) + sb.AppendFormat("\t{0}.{1},\n", ((IObjectMapper)mapper).PropertyType.Name, + db.DataProvider.Convert(((ValueMapper)mapField).ColumnName, ConvertType.NameToQueryField)); + else if (mapField is IPropertiesMapping) + { + var propertiesMapping = (IPropertiesMapping)mapField; + var cel = propertiesMapping.ParentMapping; + while (cel != null) + { + // To avoid recursion dont take in account types already loaded. + if (((IMapper)cel).PropertyType == mapField.PropertyType) + continue; + cel = cel.ParentMapping; + } + var objectMapper = (IObjectMapper)mapField; + if (!objectMapper.IsLazy) + BuildSelectSQL(propertiesMapping, sb, db); + } + else + throw new NotImplementedException(mapField.GetType() + " is not yet implemented."); + } + } + + private void AppendJoinTableName(StringBuilder sb, DbManager db, Type type) + { + string parentName = GetTableName(type); + + foreach (PropertyInfo prop in type.GetProperties()) + { + bool isCollection = prop.PropertyType.GetInterfaces().ToList().Contains(typeof(IList)); + Type listElementType = null; + if (isCollection) + { + listElementType = FullMappingSchema.GetGenericType(prop.PropertyType); + } + + if (!_ignoreLazyLoad) + { + object[] lazy = prop.GetCustomAttributes(typeof(LazyInstanceAttribute), true); + if (lazy.Length > 0) + { + if (((LazyInstanceAttribute)lazy[0]).IsLazy) + { + continue; + } + } + } + + object[] attribs = prop.GetCustomAttributes(typeof(AssociationAttribute), true); + if (attribs.Length > 0) + { + var assocAttrib = (AssociationAttribute)attribs[0]; + + PropertyInfo parentField = type.GetProperty(assocAttrib.ThisKey); + PropertyInfo childField = prop.PropertyType.GetProperty(assocAttrib.OtherKey); + if (isCollection) + { + childField = listElementType.GetProperty(assocAttrib.OtherKey); + //FullMappingSchema.GetColumnFromProperty(listElementType, associationAttribute.OtherKey); + } + + object[] parentFieldAttributes = parentField.GetCustomAttributes(typeof(MapFieldAttribute), true); + string parentDbField = parentFieldAttributes.Length > 0 + ? ((MapFieldAttribute)parentFieldAttributes[0]).MapName + : assocAttrib.ThisKey; + + object[] childFieldAttributes = childField.GetCustomAttributes(typeof(MapFieldAttribute), true); + string childDbField = childFieldAttributes.Length > 0 + ? ((MapFieldAttribute)childFieldAttributes[0]).MapName + : assocAttrib.OtherKey; + + + string childDatabase = isCollection + ? GetDatabaseName(listElementType) + : GetDatabaseName(prop.PropertyType); + + string childOwner = isCollection ? base.GetOwnerName(listElementType) : base.GetOwnerName(prop.PropertyType); + string childName = isCollection ? base.GetTableName(listElementType) : base.GetTableName(prop.PropertyType); + string childAlias = isCollection ? GetTableName(listElementType) : GetTableName(prop.PropertyType); + + StringBuilder childFullName = db.DataProvider.CreateSqlProvider().BuildTableName( + new StringBuilder(), + childDatabase == null + ? null + : db.DataProvider.Convert(childDatabase, ConvertType.NameToDatabase).ToString(), + childOwner == null + ? null + : db.DataProvider.Convert(childOwner, ConvertType.NameToOwner).ToString(), + childName == null + ? null + : db.DataProvider.Convert(childName, ConvertType.NameToQueryTable).ToString()); + + sb.AppendFormat("\tINNER JOIN {0} {1} ON {2}.{3}={4}.{5}\n", + childFullName, + childAlias, + parentName, + parentDbField, + childAlias, + childDbField + ); + + AppendJoinTableName(sb, db, isCollection ? listElementType : prop.PropertyType); + } + } + + sb.AppendLine(); + + //SELECT + // ARTIST2.ID_ARTIST, + // ARTIST2.ARTIST, + // TRACK.ID_TRACK, + // TRACK.TRACK, + // TRACK.ID_ARTIST, + // ARTIST.ID_ARTIST, + // ARTIST.ARTIST + //FROM + // PITAFR01.ARTIST ARTIST2 + // INNER JOIN PITAFR01.TRACK TRACK ON ARTIST2.ID_ARTIST=TRACK.ID_ARTIST + // INNER JOIN PITAFR01.ARTIST ARTIST ON TRACK.ID_ARTIST=ARTIST.ID_ARTIST + //WHERE + // ARTIST2.ID_ARTIST = 2566 + } + + private void AddWherePK(DbManager db, SqlQueryInfo query, StringBuilder sb, int nParameter, + FullObjectMapper mapper) + { + sb.Append("WHERE\n"); + + foreach (IMapper mm in mapper.PropertiesMapping) + { + if (mm is ValueMapper && mm.DataReaderIndex == mapper.DataReaderIndex) + { + var valueMapper = (ValueMapper)mm; + + string tableAlias = mapper.PropertyType.Name; + + //mm.Name = ID_TRACK + SqlQueryParameterInfo p = query.AddParameter( + db.DataProvider.Convert(valueMapper.ColumnName + "_W", ConvertType.NameToQueryParameter). + ToString(), + valueMapper.ColumnName); + + sb.AppendFormat("\t{0}.{1} = ", tableAlias, db.DataProvider.Convert(p.FieldName, ConvertType.NameToQueryField)); + + if (nParameter < 0) + sb.AppendFormat("{0} AND\n", p.ParameterName); + else + sb.AppendFormat("{{{0}}} AND\n", nParameter++); + } + } + + sb.Remove(sb.Length - 5, 5); + } + } +} \ No newline at end of file