Beispiel #1
0
        /// <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;
 }
Beispiel #4
0
        /// <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);
            }
        }