- VERSION 5.08.30

- Se cambiaron los 4 handlers de B4A a uno solo que toma el DB de la ruta automáticamente.
- Se agregaron validaciones del numero de parametros y si el query no los requiere o se dan de mas o de menos, manda un error especificando eso, ya no se reciben errores directos de la base de datos, esto fue tanto para B4A como para JSON.
- Se modificó el Readme.md para incluir todos estos cambios.
This commit is contained in:
2025-08-30 20:31:50 -06:00
parent 911879b5d5
commit 986eb5e8d4
19 changed files with 955 additions and 639 deletions

View File

@@ -30,7 +30,6 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
Dim con As SQL Dim con As SQL
Try Try
con = Connector.GetConnection("DB1") con = Connector.GetConnection("DB1")
Log("Metodo: " & method)
If method = "query2" Then If method = "query2" Then
q = ExecuteQuery2("DB1", con, in, resp) q = ExecuteQuery2("DB1", con, in, resp)
'#if VERSION1 '#if VERSION1

View File

@@ -4,158 +4,260 @@ ModulesStructureVersion=1
Type=Class Type=Class
Version=10.3 Version=10.3
@EndOfDesignText@ @EndOfDesignText@
'Handler class for JSON requests from Web Clients (JavaScript/axios) ' Handler class for JSON requests from Web Clients (JavaScript/axios)
'VERSION 14 (Validación de Parámetros): Chequea que el número de '?' coincida con los parámetros recibidos. ' VERSIÓN 16 (Comentarios y Mensajes en Español):
' - Se añaden comentarios detallados a la versión con mensajes de error en español.
' - Revisa que el 'query' exista en config.properties antes de continuar.
' - Asegura que la conexión a la BD se cierre en todos los 'Return' para evitar fugas.
Sub Class_Globals Sub Class_Globals
Private Connector As RDCConnector ' Declara una variable privada para mantener una instancia del conector RDC.
' Este objeto maneja la comunicación con la base de datos.
Private Connector As RDCConnector
End Sub End Sub
' Subrutina de inicialización de la clase. Se llama cuando se crea un objeto de esta clase.
' En este caso, no se necesita ninguna inicialización específica.
Public Sub Initialize Public Sub Initialize
End Sub End Sub
' Este es el método principal que maneja las peticiones HTTP entrantes (req) y prepara la respuesta (resp).
Sub Handle(req As ServletRequest, resp As ServletResponse) Sub Handle(req As ServletRequest, resp As ServletResponse)
' --- Headers CORS --- Log("============== DB1JsonHandler ==============")
resp.SetHeader("Access-Control-Allow-Origin", "*") ' --- Headers CORS (Cross-Origin Resource Sharing) ---
resp.SetHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS") ' Estos encabezados son necesarios para permitir que un cliente web (ej. una página con JavaScript)
resp.SetHeader("Access-Control-Allow-Headers", "Content-Type") ' que se encuentra en un dominio diferente pueda hacer peticiones a este servidor.
resp.SetHeader("Access-Control-Allow-Origin", "*") ' Permite peticiones desde cualquier origen.
resp.SetHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS") ' Métodos HTTP permitidos.
resp.SetHeader("Access-Control-Allow-Headers", "Content-Type") ' Encabezados permitidos en la petición.
If req.Method = "OPTIONS" Then Return ' El método OPTIONS es una "petición de comprobación previa" (preflight request) que envían los navegadores
' para verificar los permisos CORS antes de enviar la petición real (ej. POST).
' Si es una petición OPTIONS, simplemente terminamos la ejecución sin procesar nada más.
If req.Method = "OPTIONS" Then Return
Dim DB As String = "DB1" ' Establece "DB1" como el nombre de la base de datos por defecto.
Connector = Main.Connectors.Get(DB) Dim DB As String = "DB1"
Dim con As SQL ' Obtiene el objeto conector para la base de datos por defecto desde el objeto Main.
Connector = Main.Connectors.Get(DB)
' Declara una variable para la conexión SQL.
Dim con As SQL
Try ' Inicia un bloque Try...Catch para manejar posibles errores durante la ejecución.
Dim jsonString As String = req.GetParameter("j") Try
If jsonString = Null Or jsonString = "" Then ' Obtiene el valor del parámetro 'j' de la petición. Se espera que contenga una cadena JSON.
SendErrorResponse(resp, 400, "Missing 'j' parameter") Dim jsonString As String = req.GetParameter("j")
Return ' Verifica si el parámetro 'j' es nulo o está vacío.
End If If jsonString = Null Or jsonString = "" Then
' Si falta el parámetro, envía una respuesta de error 400 (Bad Request) y termina la ejecución.
Dim parser As JSONParser SendErrorResponse(resp, 400, "Falta el parametro 'j' en el URL")
parser.Initialize(jsonString) Return
Dim RootMap As Map = parser.NextObject
Dim execType As String = RootMap.GetDefault("exec", "")
Dim queryName As String = RootMap.Get("query")
Dim paramsMap As Map = RootMap.Get("params")
If RootMap.Get("dbx") <> Null Then DB = RootMap.Get("dbx") ' Si se especifica, usamos la BD indicada, si no, usamos "DB1".
' Log("RootMap: " & RootMap)
' Log("LA BD: " & DB)
' Log(Main.listaDeCP.size)
' Log("Contiene: " & Main.listaDeCP.IndexOf(DB))
If Main.listaDeCP.IndexOf(DB) = -1 Then
SendErrorResponse(resp, 400, "Invalid 'DB' name. The '" & DB & "' name is not valid.")
End If End If
Dim paramKeys As List ' Crea un objeto JSONParser para analizar la cadena JSON.
paramKeys.Initialize Dim parser As JSONParser
If paramsMap <> Null And paramsMap.IsInitialized Then parser.Initialize(jsonString)
For Each key As String In paramsMap.Keys ' Convierte la cadena JSON en un objeto Map, que es como un diccionario (clave-valor).
paramKeys.Add(key) Dim RootMap As Map = parser.NextObject
Next
End If
paramKeys.Sort(True)
Dim orderedParams As List ' Extrae los datos necesarios del JSON.
orderedParams.Initialize Dim execType As String = RootMap.GetDefault("exec", "") ' Tipo de ejecución: "executeQuery" o "executeCommand".
For Each key As String In paramKeys Dim queryName As String = RootMap.Get("query") ' Nombre del comando SQL (definido en config.properties).
orderedParams.Add(paramsMap.Get(key)) Dim paramsMap As Map = RootMap.Get("params") ' Un mapa con los parámetros para la consulta.
Next ' Log(RootMap)
' Verifica si en el JSON se especificó un nombre de base de datos diferente con la clave "dbx".
If RootMap.Get("dbx") <> Null Then DB = RootMap.Get("dbx") ' Si se especifica, usamos la BD indicada, si no, se queda "DB1".
con = Connector.GetConnection(DB) ' Valida que el nombre de la base de datos (DB) exista en la lista de conexiones configuradas en Main.
Dim sqlCommand As String = Connector.GetCommand(DB, queryName) If Main.listaDeCP.IndexOf(DB) = -1 Then
SendErrorResponse(resp, 400, "Parametro 'DB' invalido. El nombre '" & DB & "' no es válido.")
' Se añade Return para detener la ejecución si la BD no es válida.
Return
End If
If execType.ToLowerCase = "executequery" Then ' Prepara una lista para almacenar las claves de los parámetros.
Dim rs As ResultSet Dim paramKeys As List
paramKeys.Initialize
' Si el mapa de parámetros existe y está inicializado...
If paramsMap <> Null And paramsMap.IsInitialized Then
' ...itera sobre todas las claves y las añade a la lista 'paramKeys'.
For Each key As String In paramsMap.Keys
paramKeys.Add(key)
Next
End If
' Ordena las claves alfabéticamente. Esto es crucial para asegurar que los parámetros
' se pasen a la consulta SQL en un orden consistente y predecible.
paramKeys.Sort(True)
If sqlCommand.Contains("?") Then ' Prepara una lista para almacenar los valores de los parámetros en el orden correcto.
' ================================================================= Dim orderedParams As List
' === VALIDACIÓN DE CONTEO DE PARÁMETROS ========================== orderedParams.Initialize
' ================================================================= ' Itera sobre la lista de claves ya ordenada.
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length For Each key As String In paramKeys
Dim receivedParams As Int = orderedParams.Size ' Añade el valor correspondiente a cada clave a la lista 'orderedParams'.
If expectedParams <> receivedParams Then orderedParams.Add(paramsMap.Get(key))
SendErrorResponse(resp, 400, $"Parameter count mismatch. The command '${queryName}' expects ${expectedParams} parameter(s), but received ${receivedParams}."$) Next
Return ' Detenemos la ejecución antes de tocar la BD
End If
' =================================================================
rs = con.ExecQuery2(sqlCommand, orderedParams)
Else
rs = con.ExecQuery(sqlCommand)
End If
' --- Procesamiento de resultados (sin cambios) --- ' Obtiene una conexión a la base de datos del pool de conexiones.
Dim ResultList As List con = Connector.GetConnection(DB)
ResultList.Initialize ' Obtiene la cadena SQL del archivo de configuración usando el nombre de la consulta (queryName).
Dim jrs As JavaObject = rs Dim sqlCommand As String = Connector.GetCommand(DB, queryName)
Dim rsmd As JavaObject = jrs.RunMethod("getMetaData", Null)
Dim cols As Int = rsmd.RunMethod("getColumnCount", Null)
Do While rs.NextRow ' <<< INICIO NUEVA VALIDACIÓN: VERIFICAR SI EL COMANDO EXISTE >>>
Dim RowMap As Map ' Comprueba si el comando SQL (query) especificado en el JSON fue encontrado en el archivo de configuración.
RowMap.Initialize If sqlCommand = Null Or sqlCommand = "null" Or sqlCommand.Trim = "" Then
For i = 1 To cols ' Si no se encontró el comando, crea un mensaje de error claro.
Dim ColumnName As String = rsmd.RunMethod("getColumnName", Array(i)) Dim errorMessage As String = $"El comando '${queryName}' no fue encontrado en el config.properties de '${DB}'."$
Dim value As Object = jrs.RunMethod("getObject", Array(i)) ' Registra el error en el log del servidor para depuración.
RowMap.Put(ColumnName, value) Log(errorMessage)
Next ' Envía una respuesta de error 400 (Bad Request) al cliente en formato JSON.
ResultList.Add(RowMap) SendErrorResponse(resp, 400, errorMessage)
Loop ' Cierra la conexión a la base de datos antes de salir para evitar fugas de conexión.
rs.Close If con <> Null And con.IsInitialized Then con.Close
' Detiene la ejecución del método Handle para esta petición.
Return
End If
' <<< FIN NUEVA VALIDACIÓN >>>
SendSuccessResponse(resp, CreateMap("result": ResultList)) ' Comprueba el tipo de ejecución solicitado ("executeQuery" o "executeCommand").
Else If execType.ToLowerCase = "executecommand" Then If execType.ToLowerCase = "executequery" Then
If sqlCommand.Contains("?") Then ' Declara una variable para almacenar el resultado de la consulta.
' ================================================================= Dim rs As ResultSet
' === VALIDACIÓN DE CONTEO DE PARÁMETROS (para Comandos) ==========
' =================================================================
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
Dim receivedParams As Int = orderedParams.Size
If expectedParams <> receivedParams Then
SendErrorResponse(resp, 400, $"Parameter count mismatch. The command '${queryName}' expects ${expectedParams} parameter(s), but received ${receivedParams}."$)
Return ' Detenemos la ejecución
End If
' =================================================================
End If
con.ExecNonQuery2(sqlCommand, orderedParams) ' Si el comando SQL contiene placeholders ('?'), significa que espera parámetros.
SendSuccessResponse(resp, CreateMap("message": "Command executed successfully")) If sqlCommand.Contains("?") Then
' =================================================================
' === VALIDACIÓN DE CONTEO DE PARÁMETROS ==========================
' =================================================================
' Calcula cuántos parámetros espera la consulta contando el número de '?'.
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
' Obtiene cuántos parámetros se recibieron.
Dim receivedParams As Int = orderedParams.Size
' Compara si la cantidad de parámetros esperados y recibidos es diferente.
If expectedParams <> receivedParams Then
' Si no coinciden, envía un error 400 detallado.
SendErrorResponse(resp, 400, $"Número de parametros equivocado para '${queryName}'. Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$)
' Cierra la conexión antes de salir para evitar fugas.
If con <> Null And con.IsInitialized Then con.Close
' Detiene la ejecución para evitar un error en la base de datos.
Return
End If
' =================================================================
' Ejecuta la consulta pasando el comando SQL y la lista ordenada de parámetros.
rs = con.ExecQuery2(sqlCommand, orderedParams)
Else
' Si no hay '?', ejecuta la consulta directamente sin parámetros.
rs = con.ExecQuery(sqlCommand)
End If
Else ' --- Procesamiento de resultados ---
SendErrorResponse(resp, 400, "Invalid 'exec' value. Use '" & execType & "' is not valid.") ' Prepara una lista para almacenar todas las filas del resultado.
End If Dim ResultList As List
ResultList.Initialize
' Usa un objeto JavaObject para acceder a los metadatos del resultado (info de columnas).
Dim jrs As JavaObject = rs
Dim rsmd As JavaObject = jrs.RunMethod("getMetaData", Null)
' Obtiene el número de columnas en el resultado.
Dim cols As Int = rsmd.RunMethod("getColumnCount", Null)
Catch ' Itera sobre cada fila del resultado (ResultSet).
Log(LastException) Do While rs.NextRow
SendErrorResponse(resp, 500, LastException.Message) ' Crea un mapa para almacenar los datos de la fila actual (columna -> valor).
End Try Dim RowMap As Map
RowMap.Initialize
' Itera sobre cada columna de la fila.
For i = 1 To cols
' Obtiene el nombre de la columna.
Dim ColumnName As String = rsmd.RunMethod("getColumnName", Array(i))
' Obtiene el valor de la columna.
Dim value As Object = jrs.RunMethod("getObject", Array(i))
' Añade la pareja (nombre_columna, valor) al mapa de la fila.
RowMap.Put(ColumnName, value)
Next
' Añade el mapa de la fila a la lista de resultados.
ResultList.Add(RowMap)
Loop
' Cierra el ResultSet para liberar recursos de la base de datos.
rs.Close
' Envía una respuesta de éxito con la lista de resultados en formato JSON.
SendSuccessResponse(resp, CreateMap("result": ResultList))
Else If execType.ToLowerCase = "executecommand" Then
' Si es un comando (INSERT, UPDATE, DELETE), también valida los parámetros.
If sqlCommand.Contains("?") Then
' =================================================================
' === VALIDACIÓN DE CONTEO DE PARÁMETROS (para Comandos) ==========
' =================================================================
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
Dim receivedParams As Int = orderedParams.Size
If expectedParams <> receivedParams Then
SendErrorResponse(resp, 400, $"Número de parametros equivocado para '${queryName}'. Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$)
' Cierra la conexión antes de salir.
If con <> Null And con.IsInitialized Then con.Close
' Detiene la ejecución.
Return
End If
' =================================================================
End If
' Ejecuta el comando que no devuelve resultados (NonQuery) con sus parámetros.
con.ExecNonQuery2(sqlCommand, orderedParams)
' Envía una respuesta de éxito con un mensaje de confirmación.
SendSuccessResponse(resp, CreateMap("message": "Command executed successfully"))
Else
' Si el valor de 'exec' no es ni "executeQuery" ni "executeCommand", envía un error.
SendErrorResponse(resp, 400, "Parametro 'exec' inválido. '" & execType & "' no es un valor permitido.")
End If
Catch
' Si ocurre cualquier error inesperado en el bloque Try...
' Registra la excepción completa en el log del servidor para diagnóstico.
Log(LastException)
' Envía una respuesta de error 500 (Internal Server Error) con el mensaje de la excepción.
SendErrorResponse(resp, 500, LastException.Message)
End Try
If con <> Null And con.IsInitialized Then ' Este bloque se ejecuta siempre al final, haya habido error o no, *excepto si se usó Return antes*.
con.Close ' Comprueba si el objeto de conexión fue inicializado y sigue abierto.
End If If con <> Null And con.IsInitialized Then
' Cierra la conexión para devolverla al pool y que pueda ser reutilizada.
' Esto es fundamental para no agotar las conexiones a la base de datos.
con.Close
End If
End Sub End Sub
' --- Subrutinas de ayuda para respuestas JSON (sin cambios) --- ' --- Subrutinas de ayuda para respuestas JSON ---
' Construye y envía una respuesta JSON de éxito.
Private Sub SendSuccessResponse(resp As ServletResponse, dataMap As Map) Private Sub SendSuccessResponse(resp As ServletResponse, dataMap As Map)
dataMap.Put("success", True) ' Añade el campo "success": true al mapa de datos para indicar que todo salió bien.
Dim jsonGenerator As JSONGenerator dataMap.Put("success", True)
jsonGenerator.Initialize(dataMap) ' Crea un generador de JSON.
resp.ContentType = "application/json" Dim jsonGenerator As JSONGenerator
resp.Write(jsonGenerator.ToString) jsonGenerator.Initialize(dataMap)
' Establece el tipo de contenido de la respuesta a "application/json".
resp.ContentType = "application/json"
' Escribe la cadena JSON generada en el cuerpo de la respuesta HTTP.
resp.Write(jsonGenerator.ToString)
End Sub End Sub
' Construye y envía una respuesta JSON de error.
Private Sub SendErrorResponse(resp As ServletResponse, statusCode As Int, errorMessage As String) Private Sub SendErrorResponse(resp As ServletResponse, statusCode As Int, errorMessage As String)
Dim resMap As Map = CreateMap("success": False, "error": errorMessage) ' Personaliza el mensaje de error si es un error común de parámetros de Oracle o JDBC.
Dim jsonGenerator As JSONGenerator If errorMessage.Contains("Índice de columnas no válido") Or errorMessage.Contains("ORA-17003") Then errorMessage = "NUMERO DE PARAMETROS EQUIVOCADO: " & errorMessage
jsonGenerator.Initialize(resMap) ' Crea un mapa con el estado de error y el mensaje.
resp.Status = statusCode Dim resMap As Map = CreateMap("success": False, "error": errorMessage)
resp.ContentType = "application/json" ' Genera la cadena JSON a partir del mapa.
resp.Write(jsonGenerator.ToString) Dim jsonGenerator As JSONGenerator
End Sub jsonGenerator.Initialize(resMap)
' Establece el código de estado HTTP (ej. 400 para error del cliente, 500 para error del servidor).
resp.Status = statusCode
' Establece el tipo de contenido y escribe la respuesta de error.
resp.ContentType = "application/json"
resp.Write(jsonGenerator.ToString)
End Sub

View File

@@ -55,6 +55,7 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
End Sub End Sub
Private Sub ExecuteQuery2 (DB As String, con As SQL, in As InputStream, resp As ServletResponse) As String Private Sub ExecuteQuery2 (DB As String, con As SQL, in As InputStream, resp As ServletResponse) As String
Log("==== ExecuteQuery2 ==== ")
Dim ser As B4XSerializator Dim ser As B4XSerializator
Dim m As Map = ser.ConvertBytesToObject(Bit.InputStreamToBytes(in)) Dim m As Map = ser.ConvertBytesToObject(Bit.InputStreamToBytes(in))
Dim cmd As DBCommand = m.Get("command") Dim cmd As DBCommand = m.Get("command")
@@ -162,7 +163,7 @@ Private Sub ExecuteBatch(DB As String, con As SQL, in As InputStream, resp As Se
End Sub End Sub
Private Sub ExecuteQuery (DB As String, con As SQL, in As InputStream, resp As ServletResponse) As String Private Sub ExecuteQuery (DB As String, con As SQL, in As InputStream, resp As ServletResponse) As String
' Log("==== ExecuteQuery ==== ") Log("==== ExecuteQuery ==== ")
Dim clientVersion As Float = ReadObject(in) 'ignore Dim clientVersion As Float = ReadObject(in) 'ignore
Dim queryName As String = ReadObject(in) Dim queryName As String = ReadObject(in)
Dim limit As Int = ReadInt(in) Dim limit As Int = ReadInt(in)

View File

@@ -1,130 +0,0 @@
B4J=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=10.3
@EndOfDesignText@
'Handler class for JSON requests from Web Clients (JavaScript/axios)
'VERSION 13 (Corrección Final): Soluciona "Miembro desconocido" usando jrs.RunMethod.
Sub Class_Globals
Private Connector As RDCConnector
End Sub
Public Sub Initialize
End Sub
Sub Handle(req As ServletRequest, resp As ServletResponse)
' --- Headers CORS ---
resp.SetHeader("Access-Control-Allow-Origin", "*")
resp.SetHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
resp.SetHeader("Access-Control-Allow-Headers", "Content-Type")
If req.Method = "OPTIONS" Then Return
Dim DB As String = "DB1"
Connector = Main.Connectors.Get(DB)
Dim con As SQL
Try
Dim jsonString As String = req.GetParameter("j")
If jsonString = Null Or jsonString = "" Then
SendErrorResponse(resp, 400, "Missing 'j' parameter")
Return
End If
Dim parser As JSONParser
parser.Initialize(jsonString)
Dim RootMap As Map = parser.NextObject
Dim execType As String = RootMap.GetDefault("exec", "")
Dim queryName As String = RootMap.Get("query")
Dim paramsMap As Map = RootMap.Get("params")
Dim paramKeys As List
paramKeys.Initialize
If paramsMap <> Null And paramsMap.IsInitialized Then
For Each key As String In paramsMap.Keys
paramKeys.Add(key)
Next
End If
paramKeys.Sort(True)
Dim orderedParams As List
orderedParams.Initialize
For Each key As String In paramKeys
orderedParams.Add(paramsMap.Get(key))
Next
con = Connector.GetConnection(DB)
Dim sqlCommand As String = Connector.GetCommand(DB, queryName)
If execType.ToLowerCase = "executequery" Then
Dim rs As ResultSet
If sqlCommand.Contains("?") Then
rs = con.ExecQuery2(sqlCommand, orderedParams)
Else
rs = con.ExecQuery(sqlCommand)
End If
Dim ResultList As List
ResultList.Initialize
Dim jrs As JavaObject = rs
Dim rsmd As JavaObject = jrs.RunMethod("getMetaData", Null)
Dim cols As Int = rsmd.RunMethod("getColumnCount", Null)
Do While rs.NextRow
Dim RowMap As Map
RowMap.Initialize
For i = 1 To cols
Dim ColumnName As String = rsmd.RunMethod("getColumnName", Array(i))
' =================================================================
' === CORRECCIÓN "MIEMBRO DESCONOCIDO" ============================
' =================================================================
Dim value As Object = jrs.RunMethod("getObject", Array(i))
RowMap.Put(ColumnName, value)
Next
ResultList.Add(RowMap)
Loop
rs.Close
SendSuccessResponse(resp, CreateMap("result": ResultList))
Else If execType.ToLowerCase = "executecommand" Then
con.ExecNonQuery2(sqlCommand, orderedParams)
SendSuccessResponse(resp, CreateMap("message": "Command executed successfully"))
Else
SendErrorResponse(resp, 400, "Invalid 'exec' value. Use '" & execType & "' is not valid.")
End If
Catch
Log(LastException)
SendErrorResponse(resp, 500, LastException.Message)
End Try
If con <> Null And con.IsInitialized Then
con.Close
End If
End Sub
' --- Subrutinas de ayuda para respuestas JSON (sin cambios) ---
Private Sub SendSuccessResponse(resp As ServletResponse, dataMap As Map)
dataMap.Put("success", True)
Dim jsonGenerator As JSONGenerator
jsonGenerator.Initialize(dataMap)
resp.ContentType = "application/json"
resp.Write(jsonGenerator.ToString)
End Sub
Private Sub SendErrorResponse(resp As ServletResponse, statusCode As Int, errorMessage As String)
If errorMessage.Contains("Índice de columnas no válido") Or errorMessage.Contains("ORA-17003") Then errorMessage = "NUMERO DE PARAMETROS EQUIVOCADO: " & errorMessage
Dim resMap As Map = CreateMap("success": False, "error": errorMessage)
Dim jsonGenerator As JSONGenerator
jsonGenerator.Initialize(resMap)
resp.Status = statusCode
resp.ContentType = "application/json"
resp.Write(jsonGenerator.ToString)
End Sub

609
DBHandlerGenerico.bas Normal file
View File

@@ -0,0 +1,609 @@
B4J=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=10.3
@EndOfDesignText@
' Handler genérico para peticiones desde clientes B4A/B4i (DBRequestManager)
' Determina la base de datos a utilizar dinámicamente a partir de la URL de la petición.
' Versión con validación de parámetros y errores en texto plano.
Sub Class_Globals
' Estas constantes y variables solo se compilan si se usa la #if VERSION1,
' lo que sugiere que es para dar soporte a una versión antigua del protocolo de comunicación.
' #if VERSION1
' Constantes para identificar los tipos de datos en la serialización personalizada (protocolo V1).
Private const T_NULL = 0, T_STRING = 1, T_SHORT = 2, T_INT = 3, T_LONG = 4, T_FLOAT = 5 _
,T_DOUBLE = 6, T_BOOLEAN = 7, T_BLOB = 8 As Byte
' Utilidades para convertir entre tipos de datos y arrays de bytes.
Private bc As ByteConverter
' Utilidad para comprimir/descomprimir streams de datos (usado en V1).
Private cs As CompressedStreams
' #end if
' Mapa para convertir tipos de columna JDBC de fecha/hora a métodos de obtención de datos.
Private DateTimeMethods As Map
' Objeto que gestiona las conexiones a las diferentes bases de datos definidas en config.properties.
Private Connector As RDCConnector
End Sub
' Se ejecuta una vez cuando se crea una instancia de esta clase.
Public Sub Initialize
' Inicializa el mapa que asocia los códigos de tipo de columna de fecha/hora de JDBC
' con los nombres de los métodos correspondientes para leerlos correctamente.
DateTimeMethods = CreateMap(91: "getDate", 92: "getTime", 93: "getTimestamp")
End Sub
' Método principal que maneja cada petición HTTP que llega a este servlet.
Sub Handle(req As ServletRequest, resp As ServletResponse)
' === INICIO DE LA LÓGICA DINÁMICA ===
' Extrae la URI completa de la petición (ej. /DB1/endpoint).
Dim URI As String = req.RequestURI
' Variable para almacenar la "llave" o identificador de la base de datos (ej. "DB1").
Dim dbKey As String
' Comprueba si la URI tiene contenido y empieza con "/".
If URI.Length > 1 And URI.StartsWith("/") Then
' Extrae la parte de la URI que viene después del primer "/".
dbKey = URI.Substring(1)
' Si la llave contiene más "/", se queda solo con la primera parte.
' Esto permite URLs como /DB1/clientes o /DB2/productos, extrayendo "DB1" o "DB2".
If dbKey.Contains("/") Then
dbKey = dbKey.SubString2(0, dbKey.IndexOf("/"))
End If
Else
' Si la URI está vacía o es "/", usa "DB1" como la base de datos por defecto.
dbKey = "DB1"
End If
' Convierte la llave a mayúsculas para que no sea sensible a mayúsculas/minúsculas (ej. "db1" se convierte en "DB1").
dbKey = dbKey.ToUpperCase
' Verifica si la llave de la base de datos extraída existe en la configuración de conectores.
If Main.Connectors.ContainsKey(dbKey) = False Then
' Si no existe, crea un mensaje de error claro.
Dim ErrorMsg As String = $"Invalid DB key specified in URL: '${dbKey}'. Valid keys are: ${Main.listaDeCP}"$
' Registra el error en el log del servidor.
Log(ErrorMsg)
' Envía una respuesta de error 400 (Bad Request) al cliente en formato de texto plano.
SendPlainTextError(resp, 400, ErrorMsg)
' Termina la ejecución de este método.
Return
End If
' === FIN DE LA LÓGICA DINÁMICA ===
Log("********************* " & dbKey & " ********************")
' Guarda el tiempo de inicio para medir la duración de la petición.
Dim start As Long = DateTime.Now
' Variable para almacenar el nombre del comando SQL a ejecutar.
Dim q As String
' Obtiene el stream de entrada de la petición, que contiene los datos enviados por el cliente.
Dim in As InputStream = req.InputStream
' Obtiene el parámetro "method" de la URL (ej. ?method=query2).
Dim method As String = req.GetParameter("method")
' Obtiene el conector correspondiente a la base de datos seleccionada.
Connector = Main.Connectors.Get(dbKey)
' Declara la variable para la conexión a la base de datos.
Dim con As SQL
Try
' Obtiene una conexión del pool de conexiones.
con = Connector.GetConnection(dbKey)
Log("Metodo: " & method)
' Determina qué función ejecutar basándose en el parámetro "method".
If method = "query2" Then
' Ejecuta una consulta usando el protocolo más nuevo (B4XSerializator).
q = ExecuteQuery2(dbKey, con, in, resp)
'#if VERSION1
Else if method = "query" Then
' Protocolo antiguo: descomprime el stream y ejecuta la consulta.
in = cs.WrapInputStream(in, "gzip")
q = ExecuteQuery(dbKey, con, in, resp)
Else if method = "batch" Then
' Protocolo antiguo: descomprime el stream y ejecuta un lote de comandos.
in = cs.WrapInputStream(in, "gzip")
q = ExecuteBatch(dbKey, con, in, resp)
'#end if
Else if method = "batch2" Then
' Ejecuta un lote de comandos usando el protocolo más nuevo.
q = ExecuteBatch2(dbKey, con, in, resp)
Else
' Si el método es desconocido, lo registra y envía un error.
Log("Unknown method: " & method)
SendPlainTextError(resp, 500, "unknown method")
End If
Catch
' Si ocurre cualquier error en el bloque Try, lo captura.
Log(LastException)
' Envía un error 500 (Internal Server Error) al cliente con el mensaje de la excepción.
SendPlainTextError(resp, 500, LastException.Message)
End Try
' Asegura que la conexión a la BD se cierre y se devuelva al pool.
If con <> Null And con.IsInitialized Then con.Close
' Registra en el log el comando ejecutado, cuánto tiempo tardó y la IP del cliente.
Log($"Command: ${q}, took: ${DateTime.Now - start}ms, client=${req.RemoteAddress}"$)
End Sub
' Ejecuta una consulta única usando el protocolo V2 (B4XSerializator).
Private Sub ExecuteQuery2 (DB As String, con As SQL, in As InputStream, resp As ServletResponse) As String
' Objeto para deserializar los datos enviados desde el cliente.
Dim ser As B4XSerializator
' Convierte el stream de entrada a un array de bytes y luego a un objeto Mapa.
Dim m As Map = ser.ConvertBytesToObject(Bit.InputStreamToBytes(in))
' Extrae el objeto DBCommand del mapa.
Dim cmd As DBCommand = m.Get("command")
' Extrae el límite de filas a devolver.
Dim limit As Int = m.Get("limit")
' Obtiene la sentencia SQL correspondiente al nombre del comando desde config.properties.
Dim sqlCommand As String = Connector.GetCommand(DB, cmd.Name)
' <<< INICIO NUEVA VALIDACIÓN: VERIFICAR SI EL COMANDO EXISTE >>>
' Comprueba si el comando no fue encontrado en el archivo de configuración.
If sqlCommand = Null Or sqlCommand = "null" Or sqlCommand.Trim = "" Then
Dim errorMessage As String = $"El comando '${cmd.Name}' no fue encontrado en el config.properties de '${DB}'."$
Log(errorMessage)
' Envía un error 400 (Bad Request) al cliente informando del problema.
SendPlainTextError(resp, 400, errorMessage)
Return "error" ' Retorna un texto para el log.
End If
' <<< FIN NUEVA VALIDACIÓN >>>
' --- INICIO VALIDACIÓN DE PARÁMETROS ---
' Comprueba si el SQL espera parámetros o si se recibieron parámetros.
If sqlCommand.Contains("?") Or (cmd.Parameters <> Null And cmd.Parameters.Length > 0) Then
' Cuenta cuántos '?' hay en la sentencia SQL para saber cuántos parámetros se esperan.
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
' Cuenta cuántos parámetros se recibieron.
Dim receivedParams As Int
If cmd.Parameters = Null Then receivedParams = 0 Else receivedParams = cmd.Parameters.Length
' Compara el número de parámetros esperados con los recibidos.
If expectedParams <> receivedParams Then
Dim errorMessage As String = $"Número de parametros equivocado para "${cmd.Name}". Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$
Log(errorMessage)
' Si no coinciden, envía un error 400 al cliente.
SendPlainTextError(resp, 400, errorMessage)
Return "error"
End If
End If
' --- FIN VALIDACIÓN ---
' Ejecuta la consulta SQL con los parámetros proporcionados.
Dim rs As ResultSet = con.ExecQuery2(sqlCommand, cmd.Parameters)
' Si el límite es 0 o negativo, lo establece a un valor muy alto (máximo entero).
If limit <= 0 Then limit = 0x7fffffff 'max int
' Obtiene el objeto Java subyacente del ResultSet para acceder a métodos adicionales.
Dim jrs As JavaObject = rs
' Obtiene los metadatos del ResultSet (información sobre las columnas).
Dim rsmd As JavaObject = jrs.RunMethod("getMetaData", Null)
' Obtiene el número de columnas del resultado.
Dim cols As Int = rs.ColumnCount
' Crea un objeto DBResult para empaquetar la respuesta.
Dim res As DBResult
res.Initialize
res.columns.Initialize
res.Tag = Null
' Llena el mapa de columnas con el nombre de cada columna y su índice.
For i = 0 To cols - 1
res.columns.Put(rs.GetColumnName(i), i)
Next
' Inicializa la lista de filas.
res.Rows.Initialize
' Itera sobre cada fila del ResultSet, hasta llegar al límite.
Do While rs.NextRow And limit > 0
Dim row(cols) As Object
' Itera sobre cada columna de la fila actual.
For i = 0 To cols - 1
' Obtiene el tipo de dato de la columna según JDBC.
Dim ct As Int = rsmd.RunMethod("getColumnType", Array(i + 1))
' Maneja diferentes tipos de datos para leerlos de la forma correcta.
If ct = -2 Or ct = 2004 Or ct = -3 Or ct = -4 Then ' Tipos BLOB/binarios
row(i) = rs.GetBlob2(i)
Else If ct = 2005 Then ' Tipo CLOB (texto largo)
row(i) = rs.GetString2(i)
Else if ct = 2 Or ct = 3 Then ' Tipos numéricos que pueden tener decimales
row(i) = rs.GetDouble2(i)
Else If DateTimeMethods.ContainsKey(ct) Then ' Tipos de Fecha/Hora
' Obtiene el objeto de tiempo/fecha de Java.
Dim SQLTime As JavaObject = jrs.RunMethodJO(DateTimeMethods.Get(ct), Array(i + 1))
If SQLTime.IsInitialized Then
' Lo convierte a milisegundos (Long) para B4X.
row(i) = SQLTime.RunMethod("getTime", Null)
Else
row(i) = Null
End If
Else ' Para todos los demás tipos de datos
' Usa getObject que funciona para la mayoría de los tipos estándar.
row(i) = jrs.RunMethod("getObject", Array(i + 1))
End If
Next
' Añade la fila completa a la lista de resultados.
res.Rows.Add(row)
limit = limit - 1
Loop
' Cierra el ResultSet para liberar recursos.
rs.Close
' Serializa el objeto DBResult completo a un array de bytes.
Dim data() As Byte = ser.ConvertObjectToBytes(res)
' Escribe los datos serializados en el stream de respuesta.
resp.OutputStream.WriteBytes(data, 0, data.Length)
' Devuelve el nombre del comando para el log.
Return "query: " & cmd.Name
End Sub
' Ejecuta un lote de comandos (INSERT, UPDATE, DELETE) usando el protocolo V2.
Private Sub ExecuteBatch2(DB As String, con As SQL, in As InputStream, resp As ServletResponse) As String
Dim ser As B4XSerializator
' Deserializa el mapa que contiene la lista de comandos.
Dim m As Map = ser.ConvertBytesToObject(Bit.InputStreamToBytes(in))
' Obtiene la lista de objetos DBCommand.
Dim commands As List = m.Get("commands")
' Prepara un objeto DBResult para la respuesta (aunque para batch no devuelve datos, solo confirmación).
Dim res As DBResult
res.Initialize
res.columns = CreateMap("AffectedRows (N/A)": 0)
res.Rows.Initialize
res.Tag = Null
Try
' Inicia una transacción. Todos los comandos del lote se ejecutarán como una unidad.
con.BeginTransaction
' Itera sobre cada comando en la lista.
For Each cmd As DBCommand In commands
' Obtiene la sentencia SQL para el comando actual.
Dim sqlCommand As String = Connector.GetCommand(DB, cmd.Name)
' <<< INICIO NUEVA VALIDACIÓN: VERIFICAR SI EL COMANDO EXISTE DENTRO DEL BATCH >>>
If sqlCommand = Null Or sqlCommand = "null" Or sqlCommand.Trim = "" Then
con.Rollback ' Deshace la transacción si un comando es inválido.
Dim errorMessage As String = $"El comando '${cmd.Name}' no fue encontrado en el config.properties de '${DB}'."$
Log(errorMessage)
SendPlainTextError(resp, 400, errorMessage)
Return "error"
End If
' <<< FIN NUEVA VALIDACIÓN >>>
' --- INICIO VALIDACIÓN DE PARÁMETROS DENTRO DEL BATCH ---
If sqlCommand.Contains("?") Or (cmd.Parameters <> Null And cmd.Parameters.Length > 0) Then
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
Dim receivedParams As Int
If cmd.Parameters = Null Then receivedParams = 0 Else receivedParams = cmd.Parameters.Length
' Si el número de parámetros no coincide, deshace la transacción y envía error.
If expectedParams <> receivedParams Then
con.Rollback
Dim errorMessage As String = $"Número de parametros equivocado para "${cmd.Name}". Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$
Log(errorMessage)
SendPlainTextError(resp, 400, errorMessage)
Return "error"
End If
End If
' --- FIN VALIDACIÓN ---
' Ejecuta el comando (no es una consulta, no devuelve filas).
con.ExecNonQuery2(sqlCommand, cmd.Parameters)
Next
' Añade una fila simbólica al resultado para indicar éxito.
res.Rows.Add(Array As Object(0))
' Si todos los comandos se ejecutaron sin error, confirma la transacción.
con.TransactionSuccessful
Catch
' Si cualquier comando falla, se captura el error.
con.Rollback ' Se deshacen todos los cambios hechos en la transacción.
Log(LastException)
SendPlainTextError(resp, 500, LastException.Message)
End Try
' Serializa y envía la respuesta al cliente.
Dim data() As Byte = ser.ConvertObjectToBytes(res)
resp.OutputStream.WriteBytes(data, 0, data.Length)
' Devuelve un resumen para el log.
Return $"batch (size=${commands.Size})"$
End Sub
' Código compilado condicionalmente para el protocolo antiguo (V1).
'#if VERSION1
' Ejecuta un lote de comandos usando el protocolo V1.
Private Sub ExecuteBatch(DB As String, con As SQL, in As InputStream, resp As ServletResponse) As String
' Lee y descarta la versión del cliente.
Dim clientVersion As Float = ReadObject(in) 'ignore
' Lee cuántos comandos vienen en el lote.
Dim numberOfStatements As Int = ReadInt(in)
Dim res(numberOfStatements) As Int ' Array para resultados (aunque no se usa).
Try
con.BeginTransaction
' Itera para procesar cada comando del lote.
For i = 0 To numberOfStatements - 1
' Lee el nombre del comando y la lista de parámetros usando el deserializador V1.
Dim queryName As String = ReadObject(in)
Dim params As List = ReadList(in)
Dim sqlCommand As String = Connector.GetCommand(DB, queryName)
' <<< INICIO NUEVA VALIDACIÓN: VERIFICAR SI EL COMANDO EXISTE (V1) >>>
If sqlCommand = Null Or sqlCommand = "null" Or sqlCommand.Trim = "" Then
con.Rollback
Dim errorMessage As String = $"El comando '${queryName}' no fue encontrado en el config.properties de '${DB}'."$
Log(errorMessage)
SendPlainTextError(resp, 400, errorMessage)
Return "error"
End If
' <<< FIN NUEVA VALIDACIÓN >>>
' --- INICIO VALIDACIÓN DE PARÁMETROS DENTRO DEL BATCH (V1) ---
If sqlCommand.Contains("?") Or (params <> Null And params.Size > 0) Then
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
Dim receivedParams As Int
If params = Null Then receivedParams = 0 Else receivedParams = params.Size
If expectedParams <> receivedParams Then
con.Rollback
Dim errorMessage As String = $"Número de parametros equivocado para "${queryName}". Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$
Log(errorMessage)
SendPlainTextError(resp, 400, errorMessage)
Return "error"
End If
End If
' --- FIN VALIDACIÓN ---
' Ejecuta el comando.
con.ExecNonQuery2(sqlCommand, params)
Next
' Confirma la transacción.
con.TransactionSuccessful
' Comprime la salida antes de enviarla.
Dim out As OutputStream = cs.WrapOutputStream(resp.OutputStream, "gzip")
' Escribe la respuesta usando el serializador V1.
WriteObject(Main.VERSION, out)
WriteObject("batch", out)
WriteInt(res.Length, out)
For Each r As Int In res
WriteInt(r, out)
Next
out.Close
Catch
con.Rollback
Log(LastException)
SendPlainTextError(resp, 500, LastException.Message)
End Try
Return $"batch (size=${numberOfStatements})"$
End Sub
' Ejecuta una consulta única usando el protocolo V1.
Private Sub ExecuteQuery(DB As String, con As SQL, in As InputStream, resp As ServletResponse) As String
Log("====================== ExecuteQuery =====================")
' Deserializa los datos de la petición usando el protocolo V1.
Dim clientVersion As Float = ReadObject(in) 'ignore
Dim queryName As String = ReadObject(in)
Dim limit As Int = ReadInt(in)
Dim params As List = ReadList(in)
' Obtiene la sentencia SQL.
Dim theSql As String = Connector.GetCommand(DB, queryName)
Log(444 & "|" & theSql)
' <<< INICIO NUEVA VALIDACIÓN: VERIFICAR SI EL COMANDO EXISTE (V1) >>>
If theSql = Null Or theSql ="null" Or theSql.Trim = "" Then
Dim errorMessage As String = $"El comando '${queryName}' no fue encontrado en el config.properties de '${DB}'."$
Log(errorMessage)
SendPlainTextError(resp, 400, errorMessage)
Return "error"
End If
' <<< FIN NUEVA VALIDACIÓN >>>
' --- INICIO VALIDACIÓN DE PARÁMETROS (V1) ---
If theSql.Contains("?") Or (params <> Null And params.Size > 0) Then
Dim expectedParams As Int = theSql.Length - theSql.Replace("?", "").Length
Dim receivedParams As Int
If params = Null Then receivedParams = 0 Else receivedParams = params.Size
If expectedParams <> receivedParams Then
Dim errorMessage As String = $"Número de parametros equivocado para "${queryName}". Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$
Log(errorMessage)
SendPlainTextError(resp, 400, errorMessage)
Return "error"
End If
End If
' --- FIN VALIDACIÓN ---
' Ejecuta la consulta.
Dim rs As ResultSet = con.ExecQuery2(theSql, params)
If limit <= 0 Then limit = 0x7fffffff 'max int
Dim jrs As JavaObject = rs
Dim rsmd As JavaObject = jrs.RunMethod("getMetaData", Null)
Dim cols As Int = rs.ColumnCount
' Comprime el stream de salida.
Dim out As OutputStream = cs.WrapOutputStream(resp.OutputStream, "gzip")
' Escribe la cabecera de la respuesta V1.
WriteObject(Main.VERSION, out)
WriteObject("query", out)
WriteInt(rs.ColumnCount, out)
' Escribe los nombres de las columnas.
For i = 0 To cols - 1
WriteObject(rs.GetColumnName(i), out)
Next
' Itera sobre las filas del resultado.
Do While rs.NextRow And limit > 0
' Escribe un byte '1' para indicar que viene una fila.
WriteByte(1, out)
' Itera sobre las columnas de la fila.
For i = 0 To cols - 1
Dim ct As Int = rsmd.RunMethod("getColumnType", Array(i + 1))
' Maneja los tipos de datos binarios de forma especial.
If ct = -2 Or ct = 2004 Or ct = -3 Or ct = -4 Then
WriteObject(rs.GetBlob2(i), out)
Else
' Escribe el valor de la columna.
WriteObject(jrs.RunMethod("getObject", Array(i + 1)), out)
End If
Next
limit = limit - 1
Loop
' Escribe un byte '0' para indicar el fin de las filas.
WriteByte(0, out)
out.Close
rs.Close
Return "query: " & queryName
End Sub
' Escribe un único byte en el stream de salida.
Private Sub WriteByte(value As Byte, out As OutputStream)
out.WriteBytes(Array As Byte(value), 0, 1)
End Sub
' Serializador principal para el protocolo V1. Escribe un objeto al stream.
Private Sub WriteObject(o As Object, out As OutputStream)
Dim data() As Byte
' Escribe un byte de tipo seguido de los datos.
If o = Null Then
out.WriteBytes(Array As Byte(T_NULL), 0, 1)
Else If o Is Short Then
out.WriteBytes(Array As Byte(T_SHORT), 0, 1)
data = bc.ShortsToBytes(Array As Short(o))
Else If o Is Int Then
out.WriteBytes(Array As Byte(T_INT), 0, 1)
data = bc.IntsToBytes(Array As Int(o))
Else If o Is Float Then
out.WriteBytes(Array As Byte(T_FLOAT), 0, 1)
data = bc.FloatsToBytes(Array As Float(o))
Else If o Is Double Then
out.WriteBytes(Array As Byte(T_DOUBLE), 0, 1)
data = bc.DoublesToBytes(Array As Double(o))
Else If o Is Long Then
out.WriteBytes(Array As Byte(T_LONG), 0, 1)
data = bc.LongsToBytes(Array As Long(o))
Else If o Is Boolean Then
out.WriteBytes(Array As Byte(T_BOOLEAN), 0, 1)
Dim b As Boolean = o
Dim data(1) As Byte
If b Then data(0) = 1 Else data(0) = 0
Else If GetType(o) = "[B" Then ' Si el objeto es un array de bytes (BLOB)
data = o
out.WriteBytes(Array As Byte(T_BLOB), 0, 1)
' Escribe la longitud de los datos antes de los datos mismos.
WriteInt(data.Length, out)
Else ' Trata todo lo demás como un String
out.WriteBytes(Array As Byte(T_STRING), 0, 1)
data = bc.StringToBytes(o, "UTF8")
' Escribe la longitud del string antes del string.
WriteInt(data.Length, out)
End If
' Escribe los bytes del dato.
If data.Length > 0 Then out.WriteBytes(data, 0, data.Length)
End Sub
' Deserializador principal para el protocolo V1. Lee un objeto del stream.
Private Sub ReadObject(In As InputStream) As Object
' Lee el primer byte para determinar el tipo de dato.
Dim data(1) As Byte
In.ReadBytes(data, 0, 1)
Select data(0)
Case T_NULL
Return Null
Case T_SHORT
Dim data(2) As Byte
Return bc.ShortsFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_INT
Dim data(4) As Byte
Return bc.IntsFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_LONG
Dim data(8) As Byte
Return bc.LongsFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_FLOAT
Dim data(4) As Byte
Return bc.FloatsFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_DOUBLE
Dim data(8) As Byte
Return bc.DoublesFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_BOOLEAN
Dim b As Byte = ReadByte(In)
Return b = 1
Case T_BLOB
' Lee la longitud, luego lee esa cantidad de bytes.
Dim len As Int = ReadInt(In)
Dim data(len) As Byte
Return ReadBytesFully(In, data, data.Length)
Case Else ' T_STRING
' Lee la longitud, luego lee esa cantidad de bytes y los convierte a string.
Dim len As Int = ReadInt(In)
Dim data(len) As Byte
ReadBytesFully(In, data, data.Length)
Return BytesToString(data, 0, data.Length, "UTF8")
End Select
End Sub
' Se asegura de leer exactamente la cantidad de bytes solicitada del stream.
Private Sub ReadBytesFully(In As InputStream, Data() As Byte, Len As Int) As Byte()
Dim count = 0, Read As Int
' Sigue leyendo en un bucle hasta llenar el buffer, por si los datos llegan en partes.
Do While count < Len And Read > -1
Read = In.ReadBytes(Data, count, Len - count)
count = count + Read
Loop
Return Data
End Sub
' Escribe un entero (4 bytes) en el stream.
Private Sub WriteInt(i As Int, out As OutputStream)
Dim data() As Byte
data = bc.IntsToBytes(Array As Int(i))
out.WriteBytes(data, 0, data.Length)
End Sub
' Lee un entero (4 bytes) del stream.
Private Sub ReadInt(In As InputStream) As Int
Dim data(4) As Byte
Return bc.IntsFromBytes(ReadBytesFully(In, data, data.Length))(0)
End Sub
' Lee un solo byte del stream.
Private Sub ReadByte(In As InputStream) As Byte
Dim data(1) As Byte
In.ReadBytes(data, 0, 1)
Return data(0)
End Sub
' Lee una lista de objetos del stream (protocolo V1).
Private Sub ReadList(in As InputStream) As List
' Primero lee la cantidad de elementos en la lista.
Dim len As Int = ReadInt(in)
Dim l1 As List
l1.Initialize
' Luego lee cada objeto uno por uno y lo añade a la lista.
For i = 0 To len - 1
l1.Add(ReadObject(in))
Next
Return l1
End Sub
'#end If
' Envía una respuesta de error en formato de texto plano.
' Esto evita la página de error HTML por defecto que genera resp.SendError.
' resp: El objeto ServletResponse para enviar la respuesta.
' statusCode: El código de estado HTTP (ej. 400 para Bad Request, 500 para Internal Server Error).
' errorMessage: El mensaje de error que se enviará al cliente.
Private Sub SendPlainTextError(resp As ServletResponse, statusCode As Int, errorMessage As String)
Try
' Establece el código de estado HTTP (ej. 400, 500).
resp.Status = statusCode
' Define el tipo de contenido como texto plano, con codificación UTF-8 para soportar acentos.
resp.ContentType = "text/plain; charset=utf-8"
' Obtiene el OutputStream de la respuesta para escribir los datos directamente.
Dim out As OutputStream = resp.OutputStream
' Convierte el mensaje de error a un array de bytes usando UTF-8.
Dim data() As Byte = errorMessage.GetBytes("UTF8")
' Escribe los bytes en el stream de salida.
out.WriteBytes(data, 0, data.Length)
' Cierra el stream para asegurar que todos los datos se envíen correctamente.
out.Close
Catch
' Si algo falla al intentar enviar la respuesta de error, lo registra en el log
' para que no se pierda la causa original del problema.
Log("Error sending plain text error response: " & LastException)
End Try
End Sub

View File

@@ -22,7 +22,7 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
' rdcc.Initialize ' rdcc.Initialize
Private estaDB As String = "" Private estaDB As String = ""
' Log(Main.listaDeCP) ' Log(Main.listaDeCP)
resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <a href="/manager?command=rpm2">Reiniciar</a> | <a href="/manager?command=reviveBow">Revive Bow</a> | </br></br>"$) resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <br/>"$)
For i = 0 To Main.listaDeCP.Size - 1 For i = 0 To Main.listaDeCP.Size - 1
Main.Connectors.Get(Main.listaDeCP.get(i)).As(RDCConnector).Initialize(Main.listaDeCP.get(i)) Main.Connectors.Get(Main.listaDeCP.get(i)).As(RDCConnector).Initialize(Main.listaDeCP.get(i))
If Main.listaDeCP.get(i) <> "DB1" Then estaDB = "." & Main.listaDeCP.get(i) Else estaDB = "" If Main.listaDeCP.get(i) <> "DB1" Then estaDB = "." & Main.listaDeCP.get(i) Else estaDB = ""
@@ -42,7 +42,7 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
' shl.WorkingDirectory = GlobalParameters.WorkingDirectory ' shl.WorkingDirectory = GlobalParameters.WorkingDirectory
' shl.Run(-1) ' shl.Run(-1)
else If Command = "rsx" Then 'Reiniciamos el servidor DBReq else If Command = "rsx" Then 'Reiniciamos el servidor DBReq
resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <a href="/manager?command=rpm2">Reiniciar</a> | <a href="/manager?command=reviveBow">Revive Bow</a> | </br></br>"$) resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <br/>"$)
Log($"Ejecutamos ${File.DirApp}\start.bat"$) Log($"Ejecutamos ${File.DirApp}\start.bat"$)
resp.Write($"Ejecutamos ${File.DirApp}\start.bat"$) resp.Write($"Ejecutamos ${File.DirApp}\start.bat"$)
Public shl As Shell Public shl As Shell
@@ -50,22 +50,13 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
shl.WorkingDirectory = File.DirApp shl.WorkingDirectory = File.DirApp
shl.Run(-1) shl.Run(-1)
else If Command = "rpm2" Then 'Reiniciamos el proceso DBReq en PM2 else If Command = "rpm2" Then 'Reiniciamos el proceso DBReq en PM2
resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <a href="/manager?command=rpm2">Reiniciar</a> | <a href="/manager?command=reviveBow">Revive Bow</a> | </br></br>"$) resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <br/>"$)
Log($"Ejecutamos ${File.DirApp}\reiniciaProcesoPM2.bat"$) Log($"Ejecutamos ${File.DirApp}\reiniciaProcesoPM2.bat"$)
resp.Write($"Ejecutamos ${File.DirApp}\reiniciaProcesoPM2.bat"$) resp.Write($"Ejecutamos ${File.DirApp}\reiniciaProcesoPM2.bat"$)
Public shl As Shell Public shl As Shell
shl.Initialize("shl","cmd",Array("/c",File.DirApp & "\reiniciaProcesoPM2.bat " & Main.srvr.Port)) shl.Initialize("shl","cmd",Array("/c",File.DirApp & "\reiniciaProcesoPM2.bat " & Main.srvr.Port))
shl.WorkingDirectory = File.DirApp shl.WorkingDirectory = File.DirApp
shl.Run(-1) shl.Run(-1)
else If Command = "reviveBow" Then 'Reiniciamos el proceso DBReq en PM2
resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <a href="/manager?command=rpm2">Reiniciar</a> | <a href="/manager?command=reviveBow">Revive Bow</a> | </br></br>"$)
Log($"Ejecutamos ${File.DirApp}\reiniciaProcesoBow.bat"$)
resp.Write($"Ejecutamos ${File.DirApp}\reiniciaProcesoBow.bat<br><br>"$)
resp.Write($"!!!BOW REINICIANDO!!!"$)
Public shl As Shell
shl.Initialize("shl","cmd",Array("/c",File.DirApp & "\reiniciaProcesoBow.bat " & Main.srvr.Port))
shl.WorkingDirectory = File.DirApp
shl.Run(-1)
else If Command = "paused" Then else If Command = "paused" Then
GlobalParameters.IsPaused = 1 GlobalParameters.IsPaused = 1
else If Command = "continue" Then else If Command = "continue" Then

