示例#1
0
 public static bool GenerateRenameSpecificObject(ISpecificObjectStructure oldObj, NameWithSchema newName, Action <ISpecificObjectStructure, string> changeSchema, Action <ISpecificObjectStructure, string> rename, bool allowChangeSchema, bool allowRename, DbDiffOptions opts)
 {
     newName = GenerateNewName(oldObj.ObjectName, newName, opts);
     if (DbDiffTool.EqualFullNames(oldObj.ObjectName, newName, opts))
     {
         return(true);
     }
     if (!EqualSchemas(oldObj.ObjectName.Schema, newName.Schema, opts) && !allowChangeSchema)
     {
         return(false);
     }
     if (oldObj.ObjectName.Name != newName.Name && !allowRename)
     {
         return(false);
     }
     if (!EqualSchemas(oldObj.ObjectName.Schema, newName.Schema, opts))
     {
         changeSchema(oldObj, newName.Schema);
     }
     if (oldObj.ObjectName.Name != newName.Name)
     {
         var tmpo = (SpecificObjectStructure)oldObj.CloneObject();
         tmpo.ObjectName = new NameWithSchema(newName.Schema, oldObj.ObjectName.Name);
         rename(tmpo, newName.Name);
     }
     return(true);
 }
示例#2
0
 public static bool GenerateRename(NameWithSchema oldName, NameWithSchema newName, Action <NameWithSchema, string> changeSchema, Action <NameWithSchema, string> rename, bool allowChangeSchema, bool allowRename, DbDiffOptions opts)
 {
     newName = GenerateNewName(oldName, newName, opts);
     if (DbDiffTool.EqualFullNames(oldName, newName, opts))
     {
         return(true);
     }
     if (!EqualSchemas(oldName.Schema, newName.Schema, opts) && !allowChangeSchema)
     {
         return(false);
     }
     if (oldName.Name != newName.Name && !allowRename)
     {
         return(false);
     }
     if (!EqualSchemas(oldName.Schema, newName.Schema, opts))
     {
         changeSchema(oldName, newName.Schema);
     }
     if (oldName.Name != newName.Name)
     {
         rename(new NameWithSchema(newName.Schema, oldName.Name), newName.Name);
     }
     return(true);
 }
示例#3
0
        public static void RenameObject(this IAlterProcessor proc, IAbstractObjectStructure obj, DbDiffOptions opts, NameWithSchema newName)
        {
            bool renameOk = false;
            var  dom      = obj as IDomainStructure;

            if (dom != null)
            {
                renameOk = DbDiffTool.GenerateRename(dom.FullName, newName,
                                                     (old, sch) => proc.ChangeDomainSchema(old, sch),
                                                     (old, nam) => proc.RenameDomain(old, nam),
                                                     proc.AlterCaps.ChangeTableSchema, proc.AlterCaps.RenameDomain, opts);
            }
            var tbl = obj as ITableStructure;

            if (tbl != null)
            {
                renameOk = DbDiffTool.GenerateRename(tbl.FullName, newName,
                                                     (old, sch) => proc.ChangeTableSchema(old, sch),
                                                     (old, nam) => proc.RenameTable(old, nam),
                                                     proc.AlterCaps.ChangeTableSchema, proc.AlterCaps.RenameTable, opts);
            }
            var col = obj as IColumnStructure;

            if (col != null)
            {
                if (proc.AlterCaps.RenameColumn)
                {
                    proc.RenameColumn(col, newName.Name);
                    renameOk = true;
                }
            }
            var cnt = obj as IConstraint;

            if (cnt != null)
            {
                if (proc.AlterCaps.RenameConstraint)
                {
                    proc.RenameConstraint(cnt, newName.Name);
                    renameOk = true;
                }
            }
            var spec = obj as ISpecificObjectStructure;

            if (spec != null)
            {
                renameOk = DbDiffTool.GenerateRenameSpecificObject(spec, newName,
                                                                   (old, sch) => proc.ChangeSpecificObjectSchema(old, sch),
                                                                   (old, nam) => proc.RenameSpecificObject(old, nam),
                                                                   proc.AlterCaps[spec.ObjectType].ChangeSchema, proc.AlterCaps[spec.ObjectType].Rename, opts);
            }
            if (!renameOk)
            {
                throw new AlterNotPossibleError();
            }
        }
