Ejemplo n.º 1
0
        /// alters table, decomposes to alter actions; doesn't transform alter plan
        /// proc must be able to run all logical operations
        public static void DecomposeAlterTable(this IAlterProcessor proc, ITableStructure oldTable, ITableStructure newTable, DbDiffOptions options)
        {
            DbObjectPairing pairing = CreateTablePairing(oldTable, newTable);
            // decompose to alter actions
            AlterPlan plan = new AlterPlan();

            AlterTable(plan, oldTable, newTable, options, pairing);
            var run = plan.CreateRunner();

            run.Run(proc, options);
        }
Ejemplo n.º 2
0
        public static DbObjectPairing CreateTablePairing(ITableStructure oldTable, ITableStructure newTable)
        {
            DatabaseStructure src = new DatabaseStructure();
            DatabaseStructure dst = new DatabaseStructure(src);

            src.AddObject(oldTable, true);
            dst.AddObject(newTable, true);
            DbObjectPairing pairing = new DbObjectPairing(src, dst);

            return(pairing);
        }
Ejemplo n.º 3
0
        public static AlterPlan PlanAlterTable(ITableStructure oldTable, ITableStructure newTable, DbDiffOptions opts)
        {
            AlterPlan plan = new AlterPlan();

            if (oldTable == null)
            {
                plan.CreateTable(newTable);
            }
            else
            {
                DbObjectPairing pairing = CreateTablePairing(oldTable, newTable);
                AlterTable(plan, oldTable, newTable, opts, pairing);
            }
            return(plan);
        }
Ejemplo n.º 4
0
        public static bool EqualsColumns(IColumnStructure a, IColumnStructure b, bool checkName, DbDiffOptions opts, DbObjectPairing pairing)
        {
            if (a.DefaultValue == null)
            {
                if (a.DefaultValue != b.DefaultValue)
                {
                    opts.DiffLogger.Trace("Column {0}, {1}: different default values: {2}; {3}", a, b, a.DefaultValue, b.DefaultValue);
                    return(false);
                }
            }
            else
            {
                if (!a.DefaultValue.Equals(b.DefaultValue))
                {
                    opts.DiffLogger.Trace("Column {0}, {1}: different default values: {2}; {3}", a, b, a.DefaultValue, b.DefaultValue);
                    return(false);
                }
            }
            if (checkName && !DbDiffTool.EqualNames(a.ColumnName, b.ColumnName, opts))
            {
                opts.DiffLogger.Trace("Column, different name: {0}; {1}", a, b);
                return(false);
            }
            if (!DbDiffTool.EqualFullNames(a.Domain, b.Domain, opts))
            {
                opts.DiffLogger.Trace("Column {0}, {1}: different domain: {2}; {3}", a, b, a.Domain, b.Domain);
                return(false);
            }
            if (a.IsNullable != b.IsNullable)
            {
                opts.DiffLogger.Trace("Column {0}, {1}: different nullable: {2}; {3}", a, b, a.IsNullable, b.IsNullable);
                return(false);
            }
            var btype = b.DataType;
            var atype = a.DataType;

            if (pairing != null && pairing.Target != null && pairing.Source.Dialect != null)
            {
                btype = pairing.Source.Dialect.MigrateDataType(b, btype, pairing.Source.Dialect.GetDefaultMigrationProfile(), null);
                btype = pairing.Source.Dialect.GenericTypeToSpecific(btype).ToGenericType();

                // normalize type
                atype = pairing.Source.Dialect.GenericTypeToSpecific(atype).ToGenericType();
            }
            if (!EqualTypes(atype, btype, opts))
            {
                opts.DiffLogger.Trace("Column {0}, {1}: different types: {2}; {3}", a, b, a.DataType, b.DataType);
                return(false);
            }
            if (!opts.IgnoreColumnCollation && a.Collation != b.Collation)
            {
                opts.DiffLogger.Trace("Column {0}, {1}: different collations: {2}; {3}", a, b, a.Collation, b.Collation);
                return(false);
            }
            if (!opts.IgnoreColumnCharacterSet && a.CharacterSet != b.CharacterSet)
            {
                opts.DiffLogger.Trace("Column {0}, {1}: different character sets: {2}; {3}", a, b, a.CharacterSet, b.CharacterSet);
                return(false);
            }
            return(true);
        }
