Пример #1
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="operation"></param>
        // mbr - 2009-07-21 - made public...
        //internal DatabaseUpdateContext(IOperationItem operation)
        public DatabaseUpdateContext(IOperationItem operation, bool trace)
		{
			if(operation == null)
				operation = new OperationItem();
			_operation = operation;
            this.Trace = trace;
		}
Пример #2
0
        /// <summary>
        /// Gets the bar for the given item.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private FloatingOperationDialogBar GetBarForItem(IOperationItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            // find the bar with the given item...
            FloatingOperationDialogBar bar = null;

            foreach (FloatingOperationDialogBar scanBar in this.panelBars.Controls)
            {
                if (scanBar.Item == item)
                {
                    bar = scanBar;
                    break;
                }
            }

            // not found... create one...
            if (bar == null)
            {
                bar = this.AddBar(item);
            }

            // return...
            return(bar);
        }
Пример #3
0
        /// <summary>
        /// Updates the view.
        /// </summary>
        public void RefreshView()
        {
            if (this.InvokeRequired)
            {
                RefreshViewDelegate d = new RefreshViewDelegate(this.RefreshView);
                this.Invoke(d);
                return;
            }

            // set...
            IOperationItem item = this.CurrentItem;

            if (item != null)
            {
                // get the bar to display status information in...
                FloatingOperationDialogBar bar = this.GetBarForItem(item);
                if (bar != null)
                {
                    bar.RefreshView();
                }
            }
            else
            {
                if (this.IsDefaultBarVisible)
                {
                    this.DefaultBar.Status = this.Caption;
                }
            }
        }
Пример #4
0
 public GetSchemaArgs(IOperationItem op)
 {
     if (op == null)
     {
         op = new OperationItem();
     }
     _operationItem = op;
 }
Пример #5
0
 /// <summary>
 /// Adds a IOperationItem instance to the collection.
 /// </summary>
 /// <param name="item">The item to add.</param>
 public void Add(IOperationItem item)
 {
     if (item == null)
     {
         throw new ArgumentNullException("item");
     }
     List.Add(item);
 }
Пример #6
0
 /// <summary>
 /// Inserts a IOperationItem instance into the collection.
 /// </summary>
 /// <param name="item">The item to add.</param>
 public void Insert(int index, IOperationItem item)
 {
     if (item == null)
     {
         throw new ArgumentNullException("item");
     }
     List.Insert(index, item);
 }
Пример #7
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="log"></param>
 /// <param name="innerOperation"></param>
 public EntityGenerationContext(EntityGenerator generator, ILog log, IOperationItem innerOperation)
     : base(log, innerOperation)
 {
     if (generator == null)
     {
         throw new ArgumentNullException("generator");
     }
     _generator = generator;
 }
Пример #8
0
 /// <summary>
 /// Discovers if the given item is in the collection.
 /// </summary>
 /// <param name="item">The item to find.</param>
 /// <returns>Returns true if the given item is in the collection.</returns>
 public bool Contains(IOperationItem item)
 {
     if (IndexOf(item) == -1)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
Пример #9
0
        public FloatingOperationDialogBar(IOperationItem item) : this()
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            // set...
            _item = item;
            this.RefreshView();
        }
Пример #10
0
        internal DatabaseUpdateUIWorker(ConnectionSettings settings, DatabaseUpdateOperation type, IOperationItem operation)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            // set...
            _settings  = settings;
            _type      = type;
            _operation = operation;
        }
