B4A=true Group=Default Group ModulesStructureVersion=1 Type=Class Version=12.8 @EndOfDesignText@ 'Class module: jRDC1Wrapper 'Version 1.3 - Thread-Safe with ExecuteCommand support Public Sub Class_Globals ' Public properties to be accessed after the wait for completes Type TResultado(Tag As String, Success As Boolean, resultado As DBResult, ErrorMessage As String) ' Type TCommandResult(Tag As String, Success As Boolean, RowsAffected As Int, ErrorMessage As String) 'C <<< Definimos un tipo para almacenar la información de cada job Type TJobInfo (Target As Object, EventName As String, IsQuery As Boolean) 'C <<< Un mapa para mantener un registro de los jobs activos Private activeJobs As Map 'C <<< Un contador para generar tags únicos para cada job Private jobCounter As Int Public reqManager As DBRequestManager Public cmd As DBCommand Public resultado As TResultado ' Public commandResult As TCommandResult Private logger As Boolean = False End Sub 'Initializes the object. Public Sub Initialize 'C <<< Inicializamos el mapa y el contador activeJobs.Initialize jobCounter = 0 End Sub 'Executes the query using the old jRDC1 mechanism. 'Parameters: ' - rdcLink: The link for the reqManager initialization. ' - Command: The DBCommand to execute. ' - Target: The module (like 'Me') where the completed event should be raised. ' - Event: The name of the event to raise when the query completes (e.g., "WrapperEvent"). Public Sub ExecuteQuery(rdcLink As String, Command As DBCommand, Target As Object, Event As String) '<<< Incrementamos el contador para obtener un ID único jobCounter = jobCounter + 1 Dim currentJobTag As String = "reqManagerWJob_" & jobCounter currentJobTag = Event If logger Then Log($"ExecuteQuery (Tag: ${currentJobTag}): Command=${Command.Name}, Event=${Event}"$) '<<< Creamos una instancia de TJobInfo para guardar el target y el evento Dim jobInfo As TJobInfo jobInfo.Initialize jobInfo.Target = Target jobInfo.EventName = Event jobInfo.IsQuery = True ' Mark as query job '<<< Guardamos la información del job en el mapa, usando el tag único como llave activeJobs.Put(currentJobTag, jobInfo) reqManager.Initialize(Me, rdcLink) cmd = Command '<<< Ejecutamos la consulta pasando nuestro TAG ÚNICO reqManager.ExecuteQuery(cmd, 0, currentJobTag) End Sub 'Executes a command (INSERT, UPDATE, DELETE) using the old jRDC1 mechanism. 'Parameters: ' - rdcLink: The link for the reqManager initialization. ' - Command: The DBCommand to execute. ' - Target: The module (like 'Me') where the completed event should be raised. ' - Event: The name of the event to raise when the command completes (e.g., "WrapperEvent"). Public Sub ExecuteCommand(rdcLink As String, Command As DBCommand, Target As Object, Event As String) '<<< Incrementamos el contador para obtener un ID único jobCounter = jobCounter + 1 Dim currentJobTag As String = "reqManagerWJob_" & jobCounter currentJobTag = Event If logger Then Log($"ExecuteCommand (Tag: ${currentJobTag}): Command=${Command.Name}, Event=${Event}"$) '<<< Creamos una instancia de TJobInfo para guardar el target y el evento Dim jobInfo As TJobInfo jobInfo.Initialize jobInfo.Target = Target jobInfo.EventName = Event jobInfo.IsQuery = False ' Mark as command job '<<< Guardamos la información del job en el mapa, usando el tag único como llave activeJobs.Put(currentJobTag, jobInfo) reqManager.Initialize(Me, rdcLink) cmd = Command '<<< Ejecutamos el comando pasando nuestro TAG ÚNICO reqManager.ExecuteCommand(cmd, currentJobTag) End Sub 'This sub will be called by the DBRequestManager when the job is done Public Sub JobDone(job As HttpJob) Log("===== JDDBRW =====") LogColor("JobDone: '" & reqManager.HandleJob(job).tag & "' - Registros: " & reqManager.HandleJob(job).Rows.Size, Colors.Green) 'Mod por CHV - 211110 '<<< Obtenemos el Tag único que asignamos al job Dim currentJobTag As String = job.Tag 'C <<< Verificamos si este job fue iniciado por nuestro wrapper If activeJobs.ContainsKey(currentJobTag) = False Then If logger Then Log($"JobDone: Se recibió un job con un tag desconocido: ${currentJobTag}"$) job.Release Return End If '<<< Recuperamos la información específica de este job desde el mapa Dim jobInfo As TJobInfo = activeJobs.Get(currentJobTag) Try If jobInfo.IsQuery Then ' Handle query result resultado.Initialize resultado.Tag = jobInfo.EventName ' Usamos el nombre del evento original como Tag del resultado If job.Success Then Dim dbResult As DBResult = reqManager.HandleJob(job) resultado.Success = True resultado.Resultado = dbResult resultado.ErrorMessage = "" Else resultado.Success = False resultado.Resultado = Null resultado.ErrorMessage = job.ErrorMessage End If job.Release '<<< Usamos la información recuperada del mapa para llamar al Sub correcto If logger Then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta) CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resultado) Else ' Handle command result resultado.Initialize resultado.Tag = jobInfo.EventName If job.Success Then Dim dbResult As DBResult = reqManager.HandleJob(job) ' Dim rowsAffected As Int = reqManager.HandleCommandResult(job) ' For Each records() As Object In dbResult.Rows ' Dim rowsAffected As Int = records(dbResult.Columns.Get("AffectedRows")) ' Next resultado.Success = True resultado.resultado = dbResult resultado.ErrorMessage = "" Else resultado.Success = False resultado.resultado = Null resultado.ErrorMessage = job.ErrorMessage End If job.Release '<<< Usamos la información recuperada del mapa para llamar al Sub correcto If logger Then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta) CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resultado) End If 'C <<< Se remueve el job del mapa en caso de ÉXITO activeJobs.Remove(currentJobTag) Catch If logger Then LogColor("Error en jRDC1Wrapper.JobDone: " & LastException, Colors.Red) '<<< MUY IMPORTANTE: Remover el job del mapa para no tener fugas de memoria activeJobs.Remove(currentJobTag) End Try End Sub