Ejemplo n.º 5
0
 public static bool EqualsConstraints(IConstraint csrc, IConstraint cdst, DbDiffOptions options, bool checkNames, DbObjectPairing pairing)
 {
     if (checkNames && !options.IgnoreConstraintNames)
     {
         if (!EqualNames(csrc.Name, cdst.Name, options))
         {
             if (csrc is IPrimaryKey && cdst is IPrimaryKey && (pairing.Source.Dialect.DialectCaps.AnonymousPrimaryKey || pairing.Target.Dialect.DialectCaps.AnonymousPrimaryKey))
             {
                 // do nothing
             }
             else
             {
                 return(false);
             }
         }
     }
     if (csrc.GetType() != cdst.GetType())
     {
         return(false);
     }
     if (csrc is ColumnsConstraint)
     {
         ITableStructure tsrc = pairing.Source.FindTable(csrc.Table.FullName);
         ITableStructure tdst = pairing.Target.FindTable(cdst.Table.FullName);
         if (!EqualsColumnRefs(tsrc, tdst, ((ColumnsConstraint)csrc).Columns, ((ColumnsConstraint)cdst).Columns))
         {
             return(false);
         }
         //if (!((ColumnsConstraint)csrc).Columns.EqualSequence(((ColumnsConstraint)cdst).Columns)) return false;
         if (csrc is ForeignKey)
         {
             var fsrc = (ForeignKey)csrc;
             var fdst = (ForeignKey)cdst;
             if (!EqualFullNames(fsrc.PrimaryKeyTable, fdst.PrimaryKeyTable, options))
             {
                 return(false);
             }
             ITableStructure psrc = pairing.Source.FindTable(fsrc.PrimaryKeyTable);
             ITableStructure pdst = pairing.Target.FindTable(fdst.PrimaryKeyTable);
             if (!EqualsColumnRefs(psrc, pdst, fsrc.PrimaryKeyColumns, fdst.PrimaryKeyColumns))
             {
                 return(false);
             }
             if (fsrc.OnDeleteAction != fdst.OnDeleteAction)
             {
                 return(false);
             }
             if (fsrc.OnUpdateAction != fdst.OnUpdateAction)
             {
                 return(false);
             }
         }
         if (csrc is IIndex)
         {
             var isrc = (IndexConstraint)csrc;
             var idst = (IndexConstraint)cdst;
             if (isrc.IsUnique != idst.IsUnique)
             {
                 return(false);
             }
         }
     }
     if (csrc is CheckConstraint)
     {
         if (((CheckConstraint)csrc).Expression != ((CheckConstraint)cdst).Expression)
         {
             return(false);
         }
     }
     return(true);
 }
Ejemplo n.º 6
0
        public static bool EqualTables(ITableStructure tsrc, ITableStructure tdst, DbDiffOptions options, DbObjectPairing pairing, bool testNames)
        {
            if (options.IgnoreColumnOrder)
            {
                if (tsrc.Columns.Count != tdst.Columns.Count)
                {
                    return(false);
                }
                foreach (var scol in tsrc.Columns)
                {
                    var dcol = (from c in tdst.Columns where c.GroupId == scol.GroupId select c).FirstOrDefault();
                    if (dcol == null)
                    {
                        return(false);
                    }
                    using (var ctx = new DbDiffChangeLoggerContext(options, NopLogger.Instance, DbDiffOptsLogger.DiffLogger))
                    {
                        if (!EqualsColumns(scol, dcol, true, options, pairing))
                        {
                            return(false);
                        }
                    }
                }
            }
            else
            {
                using (var ctx = new DbDiffChangeLoggerContext(options, NopLogger.Instance, DbDiffOptsLogger.DiffLogger))
                {
                    if (!tsrc.Columns.EqualSequence(tdst.Columns, (c1, c2) => EqualsColumns(c1, c2, true, options, pairing)))
                    {
                        return(false);
                    }
                }
            }

            List <IConstraint> csrc = new List <IConstraint>(tsrc.Constraints);
            List <IConstraint> cdst = new List <IConstraint>(tdst.Constraints);

            csrc.Sort(CompareConstraints);
            cdst.Sort(CompareConstraints);

            if (!csrc.EqualSequence(cdst, (c1, c2) => EqualsConstraints(c1, c2, options, true, pairing)))
            {
                return(false);
            }

            if (testNames && !EqualFullNames(tsrc.FullName, tdst.FullName, options))
            {
                return(false);
            }
            if (GetTableAlteredOptions(tsrc, tdst, options).Count > 0)
            {
                return(false);
            }
            return(true);
        }
