diff --git a/src/Microsoft.SqlTools.Hosting/Hosting/Contracts/DmpServerCapabilities.cs b/src/Microsoft.SqlTools.Hosting/Hosting/Contracts/DmpServerCapabilities.cs
index 13ec99c391..9ae40cde1a 100644
--- a/src/Microsoft.SqlTools.Hosting/Hosting/Contracts/DmpServerCapabilities.cs
+++ b/src/Microsoft.SqlTools.Hosting/Hosting/Contracts/DmpServerCapabilities.cs
@@ -3,6 +3,8 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
+using Microsoft.SqlTools.Hosting.Hosting.Contracts;
+
namespace Microsoft.SqlTools.Hosting.Contracts
{
///
@@ -19,5 +21,10 @@ public class DmpServerCapabilities
public ConnectionProviderOptions ConnectionProvider { get; set; }
public AdminServicesProviderOptions AdminServicesProvider { get; set; }
+
+ ///
+ /// List of features
+ ///
+ public FeatureMetadataProvider[] Features { get; set; }
}
}
diff --git a/src/Microsoft.SqlTools.Hosting/Hosting/Contracts/FeatureMetadataProvider.cs b/src/Microsoft.SqlTools.Hosting/Hosting/Contracts/FeatureMetadataProvider.cs
new file mode 100644
index 0000000000..d0dc0a8a90
--- /dev/null
+++ b/src/Microsoft.SqlTools.Hosting/Hosting/Contracts/FeatureMetadataProvider.cs
@@ -0,0 +1,31 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.Hosting.Contracts;
+
+namespace Microsoft.SqlTools.Hosting.Hosting.Contracts
+{
+ ///
+ /// Includes the metadata for a feature
+ ///
+ public class FeatureMetadataProvider
+ {
+ ///
+ /// Indicates whether the feature is enabled
+ ///
+ public bool Enabled { get; set; }
+
+ ///
+ /// Feature name
+ ///
+ public string FeatureName { get; set; }
+
+ ///
+ /// The options metadata avaialble for this feature
+ ///
+ public ServiceOption[] OptionsMetadata { get; set; }
+
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/Contracts/DatabaseFileInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/Contracts/DatabaseFileInfo.cs
index 9321655c93..187a8263e8 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/Contracts/DatabaseFileInfo.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/Contracts/DatabaseFileInfo.cs
@@ -29,6 +29,7 @@ public DatabaseFileInfo(LocalizedPropertyInfo[] properties)
var idProperty = this.Properties.FirstOrDefault(x => x.PropertyName == IdPropertyName);
Id = idProperty == null || idProperty.PropertyValue == null ? string.Empty : idProperty.PropertyValue.ToString();
}
+ IsSelected = true;
}
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/Contracts/RestoreRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/Contracts/RestoreRequest.cs
index be5f622b92..a328133355 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/Contracts/RestoreRequest.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/Contracts/RestoreRequest.cs
@@ -14,15 +14,18 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts
///
public class RestoreParams : GeneralRequestDetails
{
- public string SessionId
+ ///
+ /// Restore session id. The parameter is optional and if passed, an existing plan will be used
+ ///
+ internal string SessionId
{
get
{
- return GetOptionValue("sessionId");
+ return GetOptionValue(RestoreOptionsHelper.SessionId);
}
set
{
- SetOptionValue("sessionId", value);
+ SetOptionValue(RestoreOptionsHelper.SessionId, value);
}
}
@@ -34,75 +37,75 @@ public string SessionId
///
/// Comma delimited list of backup files
///
- public string BackupFilePaths
+ internal string BackupFilePaths
{
get
{
- return GetOptionValue("backupFilePaths");
+ return GetOptionValue(RestoreOptionsHelper.BackupFilePaths);
}
set
{
- SetOptionValue("backupFilePaths", value);
+ SetOptionValue(RestoreOptionsHelper.BackupFilePaths, value);
}
}
///
/// Target Database name to restore to
///
- public string TargetDatabaseName
+ internal string TargetDatabaseName
{
get
{
- return GetOptionValue("targetDatabaseName");
+ return GetOptionValue(RestoreOptionsHelper.TargetDatabaseName);
}
set
{
- SetOptionValue("targetDatabaseName", value);
+ SetOptionValue(RestoreOptionsHelper.TargetDatabaseName, value);
}
}
///
/// Source Database name to restore from
///
- public string SourceDatabaseName
+ internal string SourceDatabaseName
{
get
{
- return GetOptionValue("sourceDatabaseName");
+ return GetOptionValue(RestoreOptionsHelper.SourceDatabaseName);
}
set
{
- SetOptionValue("sourceDatabaseName", value);
+ SetOptionValue(RestoreOptionsHelper.SourceDatabaseName, value);
}
}
///
/// If set to true, the db files will be relocated to default data location in the server
///
- public bool RelocateDbFiles
+ internal bool RelocateDbFiles
{
get
{
- return GetOptionValue("relocateDbFiles");
+ return GetOptionValue(RestoreOptionsHelper.RelocateDbFiles);
}
set
{
- SetOptionValue("relocateDbFiles", value);
+ SetOptionValue(RestoreOptionsHelper.RelocateDbFiles, value);
}
}
///
/// Ids of the backup set to restore
///
- public string[] SelectedBackupSets
+ internal string[] SelectedBackupSets
{
get
{
- return GetOptionValue("selectedBackupSets");
+ return GetOptionValue(RestoreOptionsHelper.SelectedBackupSets);
}
set
{
- SetOptionValue("selectedBackupSets", value);
+ SetOptionValue(RestoreOptionsHelper.SelectedBackupSets, value);
}
}
}
@@ -160,8 +163,15 @@ public class RestoreDatabaseFileInfo
///
public class RestorePlanResponse
{
- public string RestoreSessionId { get; set; }
+ ///
+ /// Restore session id, can be used in restore request to use an existing restore plan
+ ///
+ public string SessionId { get; set; }
+
+ ///
+ /// The list of backup sets to restore
+ ///
public DatabaseFileInfo[] BackupSetsToRestore { get; set; }
///
@@ -185,30 +195,14 @@ public class RestorePlanResponse
public string[] DatabaseNamesFromBackupSets { get; set; }
///
- /// Server name
- ///
- public string ServerName { get; set; }
-
- ///
- /// Database name to restore to
- ///
- public string DatabaseName { get; set; }
-
- ///
- /// Indicates whether relocating the db files is required
- /// because the original file paths are not valid in the target server
- ///
- public bool RelocateFilesNeeded { get; set; }
-
- ///
- /// Default Data folder path in the target server
+ /// For testing purpose to verify the target database
///
- public string DefaultDataFolder { get; set; }
+ internal string DatabaseName { get; set; }
///
- /// Default log folder path in the target server
+ /// Plan details
///
- public string DefaultLogFolder { get; set; }
+ public Dictionary PlanDetails { get; set; }
}
public class RestoreRequest
diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOperation/RestoreDatabaseHelper.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOperation/RestoreDatabaseHelper.cs
index 43e0a40af6..97419b82b2 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOperation/RestoreDatabaseHelper.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOperation/RestoreDatabaseHelper.cs
@@ -24,7 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
///
public class RestoreDatabaseHelper
{
-
+ public const string LastBackupTaken = "lastBackupTaken";
private static RestoreDatabaseHelper instance = new RestoreDatabaseHelper();
private ConcurrentDictionary restoreSessions = new ConcurrentDictionary();
@@ -152,7 +152,8 @@ public RestorePlanResponse CreateRestorePlanResponse(RestoreDatabaseTaskDataObje
{
RestorePlanResponse response = new RestorePlanResponse()
{
- DatabaseName = restoreDataObject.RestoreParams.TargetDatabaseName
+ DatabaseName = restoreDataObject.RestoreParams.TargetDatabaseName,
+ PlanDetails = new System.Collections.Generic.Dictionary()
};
try
{
@@ -162,7 +163,7 @@ public RestorePlanResponse CreateRestorePlanResponse(RestoreDatabaseTaskDataObje
if (restoreDataObject != null && restoreDataObject.IsValid)
{
- response.RestoreSessionId = restoreDataObject.SessionId;
+ response.SessionId = restoreDataObject.SessionId;
response.DatabaseName = restoreDataObject.TargetDatabase;
response.DbFiles = restoreDataObject.DbFiles.Select(x => new RestoreDatabaseFileInfo
{
@@ -178,12 +179,25 @@ public RestorePlanResponse CreateRestorePlanResponse(RestoreDatabaseTaskDataObje
response.ErrorMessage = SR.RestoreNotSupported;
}
+ response.PlanDetails.Add(LastBackupTaken, restoreDataObject.GetLastBackupTaken());
+
response.BackupSetsToRestore = restoreDataObject.GetBackupSetInfo().Select(x => new DatabaseFileInfo(x.ConvertPropertiesToArray())).ToArray();
var dbNames = restoreDataObject.GetSourceDbNames();
response.DatabaseNamesFromBackupSets = dbNames == null ? new string[] { } : dbNames.ToArray();
- response.RelocateFilesNeeded = !restoreDataObject.DbFilesLocationAreValid();
- response.DefaultDataFolder = restoreDataObject.DefaultDataFileFolder;
- response.DefaultLogFolder = restoreDataObject.DefaultLogFileFolder;
+
+ // Adding the default values for some of the options in the plan details
+ bool isTailLogBackupPossible = restoreDataObject.IsTailLogBackupPossible(restoreDataObject.RestorePlanner.DatabaseName);
+ // Default backup tail-log. It's true when tail-log backup is possible for the source database
+ response.PlanDetails.Add(RestoreOptionsHelper.DefaultBackupTailLog, isTailLogBackupPossible);
+ // Default backup file for tail-log bacup when Tail-Log bachup is set to true
+ response.PlanDetails.Add(RestoreOptionsHelper.DefaultTailLogBackupFile,
+ restoreDataObject.Util.GetDefaultTailLogbackupFile(restoreDataObject.RestorePlan.DatabaseName));
+ // Default stand by file path for when RESTORE WITH STANDBY is selected
+ response.PlanDetails.Add(RestoreOptionsHelper.DefaultStandbyFile, restoreDataObject.Util.GetDefaultStandbyFile(restoreDataObject.RestorePlan.DatabaseName));
+ // Default Data folder path in the target server
+ response.PlanDetails.Add(RestoreOptionsHelper.DefaultDataFileFolder, restoreDataObject.DefaultDataFileFolder);
+ // Default log folder path in the target server
+ response.PlanDetails.Add(RestoreOptionsHelper.DefaultLogFileFolder, restoreDataObject.DefaultLogFileFolder);
}
else
{
@@ -314,12 +328,29 @@ private void UpdateRestorePlan(RestoreDatabaseTaskDataObject restoreDataObject)
restoreDataObject.RestorePlanner.DatabaseName = restoreDataObject.RestoreParams.SourceDatabaseName;
}
restoreDataObject.TargetDatabase = restoreDataObject.RestoreParams.TargetDatabaseName;
- //TODO: used for other types of restore
- /*bool isTailLogBackupPossible = restoreDataObject.RestorePlanner.IsTailLogBackupPossible(restoreDataObject.RestorePlanner.DatabaseName);
- restoreDataObject.RestorePlanner.BackupTailLog = isTailLogBackupPossible;
- restoreDataObject.TailLogBackupFile = restoreDataObject.Util.GetDefaultTailLogbackupFile(dbName);
- restoreDataObject.RestorePlanner.TailLogBackupFile = restoreDataObject.TailLogBackupFile;
- */
+
+ restoreDataObject.RestoreOptions.KeepReplication = restoreDataObject.RestoreParams.GetOptionValue(RestoreOptionsHelper.KeepReplication);
+ restoreDataObject.RestoreOptions.ReplaceDatabase = restoreDataObject.RestoreParams.GetOptionValue(RestoreOptionsHelper.ReplaceDatabase);
+ restoreDataObject.RestoreOptions.SetRestrictedUser = restoreDataObject.RestoreParams.GetOptionValue(RestoreOptionsHelper.SetRestrictedUser);
+ string recoveryState = restoreDataObject.RestoreParams.GetOptionValue(RestoreOptionsHelper.RecoveryState);
+ object databaseRecoveryState;
+ if (Enum.TryParse(typeof(DatabaseRecoveryState), recoveryState, out databaseRecoveryState))
+ {
+ restoreDataObject.RestoreOptions.RecoveryState = (DatabaseRecoveryState)databaseRecoveryState;
+ }
+ bool isTailLogBackupPossible = restoreDataObject.IsTailLogBackupPossible(restoreDataObject.RestorePlanner.DatabaseName);
+ if (isTailLogBackupPossible)
+ {
+ restoreDataObject.RestorePlanner.BackupTailLog = restoreDataObject.RestoreParams.GetOptionValue(RestoreOptionsHelper.BackupTailLog);
+ restoreDataObject.TailLogBackupFile = restoreDataObject.RestoreParams.GetOptionValue(RestoreOptionsHelper.TailLogBackupFile);
+ restoreDataObject.TailLogWithNoRecovery = restoreDataObject.RestoreParams.GetOptionValue(RestoreOptionsHelper.TailLogWithNoRecovery);
+ }
+ else
+ {
+ restoreDataObject.RestorePlanner.BackupTailLog = false;
+ }
+
+ restoreDataObject.CloseExistingConnections = restoreDataObject.RestoreParams.GetOptionValue(RestoreOptionsHelper.CloseExistingConnections);
restoreDataObject.UpdateRestorePlan(restoreDataObject.RestoreParams.RelocateDbFiles);
}
@@ -340,6 +371,8 @@ public void ExecuteRestore(RestoreDatabaseTaskDataObject restoreDataObject, SqlT
{
restoreDataObject.SqlTask = sqlTask;
restoreDataObject.Execute();
+ RestoreDatabaseTaskDataObject cachedRestoreDataObject;
+ this.restoreSessions.TryRemove(restoreDataObject.SessionId, out cachedRestoreDataObject);
}
catch(Exception ex)
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOperation/RestoreDatabaseTaskDataObject.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOperation/RestoreDatabaseTaskDataObject.cs
index d746e89a63..aba3e570ac 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOperation/RestoreDatabaseTaskDataObject.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOperation/RestoreDatabaseTaskDataObject.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using Microsoft.SqlServer.Management.Smo;
@@ -20,6 +21,9 @@ public class RestoreDatabaseTaskDataObject
{
private const char BackupMediaNameSeparator = ',';
+ private DatabaseRestorePlanner restorePlanner;
+ private string tailLogBackupFile;
+
public RestoreDatabaseTaskDataObject(Server server, String databaseName)
{
PlanUpdateRequired = true;
@@ -147,6 +151,35 @@ public void RemoveFilteredBackupSets()
}
}
+ ///
+ /// Returns the last backup taken
+ ///
+ ///
+ public string GetLastBackupTaken()
+ {
+ string lastBackup = string.Empty;
+ int lastIndexSel = 0; //TODO: find the selected backup set
+ if (this.RestorePlanner.RestoreToLastBackup &&
+ this.RestorePlan.RestoreOperations[lastIndexSel] != null &&
+ this.RestorePlan.RestoreOperations.Count > 0 &&
+ this.RestorePlan.RestoreOperations[lastIndexSel].BackupSet != null)
+ {
+ int lastIndex = this.RestorePlan.RestoreOperations.Count - 1;
+ DateTime backupTime = this.RestorePlan.RestoreOperations[lastIndexSel].BackupSet.BackupStartDate;
+ string backupTimeStr = backupTime.ToLongDateString() + " " + backupTime.ToLongTimeString();
+ lastBackup = (lastIndexSel == lastIndex) ?
+ string.Format(CultureInfo.CurrentCulture, SR.TheLastBackupTaken, (backupTimeStr)) : backupTimeStr;
+ }
+ //TODO: find the selected one
+ else if (this.RestoreSelected[0] && !this.RestorePlanner.RestoreToLastBackup)
+ {
+ lastBackup = this.CurrentRestorePointInTime.Value.ToLongDateString() +
+ " " + this.CurrentRestorePointInTime.Value.ToLongTimeString();
+ }
+ return lastBackup;
+
+ }
+
///
/// Executes the restore operations
///
@@ -170,9 +203,11 @@ public void Execute()
}
}
+ ///
+ /// Restore Util
+ ///
public RestoreUtil Util { get; set; }
- private DatabaseRestorePlanner restorePlanner;
///
/// SMO database restore planner used to create a restore plan
@@ -182,7 +217,6 @@ public DatabaseRestorePlanner RestorePlanner
get { return restorePlanner; }
}
- private string tailLogBackupFile;
public bool PlanUpdateRequired { get; private set; }
///
@@ -303,6 +337,40 @@ public string LogFilesFolder
}
}
+ ///
+ /// Determines whether [is tail log backup possible].
+ ///
+ ///
+ /// true if [is tail log backup possible]; otherwise, false.
+ ///
+ internal bool IsTailLogBackupPossible(string databaseName)
+ {
+ if (this.Server.Version.Major < 9 || String.IsNullOrEmpty(this.restorePlanner.DatabaseName))
+ {
+ return false;
+ }
+
+ Database db = this.Server.Databases[databaseName];
+ if (db == null)
+ {
+ return false;
+ }
+ else
+ {
+ db.Refresh();
+ }
+
+ if (db.Status != DatabaseStatus.Normal && db.Status != DatabaseStatus.Suspect && db.Status != DatabaseStatus.EmergencyMode)
+ {
+ return false;
+ }
+ if (db.RecoveryModel == RecoveryModel.Full || db.RecoveryModel == RecoveryModel.BulkLogged)
+ {
+ return true;
+ }
+ return false;
+ }
+
///
/// Gets or sets a value indicating whether [prompt before each backup].
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOptionsHelper.cs b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOptionsHelper.cs
new file mode 100644
index 0000000000..ec133a1302
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/DisasterRecovery/RestoreOptionsHelper.cs
@@ -0,0 +1,186 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.Hosting.Contracts;
+
+namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
+{
+ public class RestoreOptionsHelper
+ {
+ internal const string KeepReplication = "keepReplication";
+ internal const string ReplaceDatabase = "replaceDatabase";
+ internal const string SetRestrictedUser = "setRestrictedUser";
+ internal const string RecoveryState = "eecoveryState";
+ internal const string BackupTailLog = "backupTailLog";
+ internal const string DefaultBackupTailLog = "defaultBackupTailLog";
+ internal const string TailLogBackupFile = "tailLogBackupFile";
+ internal const string DefaultTailLogBackupFile = "defaultTailLogBackupFile";
+ internal const string TailLogWithNoRecovery = "tailLogWithNoRecovery";
+ internal const string CloseExistingConnections = "closeExistingConnections";
+ internal const string RelocateDbFiles = "relocateDbFiles";
+ internal const string DataFileFolder = "dataFileFolder";
+ internal const string DefaultDataFileFolder = "defaultDataFileFolder";
+ internal const string LogFileFolder = "logFileFolder";
+ internal const string DefaultLogFileFolder = "defaultLogFileFolder";
+ internal const string SessionId = "sessionId";
+ internal const string BackupFilePaths = "backupFilePaths";
+ internal const string TargetDatabaseName = "targetDatabaseName";
+ internal const string SourceDatabaseName = "sourceDatabaseName";
+ internal const string SelectedBackupSets = "selectedBackupSets";
+ internal const string StandbyFile = "standbyFile";
+ internal const string DefaultStandbyFile = "defaultStandbyFile";
+
+ ///
+ /// Creates the options metadata available for restore operations
+ ///
+ ///
+ public static ServiceOption[] CreateRestoreOptions()
+ {
+ ServiceOption[] options = new ServiceOption[]
+ {
+
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.KeepReplication,
+ DisplayName = "Keep Replication",
+ Description = "Preserve the replication settings (WITH KEEP_REPLICATION)",
+ ValueType = ServiceOption.ValueTypeBoolean,
+ IsRequired = false,
+ GroupName = "Restore options"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.ReplaceDatabase,
+ DisplayName = "ReplaceDatabase",
+ Description = "Overwrite the existing database (WITH REPLACE)",
+ ValueType = ServiceOption.ValueTypeBoolean,
+ IsRequired = false,
+ GroupName = "Restore options"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.SetRestrictedUser,
+ DisplayName = "SetRestrictedUser",
+ Description = "Restrict access to the restored database (WITH RESTRICTED_USER)",
+ ValueType = ServiceOption.ValueTypeBoolean,
+ IsRequired = false,
+ GroupName = "Restore options"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.RecoveryState,
+ DisplayName = "Recovery State",
+ Description = "Recovery State",
+ ValueType = ServiceOption.ValueTypeCategory,
+ IsRequired = false,
+ GroupName = "Restore options",
+ CategoryValues = new CategoryValue[]
+ {
+ new CategoryValue
+ {
+ Name = "WithRecovery",
+ DisplayName = "RESTORE WITH RECOVERTY"
+ },
+ new CategoryValue
+ {
+ Name = "WithNoRecovery",
+ DisplayName = "RESTORE WITH NORECOVERTY"
+ },
+ new CategoryValue
+ {
+ Name = "WithStandBy",
+ DisplayName = "RESTORE WITH STANDBY"
+ }
+ }
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.StandbyFile,
+ DisplayName = "Standby file",
+ Description = "Standby file",
+ ValueType = ServiceOption.ValueTypeString,
+ IsRequired = false,
+ GroupName = "Restore options"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.BackupTailLog,
+ DisplayName = "Backup Tail Log",
+ Description = "Take tail-log backup before restore",
+ ValueType = ServiceOption.ValueTypeBoolean,
+ IsRequired = false,
+ DefaultValue = "true",
+ GroupName = "Tail-Log backup"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.BackupTailLog,
+ DisplayName = "Backup Tail Log",
+ Description = "Take tail-log backup before restore",
+ ValueType = ServiceOption.ValueTypeBoolean,
+ IsRequired = false,
+ DefaultValue = "true",
+ GroupName = "Tail-Log backup"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.TailLogBackupFile,
+ DisplayName = "Tail Log Backup File",
+ Description = "Tail Log Backup File",
+ ValueType = ServiceOption.ValueTypeString,
+ IsRequired = false,
+ GroupName = "Tail-Log backup"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.TailLogWithNoRecovery,
+ DisplayName = "Tail Log With NoRecovery",
+ Description = "Leave source database in the restoring state(WITH NORECOVERTY)",
+ ValueType = ServiceOption.ValueTypeBoolean,
+ IsRequired = false,
+ GroupName = "Tail-Log backup"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.CloseExistingConnections,
+ DisplayName = "Close Existing Connections",
+ Description = "Close existing connections to destination database",
+ ValueType = ServiceOption.ValueTypeBoolean,
+ IsRequired = false,
+ GroupName = "Server connections"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.RelocateDbFiles,
+ DisplayName = "Relocate all files",
+ Description = "Relocate all files",
+ ValueType = ServiceOption.ValueTypeBoolean,
+ IsRequired = false,
+ GroupName = "Restore database files as"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.DataFileFolder,
+ DisplayName = "Data file folder",
+ Description = "Data file folder",
+ ValueType = ServiceOption.ValueTypeString,
+ IsRequired = false,
+ GroupName = "Restore database files as"
+ },
+ new ServiceOption
+ {
+ Name = RestoreOptionsHelper.LogFileFolder,
+ DisplayName = "Log file folder",
+ Description = "Log file folder",
+ ValueType = ServiceOption.ValueTypeString,
+ IsRequired = false,
+ GroupName = "Restore database files as"
+ }
+ };
+
+ return options;
+ }
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
index 7491761c97..d5c0e055a4 100755
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
@@ -3477,6 +3477,14 @@ public static string RestoreBackupSetExpiration
}
}
+ public static string TheLastBackupTaken
+ {
+ get
+ {
+ return Keys.GetString(Keys.TheLastBackupTaken);
+ }
+ }
+
public static string ConnectionServiceListDbErrorNotConnected(string uri)
{
return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri);
@@ -4890,6 +4898,9 @@ public class Keys
public const string RestoreBackupSetExpiration = "RestoreBackupSetExpiration";
+ public const string TheLastBackupTaken = "TheLastBackupTaken";
+
+
private Keys()
{ }
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
index 5dcda5caaf..bfd644fa45 100755
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
@@ -1911,4 +1911,8 @@
Expiration
+
+ The last backup taken ({0})
+
+
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
index f9b8ca62ce..08c6e99b04 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
@@ -835,4 +835,5 @@ RestoreBackupSetStartDate = Start Date
RestoreBackupSetFinishDate = Finish Date
RestoreBackupSetSize = Size
RestoreBackupSetUserName = User Name
-RestoreBackupSetExpiration = Expiration
\ No newline at end of file
+RestoreBackupSetExpiration = Expiration
+TheLastBackupTaken = The last backup taken ({0})
\ No newline at end of file
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
index d1fa9fab34..23be7182c5 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
@@ -2239,6 +2239,11 @@
Name
+
+
+ The last backup taken ({0})
+
+