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,6 +10,12 @@ using System.Diagnostics; | ||
10 | 10 | ||
11 | using Vrh.XmlProcessing; | 11 | using Vrh.XmlProcessing; |
12 | using System.Xml.Linq; | 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 | namespace Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS | 20 | namespace Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS |
15 | { | 21 | { |
@@ -68,17 +74,35 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS | @@ -68,17 +74,35 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS | ||
68 | /// Visszaadja a lenyomott billentyűt, ha van, commandmode-ban pedig az enter-t | 74 | /// Visszaadja a lenyomott billentyűt, ha van, commandmode-ban pedig az enter-t |
69 | /// </summary> | 75 | /// </summary> |
70 | /// <returns></returns> | 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 | switch (ck) | 107 | switch (ck) |
84 | { | 108 | { |
Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs
@@ -65,7 +65,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS | @@ -65,7 +65,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS | ||
65 | ExternalProcess.StartInfo.FileName = config.Exe; | 65 | ExternalProcess.StartInfo.FileName = config.Exe; |
66 | ExternalProcess.StartInfo.WindowStyle = config.ProcessWindowsStyle; | 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 | ExternalProcess.StartInfo.Arguments = resolvedtext; | 69 | ExternalProcess.StartInfo.Arguments = resolvedtext; |
70 | ExternalProcess.Start(); | 70 | ExternalProcess.Start(); |
71 | int waitingtime = config.WaitForExit ? -1 : 0; | 71 | int waitingtime = config.WaitForExit ? -1 : 0; |
@@ -633,8 +633,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS | @@ -633,8 +633,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS | ||
633 | Exe = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Exe), x, ""); | 633 | Exe = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Exe), x, ""); |
634 | this.Key = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Key), x, ""); | 634 | this.Key = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Key), x, ""); |
635 | this.Description = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Description), x, Exe); | 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 | Arguments = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Arguments), x, XmlStructure.ExternalUtility.Attributes.Arguments.Values.DEFAULT); | 638 | Arguments = GetValue(nameof(XmlStructure.ExternalUtility.Attributes.Arguments), x, XmlStructure.ExternalUtility.Attributes.Arguments.Values.DEFAULT); |
639 | 639 | ||
640 | ProcessWindowsStyle = GetValue<ProcessWindowStyle>(nameof(XmlStructure.ExternalUtility.Attributes.WindowStyle), x, XmlStructure.ExternalUtility.Attributes.WindowStyle.Values.DEFAULT); | 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,6 +26,12 @@ using System.Text.RegularExpressions; | ||
26 | using Microsoft.SqlServer.Management.Common; | 26 | using Microsoft.SqlServer.Management.Common; |
27 | using Microsoft.SqlServer.Management.Smo; | 27 | using Microsoft.SqlServer.Management.Smo; |
28 | using Microsoft.Data.SqlClient; | 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 | namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS | 36 | namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS |
31 | { | 37 | { |
@@ -926,27 +932,30 @@ GO | @@ -926,27 +932,30 @@ GO | ||
926 | else { return null; } | 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 | catch (ApplicationException e) { ColorConsole.WriteLine("FATAL ERROR! in script parameter substitution!", ConsoleColor.Red); returntext = null; } | 960 | catch (ApplicationException e) { ColorConsole.WriteLine("FATAL ERROR! in script parameter substitution!", ConsoleColor.Red); returntext = null; } |
952 | catch (Exception e) { ColorConsole.WriteLine("FATAL ERROR! " + e.MessageNested(), ConsoleColor.Red); returntext = null; } | 961 | catch (Exception e) { ColorConsole.WriteLine("FATAL ERROR! " + e.MessageNested(), ConsoleColor.Red); returntext = null; } |
@@ -985,29 +994,49 @@ GO | @@ -985,29 +994,49 @@ GO | ||
985 | foreach (var s in sqld.Xml_SQLScriptList) | 994 | foreach (var s in sqld.Xml_SQLScriptList) |
986 | { | 995 | { |
987 | ColorConsole.Write(s.Key, ConsoleColor.Yellow, bracket: "[]",suffix:" ",prefix: " "); | 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 | vlist.Add(s.Key); | 1003 | vlist.Add(s.Key); |
992 | } | 1004 | } |
993 | var scriptkey = ColorConsole.ReadLine("Select the script! [empty]=next DB, [*]=all, [EX]=exit.", ConsoleColor.Yellow, prefix:" ", suffix: " --> ", validitylist: vlist); | 1005 | var scriptkey = ColorConsole.ReadLine("Select the script! [empty]=next DB, [*]=all, [EX]=exit.", ConsoleColor.Yellow, prefix:" ", suffix: " --> ", validitylist: vlist); |
994 | if (string.IsNullOrWhiteSpace(scriptkey)) { continue; } | 1006 | if (string.IsNullOrWhiteSpace(scriptkey)) { continue; } |
995 | if (scriptkey.ToUpper() == "EX") { return o; } | 1007 | if (scriptkey.ToUpper() == "EX") { return o; } |
996 | SQLDataBase.SQLScript ss = sqld.Xml_SQLScriptList.FirstOrDefault(s=>s.Key==scriptkey); | 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 | else | 1010 | else |
1003 | { | 1011 | { |
1004 | - ColorConsole.WriteLine(ssScriptText); | ||
1005 | var confirm = ColorConsole.ReadLine("Enter CONFIRM to start! [EX]=exit.", ConsoleColor.Yellow, prefix:" ", suffix: " --> ", validitylist: new List<string>() {"CONFIRM"}); | 1012 | var confirm = ColorConsole.ReadLine("Enter CONFIRM to start! [EX]=exit.", ConsoleColor.Yellow, prefix:" ", suffix: " --> ", validitylist: new List<string>() {"CONFIRM"}); |
1006 | if (confirm == "CONFIRM") | 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 | else {ColorConsole.WriteLine($"Script was NOT executed!", ConsoleColor.Red);} | 1040 | else {ColorConsole.WriteLine($"Script was NOT executed!", ConsoleColor.Red);} |
1012 | } | 1041 | } |
1013 | } | 1042 | } |
@@ -1016,6 +1045,16 @@ GO | @@ -1016,6 +1045,16 @@ GO | ||
1016 | } | 1045 | } |
1017 | return o; | 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 | private static object DropDB(object parameter, object o) | 1058 | private static object DropDB(object parameter, object o) |
1020 | { | 1059 | { |
1021 | var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>(); | 1060 | var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>(); |
@@ -1893,32 +1932,218 @@ GO | @@ -1893,32 +1932,218 @@ GO | ||
1893 | { | 1932 | { |
1894 | DBKEY,DATABASE,DATASOURCE,DBOTYPE,DBONAME,DBDATAGROUP,BACKUPTS,SHRINKOPTION,SHRINKFREESPACEPERCENT, | 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 | sqltxt = VRH.Common.StringConstructor.ResolveConstructorR(vars, sqltxt, "{}@@"); | 2148 | sqltxt = VRH.Common.StringConstructor.ResolveConstructorR(vars, sqltxt, "{}@@"); |
1924 | 2149 | ||
@@ -2607,6 +2832,7 @@ GO | @@ -2607,6 +2832,7 @@ GO | ||
2607 | public static class Description { public static class Values { public const string DEFAULT = ""; } } | 2832 | public static class Description { public static class Values { public const string DEFAULT = ""; } } |
2608 | public static class ScriptCommandTimeout { public static class Values { public const int DEFAULT = 10000; } } | 2833 | public static class ScriptCommandTimeout { public static class Values { public const int DEFAULT = 10000; } } |
2609 | public static class Parameters { public static class Values { public const string DEFAULT = ""; } } | 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,6 +2849,7 @@ GO | ||
2623 | public string ScriptText = ""; | 2849 | public string ScriptText = ""; |
2624 | public int CommandTimeout = 10000; | 2850 | public int CommandTimeout = 10000; |
2625 | public string ArgumentParameters; | 2851 | public string ArgumentParameters; |
2852 | + public bool Multirun = false; | ||
2626 | 2853 | ||
2627 | public SQLScript() { } | 2854 | public SQLScript() { } |
2628 | public SQLScript(SQLScript sqls) { Name = sqls.Name; Description = sqls.Description; ScriptText= sqls.ScriptText; } | 2855 | public SQLScript(SQLScript sqls) { Name = sqls.Name; Description = sqls.Description; ScriptText= sqls.ScriptText; } |
@@ -2634,8 +2861,10 @@ GO | @@ -2634,8 +2861,10 @@ GO | ||
2634 | Name = GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.Name), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.Name.Values.DEFAULT); | 2861 | Name = GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.Name), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.Name.Values.DEFAULT); |
2635 | FilePath = GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.File), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.File.Values.DEFAULT); | 2862 | FilePath = GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.File), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.File.Values.DEFAULT); |
2636 | Description= GetValue(nameof(XmlStructure.SQLDataBase.Scripts.Script.Attributes.Description), sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Attributes.Description.Values.DEFAULT); | 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 | if (string.IsNullOrWhiteSpace(this.FilePath)) | 2868 | if (string.IsNullOrWhiteSpace(this.FilePath)) |
2640 | { | 2869 | { |
2641 | ScriptText = GetValue(sqlscriptXml, XmlStructure.SQLDataBase.Scripts.Script.Values.DEFAULT); | 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,5 +32,5 @@ using System.Runtime.InteropServices; | ||
32 | // You can specify all the values or you can default the Build and Revision Numbers | 32 | // You can specify all the values or you can default the Build and Revision Numbers |
33 | // by using the '*' as shown below: | 33 | // by using the '*' as shown below: |
34 | // [assembly: AssemblyVersion("1.0.*")] | 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,6 +20,8 @@ using VRH.Common; | ||
20 | using Microsoft.Win32; | 20 | using Microsoft.Win32; |
21 | using System.Reflection; | 21 | using System.Reflection; |
22 | using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; | 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 | namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS | 26 | namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS |
25 | { | 27 | { |
@@ -325,39 +327,70 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS | @@ -325,39 +327,70 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS | ||
325 | if (list32.Count() > 0) { if (list64.Count() > 0) { os = "64bit"; } else { os = "32bit"; } } | 327 | if (list32.Count() > 0) { if (list64.Count() > 0) { os = "64bit"; } else { os = "32bit"; } } |
326 | return os; | 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 | string kvpk = null; | 395 | string kvpk = null; |
363 | string kvpv = null; | 396 | string kvpv = null; |
@@ -368,7 +401,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS | @@ -368,7 +401,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS | ||
368 | KeyValuePair<string, string> r = new KeyValuePair<string, string>(kvpk, kvpv); | 401 | KeyValuePair<string, string> r = new KeyValuePair<string, string>(kvpk, kvpv); |
369 | return r; | 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,14 +347,17 @@ | ||
347 | <Reference Include="Microsoft.CSharp" /> | 347 | <Reference Include="Microsoft.CSharp" /> |
348 | <Reference Include="System.Data" /> | 348 | <Reference Include="System.Data" /> |
349 | <Reference Include="System.Xml" /> | 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 | </Reference> | 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 | </Reference> | 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 | </Reference> | 361 | </Reference> |
359 | <Reference Include="Vrh.Web.Providers, Version=2.0.2.0, Culture=neutral, processorArchitecture=MSIL"> | 362 | <Reference Include="Vrh.Web.Providers, Version=2.0.2.0, Culture=neutral, processorArchitecture=MSIL"> |
360 | <HintPath>..\packages\VRH.Web.Providers.2.0.2\lib\net452\Vrh.Web.Providers.dll</HintPath> | 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,7 +73,7 @@ | ||
73 | <package id="System.Threading.Timer" version="4.0.1" targetFramework="net472" /> | 73 | <package id="System.Threading.Timer" version="4.0.1" targetFramework="net472" /> |
74 | <package id="System.Xml.ReaderWriter" version="4.0.11" targetFramework="net472" /> | 74 | <package id="System.Xml.ReaderWriter" version="4.0.11" targetFramework="net472" /> |
75 | <package id="System.Xml.XDocument" version="4.0.11" targetFramework="net472" /> | 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 | <package id="VRH.Web.Providers" version="2.0.2" targetFramework="net472" /> | 77 | <package id="VRH.Web.Providers" version="2.0.2" targetFramework="net472" /> |
78 | <package id="Vrh.XmlProcessing" version="2.8.0" targetFramework="net472" /> | 78 | <package id="Vrh.XmlProcessing" version="2.8.0" targetFramework="net472" /> |
79 | </packages> | 79 | </packages> |
80 | \ No newline at end of file | 80 | \ No newline at end of file |