/// <summary> /// called before dialog's host executes actions on all panels in the dialog one by one. /// If something fails inside this function and the execution should be aborted, /// it can either raise an exception [in which case the framework will show message box with exception text] /// or set executionResult out parameter to be ExecutionMode.Failure /// NOTE: it might be called from worker thread /// </summary> /// <param name="executionInfo">information about execution action</param> /// <param name="executionResult">result of the execution</param> /// <returns> /// true if regular execution should take place, false if everything /// has been done by this function /// NOTE: in case of returning false during scripting operation /// PreProcessExecutionInfo.Script property of executionInfo parameter /// MUST be set by this function [if execution result is success] /// </returns> public bool PreProcessExecution(PreProcessExecutionInfo executionInfo, out ExecutionMode executionResult) { //we start from failure executionResult = ExecutionMode.Failure; //OK, we do server switching for scripting for SQL/Analysis Server execution here RunType runType = executionInfo.RunType; if (IsScripting(runType)) { if (!PreProcessScripting(executionInfo, out executionResult)) { return(false); } } if (DataContainer != null) { //we take over execution here. We substitute the server here for AMO and SQL //dialogs if (DataContainer.ContainerServerType == CDataContainer.ServerType.SQL) { ExecuteForSql(executionInfo, out executionResult); return(false);//execution of the entire control was done here } } // call virtual function to do regular execution return(DoPreProcessExecution(executionInfo.RunType, out executionResult)); }
/// <summary> /// called when we need to script a Sql server dlg. /// </summary> /// <param name="executionInfo"></param> /// <param name="executionResult"></param> private void ExecuteForSql(PreProcessExecutionInfo executionInfo, out ExecutionMode executionResult) { Microsoft.SqlServer.Management.Smo.Server oldServer = null; if (NeedToSwitchServer) { // We use a new instance of the SMO Server object every time we script // so that any changes that are made to the SMO server while scripting are // not kept when the script operation is completed. oldServer = DataContainer.Server; //BUGBUG - see if we can use copy ctor instead DataContainer.Server = new Microsoft.SqlServer.Management.Smo.Server(DataContainer.ServerConnection); } String szScript = null; bool isScripting = IsScripting(executionInfo.RunType); var executionModeOriginal = GetServerConnectionForScript().SqlExecutionModes; //For Azure the ExecutionManager is different depending on which ExecutionManager //used - one at the Server level and one at the Database level. So to ensure we //don't use the wrong execution mode we need to set the mode for both (for on-prem //this will essentially be a no-op) SqlExecutionModes subjectExecutionModeOriginal = executionModeOriginal; SqlSmoObject sqlDialogSubject = null; try { sqlDialogSubject = this.DataContainer.SqlDialogSubject; } catch (System.Exception) { //We may not have a valid dialog subject here (such as if the object hasn't been created yet) //so in that case we'll just ignore it as that's a normal scenario. } if (sqlDialogSubject != null) { subjectExecutionModeOriginal = sqlDialogSubject.ExecutionManager.ConnectionContext.SqlExecutionModes; } try { SqlExecutionModes newMode = isScripting ? SqlExecutionModes.CaptureSql : SqlExecutionModes.ExecuteSql; //now, do the execution itself GetServerConnectionForScript().SqlExecutionModes = newMode; if (sqlDialogSubject != null) { sqlDialogSubject.ExecutionManager.ConnectionContext.SqlExecutionModes = newMode; } executionResult = DoPreProcessExecutionAndRunViews(executionInfo.RunType); if (isScripting) { if (executionResult == ExecutionMode.Success) { szScript = BuildSqlScript(); } } } finally { GetServerConnectionForScript().SqlExecutionModes = executionModeOriginal; if (isScripting) { GetServerConnectionForScript().CapturedSql.Clear(); } if (sqlDialogSubject != null) { sqlDialogSubject.ExecutionManager.ConnectionContext.SqlExecutionModes = subjectExecutionModeOriginal; if (isScripting) { sqlDialogSubject.ExecutionManager.ConnectionContext.CapturedSql.Clear(); } } //see if we need to restore the server if (oldServer != null) { DataContainer.Server = oldServer; } } if (isScripting) { executionInfo.Script = szScript; } }
/// <summary> /// Called to intercept scripting operation /// </summary> /// <param name="executionInfo"></param> /// <param name="executionResult"></param> /// <returns> /// true if regular execution should take place, false the script /// has been created by this function /// </returns> protected virtual bool PreProcessScripting(PreProcessExecutionInfo executionInfo, out ExecutionMode executionResult) { //we don't do anything here, but we enable derived classes to do something... executionResult = ExecutionMode.Success; return(true); }
/// <summary> /// we call the run now implementaion of the management action. /// If any exception is generated we stop the execution and we set the execution mode flag to failure. /// </summary> /// <param name="sender"></param> public void RunNow(RunType runType, object sender) { try { // reset some internal vars this.executionResult = ExecutionMode.Failure; // ensure that we have valid StringBulder for scripting if (IsScripting(runType)) { EnsureValidScriptBuilder(); } // do preprocess action. It is possible to do entire execution from inside this method if (this.managementAction != null) { PreProcessExecutionInfo preProcessInfo = new PreProcessExecutionInfo(runType); if (!this.managementAction.PreProcessExecution(preProcessInfo, out this.executionResult)) { // In case of scripting preProcessInfo.Script must contain text of the script if (executionResult == ExecutionMode.Success && IsScripting(runType) && preProcessInfo.Script != null) { this.script.Append(preProcessInfo.Script); } return; // result of execution is in executionResult } } // NOTE: post process action is done in finally block below // start executing this.executionResult = this.executionHandlerDelegate.Run(runType, sender); } #region error handling catch (OutOfMemoryException) { throw; } catch (System.Threading.ThreadAbortException) { throw; } catch (OperationCanceledException) { this.executionResult = ExecutionMode.Cancel; } catch (Exception e) { ProcessExceptionDuringExecution(e); return; } finally { //do postprocess action if (this.managementAction != null) { this.managementAction.PostProcessExecution(runType, this.executionResult); } } #endregion }