mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 18:47:57 -05:00
Backup service - add database metatdata request (#358)
* Add backup database metadata json rpc * Backup database metadata changes after sync * Changed request class name to BackupConfigInfo and made other changes according to comments * Addressed PR comments
This commit is contained in:
@@ -131,9 +131,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DatabaseTaskHelper CreateDatabaseTaskHelper(ConnectionInfo connInfo)
|
/// <summary>
|
||||||
|
/// Return database info for a specific database
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connInfo"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static DatabaseInfo GetDatabaseInfo(ConnectionInfo connInfo)
|
||||||
|
{
|
||||||
|
DatabaseTaskHelper taskHelper = CreateDatabaseTaskHelper(connInfo, true);
|
||||||
|
return DatabaseTaskHelper.DatabasePrototypeToDatabaseInfo(taskHelper.Prototype);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create database task helper
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connInfo">connection info</param>
|
||||||
|
/// <param name="databaseExists">flag indicating whether to create taskhelper for existing database or not</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static DatabaseTaskHelper CreateDatabaseTaskHelper(ConnectionInfo connInfo, bool databaseExists = false)
|
||||||
{
|
{
|
||||||
XmlDocument xmlDoc = CreateDataContainerDocument(connInfo);
|
XmlDocument xmlDoc = CreateDataContainerDocument(connInfo, databaseExists);
|
||||||
char[] passwordArray = connInfo.ConnectionDetails.Password.ToCharArray();
|
char[] passwordArray = connInfo.ConnectionDetails.Password.ToCharArray();
|
||||||
CDataContainer dataContainer;
|
CDataContainer dataContainer;
|
||||||
|
|
||||||
@@ -169,10 +186,20 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
return taskHelper;
|
return taskHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static XmlDocument CreateDataContainerDocument(ConnectionInfo connInfo)
|
/// <summary>
|
||||||
|
/// Create data container document
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connInfo">connection info</param>
|
||||||
|
/// <param name="databaseExists">flag indicating whether to create document for existing database or not</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static XmlDocument CreateDataContainerDocument(ConnectionInfo connInfo, bool databaseExists)
|
||||||
{
|
{
|
||||||
string xml =
|
string xml = string.Empty;
|
||||||
string.Format(@"<?xml version=""1.0""?>
|
|
||||||
|
if (!databaseExists)
|
||||||
|
{
|
||||||
|
xml =
|
||||||
|
string.Format(@"<?xml version=""1.0""?>
|
||||||
<formdescription><params>
|
<formdescription><params>
|
||||||
<servername>{0}</servername>
|
<servername>{0}</servername>
|
||||||
<connectionmoniker>{0} (SQLServer, user = {1})</connectionmoniker>
|
<connectionmoniker>{0} (SQLServer, user = {1})</connectionmoniker>
|
||||||
@@ -182,7 +209,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
</params></formdescription> ",
|
</params></formdescription> ",
|
||||||
connInfo.ConnectionDetails.ServerName.ToUpper(),
|
connInfo.ConnectionDetails.ServerName.ToUpper(),
|
||||||
connInfo.ConnectionDetails.UserName);
|
connInfo.ConnectionDetails.UserName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xml =
|
||||||
|
string.Format(@"<?xml version=""1.0""?>
|
||||||
|
<formdescription><params>
|
||||||
|
<servername>{0}</servername>
|
||||||
|
<connectionmoniker>{0} (SQLServer, user = {1})</connectionmoniker>
|
||||||
|
<servertype>sql</servertype>
|
||||||
|
<urn>Server[@Name='{0}']</urn>
|
||||||
|
<database>{2}</database>
|
||||||
|
</params></formdescription> ",
|
||||||
|
connInfo.ConnectionDetails.ServerName.ToUpper(),
|
||||||
|
connInfo.ConnectionDetails.UserName,
|
||||||
|
connInfo.ConnectionDetails.DatabaseName);
|
||||||
|
}
|
||||||
var xmlDoc = new XmlDocument();
|
var xmlDoc = new XmlDocument();
|
||||||
xmlDoc.LoadXml(xml);
|
xmlDoc.LoadXml(xml);
|
||||||
return xmlDoc;
|
return xmlDoc;
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
string itemPrefix = AdminServicesProviderOptionsHelper.DatabaseFiles + "." + i + ".";
|
string itemPrefix = AdminServicesProviderOptionsHelper.DatabaseFiles + "." + i + ".";
|
||||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Name, file.Name);
|
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Name, file.Name);
|
||||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.PhysicalName, file.PhysicalName);
|
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.PhysicalName, file.PhysicalName);
|
||||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Autogrowth, file.DefaultAutogrowth.ToString());
|
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Autogrowth, (file.DefaultAutogrowth != null ? file.DefaultAutogrowth.ToString() : string.Empty));
|
||||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.DatabaseFileType, file.DatabaseFileType.ToString());
|
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.DatabaseFileType, file.DatabaseFileType.ToString());
|
||||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Folder, file.DefaultFolder);
|
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Folder, file.DefaultFolder);
|
||||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Size, file.DefaultSize);
|
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Size, file.DefaultSize);
|
||||||
|
|||||||
@@ -5,23 +5,22 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.ComponentModel;
|
using System.Collections.Generic;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
|
using Microsoft.Data.Tools.DataSets;
|
||||||
|
using Microsoft.SqlServer.Management.Common;
|
||||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||||
using Microsoft.SqlServer.Management.Smo;
|
using Microsoft.SqlServer.Management.Smo;
|
||||||
using Microsoft.SqlServer.Management.Common;
|
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Common;
|
|
||||||
using Microsoft.Data.Tools.DataSets;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
||||||
{
|
{
|
||||||
public class BackupFactory
|
public class BackupUtilities
|
||||||
{
|
{
|
||||||
private CDataContainer dataContainer;
|
private CDataContainer dataContainer;
|
||||||
private ServerConnection serverConnection;
|
private ServerConnection serverConnection;
|
||||||
private BackupRestoreUtil backupRestoreUtil = null;
|
private CommonUtilities backupRestoreUtil = null;
|
||||||
private UrlControl urlControl;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constants
|
/// Constants
|
||||||
@@ -91,7 +90,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ctor
|
/// Ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BackupFactory()
|
public BackupUtilities()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,12 +100,15 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
/// <param name="dataContainer"></param>
|
/// <param name="dataContainer"></param>
|
||||||
/// <param name="sqlConnection"></param>
|
/// <param name="sqlConnection"></param>
|
||||||
/// <param name="input"></param>
|
/// <param name="input"></param>
|
||||||
public void Initialize(CDataContainer dataContainer, SqlConnection sqlConnection, BackupInfo input)
|
public void Initialize(CDataContainer dataContainer, SqlConnection sqlConnection)
|
||||||
{
|
{
|
||||||
this.dataContainer = dataContainer;
|
this.dataContainer = dataContainer;
|
||||||
this.serverConnection = new ServerConnection(sqlConnection); // @@ check the value!
|
this.serverConnection = new ServerConnection(sqlConnection);
|
||||||
this.backupRestoreUtil = new BackupRestoreUtil(this.dataContainer, this.serverConnection);
|
this.backupRestoreUtil = new CommonUtilities(this.dataContainer, this.serverConnection);
|
||||||
//this.urlControl.SqlServer = dataContainer.Server;
|
}
|
||||||
|
|
||||||
|
public void SetBackupInput(BackupInfo input)
|
||||||
|
{
|
||||||
this.backupInfo = input;
|
this.backupInfo = input;
|
||||||
|
|
||||||
// convert the types
|
// convert the types
|
||||||
@@ -118,22 +120,45 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
{
|
{
|
||||||
this.isLocalPrimaryReplica = this.backupRestoreUtil.IsLocalPrimaryReplica(this.backupInfo.DatabaseName);
|
this.isLocalPrimaryReplica = this.backupRestoreUtil.IsLocalPrimaryReplica(this.backupInfo.DatabaseName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: when is backup device not null?
|
|
||||||
//bStatus = param.GetParam("backupdevice", ref this.initialBackupDestination);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods for UI logic
|
#region Methods for UI logic
|
||||||
|
|
||||||
// Return recovery model of the current database
|
public BackupConfigInfo GetBackupConfigInfo(string databaseName)
|
||||||
private string GetRecoveryModel()
|
|
||||||
{
|
{
|
||||||
RecoveryModel recoveryModel = this.backupRestoreUtil.GetRecoveryModel(this.backupInfo.DatabaseName);
|
BackupConfigInfo databaseInfo = new BackupConfigInfo();
|
||||||
|
databaseInfo.RecoveryModel = this.GetRecoveryModel(databaseName);
|
||||||
|
databaseInfo.DefaultBackupFolder = this.GetDefaultBackupFolder();
|
||||||
|
databaseInfo.LatestBackups = this.GetLatestBackupLocations(databaseName);
|
||||||
|
return databaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return recovery model of the database
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string GetRecoveryModel(string databaseName)
|
||||||
|
{
|
||||||
|
RecoveryModel recoveryModel = this.backupRestoreUtil.GetRecoveryModel(databaseName);
|
||||||
return recoveryModel.ToString();
|
return recoveryModel.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetDefaultBackupFolder()
|
||||||
|
{
|
||||||
|
return this.backupRestoreUtil.GetDefaultBackupFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the latest backup locations
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<RestoreItemSource> GetLatestBackupLocations(string databaseName)
|
||||||
|
{
|
||||||
|
return this.backupRestoreUtil.GetLatestBackupLocations(databaseName);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return true if backup to URL is supported in the current SQL Server version
|
/// Return true if backup to URL is supported in the current SQL Server version
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -141,9 +166,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
{
|
{
|
||||||
return BackupRestoreBase.IsBackupUrlDeviceSupported(this.dataContainer.Server.PingSqlServerVersion(this.dataContainer.ServerName)); //@@ originally, DataContainer.Server.ServerVersion
|
return BackupRestoreBase.IsBackupUrlDeviceSupported(this.dataContainer.Server.PingSqlServerVersion(this.dataContainer.ServerName)); //@@ originally, DataContainer.Server.ServerVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private string GetDefaultBackupSetName()
|
private string GetDefaultBackupSetName()
|
||||||
{
|
{
|
||||||
string bkpsetName = this.backupInfo.DatabaseName + "-"
|
string bkpsetName = this.backupInfo.DatabaseName + "-"
|
||||||
@@ -247,7 +272,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
for (int i = 0; i < this.backupInfo.BackupPathList.Count; i++)
|
for (int i = 0; i < this.backupInfo.BackupPathList.Count; i++)
|
||||||
{
|
{
|
||||||
string DestName = Convert.ToString(this.backupInfo.BackupPathList[i], System.Globalization.CultureInfo.InvariantCulture);
|
string DestName = Convert.ToString(this.backupInfo.BackupPathList[i], System.Globalization.CultureInfo.InvariantCulture);
|
||||||
int deviceType = (int)(this.backupInfo.arChangesList[DestName]);
|
int deviceType = (int)(this.backupInfo.BackupPathDevices[DestName]);
|
||||||
switch (deviceType)
|
switch (deviceType)
|
||||||
{
|
{
|
||||||
case (int)DeviceType.LogicalDevice:
|
case (int)DeviceType.LogicalDevice:
|
||||||
@@ -276,27 +301,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/*if (this.urlControl.ListBakDestUrls.Count > 0)
|
|
||||||
{
|
|
||||||
// Append the URL filename to the URL prefix
|
|
||||||
foreach (string urlPath in this.urlControl.ListBakDestUrls.ToArray())
|
|
||||||
{
|
|
||||||
if (!String.IsNullOrWhiteSpace(urlPath))
|
|
||||||
{
|
|
||||||
bk.Devices.AddDevice(urlPath, DeviceType.Url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (this.dataContainer.HashTable.ContainsKey(bk.BackupSetName))
|
|
||||||
{
|
|
||||||
this.dataContainer.HashTable.Remove(bk.BackupSetName);
|
|
||||||
}
|
|
||||||
this.dataContainer.HashTable.Add(bk.BackupSetName, bk);*/
|
|
||||||
|
|
||||||
//TODO: This should be changed to get user inputs
|
//TODO: This should be changed to get user inputs
|
||||||
bk.FormatMedia = false;
|
bk.FormatMedia = false;
|
||||||
bk.Initialize = false;
|
bk.Initialize = false;
|
||||||
@@ -312,14 +317,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ArrayList getBackupDestinationList()
|
|
||||||
{
|
|
||||||
//TODO: return the latest backup destination paths to show to UI dialog
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int GetDeviceType(string deviceName)
|
private int GetDeviceType(string deviceName)
|
||||||
{
|
{
|
||||||
Enumerator en = new Enumerator();
|
Enumerator en = new Enumerator();
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,198 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using Microsoft.SqlServer.Management.Common;
|
|
||||||
using Microsoft.SqlServer.Management.Diagnostics;
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Common
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides connection and enumerator context for a node
|
|
||||||
/// </summary>
|
|
||||||
public interface IManagedConnection : IDisposable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Connection information.
|
|
||||||
/// </summary>
|
|
||||||
SqlOlapConnectionInfoBase Connection
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Free any resources for this connection
|
|
||||||
/// </summary>
|
|
||||||
void Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// interface used by the objectexplorer. Allows us to "pool" the main connection
|
|
||||||
/// </summary>
|
|
||||||
internal interface IManagedConnection2 : IManagedConnection
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Implementation of IManagedConnection. Allows the use of a direct or indirect connection
|
|
||||||
/// in the object explorer that takes care of the connection.
|
|
||||||
/// </summary>
|
|
||||||
internal class ManagedConnection : IManagedConnection2
|
|
||||||
{
|
|
||||||
#region private members
|
|
||||||
private bool connectionAddedToActiveConnections = false;
|
|
||||||
private bool closeOnDispose = false;
|
|
||||||
private SqlOlapConnectionInfoBase connection;
|
|
||||||
private bool closed = false;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Construction
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new managed connection
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="connection">connection wish to manage</param>
|
|
||||||
public ManagedConnection(SqlOlapConnectionInfoBase connection)
|
|
||||||
: this(connection, false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// create a new managed connection.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="connection">connection</param>
|
|
||||||
/// <param name="attemptToPool">true if we are going to try and reuse the
|
|
||||||
/// connection if possible</param>
|
|
||||||
public ManagedConnection(SqlOlapConnectionInfoBase sourceConnection, bool attemptToPool)
|
|
||||||
{
|
|
||||||
// parameter check
|
|
||||||
if (sourceConnection == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("sourceConnection");
|
|
||||||
}
|
|
||||||
|
|
||||||
// see if the connection can restrict access (single user mode)
|
|
||||||
IRestrictedAccess access = sourceConnection as IRestrictedAccess;
|
|
||||||
// see if it is cloneable
|
|
||||||
ICloneable cloneable = sourceConnection as ICloneable;
|
|
||||||
lock (ActiveConnections)
|
|
||||||
{
|
|
||||||
// if it's not single user mode then we can see if the object can be cloned
|
|
||||||
if (access == null || access.SingleConnection == false)
|
|
||||||
{
|
|
||||||
// if we are going to attempt to pool, see if the connection is in use
|
|
||||||
if (attemptToPool && !ActiveConnections.Contains(SharedConnectionUtil.GetConnectionKeyName(sourceConnection)))
|
|
||||||
{
|
|
||||||
// add it to the hashtable to indicate use.
|
|
||||||
ActiveConnections.Add(SharedConnectionUtil.GetConnectionKeyName(sourceConnection), sourceConnection);
|
|
||||||
this.connection = sourceConnection;
|
|
||||||
this.closeOnDispose = false;
|
|
||||||
this.connectionAddedToActiveConnections = true;
|
|
||||||
}
|
|
||||||
else if (cloneable != null)
|
|
||||||
{
|
|
||||||
this.connection = (SqlOlapConnectionInfoBase)cloneable.Clone();
|
|
||||||
this.closeOnDispose = true;
|
|
||||||
}
|
|
||||||
else if (sourceConnection is SqlConnectionInfoWithConnection)
|
|
||||||
{
|
|
||||||
this.connection = ((SqlConnectionInfoWithConnection)sourceConnection).Copy();
|
|
||||||
this.closeOnDispose = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if everything else has failed just use to passed in connection.
|
|
||||||
if (this.connection == null)
|
|
||||||
{
|
|
||||||
this.connection = sourceConnection;
|
|
||||||
}
|
|
||||||
|
|
||||||
// always set the lock timeout to prevent the shell from not responding
|
|
||||||
if (this.connection is SqlConnectionInfoWithConnection)
|
|
||||||
{
|
|
||||||
// set lock_timeout to 10 seconds
|
|
||||||
((SqlConnectionInfoWithConnection)this.connection).ServerConnection.LockTimeout = 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IDisposable implementation
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IManagedConnection implementation
|
|
||||||
/// <summary>
|
|
||||||
/// Connection
|
|
||||||
/// </summary>
|
|
||||||
public SqlOlapConnectionInfoBase Connection
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this.connection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Close the current connection if applicable.
|
|
||||||
/// </summary>
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
if (this.closed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this.closeOnDispose)
|
|
||||||
{
|
|
||||||
IDisposable disp = this.connection as IDisposable;
|
|
||||||
if (disp != null)
|
|
||||||
{
|
|
||||||
disp.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if we are not closing the connection and it is a sql connection then ensure it
|
|
||||||
// is left in the master database.
|
|
||||||
SqlConnectionInfoWithConnection sqlConnection = this.connection as SqlConnectionInfoWithConnection;
|
|
||||||
if (sqlConnection != null && sqlConnection.ServerConnection.DatabaseEngineType == DatabaseEngineType.Standalone)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
sqlConnection.ServerConnection.ExecuteNonQuery("use [master]");
|
|
||||||
}
|
|
||||||
// don't error if this fails
|
|
||||||
catch
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.connectionAddedToActiveConnections)
|
|
||||||
{
|
|
||||||
lock (ActiveConnections)
|
|
||||||
{
|
|
||||||
ActiveConnections.Remove(SharedConnectionUtil.GetConnectionKeyName(connection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.connection = null;
|
|
||||||
this.closed = true;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region static helpers
|
|
||||||
/// <summary>
|
|
||||||
/// hashtable we use to keep track of actively used main connections
|
|
||||||
/// </summary>
|
|
||||||
private static Hashtable activeConnections = null;
|
|
||||||
private Hashtable ActiveConnections
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (activeConnections == null)
|
|
||||||
{
|
|
||||||
activeConnections = new Hashtable();
|
|
||||||
}
|
|
||||||
return activeConnections;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Common
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// To access DataModelingSandbox from NavigableItem
|
|
||||||
/// </summary>
|
|
||||||
public interface ISandboxLoader
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Get sandbox
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>DataModelingSandbox object associated with this NavigableItem</returns>
|
|
||||||
object GetSandbox();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Refresh sandbox data associated with this NavigableItem
|
|
||||||
/// </summary>
|
|
||||||
void RefreshSandboxData();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delete sandbox from cache
|
|
||||||
/// </summary>
|
|
||||||
void DeleteSandbox();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,488 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Common
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// SqlTools Parameters, used to define what goes into starting up a Workbench Form
|
|
||||||
/// AKA a dbCommander, AKA a "dialog"
|
|
||||||
/// These parameters are xml snippets
|
|
||||||
/// </summary>
|
|
||||||
public class STParameters
|
|
||||||
{
|
|
||||||
public XmlDocument m_doc;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The data type we are interested in
|
|
||||||
/// </summary>
|
|
||||||
public enum STType { eNULL, eInt, eLong, eString };
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// default constructor
|
|
||||||
/// </summary>
|
|
||||||
public STParameters()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// TODO: Add constructor logic here
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="xmlDoc">The xml snippet used to control the dbCommander</param>
|
|
||||||
public STParameters(XmlDocument xmlDoc)
|
|
||||||
{
|
|
||||||
m_doc = xmlDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Changing the xml snippet we are using
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="xmlDoc">the new xml snippet</param>
|
|
||||||
public void SetDocument(XmlDocument xmlDoc)
|
|
||||||
{
|
|
||||||
m_doc = xmlDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Access to the xml we are using for dbCommander parameters
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>our current parameters</returns>
|
|
||||||
public XmlDocument GetDocument()
|
|
||||||
{
|
|
||||||
return m_doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Search for an xml tag, and return its value
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">the xml tag name</param>
|
|
||||||
/// <param name="value">the value of that tag</param>
|
|
||||||
/// <returns>flag that is true if the data was found, false if not</returns>
|
|
||||||
public bool GetBaseParam(string parameterName, ref object value)
|
|
||||||
{
|
|
||||||
XmlNodeList nodeList = null;
|
|
||||||
bool parameterExists;
|
|
||||||
|
|
||||||
if (m_doc == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
parameterExists = false;
|
|
||||||
nodeList = m_doc.GetElementsByTagName(parameterName);
|
|
||||||
|
|
||||||
if (nodeList.Count > 1)
|
|
||||||
{
|
|
||||||
value = null;
|
|
||||||
}
|
|
||||||
else if (nodeList.Count != 0) // anything there?
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
XmlNode node = nodeList.Item(0);
|
|
||||||
if (null != node)
|
|
||||||
{
|
|
||||||
value = node.InnerText as object;
|
|
||||||
parameterExists = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception /*e*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameterExists;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds an existing xml tag, and sets it to a new value, or if the tag is not found
|
|
||||||
/// create it and set it's value
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">tag name</param>
|
|
||||||
/// <param name="value">new value</param>
|
|
||||||
/// <returns>flag that is true if the tag was set, false if not</returns>
|
|
||||||
public bool SetBaseParam(string parameterName, object value)
|
|
||||||
{
|
|
||||||
XmlNodeList nodeList;
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
nodeList = m_doc.GetElementsByTagName(parameterName);
|
|
||||||
|
|
||||||
if (nodeList.Count == 1)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
nodeList.Item(0).InnerText = (string)value;
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
catch (InvalidCastException /*e*/)
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeList.Count == 0)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
XmlElement xmlElement = m_doc.CreateElement(parameterName);
|
|
||||||
XmlNode root = m_doc.DocumentElement;
|
|
||||||
|
|
||||||
nodeList = m_doc.GetElementsByTagName("params");
|
|
||||||
|
|
||||||
if (nodeList.Count == 1 && value is string)
|
|
||||||
{
|
|
||||||
xmlElement.InnerText = (string)value;
|
|
||||||
nodeList.Item(0).InsertAfter(xmlElement, nodeList.Item(0).LastChild);
|
|
||||||
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
string sz = e.ToString();
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get back an interger parameter.
|
|
||||||
/// NOTE: if the tag exists, but it contains non-numeric data, this will throw
|
|
||||||
/// An exception of type 'System.FormatException'
|
|
||||||
/// with Additional information: Could not find any parsible digits.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">xml tag name for the parameter of interest</param>
|
|
||||||
/// <param name="iValue">out value of parameter</param>
|
|
||||||
/// <returns>flag that is true if the data was found, false if not</returns>
|
|
||||||
public bool GetParam(string parameterName, out int value)
|
|
||||||
{
|
|
||||||
bool parameterExists = false;
|
|
||||||
|
|
||||||
value = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
object oAux = null;
|
|
||||||
|
|
||||||
if (parameterExists = GetBaseParam(parameterName, ref oAux))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
value = Convert.ToInt32((string)oAux, 10); // data is always a string, it is the value of XmlNode.InnerText
|
|
||||||
}
|
|
||||||
catch (FormatException e)
|
|
||||||
{
|
|
||||||
Debug.WriteLine(String.Format(System.Globalization.CultureInfo.CurrentCulture, "Non numeric data in tag: {0}", parameterName));
|
|
||||||
Debug.WriteLine(e.Message);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InvalidCastException /*e*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameterExists;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Accessor for a boolean parameter
|
|
||||||
/// NOTE: if the tag exists, but it contains non-numeric data, this will throw
|
|
||||||
/// An exception of type 'System.FormatException'
|
|
||||||
/// with Additional information: Could not find any parsible digits.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">xml tag name for the parameter of interest</param>
|
|
||||||
/// <param name="value">out value of parameter</param>
|
|
||||||
/// <returns>flag that is true if the data was found, false if not</returns>
|
|
||||||
public bool GetParam(string parameterName, ref bool value)
|
|
||||||
{
|
|
||||||
bool parameterExists = false;
|
|
||||||
|
|
||||||
value = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
object oAux = null;
|
|
||||||
if (parameterExists = GetBaseParam(parameterName, ref oAux))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
value = Convert.ToBoolean((string)oAux, System.Globalization.CultureInfo.InvariantCulture); // data is always a string, it is the value of XmlNode.InnerText
|
|
||||||
}
|
|
||||||
catch (FormatException e)
|
|
||||||
{
|
|
||||||
Debug.WriteLine(String.Format(System.Globalization.CultureInfo.CurrentCulture, "Non boolean data in tag: {0}", parameterName));
|
|
||||||
Debug.WriteLine(e.Message);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InvalidCastException /*e*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameterExists;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Accessor to a string parameter
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">xml tag name for the parameter of interest</param>
|
|
||||||
/// <param name="value">out value of parameter</param>
|
|
||||||
/// <returns>flag that is true if the data was found, false if not</returns>
|
|
||||||
public bool GetParam(string parameterName, ref string value)
|
|
||||||
{
|
|
||||||
bool parameterExists;
|
|
||||||
|
|
||||||
value = "";
|
|
||||||
parameterExists = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
object oAux = null;
|
|
||||||
|
|
||||||
if (parameterExists = GetBaseParam(parameterName, ref oAux))
|
|
||||||
{
|
|
||||||
value = (string)oAux;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InvalidCastException /*e*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameterExists;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Accessor to long parameter (Int64)
|
|
||||||
/// NOTE: if the tag exists, but it contains non-numeric data, this will throw
|
|
||||||
/// An exception of type 'System.FormatException'
|
|
||||||
/// with Additional information: Could not find any parsible digits.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">xml tag name for the parameter of interest</param>
|
|
||||||
/// <param name="value">out value of parameter</param>
|
|
||||||
/// <returns>flag that is true if the data was found, false if not</returns>
|
|
||||||
public bool GetParam(string parameterName, out long value)
|
|
||||||
{
|
|
||||||
bool parameterExists = false;
|
|
||||||
|
|
||||||
value = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
object oAux = null;
|
|
||||||
|
|
||||||
if (parameterExists = GetBaseParam(parameterName, ref oAux))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
value = Convert.ToInt64((string)oAux, 10); // data is always a string, it is the value of XmlNode.InnerText
|
|
||||||
}
|
|
||||||
catch (FormatException e)
|
|
||||||
{
|
|
||||||
Debug.WriteLine(String.Format(System.Globalization.CultureInfo.CurrentCulture, "Non numeric data in tag: {0}", parameterName));
|
|
||||||
Debug.WriteLine(e.Message);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InvalidCastException /*e*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameterExists;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set an int (Int32) parameter
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">tag name for parameter</param>
|
|
||||||
/// <param name="value">integer value</param>
|
|
||||||
/// <returns>true if set was successful, false if not</returns>
|
|
||||||
public bool SetParam(string parameterName, int value)
|
|
||||||
{
|
|
||||||
bool success;
|
|
||||||
|
|
||||||
success = SetBaseParam(parameterName, (object)value);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set a string parameter
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">tag name for parameter</param>
|
|
||||||
/// <param name="value">string value</param>
|
|
||||||
/// <returns>true if set was successful, false if not</returns>
|
|
||||||
public bool SetParam(string parameterName, string value)
|
|
||||||
{
|
|
||||||
bool success;
|
|
||||||
|
|
||||||
success = SetBaseParam(parameterName, (object)value);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set a long (Int64) parameter
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">tag name for parameter</param>
|
|
||||||
/// <param name="value">long value</param>
|
|
||||||
/// <returns>true if set was successful, false if not</returns>
|
|
||||||
public bool SetParam(string parameterName, long value)
|
|
||||||
{
|
|
||||||
bool success;
|
|
||||||
|
|
||||||
success = SetBaseParam(parameterName, (object)value);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a string collection parameter
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">name of collection</param>
|
|
||||||
/// <param name="list">collection that gets filled up with parameters</param>
|
|
||||||
/// <param name="getInnerXml">true if we want to get at inner nodes, false if not</param>
|
|
||||||
/// <returns>true if parameter(s) exist</returns>
|
|
||||||
public bool GetParam(string parameterName, System.Collections.Specialized.StringCollection list, bool getInnerXml)
|
|
||||||
{
|
|
||||||
/// necessary for OALP objects path that is in an XML form
|
|
||||||
if (true == getInnerXml)
|
|
||||||
{
|
|
||||||
XmlNodeList nodeList;
|
|
||||||
bool parameterExists;
|
|
||||||
long lCount;
|
|
||||||
|
|
||||||
parameterExists = false;
|
|
||||||
nodeList = m_doc.GetElementsByTagName(parameterName);
|
|
||||||
|
|
||||||
list.Clear();
|
|
||||||
|
|
||||||
lCount = nodeList.Count;
|
|
||||||
|
|
||||||
if (lCount > 0)
|
|
||||||
{
|
|
||||||
parameterExists = true;
|
|
||||||
|
|
||||||
for (long i = 0; i < lCount; i++)
|
|
||||||
{
|
|
||||||
list.Add(nodeList.Item((int)i).InnerXml);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parameterExists = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameterExists;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetParam(parameterName, list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Access to a collection of parameters
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">name of collection</param>
|
|
||||||
/// <param name="list">list to fill with parameters</param>
|
|
||||||
/// <returns>parameter(s) exist</returns>
|
|
||||||
public bool GetParam(string parameterName, System.Collections.Specialized.StringCollection list)
|
|
||||||
{
|
|
||||||
XmlNodeList nodeList;
|
|
||||||
bool parameterExists;
|
|
||||||
long lCount;
|
|
||||||
|
|
||||||
parameterExists = false;
|
|
||||||
nodeList = m_doc.GetElementsByTagName(parameterName);
|
|
||||||
|
|
||||||
list.Clear();
|
|
||||||
|
|
||||||
lCount = nodeList.Count;
|
|
||||||
|
|
||||||
if (lCount > 0)
|
|
||||||
{
|
|
||||||
parameterExists = true;
|
|
||||||
|
|
||||||
for (long i = 0; i < lCount; i++)
|
|
||||||
{
|
|
||||||
list.Add(nodeList.Item((int)i).InnerText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parameterExists = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameterExists;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool GetParam(string parameterName, ref ArrayList list)
|
|
||||||
{
|
|
||||||
System.Collections.Specialized.StringCollection stringList = new System.Collections.Specialized.StringCollection();
|
|
||||||
bool parameterExists = GetParam(parameterName, stringList);
|
|
||||||
list.Clear();
|
|
||||||
if (!parameterExists)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < stringList.Count; i++)
|
|
||||||
{
|
|
||||||
list.Add(stringList[i]);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This function does nothing but return false
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">ignored</param>
|
|
||||||
/// <param name="type">ignored</param>
|
|
||||||
/// <returns>always false</returns>
|
|
||||||
public bool GetParamType(string parameterName, STType type)
|
|
||||||
{
|
|
||||||
bool whatever = false;
|
|
||||||
|
|
||||||
return whatever;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This function does nothing but return false
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">ignored</param>
|
|
||||||
/// <param name="type">ignored</param>
|
|
||||||
/// <returns>always false</returns>
|
|
||||||
public bool SetParamType(string parameterName, STType type)
|
|
||||||
{
|
|
||||||
bool whatever = false;
|
|
||||||
|
|
||||||
return whatever;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
|
|
||||||
using System;
|
|
||||||
//using Microsoft.SqlServer.Management.AzureCredential;
|
|
||||||
using Microsoft.SqlServer.Management.Common;
|
|
||||||
//using Microsoft.SqlServer.Management.Smo.RegSvrEnum;
|
|
||||||
using SFC = Microsoft.SqlServer.Management.Sdk.Sfc;
|
|
||||||
//using Microsoft.SqlServer.StorageClient;
|
|
||||||
//using Microsoft.SqlServer.Management.SqlMgmt;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Summary description for SharedConectionUtil
|
|
||||||
/// Moved GetConnectionName static call in a public class acessible for both
|
|
||||||
/// OEXM and OE
|
|
||||||
/// </summary>
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Common
|
|
||||||
{
|
|
||||||
internal class SharedConnectionUtil
|
|
||||||
{
|
|
||||||
public SharedConnectionUtil()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ci"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GetConnectionKeyName(SqlOlapConnectionInfoBase ci)
|
|
||||||
{
|
|
||||||
|
|
||||||
//// Note that these strings are not localized. The returned string is used by OE in a
|
|
||||||
//// hash of connections so it can tell if it already has such a connection open. This
|
|
||||||
//// string is never seen by the user. For the string seen by the user, see
|
|
||||||
//// ServerNameHandler.cs.
|
|
||||||
string displayName = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0} (", ci.ServerName);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(ci.DatabaseName))
|
|
||||||
{
|
|
||||||
displayName += ", " + ci.DatabaseName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return displayName;
|
|
||||||
|
|
||||||
//switch (ci.ServerType)
|
|
||||||
//{
|
|
||||||
// case ConnectionType.AzureStorage:
|
|
||||||
// AzureStorageConnectionInfo azureCI = ci as AzureStorageConnectionInfo;
|
|
||||||
// displayName = "AzureStorage," + azureCI.BlobClient.BaseUri;
|
|
||||||
// break;
|
|
||||||
// case ConnectionType.AzureAccount:
|
|
||||||
// if (ci is CertificateBasedAuthenticationInfo)
|
|
||||||
// {
|
|
||||||
// displayName = "AzureSubscription," + (ci as CertificateBasedAuthenticationInfo).SubscriptionId;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// displayName = "AzureSubscription";
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case ConnectionType.Sql:
|
|
||||||
// displayName += "SQLServer";
|
|
||||||
// SqlConnectionInfo sqlCi = ci as SqlConnectionInfo;
|
|
||||||
// if (sqlCi.UseIntegratedSecurity == true)
|
|
||||||
// {
|
|
||||||
// displayName += ", trusted";
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// displayName += String.Format(System.Globalization.CultureInfo.InvariantCulture, ", user = {0}", sqlCi.UserName);
|
|
||||||
// //In Cloud a user can have access to only a few UDBs without access to master DB
|
|
||||||
// // and hence need to show different OE hierarchy trees for each DB
|
|
||||||
// //Same is the case with a contained user.
|
|
||||||
|
|
||||||
|
|
||||||
// if (ServerInfoCache.GetDatabaseEngineType(ci.ServerName) == DatabaseEngineType.SqlAzureDatabase
|
|
||||||
// || SFC.ExecuteSql.GetDatabaseEngineType(ci) == DatabaseEngineType.SqlAzureDatabase
|
|
||||||
// || SFC.ExecuteSql.IsContainedAuthentication(ci))
|
|
||||||
// {
|
|
||||||
// if (!string.IsNullOrEmpty(ci.DatabaseName))
|
|
||||||
// {
|
|
||||||
// displayName += ", " + ci.DatabaseName;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case ConnectionType.Olap:
|
|
||||||
// displayName += "OLAP";
|
|
||||||
// break;
|
|
||||||
// case ConnectionType.SqlCE:
|
|
||||||
// displayName += "SqlCE";
|
|
||||||
// break;
|
|
||||||
// case ConnectionType.ReportServer:
|
|
||||||
// displayName += "Rs";
|
|
||||||
// displayName += String.Format(System.Globalization.CultureInfo.InvariantCulture, ", connection = {0}", ci.ConnectionString);
|
|
||||||
// break;
|
|
||||||
// case ConnectionType.IntegrationServer:
|
|
||||||
// displayName += "SSIS";
|
|
||||||
// break;
|
|
||||||
//}
|
|
||||||
//displayName += ")";
|
|
||||||
//return displayName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,12 +5,14 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Microsoft.Data.Tools.DataSets;
|
using Microsoft.Data.Tools.DataSets;
|
||||||
using Microsoft.SqlServer.Management.Common;
|
using Microsoft.SqlServer.Management.Common;
|
||||||
using Microsoft.SqlServer.Management.Smo;
|
|
||||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||||
|
using Microsoft.SqlServer.Management.Smo;
|
||||||
using SMO = Microsoft.SqlServer.Management.Smo;
|
using SMO = Microsoft.SqlServer.Management.Smo;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Common;
|
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||||
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
||||||
{
|
{
|
||||||
@@ -74,15 +76,15 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Summary description for SqlBackupRestoreBase.
|
/// Common methods used for backup and restore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BackupRestoreUtil
|
public class CommonUtilities
|
||||||
{
|
{
|
||||||
private CDataContainer DataContainer;
|
private CDataContainer DataContainer;
|
||||||
private ServerConnection SqlConnection = null;
|
private ServerConnection SqlConnection = null;
|
||||||
private ArrayList ExcludedDbs;
|
private ArrayList ExcludedDbs;
|
||||||
|
|
||||||
public BackupRestoreUtil(CDataContainer dataContainer, ServerConnection sqlConnection)
|
public CommonUtilities(CDataContainer dataContainer, ServerConnection sqlConnection)
|
||||||
{
|
{
|
||||||
DataContainer = dataContainer;
|
DataContainer = dataContainer;
|
||||||
this.SqlConnection = sqlConnection;
|
this.SqlConnection = sqlConnection;
|
||||||
@@ -986,9 +988,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ArrayList GetLatestBackupLocations(string DatabaseName)
|
public List<RestoreItemSource> GetLatestBackupLocations(string DatabaseName)
|
||||||
{
|
{
|
||||||
ArrayList LatestLocations = new ArrayList();
|
List<RestoreItemSource> LatestLocations = new List<RestoreItemSource>();
|
||||||
|
|
||||||
Enumerator en = null;
|
Enumerator en = null;
|
||||||
DataSet ds = new DataSet();
|
DataSet ds = new DataSet();
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Admin.Contracts;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides database info for backup.
|
||||||
|
/// </summary>
|
||||||
|
public class BackupConfigInfo
|
||||||
|
{
|
||||||
|
public DatabaseInfo DatabaseInfo { get; set; }
|
||||||
|
public string RecoveryModel { get; set; }
|
||||||
|
public List<RestoreItemSource> LatestBackups { get; set; }
|
||||||
|
public string DefaultBackupFolder { get; set; }
|
||||||
|
|
||||||
|
public BackupConfigInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// 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.Protocol.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Admin.Contracts;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts
|
||||||
|
{
|
||||||
|
|
||||||
|
public class BackupConfigInfoResponse
|
||||||
|
{
|
||||||
|
public BackupConfigInfo BackupConfigInfo { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BackupConfigInfoRequest
|
||||||
|
{
|
||||||
|
public static readonly
|
||||||
|
RequestType<DefaultDatabaseInfoParams, BackupConfigInfoResponse> Type =
|
||||||
|
RequestType<DefaultDatabaseInfoParams, BackupConfigInfoResponse>.Create("disasterrecovery/backupconfiginfo");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts
|
||||||
@@ -48,12 +47,12 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of {key: backup path, value: device type}
|
/// List of {key: backup path, value: device type}
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, int> arChangesList { get; set; }
|
public Dictionary<string, int> BackupPathDevices { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of selected backup paths
|
/// List of selected backup paths
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ArrayList BackupPathList { get; set; }
|
public List<string> BackupPathList { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,19 +2,15 @@
|
|||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
using System;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.Hosting.Protocol;
|
using Microsoft.SqlTools.Hosting.Protocol;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Admin.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.SqlServer.Management.Smo;
|
|
||||||
using Microsoft.SqlServer.Management.Common;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data.SqlClient;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.Common;
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
||||||
{
|
{
|
||||||
@@ -22,14 +18,14 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
{
|
{
|
||||||
private static readonly Lazy<DisasterRecoveryService> instance = new Lazy<DisasterRecoveryService>(() => new DisasterRecoveryService());
|
private static readonly Lazy<DisasterRecoveryService> instance = new Lazy<DisasterRecoveryService>(() => new DisasterRecoveryService());
|
||||||
private static ConnectionService connectionService = null;
|
private static ConnectionService connectionService = null;
|
||||||
private BackupFactory backupFactory;
|
private BackupUtilities backupFactory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default, parameterless constructor.
|
/// Default, parameterless constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal DisasterRecoveryService()
|
internal DisasterRecoveryService()
|
||||||
{
|
{
|
||||||
this.backupFactory = new BackupFactory();
|
this.backupFactory = new BackupUtilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -64,27 +60,47 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void InitializeService(ServiceHost serviceHost)
|
public void InitializeService(ServiceHost serviceHost)
|
||||||
{
|
{
|
||||||
|
// Get database info
|
||||||
|
serviceHost.SetRequestHandler(BackupConfigInfoRequest.Type, HandleBackupConfigInfoRequest);
|
||||||
|
// Create backup
|
||||||
serviceHost.SetRequestHandler(BackupRequest.Type, HandleBackupRequest);
|
serviceHost.SetRequestHandler(BackupRequest.Type, HandleBackupRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static async Task HandleBackupConfigInfoRequest(
|
||||||
/// Handles a backup request
|
DefaultDatabaseInfoParams optionsParams,
|
||||||
/// </summary>
|
RequestContext<BackupConfigInfoResponse> requestContext)
|
||||||
internal static async Task HandleBackupRequest(
|
{
|
||||||
BackupParams backupParams,
|
var response = new BackupConfigInfoResponse();
|
||||||
RequestContext<BackupResponse> requestContext)
|
|
||||||
{
|
|
||||||
ConnectionInfo connInfo;
|
ConnectionInfo connInfo;
|
||||||
DisasterRecoveryService.ConnectionServiceInstance.TryFindConnection(
|
DisasterRecoveryService.ConnectionServiceInstance.TryFindConnection(
|
||||||
backupParams.OwnerUri,
|
optionsParams.OwnerUri,
|
||||||
out connInfo);
|
out connInfo);
|
||||||
CDataContainer dataContainer;
|
|
||||||
|
if (connInfo != null)
|
||||||
|
{
|
||||||
|
CDataContainer dataContainer = GetDataContainer(connInfo);
|
||||||
|
SqlConnection sqlConn = GetSqlConnection(connInfo);
|
||||||
|
if (sqlConn != null)
|
||||||
|
{
|
||||||
|
DisasterRecoveryService.Instance.InitializeBackup(dataContainer, sqlConn);
|
||||||
|
BackupConfigInfo backupConfigInfo = DisasterRecoveryService.Instance.GetDatabaseInfo(sqlConn.Database);
|
||||||
|
backupConfigInfo.DatabaseInfo = AdminService.GetDatabaseInfo(connInfo);
|
||||||
|
response.BackupConfigInfo = backupConfigInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await requestContext.SendResult(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static CDataContainer GetDataContainer(ConnectionInfo connInfo)
|
||||||
|
{
|
||||||
|
CDataContainer dataContainer = null;
|
||||||
|
|
||||||
if (connInfo != null)
|
if (connInfo != null)
|
||||||
{
|
{
|
||||||
char[] passwordArray = connInfo.ConnectionDetails.Password.ToCharArray();
|
char[] passwordArray = connInfo.ConnectionDetails.Password.ToCharArray();
|
||||||
if (string.Equals(connInfo.ConnectionDetails.AuthenticationType, "SqlLogin", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(connInfo.ConnectionDetails.AuthenticationType, "SqlLogin", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
fixed (char* passwordPtr = passwordArray)
|
fixed (char* passwordPtr = passwordArray)
|
||||||
@@ -109,11 +125,32 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
null,
|
null,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles a backup request
|
||||||
|
/// </summary>
|
||||||
|
internal static async Task HandleBackupRequest(
|
||||||
|
BackupParams backupParams,
|
||||||
|
RequestContext<BackupResponse> requestContext)
|
||||||
|
{
|
||||||
|
ConnectionInfo connInfo;
|
||||||
|
DisasterRecoveryService.ConnectionServiceInstance.TryFindConnection(
|
||||||
|
backupParams.OwnerUri,
|
||||||
|
out connInfo);
|
||||||
|
CDataContainer dataContainer;
|
||||||
|
|
||||||
|
if (connInfo != null)
|
||||||
|
{
|
||||||
|
dataContainer = GetDataContainer(connInfo);
|
||||||
SqlConnection sqlConn = GetSqlConnection(connInfo);
|
SqlConnection sqlConn = GetSqlConnection(connInfo);
|
||||||
if (sqlConn != null)
|
if (sqlConn != null)
|
||||||
{
|
{
|
||||||
DisasterRecoveryService.Instance.InitializeBackup(dataContainer, sqlConn, backupParams.BackupInfo);
|
DisasterRecoveryService.Instance.InitializeBackup(dataContainer, sqlConn);
|
||||||
|
DisasterRecoveryService.Instance.SetBackupInput(backupParams.BackupInfo);
|
||||||
DisasterRecoveryService.Instance.PerformBackup();
|
DisasterRecoveryService.Instance.PerformBackup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,15 +184,25 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeBackup(CDataContainer dataContainer, SqlConnection sqlConnection, BackupInfo input)
|
private void InitializeBackup(CDataContainer dataContainer, SqlConnection sqlConnection)
|
||||||
|
{
|
||||||
|
this.backupFactory.Initialize(dataContainer, sqlConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetBackupInput(BackupInfo input)
|
||||||
{
|
{
|
||||||
this.backupFactory.Initialize(dataContainer, sqlConnection, input);
|
this.backupFactory.SetBackupInput(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PerformBackup()
|
private void PerformBackup()
|
||||||
{
|
{
|
||||||
this.backupFactory.PerformBackup();
|
this.backupFactory.PerformBackup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BackupConfigInfo GetDatabaseInfo(string databaseName)
|
||||||
|
{
|
||||||
|
return this.backupFactory.GetBackupConfigInfo(databaseName);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
|
||||||
{
|
|
||||||
//TODO: Should URL be added to Carbon?
|
|
||||||
public partial class UrlControl
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Server
|
|
||||||
/// </summary>
|
|
||||||
public Microsoft.SqlServer.Management.Smo.Server SqlServer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// list of Backup Urls
|
|
||||||
/// </summary>
|
|
||||||
private ArrayList listBakDestUrls;
|
|
||||||
|
|
||||||
public UrlControl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// List of backup urls
|
|
||||||
/// </summary>
|
|
||||||
public ArrayList ListBakDestUrls
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this.listBakDestUrls;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user