Example #1
0
 public virtual EagarDataRecord[] Transform(EagarDataRecord[] readers, Type entityType, QueryProcessingRecordsContext context)
 {
     return(readers);
 }
Example #2
0
        public EagarDataRecord[] DoJoinMapping(
            EagarDataRecord[] readers,
            QueryIdentifier sourceAlias,
            QueryProcessingRecordsContext context,
            bool sourceJoin = true,
            bool toplevel   = false)
        {
            foreach (var mapping in Mappings
                     .Where(e => sourceJoin ? e.SourceAlias.Equals(sourceAlias) : e.TargetAlias.Equals(sourceAlias)).ToArray())
            {
                var targetColumnsIndexMapping = new Dictionary <ColumnInfo, int>();
                var sourceColumnsIndexMapping = new Dictionary <ColumnInfo, int>();
                var targetColumns             = mapping.TargetColumns.ToArray();
                for (int index = 0; index < targetColumns.Length; index++)
                {
                    var columnInfo = targetColumns[index];

                    if (targetColumnsIndexMapping.ContainsKey(columnInfo))
                    {
                        throw new InvalidOperationException($"1Error while mapping columns. Column: '{columnInfo.NaturalName}' exists")
                              {
                                  Data = { { "Columns", targetColumnsIndexMapping } }
                              };
                    }

                    targetColumnsIndexMapping.Add(columnInfo, index);
                }

                var sourceColumns = mapping.SourceColumns.ToArray();
                for (int index = 0; index < sourceColumns.Length; index++)
                {
                    var columnInfo = sourceColumns[index];

                    if (sourceColumnsIndexMapping.ContainsKey(columnInfo))
                    {
                        throw new InvalidOperationException($"2Error while mapping columns. Column: '{columnInfo.NaturalName}' exists")
                              {
                                  Data = { { "Columns", sourceColumnsIndexMapping } }
                              };
                    }

                    sourceColumnsIndexMapping.Add(columnInfo, index);
                }
                var targetTable =
                    context.QueryContainer
                    .AccessLayer
                    .Config
                    .GetOrCreateClassInfoCache(mapping.TargetType);

                var primaryKeyColumn = mapping.SourceColumns.FirstOrDefault(e =>
                                                                            e.IsEquivalentTo(targetTable.PrimaryKeyProperty.DbName) &&
                                                                            e.Alias.Equals(mapping.TargetAlias));

                var primaryKeyOrdinal = sourceColumnsIndexMapping
                                        .FirstOrDefault(f => f.Key.IsEqualsTo(primaryKeyColumn));

                var targetOrdinal = sourceColumnsIndexMapping
                                    .FirstOrDefault(f => f.Key.IsEqualsTo(mapping.TargetColumn));

                var sourceOrdinal = targetColumnsIndexMapping
                                    .FirstOrDefault(f => f.Key.IsEqualsTo(mapping.SourceColumn));

                readers = readers
                          .GroupBy(e => e[primaryKeyOrdinal.Value])
                          .Select(e => e.First())
                          .Select(record =>
                {
                    SetRelationOnRecord(mapping.TargetName,
                                        mapping.Records,
                                        targetOrdinal.Value,
                                        record,
                                        sourceOrdinal.Value);
                    return(record);
                })
                          .ToArray();
                Mappings.Remove(mapping);
                DoJoinMapping(mapping.Records, mapping.SourceAlias, context, false);

                if (toplevel)
                {
                    context.Columns = context.Columns.Concat(new[]
                    {
                        new ColumnInfo(mapping.TargetName, null, null),
                    }).ToArray();
                }
            }
            return(readers);
        }
Example #3
0
 public override EagarDataRecord[] Transform(EagarDataRecord[] readers, Type entityType, QueryProcessingRecordsContext context)
 {
     return(JoinTables(readers, entityType, context));
 }
