awe-104 Recuperación y manipulación de datos
La recuperación de los datos utilizando AWE se puede hacer desde diferentes fuentes: enumerados, consultas, colas, servicios (Java y C), etc. Esto ayuda a la integración del lado del cliente con la lógica de negocio alojada en el servidor.
Enumerated
Los enumerados de AWE son útiles para gestionar listas de datos clave-valor. Son controlados desde el archivo Enumerated.xml que se puede encontrar en la carpeta "global" del proyecto.
Este archivo tiene la siguiente estructura:
<?xml version="1.0" encoding="UTF-8"?>
<enumerated xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation = "https://aweframework.gitlab.io/awe/docs/schemas/enumerated.xsd">
<group id="[Group Id]">
<option label="[Option label]" value="[Option value]" />
<option label="[Option label]" value="[Option value]" />
...
</group>
...
</enumerated>
Creación del archivo Enumerated.xml
El archivo Enumerated.xml debe ser creado en la carpeta "global" del proyecto.
Este archivo debe tener una cabecera que haga referencia al esquema a seguir. Hay que asegurarse de que la ruta es correcta.
<?xml version="1.0" encoding="UTF-8"?>
<enumerated xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation = "https://aweframework.gitlab.io/awe/docs/schemas/enumerated.xsd">
....
</enumerated>
Nuestro primer enumerado
Para este tutorial usaremos un enumerado numérico como ejemplo, para mapear los valores "SÍ-NO".
Para esto, añadiremos al contenido del archivo la etiqueta group con sus opciones correspondientes.
<?xml version="1.0" encoding="UTF-8"?>
<enumerated xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation = "https://aweframework.gitlab.io/awe/docs/schemas/enumerated.xsd">
<!-- Enumerated YES (0) | NO (1) -->
<group id="Es1Es0">
<option label="ENUM_NO" value="0" />
<option label="ENUM_YES" value="1" />
</group>
...
</enumerated>
Cada una de las etiquetas option insertadas representará un elemento diferente del enumerado.
El caso más habitual de uso para un enumerado está en los componentes de tipo select.
<criteria label="PARAMETER_ACTIVE" component="select" id="CrtSta" initial-load="enum" target-action="Es1Es0" style="col-xs-6 col-sm-3 col-lg-2" optional="true" />
Ejemplos de enumerados
Estos son algunos ejemplos de enumerados:
<enumerated xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation = "https://aweframework.gitlab.io/awe/docs/schemas/enumerated.xsd">
<!-- Enumerated YES (0) | NO (1) -->
<group id="Es1Es0">
<option label="ENUM_NO" value="0" />
<option label="ENUM_YES" value="1" />
</group>
...
<!-- LANGUAGES -->
<group id="LanUsr">
<option label="ENUM_LAN_ES" value="ESP"/>
<option label="ENUM_LAN_EN" value="ENG"/>
<option label="ENUM_LAN_FR" value="FRA"/>
</group>
...
</enumerated>
Variables
Las variables en AWE se utilizan para facilitar la recuperación de datos, permitiendo pasar los valores que tenemos en pantalla o disponibles en el servidor (por ejemplo en un servicio Java). Por ejemplo, si queremos usar el valor de un criterio en pantalla en una cláusula where, debemos usar una variable.
En las siguientes líneas veremos algunos ejemplos que aclararán este concepto.
Consultas de base de datos
Las consultas de base de datos se realizan desde el archivo Queries.xml. En este archivo, las consultas SQL se crean usando el formato dado por AWE, y este se encarga de traducirlas. Como en la sección anterior, este archivo debe ubicarse en la carpeta global.
Nota: El concepto QUERY en el entorno de AWE hace referencia a una acción solicitada al servidor donde el cliente espera algunos datos como respuesta. No debería ser confundido con QUERY SQL.
Dentro de las consultas SQL, hay varias maneras de recuperar datos: field, computed y compound.
La recuperación con field se utiliza para obtener campos presentes en una consulta SQL, o en otra forma, valores de columna.
<query id="CheckAdeudoId">
<field id="Id" transform="NUMBER" pattern="###" />
<field id="Id_File" />
<table id="Adeudo" />
<where>
<and>
<filter left-field="Id_File" condition="eq" right-variable="varIdFile" trim="true" />
</and>
</where>
<variable type="STRING" id="varIdFile" name="idFile" />
</query>
En este ejemplo, tenemos una variable con un identificador de archivo para obtenerlo de la tabla de la base de datos usando una cláusula WHERE. Este campo recuperado es de tipo string pero lo trasformamos a un formato numérico.
Como puede ver, tenemos diferentes atributos que permiten realizar varias operaciones estándar en SQL. Por ejemplo, trim.
select
and select-multiple
components
select
and select-multiple
components require special naming on query fields to be filled:
<criteria label="PARAMETER_SELECT" id="select" variable="select" component="select"
initial-load="query" target-action="FillSelect" optional="true"/>
The fields which are required are the following:
value
: The value which will be sent to the server as the selected option of this criterion.label
: The text shown on each option
<query id="FillSelect">
<table id="MyTable"/>
<field id="field1" alias="value" />
<field id="field2" alias="label" />
<where>
<and>
...
</and>
</where>
...
</query>
Important: If you fill a
select
type criterion with theinitial-load
attribute, you must check that the variables on the query doesn't refer to the current window (as it is being created on screen generation).
suggest
and suggest-multiple
components
suggest
and suggest-multiple
components require the same special naming as select
type components, but they are not populated on page generation, as they search the values when user types any text.
<criteria label="PARAMETER_SUGGEST" id="suggest" variable="suggest" component="suggest"
server-action="data" target-action="FillSuggest"/>
A special variable called suggest
is sent when user types some text, and it can be used in the query to retrieve the filtered data:
<query id="FillSuggest">
<table id="MyTable"/>
<field id="field1" alias="value" />
<field id="field2" alias="label" />
<where>
<and>
<filter left-field="field2" condition="like" right-variable="suggest" ignorecase="true" />
</and>
</where>
<variable id="suggest" type="STRINGB" name="suggest"/>
</query>
Mantenimiento de base de datos
Mantenimiento de base de datos son aquellas acciones que realizan modificaciones en datos almacenados, es decir, en SQL, acciones como INSERT, UPDATE y DELETE. Además, dentro de un único mantenimiento, se pueden realizar varias de estas operaciones a la vez.
Los mantenimientos se crean dentro del archivo Maintain.xml y se encuentran en la carpeta global, como hemos visto anteriormente.
Dentro del archivo Maintain.xml los mantenimientos deben definirse con la etiqueta target.
En este ejemplo de INSERT, se inserta una fila en la tabla AwePro. El campo IdePro se rellena con la secuencia de AWE ProKey.
<target name="ProNew">
<insert audit="HISAwePro">
<table id="AwePro" />
<field id="IdePro" sequence="ProKey" />
<field id="Acr" variable="Acr" />
<field id="Nam" variable="Nam" />
<field id="IdeThm" variable="IdeThm" />
<field id="ScrIni" variable="ScrIni" />
<field id="Res" variable="Res" />
<field id="Act" variable="Act" />
<variable id="Acr" type="STRINGN" name="Acr" />
<variable id="Nam" type="STRINGN" name="Nam" />
<variable id="IdeThm" type="INTEGER" name="IdeThm" />
<variable id="ScrIni" type="STRING" name="ScrIni" />
<variable id="Res" type="STRING" name="Res" />
<variable id="Act" type="INTEGER" name="Act" />
</insert>
</target>
Aquí se puede ver una modificación (UPDATE) sobre la misma tabla.
<target name="ProUpd">
<update audit="HISAwePro">
<table id="AwePro" />
<field id="IdePro" variable="IdePro" />
<field id="Acr" variable="Acr" />
<field id="Nam" variable="Nam" />
<field id="IdeThm" variable="IdeThm" />
<field id="ScrIni" variable="ScrIni" />
<field id="Res" variable="Res" />
<field id="Act" variable="Act" />
<where>
<and>
<filter left-field="IdePro" condition="eq" right-variable="IdePro" />
</and>
</where>
<variable id="IdePro" type="INTEGER" name="IdePro" />
<variable id="Acr" type="STRINGN" name="Acr" />
<variable id="Nam" type="STRINGN" name="Nam" />
<variable id="IdeThm" type="INTEGER" name="IdeThm" />
<variable id="ScrIni" type="STRING" name="ScrIni" />
<variable id="Res" type="STRING" name="Res" />
<variable id="Act" type="INTEGER" name="Act" />
</update>
</target>
En el siguiente ejemplo con una acción de DELETE, se puede ver cómo se realiza primero uno de ellos y antes de que el segundo comience una confirmación (commit) de la primera operación. Si no se declara ningún commit explícito, se hará de todos modos pero después de todas las operaciones definidas dentro de la etiqueta target.
A continuación vemos un ejemplo utilizando el atributo multiple. Cuando se establece a true significa que la variable IdePro es una lista de valores, así que se ejecutarán tantas DELETE acciones como elementos están en esa lista.
<target name="ProDel">
<delete multiple="true" audit="HISAweModPro">
<table id="AweModPro" />
<field id="IdePro" variable="IdePro" audit="true" />
<where>
<and>
<filter left-field="IdePro" condition="eq" right-variable="IdePro" />
</and>
</where>
<variable id="IdePro" type="INTEGER" name="IdePro" />
</delete>
<commit/>
<delete multiple="true" audit="HISAweScrRes">
<table id="AweScrRes" />
<field id="IdePro" variable="IdePro" audit="true" />
<where>
<and>
<filter left-field="IdePro" condition="eq" right-variable="IdePro" />
</and>
</where>
<variable id="IdePro" type="INTEGER" name="IdePro" />
</delete>
</target>
Finalmente, también se pueden utilizar mantenimientos de tipo multiple, es decir, con etiqueta multiple. Esto significa que las acciones que se pueden realizar son cualquiera de estas 3 (INSERT, UPDATE, DELETE). La forma de saber qué tipo de operación queremos realizar es a través de una variable implícita generada automáticamente que contiene esta información. El nombre de esta variable es grid_name-RowTyp y la forma de enlazar este mantenimiento con una tabla es con el atributo grid (en este ejemplo, GrdScrAccLst).
<!-- Screen Access Multiple -->
<target name="ScrAccUpd">
<multiple audit="HISAweScrRes" grid="GrdScrAccLst">
<table id="AweScrRes" />
<field id="IdeAweScrRes" variable="IdeAweScrRes" sequence="ScrResKey" key="true" />
<field id="IdePro" variable="IdePro" />
<field id="IdeOpe" variable="IdeOpe" />
<field id="IdeMod" variable="IdeMod" />
<field id="Opt" variable="Opt" />
<field id="AccMod" variable="AccMod" />
<field id="Act" variable="Act" />
<variable id="IdeAweScrRes" type="INTEGER" name="IdeAweScrRes" />
<variable id="IdeOpe" type="INTEGER" name="IdeOpe"/>
<variable id="IdePro" type="INTEGER" name="IdePro"/>
<variable id="IdeMod" type="INTEGER" name="IdeMod"/>
<variable id="Opt" type="STRING" name="Opt" />
<variable id="AccMod" type="STRING" name="AccMod" />
<variable id="Act" type="INTEGER" name="Act" />
</multiple>
</target>
Envío de correo electrónico
AWE tiene la capacidad de enviar correos electrónicos de una manera sencilla. Estas entregas pueden ser definidas en el archivo Email.xml.
<email id="TransfersSNCEEmaRep">
<from value="FromValue" label="FromValue" />
<to label="RepEmaDst" value="RepEmaDst" />
<subject label="RepTit" value="RepTit" />
<body label="RepMsg" type="html" value="RepMsg"/>
<body label="RepMsg" type="text" value="RepMsg"/>
<variable type="STRING" id="FromValue" property="sch.report.email"/>
<variable type="STRING" id="RepMsg" name="RepMsg"/>
<variable type="STRING" id="RepTit" name="RepTit"/>
</email>
La forma más común de enviar un correo electrónico sería con una acción dentro de un mantenimiento.
Ejemplo:
<!-- Send reports by e-mail -->
<target name="SndRep">
<send-email id="SndRep" />
</target>
Conexión con colas de mensajes
Las conexiones con colas de mensajes a través de AWE se definen en el archivo Queues.xml dentro de la carpeta global del proyecto.
Las dos partes principales de la definición de una cola de mensajes son la definición de la petición y los mensajes de respuesta.
Estos son algunos ejemplos:
<queues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://aweframework.gitlab.io/awe/docs/schemas/queues.xsd">
<!-- Queue retreive sync test with wrappers -->
<queue id="SynQueWrpTxt">
<request-message destination="AweReq" type="TEXT" selector="wrapper">
<message-wrapper type="XML" classname="com.almis.awe.test.wrappers.Casa" />
</request-message>
<response-message destination="AweRes" type="TEXT">
<message-wrapper type="XML" classname="com.almis.awe.test.wrappers.Casa" />
</response-message>
</queue>
<!-- Queue retreive sync test (parameter list) -->
<queue id="TstGrdQue">
<request-message destination="AweReq" type="MAP" selector="grid">
</request-message>
<response-message destination="AweRes" type="MAP">
<message-parameter id="OutFld1" type="STRING" name="MapKey1" list="true" />
<message-parameter id="OutFld2" type="STRING" name="MapKey2" list="true" />
<message-parameter id="OutFld3" type="STRING" name="MapKey3" list="true" />
<message-parameter id="OutFld4" type="STRING" name="MapKey4" list="true" />
</response-message>
</queue>
...
</queues>
Services
Los servicios definidos en AWE, dentro del archivo Services.xml, pueden ser invocados desde una consulta (archivo Queries.xml) o desde mantenimiento (archivo Maintain.xml).
Desde consultas:
<query id="GetFechasCancelacionesSup" service="GetFilteredDates">
<field id="label" alias="label" transform="DATE" function="TRUNCDATE" />
<field id="value" alias="value" transform="DATE" function="TRUNCDATE" />
<variable id="Dias" type="INTEGER" name="Dias" value="10" />
</query>
Desde mantenimientos:
<target name="checkYearHolidays">
<serve service="checkYearHolidays"/>
</target>