using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Data.SqlClient;
namespace Erris.UnitTests.UITests
{
internal class DatabaseBackups
{
///
/// Restore the given database, using the given backup file.
/// Note that the database must exist. Any current connections to the database will be forcibly closed, for the Restore operation.
///
///
///
///
///
internal static void RestoreDatabase(string cxnString, string backupFilePath, string srcLogicalName, string mdfDir)
{
using (SqlConnection cxn = new SqlConnection(cxnString))
{
Console.WriteLine("RestoreDatabase - begin: " + cxn.Database);
//do not open the cxn, since we need to restore the database!
Server server = new Server(cxn.DataSource);
//setDatabaseOffline(): we need to make sure there are no open connections to the database, before we can Restore.
setDatabaseOffline(cxnString);
{
Database unitTestingDatabase = server.Databases[cxn.Database];
dropDatabase(unitTestingDatabase); //to make sure we restore database - there was issue where database was not actually updated
}
//if (unitTestingDatabase == null)
{
// unitTestingDatabase = new Database(server, cxn.Database);
// unitTestingDatabase.Create();
Microsoft.SqlServer.Management.Smo.Restore restore = new Microsoft.SqlServer.Management.Smo.Restore();
restore.NoRecovery = false;
restore.Action = RestoreActionType.Database;
//we cannot assume that the db files are named after the db (NOT default SQL Server behaviour).
string mainMdfPath = mdfDir + @"\" + cxn.Database + ".mdf";
File.Delete(mainMdfPath);
restore.RelocateFiles.Add(new RelocateFile(srcLogicalName, mainMdfPath));
string logMdfPath = mdfDir + @"\" + cxn.Database + ".ldf";
File.Delete(logMdfPath);
restore.RelocateFiles.Add(new RelocateFile(srcLogicalName + "_log", logMdfPath));
restore.ReplaceDatabase = true;
BackupDeviceItem bdi = default(BackupDeviceItem);
bdi = new BackupDeviceItem(backupFilePath, DeviceType.File);
restore.Devices.Add(bdi);
restore.Database = cxn.Database;
//restore.PercentCompleteNotification = 10;
restore.SqlRestore(server);
//Restore completed.
//Set database online again.
Database unitTestingDatabase = server.Databases[cxn.Database];
unitTestingDatabase = server.Databases[cxn.Database];
unitTestingDatabase.Refresh();
unitTestingDatabase.SetOnline();
server.Refresh();
}
Console.WriteLine("RestoreDatabase - end: " + cxn.Database);
}
}
private static void dropDatabase(Database unitTestingDatabase)
{
if(unitTestingDatabase != null)
unitTestingDatabase.Drop();
}
private static void setDatabaseOffline(string cxnString)
{
using (SqlConnection cxn = new SqlConnection(cxnString))
{
cxn.Open();
string cmdText = string.Format("ALTER DATABASE {0} SET OFFLINE WITH ROLLBACK IMMEDIATE", //rolls back any current txns
cxn.Database
);
using (SqlCommand cmd = new SqlCommand(cmdText, cxn))
{
cmd.ExecuteNonQuery();
}
cxn.Close();
}
}
internal static void BackupDatabase(string srcCxn, string sharedBackupDir, string srcLogicalName, TimeSpan timeout, string serverBackupDirFromClient, out string localSharedBackupFile, out string backupFilePath)
{
SqlConnection cxn = new SqlConnection(srcCxn);
string dbName = cxn.Database;
Console.WriteLine("BackupDatabase - begin: " + dbName);
backupFilePath = sharedBackupDir + "\\" + dbName + ".bak";
//first, delete the backup file, if it exists.
//this is to make sure the backup file only contains 1 restore set.
localSharedBackupFile = serverBackupDirFromClient + @"\" + Path.GetFileName(backupFilePath);
if (File.Exists(localSharedBackupFile))
File.Delete(localSharedBackupFile);
//note: if there is an existing .bak file, SQL Server will just overwrite it [ok].
ServerConnection conn = new ServerConnection(cxn);
Server server = new Server(conn);
Database database = server.Databases[dbName];
//To Avoid TimeOut Exception
server.ConnectionContext.StatementTimeout = (int)timeout.TotalSeconds;
RecoveryModel recoverymodel = database.DatabaseOptions.RecoveryModel;
//Define a Backup object variable.
Backup backup = new Backup();
//backup.CompressionOption = BackupCompressionOptions.On;
//Specify the type of backup, the description, the name, and the database to be backed up.
backup.Action = BackupActionType.Database;
backup.BackupSetDescription = "Full backup of " + dbName + ".";
backup.BackupSetName = "BACKUP_FOR_TFS_WEBSITE";
backup.Database = dbName;
//Declare a BackupDeviceItem
BackupDeviceItem bdi = new BackupDeviceItem(backupFilePath, DeviceType.File);
//Add the device to the Backup object.
backup.Devices.Add(bdi);
//Set the Incremental property to False to specify that this is a full database backup.
backup.Incremental = false;
backup.CopyOnly = true; //do not affect logs of source database
//Set the expiration date.
backup.ExpirationDate = DateTime.Today;
//Specify that the log must be truncated after the backup is complete.
backup.LogTruncation = BackupTruncateLogType.Truncate;
//Run SqlBackup to perform the full database backup on the instance of SQL Server.
backup.SqlBackup(server);
//Remove the backup device from the Backup object.
backup.Devices.Remove(bdi);
Console.WriteLine("BackupDatabase - end: " + dbName);
}
}
}
using Microsoft.SqlServer.Management.Smo;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Data.SqlClient;
namespace Erris.UnitTests.UITests
{
internal class DatabaseBackups
{
///
/// Restore the given database, using the given backup file.
/// Note that the database must exist. Any current connections to the database will be forcibly closed, for the Restore operation.
///
///
///
///
///
internal static void RestoreDatabase(string cxnString, string backupFilePath, string srcLogicalName, string mdfDir)
{
using (SqlConnection cxn = new SqlConnection(cxnString))
{
Console.WriteLine("RestoreDatabase - begin: " + cxn.Database);
//do not open the cxn, since we need to restore the database!
Server server = new Server(cxn.DataSource);
//setDatabaseOffline(): we need to make sure there are no open connections to the database, before we can Restore.
setDatabaseOffline(cxnString);
{
Database unitTestingDatabase = server.Databases[cxn.Database];
dropDatabase(unitTestingDatabase); //to make sure we restore database - there was issue where database was not actually updated
}
//if (unitTestingDatabase == null)
{
// unitTestingDatabase = new Database(server, cxn.Database);
// unitTestingDatabase.Create();
Microsoft.SqlServer.Management.Smo.Restore restore = new Microsoft.SqlServer.Management.Smo.Restore();
restore.NoRecovery = false;
restore.Action = RestoreActionType.Database;
//we cannot assume that the db files are named after the db (NOT default SQL Server behaviour).
string mainMdfPath = mdfDir + @"\" + cxn.Database + ".mdf";
File.Delete(mainMdfPath);
restore.RelocateFiles.Add(new RelocateFile(srcLogicalName, mainMdfPath));
string logMdfPath = mdfDir + @"\" + cxn.Database + ".ldf";
File.Delete(logMdfPath);
restore.RelocateFiles.Add(new RelocateFile(srcLogicalName + "_log", logMdfPath));
restore.ReplaceDatabase = true;
BackupDeviceItem bdi = default(BackupDeviceItem);
bdi = new BackupDeviceItem(backupFilePath, DeviceType.File);
restore.Devices.Add(bdi);
restore.Database = cxn.Database;
//restore.PercentCompleteNotification = 10;
restore.SqlRestore(server);
//Restore completed.
//Set database online again.
Database unitTestingDatabase = server.Databases[cxn.Database];
unitTestingDatabase = server.Databases[cxn.Database];
unitTestingDatabase.Refresh();
unitTestingDatabase.SetOnline();
server.Refresh();
}
Console.WriteLine("RestoreDatabase - end: " + cxn.Database);
}
}
private static void dropDatabase(Database unitTestingDatabase)
{
if(unitTestingDatabase != null)
unitTestingDatabase.Drop();
}
private static void setDatabaseOffline(string cxnString)
{
using (SqlConnection cxn = new SqlConnection(cxnString))
{
cxn.Open();
string cmdText = string.Format("ALTER DATABASE {0} SET OFFLINE WITH ROLLBACK IMMEDIATE", //rolls back any current txns
cxn.Database
);
using (SqlCommand cmd = new SqlCommand(cmdText, cxn))
{
cmd.ExecuteNonQuery();
}
cxn.Close();
}
}
internal static void BackupDatabase(string srcCxn, string sharedBackupDir, string srcLogicalName, TimeSpan timeout, string serverBackupDirFromClient, out string localSharedBackupFile, out string backupFilePath)
{
SqlConnection cxn = new SqlConnection(srcCxn);
string dbName = cxn.Database;
Console.WriteLine("BackupDatabase - begin: " + dbName);
backupFilePath = sharedBackupDir + "\\" + dbName + ".bak";
//first, delete the backup file, if it exists.
//this is to make sure the backup file only contains 1 restore set.
localSharedBackupFile = serverBackupDirFromClient + @"\" + Path.GetFileName(backupFilePath);
if (File.Exists(localSharedBackupFile))
File.Delete(localSharedBackupFile);
//note: if there is an existing .bak file, SQL Server will just overwrite it [ok].
ServerConnection conn = new ServerConnection(cxn);
Server server = new Server(conn);
Database database = server.Databases[dbName];
//To Avoid TimeOut Exception
server.ConnectionContext.StatementTimeout = (int)timeout.TotalSeconds;
RecoveryModel recoverymodel = database.DatabaseOptions.RecoveryModel;
//Define a Backup object variable.
Backup backup = new Backup();
//backup.CompressionOption = BackupCompressionOptions.On;
//Specify the type of backup, the description, the name, and the database to be backed up.
backup.Action = BackupActionType.Database;
backup.BackupSetDescription = "Full backup of " + dbName + ".";
backup.BackupSetName = "BACKUP_FOR_TFS_WEBSITE";
backup.Database = dbName;
//Declare a BackupDeviceItem
BackupDeviceItem bdi = new BackupDeviceItem(backupFilePath, DeviceType.File);
//Add the device to the Backup object.
backup.Devices.Add(bdi);
//Set the Incremental property to False to specify that this is a full database backup.
backup.Incremental = false;
backup.CopyOnly = true; //do not affect logs of source database
//Set the expiration date.
backup.ExpirationDate = DateTime.Today;
//Specify that the log must be truncated after the backup is complete.
backup.LogTruncation = BackupTruncateLogType.Truncate;
//Run SqlBackup to perform the full database backup on the instance of SQL Server.
backup.SqlBackup(server);
//Remove the backup device from the Backup object.
backup.Devices.Remove(bdi);
Console.WriteLine("BackupDatabase - end: " + dbName);
}
}
}
Comments
Post a Comment