Example #4
0
        private void CreateJoinMapping(
            JoinParseInfo joinTableQueryPart,
            EagarDataRecord[] readers,
            Type entityType,
            QueryProcessingRecordsContext context)
        {
            var parentedReaders = new List <EagarDataRecord>();
            var property        = joinTableQueryPart.TargetProperty;

            var sourceColumn = joinTableQueryPart.TargetColumnName;
            var targetColumn = joinTableQueryPart.SourceColumnName;

            if (sourceColumn == null)
            {
                throw new InvalidOperationException();
            }
            if (targetColumn == null)
            {
                throw new InvalidOperationException();
            }

            var fields        = joinTableQueryPart.Columns.ToArray();
            var fieldsOfChild = fields
                                .Select((item, index) => item.ColumnIdentifier())
                                .ToArray();

            var columnMapping             = new Dictionary <string, int>();
            var sourceColumnsIndexMapping = context.Columns.ToArray().Select((item, index) => new
            {
                item,
                index
            }).ToDictionary(e => e.item, e => e.index);

            foreach (var fieldOfChild in fieldsOfChild)
            {
                var child         = fieldOfChild;
                var indexOfSource =
                    sourceColumnsIndexMapping
                    .FirstOrDefault(e => e.Key.ColumnIdentifier().Equals(child));
                if (columnMapping.ContainsKey(indexOfSource.Key.NaturalName))
                {
                    throw new InvalidOperationException($"Column name collision detected. Column '{indexOfSource.Key.NaturalName}'")
                          {
                              Data =
                              {
                                  { "Columns", sourceColumnsIndexMapping },
                                  { "Field",   indexOfSource             },
                              }
                          };
                }

                columnMapping.Add(indexOfSource.Key.NaturalName, indexOfSource.Value);
            }

            var groupBy = columnMapping[columnMapping.FirstOrDefault().Key];
            //TODO might not be the PrimaryKey of the foreign table

            var readerGroups = readers
                               .GroupBy(e => e[groupBy])
                               .Select(e => e.First())
                               .ToArray();

            foreach (var readerGroup in readerGroups)
            {
                var naturalReader = new EagarDataRecord(columnMapping.Keys.ToArray(),
                                                        new ArrayList(columnMapping.Values.Select(f => readerGroup[f]).ToArray()));

                parentedReaders.Add(naturalReader);
            }

            Mappings.Add(new RelationMapping()
            {
                TargetColumns = joinTableQueryPart.Columns,
                SourceColumns = context.Columns
                                .Where(e => e.Alias.Equals(joinTableQueryPart.SourceTable))
                                .ToArray(),
                Records      = parentedReaders.ToArray(),
                SourceColumn = sourceColumn,
                TargetColumn = targetColumn,
                TargetName   = property.PropertyName,
                TargetType   = entityType,
                SourceAlias  = joinTableQueryPart.Alias,
                TargetAlias  = joinTableQueryPart.SourceTable
            });

            if (readerGroups.Any())
            {
                foreach (var subJoinTableQueryPart in joinTableQueryPart.DependingJoins)
                {
                    CreateJoinMapping(subJoinTableQueryPart,
                                      readers,
                                      subJoinTableQueryPart.TargetTableType,
                                      context);
                }
            }

            foreach (var eagarDataRecord in readers)
            {
                foreach (var columnInfo in joinTableQueryPart.Columns)
                {
                    //eagarDataRecord.Remove(columnInfo.ColumnIdentifier());
                    eagarDataRecord.Remove(columnInfo.ColumnIdentifier().TrimAlias());
                }
            }

            context.Columns = context.Columns
                              .Except(joinTableQueryPart.Columns)
                              .ToArray();
        }
Example #5
0
        public EagarDataRecord[] JoinTables(EagarDataRecord[] readers, Type entityType, QueryProcessingRecordsContext context)
        {
            if (_joinTableQueryPart.TargetTableType != entityType)
            {
                return(readers);
            }

            CreateJoinMapping(_joinTableQueryPart,
                              readers,
                              entityType,
                              context);
            return(readers);

            //var targetTable =
            //	context.QueryContainer
            //		.AccessLayer
            //		.Config
            //		.GetOrCreateClassInfoCache(_joinTableQueryPart.TargetTableType);

            //var primaryKeyColumn = context.Columns.FirstOrDefault(e =>
            //	e.IsEquivalentTo(targetTable.PrimaryKeyProperty.DbName) &&
            //	e.Alias == _joinTableQueryPart.SourceTable);

            //var sourceColumnsIndexMapping = new Dictionary<ColumnInfo, int>();
            //var columnInfos = context.Columns.ToArray();
            //for (int index = 0; index < columnInfos.Length; index++)
            //{
            //	var columnInfo = columnInfos[index];

            //	if (sourceColumnsIndexMapping.ContainsKey(columnInfo))
            //	{
            //		throw new InvalidOperationException($"1Error while mapping columns. Column: '{columnInfo.NaturalName}' exists")
            //		{
            //			Data = { { "Columns", sourceColumnsIndexMapping } }
            //		};
            //	}

            //	sourceColumnsIndexMapping.Add(columnInfo, index);
            //}

            //var primaryKeyCache = sourceColumnsIndexMapping
            //	.FirstOrDefault(f => f.Key.IsEqualsTo(primaryKeyColumn));

            //var targetColumnCache = sourceColumnsIndexMapping
            //	.FirstOrDefault(f => f.Key.IsEqualsTo(mapping.TargetColumn));

            //if (targetColumnCache.Key == null)
            //{
            //	throw new InvalidOperationException();
            //}

            //if (primaryKeyCache.Key == null)
            //{
            //	throw new InvalidOperationException();
            //}

            //var primaryKeyOrdinal = primaryKeyCache
            //	.Value;

            //var targetColumnOrdinal = targetColumnCache
            //		.Value;

            //var identifierNames = context.Columns.Select(e => e.ColumnIdentifier().TrimAlias())
            //	.ToArray();

            //var reducedRecords = readers
            //	.GroupBy(e => e[primaryKeyOrdinal])
            //	.Select(e => e.First())
            //	.Select(record =>
            //	{
            //		var naturalReader = new EagarDataRecord(identifierNames,
            //			new ArrayList(sourceColumnsIndexMapping
            //				.Select(f => record[f.Value])
            //				.ToArray()));
            //		if (restRecords.Any())
            //		{
            //			SetRelationOnRecord(outerMostCreatedForginKeys,
            //			   restRecords,
            //			   sourceColumn,
            //			   naturalReader,
            //			   targetColumnOrdinal
            //			   );
            //		}
            //		return naturalReader;
            //	})
            //	.ToArray();

            //context.Columns = context.Columns.Concat(new[]
            //{
            //		new ColumnInfo(outerMostCreatedForginKeys, null, null),
            //	}).ToArray();
        }
