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 #### 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) ### AyaNova 8.0.17 (2022-10-12)

View File

@@ -395,7 +395,7 @@ namespace AyaNova.Util
// Erase all user entered data from the db // Erase all user entered data from the db
// This is called by seeder for trial seeding purposes // This is called by seeder for trial seeding purposes
// and by v8 migrate and by license controller when erasing db // 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 //case 4221
//erase plan to use truncate table instead of slower delete method //erase plan to use truncate table instead of slower delete method
@@ -407,8 +407,8 @@ namespace AyaNova.Util
//- $profit //- $profit
_log.LogInformation("Erasing Database \"{0}\"", _dbName); _log.LogInformation("Erasing Database \"{0}\"", _dbName);
AyaNova.Api.ControllerHelpers.ApiServerState apiServerState = (AyaNova.Api.ControllerHelpers.ApiServerState)ServiceProviderProvider.Provider.GetService(typeof(AyaNova.Api.ControllerHelpers.ApiServerState)); 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 //REMOVE ALL REMAINING DATA
await EraseTableAsync("aunitmeterreading", conn); await TruncateTableAsync("aunitmeterreading", conn);
await EraseTableAsync("acustomerservicerequest", conn); await TruncateTableAsync("acustomerservicerequest", conn);
//--- WorkOrder //--- WorkOrder
await EraseTableAsync("aworkorderitemexpense", conn); await TruncateTableAsync("aworkorderitemexpense", conn);
await EraseTableAsync("aworkorderitemlabor", conn); await TruncateTableAsync("aworkorderitemlabor", conn);
await EraseTableAsync("aworkorderitemloan", conn); await TruncateTableAsync("aworkorderitemloan", conn);
await EraseTableAsync("aworkorderitempart", conn); await TruncateTableAsync("aworkorderitempart", conn);
await EraseTableAsync("aworkorderitempartrequest", conn); await TruncateTableAsync("aworkorderitempartrequest", conn);
await EraseTableAsync("aworkorderitemscheduleduser", conn); await TruncateTableAsync("aworkorderitemscheduleduser", conn);
await EraseTableAsync("aworkorderitemtask", conn); await TruncateTableAsync("aworkorderitemtask", conn);
await EraseTableAsync("aworkorderitemtravel", conn); await TruncateTableAsync("aworkorderitemtravel", conn);
await EraseTableAsync("aworkorderitemunit", conn); await TruncateTableAsync("aworkorderitemunit", conn);
await EraseTableAsync("aworkorderitemoutsideservice", conn); await TruncateTableAsync("aworkorderitemoutsideservice", conn);
await EraseTableAsync("aworkorderitem", conn); await TruncateTableAsync("aworkorderitem", conn);
await EraseTableAsync("aworkorderstate", conn); await TruncateTableAsync("aworkorderstate", conn);
await EraseTableAsync("aworkorder", conn); await TruncateTableAsync("aworkorder", conn);
//--- //---
//--- QUOTE //--- QUOTE
await EraseTableAsync("aquoteitemexpense", conn); await TruncateTableAsync("aquoteitemexpense", conn);
await EraseTableAsync("aquoteitemlabor", conn); await TruncateTableAsync("aquoteitemlabor", conn);
await EraseTableAsync("aquoteitemloan", conn); await TruncateTableAsync("aquoteitemloan", conn);
await EraseTableAsync("aquoteitempart", conn); await TruncateTableAsync("aquoteitempart", conn);
await EraseTableAsync("aquoteitemscheduleduser", conn); await TruncateTableAsync("aquoteitemscheduleduser", conn);
await EraseTableAsync("aquoteitemtask", conn); await TruncateTableAsync("aquoteitemtask", conn);
await EraseTableAsync("aquoteitemtravel", conn); await TruncateTableAsync("aquoteitemtravel", conn);
await EraseTableAsync("aquoteitemunit", conn); await TruncateTableAsync("aquoteitemunit", conn);
await EraseTableAsync("aquoteitemoutsideservice", conn); await TruncateTableAsync("aquoteitemoutsideservice", conn);
await EraseTableAsync("aquoteitem", conn); await TruncateTableAsync("aquoteitem", conn);
await EraseTableAsync("aquotestate", conn); await TruncateTableAsync("aquotestate", conn);
await EraseTableAsync("aquote", conn); await TruncateTableAsync("aquote", conn);
//--- //---
//--- PM //--- PM
await EraseTableAsync("apmitemexpense", conn); await TruncateTableAsync("apmitemexpense", conn);
await EraseTableAsync("apmitemlabor", conn); await TruncateTableAsync("apmitemlabor", conn);
await EraseTableAsync("apmitemloan", conn); await TruncateTableAsync("apmitemloan", conn);
await EraseTableAsync("apmitempart", conn); await TruncateTableAsync("apmitempart", conn);
await EraseTableAsync("apmitemscheduleduser", conn); await TruncateTableAsync("apmitemscheduleduser", conn);
await EraseTableAsync("apmitemtask", conn); await TruncateTableAsync("apmitemtask", conn);
await EraseTableAsync("apmitemtravel", conn); await TruncateTableAsync("apmitemtravel", conn);
await EraseTableAsync("apmitemunit", conn); await TruncateTableAsync("apmitemunit", conn);
await EraseTableAsync("apmitemoutsideservice", conn); await TruncateTableAsync("apmitemoutsideservice", conn);
await EraseTableAsync("apmitem", conn); await TruncateTableAsync("apmitem", conn);
await EraseTableAsync("apm", conn);//bugbug await TruncateTableAsync("apm", conn);//bugbug
//--- //---
await EraseTableAsync("afileattachment", conn); await TruncateTableAsync("afileattachment", conn);
await EraseTableAsync("aevent", conn); await TruncateTableAsync("aevent", conn);
await EraseTableAsync("adatalistsavedfilter", conn); await TruncateTableAsync("adatalistsavedfilter", conn);
await EraseTableAsync("adatalistcolumnview", conn); await TruncateTableAsync("adatalistcolumnview", conn);
await EraseTableAsync("apicklisttemplate", conn, true); await TruncateTableAsync("apicklisttemplate", conn, true);
await EraseTableAsync("aformcustom", conn); await TruncateTableAsync("aformcustom", conn);
await EraseTableAsync("asearchkey", conn); await TruncateTableAsync("asearchkey", conn);
await EraseTableAsync("asearchdictionary", conn); await TruncateTableAsync("asearchdictionary", conn);
await EraseTableAsync("atag", conn); await TruncateTableAsync("atag", conn);
await EraseTableAsync("apurchaseorderitem", conn); await TruncateTableAsync("apurchaseorderitem", conn);
await EraseTableAsync("apurchaseorder", conn); await TruncateTableAsync("apurchaseorder", conn);
await EraseTableAsync("apartassemblyitem", conn); await TruncateTableAsync("apartassemblyitem", conn);
await EraseTableAsync("apartassembly", conn); await TruncateTableAsync("apartassembly", conn);
await EraseTableAsync("apartinventory", conn); await TruncateTableAsync("apartinventory", conn);
await EraseTableAsync("apart", conn); await TruncateTableAsync("apart", conn);
await EraseTableAsync("aloanunit", conn); await TruncateTableAsync("aloanunit", conn);
await EraseTableAsync("aunitmodel", conn); await TruncateTableAsync("aunitmodel", conn);
await EraseTableAsync("avendor", conn); await TruncateTableAsync("avendor", conn);
await EraseTableAsync("aunit", conn); await TruncateTableAsync("aunit", conn);
await EraseTableAsync("aproject", conn);//depends on User, dependants are wo,quote,pm await TruncateTableAsync("aproject", conn);//depends on User, dependants are wo,quote,pm
await EraseTableAsync("acustomernote", conn); await TruncateTableAsync("acustomernote", conn);
await EraseTableAsync("acustomer", conn); await TruncateTableAsync("acustomer", conn);
await EraseTableAsync("aheadoffice", conn); await TruncateTableAsync("aheadoffice", conn);
await EraseTableAsync("acontract", conn); await TruncateTableAsync("acontract", conn);
//----- NOTIFICATION //----- NOTIFICATION
await EraseTableAsync("ainappnotification", conn); await TruncateTableAsync("ainappnotification", conn);
await EraseTableAsync("anotifyevent", conn); await TruncateTableAsync("anotifyevent", conn);
await EraseTableAsync("anotifydeliverylog", conn); await TruncateTableAsync("anotifydeliverylog", conn);
await EraseTableAsync("anotifysubscription", conn); await TruncateTableAsync("anotifysubscription", conn);
await EraseTableAsync("acustomernotifyevent", conn); await TruncateTableAsync("acustomernotifyevent", conn);
await EraseTableAsync("acustomernotifydeliverylog", conn); await TruncateTableAsync("acustomernotifydeliverylog", conn);
await EraseTableAsync("acustomernotifysubscription", conn); await TruncateTableAsync("acustomernotifysubscription", conn);
await EraseTableAsync("amemo", conn); await TruncateTableAsync("amemo", conn);
await EraseTableAsync("areminder", conn);//depends on User await TruncateTableAsync("areminder", conn);//depends on User
await EraseTableAsync("areview", conn);//depends on User await TruncateTableAsync("areview", conn);//depends on User
await EraseTableAsync("aservicerate", conn); await TruncateTableAsync("aservicerate", conn);
await EraseTableAsync("atravelrate", conn); await TruncateTableAsync("atravelrate", conn);
if (!keepTaxCodes) if (!keepTaxCodes)
await EraseTableAsync("ataxcode", conn); await EraseTableAsync("ataxcode", conn);
await EraseTableAsync("aquotestatus", conn); await TruncateTableAsync("aquotestatus", conn);
await EraseTableAsync("aworkorderstatus", conn); await TruncateTableAsync("aworkorderstatus", conn);
await EraseTableAsync("aworkorderitemstatus", conn); await TruncateTableAsync("aworkorderitemstatus", conn);
await EraseTableAsync("aworkorderitempriority", conn); await TruncateTableAsync("aworkorderitempriority", conn);
await EraseTableAsync("ataskgroup", conn);//items cascade await TruncateTableAsync("ataskgroup", conn);//items cascade
await EraseTableAsync("ametricmm", conn, true); await TruncateTableAsync("ametricmm", conn, true);
await EraseTableAsync("ametricdd", conn, true); await TruncateTableAsync("ametricdd", conn, true);
await EraseTableAsync("adashboardview", conn); await TruncateTableAsync("adashboardview", conn);
await EraseTableAsync("aintegration", conn); await TruncateTableAsync("aintegration", 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
// 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);
//case 4221 truncate support //case 4221 truncate support
@@ -673,8 +657,8 @@ namespace AyaNova.Util
+ "FROM auseroptions_backup where userid = 1;"; + "FROM auseroptions_backup where userid = 1;";
await cmd.ExecuteNonQueryAsync(); await cmd.ExecuteNonQueryAsync();
cmd.CommandText="DROP TABLE IF EXISTS AUSEROPTIONS_BACKUP, AUSER_BACKUP;"; cmd.CommandText = "DROP TABLE IF EXISTS AUSEROPTIONS_BACKUP, AUSER_BACKUP;";
await cmd.ExecuteNonQueryAsync(); await cmd.ExecuteNonQueryAsync();
} }
@@ -682,15 +666,6 @@ namespace AyaNova.Util
using (var cmd = new Npgsql.NpgsqlCommand()) using (var cmd = new Npgsql.NpgsqlCommand())
{ {
cmd.Connection = conn; 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;"; cmd.CommandText = "delete from \"apartwarehouse\" where id <> 1;";
await cmd.ExecuteNonQueryAsync(); 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()) using (var cmd = new Npgsql.NpgsqlCommand())
{ {
cmd.Connection = conn; 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 = "TRUNCATE \"" + sTable + "\" RESTART IDENTITY CASCADE;";
//// cmd.CommandText = $"delete from {sTable};";
await cmd.ExecuteNonQueryAsync(); 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();
}
} }
} }