示例#4
0
        public static void AlterDatabase(this IAlterProcessor proc, IDatabaseStructure src, IDatabaseStructure dst, DbDiffOptions opts, IDatabaseSource targetDb, Action <AlterPlan> extendPlan)
        {
            AlterPlan plan = new AlterPlan();

            DbDiffTool.AlterDatabase(plan, src, dst, opts);
            if (extendPlan != null)
            {
                extendPlan(plan);
            }
            plan.Transform(proc.AlterCaps, opts, targetDb);
            var run = plan.CreateRunner();

            run.Run(proc, opts);
        }
示例#5
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));
                    }
                }
            }
        }
示例#6
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);
 }
示例#7
0
 public void RecreateTable(ITableStructure src, ITableStructure dst)
 {
     DbDiffTool.DecomposeAlterTable(this, src, dst, new DbDiffOptions());
 }
示例#8
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);
        }
示例#9
0
        public virtual void CreateDatabaseObjects(IDatabaseStructure db, CreateDatabaseObjectsProps props)
        {
            if (Dialect.DialectCaps.Domains && props.CreateDomains)
            {
                foreach (var domain in db.Domains)
                {
                    try
                    {
                        CreateDomain(domain);
                    }
                    catch (Exception err)
                    {
                        ProgressInfo.RaiseErrorEx(err, "DAE-00244 " + Texts.Get("s_error_creating$domain", "domain", domain.FullName), "DOMAIN");
                    }
                }
            }
            if (Dialect.DialectCaps.MultipleSchema && props.CreateSchemata)
            {
                foreach (var schema in db.Schemata)
                {
                    try
                    {
                        CreateSchema(schema);
                    }
                    catch (Exception err)
                    {
                        ProgressInfo.RaiseErrorEx(err, "DAE-00245 " + Texts.Get("s_error_creating$schema", "schema", schema.SchemaName), "SCHEMA");
                    }
                }
            }
            var refsToCreate = new List <IForeignKey>();

            if (props.CreateTables)
            {
                foreach (var tbl in db.Tables)
                {
                    ITableStructure tbl2 = tbl;
                    if (!Dialect.DialectCaps.UncheckedReferences)
                    {
                        var newtbl = new TableStructure(tbl);
                        foreach (ForeignKey fk in new List <ForeignKey>(newtbl.GetConstraints <ForeignKey>()))
                        {
                            newtbl._Constraints.Remove(fk);
                            fk.SetDummyTable(tbl.FullName);
                            refsToCreate.Add(fk);
                        }
                        tbl2 = newtbl;
                    }

                    Logging.Debug("Creating table {0}", tbl2.FullName);
                    SetCurWork(String.Format("{0} {1}", Texts.Get("s_creating_table"), tbl2.FullName));
                    if (m_props.DumpWriterConfig != null && m_props.DumpWriterConfig.IncludeDropStatement)
                    {
                        DropTable(tbl2, DropFlags.TestIfExist);
                    }
                    try
                    {
                        CreateTable(tbl2);
                    }
                    catch (Exception err)
                    {
                        ProgressInfo.RaiseErrorEx(err, "DAE-00246 " + Texts.Get("s_error_creating$table", "table", tbl2.FullName), "TABLE");
                    }
                }
            }
            if (props.CreateFixedData)
            {
                foreach (var tbl in db.Tables)
                {
                    this.UpdateData(tbl, DbDiffTool.AlterFixedData(null, tbl.FixedData, null, new DbDiffOptions()), null);
                }
            }
            foreach (var fk in refsToCreate)
            {
                CreateConstraint(fk);
            }
            if (props.CreateSpecificObjects)
            {
                foreach (var obj in db.GetSpecObjectsOrderByDependency())
                {
                    SetCurWork(String.Format("{0} {1}", Texts.Get("s_creating_object"), obj.ObjectName));
                    if (m_props.DumpWriterConfig != null && m_props.DumpWriterConfig.IncludeDropStatement)
                    {
                        DropSpecificObject(obj, DropFlags.TestIfExist);
                    }
                    try
                    {
                        CreateSpecificObject(obj);
                    }
                    catch (Exception err)
                    {
                        if (ProgressInfo != null)
                        {
                            ProgressInfo.LogMessage("s_create_object", LogLevel.Error, Texts.Get("s_error_creating_object$name", "name", obj.ObjectName) + ": " + err.Message);
                        }
                        Logging.Error("Error creating object:" + err.ToString());
                    }
                }
            }
        }
示例#10
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));
            }
        }
示例#11
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();
        }