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); }
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); }
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(); } }
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); }
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)); } } } }
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); }
public void RecreateTable(ITableStructure src, ITableStructure dst) { DbDiffTool.DecomposeAlterTable(this, src, dst, new DbDiffOptions()); }
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); }
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()); } } } }
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)); } }
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(); }