Ejemplo n.º 7
0
 public static bool EqualTables(ITableStructure tsrc, ITableStructure tdst, DbDiffOptions options, DbObjectPairing pairing)
 {
     return(EqualTables(tsrc, tdst, options, pairing, true));
 }
Ejemplo n.º 8
0
        public static void AlterDatabase(AlterPlan plan, DbObjectPairing pairing, DbDiffOptions opts)
        {
            var src = pairing.Source;
            var dst = pairing.Target;

            //var caps = proc.AlterCaps;

            // domains
            foreach (IDomainStructure dsrc in src.Domains)
            {
                IDomainStructure ddst = pairing.FindPair(dsrc);
                if (ddst == null)
                {
                    plan.DropDomain(dsrc);
                }
                else if (!DbDiffTool.EqualDomains(dsrc, ddst, opts, true))
                {
                    if (DbDiffTool.EqualDomains(dsrc, ddst, opts, false))
                    {
                        plan.RenameDomain(dsrc, ddst.FullName);
                    }
                    else
                    {
                        plan.ChangeDomain(dsrc, ddst);
                    }
                }
            }

            foreach (IDomainStructure ddst in dst.Domains)
            {
                if (!pairing.IsPaired(ddst))
                {
                    plan.CreateDomain(ddst);
                }
            }

            // drop tables
            foreach (ITableStructure tsrc in new List <ITableStructure>(src.Tables))
            {
                ITableStructure tdst = pairing.FindPair(tsrc);
                if (tdst == null)
                {
                    plan.DropTable(tsrc);
                }
            }
            // change tables
            foreach (ITableStructure tsrc in new List <ITableStructure>(src.Tables))
            {
                ITableStructure tdst = pairing.FindPair(tsrc);
                if (tdst == null)
                {
                    continue;
                }
                if (!DbDiffTool.EqualTables(tsrc, tdst, opts, pairing))
                {
                    DbDiffTool.AlterTable(plan, tsrc, tdst, opts, pairing);
                }
                else
                {
                    DbDiffTool.AlterFixedData(plan, tsrc, tdst, opts);
                }
            }
            // create tables
            foreach (ITableStructure tdst in dst.Tables)
            {
                if (!pairing.IsPaired(tdst))
                {
                    var script = DbDiffTool.AlterFixedData(null, tdst.FixedData, null, opts);
                    plan.CreateTable(tdst, script);
                    //if (script != null) plan.UpdateData(tdst.FullName, script);
                }
            }

            // specific objects
            foreach (ISpecificObjectStructure osrc in src.GetAllSpecificObjects())
            {
                var repr = SpecificRepresentationAddonType.Instance.FindRepresentation(osrc.ObjectType);
                if (!repr.UseInSynchronization)
                {
                    continue;
                }

                ISpecificObjectStructure odst = pairing.FindPair(osrc);
                if (odst == null)
                {
                    plan.DropSpecificObject(osrc);
                    //proc.DropSpecificObject(osrc);
                }
                else if (!DbDiffTool.EqualsSpecificObjects(osrc, odst, opts))
                {
                    DbDiffTool.AlterSpecificObject(osrc, odst, plan, opts, pairing);
                }
            }
            foreach (ISpecificObjectStructure odst in dst.GetAllSpecificObjects())
            {
                var repr = SpecificRepresentationAddonType.Instance.FindRepresentation(odst.ObjectType);
                if (!repr.UseInSynchronization)
                {
                    continue;
                }

                if (!pairing.IsPaired(odst))
                {
                    plan.CreateSpecificObject(odst);
                    //proc.CreateSpecificObject(odst);
                }
            }

            foreach (ISchemaStructure ssrc in src.Schemata)
            {
                ISchemaStructure sdst = pairing.FindPair(ssrc);
                if (sdst == null)
                {
                    plan.DropSchema(ssrc);
                }
                else if (ssrc.SchemaName != sdst.SchemaName)
                {
                    plan.RenameSchema(ssrc, sdst.SchemaName);
                    //if (caps.RenameSchema) proc.RenameSchema(ssrc, sdst.SchemaName);
                    //else
                    //{
                    //    proc.DropSchema(ssrc);
                    //    proc.CreateSchema(sdst);
                    //}
                }
            }

            foreach (ISchemaStructure sdst in dst.Schemata)
            {
                if (!pairing.IsPaired(sdst))
                {
                    plan.CreateSchema(sdst);
                }
            }

            var alteredOptions = GetDatabaseAlteredOptions(src, dst, opts);

            if (alteredOptions.Count > 0)
            {
                plan.ChangeDatabaseOptions(null, alteredOptions);
            }

            if (opts.SchemaMode == DbDiffSchemaMode.Ignore)
            {
                plan.RunNameTransformation(new SetSchemaNameTransformation(null));
            }
        }
