예제 #1
0
 public override void TransformToImplementedOps(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> replacement, AlterPlan plan, IDatabaseSource targetDb)
 {
     if (!caps.PermuteColumns)
     {
         TransformToRecreateTable(replacement, plan, targetDb);
     }
 }
예제 #2
0
 public override void TransformToImplementedOps(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> replacement, AlterPlan plan, IDatabaseSource targetDb)
 {
     if (targetDb != null && !targetDb.Dialect.DialectCaps.UncheckedReferences)
     {
         replacement.Clear();
         replacement.Add(this);
         var table = (TableStructure)NewObject;
         foreach (var cnt in new List <IConstraint>(table.Constraints))
         {
             var fk = cnt as ForeignKey;
             if (fk == null)
             {
                 continue;
             }
             table._Constraints.Remove(cnt);
             fk.SetDummyTable(table.FullName);
             replacement.Add(new AlterOperation_CreateConstraint
             {
                 NewObject = fk
             });
         }
         return;
     }
     base.TransformToImplementedOps(caps, opts, replacement, plan, targetDb);
 }
예제 #3
0
        public override void AddLogicalDependencies(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> before, List <AlterOperation> after, AlterPlan plan, IDatabaseSource targetDb)
        {
            base.AddLogicalDependencies(caps, opts, before, after, plan, targetDb);

            var pk = OldObject as IPrimaryKey;

            if (pk != null)
            {
                ParentTable.LoadStructure(TableStructureMembers.ReferencedFrom, targetDb);
                foreach (var col in pk.Columns)
                {
                    foreach (ForeignKey fk in ParentTable.GetReferencedFrom())
                    {
                        bool fkdeleted = false;
                        for (int i = 0; i < fk.PrimaryKeyColumns.Count; i++)
                        {
                            if (fk.PrimaryKeyColumns[i].ColumnName == col.ColumnName)
                            {
                                fkdeleted = true;
                                break;
                            }
                        }
                        if (fkdeleted)
                        {
                            opts.AlterLogger.Warning(Texts.Get("s_dropped_reference$table$fk", "table", fk.Table.FullName, "fk", fk.Name));
                            before.Add(new AlterOperation_DropConstraint {
                                ParentTable = ParentTable, OldObject = fk
                            });
                        }
                    }
                }
            }
        }
예제 #4
0
        public void AlterDatabase()
        {
            var dbconn = this.FindDatabaseConnection(ConnPack);

            if (!AlterDatabaseVisible() || dbconn == null)
            {
                return;
            }
            var dbmem = new DatabaseStructureMembers();

            dbmem.DatabaseOptions = true;
            var m_db  = dbconn.InvokeLoadStructure(dbmem, null);
            var props = new DatabaseProperties
            {
                Name         = dbconn.DatabaseName,
                SpecificData = m_db.SpecificData,
            };

            if (DatabasePropertiesForm.Run(props, dbconn, true))
            {
                var plan = new AlterPlan();
                var opts = new DbDiffOptions();
                plan.ChangeDatabaseOptions(dbconn.DatabaseName, props.SpecificData);
                plan.Transform(dbconn.Dialect.DumperCaps, opts, dbconn);

                string alterSql = dbconn.Dialect.GenerateScript(dmp => plan.CreateRunner().Run(dmp, opts));
                if (SqlConfirmForm.Run(alterSql))
                {
                    dbconn.AlterDatabase(plan, opts);
                }
            }
        }
예제 #5
0
 public DbDiffChangeLoggerContext(DbDiffOptions opts, ILogger logger, DbDiffOptsLogger ltype)
 {
     m_opts     = opts;
     m_ltype    = ltype;
     m_oldValue = m_opts.DiffLogger;
     m_opts.SetLogger(m_ltype, logger);
 }
예제 #6
0
 public override void TransformToImplementedOps(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> replacement, AlterPlan plan, IDatabaseSource targetDb)
 {
     if (!caps[((ISpecificObjectStructure)OldObject).ObjectType].Change)
     {
         plan.RecreateObject(OldObject, NewObject);
         replacement.Clear();
     }
 }
예제 #7
0
 public override void Run(IAlterProcessor proc, DbDiffOptions opts)
 {
     base.Run(proc, opts);
     if (Data != null)
     {
         proc.UpdateData((TableStructure)NewObject, Data, null);
     }
 }
예제 #8
0
 public static bool EqualFullNames(NameWithSchema lft, NameWithSchema rgt, DbDiffOptions options)
 {
     if (lft == null || rgt == null)
     {
         return(lft == rgt);
     }
     return(EqualSchemas(lft.Schema, rgt.Schema, options) && EqualNames(lft.Name, rgt.Name, options));
 }