Пример #11
0
        ///// <summary>
        ///// Gets the work units that describe the differences between two schemas.
        ///// </summary>
        ///// <param name="existingSchema"></param>
        ///// <returns></returns>
        //public WorkUnitCollection GetSchemaWorkUnits(SqlSchema existingSchema)
        //{
        //	return this.GetSchemaWorkUnits(existingSchema, null);
        //}

        /// <summary>
        /// Gets the work units that describe the differences between two schemas.
        /// </summary>
        /// <param name="existingSchema"></param>
        /// <returns></returns>
        public WorkUnitCollection GetSchemaWorkUnits(SqlSchema existingSchema, IOperationItem operation = null)
        {
            if (existingSchema == null)
            {
                throw new ArgumentNullException("existingSchema");
            }

            // item...
            if (operation == null)
            {
                operation = new OperationItem();
            }

            // results...
            WorkUnitCollection results = new WorkUnitCollection();

            // find missing tables...
            operation.ProgressMaximum = this.Tables.Count;
            operation.ProgressValue   = 0;
            foreach (SqlTable table in this.Tables)
            {
                // walk...
                SqlTable matchingTable = null;
                foreach (SqlTable existingTable in existingSchema.Tables)
                {
                    if (string.Compare(table.NativeName, existingTable.NativeName, true, System.Globalization.CultureInfo.InvariantCulture) == 0)
                    {
                        matchingTable = existingTable;
                        break;
                    }
                }

                // found?
                if (matchingTable == null)
                {
                    results.AddRange(table.GetCreateTableWorkUnit());
                }
                else
                {
                    results.AddRange(table.GetSchemaWorkUnits(matchingTable));
                }

                // next...
                operation.IncrementProgress();
            }

            // mbr - 14-12-2005 - sort the units...
            results.Sort(new SchemaWorkUnitTypeComparer());

            // return...
            return(results);
        }
Пример #12
0
        /// <summary>
        /// Removes a IOperationItem item to the collection.
        /// </summary>
        /// <param name="item">The item to remove.</param>
        public void Remove(IOperationItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            // remove it... this is a safer version that doesn't throw if the item is not found...
            int index = this.IndexOf(item);

            if (index != -1)
            {
                this.RemoveAt(index);
            }
        }
Пример #13
0
        /// <summary>
        /// Adds a bar to the view.
        /// </summary>
        /// <returns></returns>
        private FloatingOperationDialogBar AddBar(IOperationItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            // invoke?
            if (this.InvokeRequired)
            {
                // flip...
                AddBarDelegate d = new AddBarDelegate(this.AddBar);
                return((FloatingOperationDialogBar)this.Invoke(d, new object[] { item }));
            }

            // layout...
            this.panelBars.SuspendLayout();
            try
            {
                // clear...
                if (this.IsDefaultBarVisible)
                {
                    this.panelBars.Controls.Clear();
                }

                // create...
                FloatingOperationDialogBar bar = new FloatingOperationDialogBar(item);
                bar.Dock = DockStyle.Top;
                this.panelBars.Controls.Add(bar);

                // listen...
                item.Finished += new EventHandler(item_Finished);

                // set...
                _currentItem = item;

                // return...
                return(bar);
            }
            finally
            {
                this.panelBars.ResumeLayout();
            }
        }
Пример #14
0
        /// <summary>
        /// Creates a context.
        /// </summary>
        /// <param name="log"></param>
        public OperationContext(ILog log, IOperationItem innerOperation)
        {
            if (log == null)
            {
                log = new NullLog();
            }
            _innerLog = log;

            // check...
            if (innerOperation == null)
            {
                innerOperation             = new OperationItem();
                _defaultInnerOperationUsed = true;
            }
            _innerOperation = innerOperation;

            // setup...
            _logItems.ItemAdded += new OperationLogItemEventHandler(_logItems_ItemAdded);
        }
Пример #15
0
        /// <summary>
        /// Removes the bar from the view.
        /// </summary>
        /// <param name="item"></param>
        private void RemoveBar(IOperationItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            // invoke...
            if (this.InvokeRequired)
            {
                // flip...
                RemoveBarDelegate d = new RemoveBarDelegate(this.RemoveBar);
                this.Invoke(d, new object[] { item });
                return;
            }

            // layout...
            this.panelBars.SuspendLayout();
            try
            {
                // fins...
                FloatingOperationDialogBar bar = this.GetBarForItem(item);
                if (bar != null)
                {
                    // unsub...
                    item.Finished -= new EventHandler(item_Finished);

                    // remove...
                    this.panelBars.Controls.Remove(bar);

                    // count?
                    if (this.panelBars.Controls.Count == 0)
                    {
                        ShowDefaultBar();
                    }
                }
            }
            finally
            {
                this.panelBars.ResumeLayout();
            }
        }
