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 | ... | ... |