예제 #9
0
 public override void TransformToImplementedOps(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> replacement, AlterPlan plan, IDatabaseSource targetDb)
 {
     base.TransformToImplementedOps(caps, opts, replacement, plan, targetDb);
     if (DbName == null)
     {
         DbName = targetDb.DatabaseName;
     }
 }
예제 #10
0
        public override void TransformToImplementedOps(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> replacement, AlterPlan plan, IDatabaseSource targetDb)
        {
            var c = GetConstraintCaps(caps, OldObject);

            if (!c.Drop)
            {
                TransformToRecreateTable(replacement, plan, targetDb);
            }
        }
예제 #11
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);
        }
예제 #12
0
        public static void DropObject(this IDatabaseSource conn, IAbstractObjectStructure obj)
        {
            DatabaseStructure oldDb = new DatabaseStructure();

            oldDb.AddObject(obj, true);
            DatabaseStructure newDb = new DatabaseStructure(oldDb);

            newDb.DropObject(obj);
            conn.AlterDatabase(oldDb, newDb, DbDiffOptions.AlterStructureOptions());
        }
예제 #13
0
        public static void ChangeObject(this IDatabaseSource conn, IAbstractObjectStructure oldObj, Action <AbstractObjectStructure> changeFunc)
        {
            DatabaseStructure oldDb = new DatabaseStructure();

            oldDb.AddObject(oldObj, true);
            DatabaseStructure       newDb  = new DatabaseStructure(oldDb);
            AbstractObjectStructure newObj = (AbstractObjectStructure)newDb.FindByGroupId(oldObj);

            changeFunc(newObj);
            conn.AlterDatabase(oldDb, newDb, DbDiffOptions.AlterStructureOptions());
        }
예제 #14
0
        //public void EndFixedOrder()
        //{
        //    m_fixedOrderCounter++;
        //}

        //public void BeginFixedOrder()
        //{
        //    m_fixedOrderCounter--;
        //}

        public void AddLogicalDependencies(AlterProcessorCaps caps, DbDiffOptions opts, IDatabaseSource targetDb)
        {
            for (int index = 0; index < Operations.Count; index++)
            {
                var before = new List <AlterOperation>();
                var after  = new List <AlterOperation>();
                Operations[index].AddLogicalDependencies(caps, opts, before, after, this, targetDb);
                Operations.InsertRange(index, before);
                index += before.Count;
                Operations.InsertRange(index + 1, after);
                index += after.Count;
            }
        }
예제 #15
0
        public override void Run(IAlterProcessor proc, DbDiffOptions opts)
        {
            var newtbl = new TableStructure(ParentTable);
            var dbs    = new DatabaseStructure();

            dbs.Tables.Add(newtbl);
            foreach (var op in AlterTableOps)
            {
                op.Run(dbs, opts);
            }
            proc.RecreateTable(ParentTable, newtbl);
            opts.AlterLogger.Info(Texts.Get("s_recreated$table", "table", ParentTable.FullName));
        }
예제 #16
0
 public override void TransformToImplementedOps(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> replacement, AlterPlan plan, IDatabaseSource targetDb)
 {
     if (!caps.ChangeColumn)
     {
         TransformToRecreateTable(replacement, plan, targetDb);
         return;
     }
     if (!caps.ChangeAutoIncrement && ((IColumnStructure)OldObject).DataType.IsAutoIncrement() != ((IColumnStructure)NewObject).DataType.IsAutoIncrement())
     {
         TransformToRecreateTable(replacement, plan, targetDb);
         return;
     }
 }
예제 #17
0
        public override void TransformToImplementedOps(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> replacement, AlterPlan plan, IDatabaseSource targetDb)
        {
            var c = GetConstraintCaps(caps, NewObject);

            if (!c.Change)
            {
                if (c.Create && c.Drop)
                {
                    plan.RecreateObject(OldObject, NewObject);
                    replacement.Clear();
                }
                else
                {
                    TransformToRecreateTable(replacement, plan, targetDb);
                }
            }
        }
예제 #18
0
 public static bool EqualTypes(DbTypeBase t1, DbTypeBase t2, DbDiffOptions opts)
 {
     if (!opts.IgnoreSpecificData && !t1.SpecificData.EqualsDictionary(t2.SpecificData, opts.IgnoreDataTypeProperties))
     {
         opts.DiffLogger.Trace("Types {0}, {1}: different specific data: {2}; {3}", t1, t2, t1.SpecificData.Format(), t2.SpecificData.Format());
         return(false);
     }
     if (t1.Code != t2.Code)
     {
         opts.DiffLogger.Trace("Types {0}, {1}: different type code: {2}; {3}", t1, t2, t1.Code, t2.Code);
         return(false);
     }
     if (!XmlTool.PropertiesEquals(t1, t2, opts.DiffLogger))
     {
         return(false);
     }
     return(true);
 }
