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 = "jRDCWrapJob_" & jobCounter

	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 = "jRDCWrapJob_" & jobCounter

	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)
	'<<< 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