Example #1
0
        public Translator(SourceTable tbl, IDataReader source, IEnumerable<SourceColumn> srcColumns, Converter[] converter)
        {
            if (tbl == null) throw new ArgumentNullException("tbl");
            if (source == null) throw new ArgumentNullException("source");
            if (srcColumns == null) throw new ArgumentNullException("srcColumns");

            //_tbl = tbl;
            _source = source;
            _srcColumns = srcColumns.ToArray();
            _srcColumnsInfos = _srcColumns.Select(
                col => new SourceColumnInfo(DbTypeMapper.GetDbTypeForProperty(col.DestinationProperty.Last().GetType()),
                        DbTypeMapper.GetDbType(col.DbType),
                        col.DestinationProperty.Last() is EnumerationProperty,
                        col.DestinationProperty.First() is CompoundObjectProperty)).ToArray();
            _converter = converter != null ? converter.ToDictionary(c => c.Column) : new Dictionary<SourceColumn, Converter>();
            _resultColumnCount = _srcColumns.Length;

            if (typeof(IMigrationInfo).IsAssignableFrom(tbl.DestinationObjectClass.GetDataType()))
            {
                // TODO: That's a bad hack!
                _errorColIdx = _resultColumnCount;
                _resultColumnCount++;
            }
            else
            {
                _errorColIdx = -1;
            }

            foreach (var comp in srcColumns
                .Where(c => c.DestinationProperty.First() is CompoundObjectProperty)
                .GroupBy(c => c.DestinationProperty.First()))
            {
                foreach (var col in comp)
                {
                    _compoundObjectSourceColumns[col.Name] = _resultColumnCount;
                }
                _resultColumnCount++;
            }
        }
Example #2
0
        public void TableBaseMigration(SourceTable tbl, Converter[] converter, Join[] additional_joins)
        {
            // ------------------- Argument checks -------------------
            if (tbl == null)
                throw new ArgumentNullException("tbl");
            if (tbl.DestinationObjectClass == null)
            {
                Log.InfoFormat("Skipping base migration of unmapped table [{0}]", tbl.Name);
                return;
            }

            using (Log.InfoTraceMethodCallFormat("TableBaseMigration", "{0} to {1}", tbl.Name, tbl.DestinationObjectClass.Name))
            {
                // ------------------- Build columns -------------------
                var mappedColumns = tbl.SourceColumn
                    .Where(c => c.DestinationProperty.Count > 0)
                    .OrderBy(c => c.Name)
                    .ToList();
                // Ref Cols
                var referringCols = mappedColumns.Where(c => c.References != null).ToList();

                // ------------------- Migrate -------------------
                if (referringCols.Count == 0 && (additional_joins == null || additional_joins.Length == 0))
                {
                    TableBaseSimpleMigration(tbl, converter, mappedColumns);
                }
                else
                {
                    TableBaseComplexMigration(tbl, converter, mappedColumns, referringCols, additional_joins);
                }
            }
        }
Example #3
0
        private void TableBaseSimpleMigration(SourceTable tbl, Converter[] nullConverter, List<SourceColumn> mappedColumns)
        {
            var dstColumnNames = GetDestinationColumnNames(tbl, mappedColumns);
            var srcColumnNames = mappedColumns.Select(c => c.Name).ToArray();
            var tblRef = _src.GetTableName(tbl.StagingDatabase.Schema, tbl.Name);

            // no fk mapping required
            using (var srcReader = _src.ReadTableData(tblRef, srcColumnNames))
            using (var translator = new Translator(tbl, srcReader, mappedColumns, nullConverter))
            {
                _dst.WriteTableData(_dst.GetTableName(tbl.DestinationObjectClass.Module.SchemaName, tbl.DestinationObjectClass.TableName), translator, dstColumnNames);

                WriteLog(
                    tbl.Name, translator.ProcessedRows,
                    tbl.DestinationObjectClass.TableName, translator.ProcessedRows);
            }
        }
Example #4
0
        private void TableBaseComplexMigration(SourceTable tbl, Converter[] converter, List<SourceColumn> mappedColumns, List<SourceColumn> referringCols, Join[] additional_joins)
        {
            if (additional_joins != null
                && additional_joins.Length > 0
                && additional_joins.All(j => referringCols
                    .Select(c => c.DestinationProperty.Single())
                    .OfType<ObjectReferenceProperty>()
                    .Any(orp => j.JoinTableName == _dst.GetTableName(orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.Module.SchemaName, orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.TableName))))
            {
                throw new InvalidOperationException("Unmapped additional joins found");
            }

            // could automatically create needed indices
            var all_joins = new Dictionary<SourceColumn, Join>();
            var root_joins = referringCols
                .GroupBy(k => k.DestinationProperty.Single())
                .SelectMany(referenceGroup => CreateReferenceJoin(referenceGroup, all_joins))
                .ToArray();

            // Add manual joins
            IEnumerable<Join> joins;
            if (additional_joins != null)
            {
                joins = root_joins.Union(additional_joins);
            }
            else
            {
                joins = root_joins;
            }

            var srcColumns = mappedColumns
                                .Where(c => c.References == null)
                                .Union(
                                    referringCols
                                        .GroupBy(k => k.DestinationProperty.Single()) // referring columns cannot be mapped remotely
                                        .Select(g => g.First(p => p.References.References == null))
                                ).ToList();
            var srcColumnNames = srcColumns.Select(c =>
            {
                var orp = c.DestinationProperty.FirstOrDefault() as ObjectReferenceProperty;
                if (c.References != null)
                {
                    return new ProjectionColumn("ID", all_joins[c], System.Data.DbType.Int32, c.DestinationProperty.Single().Name);
                }
                else if (c.References == null
                    && orp != null)
                {
                    if (additional_joins != null
                        && additional_joins.Count(i => i.JoinTableName == _dst.GetTableName(orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.Module.SchemaName, orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.TableName)) > 0)
                    {
                        return new ProjectionColumn(
                            "ID",
                            additional_joins.Single(j => j.JoinTableName == _dst.GetTableName(orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.Module.SchemaName, orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.TableName)),
                            System.Data.DbType.Int32,
                            orp.Name);
                    }
                    else if (converter.Any(cnv => cnv.Column.Name == c.Name))
                    {
                        return new ProjectionColumn(c.Name, ColumnRef.PrimaryTable, c.DestinationProperty.Single().Name);
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("No join found for {0}", c));
                    }
                }
                else
                {
                    return new ProjectionColumn(c.Name, ColumnRef.PrimaryTable, (System.Data.DbType)c.DbType, null);
                }
            }).ToList();

            var dstColumnNames = GetDestinationColumnNames(tbl, srcColumns);
            long processedRows;

            using (var srcReader = _src.ReadJoin(_src.GetTableName(tbl.StagingDatabase.Schema, tbl.Name), srcColumnNames, joins))
            using (var translator = new Translator(tbl, srcReader, srcColumns, converter))
            {
                _dst.WriteTableData(_dst.GetTableName(tbl.DestinationObjectClass.Module.SchemaName, tbl.DestinationObjectClass.TableName), translator, dstColumnNames);
                processedRows = translator.ProcessedRows;
            }

            // count rows in original table, joins should not add or remove rows
            WriteLog(
                tbl.Name, _src.CountRows(_src.GetTableName(tbl.StagingDatabase.Schema, tbl.Name)),
                tbl.DestinationObjectClass.TableName, processedRows);
        }