Manual de Referencia de HDBC RDD (Replaceable Database Driver)
El RDD de HDBC (
Esta capa traduce en tiempo real las operaciones procedurales al dialecto SQL del motor configurado (SQLite, MySQL, PostgreSQL, etc.), lo que es ideal para portar aplicaciones "Legacy" o para desarrolladores que prefieran evitar el uso de objetos y sentencias SQL manuales.
---
1. Configuración Inicial e Inyección del RDD
Para comenzar, debe enlazar el núcleo de conexión
#include "hdbc_conn.ch"
#include "hdbc.ch"
#include "rddsys.ch"
PROCEDURE Main()
LOCAL oDbc := THDbc():new( HDBC_DRIVER_SQLITE )
oDbc:connect( "database=test_rdd.db" )
// 1. Registrar el driver en el subsistema RDD
rddRegister( "RDDHDBC", RDT_FULL )
// 2. Transmitir la conexión activa al ámbito RDD
HDbcRdd_Init( oDbc )
// 3. (Opcional) Hacerlo el RDD por defecto
RddSetDefault( "RDDHDBC" )[!TIP]
Al finalizar la aplicación, libere la memoria asociada llamando aHDbcRdd_End() antes de cerrar la conexión deTHDbc .
---
2. Operaciones Básicas xBase (CRUD)
2.1 Creación de Tablas (dbCreate )
Puede crear tablas remotas usando diccionarios de arrays estándar de Harbour o el tipo especializado
LOCAL aStruct := { ;
{ "ID", "N", 10, 0 }, ;
{ "NOMBRE", "C", 50, 0 }, ;
{ "SALARIO", "N", 12, 2 }, ;
{ "FECHA", "D", 8, 0 }, ;
{ "ACTIVO", "L", 1, 0 } ;
}
dbCreate( "empleados", aStruct, "RDDHDBC" )2.2 Apertura (USE )
USE empleados ALIAS EMP VIA "RDDHDBC" NEW
IF NetErr()
? "Error abriendo tabla remota"
ENDIF2.3 Altas (APPEND BLANK y REPLACE )
SELECT EMP
APPEND BLANK
REPLACE FIELD->ID WITH 1, ;
FIELD->NOMBRE WITH "Juan Pérez", ;
FIELD->SALARIO WITH 2500.50, ;
FIELD->ACTIVO WITH .T.2.4 Navegación (dbSkip , EOF , BOF )
EMP->( dbGoTop() )
DO WHILE ! EMP->( Eof() )
? "ID:", EMP->ID, "Nombre:", EMP->NOMBRE
EMP->( dbSkip() )
ENDDO2.5 Bajas Lógicas y Físicas
Si su motor detecta una columna interna para eliminaciones lógicas (SoftDeletes), el comando
GOTO 2
DELETE
? "Registro 2 marcado como borrado. Deleted():", Deleted()---
3. Funciones Avanzadas del RDD
3.1 Índices y Búsquedas (INDEX ON y dbSeek )
El RDD permite indexación dinámica local en memoria / servidor permitiendo búsquedas rápidas.
USE clientes ALIAS CLI NEW VIA "RDDHDBC"
INDEX ON FIELD->nombre TAG por_nombre
SEEK "Maria García"
IF Found()
? "ENCONTRADA! ID:", CLI->id, "Ciudad:", CLI->ciudad
ENDIF3.2 Filtrado y Contención (SET FILTER y SCOPES )
Mientras que el filtro evalúa registro a registro, HDBC también soporta los SCOPES (Acotaciones de Índice), los cuales son extremadamente más rápidos porque limitan la consulta nativa en su pre-generación inyectando sentencias lógicas.
Uso de SET FILTER:
SET FILTER TO CLI->ciudad == "Madrid"
GO TOP
DO WHILE ! Eof()
? "Encontrado en Madrid:", CLI->nombre
SKIP
ENDDO
SET FILTER TO // Limpiar FiltroUso de SCOPES (Filtro Inteligente Indexado):
// Asumiendo un tag 'idx_ciudad' creado...
ORDSETFOCUS( "idx_ciudad" )
// Acota tanto por arriba (0) como por abajo (1)
ORDSCOPE( 0, "Madrid" )
ORDSCOPE( 1, "Madrid" )
GO TOP
// El bucle ahora sólo navega clientes de Madrid de modo relámpago
ORDSCOPE( 0, NIL ) // Limpiar scope3.3 Relaciones Entidad-Referencia (SET RELATION )
Vincule cursores mediante apuntadores síncronos xBase para avanzar múltiples WorkAreas en paralelo:
USE facturas ALIAS FAC NEW VIA "RDDHDBC"
SELECT CLI
INDEX ON FIELD->id TAG id_cli
SELECT FAC
SET RELATION TO FAC->cliente_id INTO CLI
GO TOP
DO WHILE ! Eof()
// Por debajo, el driver localizará concurrentemente en el puntero de CLI
? "Factura:", FAC->id, "-> Cliente:", CLI->nombre
SKIP
ENDDO3.4 Inyección de Vistas SQL Complejas ("SQL-as-Table")
Este es uno de los recursos más potentes del
USE "SELECT c.nombre, COALESCE(SUM(f.total), 0) as total FROM clientes c LEFT JOIN facturas f ON c.id = f.cliente_id GROUP BY c.id, c.nombre" ALIAS RESUMEN NEW VIA "RDDHDBC"
IF Used()
DO WHILE ! Eof()
? "Resumen:", RESUMEN->nombre, "Total:", RESUMEN->total
SKIP
ENDDO
CLOSE RESUMEN
ENDIF---
4. Transacciones y Bloqueos
El RDD soporta mecanismos híbridos valiéndose en el control de su objeto padre
Transacciones
Emplee directamente el nivel
oDbc:beginTrans()
REPLACE SEC->saldo WITH SEC->saldo + 500
IF lTodoCorrecto
oDbc:commit()
ELSE
oDbc:rollback()
ENDIF---
5. Mantenimiento Físico (PACK y ZAP)
El RDDHDBC integra utilidades físicas nativas para el mantenimiento del modelo de datos tradicional xBase.
ZAP (Vaciado Completo)
Al invocar
USE auditorias ALIAS AUD VIA "RDDHDBC" EXCLUSIVE
ZAP
? "Tabla de auditoría truncada radicalmente."PACK (Purga de Bajas Lógicas SoftDeletes)
En las tablas tradicionales DBF
Ejecutar el comando
USE clientes ALIAS CLI VIA "RDDHDBC" EXCLUSIVE
PACK
? "Base de datos saneada permanentemente de tuplas borradas."Bloqueos de Registros Optimistas
Puede emitir instrucciones
GO TOP
IF RLock()
REPLACE SEC->saldo WITH 2000
UNLOCK
ELSE
? "Alguien más tiene bloqueada esta fila."
ENDIFY esto funciona con:
MySQL, MariaDb, SQLite y clónicos, Postgres, Oracle, SQLServer, Interbase, Firebird y ODBC
Ya es una realidad escribir un PRG para cualquier base de datos!!!
Sevilla - Andalucía