Commit d4dde2c4e3c5731acdfdb523c6aa34213af305f7
1 parent
32c3a934
v1.31.0
- Multirun script-ek végrehajtása
Showing
7 changed files
with
398 additions
and
109 deletions
Show diff stats
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs
| ... | ... | @@ -10,6 +10,12 @@ using System.Diagnostics; |
| 10 | 10 | |
| 11 | 11 | using Vrh.XmlProcessing; |
| 12 | 12 | using System.Xml.Linq; |
| 13 | +using Microsoft.SqlServer.Management.Smo; | |
| 14 | +using static Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS.CLP.Module.ScheduledTaskManager.Function; | |
| 15 | +using static Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS.FolderToClean.XmlStructure.FolderToClean.Conditions.Condition.Attributes; | |
| 16 | +using System.Reflection; | |
| 17 | +using System.Threading; | |
| 18 | +using System.Windows.Forms; | |
| 13 | 19 | |
| 14 | 20 | namespace Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS |
| 15 | 21 | { |
| ... | ... | @@ -68,17 +74,35 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS |
| 68 | 74 | /// Visszaadja a lenyomott billentyűt, ha van, commandmode-ban pedig az enter-t |
| 69 | 75 | /// </summary> |
| 70 | 76 | /// <returns></returns> |
| 71 | - public static ConsoleKeyInfo ReadKey() | |
| 72 | - { | |
| 73 | - if (SilentMode) { return GetConsoleKey(ConsoleKey.Enter); } | |
| 74 | - else { return Console.ReadKey(); } | |
| 75 | - } | |
| 77 | + public static ConsoleKeyInfo? ReadKey(TimeSpan? maxwaittime) | |
| 78 | + { | |
| 79 | + if (SilentMode) { return GetConsoleKey(ConsoleKey.Enter); } | |
| 80 | + if (maxwaittime ==null || maxwaittime == TimeSpan.Zero) { return Console.ReadKey(); } | |
| 81 | + else | |
| 82 | + { | |
| 83 | + var strtime = DateTime.Now; | |
| 84 | + var endtime = strtime.Add(maxwaittime.Value); | |
| 85 | + var nexttime = strtime; | |
| 86 | + while (nexttime <= endtime) | |
| 87 | + { | |
| 88 | + if (Console.KeyAvailable) return Console.ReadKey(true); | |
| 89 | + Thread.Sleep(50); | |
| 90 | + nexttime = DateTime.Now; | |
| 91 | + } | |
| 92 | + return null; | |
| 93 | + } | |
| 94 | + } | |
| 95 | + public static ConsoleKeyInfo ReadKey() | |
| 96 | + { | |
| 97 | + if (SilentMode) { return GetConsoleKey(ConsoleKey.Enter); } | |
| 98 | + else { return Console.ReadKey(); } | |
| 99 | + } | |
| 76 | 100 | |
| 77 | - /// <summary> | |
| 78 | - /// Visszaadja a lenyomott billentyűt, ha van, commandmode-ban pedig az enter-t | |
| 79 | - /// </summary> | |
| 80 | - /// <returns></returns> | |
| 81 | - public static ConsoleKeyInfo GetConsoleKey(ConsoleKey ck, bool shift = false, bool alt=false,bool control=false) | |
| 101 | + /// <summary> | |
| 102 | + /// Visszaadja a lenyomott billentyűt, ha van, commandmode-ban pedig az enter-t | |
| 103 | + /// </summary> | |
| 104 | + /// <returns></returns> | |
| 105 | + public static ConsoleKeyInfo GetConsoleKey(ConsoleKey ck, bool shift = false, bool alt=false,bool control=false) | |
| 82 | 106 | { |
| 83 | 107 | switch (ck) |
| 84 | 108 | { | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs
| ... | ... | @@ -65,7 +65,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS |
| 65 | 65 | ExternalProcess.StartInfo.FileName = config.Exe; |
| 66 | 66 | ExternalProcess.StartInfo.WindowStyle = config.ProcessWindowsStyle; |
| 67 | 67 | |
| 68 | - if (!Tools.ResolveArguments(config.ArgumentParameters, config.Arguments, out string resolvedtext)) { return o; }; | |
| 68 | + if (!Tools.KvpString.Resolve(config.ArgumentParameters, config.Arguments, out string resolvedtext)) { return o; }; | |
| 69 | 69 | ExternalProcess.StartInfo.Arguments = resolvedtext; |
| 70 | 70 | ExternalProcess.Start(); |
| 71 | 71 | int waitingtime = config.WaitForExit ? -1 : 0; |
| ... | ... | @@ -633,8 +633,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS |
| 633 | 633 | Exe = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Exe), x, ""); |
| 634 | 634 | this.Key = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Key), x, ""); |
| 635 | 635 | this.Description = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Description), x, Exe); |
| 636 | - Tools.ResolveArguments(ArgumentParameters, this.Key,out this.Key,interactive:false); | |
| 637 | - Tools.ResolveArguments(ArgumentParameters, this.Description, out this.Description, interactive: false); | |
| 636 | + Tools.KvpString.Resolve(ArgumentParameters, this.Key,out this.Key,disableinteractive:true); | |
| 637 | + Tools.KvpString.Resolve(ArgumentParameters, this.Description, out this.Description, disableinteractive: true); | |
| 638 | 638 | Arguments = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Arguments), x, XmlStructure.ExternalUtility.Attributes.Arguments.Values.DEFAULT); |
| 639 | 639 | |
| 640 | 640 | ProcessWindowsStyle = GetValue<ProcessWindowStyle>(nameof(XmlStructure.ExternalUtility.Attributes.WindowStyle), x, XmlStructure.ExternalUtility.Attributes.WindowStyle.Values.DEFAULT); | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs
| ... | ... | @@ -26,6 +26,12 @@ using System.Text.RegularExpressions; |
| 26 | 26 | using Microsoft.SqlServer.Management.Common; |
| 27 | 27 | using Microsoft.SqlServer.Management.Smo; |
| 28 | 28 | using Microsoft.Data.SqlClient; |
| 29 | +using Microsoft.Identity.Client; | |
| 30 | +using VRH.Common.Log4ProIS; | |
| 31 | +using System.Security.Cryptography; | |
| 32 | +using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder; | |
| 33 | +using System.Windows.Controls; | |
| 34 | +using Menu = Vrh.Log4Pro.MaintenanceConsole.MenuNS.Menu; | |
| 29 | 35 | |
| 30 | 36 | namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS |
| 31 | 37 | { |
| ... | ... | @@ -926,27 +932,30 @@ GO |
| 926 | 932 | else { return null; } |
| 927 | 933 | } |
| 928 | 934 | |
| 929 | - string ssScriptText = null; | |
| 930 | - string LastUpdatedTrigger_parameters = $"DBNAME={triggertoexecute.Db};SCHEMA={triggertoexecute.Schema};TABLE={triggertoexecute.Table};COLUMN={triggertoexecute.Column};TRIGGER={LastUpdatedTrigger_triggername};"; | |
| 931 | - if (!Tools.ResolveArguments(LastUpdatedTrigger_parameters, RemoveLastUpdatedTrigger_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 932 | - try { SQLDataBaseManagerCore.ExecuteSQLScript(sqlcs, ssScriptText, 5000, null); } | |
| 933 | - catch (Exception e) { ColorConsole.WriteLine(e.MessageNested(), ConsoleColor.Yellow); } | |
| 934 | - if (!Tools.ResolveArguments(LastUpdatedTrigger_parameters, RemoveLastUpdatedColumn_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 935 | - try { SQLDataBaseManagerCore.ExecuteSQLScript(sqlcs, ssScriptText, 5000, null); } | |
| 936 | - catch (Exception e) { ColorConsole.WriteLine(e.MessageNested(), ConsoleColor.Yellow); } | |
| 937 | - | |
| 938 | - if (!triggertoexecute.Remove) | |
| 935 | + using (var sqlc = ServerConnectionPool.GetSqlConnection(sqlcs, open: true)) | |
| 939 | 936 | { |
| 940 | - if (!Tools.ResolveArguments(LastUpdatedTrigger_parameters, CreateLastUpdatedColumn_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 941 | - SQLDataBaseManagerCore.ExecuteSQLScript(sqlcs, ssScriptText, 5000, null); | |
| 937 | + string ssScriptText = null; | |
| 938 | + string LastUpdatedTrigger_parameters = $"DBNAME={triggertoexecute.Db};SCHEMA={triggertoexecute.Schema};TABLE={triggertoexecute.Table};COLUMN={triggertoexecute.Column};TRIGGER={LastUpdatedTrigger_triggername};"; | |
| 939 | + if (!Tools.KvpString.Resolve(LastUpdatedTrigger_parameters, RemoveLastUpdatedTrigger_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 940 | + try { SQLDataBaseManagerCore.ExecuteSQLScript(sqlc, ssScriptText, 5000, null); } | |
| 941 | + catch (Exception e) { ColorConsole.WriteLine(e.MessageNested(), ConsoleColor.Yellow); } | |
| 942 | + if (!Tools.KvpString.Resolve(LastUpdatedTrigger_parameters, RemoveLastUpdatedColumn_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 943 | + try { SQLDataBaseManagerCore.ExecuteSQLScript(sqlc, ssScriptText, 5000, null); } | |
| 944 | + catch (Exception e) { ColorConsole.WriteLine(e.MessageNested(), ConsoleColor.Yellow); } | |
| 945 | + | |
| 946 | + if (!triggertoexecute.Remove) | |
| 947 | + { | |
| 948 | + if (!Tools.KvpString.Resolve(LastUpdatedTrigger_parameters, CreateLastUpdatedColumn_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 949 | + SQLDataBaseManagerCore.ExecuteSQLScript(sqlc, ssScriptText, 5000, null); | |
| 942 | 950 | |
| 943 | - if (!Tools.ResolveArguments(LastUpdatedTrigger_parameters, CreateLastUpdatedTrigger_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 944 | - SQLDataBaseManagerCore.ExecuteSQLScript(sqlcs, ssScriptText, 5000, null); | |
| 951 | + if (!Tools.KvpString.Resolve(LastUpdatedTrigger_parameters, CreateLastUpdatedTrigger_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 952 | + SQLDataBaseManagerCore.ExecuteSQLScript(sqlc, ssScriptText, 5000, null); | |
| 945 | 953 | |
| 946 | - if (!Tools.ResolveArguments(LastUpdatedTrigger_parameters, EnableLastUpdatedTrigger_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 947 | - SQLDataBaseManagerCore.ExecuteSQLScript(sqlcs, ssScriptText, 5000, null); | |
| 954 | + if (!Tools.KvpString.Resolve(LastUpdatedTrigger_parameters, EnableLastUpdatedTrigger_Script, out ssScriptText)) { throw new ApplicationException(); } | |
| 955 | + SQLDataBaseManagerCore.ExecuteSQLScript(sqlc, ssScriptText, 5000, null); | |
| 956 | + } | |
| 948 | 957 | } |
| 949 | - ColorConsole.WriteLine($"SUCCESS! {removeactionText} trigger to store LastUpdate TimeStamp: {LastUpdatedTrigger_fulldesignation}", ConsoleColor.Green); | |
| 958 | + ColorConsole.WriteLine($"SUCCESS! {removeactionText} trigger to store LastUpdate TimeStamp: {LastUpdatedTrigger_fulldesignation}", ConsoleColor.Green); | |
| 950 | 959 | } |
| 951 | 960 | catch (ApplicationException e) { ColorConsole.WriteLine("FATAL ERROR! in script parameter substitution!", ConsoleColor.Red); returntext = null; } |
| 952 | 961 | catch (Exception e) { ColorConsole.WriteLine("FATAL ERROR! " + e.MessageNested(), ConsoleColor.Red); returntext = null; } |
| ... | ... | @@ -985,29 +994,49 @@ GO |
| 985 | 994 | foreach (var s in sqld.Xml_SQLScriptList) |
| 986 | 995 | { |
| 987 | 996 | ColorConsole.Write(s.Key, ConsoleColor.Yellow, bracket: "[]",suffix:" ",prefix: " "); |
| 988 | - var fromfile = string.IsNullOrWhiteSpace(s.FilePath) ? "": $",from:{s.FilePath}"; | |
| 989 | - ColorConsole.Write($"{s.Description} ({s.Name}{fromfile})", ConsoleColor.Yellow, prefix: "Script:"); | |
| 990 | - ColorConsole.WriteLine(); | |
| 997 | + ColorConsole.Write(s.Name, ConsoleColor.Yellow, bracket: "[]", prefix: "Script:"); | |
| 998 | + if (s.Multirun) ColorConsole.Write("MULTIRUN", ConsoleColor.Red, bracket: "[]",prefix: " "); | |
| 999 | + ColorConsole.Write(s.Description, ConsoleColor.Yellow, prefix: " "); | |
| 1000 | + if (!string.IsNullOrWhiteSpace(s.FilePath)) { ColorConsole.Write(s.FilePath, ConsoleColor.Yellow, prefix: ", from file:"); | |
| 1001 | + } | |
| 1002 | + ColorConsole.WriteLine(); | |
| 991 | 1003 | vlist.Add(s.Key); |
| 992 | 1004 | } |
| 993 | 1005 | var scriptkey = ColorConsole.ReadLine("Select the script! [empty]=next DB, [*]=all, [EX]=exit.", ConsoleColor.Yellow, prefix:" ", suffix: " --> ", validitylist: vlist); |
| 994 | 1006 | if (string.IsNullOrWhiteSpace(scriptkey)) { continue; } |
| 995 | 1007 | if (scriptkey.ToUpper() == "EX") { return o; } |
| 996 | 1008 | SQLDataBase.SQLScript ss = sqld.Xml_SQLScriptList.FirstOrDefault(s=>s.Key==scriptkey); |
| 997 | - if (!Tools.ResolveArguments(ss.ArgumentParameters, ss.ScriptText,out string ssScriptText)) { return o; } | |
| 998 | - if (ss.ScriptText == null) | |
| 999 | - { | |
| 1000 | - ColorConsole.WriteLine($"Nothing to execute!. Check script definition entry!", ConsoleColor.Red); | |
| 1001 | - } | |
| 1009 | + if (string.IsNullOrWhiteSpace(ss.ScriptText)) { ColorConsole.WriteLine($"Nothing to execute!. Check script definition entry!", ConsoleColor.Red); } | |
| 1002 | 1010 | else |
| 1003 | 1011 | { |
| 1004 | - ColorConsole.WriteLine(ssScriptText); | |
| 1005 | 1012 | var confirm = ColorConsole.ReadLine("Enter CONFIRM to start! [EX]=exit.", ConsoleColor.Yellow, prefix:" ", suffix: " --> ", validitylist: new List<string>() {"CONFIRM"}); |
| 1006 | 1013 | if (confirm == "CONFIRM") |
| 1007 | 1014 | { |
| 1008 | - SQLDataBaseManagerCore.ExecuteSQLScript(sqld.SQLCS, ssScriptText, ss.CommandTimeout, null); | |
| 1009 | - ColorConsole.WriteLine($"Script executed. Name:{sqld.DBName}, script name: {ss.Name}", ConsoleColor.Green); | |
| 1010 | - } | |
| 1015 | + bool multirunmode = ss.Multirun; | |
| 1016 | + int commandtimeout = ss.CommandTimeout; | |
| 1017 | + ReturnInfoJSON result = null; | |
| 1018 | + using (var sqlc = ServerConnectionPool.GetSqlConnection(sqld.SQLCS, open: true)) | |
| 1019 | + { | |
| 1020 | + if (multirunmode) { result = SQLDataBaseManagerCore.ExecuteMultirunSQLScript(sqlc, ss, ExitAfterOneRun); } | |
| 1021 | + else | |
| 1022 | + { | |
| 1023 | + if (!Tools.KvpString.Resolve(ss.ArgumentParameters, ss.ScriptText, out string ssScriptText)) { return o; } | |
| 1024 | + ColorConsole.WriteLine(ssScriptText); | |
| 1025 | + result = SQLDataBaseManagerCore.ExecuteSQLScript(sqlc, ssScriptText, commandtimeout, null); | |
| 1026 | + } | |
| 1027 | + } | |
| 1028 | + if (result.ReturnValue == 0) | |
| 1029 | + { | |
| 1030 | + ColorConsole.WriteLine(result.ReturnMessage, ConsoleColor.White); | |
| 1031 | + ColorConsole.WriteLine($"Script execution SUCCESS. Name:{sqld.DBName}, script name: {ss.Name}", ConsoleColor.Green); | |
| 1032 | + } | |
| 1033 | + else | |
| 1034 | + { | |
| 1035 | + ColorConsole.WriteLine(result.ReturnMessage, ConsoleColor.White); | |
| 1036 | + ColorConsole.WriteLine($"Script execution FAILURE. Name:{sqld.DBName}, script name: {ss.Name}", ConsoleColor.Red); | |
| 1037 | + } | |
| 1038 | + | |
| 1039 | + } | |
| 1011 | 1040 | else {ColorConsole.WriteLine($"Script was NOT executed!", ConsoleColor.Red);} |
| 1012 | 1041 | } |
| 1013 | 1042 | } |
| ... | ... | @@ -1016,6 +1045,16 @@ GO |
| 1016 | 1045 | } |
| 1017 | 1046 | return o; |
| 1018 | 1047 | } |
| 1048 | + static bool ExitAfterOneRun(ReturnInfoJSON runresult) | |
| 1049 | + { | |
| 1050 | + if (runresult != null) | |
| 1051 | + { | |
| 1052 | + ColorConsole.Write(runresult.ReturnValue==0?"OK":"NOK", runresult.ReturnValue == 0 ? ConsoleColor.Green : ConsoleColor.Red); | |
| 1053 | + ColorConsole.WriteLine(runresult.ReturnMessage, ConsoleColor.White,prefix:" "); | |
| 1054 | + } | |
| 1055 | + var returnkey = ColorConsole.ReadKey(new TimeSpan(0, 0, 5)); | |
| 1056 | + return returnkey != null; | |
| 1057 | + } | |
| 1019 | 1058 | private static object DropDB(object parameter, object o) |
| 1020 | 1059 | { |
| 1021 | 1060 | var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>(); |
| ... | ... | @@ -1893,32 +1932,218 @@ GO |
| 1893 | 1932 | { |
| 1894 | 1933 | DBKEY,DATABASE,DATASOURCE,DBOTYPE,DBONAME,DBDATAGROUP,BACKUPTS,SHRINKOPTION,SHRINKFREESPACEPERCENT, |
| 1895 | 1934 | } |
| 1896 | - #endregion DBSubstitution | |
| 1935 | + #endregion DBSubstitution | |
| 1936 | + | |
| 1937 | + #region ExecuteSQLScriptWithMultipleRuns | |
| 1938 | + /// <summary> | |
| 1939 | + /// Executes a multirun script. Its parameters are in the <Script Parameters=> attribute, as list of KEY=VALUE; pairs. | |
| 1940 | + /// Keys: | |
| 1941 | + /// DAYSBACK (C# int value) or LIMITDATE (C# DateTime value): how many days from now, or from when the older rows should be deleted | |
| 1942 | + /// NUMOFDAYSINONERUN (C# int value): how many days are deleted in one run | |
| 1943 | + /// DELAYBETWEENRUNS (C# TimeSpan value): how much delay will be between runs | |
| 1944 | + /// TESTMODE (C# bool value): if testmode, no delete takes place | |
| 1945 | + /// </summary> | |
| 1946 | + /// <param name="sqlc">connectionstring az sql server-hez</param> | |
| 1947 | + /// <param name="sqlscript">az sql script (multirun interfész szerint!!!) | |
| 1948 | + /// this should be used in the script in the following way: | |
| 1949 | + /// DECLARE @RUNNINGMODE AS varchar(20) = '{RUNNINGMODE}' | |
| 1950 | + /// IF @RUNNINGMODE = 'GETTOTALRECORDS' | |
| 1951 | + /// THEN | |
| 1952 | + /// -- this part of the script should count the number of the rows of the dab, that will decrease after each run | |
| 1953 | + /// SELECT @RV, @RM -- @RV:0, @RM:the number of rows | |
| 1954 | + /// END | |
| 1955 | + /// ELSE IF @RUNNINGMODE = 'GETMINDATE' | |
| 1956 | + /// THEN | |
| 1957 | + /// -- this part of the script should return a DateTime value, that is the oldest date in the database | |
| 1958 | + /// SELECT @RV, @RM -- @RV:0, @RM:the Date, that is considered the oldest; no rows will be deleted before this | |
| 1959 | + /// END | |
| 1960 | + /// ELSE IF @RUNNINGMODE = 'ONERUN' | |
| 1961 | + /// THEN | |
| 1962 | + /// -- this part of the script deletes some rows from the database, older then a limitdate(parameter) | |
| 1963 | + /// -- parameter usage: DECLARE @RUNDELETEBEFOREDATE AS DATE = '{RUNDELETEBEFOREDATE}' | |
| 1964 | + /// SELECT @RV, @RM -- @RV:(0=OK, otherwise NOK), @RM:message with the result description | |
| 1965 | + /// END | |
| 1966 | + /// </param> | |
| 1967 | + /// <param name="ExitAfterOneRun">az a függvény, ami minde run után végrehajtásra kerül; | |
| 1968 | + /// bemenő paramétere az előző run eredménye, | |
| 1969 | + /// kimenő paramétere pedig igaz, ha ki kell lépni a végrehajtásból. | |
| 1970 | + /// </param> | |
| 1971 | + /// <returns></returns> | |
| 1972 | + public static ReturnInfoJSON ExecuteMultirunSQLScript(SqlConnection sqlc, SQLDataBase.SQLScript sqlscript, Func<ReturnInfoJSON, bool> ExitAfterOneRun=null) | |
| 1973 | + { | |
| 1974 | + var multirunresult = new List<KeyValuePair<string, string>>(); | |
| 1975 | + | |
| 1976 | + var argkvplist = (new Tools.KvpString(sqlscript.ArgumentParameters)).ResolveInteractive(); | |
| 1977 | + if(argkvplist==null) { return Finalize(0, Add(multirunresult, ERRMSG_NOTHINGTOEXECUTE)); } //user exit with selecting EX | |
| 1978 | + | |
| 1979 | + bool par_testmode; | |
| 1980 | + int par_limitdays; | |
| 1981 | + DateTime par_limitdate; | |
| 1982 | + TimeSpan par_lengthofonerun; | |
| 1983 | + TimeSpan par_delaybetweenruns; | |
| 1984 | + | |
| 1985 | + #region parameterek feldolgozása | |
| 1986 | + var testmodestring = argkvplist.GetValue(XMLPAR_TESTMODE, "false"); | |
| 1987 | + if ( !bool.TryParse(testmodestring, out par_testmode)) { return Finalize(1, Add(multirunresult, "Result", $"Parameter error:{XMLPAR_TESTMODE}")); } | |
| 1988 | + | |
| 1989 | + var daysbackstring = argkvplist.GetValue(XMLPAR_DAYSBACK, null); | |
| 1990 | + var limitdatestring = argkvplist.GetValue(XMLPAR_LIMITDATE, null); | |
| 1991 | + if (daysbackstring == null && limitdatestring == null) { par_limitdays = 90; par_limitdate = DateTime.Now.Subtract(new TimeSpan(par_limitdays, 0, 0, 0)); } | |
| 1992 | + else if (!string.IsNullOrEmpty(daysbackstring) && !string.IsNullOrEmpty(limitdatestring)) { return Finalize(1, Add(multirunresult, "Result", $"Parameter error:{XMLPAR_DAYSBACK} and {XMLPAR_LIMITDATE} are both defined.")); } | |
| 1993 | + else if (!string.IsNullOrEmpty(limitdatestring)) | |
| 1994 | + { | |
| 1995 | + if (!DateTime.TryParse(limitdatestring, out par_limitdate)) return Finalize(1, Add(multirunresult, "Result", $"Parameter error:" + XMLPAR_LIMITDATE)); | |
| 1996 | + par_limitdays = (int)DateTime.Now.Subtract(par_limitdate).TotalDays; | |
| 1997 | + } | |
| 1998 | + else /*if (!string.IsNullOrEmpty(daysbackstring)) */ | |
| 1999 | + { | |
| 2000 | + if(!int.TryParse(daysbackstring, out par_limitdays)) return Finalize(1, Add(multirunresult, "Result", $"Parameter error:" + XMLPAR_DAYSBACK)); | |
| 2001 | + par_limitdate = DateTime.Now.Subtract(new TimeSpan(par_limitdays, 0, 0, 0)); | |
| 2002 | + } | |
| 1897 | 2003 | |
| 1898 | - #region ExecuteSQLScript | |
| 1899 | - /// <summary> | |
| 1900 | - /// Egy SQL script végrehajtása (GO-val lezárt batch-eket tartalmazhat) | |
| 1901 | - /// </summary> | |
| 1902 | - /// <param name="sqlconnectionstring">sql connection string</param> | |
| 1903 | - /// <param name="sqltxt">a script</param> | |
| 1904 | - /// <param name="commandtimeout">az egyes batch-ek végrehajtási időzítése</param> | |
| 1905 | - /// <param name="vars"> | |
| 1906 | - /// behelyettesítendő változók (a scriptben ezek nevei {} között kell legyenek) | |
| 1907 | - /// a következő neveket felismeri akkor is, ha nincsenek benne a sztótárban: | |
| 1908 | - /// DATASOURCE: a sql server neve domain/név formában | |
| 1909 | - /// DATABASE: az aadatbázis neve | |
| 1910 | - /// </param> | |
| 1911 | - /// <returns> | |
| 1912 | - /// egy ReturnInfoJSON struktúrát, amiben a ReturnValue és ReturnMessage a script által előállított két | |
| 1913 | - /// (egy int és egy string) értéket tartalmazza pl. egy ilyen eredményt: SELECT @returncode, @returnmessage; | |
| 1914 | - /// Ha a végrehajtás nem ad vissza eredményt, akkor az első érték 0, a második pedig null; | |
| 1915 | - /// | |
| 1916 | - /// </returns> | |
| 1917 | - public static ReturnInfoJSON ExecuteSQLScript(string sqlconnectionstring, string sqltxt, int commandtimeout, Dictionary<string, string> vars) | |
| 1918 | - { | |
| 1919 | - using (var sqlc = ServerConnectionPool.GetSqlConnection(sqlconnectionstring,open:true)) { return ExecuteSQLScript(sqlc,sqltxt, commandtimeout, vars); } | |
| 1920 | - } | |
| 1921 | - public static ReturnInfoJSON ExecuteSQLScript(SqlConnection sqlconnection, string sqltxt, int commandtimeout, Dictionary<string, string> vars) | |
| 2004 | + if (!TimeSpan.TryParse(argkvplist.GetValue(XMLPAR_NUMOFDAYSINONERUN, "#$NONE#$"), out par_lengthofonerun)) { par_lengthofonerun = new TimeSpan(0, 12, 0); } | |
| 2005 | + if (!TimeSpan.TryParse(argkvplist.GetValue(XMLPAR_DELAYBETWEENRUNS, "#$NONE#$"), out par_delaybetweenruns)) { par_delaybetweenruns = new TimeSpan(0, 0, 10); } | |
| 2006 | + #endregion parameterek feldolgozása | |
| 2007 | + if (par_limitdays<=0) { return Finalize(0, Add(multirunresult, "Result", $"SKIPPED (function disabled).")); } | |
| 2008 | + | |
| 2009 | + Add(multirunresult, $"LIMIT", $"{par_limitdays}days (before:{par_limitdate})"); | |
| 2010 | + Add(multirunresult, $"STAT", $"run length:{par_lengthofonerun.TotalHours}hours, delay between runs:{par_delaybetweenruns.TotalSeconds}sec"); | |
| 2011 | + Add(multirunresult, $"TESTMODE", $"{par_testmode}"); | |
| 2012 | + | |
| 2013 | + try | |
| 2014 | + { | |
| 2015 | + DateTime starttime = DateTime.Now; | |
| 2016 | + string sqltxtalmostresolved = argkvplist.Substitute(sqlscript.ScriptText); //parameters of the run are still unresolved | |
| 2017 | + if (sqltxtalmostresolved == null) {return Finalize(1, Add(multirunresult, ERRMSG_NOTHINGTOEXECUTE));} //won't really get, but we never know... | |
| 2018 | + | |
| 2019 | + ReturnInfoJSON ret1=null; | |
| 2020 | + string sqltxt = null; | |
| 2021 | + int? getdbnumofrowsresult=null; | |
| 2022 | + DateTime? getdbmindateresult=null; | |
| 2023 | + | |
| 2024 | + //get number of total records in the database | |
| 2025 | + getdbnumofrowsresult = GetDBNumofRows(sqltxtalmostresolved, multirunresult, sqlscript.CommandTimeout, sqlc); | |
| 2026 | + if (getdbnumofrowsresult == null) return Finalize(1, multirunresult); | |
| 2027 | + int numoftotaldbrecords_before = getdbnumofrowsresult.Value; | |
| 2028 | + | |
| 2029 | + //get minimum date in the database | |
| 2030 | + getdbmindateresult = GetDBMindate(sqltxtalmostresolved, multirunresult, sqlscript.CommandTimeout, sqlc); | |
| 2031 | + if (getdbmindateresult == null) return Finalize(1, multirunresult); | |
| 2032 | + DateTime mindateTS_before = getdbmindateresult.Value; | |
| 2033 | + | |
| 2034 | + var limitdatefornextrun = mindateTS_before; | |
| 2035 | + int exceptioncounter = 0; | |
| 2036 | + const int MAXEXCEPTIONS = 3; //after this number of subsequent exceptions we exit | |
| 2037 | + int deleteruncounter = 0; | |
| 2038 | + int runresult; | |
| 2039 | + while (true) | |
| 2040 | + { | |
| 2041 | + if (limitdatefornextrun >= par_limitdate) break; | |
| 2042 | + limitdatefornextrun = limitdatefornextrun + par_lengthofonerun; | |
| 2043 | + var loople = new List<KeyValuePair<string, string>>(); | |
| 2044 | + if (limitdatefornextrun > par_limitdate) limitdatefornextrun = par_limitdate; | |
| 2045 | + Add(loople, $"RUN#{deleteruncounter}"); | |
| 2046 | + try | |
| 2047 | + { | |
| 2048 | + sqltxt = Tools.KvpString.Substitute($"{RUNNINGMODE}={RUNNINGMODE_ONERUN};{RUNNINGMODE_ONERUN_PARAMETER_DELETEBEFOREDATE}={limitdatefornextrun:s};", sqltxtalmostresolved); | |
| 2049 | + if (sqltxt == null) { return Finalize(1, Add(multirunresult, ERRMSG_NOTHINGTOEXECUTE)); } //won't really get, but we never know... | |
| 2050 | + ret1 = ExecuteSQLScript(sqlc, sqltxt, sqlscript.CommandTimeout, null); | |
| 2051 | + Add(loople, $"LIMITDATE", limitdatefornextrun.ToString()); | |
| 2052 | + Add(loople, $"RETCODE", ret1.ReturnValue.ToString()); | |
| 2053 | + Add(loople, $"RETMSG", ret1.ReturnMessage); | |
| 2054 | + | |
| 2055 | + deleteruncounter++; | |
| 2056 | + exceptioncounter = 0; | |
| 2057 | + runresult = 0; | |
| 2058 | + } | |
| 2059 | + catch (Exception ex) | |
| 2060 | + { | |
| 2061 | + exceptioncounter++; | |
| 2062 | + string errmsg = ""; while (ex != null) { errmsg += ex.Message; ex = ex.InnerException; } | |
| 2063 | + Add(loople, $"EXCEPTION RESULT DeleteRun", errmsg); | |
| 2064 | + runresult = 1; | |
| 2065 | + if (exceptioncounter > MAXEXCEPTIONS) { return Finalize(1, multirunresult); } | |
| 2066 | + } | |
| 2067 | + var exitfromloop = (ExitAfterOneRun?.Invoke(Finalize(runresult, loople))) ?? false; | |
| 2068 | + if (exitfromloop) { Add(multirunresult, $"Exit requested by user"); break; } | |
| 2069 | + Thread.Sleep((int)(par_delaybetweenruns.TotalMilliseconds)); | |
| 2070 | + } | |
| 2071 | + | |
| 2072 | + //get minimum date in the database | |
| 2073 | + getdbmindateresult = GetDBMindate(sqltxtalmostresolved,multirunresult, sqlscript.CommandTimeout,sqlc); | |
| 2074 | + if (getdbmindateresult==null) return Finalize(1, multirunresult); | |
| 2075 | + DateTime mindateTS_after = getdbmindateresult.Value; | |
| 2076 | + | |
| 2077 | + //get number of total records in the database | |
| 2078 | + getdbnumofrowsresult = GetDBNumofRows(sqltxtalmostresolved, multirunresult, sqlscript.CommandTimeout, sqlc); | |
| 2079 | + if (getdbnumofrowsresult == null) return Finalize(1, multirunresult); | |
| 2080 | + int numoftotaldbrecords_after = getdbnumofrowsresult.Value; | |
| 2081 | + | |
| 2082 | + Add(multirunresult, $"NUMOFRUNS", deleteruncounter.ToString()); | |
| 2083 | + Add(multirunresult, $"DBRECORDS", $"{numoftotaldbrecords_before}-->{numoftotaldbrecords_after}"); | |
| 2084 | + Add(multirunresult, $"MINDATE", $"{mindateTS_before}-->{mindateTS_after}"); | |
| 2085 | + Add(multirunresult, $"PROCESSINGTIME", $"{DateTime.Now.Subtract(starttime)}"); | |
| 2086 | + return Finalize(0, multirunresult); | |
| 2087 | + } | |
| 2088 | + catch (Exception ex) { return Finalize(1, Add(multirunresult, ex)); } | |
| 2089 | + } | |
| 2090 | + private static DateTime? GetDBMindate(string sqltxtalmostresolved, List<KeyValuePair<string, string>> multirunresult,int commandtimeout, SqlConnection sqlc) | |
| 2091 | + { | |
| 2092 | + //get minimum date in the database | |
| 2093 | + string sqltxt = Tools.KvpString.Substitute($"{RUNNINGMODE}={RUNNINGMODE_GETMINDATE};{RUNNINGMODE_ONERUN_PARAMETER_DELETEBEFOREDATE}=;", sqltxtalmostresolved); | |
| 2094 | + if (sqltxt == null) { Add(multirunresult, ERRMSG_NOTHINGTOEXECUTE); return null; } //won't really get, but we never know... | |
| 2095 | + var ret1 = ExecuteSQLScript(sqlc, sqltxt, commandtimeout, null); | |
| 2096 | + if (ret1.ReturnValue != 0) { Add(multirunresult, RUNNINGMODE_GETMINDATE + " FAILURE", ret1.ReturnMessage); return null; } | |
| 2097 | + return DateTime.Parse(ret1.ReturnMessage);//GetOldestDate.Invoke(sqlconnectionstring); | |
| 2098 | + } | |
| 2099 | + private static int? GetDBNumofRows(string sqltxtalmostresolved, List<KeyValuePair<string, string>> multirunresult, int commandtimeout, SqlConnection sqlc) | |
| 2100 | + { | |
| 2101 | + string sqltxt = Tools.KvpString.Substitute($"{RUNNINGMODE}={RUNNINGMODE_GETTOTALRECORDS};{RUNNINGMODE_ONERUN_PARAMETER_DELETEBEFOREDATE}=;", sqltxtalmostresolved); | |
| 2102 | + if (sqltxt == null) { Add(multirunresult, ERRMSG_NOTHINGTOEXECUTE); return null; } //won't really get, but we never know... | |
| 2103 | + var ret1 = ExecuteSQLScript(sqlc, sqltxt, commandtimeout, null); | |
| 2104 | + if (ret1.ReturnValue != 0) { Add(multirunresult, RUNNINGMODE_GETTOTALRECORDS + " FAILURE", ret1.ReturnMessage); return null; } | |
| 2105 | + return int.Parse(ret1.ReturnMessage); | |
| 2106 | + } | |
| 2107 | + | |
| 2108 | + const string RUNNINGMODE = "RUNNINGMODE"; | |
| 2109 | + const string RUNNINGMODE_GETTOTALRECORDS = "GETTOTALRECORDS"; | |
| 2110 | + const string RUNNINGMODE_GETMINDATE = "GETMINDATE"; | |
| 2111 | + const string RUNNINGMODE_ONERUN = "ONERUN"; | |
| 2112 | + const string RUNNINGMODE_ONERUN_PARAMETER_DELETEBEFOREDATE = "RUNDELETEBEFOREDATE"; | |
| 2113 | + | |
| 2114 | + const string XMLPAR_NUMOFDAYSINONERUN = "NUMOFDAYSINONERUN"; | |
| 2115 | + const string XMLPAR_DELAYBETWEENRUNS = "DELAYBETWEENRUNS"; | |
| 2116 | + const string XMLPAR_TESTMODE = "TESTMODE"; | |
| 2117 | + const string XMLPAR_DAYSBACK = "DAYSBACK"; | |
| 2118 | + const string XMLPAR_LIMITDATE = "LIMITDATE"; | |
| 2119 | + | |
| 2120 | + const string ERRMSG_NOTHINGTOEXECUTE = "FAILURE! Nothing to execute! Check script definition entry!"; | |
| 2121 | + | |
| 2122 | + private static List<KeyValuePair<string, string>> Add(List<KeyValuePair<string, string>> kvp, string a, string b=null) { kvp.Add(new KeyValuePair<string, string>(a, b)); return kvp; } | |
| 2123 | + private static List<KeyValuePair<string, string>> Add(List<KeyValuePair<string, string>> kvp,Exception ex) { string errmsg = ""; while (ex != null) { errmsg += ex.Message; ex = ex.InnerException; } return Add(kvp, "EXCEPTION RESULT",errmsg); } | |
| 2124 | + private static ReturnInfoJSON Finalize(int returnvalue,List<KeyValuePair<string, string>> kvplist) { var rmsg = "";foreach (var kvp in kvplist) rmsg += string.IsNullOrWhiteSpace(kvp.Value)? $"{kvp.Key};" : $"{kvp.Key}={kvp.Value};"; return new ReturnInfoJSON() { ReturnValue = returnvalue, ReturnMessage = rmsg, }; } | |
| 2125 | + #endregion ExecuteSQLScriptWithMultipleRuns | |
| 2126 | + | |
| 2127 | + #region ExecuteSQLScript | |
| 2128 | + /// <summary> | |
| 2129 | + /// Egy SQL script végrehajtása (GO-val lezárt batch-eket tartalmazhat) | |
| 2130 | + /// </summary> | |
| 2131 | + /// <param name="sqlconnectionstring">sql connection string</param> | |
| 2132 | + /// <param name="sqltxt">a script</param> | |
| 2133 | + /// <param name="commandtimeout">az egyes batch-ek végrehajtási időzítése</param> | |
| 2134 | + /// <param name="vars"> | |
| 2135 | + /// behelyettesítendő változók (a scriptben ezek nevei {} között kell legyenek) | |
| 2136 | + /// a következő neveket felismeri akkor is, ha nincsenek benne a sztótárban: | |
| 2137 | + /// DATASOURCE: a sql server neve domain/név formában | |
| 2138 | + /// DATABASE: az aadatbázis neve | |
| 2139 | + /// </param> | |
| 2140 | + /// <returns> | |
| 2141 | + /// egy ReturnInfoJSON struktúrát, amiben a ReturnValue és ReturnMessage a script által előállított két | |
| 2142 | + /// (egy int és egy string) értéket tartalmazza pl. egy ilyen eredményt: SELECT @returncode, @returnmessage; | |
| 2143 | + /// Ha a végrehajtás nem ad vissza eredményt, akkor az első érték 0, a második pedig null; | |
| 2144 | + /// | |
| 2145 | + /// </returns> | |
| 2146 | + public static ReturnInfoJSON ExecuteSQLScript(SqlConnection sqlconnection, string sqltxt, int commandtimeout, Dictionary<string, string> vars) | |
| 1922 | 2147 | { |
| 1923 | 2148 | sqltxt = VRH.Common.StringConstructor.ResolveConstructorR(vars, sqltxt, "{}@@"); |
| 1924 | 2149 | |
| ... | ... | @@ -2607,6 +2832,7 @@ GO |
| 2607 | 2832 | public static class Description { public static class Values { public const string DEFAULT = ""; } } |
| 2608 | 2833 | public static class ScriptCommandTimeout { public static class Values { public const int DEFAULT = 10000; } } |
| 2609 | 2834 | public static class Parameters { public static class Values { public const string DEFAULT = ""; } } |
| 2835 | + public static class Multirun { public static class Values { public const bool DEFAULT = false; } } | |
| 2610 | 2836 | } |
| 2611 | 2837 | } |
| 2612 | 2838 | } |
| ... | ... | @@ -2623,6 +2849,7 @@ GO |
| 2623 | 2849 | public string ScriptText = ""; |
| 2624 | 2850 | public int CommandTimeout = 10000; |
| 2625 | 2851 | public string ArgumentParameters; |
| 2852 | + public bool Multirun = false; | |
| 2626 | 2853 | |
| 2627 | 2854 | public SQLScript() { } |
| 2628 | 2855 | public SQLScript(SQLScript sqls) { Name = sqls.Name; Description = sqls.Description; ScriptText= sqls.ScriptText; } |
| ... | ... | @@ -2634,8 +2861,10 @@ GO |
| 2634 | 2861 | Name = GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.Name), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.Name.Values.DEFAULT); |
| 2635 | 2862 | FilePath = GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.File), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.File.Values.DEFAULT); |
| 2636 | 2863 | Description= GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.Description), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.Description.Values.DEFAULT); |
| 2637 | - Tools.ResolveArguments(ArgumentParameters, this.Name, out this.Name, interactive: false); | |
| 2638 | - Tools.ResolveArguments(ArgumentParameters, this.Description, out this.Description, interactive: false); | |
| 2864 | + Multirun= GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.Multirun), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.Multirun.Values.DEFAULT); | |
| 2865 | + | |
| 2866 | + Tools.KvpString.Resolve(ArgumentParameters, this.Name, out this.Name, disableinteractive: true); | |
| 2867 | + Tools.KvpString.Resolve(ArgumentParameters, this.Description, out this.Description, disableinteractive: true); | |
| 2639 | 2868 | if (string.IsNullOrWhiteSpace(this.FilePath)) |
| 2640 | 2869 | { |
| 2641 | 2870 | ScriptText = GetValue(sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Values.DEFAULT); | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs
| ... | ... | @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; |
| 32 | 32 | // You can specify all the values or you can default the Build and Revision Numbers |
| 33 | 33 | // by using the '*' as shown below: |
| 34 | 34 | // [assembly: AssemblyVersion("1.0.*")] |
| 35 | -[assembly: AssemblyVersion("1.30.1.0")] | |
| 36 | -[assembly: AssemblyFileVersion("1.30.1.0")] | |
| 35 | +[assembly: AssemblyVersion("1.31.0.0")] | |
| 36 | +[assembly: AssemblyFileVersion("1.31.0.0")] | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Tools.cs
| ... | ... | @@ -20,6 +20,8 @@ using VRH.Common; |
| 20 | 20 | using Microsoft.Win32; |
| 21 | 21 | using System.Reflection; |
| 22 | 22 | using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; |
| 23 | +using System.Runtime.CompilerServices; | |
| 24 | +using static Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS.MaintenanceToolsXmlProcessor.XmlStructure.ExternalUtility.Attributes; | |
| 23 | 25 | |
| 24 | 26 | namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS |
| 25 | 27 | { |
| ... | ... | @@ -325,39 +327,70 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS |
| 325 | 327 | if (list32.Count() > 0) { if (list64.Count() > 0) { os = "64bit"; } else { os = "32bit"; } } |
| 326 | 328 | return os; |
| 327 | 329 | } |
| 328 | - public static bool ResolveArguments(string parameterkvpstring, string stringwithparameters, out string resolvedtext, bool interactive = true) | |
| 330 | + public class KvpString | |
| 329 | 331 | { |
| 330 | - var argumentparametersdictionary = parameterkvpstring.Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries) | |
| 331 | - .Select(kvp => CreateKVP(kvp)) | |
| 332 | - .Where(kvp => kvp.Key != null) | |
| 333 | - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); | |
| 334 | - Dictionary<string, string> resolveddictionary = new Dictionary<string, string>(); | |
| 335 | - resolvedtext = stringwithparameters; | |
| 336 | - foreach (var kvp in argumentparametersdictionary) | |
| 332 | + public KvpString(string parameterkvpstring) { this.kvpstring = parameterkvpstring; BuildDict(force:true);} | |
| 333 | + private string kvpstring; | |
| 334 | + private Dictionary<string, string> kvpdict = null; | |
| 335 | + private Dictionary<string, string> kvpdictresolved = null; | |
| 336 | + public string GetValue(string argumentname, string notexistvalue = null) | |
| 337 | + { | |
| 338 | + BuildDict(); | |
| 339 | + return this.kvpdictresolved.ContainsKey(argumentname) ? this.kvpdictresolved[argumentname] : notexistvalue; | |
| 340 | + } | |
| 341 | + private void BuildDict(bool force=false) | |
| 342 | + { | |
| 343 | + if (this.kvpdict != null && !force) return; | |
| 344 | + this.kvpdict = (this.kvpstring).Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries) | |
| 345 | + .Select(kvp => CreateKVP(kvp)) | |
| 346 | + .Where(kvp => kvp.Key != null) | |
| 347 | + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); | |
| 348 | + this.kvpdictresolved = this.kvpdict.ToDictionary(d => d.Key, d => d.Value); | |
| 349 | + } | |
| 350 | + public KvpString ResolveInteractive(bool disable = false) | |
| 351 | + { | |
| 352 | + this.kvpdictresolved = new Dictionary<string, string>(); | |
| 353 | + foreach (var kvp in this.kvpdict) | |
| 354 | + { | |
| 355 | + if (kvp.Value == null) { this.kvpdictresolved.Add(kvp.Key, ""); } | |
| 356 | + else if (kvp.Value.StartsWith("?") && !disable) | |
| 357 | + { | |
| 358 | + // "?default?prompt" | |
| 359 | + string prompt = $"Enter value for {kvp.Key}:"; | |
| 360 | + string kvpdefaultvalue = null; | |
| 361 | + if (kvp.Value.Length > 1) | |
| 362 | + { | |
| 363 | + var ppp = kvp.Value.Substring(1).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries); | |
| 364 | + if (!string.IsNullOrWhiteSpace(ppp[0])) { kvpdefaultvalue = ppp[0]; }; | |
| 365 | + if (kvp.Value.Substring(1).IndexOf('?') != -1) { prompt = ppp[1]; } | |
| 366 | + } | |
| 367 | + string value = ColorConsole.ReadLine(prompt, ConsoleColor.Yellow, defaultvalue: kvpdefaultvalue); | |
| 368 | + if (value.ToUpper() == "EX") { return null; } | |
| 369 | + this.kvpdictresolved.Add(kvp.Key, value); | |
| 370 | + } | |
| 371 | + else if (kvp.Value.StartsWith("?") && disable) this.kvpdictresolved.Add(kvp.Key, $"{{{kvp.Key}}}"); | |
| 372 | + else { this.kvpdictresolved.Add(kvp.Key, kvp.Value); } | |
| 373 | + } | |
| 374 | + return this; | |
| 375 | + } | |
| 376 | + public string Substitute(string stringwithparameters) | |
| 337 | 377 | { |
| 338 | - if (kvp.Value == null) { resolveddictionary.Add(kvp.Key, "");} | |
| 339 | - else if (kvp.Value.StartsWith("?") && interactive) | |
| 340 | - { | |
| 341 | - // "?default?prompt" | |
| 342 | - string prompt = $"Enter value for {kvp.Key}:"; | |
| 343 | - string kvpdefaultvalue = null; | |
| 344 | - if (kvp.Value.Length > 1) | |
| 345 | - { | |
| 346 | - var ppp = kvp.Value.Substring(1).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries); | |
| 347 | - if (!string.IsNullOrWhiteSpace(ppp[0])) { kvpdefaultvalue = ppp[0]; }; | |
| 348 | - if (kvp.Value.Substring(1).IndexOf('?') != -1) { prompt = ppp[1]; } | |
| 349 | - } | |
| 350 | - string value = ColorConsole.ReadLine(prompt, ConsoleColor.Yellow, defaultvalue: kvpdefaultvalue); | |
| 351 | - if (value.ToUpper() == "EX") { return false; } | |
| 352 | - resolveddictionary.Add(kvp.Key, value); | |
| 353 | - } | |
| 354 | - else if (kvp.Value.StartsWith("?") && !interactive) resolveddictionary.Add(kvp.Key, $"{{{kvp.Key}}}"); | |
| 355 | - else { resolveddictionary.Add(kvp.Key, kvp.Value); } | |
| 378 | + return VRH.Common.StringConstructor.ResolveConstructorR(this.kvpdictresolved, stringwithparameters, "{}@@"); | |
| 379 | + } | |
| 380 | + public static string Substitute(string kvpstring, string stringwithparameters) | |
| 381 | + { | |
| 382 | + return VRH.Common.StringConstructor.ResolveConstructorR(new KvpString(kvpstring).kvpdictresolved, stringwithparameters, "{}@@"); | |
| 383 | + } | |
| 384 | + public static bool Resolve(string kvpstring,string stringwithparameters, out string resolvedtext, bool disableinteractive = false) | |
| 385 | + { | |
| 386 | + resolvedtext = null; | |
| 387 | + var resolvedkvpstring = (new Tools.KvpString(kvpstring)).ResolveInteractive(disableinteractive); | |
| 388 | + if (resolvedkvpstring == null) return false;//exit with EX | |
| 389 | + resolvedtext = resolvedkvpstring.Substitute(stringwithparameters); | |
| 390 | + return true; | |
| 356 | 391 | } |
| 357 | - resolvedtext = VRH.Common.StringConstructor.ResolveConstructorR(resolveddictionary, stringwithparameters, "{}@@"); | |
| 358 | - return true; | |
| 359 | - } | |
| 360 | - private static KeyValuePair<string, string> CreateKVP(string kvpstring) | |
| 392 | + } | |
| 393 | + private static KeyValuePair<string, string> CreateKVP(string kvpstring) | |
| 361 | 394 | { |
| 362 | 395 | string kvpk = null; |
| 363 | 396 | string kvpv = null; |
| ... | ... | @@ -368,7 +401,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS |
| 368 | 401 | KeyValuePair<string, string> r = new KeyValuePair<string, string>(kvpk, kvpv); |
| 369 | 402 | return r; |
| 370 | 403 | } |
| 371 | - catch { return new KeyValuePair<string, string>(kvpk, null); } | |
| 404 | + catch { return new KeyValuePair<string, string>(kvpk, ""); } | |
| 372 | 405 | } |
| 373 | 406 | } |
| 374 | 407 | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj
| ... | ... | @@ -347,14 +347,17 @@ |
| 347 | 347 | <Reference Include="Microsoft.CSharp" /> |
| 348 | 348 | <Reference Include="System.Data" /> |
| 349 | 349 | <Reference Include="System.Xml" /> |
| 350 | - <Reference Include="VRH.Common, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL"> | |
| 351 | - <HintPath>..\packages\VRH.Common.3.0.1\lib\net45\VRH.Common.dll</HintPath> | |
| 350 | + <Reference Include="VRH.Common, Version=4.1.1.0, Culture=neutral, processorArchitecture=MSIL"> | |
| 351 | + <HintPath>..\packages\VRH.Common.4.1.1\lib\net462\VRH.Common.dll</HintPath> | |
| 352 | 352 | </Reference> |
| 353 | - <Reference Include="VRH.Common.COM, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |
| 354 | - <HintPath>..\packages\VRH.Common.3.0.1\lib\net45\VRH.Common.COM.dll</HintPath> | |
| 353 | + <Reference Include="VRH.Common.COM, Version=4.1.0.0, Culture=neutral, processorArchitecture=MSIL"> | |
| 354 | + <HintPath>..\packages\VRH.Common.4.1.1\lib\net462\VRH.Common.COM.dll</HintPath> | |
| 355 | 355 | </Reference> |
| 356 | - <Reference Include="VRH.Common.EF, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |
| 357 | - <HintPath>..\packages\VRH.Common.3.0.1\lib\net45\VRH.Common.EF.dll</HintPath> | |
| 356 | + <Reference Include="VRH.Common.EF, Version=4.1.0.0, Culture=neutral, processorArchitecture=MSIL"> | |
| 357 | + <HintPath>..\packages\VRH.Common.4.1.1\lib\net462\VRH.Common.EF.dll</HintPath> | |
| 358 | + </Reference> | |
| 359 | + <Reference Include="VRH.Common.Log4ProIS, Version=4.1.1.0, Culture=neutral, processorArchitecture=MSIL"> | |
| 360 | + <HintPath>..\packages\VRH.Common.4.1.1\lib\net462\VRH.Common.Log4ProIS.dll</HintPath> | |
| 358 | 361 | </Reference> |
| 359 | 362 | <Reference Include="Vrh.Web.Providers, Version=2.0.2.0, Culture=neutral, processorArchitecture=MSIL"> |
| 360 | 363 | <HintPath>..\packages\VRH.Web.Providers.2.0.2\lib\net452\Vrh.Web.Providers.dll</HintPath> | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/packages.config
| ... | ... | @@ -73,7 +73,7 @@ |
| 73 | 73 | <package id="System.Threading.Timer" version="4.0.1" targetFramework="net472" /> |
| 74 | 74 | <package id="System.Xml.ReaderWriter" version="4.0.11" targetFramework="net472" /> |
| 75 | 75 | <package id="System.Xml.XDocument" version="4.0.11" targetFramework="net472" /> |
| 76 | - <package id="VRH.Common" version="3.0.1" targetFramework="net472" /> | |
| 76 | + <package id="VRH.Common" version="4.1.1" targetFramework="net472" /> | |
| 77 | 77 | <package id="VRH.Web.Providers" version="2.0.2" targetFramework="net472" /> |
| 78 | 78 | <package id="Vrh.XmlProcessing" version="2.8.0" targetFramework="net472" /> |
| 79 | 79 | </packages> |
| 80 | 80 | \ No newline at end of file | ... | ... |