Пример #16
0
 /// <summary>
 /// Checks to see what needs to be done in order to update the database.
 /// </summary>
 /// <param name="operation"></param>
 /// <returns></returns>
 public DatabaseUpdateCheckResults Check(IOperationItem operation, DatabaseUpdateArgs args)
 {
     return(this.CreateUpdateDatabase(operation, false, true, args));
 }
Пример #17
0
 /// <summary>
 /// Creates a database.
 /// </summary>
 /// <param name="operation"></param>
 public void Create(IOperationItem operation, DatabaseUpdateArgs args)
 {
     this.CreateUpdateDatabase(operation, true, false, args);
 }
Пример #18
0
        /// <summary>
        /// Processes the given work units.
        /// </summary>
        /// <param name="units"></param>
        public void Process(WorkUnitCollection units, bool trace = false, IOperationItem operation = null, bool outsideTransaction = false, ITimingBucket timings = null)
        {
            if (units == null)
            {
                throw new ArgumentNullException("units");
            }
            if (units.Count == 0)
            {
                return;
            }

            // operation...
            if (timings == null)
            {
                timings = NullTimingBucket.Instance;
            }
            if (operation == null)
            {
                operation = NullOperationItem.Instance;
            }

            // mbr - 02-10-2007 - case 827 - notify outside...
            // mbr - 2014-11-30 - changed this to load up the statements...
            var touchedEts          = new List <EntityType>();
            var anyNeedsTransaction = units.Count > 1;
            var context             = new WorkUnitProcessingContext(timings);

            using (timings.GetTimer("Count"))
            {
                foreach (IWorkUnit unit in units)
                {
                    ISaveChangesNotification notification = unit.Entity as ISaveChangesNotification;
                    if (notification != null)
                    {
                        notification.BeforeSaveChangesOutTransaction(unit);
                    }

                    // add...
                    if (!(touchedEts.Contains(unit.EntityType)))
                    {
                        touchedEts.Add(unit.EntityType);
                    }

                    // add...
                    if (unit.NeedsTransaction && !(anyNeedsTransaction))
                    {
                        anyNeedsTransaction = true;
                    }
                }
            }

            // mbr - 26-11-2007 - get a manager for this thread...
            IWorkUnitTransactionManager manager = null;

            using (timings.GetTimer("Initialize manager"))
            {
                if (outsideTransaction)
                {
                    manager = new OutsideTransactionWorkUnitProcessorTransactionManager();
                }
                else
                {
                    //manager = WorkUnitProcessorTransactionManager.Current;

                    // mbr - 2014-11-30 - we only want to use transactions if we are in a tranaction. the old
                    // approach created a transaction just for single row inserts, which turned out created
                    // quite a slowdown...
                    if (anyNeedsTransaction)
                    {
                        manager = WorkUnitProcessorTransactionManager.Current;
                    }
                    else
                    {
                        manager = WorkUnitProcessorNullTransactionManager.Current;
                    }
                }
                if (manager == null)
                {
                    throw new InvalidOperationException("manager is null.");
                }

                // initialise the manager...
                manager.Initialize();
            }

            try
            {
                // mbr - 26-11-2007 - now done in the manager...
//				if(connection == null)
//					connection = Database.CreateConnection(units[0].EntityType.DatabaseName);

                // mbr - 26-11-2007 - don't do transactions here (the manager will do it)...
//				connection.BeginTransaction();
                try
                {
                    // reset the bag...
                    using (timings.GetTimer("Reset"))
                        context.ResetBag();

                    // run...
                    operation.ProgressMaximum = units.Count;
                    operation.ProgressValue   = 0;

                    // mbr - 06-09-2007 - for c7 - the "before" event can replace the work unit.  (done by changing the entity and regenerating.)
                    //foreach(IWorkUnit unit in units)
                    for (int index = 0; index < units.Count; index++)
                    {
                        using (var child = timings.GetChildBucket("Execute"))
                        {
                            // get a connection to use here...
                            IConnection connection = null;
                            using (child.GetTimer("Connect"))
                            {
                                connection = manager.GetConnection(units[index]);
                                if (connection == null)
                                {
                                    throw new InvalidOperationException("connection is null.");
                                }

                                // set...
                                context.SetConnection(connection);
                            }

                            // get the unit...
                            IWorkUnit unit = units[index];
                            try
                            {
                                if (trace)
                                {
                                    this.LogInfo(() => string.Format("Running unit '{0}'...", unit));
                                }

                                ISaveChangesNotification notification = unit.Entity as ISaveChangesNotification;
                                using (child.GetTimer("NotifyPre"))
                                {
                                    // before...
                                    if (notification != null)
                                    {
                                        // mbr - 02-10-2007 - case 827 - changed interface.
                                        //								IWorkUnit newUnit = notification.BeforeSaveChanges(unit);
                                        IWorkUnit newUnit = notification.BeforeSaveChangesInTransaction(unit, connection);

                                        // patch it..
                                        if (newUnit != unit)
                                        {
                                            units[index] = newUnit;
                                            unit         = newUnit;
                                        }
                                    }
                                }

                                // run it...
                                using (var childChild = child.GetChildBucket("Process"))
                                    unit.Process(context, childChild);

                                // set...
                                using (child.GetTimer("Results"))
                                    unit.SetResultsBag(context.Bag);

                                // mbr - 10-10-2007 - for c7 - do reconciliation here...
                                using (child.GetTimer("Reconcile"))
                                {
                                    WorkUnitCollection forReconciliation = new WorkUnitCollection();
                                    forReconciliation.Add(unit);
                                    unit.EntityType.Persistence.ReconcileWorkUnitProcessorResults(forReconciliation);
                                }

                                // mbr - 02-10-2007 - case 827 - call...
                                using (child.GetTimer("NotifyPost"))
                                {
                                    if (notification != null)
                                    {
                                        notification.AfterSaveChangesInTransaction(unit, connection);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new InvalidOperationException(string.Format(Cultures.Exceptions, "Failed when processing '{0}'.", unit), ex);
                            }

                            // next...
                            operation.IncrementProgress();
                        }
                    }

                    // mbr - 26-11-2007 - it's the manager that needs to commit...
//					connection.Commit();

                    using (timings.GetTimer("Commit"))
                        manager.Commit();
                }
                catch (Exception ex)
                {
                    // rollback...
                    try
                    {
                        // mbr - 26-11-2007 - it's the manager that needs to rollback...
//						connection.Rollback();
                        manager.Rollback(ex);
                    }
                    catch (Exception rollbackEx)
                    {
                        // mbr - 26-11-2007 - added.
                        if (this.Log.IsWarnEnabled)
                        {
                            this.Log.Warn("A further exception occurred whilst rolling back the transaction.", rollbackEx);
                        }
                    }

                    // throw...
                    throw new InvalidOperationException("Failed to process work units.", ex);
                }
            }
            finally
            {
                // mbr - 26-11-2007 - get the manager to tear down...
//				if(connection != null)
//					connection.Dispose();
                using (timings.GetTimer("Dispose"))
                    manager.Dispose();

                // mbr - 2010-04-19 - invalidate the caches...
                //EntityCache.Invalidate(touchedEts);

                // flag...
                foreach (IWorkUnit unit in units)
                {
                    ISaveChangesNotification notification = unit.Entity as ISaveChangesNotification;
                    if (notification != null)
                    {
                        notification.AfterSaveChangesOutTransaction(unit);
                    }
                }
            }
        }
Пример #19
0
 public void Update(IOperationItem operation)
 {
     this.Update(operation, new DatabaseUpdateArgs());
 }
Пример #20
0
 /// <summary>
 /// Returns the index of the item in the collection.
 /// </summary>
 /// <param name="item">The item to find.</param>
 /// <returns>The index of the item, or -1 if it is not found.</returns>
 public int IndexOf(IOperationItem item)
 {
     return(List.IndexOf(item));
 }
Пример #21
0
 public DatabaseUpdateCheckResults Check(IOperationItem operation)
 {
     return(this.Check(operation, new DatabaseUpdateArgs()));
 }
Пример #22
0
        /// <summary>
        /// Generates the selected tables.
        /// </summary>
        internal void Generate(Project project, string entitiesFolderPath, string servicesFolderPath, string proceduresFolderPath,
                               ArrayList lockedFiles, IOperationItem item)
        {
            if (project == null)
            {
                throw new ArgumentNullException("project");
            }
            if (entitiesFolderPath == null)
            {
                throw new ArgumentNullException("entitiesFolderPath");
            }
            if (entitiesFolderPath.Length == 0)
            {
                throw new ArgumentOutOfRangeException("'entitiesFolderPath' is zero-length.");
            }
            if (proceduresFolderPath == null)
            {
                throw new ArgumentNullException("proceduresFolderPath");
            }
            if (proceduresFolderPath.Length == 0)
            {
                throw new ArgumentOutOfRangeException("'proceduresFolderPath' is zero-length.");
            }

            // item?
            if (item == null)
            {
                item = new OperationItem();
            }

            // busy...
            item.ProgressValue = 0;
            item.Status        = "Retrieving tables...";
            SqlTable[] tables = project.Schema.GetTablesForGeneration();
            item.ProgressMaximum = tables.Length;

            // walk the tables...
            foreach (SqlTable table in tables)
            {
                if (!table.Generate)
                {
                    continue;
                }

                item.Status = string.Format("Generating '{0}' classes...", table.Name);
                this.Generate(project, entitiesFolderPath, servicesFolderPath, table, lockedFiles);
                item.IncrementProgress();
            }

            // mbr - 15-06-2006 - walk the procs...
            item.ProgressValue = 0;
            item.Status        = "Retrieving tables...";
            SqlProcedure[] procs = project.Schema.GetProceduresForGeneration();
            item.ProgressMaximum = procs.Length;

            // walk the tables...
            foreach (SqlProcedure proc in procs)
            {
                if (!proc.Generate)
                {
                    continue;
                }

                item.Status = string.Format("Generating '{0}' classes...", proc.Name);
                this.Generate(project, proceduresFolderPath, proc, lockedFiles);
                item.IncrementProgress();
            }
        }
Пример #23
0
        /// <summary>
        /// Creates ot updates the database.
        /// </summary>
        /// <param name="create"></param>
        /// <param name="checkOnly"></param>
        // mbr - 28-09-2007 - case 814 - added args.
        private DatabaseUpdateCheckResults CreateUpdateDatabase(IOperationItem operation, bool create, bool checkOnly,
                                                                DatabaseUpdateArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            // operation...
            if (operation == null)
            {
                operation = new OperationItem();
            }

            // set...
            operation.Status = "Loading existing schema...";

            // database...
            SqlSchema databaseSchema = null;

            if (create)
            {
                databaseSchema = new SqlSchema();
            }
            else
            {
                if (args.Trace)
                {
                    this.LogInfo(() => "Loading schema...");
                }

                // mbr - 28-09-2007 - case 814 - defer to a method that can limit the types...
//				databaseSchema = Database.GetSchema();fic
                databaseSchema = this.GetSchema(args);
                if (databaseSchema == null)
                {
                    throw new InvalidOperationException("databaseSchema is null.");
                }
            }

            // Create an entity schema
            SqlSchema entitySchema = new SqlSchema();

            // Load all the entity types from the path
            ArrayList entityTypes = new ArrayList();

            // mbr - 02-10-2007 - for c7 - changed so that we can limit the entity types...
            if (args.LimitEntityTypes.Count == 0)
            {
                // mbr - 04-10-2007 - case 851 - do not do this behaviour (oddly both of these statements are
                // actually identical),
//				entityTypes.AddRange(EntityType.GetAllEntityTypes());
//				this.MergeEntityTypes(entityTypes, EntityType.LoadFromAttributes(AssemblyPath));
//				foreach(Assembly asm in this.Assemblies)
//					this.MergeEntityTypes(entityTypes, EntityType.LoadFromAttributes(asm));

                // load...
                this.MergeEntityTypes(entityTypes, EntityType.GetEntityTypes());
            }
            else
            {
                this.MergeEntityTypes(entityTypes, args.LimitEntityTypes);
            }

            // log...
            if (args.Trace)
            {
                this.LogInfo(() => string.Format("Found '{0}' entity types.", entityTypes.Count));
            }

            // steps...
            DatabaseUpdateStepCollection steps = new DatabaseUpdateStepCollection();

            if (args.AddArrayParameterUdts)
            {
                steps.Add(new AddArrayParameterUdtsUpdateStep());
            }

            SyncSchemaDatabaseUpdateStep syncStep = new SyncSchemaDatabaseUpdateStep();

            steps.Add(syncStep);

            // mbr - 02-03-2006 - we can have update steps that don't have an entity type...
            TypeFinder finder = new TypeFinder(typeof(DatabaseUpdateStep));

            finder.AddAttributeSpecification(typeof(DatabaseUpdateStepAttribute), false);
            Type[] stepTypes = finder.GetTypes();
            if (stepTypes == null)
            {
                throw new InvalidOperationException("stepTypes is null.");
            }

            // mbr - 02-10-2007 - for c7...
            if (Database.ExtensibilityProvider == null)
            {
                throw new InvalidOperationException("Database.ExtensibilityProvider is null.");
            }

            // Walk each entity type and add to entitySchema
            foreach (EntityType entityType in entityTypes)
            {
                // mbr - 14-12-2005 - should we do it?
                bool skip = entityType.Type.IsDefined(typeof(SkipDatabaseUpdateAttribute), false);

                // mbr - 2010-01-29 - changed the log here to allow db update to do named databases...
//				if(!(skip) && entityType.UsesDefaultDatabase)
                bool ok = false;
                if (!(skip))
                {
                    // no named database, and entity has no named database...
                    if (!(args.HasDatabaseName) && entityType.UsesDefaultDatabase)
                    {
                        ok = true;
                    }
                    else if (args.HasDatabaseName && string.Compare(entityType.DatabaseName, args.DatabaseName, true, Cultures.System) == 0)
                    {
                        ok = true;
                    }
                }
                else
                {
                    ok = false;
                }

                // do we do it?
                if (ok)
                {
                    if (args.Trace)
                    {
                        this.LogInfo(() => string.Format("Touching '{0}' ({1})...", entityType.Name, entityType.Type.Assembly.GetName().Name));
                    }

                    // add the base table...
                    SqlTable coreTable = SqlTable.GetTable(entitySchema, entityType);
                    if (coreTable == null)
                    {
                        throw new InvalidOperationException("coreTable is null.");
                    }
                    entitySchema.Tables.Add(coreTable);

                    // type...
                    Type type = entityType.Type;
                    if (type == null)
                    {
                        throw new InvalidOperationException("type is null.");
                    }

                    // reload it - something weird happens with these and they can't be used with the metadata so reload it so that we're
                    // certain we have the right ones...
                    type = Type.GetType(type.AssemblyQualifiedName, true, true);
                    if (type == null)
                    {
                        throw new InvalidOperationException("type is null.");
                    }

                    // mbr - 02-10-2007 - for c7 - add other tables that we need...
                    Database.ExtensibilityProvider.AddSchemaTables(entityType, type, coreTable, entitySchema);

                    // add the custom units...
                    foreach (Type stepType in stepTypes)
                    {
                        // get the attribute...
                        DatabaseUpdateStepAttribute[] attrs = (DatabaseUpdateStepAttribute[])stepType.GetCustomAttributes(typeof(DatabaseUpdateStepAttribute), true);
                        if (attrs == null)
                        {
                            throw new InvalidOperationException("attrs is null.");
                        }

                        // walk...
                        foreach (DatabaseUpdateStepAttribute attr in attrs)
                        {
                            if (attr.EntityType != null && attr.EntityType.IsAssignableFrom(type))
                            {
                                // create...
                                DatabaseUpdateStep step = (DatabaseUpdateStep)Activator.CreateInstance(stepType, new object[] { type });
                                if (step == null)
                                {
                                    throw new InvalidOperationException("step is null.");
                                }

                                // add..
                                steps.Add(step);
                            }
                        }
                    }
                }
                else
                {
                    if (args.Trace)
                    {
                        this.LogInfo(() => string.Format("Skipping '{0}'.", entityType.Name));
                    }
                }
            }

            // mbr - 02-10-2007 - for c7 - don't do custom steps if we're limiting entity types...
            if (args.LimitEntityTypes.Count == 0)
            {
                // do the ones that don't have entity types...
                foreach (Type stepType in stepTypes)
                {
                    // get the attribute...
                    DatabaseUpdateStepAttribute[] attrs = (DatabaseUpdateStepAttribute[])stepType.GetCustomAttributes(typeof(DatabaseUpdateStepAttribute), true);
                    if (attrs == null)
                    {
                        throw new InvalidOperationException("attrs is null.");
                    }

                    // walk...
                    foreach (DatabaseUpdateStepAttribute attr in attrs)
                    {
                        if (attr.EntityType == null)
                        {
                            // create...
                            DatabaseUpdateStep step = (DatabaseUpdateStep)Activator.CreateInstance(stepType);
                            if (step == null)
                            {
                                throw new InvalidOperationException("step is null.");
                            }

                            // add..
                            steps.Add(step);
                        }
                    }
                }
            }

            // get the work units...
            operation.Status = "Creating schema delta...";

            // mbr - 02-10-2007 - for c7 - changed to deferral.
//			syncStep.WorkUnits.AddRange(entitySchema.GetSchemaWorkUnits(databaseSchema, operation));
            syncStep.Initialize(entitySchema, databaseSchema);

            // run...
            if (!(checkOnly))
            {
                if (args.Trace)
                {
                    this.LogInfo(() => string.Format("Applying '{0}' steps...", steps.Count));
                }

                // context...
                DatabaseUpdateContext context = new DatabaseUpdateContext(operation, args.Trace);

                // mbr - 21-12-2005 - run the steps...
                foreach (DatabaseUpdateStep step in steps)
                {
                    try
                    {
                        if (args.Trace)
                        {
                            this.LogInfo(() => string.Format("Applying step: {0}", step));
                        }

                        // set...
                        operation.Status = string.Format("Running step '{0}'...", step);
                        step.Execute(context);
                    }
                    catch (Exception ex)
                    {
                        // log...
                        string message = string.Format("Failed database update when running step '{0}'.", step);
                        if (this.Log.IsErrorEnabled)
                        {
                            this.Log.Error(message, ex);
                        }

                        // throw...
                        throw new InvalidOperationException(message, ex);
                    }
                }
            }
            else
            {
                if (args.Trace)
                {
                    this.LogInfo(() => "Checking only -- not doing work.");
                }
            }

            if (args.Trace)
            {
                this.LogInfo(() => "Database update finished.");
            }

            this.OnUpdated();

            // return...
            return(new DatabaseUpdateCheckResults(steps));
        }