Ejemplo n.º 9
0
 public static void AlterSpecificObject(ISpecificObjectStructure osrc, ISpecificObjectStructure odst, AlterPlan plan, DbDiffOptions opts, DbObjectPairing pairing)
 {
     //bool altered = false;
     if (osrc.CreateSql == odst.CreateSql)
     {
         plan.RenameSpecificObject(osrc, odst.ObjectName);
         //altered = GenerateRename(osrc.ObjectName, odst.ObjectName,
         //    (old, sch) =>
         //    {
         //        var o2 = new SpecificObjectStructure(osrc);
         //        o2.ObjectName = old;
         //        proc.ChangeSpecificObjectSchema(o2, sch);
         //    },
         //    (old, nam) =>
         //    {
         //        var o2 = new SpecificObjectStructure(osrc);
         //        o2.ObjectName = old;
         //        proc.RenameSpecificObject(o2, nam);
         //    }, caps[osrc.ObjectType].ChangeSchema, caps[osrc.ObjectType].Rename, opts);
     }
     else
     {
         plan.ChangeSpecificObject(osrc, odst);
     }
     //if (!altered)
     //{
     //    proc.DropSpecificObject(osrc);
     //    SpecificObjectStructure odst2 = new SpecificObjectStructure(odst);
     //    odst2.ObjectName = GenerateNewName(osrc.ObjectName, odst.ObjectName, opts);
     //    proc.CreateSpecificObject(odst);
     //}
 }
