Ir al contenido

DataSource en PHP

El atributo dataSource en <histrix> delega en una clase PHP la obtención o la grabación de los datos, en lugar de dejar que el motor arme el SQL a partir del XML. Se usa cuando la consulta no se puede expresar en el XML: agregaciones complejas, columnas dinámicas, datos de un servicio externo o lógica de grabación propia.

<histrix tipo="consulta" dataSource="MiClase">

La clase expone métodos estáticos. El motor llama al que corresponde según la operación:

<?php
class MiClase
{
public static function Select($dataContainer)
{
// debe devolver un arreglo de filas (arreglos campo => valor)
}
public static function Insert($dataContainer)
{
}
public static function Update($dataContainer, $rowData)
{
}
public static function Delete($dataContainer, $row)
{
}
}
Método Firma Cuándo se llama
Select ($dataContainer) Al consultar datos
Insert ($dataContainer) Al insertar
Update ($dataContainer, $rowData) Al modificar, una vez por fila
Delete ($dataContainer, $row) Al borrar
create ($dataContainer) Al construir el contenedor, antes de leer datos
import ($dataContainer, $file) Al importar un archivo

Solo hay que implementar los que se usan: si falta Insert, la inserción sigue el camino normal del motor.

Con la sintaxis Clase::Método se elige explícitamente qué método invocar para el Select, lo que permite agrupar consultas relacionadas:

<histrix tipo="consulta" dataSource="Reportes::VentasPorMes">

Sin ::, el método por omisión es Select.

Cuando hay dataSource, el motor no genera SQL y por lo tanto no aplica los <filters>. El filtrado corre por cuenta de la clase, leyendo los valores del contenedor:

$desde = $dataContainer->getField('fecha_desde')->valor;

$dataContainer es una instancia de \Histrix\Data\Container. Métodos de uso frecuente:

Método Devuelve
getField($nombre, $tabla) El objeto campo; su valor está en ->valor
getSelect() El SQL que el motor habría ejecutado, como string
getData($fila) Los datos cargados en el contenedor
setFieldValue($campo, $valor) Asigna un valor a un campo
getHttpRequest() La request PSR-7
getFilters() Los filtros declarados
getConditions() Las condiciones acumuladas
getTitle() El título del programa

Parámetros de la request:

$request = $dataContainer->getHttpRequest();
$postVars = $request->getParsedBody(); // cuerpo
$params = $request->getQueryParams(); // query string

Dentro de un dataSource se puede armar otro contenedor para reutilizar la definición de un XML existente.

A partir de un XML en disco:

$file = 'example_ing.xml';
$dir = 'example/other/';
$reader = \Histrix\Parser\XmlParser::getReader('', $dir . $file);
$dataContainer = $reader->getContainer();

A partir de una definición en memoria:

$string = '<histrix tipo="consulta">
<form>
<table id="HTXUSERS">
<fieldGroup>
<field id="field_1" local="true" order="2"/>
<field id="field_2" local="true" order="1"/>
</fieldGroup>
</table>
</form>
</histrix>';
$xml = simplexml_load_string($string);
$parser = new \Histrix\Parser\XmlParser();
$parser->xml = 'test.xml';
$dataContainer = $parser->createDataContainer($xml);

Las clases se cargan por classmap de Composer. Después de crear, mover o renombrar una, hay que regenerar el mapa:

Ventana de terminal
composer dumpautoload

En una instalación con Docker, el comando corre dentro del contenedor:

Ventana de terminal
docker exec -it histrix composer dumpautoload

Si el XML se ejecuta pero no hace nada de lo que define el dataSource, o la request falla con Class 'NombreDeLaClase' not found, el mapa está desactualizado.