(Lenguaje de Datos Estructurado)
Porque SDL Bridge no es solo SQL…
es SQL con estructura semántica:
- Variables tipadas (
{{fecha:datetime}})- Contratos explícitos entre DBA y sistema
- Abstracción segura sobre la base de datos
Versión 1.0
Un puente seguro entre DBAs y desarrolladores en entornos WordPress
Permitir a los DBAs escribir consultas SQL complejas en archivos externos (con soporte para variables), y a los desarrolladores ejecutarlas de forma segura en WordPress, sin acoplamiento directo, sin inyección SQL, y con máxima flexibilidad de despliegue.
SDL Bridge actúa como capa de abstracción que:
- Lee archivos
.sdlescritos por DBAs. - Valida y sanitiza parámetros según tipos definidos.
- Genera SQL seguro compatible con
$wpdb. - Ejecuta consultas y devuelve resultados estructurados.
sdl-bridge/
├── src/ # Núcleo del motor (PSR-4)
│ ├── Types/ # Sistema de tipos extensible
│ ├── TypeRegistry.php # Registro central de tipos
│ ├── SDLParser.php # Analiza archivos .sdl
│ ├── SDLCompiler.php # Compila SDL → SQL seguro
│ ├── ReportEngine.php # Punto de entrada
│ └── exceptions/ # Excepciones del dominio
├── bootstrap.php # Autoloader y alias global
└── (informes .sdl van fuera de esta carpeta)
// En tu plugin o tema
require_once WP_PLUGIN_DIR . '/sdl-bridge/bootstrap.php';$results = SDLBridge::report('abandoned_cart')
->withParams([
'start' => '2024-01-01 00:00:00',
'end' => '2024-02-01 00:00:00'
])
->execute();
// $results->rows: array de resultados
// $results->sql: consulta SQL generada (para debugging)✅ El alias global
SDLBridgeestá disponible tras incluirbootstrap.php.
El sistema busca los informes en este orden de prioridad:
// En wp-config.php (fuera de DOCUMENT_ROOT)
define('SDL_BRIDGE_REPORTS_DIR', '/ruta/segura/fuera/de/la/web/reports');/home/tuusuario/sdl-bridge/reports/
✅ Fuera de
public_html/,htdocs/, etc.
/wp-content/plugins/tu-plugin/reports/
⚠️ Se añade.htaccessconDeny from all, pero no es 100% seguro.
- Es un superconjunto de SQL estándar.
- Soporta variables con sintaxis:
{{nombre:tipo}}. - Si no hay variables, se trata como SQL puro.
SELECT product_id, SUM(qty) AS total
FROM wp_wtf_session_events
WHERE event_timestamp >= {{start:datetime}}
AND event_timestamp < {{end:datetime}}
AND store_id = {{store_id:int}}
GROUP BY product_id| Tipo | Validación | Ejemplo de uso |
|---|---|---|
string |
Escapa con $wpdb->_real_escape() |
'O\'Reilly' |
int |
Solo enteros válidos | 42 |
float |
Números decimales | 3.1415 |
bool |
1 / 0 |
1 |
date |
Formato YYYY-MM-DD |
'2024-05-01' |
datetime |
Formato YYYY-MM-DD HH:MM:SS |
'2024-05-01 12:00:00' |
array |
Array → (val1,val2,...) |
(1,2,3) |
Para añadir un nuevo tipo (ej: uuid):
// 1. Crear clase
class UuidType extends BaseType { ... }
// 2. Registrar
$engine = new \SDLBridge\ReportEngine($reportsDir);
$engine->registerType('uuid', new UuidType());
// 3. Usar en SDL
// WHERE user_id = {{user_id:uuid}}- Ningún valor entra sin validación y sanitización.
- Todos los tipos usan mecanismos de WordPress (
$wpdb->_real_escape()). - Variables de tipo
identifier(nombres de tabla/columna) están prohibidas por defecto (riesgo alto). - Los informes deben estar fuera de
DOCUMENT_ROOT(recomendado).
| Excepción | Cuándo se lanza |
|---|---|
SDLException |
Error genérico en SDL (variables faltantes, etc.) |
TypeNotFoundException |
Tipo no registrado (ej: {{fecha:fechota}}) |
✅ Ambas extienden
\RuntimeExceptiony pertenecen al namespaceSDLBridge\exceptions.
- PSR-4 compatible.
- Usa
__DIR__debootstrap.phpcomo raíz. - No requiere Composer.
- Resistente a inclusiones desde cualquier contexto.
WITH abandoned_sessions AS (
SELECT DISTINCT session_header_id
FROM wp_wtf_session_events
WHERE event_type = 'add_to_cart'
AND event_timestamp >= {{start:datetime}}
AND event_timestamp < {{end:datetime}}
AND session_header_id NOT IN (
SELECT DISTINCT session_header_id
FROM wp_wtf_session_events
WHERE event_type = 'checkout_initialized'
AND event_timestamp >= {{start:datetime}}
AND event_timestamp < {{end:datetime}}
)
),
-- ... resto de la consulta (igual que en el ejemplo original)$results = SDLBridge::report('abandoned_cart')
->withParams([
'start' => '2024-05-01 00:00:00',
'end' => '2024-06-01 00:00:00'
])
->execute();
foreach ($results->rows as $row) {
echo $row['product_name'] . ": " . $row['veces_agregado_en_carritos_abandonados'] . "\n";
}- PHP 7.4+
- WordPress 5.0+
- MySQL 5.6+ (por funciones como
COALESCE,NULLIF)
- Desacoplamiento: DBAs escriben SDL, desarrolladores solo llaman.
- Seguridad primero: sanitización por tipo, no por esperanza.
- Extensibilidad sin tocar el core: nuevos tipos = nuevas clases.
- Flexibilidad de despliegue: desde webhosts compartidos hasta datacenters blindados.
- Transparencia: siempre se puede ver la SQL generada.
SDL Bridge es una obra de ingeniería abierta.
Puedes usarlo, modificarlo y distribuirlo,
siempre que respetes el espíritu de claridad y responsabilidad con el que fue creado.
Consulta la documentación extendida para más detalles.