Example #6
0
        private void LoadResults()
        {
            var query     = _queryContainer.Compile(out var columns);
            var dbCommand =
                _queryContainer.AccessLayer.Database
                .CreateCommandWithParameterValues(query.Query, query.Parameters.ToArray());

            foreach (var queryCommandInterceptor in _queryContainer.Interceptors)
            {
                dbCommand = queryCommandInterceptor.NonQueryExecuting(dbCommand);

                if (dbCommand == null)
                {
                    throw new InvalidOperationException($"The Command interceptor: " +
                                                        $"'{queryCommandInterceptor}' has returned null");
                }
            }
            var dataRecords = _queryContainer.AccessLayer.EnumerateDataRecordsAsync(dbCommand)
                              .ToArray();

            if (_queryContainer.PostProcessors.Any())
            {
                var context = new QueryProcessingRecordsContext(_queryContainer, _queryContainer.PostProcessors, columns);
                foreach (var queryContainerPostProcessor in _queryContainer.PostProcessors)
                {
                    dataRecords = queryContainerPostProcessor.Transform(dataRecords, _type, context);
                }

                columns = context.Columns;
            }

            var relations = new List <Tuple <QueryIdentifier, QueryIdentifier, RelationProcessor> >();

            if (_queryContainer.Joins.Any())
            {
                var queryProcessingRecordsContext = new QueryProcessingRecordsContext(_queryContainer,
                                                                                      _queryContainer.PostProcessors,
                                                                                      columns);


                foreach (var queryContainerJoin in _queryContainer.Joins)
                {
                    var relationProcessor = new RelationProcessor(queryContainerJoin);
                    relations.Add(new Tuple <QueryIdentifier, QueryIdentifier, RelationProcessor>(
                                      queryContainerJoin.Alias,
                                      queryContainerJoin.SourceTable,
                                      relationProcessor));
                    dataRecords = relationProcessor
                                  .JoinTables(dataRecords,
                                              queryContainerJoin.TargetTableType,
                                              queryProcessingRecordsContext);
                }

                foreach (var queryContainerJoin in relations)
                {
                    dataRecords = queryContainerJoin
                                  .Item3
                                  .DoJoinMapping(dataRecords,
                                                 queryContainerJoin.Item1,
                                                 queryProcessingRecordsContext,
                                                 true,
                                                 true);
                }

                columns = queryProcessingRecordsContext.Columns;
            }

            var columnNames = columns.Select(f => f.NaturalName).ToArray();

            dataRecords = dataRecords.Select(record =>
                                             new EagarDataRecord(columnNames, record.MetaHeader.ToArray()))
                          .ToArray();

            var records = Partitioner.Create(dataRecords, true)
                          .AsParallel()
                          .AsOrdered()
                          .Select((dataRecord) => _queryContainer.AccessLayer
                                  .SetPropertysViaReflection(_queryContainer.AccessLayer.GetClassInfo(_type),
                                                             dataRecord))
                          .ToArray();

            var elements = new ArrayList();

            if (_queryContainer.PostProcessors.Any())
            {
                var context = new QueryProcessingEntitiesContext(records);
                foreach (var element in records)
                {
                    var item = element;
                    foreach (var queryContainerPostProcessor in _queryContainer.PostProcessors)
                    {
                        item = queryContainerPostProcessor.Transform(item, _type, context);
                    }

                    elements.Add(item);
                }
            }
            else
            {
                elements.AddRange(records);
            }

            _elements = elements.GetEnumerator();
        }