예제 #19
0
        public override void AddLogicalDependencies(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> before, List <AlterOperation> after, AlterPlan plan, IDatabaseSource targetDb)
        {
            ParentTable.LoadStructure(TableStructureMembers.ReferencedFrom, targetDb);
            var oldcol = OldObject as ColumnStructure;
            var newcol = NewObject as ColumnStructure;

            List <IForeignKey> recreateFks = new List <IForeignKey>();
            var changeCols = new List <Tuple <IColumnStructure, IColumnStructure> >();

            foreach (ForeignKey fk in ParentTable.GetReferencedFrom())
            {
                for (int i = 0; i < fk.PrimaryKeyColumns.Count; i++)
                {
                    if (fk.PrimaryKeyColumns[i].ColumnName == oldcol.ColumnName)
                    {
                        //plan.RecreateObject(fk, null);
                        TableStructure table = (TableStructure)fk.Table;
                        table.LoadStructure(TableStructureMembers.Columns, targetDb);
                        ColumnStructure othercol = table.Columns[fk.Columns[i].ColumnName] as ColumnStructure;

                        // compare types with ignoring autoincrement flag
                        // HACK: ignore specific attributes
                        var opts2 = opts.Clone();
                        opts2.IgnoreSpecificData = true;
                        DbTypeBase dt1 = othercol.DataType.Clone(), dt2 = newcol.DataType.Clone();
                        dt1.SetAutoincrement(false);
                        dt2.SetAutoincrement(false);
                        if (!DbDiffTool.EqualTypes(dt1, dt2, opts2))
                        {
                            after.Add(new AlterOperation_ChangeColumn
                            {
                                ParentTable = table,
                                OldObject   = othercol,
                                NewObject   = new ColumnStructure(othercol)
                                {
                                    DataType = dt2
                                }
                            });
                        }
                        opts.AlterLogger.Warning(Texts.Get("s_changed_referenced_column$table$column", "table", fk.Table.FullName, "column", othercol.ColumnName));
                    }
                }
            }
        }
예제 #20
0
 public static bool EqualDomains(IDomainStructure src, IDomainStructure dst, DbDiffOptions opts, bool testName)
 {
     if (testName && !DbDiffTool.EqualFullNames(src.FullName, dst.FullName, opts))
     {
         opts.DiffLogger.Trace("Domain: different names {0}; {1}", src.FullName, dst.FullName);
         return(false);
     }
     if (!EqualTypes(src.DataType, dst.DataType, opts))
     {
         opts.DiffLogger.Trace("Domain {0}, {1}: different types {2}; {3}", src.FullName, dst.FullName, src.DataType, dst.DataType);
         return(false);
     }
     if (src.IsNullable != dst.IsNullable)
     {
         opts.DiffLogger.Trace("Domain {0}, {1}: different nullable {2}; {3}", src.FullName, dst.FullName, src.IsNullable, dst.IsNullable);
         return(false);
     }
     return(true);
 }
예제 #21
0
 public static bool EqualSchemas(string lschema, string rschema, DbDiffOptions options)
 {
     if (options.SchemaMode == DbDiffSchemaMode.Ignore)
     {
         lschema = null;
     }
     if (options.SchemaMode == DbDiffSchemaMode.IngoreImplicit && lschema == options.LeftImplicitSchema)
     {
         lschema = null;
     }
     if (options.SchemaMode == DbDiffSchemaMode.Ignore)
     {
         rschema = null;
     }
     if (options.SchemaMode == DbDiffSchemaMode.IngoreImplicit && rschema == options.RightImplicitSchema)
     {
         rschema = null;
     }
     return(EqualNames(lschema, rschema, options));
 }
예제 #22
0
        public override void AddPhysicalDependencies(AlterProcessorCaps caps, DbDiffOptions opts, List <AlterOperation> before, List <AlterOperation> after, AlterPlan plan, IDatabaseSource targetDb)
        {
            var oldcol = OldObject as ColumnStructure;

            if (caps.DepCaps.ChangeColumn_Constraint || caps.DepCaps.ChangeColumn_Index)
            {
                ParentTable.LoadStructure(TableStructureMembers.Constraints, targetDb);
                foreach (var cnt in ParentTable.Constraints)
                {
                    var cc = cnt as ColumnsConstraint;
                    if (cc == null)
                    {
                        continue;
                    }
                    if (cc.Columns.Any(c => c.ColumnName == oldcol.ColumnName))
                    {
                        if (
                            (cc is IIndex && caps.DepCaps.ChangeColumn_Index) ||
                            (!(cc is IIndex) && caps.DepCaps.ChangeColumn_Constraint))
                        {
                            plan.RecreateObject(cc, null);
                        }
                    }
                }
            }
            if (caps.DepCaps.ChangeColumn_Reference)
            {
                ParentTable.LoadStructure(TableStructureMembers.ReferencedFrom, targetDb);

                foreach (ForeignKey fk in ParentTable.GetReferencedFrom())
                {
                    for (int i = 0; i < fk.PrimaryKeyColumns.Count; i++)
                    {
                        if (fk.PrimaryKeyColumns[i].ColumnName == oldcol.ColumnName)
                        {
                            plan.RecreateObject(fk, null);
                        }
                    }
                }
            }
        }
