case 4221

This commit is contained in:
2022-10-26 23:55:57 +00:00
parent 3806cca559
commit a83380d3a4
2 changed files with 117 additions and 129 deletions

View File

@@ -15,7 +15,9 @@ The most recent changes are written in the AyaNova manual [hosted on our website
#### Changed
- UI: Administration -> License page now has time in addition to date for license and maintenance expiration values
- Server: Erase database huge speed improvement
- UI: Administration -> License page added _time_ in addition to existing _date_ for license and maintenance expiration
- UI: Administration -> License page only SuperUser account is offered the Erase Database menu option (no other user has rights to erase db)
### AyaNova 8.0.17 (2022-10-12)

View File

@@ -395,7 +395,7 @@ namespace AyaNova.Util
// Erase all user entered data from the db
// This is called by seeder for trial seeding purposes
// and by v8 migrate and by license controller when erasing db
internal static async Task EmptyBizDataFromDatabaseForSeedingOrImportingAsync(ILogger _log, bool keepTaxCodes=false)
internal static async Task EmptyBizDataFromDatabaseForSeedingOrImportingAsync(ILogger _log, bool keepTaxCodes = false)
{
//case 4221
//erase plan to use truncate table instead of slower delete method
@@ -407,8 +407,8 @@ namespace AyaNova.Util
//- $profit
_log.LogInformation("Erasing Database \"{0}\"", _dbName);
AyaNova.Api.ControllerHelpers.ApiServerState apiServerState = (AyaNova.Api.ControllerHelpers.ApiServerState)ServiceProviderProvider.Provider.GetService(typeof(AyaNova.Api.ControllerHelpers.ApiServerState));
@@ -519,135 +519,119 @@ namespace AyaNova.Util
//REMOVE ALL REMAINING DATA
await EraseTableAsync("aunitmeterreading", conn);
await EraseTableAsync("acustomerservicerequest", conn);
await TruncateTableAsync("aunitmeterreading", conn);
await TruncateTableAsync("acustomerservicerequest", conn);
//--- WorkOrder
await EraseTableAsync("aworkorderitemexpense", conn);
await EraseTableAsync("aworkorderitemlabor", conn);
await EraseTableAsync("aworkorderitemloan", conn);
await EraseTableAsync("aworkorderitempart", conn);
await EraseTableAsync("aworkorderitempartrequest", conn);
await EraseTableAsync("aworkorderitemscheduleduser", conn);
await EraseTableAsync("aworkorderitemtask", conn);
await EraseTableAsync("aworkorderitemtravel", conn);
await EraseTableAsync("aworkorderitemunit", conn);
await EraseTableAsync("aworkorderitemoutsideservice", conn);
await EraseTableAsync("aworkorderitem", conn);
await EraseTableAsync("aworkorderstate", conn);
await EraseTableAsync("aworkorder", conn);
await TruncateTableAsync("aworkorderitemexpense", conn);
await TruncateTableAsync("aworkorderitemlabor", conn);
await TruncateTableAsync("aworkorderitemloan", conn);
await TruncateTableAsync("aworkorderitempart", conn);
await TruncateTableAsync("aworkorderitempartrequest", conn);
await TruncateTableAsync("aworkorderitemscheduleduser", conn);
await TruncateTableAsync("aworkorderitemtask", conn);
await TruncateTableAsync("aworkorderitemtravel", conn);
await TruncateTableAsync("aworkorderitemunit", conn);
await TruncateTableAsync("aworkorderitemoutsideservice", conn);
await TruncateTableAsync("aworkorderitem", conn);
await TruncateTableAsync("aworkorderstate", conn);
await TruncateTableAsync("aworkorder", conn);
//---
//--- QUOTE
await EraseTableAsync("aquoteitemexpense", conn);
await EraseTableAsync("aquoteitemlabor", conn);
await EraseTableAsync("aquoteitemloan", conn);
await EraseTableAsync("aquoteitempart", conn);
await EraseTableAsync("aquoteitemscheduleduser", conn);
await EraseTableAsync("aquoteitemtask", conn);
await EraseTableAsync("aquoteitemtravel", conn);
await EraseTableAsync("aquoteitemunit", conn);
await EraseTableAsync("aquoteitemoutsideservice", conn);
await EraseTableAsync("aquoteitem", conn);
await EraseTableAsync("aquotestate", conn);
await EraseTableAsync("aquote", conn);
await TruncateTableAsync("aquoteitemexpense", conn);
await TruncateTableAsync("aquoteitemlabor", conn);
await TruncateTableAsync("aquoteitemloan", conn);
await TruncateTableAsync("aquoteitempart", conn);
await TruncateTableAsync("aquoteitemscheduleduser", conn);
await TruncateTableAsync("aquoteitemtask", conn);
await TruncateTableAsync("aquoteitemtravel", conn);
await TruncateTableAsync("aquoteitemunit", conn);
await TruncateTableAsync("aquoteitemoutsideservice", conn);
await TruncateTableAsync("aquoteitem", conn);
await TruncateTableAsync("aquotestate", conn);
await TruncateTableAsync("aquote", conn);
//---
//--- PM
await EraseTableAsync("apmitemexpense", conn);
await EraseTableAsync("apmitemlabor", conn);
await EraseTableAsync("apmitemloan", conn);
await EraseTableAsync("apmitempart", conn);
await EraseTableAsync("apmitemscheduleduser", conn);
await EraseTableAsync("apmitemtask", conn);
await EraseTableAsync("apmitemtravel", conn);
await EraseTableAsync("apmitemunit", conn);
await EraseTableAsync("apmitemoutsideservice", conn);
await EraseTableAsync("apmitem", conn);
await EraseTableAsync("apm", conn);//bugbug
//---
await TruncateTableAsync("apmitemexpense", conn);
await TruncateTableAsync("apmitemlabor", conn);
await TruncateTableAsync("apmitemloan", conn);
await TruncateTableAsync("apmitempart", conn);
await TruncateTableAsync("apmitemscheduleduser", conn);
await TruncateTableAsync("apmitemtask", conn);
await TruncateTableAsync("apmitemtravel", conn);
await TruncateTableAsync("apmitemunit", conn);
await TruncateTableAsync("apmitemoutsideservice", conn);
await TruncateTableAsync("apmitem", conn);
await TruncateTableAsync("apm", conn);//bugbug
//---
await EraseTableAsync("afileattachment", conn);
await EraseTableAsync("aevent", conn);
await EraseTableAsync("adatalistsavedfilter", conn);
await EraseTableAsync("adatalistcolumnview", conn);
await EraseTableAsync("apicklisttemplate", conn, true);
await EraseTableAsync("aformcustom", conn);
await EraseTableAsync("asearchkey", conn);
await EraseTableAsync("asearchdictionary", conn);
await EraseTableAsync("atag", conn);
await EraseTableAsync("apurchaseorderitem", conn);
await EraseTableAsync("apurchaseorder", conn);
await TruncateTableAsync("afileattachment", conn);
await TruncateTableAsync("aevent", conn);
await TruncateTableAsync("adatalistsavedfilter", conn);
await TruncateTableAsync("adatalistcolumnview", conn);
await TruncateTableAsync("apicklisttemplate", conn, true);
await TruncateTableAsync("aformcustom", conn);
await TruncateTableAsync("asearchkey", conn);
await TruncateTableAsync("asearchdictionary", conn);
await TruncateTableAsync("atag", conn);
await TruncateTableAsync("apurchaseorderitem", conn);
await TruncateTableAsync("apurchaseorder", conn);
await EraseTableAsync("apartassemblyitem", conn);
await EraseTableAsync("apartassembly", conn);
await EraseTableAsync("apartinventory", conn);
await EraseTableAsync("apart", conn);
await TruncateTableAsync("apartassemblyitem", conn);
await TruncateTableAsync("apartassembly", conn);
await TruncateTableAsync("apartinventory", conn);
await TruncateTableAsync("apart", conn);
await EraseTableAsync("aloanunit", conn);
await EraseTableAsync("aunitmodel", conn);
await EraseTableAsync("avendor", conn);
await TruncateTableAsync("aloanunit", conn);
await TruncateTableAsync("aunitmodel", conn);
await TruncateTableAsync("avendor", conn);
await EraseTableAsync("aunit", conn);
await EraseTableAsync("aproject", conn);//depends on User, dependants are wo,quote,pm
await TruncateTableAsync("aunit", conn);
await TruncateTableAsync("aproject", conn);//depends on User, dependants are wo,quote,pm
await EraseTableAsync("acustomernote", conn);
await EraseTableAsync("acustomer", conn);
await EraseTableAsync("aheadoffice", conn);
await EraseTableAsync("acontract", conn);
await TruncateTableAsync("acustomernote", conn);
await TruncateTableAsync("acustomer", conn);
await TruncateTableAsync("aheadoffice", conn);
await TruncateTableAsync("acontract", conn);
//----- NOTIFICATION
await EraseTableAsync("ainappnotification", conn);
await EraseTableAsync("anotifyevent", conn);
await EraseTableAsync("anotifydeliverylog", conn);
await EraseTableAsync("anotifysubscription", conn);
await EraseTableAsync("acustomernotifyevent", conn);
await EraseTableAsync("acustomernotifydeliverylog", conn);
await EraseTableAsync("acustomernotifysubscription", conn);
await TruncateTableAsync("ainappnotification", conn);
await TruncateTableAsync("anotifyevent", conn);
await TruncateTableAsync("anotifydeliverylog", conn);
await TruncateTableAsync("anotifysubscription", conn);
await TruncateTableAsync("acustomernotifyevent", conn);
await TruncateTableAsync("acustomernotifydeliverylog", conn);
await TruncateTableAsync("acustomernotifysubscription", conn);
await EraseTableAsync("amemo", conn);
await EraseTableAsync("areminder", conn);//depends on User
await EraseTableAsync("areview", conn);//depends on User
await TruncateTableAsync("amemo", conn);
await TruncateTableAsync("areminder", conn);//depends on User
await TruncateTableAsync("areview", conn);//depends on User
await EraseTableAsync("aservicerate", conn);
await EraseTableAsync("atravelrate", conn);
await TruncateTableAsync("aservicerate", conn);
await TruncateTableAsync("atravelrate", conn);
if (!keepTaxCodes)
await EraseTableAsync("ataxcode", conn);
await EraseTableAsync("aquotestatus", conn);
await EraseTableAsync("aworkorderstatus", conn);
await EraseTableAsync("aworkorderitemstatus", conn);
await EraseTableAsync("aworkorderitempriority", conn);
await EraseTableAsync("ataskgroup", conn);//items cascade
await TruncateTableAsync("aquotestatus", conn);
await TruncateTableAsync("aworkorderstatus", conn);
await TruncateTableAsync("aworkorderitemstatus", conn);
await TruncateTableAsync("aworkorderitempriority", conn);
await TruncateTableAsync("ataskgroup", conn);//items cascade
await EraseTableAsync("ametricmm", conn, true);
await EraseTableAsync("ametricdd", conn, true);
await EraseTableAsync("adashboardview", conn);
await TruncateTableAsync("ametricmm", conn, true);
await TruncateTableAsync("ametricdd", conn, true);
await TruncateTableAsync("adashboardview", conn);
await EraseTableAsync("aintegration", conn);
await TruncateTableAsync("aintegration", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
// await EraseTableAsync("XXXXX", conn);
//############# WARNING: there can be unintended consequences easily if new tables or fields are added that REFERENCE other tables triggering a cascade delete unexpectedly
//be sure about that before making changes and test thoroughly anything that calls this method:
// the seeding and manual erase and v8-migrate code when making such changes
//case 4221 truncate support
@@ -673,8 +657,8 @@ namespace AyaNova.Util
+ "FROM auseroptions_backup where userid = 1;";
await cmd.ExecuteNonQueryAsync();
cmd.CommandText="DROP TABLE IF EXISTS AUSEROPTIONS_BACKUP, AUSER_BACKUP;";
await cmd.ExecuteNonQueryAsync();
cmd.CommandText = "DROP TABLE IF EXISTS AUSEROPTIONS_BACKUP, AUSER_BACKUP;";
await cmd.ExecuteNonQueryAsync();
}
@@ -682,15 +666,6 @@ namespace AyaNova.Util
using (var cmd = new Npgsql.NpgsqlCommand())
{
cmd.Connection = conn;
//Removed for case 4221 handled above
// // cmd.CommandText = "delete from \"auseroptions\" where UserId <> 1;";
// // await cmd.ExecuteNonQueryAsync();
// // cmd.CommandText = "ALTER SEQUENCE auseroptions_id_seq RESTART WITH 2;";
// // await cmd.ExecuteNonQueryAsync();
// // cmd.CommandText = "delete from \"auser\" where id <> 1;";
// // await cmd.ExecuteNonQueryAsync();
// // cmd.CommandText = "ALTER SEQUENCE auser_id_seq RESTART WITH 2;";
// // await cmd.ExecuteNonQueryAsync();
cmd.CommandText = "delete from \"apartwarehouse\" where id <> 1;";
await cmd.ExecuteNonQueryAsync();
@@ -724,25 +699,36 @@ namespace AyaNova.Util
///////////////////////////////////////////
// Erase all data from the table specified
// Truncate all data from the table specified
//
private static async Task EraseTableAsync(string sTable, Npgsql.NpgsqlConnection conn, bool tableHasNoSequence = false)
private static async Task TruncateTableAsync(string sTable, Npgsql.NpgsqlConnection conn, bool tableHasNoSequence = false)
{
using (var cmd = new Npgsql.NpgsqlCommand())
{
cmd.Connection = conn;
//Boo! Can't do this becuase it will fail if there is a foreign key which nearly all tables have unless cascade option is used
//but then cascade causes things to delete in any referenced table
cmd.CommandText = "TRUNCATE \"" + sTable + "\" RESTART IDENTITY CASCADE;";
//// cmd.CommandText = $"delete from {sTable};";
await cmd.ExecuteNonQueryAsync();
// // if (!tableHasNoSequence)
// // {
// // cmd.CommandText = $"ALTER SEQUENCE {sTable}_id_seq RESTART WITH 1;";
// // await cmd.ExecuteNonQueryAsync();
// // }
}
}
///////////////////////////////////////////
// Erase all data from the table specified
//
private static async Task EraseTableAsync(string sTable, Npgsql.NpgsqlConnection conn, bool tableHasNoSequence = false)
{
//this variant is used for tables that don't need to be truncated due to smaller size
//and would trigger need to backup referenced tables first
using (var cmd = new Npgsql.NpgsqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = $"delete from {sTable};";
await cmd.ExecuteNonQueryAsync();
if (!tableHasNoSequence)
{
cmd.CommandText = $"ALTER SEQUENCE {sTable}_id_seq RESTART WITH 1;";
await cmd.ExecuteNonQueryAsync();
}
}
}