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