예제 #23
0
        public void Run(IAlterProcessor proc, DbDiffOptions opts)
        {
            //foreach (var dep in RecreatedItems)
            //{
            //    opts.AlterLogger.Info(Texts.Get("s_recreated_object$object", "object", dep.RecreatedObject));
            //}

            //foreach (var cls in RecreatedItem.DropClassOrder)
            //{
            //    foreach (var dep in RecreatedItems)
            //    {
            //        if (dep.ItemClass != cls) continue;
            //        dep.RunDrop(proc, opts);
            //    }
            //}
            foreach (var op in Operations)
            {
                op.Run(proc, opts);
                using (DbDiffChangeLoggerContext ctx = new DbDiffChangeLoggerContext(opts, NopLogger.Instance, DbDiffOptsLogger.AlterLogger))
                {
                    if (op.MustRunOnParalelStructure())
                    {
                        // run operation paralel on Structure, so that we have actual object names
                        op.Run(Structure, opts);
                    }
                }
            }
            //foreach (var cls in RecreatedItem.CreateClassOrder)
            //{
            //    foreach (var dep in RecreatedItems)
            //    {
            //        if (dep.ItemClass != cls) continue;
            //        if (Structure.FindByGroupId(dep.RecreatedObject.GroupId) == null)
            //        {
            //            // object was dropped
            //            continue;
            //        }
            //        dep.RunCreate(proc, opts);
            //    }
            //}
        }
예제 #24
0
 public void AlterDatabase(AlterPlan plan, DbDiffOptions opts)
 {
     throw new NotImplementedError("DAE-00092");
 }
예제 #25
0
 public void AlterDatabase(IDatabaseStructure src, IDatabaseStructure dst, DbDiffOptions opts)
 {
     throw new NotImplementedError("DAE-00091");
 }
예제 #26
0
        public static void AlterObject(this IDatabaseSource conn, IAbstractObjectStructure oldObj, IAbstractObjectStructure newObj, DbDiffOptions options)
        {
            if (oldObj == null)
            {
                conn.CreateObject(newObj);
                return;
            }
            if (newObj == null)
            {
                conn.DropObject(oldObj);
                return;
            }
            if (oldObj.GroupId != newObj.GroupId)
            {
                throw new InternalError("DAE-00010 Altering object with different groupid");
            }
            DatabaseStructure oldDb = new DatabaseStructure();
            DatabaseStructure newDb = new DatabaseStructure(oldDb);

            oldDb.AddObject(oldObj, true);
            newDb.AddObject(newObj, true);
            conn.AlterDatabase(oldDb, newDb, options);
        }
예제 #27
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);
        }
예제 #28
0
 public static bool EqualNames(string a, string b, DbDiffOptions opts)
 {
     return(String.Compare(a, b, opts.IgnoreCase) == 0);
 }
예제 #29
0
 public static bool EqualsSpecificObjects(ISpecificObjectStructure src, ISpecificObjectStructure dst, DbDiffOptions options)
 {
     if (!EqualFullNames(src.ObjectName, dst.ObjectName, options))
     {
         return(false);
     }
     if (src.ObjectType != dst.ObjectType)
     {
         return(false);
     }
     if (src.CreateSql == null || dst.CreateSql == null)
     {
         if (src.CreateSql != dst.CreateSql)
         {
             return(false);
         }
     }
     else
     {
         if (src.SpecificDialect == dst.SpecificDialect && src.SpecificDialect != null)
         {
             var dialect = (ISqlDialect)DialectAddonType.Instance.FindHolder(src.SpecificDialect).CreateInstance();
             return(dialect.EqualSpecificObjects(src.ObjectType, src.CreateSql, dst.CreateSql));
         }
         else
         {
             if (src.CreateSql.Trim() != dst.CreateSql.Trim())
             {
                 return(false);
             }
         }
     }
     return(true);
 }
예제 #30
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);
 }