/// <summary> /// Gets the statement that can drop the given table. /// </summary> /// <param name="table"></param> /// <returns></returns> public override string[] GetDropTableStatement(BootFX.Common.Data.Schema.SqlTable table) { if (table == null) { throw new ArgumentNullException("table"); } return(new string[] { string.Format("{0} {1}{2}", this.DropTableKeyword, this.FormatTableName(table.NativeName), this.StatementSeparator) }); }
public override void AddSchemaTables(EntityType et, Type type, BootFX.Common.Data.Schema.SqlTable coreTable, BootFX.Common.Data.Schema.SqlSchema entitySchema) { // base... base.AddSchemaTables(et, type, coreTable, entitySchema); // have we done anything? if (!(et.HasExtendedProperties)) { return; } // create a table... SqlTable table = new SqlTable(et, et.NativeNameExtended.Name); // key... EntityField[] keyFields = et.GetKeyFields(); if (keyFields == null) { throw new InvalidOperationException("keyFields is null."); } ArrayList extendedKeyColumns = new ArrayList(); foreach (EntityField keyField in keyFields) { SqlColumn column = new SqlColumn(MangleIdColumnName(keyField.NativeName), keyField.DBType, keyField.Size, EntityFieldFlags.Key); // add... table.Columns.Add(column); extendedKeyColumns.Add(column); } // columns... foreach (EntityField field in et.GetExtendedProperties()) { table.Columns.Add(new SqlColumn(field)); } // relationship to parent... SqlChildToParentLink link = new SqlChildToParentLink(string.Format("FK_{0}_{1}", et.NativeName.Name, et.NativeNameExtended.Name), coreTable); link.LinkFields.AddRange((SqlColumn[])extendedKeyColumns.ToArray(typeof(SqlColumn))); link.Columns.AddRange(coreTable.GetKeyColumns()); table.LinksToParents.Add(link); // add... entitySchema.Tables.Add(table); }
/// <summary> /// Constructor. /// </summary> /// <param name="table"></param> /// <param name="index"></param> internal CreateIndexSchemaWorkUnit(EntityType entityType, SqlTable table, SqlIndex index) : base(entityType) { _index = index; _table = table; }
/// <summary> /// Gets the schema work units specific to this table. /// </summary> /// <param name="existingTable"></param> /// <returns></returns> internal WorkUnitCollection GetSchemaWorkUnits(SqlTable existingTable) { if (_entityType == null) { throw new ArgumentNullException("entityType"); } if (existingTable == null) { throw new ArgumentNullException("existingTable"); } // results... WorkUnitCollection results = new WorkUnitCollection(); // Removed indexes. SqlIndexCollection removedIndexes = new SqlIndexCollection(); // Removed indexes. SqlChildToParentLinkCollection removedForeignKeys = new SqlChildToParentLinkCollection(); // find missing columns... foreach (SqlColumn column in this.Columns) { SqlColumn existingColumn = null; foreach (SqlColumn scanColumn in existingTable.Columns) { if (string.Compare(column.NativeName, scanColumn.NativeName, true, System.Globalization.CultureInfo.InvariantCulture) == 0) { existingColumn = scanColumn; break; } } // found? if (existingColumn == null) { results.Add(new AddColumnSchemaWorkUnit(_entityType, column)); } else { // get the new column metrics. this is tricky, because if the length changes to be less than what it was, // we don't want to change the length, but we might want to change other metrics. bool changed = false; string reason = null; // check... long newLength = existingColumn.Length; if (column.Length > newLength && newLength != -1) { newLength = column.Length; // mbr - 24-07-2007 - case 321 - added reason... changed = true; reason = string.Format("Length changed from {0} to {1}", existingColumn.Length, column.Length); } // flags? bool newIsNullable = false; if (!(existingColumn.IsKey)) { newIsNullable = existingColumn.IsNullable; if (column.IsNullable != newIsNullable) { newIsNullable = column.IsNullable; // mbr - 24-07-2007 - case 321 - added reason... changed = true; reason = string.Format("Nullability changed to '{0}'", column.IsNullable); } } else { newIsNullable = false; } // type... DbType newType = existingColumn.DbType; bool newIsLarge = existingColumn.IsLarge; if (column.DbType != newType || column.IsLarge != newIsLarge) { // mbr - 24-07-2007 - case 308 - this didn't do anything, hence have changed the code // to the original intention - i.e. if something was an int and it's now a string, it will try and // convert. the original meaning of CanUpgradeType was to make sure the fx knew how // to go from // // are the compatible? // bool ok = false; // try // { // this.CanUpgradeType(newType, newIsLarge, column.DbType, column.IsLarge); // } // catch(Exception ex) // { // throw new InvalidOperationException(string.Format("Failed to check upgradability of '{0}' on '{1}'.", column, column.Table), ex); // } // can we? //if(ok) { newType = column.DbType; newIsLarge = column.IsLarge; // mbr - 24-07-2007 - case 321 - added reason... changed = true; string fromAsString = existingColumn.DbType.ToString(); if (existingColumn.IsLarge) { fromAsString += " (large)"; } string toAsString = column.DbType.ToString(); if (column.IsLarge) { toAsString += " (large)"; } reason = string.Format("Type changed from '{0}' to '{1}'", fromAsString, toAsString); } } // now check the default default... SqlDatabaseDefault existingDefault = existingColumn.DefaultExpression; SqlDatabaseDefault newDefault = column.DefaultExpression; // alter... if (changed && !(column.IsLarge)) { // Now we can check the indexes are on this column as they need to be removed foreach (SqlIndex index in existingTable.Indexes) { if (index.Columns.Contains(column.NativeName)) { removedIndexes.Add(index); results.Add(new DropIndexSchemaWorkUnit(_entityType, existingTable, index)); } } // Now we can check the foreign keys are on this column as they need to be removed foreach (SqlChildToParentLink foreignKey in existingTable.LinksToParents) { if (foreignKey.Columns.Contains(column.NativeName)) { removedForeignKeys.Add(foreignKey); results.Add(new DropForeignKeySchemaWorkUnit(_entityType, foreignKey)); } } // mbr - 24-07-2007 - case 321 - added reason. results.Add(new AlterColumnSchemaWorkUnit(_entityType, column, newType, newLength, newIsLarge, newIsNullable, newDefault, reason)); } if (((existingDefault != null && newDefault == null) || (existingDefault == null && newDefault != null)) || (existingDefault != null && newDefault != null && !(existingDefault.Equals(newDefault)))) { if (existingDefault != null) { results.Add(new DropConstraintSchemaWorkUnit(_entityType, column, existingDefault)); } if (newDefault != null) { results.Add(new AddConstraintSchemaWorkUnit(_entityType, column, newDefault)); } } } } // Check existing indexes foreach (SqlIndex index in Indexes) { SqlIndex existingIndex = null; foreach (SqlIndex scanIndex in existingTable.Indexes) { // if (string.Compare(scanIndex.NativeName, index.NativeName, true, System.Globalization.CultureInfo.InvariantCulture) == 0) { // mbr - 2011-11-02 - do we need to drop it? if (!(scanIndex.DoesMatch(index))) { // drop... results.Add(new DropIndexSchemaWorkUnit(_entityType, this, index)); } else { // create... existingIndex = scanIndex; } // stop... break; } } // found? if (existingIndex == null || removedIndexes[existingIndex.Name] != null) { results.Add(new CreateIndexSchemaWorkUnit(_entityType, this, index)); } } // Check existing foreign keys foreach (SqlChildToParentLink foreignKey in LinksToParents) { SqlChildToParentLink existingForeignKey = null; foreach (SqlChildToParentLink scanForeignKey in existingTable.LinksToParents) { // if (string.Compare(scanForeignKey.NativeName, foreignKey.NativeName, true, System.Globalization.CultureInfo.InvariantCulture) == 0) { existingForeignKey = scanForeignKey; break; } } // found? if (existingForeignKey == null || removedIndexes[existingForeignKey.Name] != null) { // mbr - 04-10-2007 - case 825 - only do this if the parent is referenced in the schema... if (Schema == null) { throw new InvalidOperationException("Schema is null."); } bool ok = foreignKey.IsSupported(this.Schema); // ok? if (ok) { results.Add(new CreateForeignKeySchemaWorkUnit(_entityType, foreignKey)); } } } // return... return(results); }
/// <summary> /// Called when a column is discovered. /// </summary> /// <param name="column"></param> protected virtual void TableDiscovered(SqlTable table) { }
/// <summary> /// Creates a table from the given row. /// </summary> /// <param name="row"></param> /// <returns></returns> private SqlTable GetSchemaTable(DataRow row, SqlSchema schema) { if (row == null) { throw new ArgumentNullException("row"); } if (schema == null) { throw new ArgumentNullException("schema"); } // get the name... string nativeName = (string)row["table_name"]; if (nativeName == null) { throw new ArgumentNullException("nativeName"); } if (nativeName.Length == 0) { throw new ArgumentOutOfRangeException("'nativeName' is zero-length."); } try { // name... string name = SqlTable.SuggestSingularName(nativeName); name = CodeDomHelper.GetPascalName(name); // create... SqlTable schemaTable = new SqlTable(nativeName, name); // mbr - 04-10-2007 - set schema... schemaTable.SetSchema(schema); // get the columns... if (Connection == null) { throw new InvalidOperationException("Connection is null."); } DataTable table = this.Connection.ExecuteDataTable(new SqlStatement("select column_name, is_nullable, data_type, character_maximum_length from information_schema.columns where table_name=@p0 order by ordinal_position", new object[] { nativeName }, this.Dialect)); foreach (DataRow columnRow in table.Rows) { // create... SqlColumn schemaColumn = this.GetSchemaColumn(columnRow); schemaTable.Columns.Add(schemaColumn); // mbr - 04-10-2007 - set owner... schemaColumn.SetSchema(schemaTable.Schema); // mbr - 01-11-2005 - added SQL Server specific stuff... this.ColumnDiscovered(schemaColumn); } // fix... FixupCommonFlags(schemaTable); // mbr - 01-11-2005 - added opportunity to fixup... TableDiscovered(schemaTable); // return... return(schemaTable); } catch (Exception ex) { throw new InvalidOperationException(string.Format("Failed when processing table '{0}'.", nativeName), ex); } }