Algunas caracteristicas de la libreria son:
- Está hecha al 100*100 en Lenguaje C (tanto las clases como las funciones) por lo que la velocidad está muy por encima de lo que se conoce hasta ahora.
- Es 100*100 POO. Se puede heredar de ellas en PRG para hacer clases más especializadas.
- Está formadas por varias clases muy faciles de usar:
* THDO: encargada de establecer la conexión con la base de datos y hacer el mantenimiento de la misma además de controlar las transacciones, y obtener objetos para la gestión de consulta y demás sentencias SQL. También se pueden ejecutar sentencias directamente y establecer atributos y controlar las excepciones.
* THDOStatetent: encargada de las sentencias de todo tipo que se le pueden enviar al servidor. Estas sentencias pueden ser directas o preparadas. Las sentencias preparadas son mucho más eficientes y evitan la inyección de codigo malintencionado en el servidor. La novedad de las sentencias preparadas en el lado del servidor es que se pueden usar BIND en los parametros y en los resultados de tal manera que esos BIND se pueden asociar a variables de Harbour y se actualizarán automaticamente sin tener que asignarlas "a mano". En el caso de un BIND de parametro cada vez que se le asigna un valor a la variable enlazada y se envía el metodo execute esta quedará actualizada y respondera como es debido. He aquí un ejemplo:
- Code: Select all Expand view
/*
* Proyecto: hdo
* Fichero: ej07.prg
* Descripcion: Uso de sentencias compiladas con variables vinculadas. Consultas
* Autor: Manu Exposito 2015-16
* Fecha: 21/08/2015
*/
#include "hdo.ch"
//------------------------------------------------------------------------------
procedure main07b()
local oDb, oStmt, oCur, e
local nSocIni := 0, nSocFin := 999999, getlist := {}
local cDb := "agenda.db"
local cTabla := "socios"
local cSql := "SELECT * FROM " + cTabla + " WHERE clavesocio BETWEEN ? AND ? ;"
cls
oDb := THDO():new( "sqlite" )
oDb:setAttribute( ATTR_ERRMODE, .t. )
if oDb:connect( cDb )
TRY
oStmt := oDb:prepare( cSql ) // Prepara la sentencia y crea el objeto oStmt
oStmt:bindParam( 1, @nSocIni ) // Asocia variables PRG
oStmt:bindParam( 2, @nSocFin )
@ MaxRow(), 00 SAY "Presiona <INTRO> para selecionar rangos o <ESC> para salir..."
while Inkey( 0 ) != 27
cls
@ 02, 02 SAY "Entrada de datos:"
@ 04, 02 SAY "Entre rango inicial:" get nSocIni PICTURE "@K"
@ 05, 02 SAY "Entre rango final..:" get nSocFin PICTURE "@K" VALID validaRango( nSocIni, nSocFin )
READ
oStmt:execute() // Ejecuta la sentencia
/*
for e := 1 to 6
muestra( oStmt:GETCOLUMNMETA( e ) )
next
*/
// Creamos un cursor local (navigator) como un hash table
oCur := THashCursor():new( oStmt:fetchAll( FETCH_HASH ) )
cls
@ 00, 00 SAY "Resultado de la consulta -> " + hb_ntos( oStmt:rowCount() ) + " registros:" COLOR "W+/R"
@ MaxRow(), 00 SAY "<ESC> para volver al menu..." COLOR "W+/R"
if oCur:recCount() > 0
miBrwCursor( oCur, 1, 0, MaxRow() - 1, MaxCol() )
else
msg( "No hay registros en ese rango" )
endif
oCur:free()
cls
@ MaxRow(), 00 SAY "Presiona <INTRO> para selecionar rangos o <ESC> para salir..."
end
CATCH e
Eval( ErrorBlock(), e )
FINALLY
if oStmt:className() == "THDOSTATEMENT"
oStmt:free()
endif
msg( "Se acabo" )
END
endif
oDb:disconnect()
return
//------------------------------------------------------------------------------
static function validaRango( r1, r2 )
local lRet := ( r1 > r2 )
if lRet
msg( "Priemero mayor que segundo: " + ;
hb_ntos( r1 ) + " > " + ;
hb_ntos( r2 ), "Error en rangos" )
endif
return !lRet
* THashCursor y TMemCursor: clases para manejar el resultado de una sentencia SQL que devuelva un conjunto de datos. La primera basada en tablas hash y la segunda en array.
Ya se puede usar Harbour Data Objects HDO para SQLite.
Voy a necesitar varios betatester, si hay alguien interesado puede ponerse en contacto conmigo
Saludos de vuestro vecino Manu Expósito