View File

@@ -19,7 +19,7 @@ Public Sub Initialize(DB As String)
' Log("RDCConnector Initialize") ' Log("RDCConnector Initialize")
If DB.EqualsIgnoreCase("DB1") Then DB = "" 'Esto para el config.properties por default If DB.EqualsIgnoreCase("DB1") Then DB = "" 'Esto para el config.properties por default
Dim config As Map = LoadConfigMap(DB) Dim config As Map = LoadConfigMap(DB)
Log($"Inicializamos ${DB}, usuario: ${config.Get("User")} - Puerto: ${config.Get("ServerPort")}"$) Log($"Inicializamos ${DB}, usuario: ${config.Get("User")}"$)
pool.Initialize(config.Get("DriverClass"), config.Get("JdbcUrl"), config.Get("User"), config.Get("Password")) pool.Initialize(config.Get("DriverClass"), config.Get("JdbcUrl"), config.Get("User"), config.Get("Password"))
Dim jo As JavaObject = pool Dim jo As JavaObject = pool
jo.RunMethod("setMaxPoolSize", Array(5)) 'number of concurrent connections jo.RunMethod("setMaxPoolSize", Array(5)) 'number of concurrent connections
@@ -72,7 +72,7 @@ Public Sub Initialize(DB As String)
' Dim jo2 As JavaObject = pool ' Dim jo2 As JavaObject = pool
' Log(jo2.GetField("END_TO_END_CLIENTID_INDEX")) ' Log(jo2.GetField("END_TO_END_CLIENTID_INDEX"))
' jo.RunMethod("setPreferredTestQuery", Array("BEGIN DBMS_SESSION.SET_IDENTIFIER('jRDC_Multi'); END;")) ' jo.RunMethod("setPreferredTestQuery", Array("BEGIN DBMS_SESSION.SET_IDENTIFIER('whatever'); END;"))
' jo.RunMethod("setPreferredTestQuery", Array("alter session set current_schema=MYSCHEMA")) ' jo.RunMethod("setPreferredTestQuery", Array("alter session set current_schema=MYSCHEMA"))
' jo2.RunMethod("setClientIdentifier",Array( "MAX")) ' Tiempo máximo de inactividad antes de cerrar una conexión ' jo2.RunMethod("setClientIdentifier",Array( "MAX")) ' Tiempo máximo de inactividad antes de cerrar una conexión
#if DEBUG #if DEBUG
@@ -88,32 +88,33 @@ End Sub
Private Sub LoadConfigMap(DB As String) As Map Private Sub LoadConfigMap(DB As String) As Map
Private DBX As String = "" Private DBX As String = ""
If DB <> "" Then DBX = "." & DB If DB <> "" Then DBX = "." & DB
Log("============= LoadConfigMap =============") Log("===========================================")
Log($""========= Leemos el config${DBX}.properties ========="$) Log($"Leemos el config${DBX}.properties"$)
Return File.ReadMap("./", "config" & DBX & ".properties") Return File.ReadMap("./", "config" & DBX & ".properties")
End Sub End Sub
Public Sub GetCommand(DB As String, Key As String) As String Public Sub GetCommand(DB As String, Key As String) As String
' Log("==== GetCommand ====") Log("==== GetCommand ====")
' Log("|" & Key & "|") ' Log("|" & DB & "|" & Key & "|")
commands = Main.commandsMap.get(DB).As(Map) commands = Main.commandsMap.get(DB).As(Map)
If commands.ContainsKey("sql." & Key) = False Then If commands.ContainsKey("sql." & Key) = False Then
Log("*** Command not found: " & Key) Log("*** Command not found: " & Key)
End If End If
' Log(commands.ContainsKey("sql." & Key))
Log("========= Traemos """ & Key & """ ==========") Log("========= Traemos """ & Key & """ ==========")
Log(">>>>>> " & commands.Get("sql." & Key) & " <<<<<<") Log(">>>>>> " & commands.Get("sql." & Key) & " <<<<<<")
Return commands.Get("sql." & Key) Return commands.Get("sql." & Key)
End Sub End Sub
Public Sub GetConnection(DB As String) As SQL Public Sub GetConnection(DB As String) As SQL
Log("============= GetConnection ============= ") Log("==== GetConnection ==== ")
If DB.EqualsIgnoreCase("DB1") Then DB = "" 'Esto para el config.properties or default If DB.EqualsIgnoreCase("DB1") Then DB = "" 'Esto para el config.properties or default
If DebugQueries Then LoadSQLCommands(LoadConfigMap(DB), DB) If DebugQueries Then LoadSQLCommands(LoadConfigMap(DB), DB)
' Log("regresamos 0")
Return pool.GetConnection Return pool.GetConnection
End Sub End Sub
Private Sub LoadSQLCommands(config2 As Map, DB As String) Private Sub LoadSQLCommands(config2 As Map, DB As String)
Log("==== LoadSQLCommands ==== ")
Log($"Cargamos los comandos desde el config.${DB}.properties"$) Log($"Cargamos los comandos desde el config.${DB}.properties"$)
Dim newCommands As Map Dim newCommands As Map
newCommands.Initialize newCommands.Initialize
@@ -123,7 +124,6 @@ Private Sub LoadSQLCommands(config2 As Map, DB As String)
End If End If
Next Next
commands = newCommands commands = newCommands
' Log(commands)
' Log($"Inicializado: ${DB} "$ & Main.commandsMap.IsInitialized) ' Log($"Inicializado: ${DB} "$ & Main.commandsMap.IsInitialized)
Main.commandsMap.Put(DB, commands) Main.commandsMap.Put(DB, commands)
End Sub End Sub

View File

@@ -1,48 +1,41 @@
# jRDC-Multi (B4J) # Servidor jRDC2-Multi Modificado (B4J)
Servidor de DBRequest que puede cargar hasta 4 archivos de config.properties al mismo tiempo.
Los archivos se deben de llamar: ## 1. Introducción
- config.propierties Este proyecto es una versión modificada del servidor [jRDC2 original](https://www.b4x.com/android/forum/threads/b4x-jrdc2-b4j-implementation-of-rdc-remote-database-connector.61801/#content), diseñada para actuar como un backend robusto y flexible. Su función principal es recibir peticiones HTTP, ejecutar comandos SQL predefinidos contra una base de datos y devolver los resultados en un formato estructurado.
- config.DB2.properties
- config.DB3.properties
- config.DB4.properties
No es necesario que sean 4 archivos, solo toma en cuenta los archivos existentes en el directorio. Ha sido adaptado para servir tanto a clientes nativos (B4A/B4i) como a clientes web modernos (JavaScript, a través de frameworks como React, Vue, Angular, etc.).
En la aplicacion movil, al URL del servidor se le agrega al final /DB2, /DB3 o /DB4. (Puerto de ejemplo: 1781) ## 2. Características Principales
- Para usar el config.properties => http://keymon.lat:1781 * **Soporte para Múltiples Bases de Datos**: Puede cargar y gestionar hasta 4 archivos de configuración (`config.properties`) simultáneamente.
- Para usar el config.DB2.properties => http://keymon.lat:1781/DB2 * **Comandos SQL Externalizados**: Las sentencias SQL se definen en los archivos de configuración, permitiendo modificarlas sin recompilar el servidor.
- Para usar el config.DB3.properties => http://keymon.lat:1781/DB3 * **Doble Handler de Peticiones**: Incluye un handler clásico para clientes B4X y un handler JSON para clientes web.
- Para usar el config.DB4.properties => http://keymon.lat:1781/DB4 * **Validaciones de Seguridad**: Verifica la existencia de comandos y la correspondencia en el número de parámetros.
* **Administración Remota**: Permite verificar el estado, recargar la configuración y reiniciar el servidor a través de URLs específicas.
El puerto es el mismo para todos los archivos, **sin importar** que diga en cada archivo, solo toma el puerto especificado en el **primer** config.properties. ## 3. Configuración
El usuario, contraseña y JdbcUrl, **si** los toma del archivo correspondiente. ### 3.1. Archivos de Configuración
Se puede revisar el **estatus** del servidor en el URL: El sistema está preparado para manejar hasta **cuatro configuraciones de bases de datos** (de `DB1` a `DB4`). No es necesario tener los cuatro archivos; el servidor cargará únicamente los que encuentre.
- http://keymon.lat:1781/test La nomenclatura de los archivos es fundamental:
Se puede forzar al servidor (**sin reiniciarlo**) a que **recargue** los archivos config.properties en el URL: * `config.properties` (para `DB1`)
* `config.DB2.properties`
* `config.DB3.properties`
* `config.DB4.properties`
- http://keymon.lat:1781/manager?command=reload **Notas importantes:**
Se puede reiniciar el servidor con el URL: * El **puerto** del servidor se toma **únicamente** del archivo principal `config.properties`, sin importar lo que digan los demás.
* Los datos de conexión (`JdbcUrl`, usuario, contraseña) sí se toman del archivo correspondiente a cada base de datos.
- http://keymon.lat:1781/manager?command=rsx ### 3.2. Añadir Drivers de Bases de Datos Adicionales
- Este comando utiliza los archivos start.bat, start2.bat y stop.bat
Si se esta corriendo el servidor con PM2, se puede reinciar con el URL: Si necesitas conectarte a otros tipos de bases de datos (ej. Oracle), debes agregar el archivo del controlador `.jar` al proyecto antes de compilar. En el módulo `Main`, añade una línea como la siguiente:
- http://keymon.lat:1781/manager?command=rpm2 ```b4x
- Este comando ejecuta el archivo reiniciaProcesoPM2.bat, y **asume** que el nombre del proceso es "RDC-Multi", si no es asi, hay que **modificar** el archivo .bat ' Este es el nombre del archivo .jar, en este caso "C:\Ruta\Adicional\ojdbc11.jar"
#AdditionalJar: ojdbc11
## Agregar drivers de mas bases de datos
Si se necesitan agregar mas controladores para conectarse a otras bases de datos, hay que agregar una linea a "Main":
- #AdditionalJar: ojdbc11 <= este es el nombre del archivo .jar, en este caso "C:\Android\AdditionalLibs\B4J\ojdbc11.jar"
- Al compilar la aplicación, el archivo del controlador se incluye en el archivo .jar del servidor (jRDC-Multi.jar) y no es necesario copiarlo o agregarlo al directorio del servidor en producción.

48
README0.md Normal file
View File

@@ -0,0 +1,48 @@
# jRDC-Multi (B4J)
Servidor de DBRequest que puede cargar hasta 4 archivos de config.properties al mismo tiempo.
Los archivos se deben de llamar:
- config.propierties
- config.DB2.properties
- config.DB3.properties
- config.DB4.properties
No es necesario que sean 4 archivos, solo toma en cuenta los archivos existentes en el directorio.
En la aplicacion movil, al URL del servidor se le agrega al final /DB2, /DB3 o /DB4. (Puerto de ejemplo: 1781)
- Para usar el config.properties => http://keymon.lat:1781
- Para usar el config.DB2.properties => http://keymon.lat:1781/DB2
- Para usar el config.DB3.properties => http://keymon.lat:1781/DB3
- Para usar el config.DB4.properties => http://keymon.lat:1781/DB4
El puerto es el mismo para todos los archivos, **sin importar** que diga en cada archivo, solo toma el puerto especificado en el **primer** config.properties.
El usuario, contraseña y JdbcUrl, **si** los toma del archivo correspondiente.
Se puede revisar el **estatus** del servidor en el URL:
- http://keymon.lat:1781/test
Se puede forzar al servidor (**sin reiniciarlo**) a que **recargue** los archivos config.properties en el URL:
- http://keymon.lat:1781/manager?command=reload
Se puede reiniciar el servidor con el URL:
- http://keymon.lat:1781/manager?command=rsx
- Este comando utiliza los archivos start.bat, start2.bat y stop.bat
Si se esta corriendo el servidor con PM2, se puede reinciar con el URL:
- http://keymon.lat:1781/manager?command=rpm2
- Este comando ejecuta el archivo reiniciaProcesoPM2.bat, y **asume** que el nombre del proceso es "RDC-Multi", si no es asi, hay que **modificar** el archivo .bat
## Agregar drivers de mas bases de datos
Si se necesitan agregar mas controladores para conectarse a otras bases de datos, hay que agregar una linea a "Main":
- #AdditionalJar: ojdbc11 <= este es el nombre del archivo .jar, en este caso "C:\Android\AdditionalLibs\B4J\ojdbc11.jar"
- Al compilar la aplicación, el archivo del controlador se incluye en el archivo .jar del servidor (jRDC-Multi.jar) y no es necesario copiarlo o agregarlo al directorio del servidor en producción.

View File

@@ -16,7 +16,7 @@ End Sub
Sub Handle(req As ServletRequest, resp As ServletResponse) Sub Handle(req As ServletRequest, resp As ServletResponse)
Log("TEST") Log("TEST")
resp.ContentType = "text/html" resp.ContentType = "text/html"
resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <a href="/manager?command=rpm2">Reiniciar</a> | <a href="/manager?command=reviveBow">Revive Bow</a> | </br></br>"$) resp.Write($"<a href="/test">Test</a> | <a href="/manager?command=reload">Reload</a> | <br/>"$)
resp.Write($"RemoteServer is running on port <strong>${Main.srvr.Port}</strong> ($DateTime{DateTime.Now})<br/>"$) resp.Write($"RemoteServer is running on port <strong>${Main.srvr.Port}</strong> ($DateTime{DateTime.Now})<br/>"$)
Try Try
' Dim con As SQL = Main.rdcConnectorDB1.GetConnection("") ' Dim con As SQL = Main.rdcConnectorDB1.GetConnection("")

View File

@@ -1,77 +0,0 @@
#Lines starting with '#' are comments.
#Backslash character at the end of line means that the command continues in the next line.
DriverClass=oracle.jdbc.driver.OracleDriver
#JdbcUrl=jdbc:mysql://localhost/test?characterEncoding=utf8
#SQL Server
#DriverClass=net.sourceforge.jtds.jdbc.Driver
# este para produccion GHAN JdbcUrl=jdbc:oracle:thin:@//192.168.15.53:1521/DBKMT
#GOHAN ---> server
#JdbcUrl=jdbc:oracle:thin:@//10.0.0.205:1521/DBKMT
#JdbcUrl=jdbc:oracle:thin:@//10.0.0.236:1521/DBKMT
JdbcUrl=jdbc:oracle:thin:@//192.168.101.13:1521/DBKMT
# SVR-KEYMON-PRODUCCION--> Usuario
User=SALMA
Password=SALMAD2016M
#User=TORRADOCONAUTO
#Password=TORRADOCONAUTOD2016M
#--> Puertos
#SAC - DFR - MDA / GOHAN -->COBRANZA
#ServerPort=1783
#GUNA - SALMA - DURAKELO - DBC / SVR-KEYMON-PRODUCCION --> DISTRIBUIDORAS
ServerPort=9010
#CMG - TORRADO / TRUNKS -->COBRANZA/ GM
#ServerPort=1781
#If Debug is true then this file will be reloaded on every query.
#This is useful if you need to modify the queries.
Debug=true
#SQL COMMANDS
##################
#################
################ S O P O R T E
#################
##################
sql.traeConexion=select 'DB2' as conexion from dual
sql.select_soporte=select * from GUNA.soporte
sql.select_conexion=SELECT 'OK' AS VALOR FROM DUAL
sql.select_almacenes_KELL=select CAT_AG_ID, CAT_AG_NOMBRE from KELLOGGS.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_GUNA=select CAT_AG_ID, CAT_AG_NOMBRE from GUNA.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_SALMA=select CAT_AG_ID, CAT_AG_NOMBRE from SALMA.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_DANVIT=select CAT_AG_ID, CAT_AG_NOMBRE from DANVIT.cat_agencias order by CAT_AG_NOMBRE
sql.proc_QUITAR_VENTA_KELL=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_QUITAR_VENTA_X_TIPO( '''||(?)||''', '''||(?)||''', '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_VENTA_GUNA=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN GUNA.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS, '''||(?)||'''); end;'); END;
sql.proc_QUITAR_VENTA_SALMA=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN SALMA.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_VENTA_DANVIT=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN DANVIT.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_PAGOPAGARE_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_ELIMINAS_PAGOS_PAGARES_REP( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_LIBERA_BANDERA_FACTURACION_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_LIBERA_FACTURACION(Cursor_SYS); end;'); END;
sql.proc_LIBERA_BANDERA_CARGAFORANEA_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_LLENAR_FILTROS ( '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_TICKET_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_QUITAR_TICKET( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.revisa_liquidada_Guna=SELECT COUNT(*) as liquidada FROM GUNA.HIST_VENTAS_DETALLE WHERE trunc(HVD_DTESYNC) = trunc(sysdate) and hvd_almacen = (?) and hvd_ruta = (?) AND (HVD_DESCUENTO != 0 or HVD_FECHA_AVION IS NOT NULL)
sql.revisa_liquidada_Kell=SELECT COUNT(*) as liquidada FROM KELLOGGS.HIST_VENTAS_DETALLE WHERE trunc(HVD_DTESYNC) = trunc(sysdate) and hvd_almacen = (?) and hvd_ruta = (?) and HVD_TIPOVENTA = (?) AND HVD_ESTATUS = 'Liquidado'
sql.select_todos_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_lo_ruta from cat_logins left join cat_agencias on cat_lo_agencia = cat_ag_id where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_lo_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosGUNA_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from cat_logins left join cat_agencias on cat_lo_agencia = cat_ag_id left join cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosKELLOGGS_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from KELLOGGS.cat_logins left join KELLOGGS.cat_agencias on cat_lo_agencia = cat_ag_id left join KELLOGGS.cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosSALMA_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_lo_ruta as cat_ru_ruta from SALMA.cat_logins left join SALMA.cat_agencias on cat_lo_agencia = cat_ag_id where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_lo_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosDANVIT_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from DANVIT.cat_logins left join DANVIT.cat_agencias on cat_lo_agencia = cat_ag_id left join DANVIT.cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_ventaXrutaGuna_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaKelloggs_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from KELLOGGS.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) and hvd_tipoventa=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaSalma_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from SALMA.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaDanvit_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from DANVIT.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_prodsTicket_Kelloggs=SELECT HVD_CLIENTE CLIENTE, HVD_PROID PRODUCTO_ID, HVD_PRONOMBRE NOMBRE_PRODUCTO, HVD_CANT CANTIDAD, HVD_COSTO_TOT COSTO_TOTAL, HVD_RUTA RUTA, HVD_CODPROMO CODPROMO,NVL(HVD_TIPOVENTA,' ') TIPOVENTA, NVL(HVD_ESTATUS,' ') ESTATUS, hvd_cedis FROM KELLOGGS.HIST_VENTAS_DETALLE WHERE TRUNC(HVD_FECHA) = TRUNC(SYSDATE) AND HVD_ALMACEN = (?) AND HVD_CLIENTE = (?) and hvd_rechazo is null ORDER BY HVD_CODPROMO, HVD_PRONOMBRE

View File

@@ -1,76 +0,0 @@
#Lines starting with '#' are comments.
#Backslash character at the end of line means that the command continues in the next line.
DriverClass=oracle.jdbc.driver.OracleDriver
#JdbcUrl=jdbc:mysql://localhost/test?characterEncoding=utf8
#SQL Server
#DriverClass=net.sourceforge.jtds.jdbc.Driver
# este para produccion GHAN JdbcUrl=jdbc:oracle:thin:@//192.168.15.53:1521/DBKMT
#GOHAN ---> server
#JdbcUrl=jdbc:oracle:thin:@//10.0.0.205:1521/DBKMT
#JdbcUrl=jdbc:oracle:thin:@//10.0.0.236:1521/DBKMT
JdbcUrl=jdbc:oracle:thin:@//192.168.101.12:1521/DBKMT
# SVR-KEYMON-PRODUCCION--> Usuario
#User=GUNA
#Password=GUNAD2015M
User=TORRADOCONAUTO
Password=TORRADOCONAUTOD2016M
#--> Puertos
#SAC - DFR - MDA / GOHAN -->COBRANZA
#ServerPort=1783
#GUNA - SALMA - DURAKELO - DBC / SVR-KEYMON-PRODUCCION --> DISTRIBUIDORAS
ServerPort=9010
#CMG - TORRADO / TRUNKS -->COBRANZA/ GM
#ServerPort=1781
#If Debug is true then this file will be reloaded on every query.
#This is useful if you need to modify the queries.
Debug=true
#SQL COMMANDS
##################
#################
################ S O P O R T E
#################
##################
sql.traeConexion=select 'DB3' as conexion from dual
sql.select_soporte=select * from GUNA.soporte
sql.select_almacenes_KELL=select CAT_AG_ID, CAT_AG_NOMBRE from KELLOGGS.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_GUNA=select CAT_AG_ID, CAT_AG_NOMBRE from GUNA.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_SALMA=select CAT_AG_ID, CAT_AG_NOMBRE from SALMA.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_DANVIT=select CAT_AG_ID, CAT_AG_NOMBRE from DANVIT.cat_agencias order by CAT_AG_NOMBRE
sql.proc_QUITAR_VENTA_KELL=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_QUITAR_VENTA_X_TIPO( '''||(?)||''', '''||(?)||''', '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_VENTA_GUNA=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN GUNA.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS, '''||(?)||'''); end;'); END;
sql.proc_QUITAR_VENTA_SALMA=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN SALMA.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_VENTA_DANVIT=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN DANVIT.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_PAGOPAGARE_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_ELIMINAS_PAGOS_PAGARES_REP( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_LIBERA_BANDERA_FACTURACION_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_LIBERA_FACTURACION(Cursor_SYS); end;'); END;
sql.proc_LIBERA_BANDERA_CARGAFORANEA_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_LLENAR_FILTROS ( '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_TICKET_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_QUITAR_TICKET( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.revisa_liquidada_Guna=SELECT COUNT(*) as liquidada FROM GUNA.HIST_VENTAS_DETALLE WHERE trunc(HVD_DTESYNC) = trunc(sysdate) and hvd_almacen = (?) and hvd_ruta = (?) AND (HVD_DESCUENTO != 0 or HVD_FECHA_AVION IS NOT NULL)
sql.revisa_liquidada_Kell=SELECT COUNT(*) as liquidada FROM KELLOGGS.HIST_VENTAS_DETALLE WHERE trunc(HVD_DTESYNC) = trunc(sysdate) and hvd_almacen = (?) and hvd_ruta = (?) and HVD_TIPOVENTA = (?) AND HVD_ESTATUS = 'Liquidado'
sql.select_todos_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_lo_ruta from cat_logins left join cat_agencias on cat_lo_agencia = cat_ag_id where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_lo_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosGUNA_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from cat_logins left join cat_agencias on cat_lo_agencia = cat_ag_id left join cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosKELLOGGS_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from KELLOGGS.cat_logins left join KELLOGGS.cat_agencias on cat_lo_agencia = cat_ag_id left join KELLOGGS.cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosSALMA_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_lo_ruta as cat_ru_ruta from SALMA.cat_logins left join SALMA.cat_agencias on cat_lo_agencia = cat_ag_id where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_lo_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosDANVIT_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from DANVIT.cat_logins left join DANVIT.cat_agencias on cat_lo_agencia = cat_ag_id left join DANVIT.cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_ventaXrutaGuna_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaKelloggs_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from KELLOGGS.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) and hvd_tipoventa=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaSalma_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from SALMA.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaDanvit_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from DANVIT.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_prodsTicket_Kelloggs=SELECT HVD_CLIENTE CLIENTE, HVD_PROID PRODUCTO_ID, HVD_PRONOMBRE NOMBRE_PRODUCTO, HVD_CANT CANTIDAD, HVD_COSTO_TOT COSTO_TOTAL, HVD_RUTA RUTA, HVD_CODPROMO CODPROMO,NVL(HVD_TIPOVENTA,' ') TIPOVENTA, NVL(HVD_ESTATUS,' ') ESTATUS, hvd_cedis FROM KELLOGGS.HIST_VENTAS_DETALLE WHERE TRUNC(HVD_FECHA) = TRUNC(SYSDATE) AND HVD_ALMACEN = (?) AND HVD_CLIENTE = (?) and hvd_rechazo is null ORDER BY HVD_CODPROMO, HVD_PRONOMBRE

View File

@@ -1,77 +0,0 @@
#Lines starting with '#' are comments.
#Backslash character at the end of line means that the command continues in the next line.
DriverClass=oracle.jdbc.driver.OracleDriver
#JdbcUrl=jdbc:mysql://localhost/test?characterEncoding=utf8
#SQL Server
#DriverClass=net.sourceforge.jtds.jdbc.Driver
# este para produccion GHAN JdbcUrl=jdbc:oracle:thin:@//192.168.15.53:1521/DBKMT
#GOHAN ---> server
#JdbcUrl=jdbc:oracle:thin:@//10.0.0.205:1521/DBKMT
#JdbcUrl=jdbc:oracle:thin:@//10.0.0.236:1521/DBKMT
JdbcUrl=jdbc:oracle:thin:@//192.168.101.13:1521/DBKMT
# SVR-KEYMON-PRODUCCION--> Usuario
User=SALMA
Password=SALMAD2016M
#User=TORRADOCONAUTO
#Password=TORRADOCONAUTOD2016M
#--> Puertos
#SAC - DFR - MDA / GOHAN -->COBRANZA
#ServerPort=1783
#GUNA - SALMA - DURAKELO - DBC / SVR-KEYMON-PRODUCCION --> DISTRIBUIDORAS
ServerPort=9000
#CMG - TORRADO / TRUNKS -->COBRANZA/ GM
#ServerPort=1781
#If Debug is true then this file will be reloaded on every query.
#This is useful if you need to modify the queries.
Debug=true
#SQL COMMANDS
##################
#################
################ S O P O R T E
#################
##################
sql.traeConexion=select 'DB4' as conexion from dual
sql.select_soporte=select * from GUNA.soporte
sql.select_conexion=SELECT 'OK' AS VALOR FROM DUAL
sql.select_almacenes_KELL=select CAT_AG_ID, CAT_AG_NOMBRE from KELLOGGS.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_GUNA=select CAT_AG_ID, CAT_AG_NOMBRE from GUNA.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_SALMA=select CAT_AG_ID, CAT_AG_NOMBRE from SALMA.cat_agencias order by CAT_AG_NOMBRE
sql.select_almacenes_DANVIT=select CAT_AG_ID, CAT_AG_NOMBRE from DANVIT.cat_agencias order by CAT_AG_NOMBRE
sql.proc_QUITAR_VENTA_KELL=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_QUITAR_VENTA_X_TIPO( '''||(?)||''', '''||(?)||''', '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_VENTA_GUNA=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN GUNA.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS, '''||(?)||'''); end;'); END;
sql.proc_QUITAR_VENTA_SALMA=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN SALMA.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_VENTA_DANVIT=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN DANVIT.SP_QUITAR_VENTA( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_PAGOPAGARE_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_ELIMINAS_PAGOS_PAGARES_REP( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_LIBERA_BANDERA_FACTURACION_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_LIBERA_FACTURACION(Cursor_SYS); end;'); END;
sql.proc_LIBERA_BANDERA_CARGAFORANEA_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_LLENAR_FILTROS ( '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.proc_QUITAR_TICKET_KELLOGGS=BEGIN EXECUTE IMMEDIATE ('DECLARE Cursor_SYS Sys_Refcursor; BEGIN KELLOGGS.SP_QUITAR_TICKET( '''||(?)||''', '''||(?)||''', '''||(?)||''', Cursor_SYS); end;'); END;
sql.revisa_liquidada_Guna=SELECT COUNT(*) as liquidada FROM GUNA.HIST_VENTAS_DETALLE WHERE trunc(HVD_DTESYNC) = trunc(sysdate) and hvd_almacen = (?) and hvd_ruta = (?) AND (HVD_DESCUENTO != 0 or HVD_FECHA_AVION IS NOT NULL)
sql.revisa_liquidada_Kell=SELECT COUNT(*) as liquidada FROM KELLOGGS.HIST_VENTAS_DETALLE WHERE trunc(HVD_DTESYNC) = trunc(sysdate) and hvd_almacen = (?) and hvd_ruta = (?) and HVD_TIPOVENTA = (?) AND HVD_ESTATUS = 'Liquidado'
sql.select_todos_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_lo_ruta from cat_logins left join cat_agencias on cat_lo_agencia = cat_ag_id where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_lo_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosGUNA_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from cat_logins left join cat_agencias on cat_lo_agencia = cat_ag_id left join cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosKELLOGGS_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from KELLOGGS.cat_logins left join KELLOGGS.cat_agencias on cat_lo_agencia = cat_ag_id left join KELLOGGS.cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosSALMA_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_lo_ruta as cat_ru_ruta from SALMA.cat_logins left join SALMA.cat_agencias on cat_lo_agencia = cat_ag_id where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_lo_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_todosDANVIT_soporte=select cat_lo_usuario, cat_lo_estatus, cat_lo_nombre, cat_lo_contrasena, cat_lo_agencia, cat_agencias.cat_ag_nombre, cat_ru_ruta from DANVIT.cat_logins left join DANVIT.cat_agencias on cat_lo_agencia = cat_ag_id left join DANVIT.cat_rutas on cat_lo_usuario = cat_ru_vendedor where (cat_lo_usuario LIKE ('%'||(?)||'%') or cat_lo_nombre LIKE ('%'||(?)||'%')) and cat_ag_nombre LIKE ('%'||(?)||'%') and cat_ru_ruta LIKE ('%'||(?)||'%') and rownum <= 20
sql.select_ventaXrutaGuna_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaKelloggs_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from KELLOGGS.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) and hvd_tipoventa=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaSalma_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from SALMA.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_ventaXrutaDanvit_soporte=select hvd_ruta, sum(hvd_costo_tot) as monto, hvd_tipoventa from DANVIT.hist_ventas_detalle where trunc(hvd_fecha)=trunc(sysdate) and hvd_ruta=(?) and hvd_almacen=(?) AND hvd_codpromo <> 'BASICA' group by hvd_ruta, hvd_tipoventa
sql.select_prodsTicket_Kelloggs=SELECT HVD_CLIENTE CLIENTE, HVD_PROID PRODUCTO_ID, HVD_PRONOMBRE NOMBRE_PRODUCTO, HVD_CANT CANTIDAD, HVD_COSTO_TOT COSTO_TOTAL, HVD_RUTA RUTA, HVD_CODPROMO CODPROMO,NVL(HVD_TIPOVENTA,' ') TIPOVENTA, NVL(HVD_ESTATUS,' ') ESTATUS, hvd_cedis FROM KELLOGGS.HIST_VENTAS_DETALLE WHERE TRUNC(HVD_FECHA) = TRUNC(SYSDATE) AND HVD_ALMACEN = (?) AND HVD_CLIENTE = (?) and hvd_rechazo is null ORDER BY HVD_CODPROMO, HVD_PRONOMBRE

View File

@@ -1,49 +0,0 @@
#Lines starting with '#' are comments.
#Backslash character at the end of line means that the command continues in the next line.
DriverClass=oracle.jdbc.driver.OracleDriver
#JdbcUrl=jdbc:mysql://localhost/test?characterEncoding=utf8
#SQL Server
#DriverClass=net.sourceforge.jtds.jdbc.Driver
# este para produccion GHAN JdbcUrl=jdbc:oracle:thin:@//192.168.15.53:1521/DBKMT
#GOHAN ---> server
#JdbcUrl=jdbc:oracle:thin:@//10.0.0.205:1521/DBKMT
#JdbcUrl=jdbc:oracle:thin:@//10.0.0.236:1521/DBKMT
JdbcUrl=jdbc:oracle:thin:@//192.168.101.10:1521/DBKMT?oracle.jdbc.defaultClientIdentifier=jRDC_Multi
# SVR-KEYMON-PRODUCCION--> Usuario
User=GUNA
Password=GUNAD2015M
#User=TORRADOCONAUTO
#Password=TORRADOCONAUTOD2016M
#--> Puertos
#SAC - DFR - MDA / GOHAN -->COBRANZA
#ServerPort=1783
#GUNA - SALMA - DURAKELO - DBC / SVR-KEYMON-PRODUCCION --> DISTRIBUIDORAS
ServerPort=9010
#CMG - TORRADO / TRUNKS -->COBRANZA/ GM
#ServerPort=1781
#If Debug is true then this file will be reloaded on every query.
#This is useful if you need to modify the queries.
Debug=true
#SQL COMMANDS
##################
#################
################ S O P O R T E
#################
##################
sql.select_revisaClienteCredito_GUNA2=select (select count(CAT_CL_CODIGO) from GUNA.CAT_CLIENTES where CAT_CL_CODIGO = ? and CAT_CL_IDALMACEN <> '100') as cuantos, (select count(ID_CLIENTE) from GUNA.CAT_CLIENTES_CREDITO where ID_CLIENTE = ?) as cuantosCredito from DUAL
sql.traeConexion=select 'DB1' as conexion from dual
sql.select_soporte=select * from GUNA.soporte
sql.select_conexion=SELECT 'OK' AS VALOR FROM DUAL

View File

@@ -3,22 +3,22 @@ Build1=Default,b4j.JRDCMulti
File1=config.properties File1=config.properties
FileGroup1=Default Group FileGroup1=Default Group
Group=Default Group Group=Default Group
Library1=byteconverter Library1=javaobject
Library2=javaobject Library2=jcore
Library3=jcore Library3=jrandomaccessfile
Library4=jrandomaccessfile Library4=jserver
Library5=jserver Library5=jshell
Library6=jshell Library6=json
Library7=json Library7=jsql
Library8=jsql Library8=byteconverter
Module1=DB1Handler Module1=DB1Handler
Module10=RDCConnector Module10=RDCConnector
Module11=TestHandler Module11=TestHandler
Module2=DB1JsonHandler Module2=DB1JsonHandler
Module3=DB2Handler Module3=DB2Handler
Module4=DB2JsonHandler Module4=DB3Handler
Module5=DB3Handler Module5=DB4Handler
Module6=DB4Handler Module6=DBHandlerGenerico
Module7=GlobalParameters Module7=GlobalParameters
Module8=Manager Module8=Manager
Module9=ping Module9=ping
@@ -31,7 +31,7 @@ Version=10.3
#Region Project Attributes #Region Project Attributes
#CommandLineArgs: #CommandLineArgs:
#MergeLibraries: True #MergeLibraries: True
' VERSION 5.08.02 ' VERSION 5.08.30
'########################################################################################################### '###########################################################################################################
'###################### PULL ############################################################# '###################### PULL #############################################################
'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull 'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull
@@ -51,13 +51,12 @@ Version=10.3
Sub Process_Globals Sub Process_Globals
Public srvr As Server Public srvr As Server
Public const VERSION As String = "5.08.12" Public const VERSION As Float = 2.23
Type DBCommand (Name As String, Parameters() As Object) Type DBCommand (Name As String, Parameters() As Object)
Type DBResult (Tag As Object, Columns As Map, Rows As List) Type DBResult (Tag As Object, Columns As Map, Rows As List)
Dim listaDeCP As List Dim listaDeCP As List
Dim cpFiles As List Dim cpFiles As List
Public Connectors, commandsMap As Map Public Connectors, commandsMap As Map
Dim onPing As Boolean = False
End Sub End Sub
Sub AppStart (Args() As String) Sub AppStart (Args() As String)
@@ -96,20 +95,23 @@ Sub AppStart (Args() As String)
srvr.AddHandler("/ping", "ping", False) ' Agrega un manejador a la ruta "/test", asignando las solicitudes a la clase TestHandler, el último parámetro indica si el manejador debe ejecutar en un nuevo hilo (False en este caso) srvr.AddHandler("/ping", "ping", False) ' Agrega un manejador a la ruta "/test", asignando las solicitudes a la clase TestHandler, el último parámetro indica si el manejador debe ejecutar en un nuevo hilo (False en este caso)
srvr.AddHandler("/test", "TestHandler", False) ' Agrega un manejador a la ruta "/test", asignando las solicitudes a la clase TestHandler, el último parámetro indica si el manejador debe ejecutar en un nuevo hilo (False en este caso) srvr.AddHandler("/test", "TestHandler", False) ' Agrega un manejador a la ruta "/test", asignando las solicitudes a la clase TestHandler, el último parámetro indica si el manejador debe ejecutar en un nuevo hilo (False en este caso)
srvr.AddHandler("/manager", "Manager", False) srvr.AddHandler("/manager", "Manager", False)
srvr.AddHandler("/db1", "DB1Handler", False) ' srvr.AddHandler("/db1", "DB1Handler", False)
srvr.AddHandler("/DB1", "DB1Handler", False) ' srvr.AddHandler("/DB1", "DB1Handler", False)
srvr.AddHandler("/db2", "DB2Handler", False) ' srvr.AddHandler("/db2", "DB2Handler", False)
srvr.AddHandler("/DB2", "DB2Handler", False) ' srvr.AddHandler("/DB2", "DB2Handler", False)
srvr.AddHandler("/db3", "DB3Handler", False) ' srvr.AddHandler("/db3", "DB3Handler", False)
srvr.AddHandler("/DB3", "DB3Handler", False) ' srvr.AddHandler("/DB3", "DB3Handler", False)
srvr.AddHandler("/db4", "DB4Handler", False) ' srvr.AddHandler("/db4", "DB4Handler", False)
srvr.AddHandler("/DB4", "DB4Handler", False) ' srvr.AddHandler("/DB4", "DB4Handler", False)
srvr.AddHandler("/DBJ", "DB1JsonHandler", False) srvr.AddHandler("/DBJ", "DB1JsonHandler", False)
srvr.AddHandler("/dbrquery", "DB1JsonHandler", False) srvr.AddHandler("/dbrquery", "DB1JsonHandler", False)
srvr.AddHandler("/*", "DB1Handler", False) ' Si no se especifica una base de datos, entonces asignamos la solicitud a la DB1. ' srvr.AddHandler("/*", "DB1Handler", False) ' Si no se especifica una base de datos, entonces asignamos la solicitud a la DB1.
srvr.AddHandler("/*", "DBHandlerGenerico", False)
srvr.Start srvr.Start
Log("===========================================================") Log("===========================================================")
Log($"-======== jRDC is running on port: ${srvr.port} (Version: ${VERSION}) ========-"$) Log($"-=== jRDC is running on port: ${srvr.port} (version = $1.2{VERSION}) ===-"$)
Log("===========================================================") Log("===========================================================")
StartMessageLoop StartMessageLoop
End Sub End Sub

View File

@@ -23,17 +23,17 @@ ModuleBreakpoints7=
ModuleBreakpoints8= ModuleBreakpoints8=
ModuleBreakpoints9= ModuleBreakpoints9=
ModuleClosedNodes0= ModuleClosedNodes0=
ModuleClosedNodes1=7,10 ModuleClosedNodes1=
ModuleClosedNodes10= ModuleClosedNodes10=
ModuleClosedNodes11= ModuleClosedNodes11=
ModuleClosedNodes2= ModuleClosedNodes2=
ModuleClosedNodes3= ModuleClosedNodes3=4,5,6
ModuleClosedNodes4= ModuleClosedNodes4=
ModuleClosedNodes5= ModuleClosedNodes5=
ModuleClosedNodes6= ModuleClosedNodes6=
ModuleClosedNodes7= ModuleClosedNodes7=
ModuleClosedNodes8= ModuleClosedNodes8=
ModuleClosedNodes9= ModuleClosedNodes9=
NavigationStack=ping,SendSuccessResponse,39,0,RDCConnector,GetConnection,102,0,RDCConnector,Initialize,11,0,RDCConnector,Class_Globals,9,0,Main,AppStart,65,6,Main,Process_Globals,30,5,ping,Initialize,9,0,ping,Handle,10,6,DB1Handler,Initialize,15,0,DB1Handler,Handle,48,6,Manager,Handle,16,5 NavigationStack=DBHandlerGenerico,SendPlainTextError,603,0,DBHandlerGenerico,Initialize,27,0,DB1JsonHandler,Class_Globals,6,0,DB1JsonHandler,Initialize,13,0,DBHandlerGenerico,Class_Globals,15,0,DB1JsonHandler,Handle,197,6,DB1JsonHandler,SendSuccessResponse,238,0,DB1JsonHandler,SendErrorResponse,255,0,Main,AppStart,76,0
SelectedBuild=0 SelectedBuild=0
VisibleModules=1,2,10,8,11,9 VisibleModules=6,2,10

View File

@@ -1,11 +0,0 @@
module.exports = {
"apps":[
{
"name":"jRDC-Multi",
"cwd":"C:/jRDC-Multi",
"script":"C:/java/jdk-14.0.1/bin/JAVA.EXE",
"args":"-jar C:/jRDC-Multi/jRDC_Multi.jar",
"exec_interpreter":""
}
]
}

View File

@@ -1,9 +0,0 @@
@rem Este script reinicia el proceso en PM2 del servidor de jRDC2
@rem estas lineas sirven para que el archivo bat corra en modo administrador.
set "params=%*"
cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && exit /B )
pm2 restart BotSoporte_4.0
exit

View File

@@ -4,6 +4,6 @@
set "params=%*" set "params=%*"
cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && exit /B ) cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && exit /B )
pm2 restart jRDC-Multi pm2 start RDC-Multi
exit exit