Updated the backup and restore functions to be more verbose and stable. Changed the version number slightly for appearance reasons. Fixed a bug on the Main Form that prevented it from refreshing the controls properly after all years have been wiped and after a database restore.
This commit is contained in:
@@ -10,6 +10,12 @@ namespace AdvertisingProfitControlData
|
||||
{
|
||||
public static readonly string DefaultBackupLocation = Path.GetPathRoot(Environment.SystemDirectory) + @"Users\" + Environment.UserName + @"\AppData\Local\APC\Backups\";
|
||||
public static readonly string DefaultBackupExtension = "apcdbbak";
|
||||
//Define the error states that certain operations may return.
|
||||
public const byte PrimaryBackupFailed = 5;
|
||||
public const byte PrimaryBackupVerifyFailed = 10;
|
||||
public const byte OptionalBackupFailed = 15;
|
||||
public const byte OptionalBackupVerifyFailed = 25;
|
||||
public byte State;
|
||||
public string ErrorMessage = string.Empty;
|
||||
|
||||
public bool SingleFileBackup(string optionalBackupFilePath = "")
|
||||
@@ -18,22 +24,94 @@ namespace AdvertisingProfitControlData
|
||||
var sqlConStrBuilder = new SqlConnectionStringBuilder(AdvertisingProfitControlDbContext.ConnectionString);
|
||||
try
|
||||
{
|
||||
using (var s = new SqlConnection(sqlConStrBuilder.ConnectionString))
|
||||
using (var sqlConnection = new SqlConnection(sqlConStrBuilder.ConnectionString))
|
||||
{
|
||||
var query = $"BACKUP DATABASE {sqlConStrBuilder.InitialCatalog} TO DISK='{defaultBackupFile}'";
|
||||
|
||||
using (var command = new SqlCommand(query, s))
|
||||
sqlConnection.InfoMessage += (s, e) =>
|
||||
{
|
||||
s.Open();
|
||||
if (e.Errors.Count > 0)
|
||||
{
|
||||
State += e.Errors[e.Errors.Count - 1].State % 5 == 0 ? e.Errors[e.Errors.Count - 1].State : (byte) 0;
|
||||
}
|
||||
};
|
||||
//Note: To get a SqlException an error must be raised at level 16 or higher.
|
||||
//Checksum command needs to be applied in order to properly verify the media as pointed out here:
|
||||
//http://www.edwinmsarmiento.com/the-scariest-lie-we-believed-about-backup-verification/
|
||||
//RAISERROR(message string, level, state) levels above 11 throw SQLExceptions.
|
||||
var query =
|
||||
@"DECLARE @BackupSuccess BIT --1 is true 0 is false
|
||||
SET @BackupSuccess = 0
|
||||
BEGIN TRY
|
||||
BACKUP DATABASE " + sqlConStrBuilder.InitialCatalog + @" TO DISK = N'" + defaultBackupFile + @"' WITH NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, CHECKSUM
|
||||
SET @BackupSuccess = 1
|
||||
RESTORE VERIFYONLY FROM DISK = N'"+ defaultBackupFile + @"' WITH NOUNLOAD, NOREWIND, CHECKSUM
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
IF @BackupSuccess = 0
|
||||
BEGIN
|
||||
RAISERROR('Backup failed', 9, " + PrimaryBackupFailed + @")
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
RAISERROR('Verify failed', 9, " + PrimaryBackupVerifyFailed + @")
|
||||
END
|
||||
END CATCH";
|
||||
using (var command = new SqlCommand(query, sqlConnection))
|
||||
{
|
||||
sqlConnection.Open();
|
||||
command.ExecuteNonQuery();
|
||||
if (optionalBackupFilePath == string.Empty) return true;
|
||||
var defaultBackupVerificationFailedFile =
|
||||
defaultBackupFile.Insert(defaultBackupFile.IndexOf(".", StringComparison.Ordinal),
|
||||
" (Verification Failed)");
|
||||
if (File.Exists(defaultBackupVerificationFailedFile))
|
||||
{
|
||||
File.Delete(defaultBackupVerificationFailedFile);
|
||||
}
|
||||
if (State == PrimaryBackupVerifyFailed)
|
||||
{
|
||||
File.Move(defaultBackupFile, defaultBackupVerificationFailedFile);
|
||||
}
|
||||
if (optionalBackupFilePath == string.Empty)
|
||||
{
|
||||
return State != PrimaryBackupFailed;
|
||||
}
|
||||
var optionalBackupFile = optionalBackupFilePath + DateTime.Now.ToString("yy-MM-dd") + "." + DefaultBackupExtension;
|
||||
command.CommandText =
|
||||
$"BACKUP DATABASE {sqlConStrBuilder.InitialCatalog} TO DISK='{optionalBackupFilePath + DateTime.Now.ToString("yy-MM-dd") + "." + DefaultBackupExtension}'";
|
||||
@"DECLARE @BackupSuccess BIT
|
||||
SET @BackupSuccess = 0
|
||||
BEGIN TRY
|
||||
BACKUP DATABASE " + sqlConStrBuilder.InitialCatalog + @" TO DISK = N'" + optionalBackupFile + @"' WITH NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, CHECKSUM
|
||||
SET @BackupSuccess = 1
|
||||
RESTORE VERIFYONLY FROM DISK = N'" + optionalBackupFile + @"' WITH NOUNLOAD, NOREWIND, CHECKSUM
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
IF @BackupSuccess = 0
|
||||
BEGIN
|
||||
RAISERROR('Optional backup failed', 9, " + OptionalBackupFailed + @")
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
RAISERROR('Optional backup verify failed', 9, " + OptionalBackupVerifyFailed + @")
|
||||
END
|
||||
END CATCH";
|
||||
command.ExecuteNonQuery();
|
||||
var optionalBackupVerficationFailedFile =
|
||||
optionalBackupFile.Insert(optionalBackupFile.IndexOf(".", StringComparison.Ordinal),
|
||||
" (Verification Failed)");
|
||||
if (State == OptionalBackupFailed || State == (OptionalBackupFailed + PrimaryBackupFailed) || State == (OptionalBackupFailed + PrimaryBackupVerifyFailed))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (File.Exists(optionalBackupVerficationFailedFile))
|
||||
{
|
||||
File.Delete(optionalBackupVerficationFailedFile);
|
||||
}
|
||||
if (State == OptionalBackupVerifyFailed || State == (OptionalBackupVerifyFailed + PrimaryBackupVerifyFailed) || State == (OptionalBackupVerifyFailed + PrimaryBackupFailed))
|
||||
{
|
||||
File.Move(optionalBackupFile, optionalBackupVerficationFailedFile);
|
||||
}
|
||||
return State == PrimaryBackupFailed;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (SqlException e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user