mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-14 18:47:44 -05:00
Integrate generate script with task service (#426)
* Support generate script for backup * change * update task service data contract for Generate Script * more changes * update test * add comments * Add missing files * update stub backup operation for testing * pr comments * remove empty space * Fix tests * Add unit/integration tests and isCancelable to TaskInfo * address pr comments * pr comments - fix tests * fix minor issue * fix minor issues * remove unused variable
This commit is contained in:
@@ -20,6 +20,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices.Contracts
|
||||
/// </summary>
|
||||
public SqlTaskStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Task execution mode
|
||||
/// </summary>
|
||||
public TaskExecutionMode TaskExecutionMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Database server name this task is created for
|
||||
/// </summary>
|
||||
@@ -30,7 +35,6 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices.Contracts
|
||||
/// </summary>
|
||||
public string DatabaseName { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Task name which defines the type of the task (e.g. CreateDatabase, Backup)
|
||||
/// </summary>
|
||||
@@ -52,5 +56,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices.Contracts
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the task can be canceled
|
||||
/// </summary>
|
||||
public bool IsCancelable { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,15 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices.Contracts
|
||||
public SqlTaskStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Database server name this task is created for
|
||||
/// Progress message
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Script for the task execution
|
||||
/// </summary>
|
||||
public string Script { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of millisecond the task was running
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines interface for task operations
|
||||
/// </summary>
|
||||
public interface ITaskOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// Execute a task
|
||||
/// </summary>
|
||||
/// <param name="mode">Task execution mode (e.g. script or execute)</param>
|
||||
void Execute(TaskExecutionMode mode);
|
||||
|
||||
/// <summary>
|
||||
/// Cancel a task
|
||||
/// </summary>
|
||||
void Cancel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines interface for scriptable task operations
|
||||
/// </summary>
|
||||
public interface IScriptableTaskOperation: ITaskOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// Script for the task operation
|
||||
/// </summary>
|
||||
string ScriptContent { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
private SqlTaskStatus status = SqlTaskStatus.NotStarted;
|
||||
private DateTime stopTime;
|
||||
|
||||
public event EventHandler<TaskEventArgs<TaskScript>> ScriptAdded;
|
||||
public event EventHandler<TaskEventArgs<TaskMessage>> MessageAdded;
|
||||
public event EventHandler<TaskEventArgs<SqlTaskStatus>> StatusChanged;
|
||||
|
||||
@@ -119,7 +120,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
/// <returns></returns>
|
||||
internal async Task<TaskResult> RunAndCancel()
|
||||
{
|
||||
AddMessage(SR.Task_InProgress, SqlTaskStatus.InProgress, true);
|
||||
AddMessage(SR.TaskInProgress, SqlTaskStatus.InProgress, true);
|
||||
|
||||
TaskResult taskResult = new TaskResult();
|
||||
Task<TaskResult> performTask = TaskToRun(this);
|
||||
@@ -129,15 +130,15 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
{
|
||||
if (TaskToCancel != null)
|
||||
{
|
||||
AutoResetEvent backupCompletedEvent = new AutoResetEvent(initialState: false);
|
||||
Task<TaskResult> cancelTask = Task.Run(() => CancelTaskAsync(TokenSource.Token, backupCompletedEvent));
|
||||
AutoResetEvent onCompletedEvent = new AutoResetEvent(initialState: false);
|
||||
Task<TaskResult> cancelTask = Task.Run(() => CancelTaskAsync(TokenSource.Token, onCompletedEvent));
|
||||
|
||||
completedTask = await Task.WhenAny(performTask, cancelTask);
|
||||
|
||||
// Release the cancelTask
|
||||
if (completedTask == performTask)
|
||||
{
|
||||
backupCompletedEvent.Set();
|
||||
onCompletedEvent.Set();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -145,7 +146,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
completedTask = await Task.WhenAny(performTask);
|
||||
}
|
||||
|
||||
AddMessage(completedTask.Result.TaskStatus == SqlTaskStatus.Failed ? completedTask.Result.ErrorMessage : SR.Task_Completed,
|
||||
AddMessage(completedTask.Result.TaskStatus == SqlTaskStatus.Failed ? completedTask.Result.ErrorMessage : SR.TaskCompleted,
|
||||
completedTask.Result.TaskStatus);
|
||||
taskResult = completedTask.Result;
|
||||
|
||||
@@ -174,16 +175,16 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
/// </summary>
|
||||
/// <param name="backupOperation"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="backupCompletedEvent"></param>
|
||||
/// <param name="onCompletedEvent"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<TaskResult> CancelTaskAsync(CancellationToken token, AutoResetEvent backupCompletedEvent)
|
||||
private async Task<TaskResult> CancelTaskAsync(CancellationToken token, AutoResetEvent onCompletedEvent)
|
||||
{
|
||||
// Create a task for backup cancellation request
|
||||
|
||||
TaskResult result = new TaskResult();
|
||||
WaitHandle[] waitHandles = new WaitHandle[2]
|
||||
{
|
||||
backupCompletedEvent,
|
||||
onCompletedEvent,
|
||||
token.WaitHandle
|
||||
};
|
||||
|
||||
@@ -371,6 +372,26 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
IsCancelRequested = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add script result of the operation
|
||||
/// </summary>
|
||||
/// <param name="script">Script content</param>
|
||||
/// <param name="errorMessage">Error occured during script</param>
|
||||
/// <param name="status">Status of the script</param>
|
||||
/// <returns></returns>
|
||||
public TaskScript AddScript(SqlTaskStatus status, string script, string errorMessage = null)
|
||||
{
|
||||
var newScript = new TaskScript
|
||||
{
|
||||
Status = status,
|
||||
Script = script,
|
||||
ErrorMessage = errorMessage
|
||||
};
|
||||
|
||||
OnScriptAdded(new TaskEventArgs<TaskScript>(newScript, this));
|
||||
return newScript;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new message to the task messages
|
||||
/// </summary>
|
||||
@@ -430,6 +451,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
ServerName = TaskMetadata.ServerName,
|
||||
Name = TaskMetadata.Name,
|
||||
Description = TaskMetadata.Description,
|
||||
TaskExecutionMode = TaskMetadata.TaskExecutionMode,
|
||||
IsCancelable = TaskMetadata.IsCancelable,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -465,6 +488,15 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScriptAdded(TaskEventArgs<TaskScript> e)
|
||||
{
|
||||
var handler = ScriptAdded;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMessageAdded(TaskEventArgs<TaskMessage> e)
|
||||
{
|
||||
var handler = MessageAdded;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Task execution mode
|
||||
/// </summary>
|
||||
public enum TaskExecutionMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Execute task
|
||||
/// </summary>
|
||||
Execute,
|
||||
|
||||
/// <summary>
|
||||
/// Script task
|
||||
/// </summary>
|
||||
Script,
|
||||
|
||||
/// <summary>
|
||||
/// Execute and script task
|
||||
/// Needed for tasks that will show the script when execution completes
|
||||
/// </summary>
|
||||
ExecuteAndScript
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Task execution mode (e.g. execute or script)
|
||||
/// </summary>
|
||||
public TaskExecutionMode TaskExecutionMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of seconds to wait before canceling the task.
|
||||
/// This is a optional field and 0 or negative numbers means no timeout
|
||||
@@ -41,6 +46,6 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
/// <summary>
|
||||
/// Data required to perform the task
|
||||
/// </summary>
|
||||
public object Data { get; set; }
|
||||
public object Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Task script message
|
||||
/// </summary>
|
||||
public class TaskScript
|
||||
{
|
||||
/// <summary>
|
||||
/// Status of script
|
||||
/// </summary>
|
||||
public SqlTaskStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Script content
|
||||
/// </summary>
|
||||
public string Script { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Error occurred during script
|
||||
/// </summary>
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -116,6 +116,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
if (sqlTask != null)
|
||||
{
|
||||
TaskInfo taskInfo = sqlTask.ToTaskInfo();
|
||||
sqlTask.ScriptAdded += OnTaskScriptAdded;
|
||||
sqlTask.MessageAdded += OnTaskMessageAdded;
|
||||
sqlTask.StatusChanged += OnTaskStatusChanged;
|
||||
await serviceHost.SendEvent(TaskCreatedNotification.Type, taskInfo);
|
||||
@@ -131,7 +132,6 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
{
|
||||
TaskId = sqlTask.TaskId.ToString(),
|
||||
Status = e.TaskData
|
||||
|
||||
};
|
||||
|
||||
if (sqlTask.IsCompleted)
|
||||
@@ -141,6 +141,23 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
||||
await serviceHost.SendEvent(TaskStatusChangedNotification.Type, progressInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnTaskScriptAdded(object sender, TaskEventArgs<TaskScript> e)
|
||||
{
|
||||
SqlTask sqlTask = e.SqlTask;
|
||||
if (sqlTask != null)
|
||||
{
|
||||
TaskProgressInfo progressInfo = new TaskProgressInfo
|
||||
{
|
||||
TaskId = sqlTask.TaskId.ToString(),
|
||||
Status = e.TaskData.Status,
|
||||
Script = e.TaskData.Script,
|
||||
Message = e.TaskData.ErrorMessage,
|
||||
};
|
||||
|
||||
await serviceHost.SendEvent(TaskStatusChangedNotification.Type, progressInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnTaskMessageAdded(object sender, TaskEventArgs<TaskMessage> e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user