Ejemplo n.º 10
0
        public static void AlterTable(AlterPlan plan, ITableStructure oldTable, ITableStructure newTable, DbDiffOptions opts, DbObjectPairing pairing)
        {
            //plan.BeginFixedOrder();
            if (oldTable == null)
            {
                throw new ArgumentNullException("oldTable", "DAE-00240 oldTable is null");
            }
            if (newTable == null)
            {
                throw new ArgumentNullException("newTable", "DAE-00241 newTable is null");
            }

            //bool processed;
            //proc.AlterTable(oldTable, newTable, out processed);
            //if (processed) return;

            InMemoryTableOperation dataOps = null;

            if (oldTable.FixedData != null)
            {
                dataOps = new InMemoryTableOperation(oldTable.FixedData.Structure);
            }

            NameWithSchema newTableName = GenerateNewName(oldTable.FullName, newTable.FullName, opts);

            bool permuteColumns = false;
            bool insertColumns  = false;
            //bool renameColumns = false;

            List <int> columnMap     = new List <int>();
            List <int> constraintMap = new List <int>();

            foreach (var col in newTable.Columns)
            {
                columnMap.Add(oldTable.Columns.IndexOfIf(c => c.GroupId == col.GroupId));
            }
            foreach (var cnt in newTable.Constraints)
            {
                int cindex = oldTable.Constraints.IndexOfIf(c => c.GroupId == cnt.GroupId);
                if (cindex < 0 && cnt is IPrimaryKey)
                {
                    // primary keys for one table are equal
                    cindex = oldTable.Constraints.IndexOfIf(c => c is IPrimaryKey);
                }
                constraintMap.Add(cindex);
            }

            if (!opts.IgnoreColumnOrder)
            {
                // count alter requests
                int lastcol = -1;
                foreach (int col in columnMap)
                {
                    if (col < 0)
                    {
                        continue;
                    }
                    if (col < lastcol)
                    {
                        permuteColumns = true;
                    }
                    lastcol = col;
                }

                bool wasins = false;
                foreach (int col in columnMap)
                {
                    if (col < 0)
                    {
                        wasins = true;
                    }
                    if (col >= 0 && wasins)
                    {
                        insertColumns = true;
                    }
                }
            }

            int index;

            // drop constraints
            index = 0;

            foreach (IConstraint cnt in oldTable.Constraints)
            {
                if (constraintMap.IndexOf(index) < 0)
                {
                    plan.DropConstraint(cnt);
                }
                index++;
            }

            // drop columns
            index = 0;
            foreach (IColumnStructure col in oldTable.Columns)
            {
                if (columnMap.IndexOf(index) < 0)
                {
                    plan.DropColumn(col);
                    if (dataOps != null)
                    {
                        dataOps.DropColumn(col.ColumnName);
                    }
                }
                index++;
            }

            if (!DbDiffTool.EqualFullNames(oldTable.FullName, newTable.FullName, opts))
            {
                plan.RenameTable(oldTable, newTable.FullName);
            }

            // create columns
            index = 0;
            foreach (IColumnStructure col in newTable.Columns)
            {
                if (columnMap[index] < 0)
                {
                    ColumnStructure newcol = new ColumnStructure(col);
                    plan.CreateColumn(oldTable, newcol);
                    if (dataOps != null)
                    {
                        dataOps.CreateColumn(newcol);
                    }
                }
                index++;
            }

            // change columns
            index = 0;
            foreach (IColumnStructure col in newTable.Columns)
            {
                if (columnMap[index] >= 0)
                {
                    IColumnStructure src = oldTable.Columns[columnMap[index]];
                    if (!DbDiffTool.EqualsColumns(src, col, true, opts, pairing))
                    {
                        using (var ctx = new DbDiffChangeLoggerContext(opts, NopLogger.Instance, DbDiffOptsLogger.DiffLogger))
                        {
                            if (DbDiffTool.EqualsColumns(src, col, false, opts, pairing))
                            {
                                plan.RenameColumn(src, col.ColumnName);
                            }
                            else
                            {
                                plan.ChangeColumn(src, col);
                            }
                            if (dataOps != null && src.ColumnName != col.ColumnName)
                            {
                                dataOps.RenameColumn(src.ColumnName, col.ColumnName);
                            }
                        }
                    }
                }
                index++;
            }

            // create fixed data script
            var script = AlterFixedData(oldTable.FixedData, newTable.FixedData, dataOps, opts);

            if (script != null)
            {
                plan.UpdateData(oldTable.FullName, script);
            }

            // change constraints
            index = 0;
            foreach (IConstraint cnt in newTable.Constraints)
            {
                if (constraintMap[index] >= 0)
                {
                    IConstraint src = oldTable.Constraints[constraintMap[index]];
                    if (DbDiffTool.EqualsConstraints(src, cnt, opts, false, pairing) && src.Name != cnt.Name)
                    {
                        if (cnt is IPrimaryKey && (pairing.Source.Dialect.DialectCaps.AnonymousPrimaryKey || pairing.Target.Dialect.DialectCaps.AnonymousPrimaryKey))
                        {
                            // do nothing
                        }
                        else
                        {
                            plan.RenameConstraint(src, cnt.Name);
                        }
                    }
                    else
                    {
                        if (!DbDiffTool.EqualsConstraints(src, cnt, opts, true, pairing))
                        {
                            plan.ChangeConstraint(src, cnt);
                        }
                    }
                }
                index++;
            }

            // create constraints
            index = 0;
            foreach (IConstraint cnt in newTable.Constraints)
            {
                if (constraintMap[index] < 0)
                {
                    plan.CreateConstraint(oldTable, cnt);
                }
                index++;;
            }

            if (permuteColumns || insertColumns)
            {
                plan.ReorderColumns(oldTable, new List <string>((from c in newTable.Columns select c.ColumnName)));
            }

            var alteredOptions = GetTableAlteredOptions(oldTable, newTable, opts);

            if (alteredOptions.Count > 0)
            {
                plan.ChangeTableOptions(oldTable, alteredOptions);
            }
            //plan.EndFixedOrder();
        }