diff --git a/dotnet/Directory.Build.props b/dotnet/Directory.Build.props index 295d677ad..760d6f7c4 100644 --- a/dotnet/Directory.Build.props +++ b/dotnet/Directory.Build.props @@ -3,7 +3,7 @@ 11.0.0.0 1 $([MSBuild]::Add($(MajorFileVersion), 100)) - 24 + 25 $(COMMIT_NUMBER) 0 $(MajorFileVersion).$(MinorFileVersion).$(PatchFileVersion) diff --git a/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj b/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj index 1ea6ee0cf..5d7ca697c 100644 --- a/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj +++ b/dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj @@ -15,7 +15,6 @@ - diff --git a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj index 139e9264e..a153ec7c7 100644 --- a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj @@ -41,6 +41,7 @@ + @@ -57,6 +58,7 @@ + diff --git a/dotnet/src/dotnetcore/GxClasses/Services/Session/GXSessionFactory.cs b/dotnet/src/dotnetcore/GxClasses/Services/Session/GXSessionFactory.cs index e21153801..51e578ce0 100644 --- a/dotnet/src/dotnetcore/GxClasses/Services/Session/GXSessionFactory.cs +++ b/dotnet/src/dotnetcore/GxClasses/Services/Session/GXSessionFactory.cs @@ -1,5 +1,8 @@ using System; +using GeneXus.Application; using GeneXus.Configuration; +using GeneXus.Data; +using GeneXus.Data.ADO; using GeneXus.Encryption; using GxClasses.Helpers; using log4net; @@ -11,7 +14,6 @@ public class GXSessionServiceFactory private static readonly ILog log = log4net.LogManager.GetLogger(typeof(GXSessionServiceFactory)); static string REDIS = "REDIS"; static string DATABASE = "DATABASE"; - public static ISessionService GetProvider() { ISessionService sessionService = null; @@ -32,7 +34,6 @@ public static ISessionService GetProvider() } else { - GXLogging.Debug(log, "Loading Session provider:", className); #if !NETCORE type = Type.GetType(className, true, true); @@ -53,16 +54,15 @@ public static ISessionService GetProvider() } } return null; - } } public class GxRedisSession : ISessionService { + private static readonly ILog log = log4net.LogManager.GetLogger(typeof(GxRedisSession)); internal static string SESSION_ADDRESS = "SESSION_PROVIDER_ADDRESS"; internal static string SESSION_INSTANCE = "SESSION_PROVIDER_INSTANCE_NAME"; internal static string SESSION_PASSWORD = "SESSION_PROVIDER_PASSWORD"; static string SESSION_TIMEOUT = "SESSION_PROVIDER_SESSION_TIMEOUT"; - public GxRedisSession(GXService serviceProvider) { string password = serviceProvider.Properties.Get(SESSION_PASSWORD); @@ -85,6 +85,8 @@ public GxRedisSession(GXService serviceProvider) int.TryParse(sessionTimeoutStrCompatibility, out sessionTimeoutMinutes); SessionTimeout = sessionTimeoutMinutes; + GXLogging.Debug(log, "Redis Host:", host, ", InstanceName:", instanceName); + GXLogging.Debug(log, "Redis sessionTimeoutMinutes:", sessionTimeoutMinutes.ToString()); } public GxRedisSession(string host, string password, string instanceName, int sessionTimeout) { @@ -95,63 +97,69 @@ public GxRedisSession(string host, string password, string instanceName, int ses } InstanceName = instanceName; SessionTimeout = sessionTimeout; + GXLogging.Debug(log, "Redis Host:", host, ", InstanceName:", instanceName); + GXLogging.Debug(log, "Redis sessionTimeoutMinutes:", sessionTimeout.ToString()); } public string ConnectionString { get; } public string InstanceName { get; } public int SessionTimeout { get; } - public string Schema => throw new NotImplementedException(); - public string TableName => throw new NotImplementedException(); } public class GxDatabaseSession : ISessionService { + private static readonly ILog log = log4net.LogManager.GetLogger(typeof(GxDatabaseSession)); internal static string SESSION_ADDRESS = "SESSION_PROVIDER_ADDRESS"; internal static string SESSION_PASSWORD = "SESSION_PROVIDER_PASSWORD"; internal static string SESSION_SCHEMA = "SESSION_PROVIDER_SCHEMA"; internal static string SESSION_TABLE_NAME = "SESSION_PROVIDER_TABLE_NAME"; - internal static string SESSION_PROVIDER_SERVER = "SESSION_PROVIDER_SERVER"; - internal static string SESSION_PROVIDER_DATABASE = "SESSION_PROVIDER_DATABASE"; - internal static string SESSION_PROVIDER_USER = "SESSION_PROVIDER_USER"; - + internal static string SESSION_DATASTORE = "SESSION_PROVIDER_DATASTORE"; + const string DEFAULT_SQLSERVER_SCHEMA = "dbo"; public GxDatabaseSession(GXService serviceProvider) { - string password = serviceProvider.Properties.Get(SESSION_PASSWORD); - if (!string.IsNullOrEmpty(password)) - { - password = CryptoImpl.Decrypt(password); - } - string serverName = serviceProvider.Properties.Get(SESSION_PROVIDER_SERVER); - string userName = serviceProvider.Properties.Get(SESSION_PROVIDER_USER); - string database = serviceProvider.Properties.Get(SESSION_PROVIDER_DATABASE); - string schema = serviceProvider.Properties.Get(SESSION_SCHEMA); - string tableName = serviceProvider.Properties.Get(SESSION_TABLE_NAME); - - string sessionAddresCompatibility = serviceProvider.Properties.Get(GxDatabaseSession.SESSION_ADDRESS); - if (!string.IsNullOrEmpty(sessionAddresCompatibility)) - { - ConnectionString = sessionAddresCompatibility; - } - - if (!string.IsNullOrEmpty(serverName)) + string datastoreName = serviceProvider.Properties.Get(SESSION_DATASTORE); + if (!string.IsNullOrEmpty(datastoreName)) { - ConnectionString += $"Data Source={serverName};"; - } - if (!string.IsNullOrEmpty(database)) - { - ConnectionString += $"Initial Catalog={database}"; - } - if (!string.IsNullOrEmpty(password)) - { - ConnectionString += $";password={password}"; + GxContext context = GxContext.CreateDefaultInstance(); + IGxDataStore datastore = context.GetDataStore(datastoreName); + string schema = datastore.Connection.CurrentSchema; + if (string.IsNullOrEmpty(schema)) + schema = DEFAULT_SQLSERVER_SCHEMA; + string tableName = serviceProvider.Properties.Get(SESSION_TABLE_NAME); + GxConnection conn = datastore.Connection as GxConnection; + Schema = schema; + TableName = tableName; + context.CloseConnections(); + GxDataRecord dr = datastore.Db as GxDataRecord; + if (dr != null && conn != null) + { + ConnectionString = dr.BuildConnectionStringImpl(conn.DataSourceName, conn.InternalUserId, conn.UserPassword, conn.DatabaseName, conn.Port, conn.CurrentSchema, conn.Data); + GXLogging.Debug(log, "Database ConnectionString:", dr.ConnectionStringForLog()); + } } - if (!string.IsNullOrEmpty(userName)) + else //Backward compatibility configuration { - ConnectionString += $";user={userName}"; + string password = serviceProvider.Properties.Get(SESSION_PASSWORD); + if (!string.IsNullOrEmpty(password)) + { + password = CryptoImpl.Decrypt(password); + } + string schema = serviceProvider.Properties.Get(SESSION_SCHEMA); + string tableName = serviceProvider.Properties.Get(SESSION_TABLE_NAME); + string sessionAddresCompatibility = serviceProvider.Properties.Get(SESSION_ADDRESS); + if (!string.IsNullOrEmpty(sessionAddresCompatibility)) + { + ConnectionString = sessionAddresCompatibility; + } + if (!string.IsNullOrEmpty(password)) + { + ConnectionString += $";password={password}"; + } + Schema = schema; + TableName = tableName; } - Schema = schema; - TableName = tableName; SessionTimeout = Preferences.SessionTimeout; + GXLogging.Debug(log, "Database sessionTimeoutMinutes:", SessionTimeout.ToString()); } public GxDatabaseSession(string host, string password, string schema, string tableName) { @@ -164,16 +172,11 @@ public GxDatabaseSession(string host, string password, string schema, string tab TableName = tableName; } public string ConnectionString { get; } - public string Schema { get; } - public string TableName { get; } - public string InstanceName => throw new NotImplementedException(); - public int SessionTimeout { get; } } - public interface ISessionService { string ConnectionString { get; } diff --git a/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs b/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs index bdaa6264e..694c11255 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs @@ -511,8 +511,8 @@ public class StringUtil const char QMARK = '_'; static char[] numbersAndSep = new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' }; static char[] numbers = new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' }; - internal static Dictionary LogUserEntryWhiteList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789+-_=/[]{}\":, ".ToDictionary(item => item, item => item); - internal static Dictionary HttpHeaderWhiteList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789.;+-_=/[]{}\"':, @()?<>\\".ToDictionary(item => item, item => item); + internal static Dictionary LogUserEntryWhiteList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+-_=/[]{}\":, ".ToDictionary(item => item, item => item); + internal static Dictionary HttpHeaderWhiteList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890.;+-_=/[]{}\"':, @()?<>\\".ToDictionary(item => item, item => item); internal static string Sanitize(string input, Dictionary WhiteList) { diff --git a/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs b/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs index 9a6f7c778..8c8579e76 100644 --- a/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs +++ b/dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs @@ -44,6 +44,8 @@ namespace GeneXus.Http using GeneXus.Notifications; using Web.Security; using System.Web.SessionState; + using GeneXus.Mock; + using GeneXus.Data.NTier; #endif @@ -274,15 +276,68 @@ private bool IsFullAjaxRequest(HttpContext httpContext) public virtual void InitializeDynEvents() { throw new Exception("The method or operation is not implemented."); } public virtual void initialize_properties() { throw new Exception("The method or operation is not implemented."); } public virtual void webExecute() { throw new Exception("The method or operation is not implemented."); } - public virtual void initialize() { throw new Exception("The method or operation is not implemented."); } #if !NETCORE + public virtual void initialize() { throw new Exception("The method or operation is not implemented."); } public virtual void cleanup() { } + virtual public bool UploadEnabled() { return false; } + + protected virtual void ExecuteEx() + { + ExecutePrivate(); + } + protected virtual void ExecutePrivate() + { + + } + protected virtual void ExecutePrivateCatch(object stateInfo) + { + try + { + ((GXHttpHandler)stateInfo).ExecutePrivate(); + } + catch (Exception e) + { + GXUtil.SaveToEventLog("Design", e); + Console.WriteLine(e.ToString()); + } + } + protected void SubmitImpl() + { + GxContext submitContext = new GxContext(); + DataStoreUtil.LoadDataStores(submitContext); + IsMain = true; + submitContext.SetSubmitInitialConfig(context); + this.context = submitContext; + initialize(); + Submit(ExecutePrivateCatch, this); + } + protected virtual void CloseCursors() + { + + } + protected void Submit(Action executeMethod, object state) + { + ThreadUtil.Submit(PropagateCulture(new WaitCallback(executeMethod)), state); + } + public static WaitCallback PropagateCulture(WaitCallback action) + { + var currentCulture = Thread.CurrentThread.CurrentCulture; + GXLogging.Debug(log, "Submit PropagateCulture " + currentCulture); + var currentUiCulture = Thread.CurrentThread.CurrentUICulture; + return (x) => + { + Thread.CurrentThread.CurrentCulture = currentCulture; + Thread.CurrentThread.CurrentUICulture = currentUiCulture; + action(x); + }; + } + protected virtual string[] GetParameters() + { + return null; + } #endif public virtual bool SupportAjaxEvent() { return false; } public virtual String AjaxOnSessionTimeout() { return "Ignore"; } -#if !NETCORE - virtual public bool UploadEnabled() { return false; } -#endif #if NETCORE public void DoAjaxLoad(int SId, GXWebRow row) { @@ -2222,22 +2277,16 @@ public virtual bool CompressHtmlResponse() { return GXUtil.CompressResponse(); } - -#if NETCORE - protected virtual void Render(HtmlTextWriter output) -#else +#if !NETCORE protected override void Render(HtmlTextWriter output) -#endif { -#if !NETCORE - localHttpContext = Context; -#endif + localHttpContext = Context; ControlOutputWriter = output; LoadParameters(Parms); InitPrivates(); webExecuteEx(localHttpContext); } - +#endif public void InitPrivates() { context.GX_msglist = new msglist(); @@ -2857,21 +2906,18 @@ public void ComponentInit() createObjects(); initialize(); } - +#if !NETCORE protected override void Render(HtmlTextWriter output) { ControlOutputWriter = output; -#if NETCORE - localHttpContext = localHttpContext; -#else localHttpContext = Context; -#endif LoadParameters(Parms); InitPrivates(); SetPrefix(_prefixId + "_"); // Load Prefix from Name property initpars(); // Initialize Iterator Parameters webExecuteEx(localHttpContext); } +#endif public virtual void componentdrawstyles() { } diff --git a/dotnet/src/dotnetframework/GxClasses/Model/GXBaseObject.cs b/dotnet/src/dotnetframework/GxClasses/Model/GXBaseObject.cs index 0f377b065..df67abdf5 100644 --- a/dotnet/src/dotnetframework/GxClasses/Model/GXBaseObject.cs +++ b/dotnet/src/dotnetframework/GxClasses/Model/GXBaseObject.cs @@ -1,5 +1,7 @@ +using GeneXus.Data.NTier; using GeneXus.Encryption; using GeneXus.Http; +using GeneXus.Mock; using GeneXus.Utils; using Jayrock.Json; using log4net; @@ -8,10 +10,16 @@ #endif using System; using System.Collections.Generic; +using System.Reflection; +using System.Threading; namespace GeneXus.Application { - + public class GxObjectParameter + { + public ParameterInfo ParmInfo { get; set; } + public string ParmName { get; set; } + } public class GXBaseObject { static readonly ILog log = log4net.LogManager.GetLogger(typeof(GXBaseObject)); @@ -19,6 +27,89 @@ public class GXBaseObject protected IGxContext _Context; bool _isMain; protected bool _isApi; + protected virtual void ExecuteEx() + { + if (GxMockProvider.Provider != null) + { + List parmInfo = GetExecuteParameterMap(); + if (GxMockProvider.Provider.Handle(_Context, this, parmInfo)) + return; + } + ExecutePrivate(); + } + protected virtual void ExecutePrivate() + { + + } + protected virtual void ExecutePrivateCatch(object stateInfo) + { + try + { + ((GXBaseObject)stateInfo).ExecutePrivate(); + } + catch (Exception e) + { + GXUtil.SaveToEventLog("Design", e); + Console.WriteLine(e.ToString()); + } + } + protected void SubmitImpl() + { + GxContext submitContext = new GxContext(); + DataStoreUtil.LoadDataStores(submitContext); + IsMain = true; + submitContext.SetSubmitInitialConfig(context); + this.context= submitContext; + initialize(); + Submit(ExecutePrivateCatch, this); + } + protected virtual void CloseCursors() + { + + } + public virtual void initialize() { throw new Exception("The method or operation is not implemented."); } + protected void Submit(Action executeMethod, object state) + { + ThreadUtil.Submit(PropagateCulture(new WaitCallback(executeMethod)), state); + } + public static WaitCallback PropagateCulture(WaitCallback action) + { + var currentCulture = Thread.CurrentThread.CurrentCulture; + GXLogging.Debug(log, "Submit PropagateCulture " + currentCulture); + var currentUiCulture = Thread.CurrentThread.CurrentUICulture; + return (x) => + { + Thread.CurrentThread.CurrentCulture = currentCulture; + Thread.CurrentThread.CurrentUICulture = currentUiCulture; + action(x); + }; + } + + + private List GetExecuteParameterMap() + { + ParameterInfo[] pars = GetType().GetMethod("execute").GetParameters(); + string[] parms = GetParameters(); + int idx = 0; + List parmInfo = new List(); + if (pars != null && parms!=null && pars.Length == parms.Length) + { + foreach (ParameterInfo par in pars) + { + parmInfo.Add(new GxObjectParameter() + { + ParmInfo = par, + ParmName = parms[idx] + }); + idx++; + } + } + return parmInfo; + } + protected virtual string[] GetParameters() + { + return null; + } public virtual IGxContext context { diff --git a/dotnet/src/dotnetframework/GxClasses/Model/GXSilentTrn.cs b/dotnet/src/dotnetframework/GxClasses/Model/GXSilentTrn.cs index 5596d0cbf..371405266 100644 --- a/dotnet/src/dotnetframework/GxClasses/Model/GXSilentTrn.cs +++ b/dotnet/src/dotnetframework/GxClasses/Model/GXSilentTrn.cs @@ -121,7 +121,6 @@ public GxSilentTrn() { } - public virtual void initialize() { } public void flushBuffer(){ } public virtual object getParm(object[] parms, int index) diff --git a/dotnet/src/dotnetframework/GxClasses/Model/GXWebProcedure.cs b/dotnet/src/dotnetframework/GxClasses/Model/GXWebProcedure.cs index d2c799c20..c7f9978d7 100644 --- a/dotnet/src/dotnetframework/GxClasses/Model/GXWebProcedure.cs +++ b/dotnet/src/dotnetframework/GxClasses/Model/GXWebProcedure.cs @@ -13,6 +13,9 @@ namespace GeneXus.Procedure #else using System.Web; #endif + using log4net; + using GeneXus.Application; + using GeneXus.Data.NTier; public class GXWebProcedure : GXHttpHandler { @@ -230,15 +233,5 @@ protected void GxDrawDynamicBitMap(int printBlock, int controlId, string value, { reportMetadata.GxDrawBitMap(printBlock, controlId, line, value, aspectRatio); } - - protected static WaitCallback PropagateCulture(WaitCallback action) - { - return GXProcedure.PropagateCulture(action); - } - protected void Submit(Action executeMethod, object state) - { - ThreadUtil.Submit(PropagateCulture(new WaitCallback(executeMethod)), state); - } - } } \ No newline at end of file diff --git a/dotnet/src/dotnetframework/GxClasses/Model/GxMockProvider.cs b/dotnet/src/dotnetframework/GxClasses/Model/GxMockProvider.cs new file mode 100644 index 000000000..166a67064 --- /dev/null +++ b/dotnet/src/dotnetframework/GxClasses/Model/GxMockProvider.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using GeneXus.Application; +using log4net; +namespace GeneXus.Mock +{ + public interface IGxMock + { + bool Handle(IGxContext context, T objectInstance, List parameters) where T : GXBaseObject; + } + public class GxMockProvider + { + static readonly ILog log = log4net.LogManager.GetLogger(typeof(GxMockProvider)); + + private static volatile IGxMock provider; + + public static IGxMock Provider{ + get + { + return provider; + } + set{ + provider = value; + if (provider != null) + GXLogging.Debug(log, "Mock provider: " + provider.GetType().FullName); + else + GXLogging.Debug(log, "Mock provider set to null "); + } + } + } + +} \ No newline at end of file diff --git a/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs b/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs index f45d80700..7ec76f78e 100644 --- a/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs +++ b/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs @@ -3,26 +3,21 @@ namespace GeneXus.Procedure { using System; - using GeneXus.Encryption; - using GeneXus.Configuration; - using GeneXus.Application; - using GeneXus.Printer; - using System.Reflection; + using System.Collections.Generic; using System.IO; - using log4net; + using System.Reflection; + using GeneXus.Application; + using GeneXus.Configuration; + using GeneXus.Data; + using GeneXus.Metadata; using GeneXus.Performance; + using GeneXus.Printer; using GeneXus.Utils; - using System.Globalization; - using System.Collections.Generic; using GeneXus.XML; - using GeneXus.Metadata; - using GeneXus.Data; + using log4net; public abstract class GXProcedure: GXBaseObject { - static readonly ILog log = log4net.LogManager.GetLogger(typeof(GeneXus.Procedure.GXProcedure)); - public abstract void initialize(); - protected int handle; protected GXReportMetadata reportMetadata; @@ -58,27 +53,52 @@ public GXProcedure() } #endif } + protected int MainImplEx(string[] args) + { + try + { + Config.ParseArgs(ref args); + return ExecuteCmdLine(args); + } + catch (Exception ex) + { + return GXUtil.HandleException(ex, Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location), args); ; + } + } - public bool DisconnectAtCleanup + protected int MainImpl(string[] args) { - get{ return disconnectUserAtCleanup;} - set{ disconnectUserAtCleanup=value;} + try + { + Config.ParseArgs(ref args); + return ExecuteCmdLine(args); + } + catch (Exception e) + { + GXUtil.SaveToEventLog("Design", e); + Console.WriteLine(e.ToString()); + return 1; + } } - protected void Submit(Action executeMethod, object state) + protected virtual int ExecuteCmdLine(string[] args) { - ThreadUtil.Submit(PropagateCulture(new WaitCallback(executeMethod)), state); + initialize(); + ExecutePrivate(); + return GX.GXRuntime.ExitCode; } - public static WaitCallback PropagateCulture(WaitCallback action) + public override void cleanup() { - var currentCulture = Thread.CurrentThread.CurrentCulture; - GXLogging.Debug(log, "Submit PropagateCulture " + currentCulture); - var currentUiCulture = Thread.CurrentThread.CurrentUICulture; - return (x) => + CloseCursors(); + if (IsMain) { - Thread.CurrentThread.CurrentCulture = currentCulture; - Thread.CurrentThread.CurrentUICulture = currentUiCulture; - action(x); - }; + context.CloseConnections(); + } + ExitApp(); + } + public bool DisconnectAtCleanup + { + get{ return disconnectUserAtCleanup;} + set{ disconnectUserAtCleanup=value;} } protected void ExitApp() { diff --git a/dotnet/src/dotnetframework/GxClasses/Reorg/GXReorg.cs b/dotnet/src/dotnetframework/GxClasses/Reorg/GXReorg.cs index cf26810d3..e2c0bba8f 100644 --- a/dotnet/src/dotnetframework/GxClasses/Reorg/GXReorg.cs +++ b/dotnet/src/dotnetframework/GxClasses/Reorg/GXReorg.cs @@ -54,6 +54,10 @@ public GXReorganization() GxContext.isReorganization = true; GXLogging.Debug(log, "GXReorganization.Ctr()"); } + protected virtual void ExecutePrivate() + { + + } public IGxContext context { get { return _Context; } @@ -387,9 +391,14 @@ public static bool IsBadImageFormatException(Exception ex) return false; #endif } + protected virtual void CloseCursors() + { + + } + } - public delegate void BlockEndCallback(string blockName, int errorCode); + public delegate void BlockEndCallback(string blockName, int errorCode); public class ReorgExecute { diff --git a/dotnet/src/extensions/mocking/src/MockDBAccess/GXMockProcedure.cs b/dotnet/src/extensions/mocking/src/MockDBAccess/GXMockProcedure.cs new file mode 100644 index 000000000..e869158b6 --- /dev/null +++ b/dotnet/src/extensions/mocking/src/MockDBAccess/GXMockProcedure.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using GeneXus.Application; +using GeneXus.Mock; + +namespace MockDBAccess +{ + public class GXMockProcedure : IGxMock + { + public bool Handle(IGxContext context, T objectInstance, List parameters) where T : GXBaseObject + { + StringBuilder builder = new StringBuilder("Mocking "); + builder.Append(objectInstance.GetType().Name); + if (parameters != null && parameters.Count>0) + { + builder.Append(" Parameters:"); + foreach (var parameter in parameters) + { + builder.Append("["); + builder.Append($"{parameter.ParmName},{parameter.ParmInfo.ParameterType.Name}"); + if (parameter.ParmInfo.ParameterType.IsByRef) + { + builder.Append(",ref"); + } + else if (parameter.ParmInfo.IsOut) + { + builder.Append(",out"); + } + else + { + builder.Append(",in"); + } + builder.Append(",value:" + objectInstance.GetType().GetField(parameter.ParmName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(objectInstance)); + builder.Append("] "); + + //objectInstance.GetType().GetField(parameter.ParmName, BindingFlags.Instance | BindingFlags.NonPublic).SetValue(objectInstance, NEWVALUE) //SET + } + } + objectInstance.context.GX_msglist.addItem(builder.ToString()); + return true; + } + } +} diff --git a/dotnet/src/extensions/mocking/test/TestMockDBAccess/MockTest.cs b/dotnet/src/extensions/mocking/test/TestMockDBAccess/MockTest.cs index 4fb7c6adf..0dc7848f5 100644 --- a/dotnet/src/extensions/mocking/test/TestMockDBAccess/MockTest.cs +++ b/dotnet/src/extensions/mocking/test/TestMockDBAccess/MockTest.cs @@ -1,4 +1,6 @@ +using GeneXus.Mock; using GeneXus.Programs; +using MockDBAccess; using NUnit.Framework; namespace TestMockDBAccess @@ -17,5 +19,19 @@ public void TestServerDateWithMockDB() new aabmtest().executeCmdLine(null) ; } - } + [Test] + public void TestMockProcedure() + { + IGxMock mock= new GXMockProcedure(); + GxMockProvider.Provider = mock; + aprocmain test = new aprocmain(); + string message = ""; + short number = 2; + test.execute(1, ref number, out message); + + string msg = test.GX_msglist.getItemText(1); + Assert.AreEqual("Mocking aprocmain Parameters:[AV8clientid,Int16,in,value:1] [AV9Number,Int16&,ref,value:2] [AV10Message,String&,ref,value:] ", msg); + + } + } } \ No newline at end of file diff --git a/dotnet/src/extensions/mocking/test/TestMockDBAccess/aprocmain.cs b/dotnet/src/extensions/mocking/test/TestMockDBAccess/aprocmain.cs new file mode 100644 index 000000000..92075c34a --- /dev/null +++ b/dotnet/src/extensions/mocking/test/TestMockDBAccess/aprocmain.cs @@ -0,0 +1,149 @@ +using System; +using GeneXus.Application; +using GeneXus.Data; +using GeneXus.Data.NTier; +using GeneXus.Procedure; +using GeneXus.Utils; +namespace GeneXus.Programs +{ + public class aprocmain : GXProcedure + { + public int executeCmdLine(string[] args) + { + short aP0_clientid; + short aP1_Number; + string aP2_Message = new string(' ', 0); + if (0 < args.Length) + { + aP0_clientid = ((short)(NumberUtil.Val((string)(args[0]), "."))); + } + else + { + aP0_clientid = 0; + } + if (1 < args.Length) + { + aP1_Number = ((short)(NumberUtil.Val((string)(args[1]), "."))); + } + else + { + aP1_Number = 0; + } + if (2 < args.Length) + { + aP2_Message = ((string)(args[2])); + } + else + { + aP2_Message = ""; + } + execute(aP0_clientid, ref aP1_Number, out aP2_Message); + return 0; + } + + public aprocmain() + { + context = new GxContext(); + DataStoreUtil.LoadDataStores(context); + dsDefault = context.GetDataStore("Default"); + IsMain = true; + context.SetDefaultTheme("Gxtestprocs", true); + } + + public aprocmain(IGxContext context) + { + this.context = context; + IsMain = false; + dsDefault = context.GetDataStore("Default"); + } + + public void execute(short aP0_clientid, + ref short aP1_Number, + out string aP2_Message) + { + this.AV8clientid = aP0_clientid; + this.AV9Number = aP1_Number; + this.AV10Message = ""; + initialize(); + ExecuteEx(); + aP1_Number = this.AV9Number; + aP2_Message = this.AV10Message; + } + + public string executeUdp(short aP0_clientid, + ref short aP1_Number) + { + execute(aP0_clientid, ref aP1_Number, out aP2_Message); + return AV10Message; + } + + public void executeSubmit(short aP0_clientid, + ref short aP1_Number, + out string aP2_Message) + { + aprocmain objaprocmain; + objaprocmain = new aprocmain(); + objaprocmain.AV8clientid = aP0_clientid; + objaprocmain.AV9Number = aP1_Number; + objaprocmain.AV10Message = ""; + objaprocmain.context.SetSubmitInitialConfig(context); + objaprocmain.initialize(); + Submit(executePrivateCatch, objaprocmain); + aP1_Number = this.AV9Number; + aP2_Message = this.AV10Message; + } + + void executePrivateCatch(object stateInfo) + { + try + { + ((aprocmain)stateInfo).ExecutePrivate(); + } + catch (Exception e) + { + GXUtil.SaveToEventLog("Design", e); + Console.WriteLine(e.ToString()); + } + } + + protected override string[] GetParameters() + { + return new string[] { "AV8clientid", "AV9Number", "AV10Message" }; ; + } + + protected override void ExecutePrivate() + { + AV10Message = string.Empty; + this.cleanup(); + } + + public override void cleanup() + { + CloseOpenCursors(); + if (IsMain) + { + context.CloseConnections(); + } + ExitApp(); + } + + protected void CloseOpenCursors() + { + } + + public override void initialize() + { + AV10Message = ""; + /* GeneXus formulas. */ + context.Gx_err = 0; + } + + private short AV8clientid; + private short AV9Number; + private string AV10Message; + private IGxDataStore dsDefault; + private string aP2_Message; + } + + +} diff --git a/dotnet/test/DotNetCoreUnitTest/Submit/SubmitTest.cs b/dotnet/test/DotNetCoreUnitTest/Submit/SubmitTest.cs index 14a81b3c2..4ab3554c0 100644 --- a/dotnet/test/DotNetCoreUnitTest/Submit/SubmitTest.cs +++ b/dotnet/test/DotNetCoreUnitTest/Submit/SubmitTest.cs @@ -11,12 +11,22 @@ namespace UnitTesting public class SubmitTest { internal static ConcurrentDictionary numbers = new ConcurrentDictionary(); + internal static short SubmitParameter; [Fact] public void SubmitAll() { MainProc proc = new MainProc(); proc.execute(); } + [Fact] + public void ParametersOnSubmit() + { + SubmitParametersProc proc = new SubmitParametersProc(); + short parmValueTest = 20; + proc.executeSubmit(parmValueTest); + ThreadUtil.WaitForEnd(); + Assert.Equal(SubmitParameter, parmValueTest); + } } public class MainProc : GXProcedure { @@ -83,4 +93,25 @@ public override void initialize() } } + public class SubmitParametersProc : GXProcedure + { + public SubmitParametersProc() + { + context = new GxContext(); + } + public void executeSubmit(short parmValue) + { + this.internalParmValue = parmValue; + SubmitImpl(); + } + protected override void ExecutePrivate() + { + SubmitTest.SubmitParameter = this.internalParmValue; + } + public override void initialize() + { + + } + private short internalParmValue; + } }