diff Extensions/JointureAddOn/DataAccess/FullSqlQuery.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/FullSqlQuery.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,289 @@
+#region
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using BLToolkit.Aspects;
+using BLToolkit.Data;
+using BLToolkit.Data.DataProvider;
+using BLToolkit.Mapping;
+
+#endregion
+
+namespace BLToolkit.DataAccess
+{
+    public class FullSqlQuery : SqlQuery
+    {
+        private readonly bool _ignoreLazyLoad;
+
+        #region Constructors
+
+        public FullSqlQuery(DbManager dbManager, bool ignoreLazyLoad = false, FactoryType factoryType = FactoryType.LazyLoading)
+            : base(dbManager)
+        {
+            dbManager.MappingSchema = new FullMappingSchema(dbManager, ignoreLazyLoad, dbManager.MappingSchema, factoryType);
+
+            _ignoreLazyLoad = ignoreLazyLoad;
+        }
+
+        #endregion
+
+        #region Overrides
+
+        private readonly Hashtable _actionSqlQueryInfo = new Hashtable();
+
+        [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);
+            }
+        }
+
+        [NoInterception]
+        public override SqlQueryInfo GetSqlQueryInfo(DbManager db, Type type, string actionName)
+        {
+            var key = type.FullName + "$" + actionName + "$" + db.DataProvider.UniqueName + "$" + GetTableName(type);
+            var query = (SqlQueryInfo) _actionSqlQueryInfo[key];
+
+            if (query == null)
+            {
+                query = CreateSqlText(db, type, actionName);
+                _actionSqlQueryInfo[key] = query;
+            }
+
+            return query;
+        }
+
+        #endregion
+
+        #region Private methods
+
+        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");
+
+            FullAppendTableName(sb, db, type);
+
+            AppendJoinTableName(mainMapper, 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");
+
+            FullAppendTableName(sb, db, type);
+
+            AppendJoinTableName(mainMapper, sb, db, type);
+
+            AddWherePK(db, query, sb, -1, mainMapper);
+
+            query.QueryText = sb.ToString();
+
+            return query;
+        }
+
+        private void FullAppendTableName(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 = FullGetTableName(type);
+            sb.Append(" " + "T" /*alias*/);
+            sb.AppendLine();
+        }
+
+        private string FullGetTableName(Type type)
+        {
+            //bool isSet;
+            //return MappingSchema.MetadataProvider.GetTableName(type, Extensions, out isSet);
+
+            return type.Name;
+        }
+
+        private void BuildSelectSql(IObjectMapper mapper, StringBuilder sb, DbManager db, string tableName = "T")
+        {
+            int tableNr = 0;
+
+            foreach (IMapper mapField in mapper.PropertiesMapping)
+            {
+                if (mapField is ValueMapper)
+                    sb.AppendFormat("\t{0}.{1} {2},\n"
+                                    , tableName /* (mapper).PropertyType.Name */,
+                                    db.DataProvider.Convert(((ValueMapper) mapField).ColumnName, ConvertType.NameToQueryField),
+                                    ((ValueMapper) mapField).ColumnAlias
+                        );
+                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(objectMapper, sb, db, tableName + tableNr.ToString());
+
+                    tableNr++;
+                }
+                else
+                    throw new NotImplementedException(mapField.GetType() + " is not yet implemented.");
+            }
+        }
+
+        private void AppendJoinTableName(IPropertiesMapping mapper, StringBuilder sb, DbManager db, Type type, string tableName = "T")
+        {
+            string parentName = FullGetTableName(type);
+            Dictionary<string, ValueMapper> valueMappers = mapper.PropertiesMapping.Where(e => e is ValueMapper).Cast<ValueMapper>().ToDictionary(e => e.PropertyName, e => e);
+
+            int tableNr = 0;
+
+            foreach (IMapper mapField in mapper.PropertiesMapping)
+            {
+                var objectMapper = mapField as IObjectMapper;
+                if (objectMapper != null)
+                {
+                    if (!_ignoreLazyLoad)
+                    {
+                        if (objectMapper.IsLazy)
+                            continue;
+                    }
+
+                    string thisKey = objectMapper.Association.ThisKey[0];
+
+                    // TITLE
+                    string parentDbField = valueMappers.ContainsKey(thisKey) ? valueMappers[thisKey].ColumnName : thisKey;
+
+                    // ARTIST
+                    string childDbField = objectMapper.PropertiesMapping.Where(e => e is ValueMapper).Cast<ValueMapper>().First(
+                        e => e.PropertyName == objectMapper.Association.OtherKey[0]).ColumnName;
+
+                    string childDatabase = GetDatabaseName(mapField.PropertyType);
+                    string childOwner = base.GetOwnerName(mapField.PropertyType);
+                    string childName = base.GetTableName(mapField.PropertyType);
+                    string childAlias = FullGetTableName(mapField.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("\tFULL OUTER JOIN {0} {1} ON {2}.{3}={4}.{5}\n",
+                                    childFullName,
+                                    tableName + tableNr.ToString() /*childAlias*/,
+                                    tableName /*parentName*/,
+                                    parentDbField,
+                                    tableName + tableNr.ToString() /*childAlias*/,
+                                    childDbField
+                        );
+                    
+                    AppendJoinTableName((IPropertiesMapping)mapField, sb, db, mapField.PropertyType, tableName + tableNr.ToString());
+                    
+                    tableNr++;
+                }
+            }
+
+            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} = ", "T" /* 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);
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file