| 
0
 | 
     1 using System;
 | 
| 
 | 
     2 using System.Collections;
 | 
| 
 | 
     3 using System.Linq;
 | 
| 
 | 
     4 using System.Reflection;
 | 
| 
 | 
     5 using System.Text;
 | 
| 
 | 
     6 using BLToolkit.Aspects;
 | 
| 
 | 
     7 using BLToolkit.Data;
 | 
| 
 | 
     8 using BLToolkit.Data.DataProvider;
 | 
| 
 | 
     9 using BLToolkit.Mapping;
 | 
| 
 | 
    10 using BLToolkit.TypeBuilder;
 | 
| 
 | 
    11 
 | 
| 
 | 
    12 namespace BLToolkit.DataAccess
 | 
| 
 | 
    13 {
 | 
| 
 | 
    14     public abstract class FullSqlQueryBase : SqlQueryBase
 | 
| 
 | 
    15     {
 | 
| 
 | 
    16         private readonly bool _ignoreLazyLoad;
 | 
| 
 | 
    17 
 | 
| 
 | 
    18         #region Constructors
 | 
| 
 | 
    19 
 | 
| 
 | 
    20         protected FullSqlQueryBase(DbManager dbManager, bool ignoreLazyLoad = false, MappingOrder mappingOrder = MappingOrder.ByColumnIndex)
 | 
| 
 | 
    21             : base(dbManager)
 | 
| 
 | 
    22         {
 | 
| 
 | 
    23             dbManager.MappingSchema = new FullMappingSchema(dbManager, mappingOrder: mappingOrder);
 | 
| 
 | 
    24 
 | 
| 
 | 
    25             _ignoreLazyLoad = ignoreLazyLoad;
 | 
| 
 | 
    26         }
 | 
| 
 | 
    27 
 | 
| 
 | 
    28         #endregion
 | 
| 
 | 
    29 
 | 
| 
 | 
    30         #region Overrides
 | 
| 
 | 
    31 
 | 
| 
 | 
    32         [NoInterception]
 | 
| 
 | 
    33         protected override SqlQueryInfo CreateSqlText(DbManager db, Type type, string actionName)
 | 
| 
 | 
    34         {
 | 
| 
 | 
    35             switch (actionName)
 | 
| 
 | 
    36             {
 | 
| 
 | 
    37                 case "SelectByKey":
 | 
| 
 | 
    38                     return CreateSelectFullByKeySqlText(db, type);
 | 
| 
 | 
    39                 case "SelectAll":
 | 
| 
 | 
    40                     return CreateSelectAllFullSqlText(db, type);
 | 
| 
 | 
    41                 default:
 | 
| 
 | 
    42                     return base.CreateSqlText(db, type, actionName);
 | 
| 
 | 
    43             }
 | 
| 
 | 
    44         }
 | 
| 
 | 
    45         
 | 
| 
 | 
    46         protected override void AppendTableName(StringBuilder sb, DbManager db, Type type)
 | 
| 
 | 
    47         {
 | 
| 
 | 
    48             var database = GetDatabaseName(type);
 | 
| 
 | 
    49             var owner = GetOwnerName(type);
 | 
| 
 | 
    50             var name = base.GetTableName(type);
 | 
| 
 | 
    51 
 | 
| 
 | 
    52             db.DataProvider.CreateSqlProvider().BuildTableName(sb,
 | 
| 
 | 
    53                                                                database == null ? null : db.DataProvider.Convert(database, ConvertType.NameToDatabase).ToString(),
 | 
| 
 | 
    54                                                                owner == null ? null : db.DataProvider.Convert(owner, ConvertType.NameToOwner).ToString(),
 | 
| 
 | 
    55                                                                name == null ? null : db.DataProvider.Convert(name, ConvertType.NameToQueryTable).ToString());
 | 
| 
 | 
    56 
 | 
| 
 | 
    57             //TODO Override OracleSqlProvider in order to avoid this mess...
 | 
| 
 | 
    58             string alias = GetTableName(type);
 | 
| 
 | 
    59             sb.Append(" " + alias);
 | 
| 
 | 
    60             sb.AppendLine();
 | 
| 
 | 
    61         }
 | 
| 
 | 
    62 
 | 
| 
 | 
    63         protected override string GetTableName(Type type)
 | 
| 
 | 
    64         {
 | 
| 
 | 
    65             //bool isSet;
 | 
| 
 | 
    66             //return MappingSchema.MetadataProvider.GetTableName(type, Extensions, out isSet);
 | 
| 
 | 
    67 
 | 
| 
 | 
    68             return type.Name;
 | 
| 
 | 
    69         }
 | 
| 
 | 
    70 
 | 
| 
 | 
    71         #endregion
 | 
| 
 | 
    72 
 | 
| 
 | 
    73         private SqlQueryInfo CreateSelectAllFullSqlText(DbManager db, Type type)
 | 
| 
 | 
    74         {
 | 
| 
 | 
    75             var sb = new StringBuilder();
 | 
| 
 | 
    76             var query = new FullSqlQueryInfo();
 | 
| 
 | 
    77 
 | 
| 
 | 
    78             sb.Append("SELECT\n");
 | 
| 
 | 
    79 
 | 
| 
 | 
    80             var mainMapper = (FullObjectMapper)db.MappingSchema.GetObjectMapper(type); ;
 | 
| 
 | 
    81             BuildSelectSQL(mainMapper, sb, db);
 | 
| 
 | 
    82 
 | 
| 
 | 
    83             sb.Remove(sb.Length - 2, 1);
 | 
| 
 | 
    84 
 | 
| 
 | 
    85             sb.Append("FROM\n\t");
 | 
| 
 | 
    86 
 | 
| 
 | 
    87             AppendTableName(sb, db, type);
 | 
| 
 | 
    88 
 | 
| 
 | 
    89             AppendJoinTableName(sb, db, type);
 | 
| 
 | 
    90 
 | 
| 
 | 
    91             query.QueryText = sb.ToString();
 | 
| 
 | 
    92 
 | 
| 
 | 
    93             return query;
 | 
| 
 | 
    94         }
 | 
| 
 | 
    95 
 | 
| 
 | 
    96         private SqlQueryInfo CreateSelectFullByKeySqlText(DbManager db, Type type)
 | 
| 
 | 
    97         {
 | 
| 
 | 
    98             var sb = new StringBuilder();
 | 
| 
 | 
    99             var query = new FullSqlQueryInfo();
 | 
| 
 | 
   100 
 | 
| 
 | 
   101             sb.Append("SELECT\n");
 | 
| 
 | 
   102 
 | 
| 
 | 
   103             var mainMapper = (FullObjectMapper)db.MappingSchema.GetObjectMapper(type);
 | 
| 
 | 
   104 
 | 
| 
 | 
   105             BuildSelectSQL(mainMapper, sb, db);
 | 
| 
 | 
   106 
 | 
| 
 | 
   107             sb.Remove(sb.Length - 2, 1);
 | 
| 
 | 
   108 
 | 
| 
 | 
   109             sb.Append("FROM\n\t");
 | 
| 
 | 
   110 
 | 
| 
 | 
   111             AppendTableName(sb, db, type);
 | 
| 
 | 
   112 
 | 
| 
 | 
   113             AppendJoinTableName(sb, db, type);
 | 
| 
 | 
   114 
 | 
| 
 | 
   115             AddWherePK(db, query, sb, -1, mainMapper);
 | 
| 
 | 
   116 
 | 
| 
 | 
   117             query.QueryText = sb.ToString();
 | 
| 
 | 
   118 
 | 
| 
 | 
   119             return query;
 | 
| 
 | 
   120         }
 | 
| 
 | 
   121 
 | 
| 
 | 
   122         private void BuildSelectSQL(IPropertiesMapping mapper, StringBuilder sb, DbManager db)
 | 
| 
 | 
   123         {
 | 
| 
 | 
   124             foreach (IMapper mapField in mapper.PropertiesMapping)
 | 
| 
 | 
   125             {
 | 
| 
 | 
   126                 if (mapField is ValueMapper)
 | 
| 
 | 
   127                     sb.AppendFormat("\t{0}.{1},\n", ((IObjectMapper)mapper).PropertyType.Name,
 | 
| 
 | 
   128                                     db.DataProvider.Convert(((ValueMapper)mapField).ColumnName, ConvertType.NameToQueryField));
 | 
| 
 | 
   129                 else if (mapField is IPropertiesMapping)
 | 
| 
 | 
   130                 {
 | 
| 
 | 
   131                     var propertiesMapping = (IPropertiesMapping)mapField;
 | 
| 
 | 
   132                     var cel = propertiesMapping.ParentMapping;
 | 
| 
 | 
   133                     while (cel != null)
 | 
| 
 | 
   134                     {
 | 
| 
 | 
   135                         // To avoid recursion dont take in account types already loaded.
 | 
| 
 | 
   136                         if (((IMapper)cel).PropertyType == mapField.PropertyType)
 | 
| 
 | 
   137                             continue;
 | 
| 
 | 
   138                         cel = cel.ParentMapping;
 | 
| 
 | 
   139                     }
 | 
| 
 | 
   140                     var objectMapper = (IObjectMapper)mapField;
 | 
| 
 | 
   141                     if (!objectMapper.IsLazy)
 | 
| 
 | 
   142                         BuildSelectSQL(propertiesMapping, sb, db);
 | 
| 
 | 
   143                 }
 | 
| 
 | 
   144                 else
 | 
| 
 | 
   145                     throw new NotImplementedException(mapField.GetType() + " is not yet implemented.");
 | 
| 
 | 
   146             }
 | 
| 
 | 
   147         }
 | 
| 
 | 
   148 
 | 
| 
 | 
   149         private void AppendJoinTableName(StringBuilder sb, DbManager db, Type type)
 | 
| 
 | 
   150         {
 | 
| 
 | 
   151             string parentName = GetTableName(type);
 | 
| 
 | 
   152 
 | 
| 
 | 
   153             foreach (PropertyInfo prop in type.GetProperties())
 | 
| 
 | 
   154             {
 | 
| 
 | 
   155                 bool isCollection = prop.PropertyType.GetInterfaces().ToList().Contains(typeof(IList));
 | 
| 
 | 
   156                 Type listElementType = null;
 | 
| 
 | 
   157                 if (isCollection)
 | 
| 
 | 
   158                 {
 | 
| 
 | 
   159                     listElementType = FullMappingSchema.GetGenericType(prop.PropertyType);
 | 
| 
 | 
   160                 }
 | 
| 
 | 
   161 
 | 
| 
 | 
   162                 if (!_ignoreLazyLoad)
 | 
| 
 | 
   163                 {
 | 
| 
 | 
   164                     object[] lazy = prop.GetCustomAttributes(typeof(LazyInstanceAttribute), true);
 | 
| 
 | 
   165                     if (lazy.Length > 0)
 | 
| 
 | 
   166                     {
 | 
| 
 | 
   167                         if (((LazyInstanceAttribute)lazy[0]).IsLazy)
 | 
| 
 | 
   168                         {
 | 
| 
 | 
   169                             continue;
 | 
| 
 | 
   170                         }
 | 
| 
 | 
   171                     }
 | 
| 
 | 
   172                 }
 | 
| 
 | 
   173 
 | 
| 
 | 
   174                 object[] attribs = prop.GetCustomAttributes(typeof(AssociationAttribute), true);
 | 
| 
 | 
   175                 if (attribs.Length > 0)
 | 
| 
 | 
   176                 {
 | 
| 
 | 
   177                     var assocAttrib = (AssociationAttribute)attribs[0];
 | 
| 
 | 
   178 
 | 
| 
 | 
   179                     PropertyInfo parentField = type.GetProperty(assocAttrib.ThisKey);
 | 
| 
 | 
   180                     PropertyInfo childField = prop.PropertyType.GetProperty(assocAttrib.OtherKey);
 | 
| 
 | 
   181                     if (isCollection)
 | 
| 
 | 
   182                     {
 | 
| 
 | 
   183                         childField = listElementType.GetProperty(assocAttrib.OtherKey);
 | 
| 
 | 
   184                         //FullMappingSchema.GetColumnFromProperty(listElementType, associationAttribute.OtherKey);
 | 
| 
 | 
   185                     }
 | 
| 
 | 
   186 
 | 
| 
 | 
   187                     object[] parentFieldAttributes = parentField.GetCustomAttributes(typeof(MapFieldAttribute), true);
 | 
| 
 | 
   188                     string parentDbField = parentFieldAttributes.Length > 0
 | 
| 
 | 
   189                                                ? ((MapFieldAttribute)parentFieldAttributes[0]).MapName
 | 
| 
 | 
   190                                                : assocAttrib.ThisKey;
 | 
| 
 | 
   191 
 | 
| 
 | 
   192                     object[] childFieldAttributes = childField.GetCustomAttributes(typeof(MapFieldAttribute), true);
 | 
| 
 | 
   193                     string childDbField = childFieldAttributes.Length > 0
 | 
| 
 | 
   194                                               ? ((MapFieldAttribute)childFieldAttributes[0]).MapName
 | 
| 
 | 
   195                                               : assocAttrib.OtherKey;
 | 
| 
 | 
   196 
 | 
| 
 | 
   197 
 | 
| 
 | 
   198                     string childDatabase = isCollection
 | 
| 
 | 
   199                                                ? GetDatabaseName(listElementType)
 | 
| 
 | 
   200                                                : GetDatabaseName(prop.PropertyType);
 | 
| 
 | 
   201 
 | 
| 
 | 
   202                     string childOwner = isCollection ? base.GetOwnerName(listElementType) : base.GetOwnerName(prop.PropertyType);
 | 
| 
 | 
   203                     string childName = isCollection ? base.GetTableName(listElementType) : base.GetTableName(prop.PropertyType);
 | 
| 
 | 
   204                     string childAlias = isCollection ? GetTableName(listElementType) : GetTableName(prop.PropertyType);
 | 
| 
 | 
   205 
 | 
| 
 | 
   206                     StringBuilder childFullName = db.DataProvider.CreateSqlProvider().BuildTableName(
 | 
| 
 | 
   207                         new StringBuilder(),
 | 
| 
 | 
   208                         childDatabase == null
 | 
| 
 | 
   209                             ? null
 | 
| 
 | 
   210                             : db.DataProvider.Convert(childDatabase, ConvertType.NameToDatabase).ToString(),
 | 
| 
 | 
   211                         childOwner == null
 | 
| 
 | 
   212                             ? null
 | 
| 
 | 
   213                             : db.DataProvider.Convert(childOwner, ConvertType.NameToOwner).ToString(),
 | 
| 
 | 
   214                         childName == null
 | 
| 
 | 
   215                             ? null
 | 
| 
 | 
   216                             : db.DataProvider.Convert(childName, ConvertType.NameToQueryTable).ToString());
 | 
| 
 | 
   217 
 | 
| 
 | 
   218                     sb.AppendFormat("\tINNER JOIN {0} {1} ON {2}.{3}={4}.{5}\n",
 | 
| 
 | 
   219                                     childFullName,
 | 
| 
 | 
   220                                     childAlias,
 | 
| 
 | 
   221                                     parentName,
 | 
| 
 | 
   222                                     parentDbField,
 | 
| 
 | 
   223                                     childAlias,
 | 
| 
 | 
   224                                     childDbField
 | 
| 
 | 
   225                         );
 | 
| 
 | 
   226 
 | 
| 
 | 
   227                     AppendJoinTableName(sb, db, isCollection ? listElementType : prop.PropertyType);
 | 
| 
 | 
   228                 }
 | 
| 
 | 
   229             }
 | 
| 
 | 
   230 
 | 
| 
 | 
   231             sb.AppendLine();
 | 
| 
 | 
   232 
 | 
| 
 | 
   233             //SELECT
 | 
| 
 | 
   234             //    ARTIST2.ID_ARTIST,
 | 
| 
 | 
   235             //    ARTIST2.ARTIST,
 | 
| 
 | 
   236             //    TRACK.ID_TRACK,
 | 
| 
 | 
   237             //    TRACK.TRACK,
 | 
| 
 | 
   238             //    TRACK.ID_ARTIST,
 | 
| 
 | 
   239             //    ARTIST.ID_ARTIST,
 | 
| 
 | 
   240             //    ARTIST.ARTIST
 | 
| 
 | 
   241             //FROM
 | 
| 
 | 
   242             //    PITAFR01.ARTIST ARTIST2
 | 
| 
 | 
   243             //    INNER JOIN PITAFR01.TRACK TRACK ON ARTIST2.ID_ARTIST=TRACK.ID_ARTIST
 | 
| 
 | 
   244             //    INNER JOIN PITAFR01.ARTIST ARTIST ON TRACK.ID_ARTIST=ARTIST.ID_ARTIST
 | 
| 
 | 
   245             //WHERE
 | 
| 
 | 
   246             //    ARTIST2.ID_ARTIST = 2566
 | 
| 
 | 
   247         }
 | 
| 
 | 
   248 
 | 
| 
 | 
   249         private void AddWherePK(DbManager db, SqlQueryInfo query, StringBuilder sb, int nParameter,
 | 
| 
 | 
   250                                 FullObjectMapper mapper)
 | 
| 
 | 
   251         {
 | 
| 
 | 
   252             sb.Append("WHERE\n");
 | 
| 
 | 
   253 
 | 
| 
 | 
   254             foreach (IMapper mm in mapper.PropertiesMapping)
 | 
| 
 | 
   255             {
 | 
| 
 | 
   256                 if (mm is ValueMapper && mm.DataReaderIndex == mapper.DataReaderIndex)
 | 
| 
 | 
   257                 {
 | 
| 
 | 
   258                     var valueMapper = (ValueMapper)mm;
 | 
| 
 | 
   259 
 | 
| 
 | 
   260                     string tableAlias = mapper.PropertyType.Name;
 | 
| 
 | 
   261 
 | 
| 
 | 
   262                     //mm.Name = ID_TRACK
 | 
| 
 | 
   263                     SqlQueryParameterInfo p = query.AddParameter(
 | 
| 
 | 
   264                         db.DataProvider.Convert(valueMapper.ColumnName + "_W", ConvertType.NameToQueryParameter).
 | 
| 
 | 
   265                             ToString(),
 | 
| 
 | 
   266                         valueMapper.ColumnName);
 | 
| 
 | 
   267 
 | 
| 
 | 
   268                     sb.AppendFormat("\t{0}.{1} = ", tableAlias, db.DataProvider.Convert(p.FieldName, ConvertType.NameToQueryField));
 | 
| 
 | 
   269 
 | 
| 
 | 
   270                     if (nParameter < 0)
 | 
| 
 | 
   271                         sb.AppendFormat("{0} AND\n", p.ParameterName);
 | 
| 
 | 
   272                     else
 | 
| 
 | 
   273                         sb.AppendFormat("{{{0}}} AND\n", nParameter++);
 | 
| 
 | 
   274                 }
 | 
| 
 | 
   275             }
 | 
| 
 | 
   276 
 | 
| 
 | 
   277             sb.Remove(sb.Length - 5, 5);
 | 
| 
 | 
   278         }
 | 
| 
 | 
   279     }
 | 
| 
 | 
   280 } |