Page 1 of 2
Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Wed Mar 05, 2025 5:18 pm
by Lailton
Hola a todos,
Me complace presentar Harbour Database Connect (HDBC), una nueva y potente librería desarrollada por Manuel Expósito (Manu), un desarrollador altamente experimentado y sofisticado con un profundo conocimiento de Harbour a nivel C.
HDBC es una librería de alto rendimiento escrita en C/C++, diseñada para brindar a los desarrolladores de Harbour máxima velocidad y flexibilidad al conectarse a bases de datos. Con HDBC, puedes acceder fácilmente a PostgreSQL, SQLite y ODBC, y pronto habrá soporte para SQL Server y MySQL/MariaDB—¡con tu apoyo, podemos acelerar su desarrollo!
¿Por qué elegir HDBC?

Núcleo en C/C++ para interacciones con bases de datos de alto rendimiento

Compatible con Harbour puro, FiveWin y modHarbour

Funciona con Harbour 32-bit y 64-bit (BCC/MSVC) – otros compiladores disponibles bajo petición

Soporte para Linux incluido
¡Oferta especial – Promoción por tiempo limitado!
Si compras HDBC este mes, también recibirás HDO a un precio exclusivo. Con HDBC + HDO, tendrás soporte para:
✔ SQLite, SQLCipher, MySQL, MariaDB, PostgreSQL, ODBC y HDORDD
Además, Manuel ofrece 1 año de actualizaciones gratuitas, todo por un precio muy asequible.

Descubre más e inicia hoy mismo:
https://harbour.blog/hdbc/
Si tienes alguna pregunta, no dudes en contactarnos.
¡Gracias!
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Wed Mar 05, 2025 6:45 pm
by Carles
Hi,
Felicidades Manu
C.
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Wed Mar 05, 2025 7:00 pm
by sysctrl2
Pinta muy bien,
HDBC LIB, es compatible con xBrowse ? puede mostrar codigo de uso?
gracias.
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Wed Mar 05, 2025 7:18 pm
by Lailton
Hola,
Si, la xBrowse de FiveWin es muy avanzada, y te permite muy facil usar Array para los dados de browse
se verificar los ejemplos en la URL tiene ejemplos de como obter los resultado como array, hash, json etc.
Como siempre la limitacion de harbour es la imaginacion

Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Wed Mar 05, 2025 8:01 pm
by Marco Augusto
Saludos
puedo usar MYSQL via ADO
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Fri Mar 07, 2025 12:23 am
by xmanuel
De momento solo usa soporte nativo a:
- SQLite y SQLCipher (SQLite cifrado)
- PostgreSQL
- MS SQLServer
- ODBC
En proyecto está:
- MariaDB/MySQL
- Firebird
- Oracle
Todas ellas con accesos nativos, usando el estándar C++20 con los compiladores MSVC 32 y 64, MinGW 32 y 64, CLang 32 y 64 y Bcc 64 (no he probado el de 32 que posiblemente no implemente el C++20)
Para que tengáis una idea estas son las clases virtuales en C++ desde las que derivan las demás especializadas en un base de datos concreta:
Code: Select all | Expand
//-----------------------------------------------------------------------------
// Harbour Data Base Connection (HDBC)
// Archivo: hdbc.hpp
// Clase virtual desde la se derivan todas
// Autor: Manu Exposito (2024)
// Notas:
//-----------------------------------------------------------------------------
#ifndef _HVDBC_HPP
#define _HVDBC_HPP
#pragma once
// De HDbc
#include "hvobject.hpp"
#include "hcompclass.hpp"
// Definicion anticipada de clases
class TVHDbc;
class TVHDbcStmt;
// De C++
#include <string>
//-----------------------------------------------------------------------------
// Clase TVHDbc: Gestion de la conexion y la base de datos
class TVHDbc : public TXVObject
{
public:
// Atributos
HB_UINT ATTR_TIMEOUT = 0; // Tiempo de espera
HB_UINT ATTR_ERRMODE = 1; // Lanaza exception
// Metodos
virtual void init() {}
virtual bool connect() = 0;
virtual bool isConnected() const = 0;
virtual void disconnect() = 0;
virtual bool reconnect() = 0;
virtual bool ping();
virtual TVHDbcStmt *prepare( const char *zSql ) const = 0;
virtual void query( const char *zSql, PHB_ITEM aColNames ) const;
virtual void tables() const = 0;
virtual void scalar( const char *zSql, HB_UINT columnIndex ) const;
virtual bool setAttribute( HB_UINT uiAttribute, PHB_ITEM xValue );
virtual PHB_ITEM getAttribute( HB_UINT uiAttribute ) const;
virtual bool beginTrans() const;
virtual bool commit() const;
virtual bool rollback() const;
virtual HB_INT exec( const char *szStmt ) const = 0;
virtual HB_INT errorCode() const noexcept = 0;
virtual const char *lastError() const noexcept = 0;
virtual HB_SIZE lastInsertId() const;
virtual std::string escapeStr( const std::string &inputStr ) = 0;
virtual std::string quote( const std::string &inputStr ) = 0;
virtual void *gethConn() const = 0;
protected:
private:
};
//-----------------------------------------------------------------------------
// Clase TVHDbcStmt: Gestion de sentencias
class TVHDbcStmt : public TXVObject
{
private:
HB_UINT uiColumnCount = 0;
HB_UINT uiParamCount = 0;
protected:
TBindList *listParam = nullptr;
TBindList *listColumn = nullptr;
int iRowCount = 0;
int iCurrentRow = -1;
public:
// Atributos
// Los ATTR_ poner en una estructura o en una enumeracion
HB_UINT ATTR_ERRMODE = 1; // Lanaza exception
// Metodos
virtual void close() = 0;
virtual bool closeCursor() = 0;
virtual void bindParam( HB_UINT index, PHB_ITEM xParam );
virtual void bindValue( HB_UINT index, PHB_ITEM xValue );
virtual void bindColumn( HB_UINT index, PHB_ITEM xColumn );
virtual bool bindParamC( const char *szIndex, PHB_ITEM xParam );
virtual bool bindValueC( const char *szIndex, PHB_ITEM xValue );
virtual HB_INT errorCode() const noexcept = 0;
virtual const char *lastError() const noexcept = 0;
virtual bool executeStmt() = 0;
virtual bool executeQuery() = 0;
virtual HB_SIZE affectedRows() const = 0;
virtual bool setAttribute( HB_UINT uiAttribute, PHB_ITEM xValue );
virtual PHB_ITEM getAttribute( HB_UINT uiAttribute ) const;
virtual bool isPrepared() const = 0;
virtual HB_SIZE rowCount() const = 0;
virtual bool fetchDirect() noexcept = 0;
virtual bool next(); // Va a la fila siguiente
virtual bool prev(); // Va a la fila anterior
virtual bool first(); // Va a la fila primera
virtual bool last(); // Va a la fila ultima
virtual bool moveTo( HB_SIZE ulRow ); // Va a la fila indicada
virtual bool move( HB_LONGLONG llSkip ); // Va a la fila iSkip siguiente o anterior (skip)
virtual void getBound() const;
virtual void getArray( PHB_ITEM aRec ) const;
virtual void getHash( PHB_ITEM hRec ) const;
virtual void getJson( PHB_ITEM cJson ) const;
virtual void getAllArray();
virtual void getAllArray( PHB_ITEM aRec );
virtual void getAllHash();
virtual void getAllJson();
virtual void columnGet( HB_UINT columnIndex = 1 ) const;
virtual const char *columnName( HB_UINT columnIndex ) const = 0;
virtual int columnLen( HB_UINT columnIndex ) const = 0;
virtual int columnNativeType( HB_UINT columnIndex ) const = 0;
virtual const char *columnType( HB_UINT columnIndex ) const = 0;
virtual void columnNames() const;
virtual void columnNames( PHB_ITEM aColNames ) const;
virtual bool nextRowset() = 0;
virtual void *gethStmt() const = 0;
virtual void getString( HB_UINT columnIndex ) const = 0;
virtual void getInteger( HB_UINT columnIndex ) const = 0;
virtual void getDouble( HB_UINT columnIndex ) const = 0;
virtual void getDate( HB_UINT columnIndex ) const = 0;
virtual void getDateTime( HB_UINT columnIndex ) const = 0;
virtual void getBool( HB_UINT columnIndex ) const = 0;
virtual void getBlob( HB_UINT columnIndex ) const = 0;
// Metodos inline
inline HB_UINT columnCount() const
{
return uiColumnCount;
}
inline void setColumnCount( HB_UINT uiColumns = 0 )
{
uiColumnCount = uiColumns;
}
inline HB_UINT paramCount() const
{
return uiParamCount;
}
inline void setParamCount( HB_UINT uiParams = 0 )
{
uiParamCount = uiParams;
}
virtual inline bool bof() const
{
return iRowCount == 0 || iCurrentRow == -1;
}
virtual inline bool eof() const
{
return iRowCount == 0 || iCurrentRow >= iRowCount;
}
protected:
virtual void setBindParam( HB_UINT index ) const = 0;
virtual void setBindColumn( HB_UINT columnIndex, PHB_ITEM xResult ) const = 0;
private:
};
class THResultSet : public TXVObject
{
private:
PHB_ITEM aData; // Array de arrays que contiene los datos
PHB_ITEM aColumnNames; // Array de nombres de columnas
HB_SIZE uiRowCount = 0; // Total de filas
HB_SIZE uiCurrentRow; // Índice de la fila actual (base 1)
HB_SIZE uiColumnCount = 0; // Numero de columnas
public:
// Constructor y destructor /* crear otro constructor especifico para usar en TStatement sin hacer los hb_itemCopy() */
THResultSet( PHB_ITEM data, PHB_ITEM columnNames );
THResultSet();
virtual ~THResultSet() override;
// Eliminar constructor de copia y operador de asignación
THResultSet( const THResultSet & ) = delete;
THResultSet &operator=( const THResultSet & ) = delete;
// Métodos de navegación
virtual bool next(); // Avanza a la siguiente fila
virtual bool previous(); // Retrocede a la fila anterior
virtual bool first(); // Va a la primera fila
virtual bool last(); // Va a la última fila
virtual bool moveTo( HB_SIZE row ); // Va a una fila específica
virtual bool move( HB_ISIZ offset ); // Mueve el cursor un número relativo de filas
// Métodos de estado del cursor
virtual bool bof() const; // Comprueba si estamos antes de la primera fila
virtual bool eof() const; // Comprueba si estamos después de la última fila
// Métodos de acceso a datos
virtual PHB_ITEM valueByPos( HB_SIZE index ) const; // Obtiene el valor de una columna
virtual PHB_ITEM valueByName( const char *colName ) const; // Obtiene el valor de una columna
virtual inline HB_SIZE getCurrentRow() const
{
return uiCurrentRow; // Obtiene el número de fila actual
}
virtual inline HB_SIZE getRowCount() const
{
return uiRowCount; // Obtiene el número total de filas
}
virtual inline void setRowCount( HB_SIZE uiNewRowCount = 0 )
{
uiRowCount = uiNewRowCount;
}
virtual inline void setColumnCount( HB_SIZE uiNewColumnCount = 0 )
{
uiColumnCount = uiNewColumnCount;
}
inline PHB_ITEM getData() const
{
return aData;
}
inline PHB_ITEM getColumnNames() const
{
return aColumnNames;
}
private:
// Métodos auxiliares
virtual HB_SIZE findColumnIndex( const char* columnName ) const; // Busca el índice de una columna por nombre
};
//-----------------------------------------------------------------------------
#endif // _HVDBC_HPP
//-----------------------------------------------------------------------------
Espero vuestro apoyo

Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Fri Mar 07, 2025 12:28 am
by xmanuel
Marco Augusto wrote: Wed Mar 05, 2025 8:01 pm
Saludos
puedo usar MYSQL via ADO
HDBC con acceso nativo a MySQL/MaríaDb será mucho más rápida que "MYSQL vía ADO" por lo que no renta usar ADO.
Saludos
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Fri Mar 07, 2025 12:42 am
by xmanuel
Este ejemplo que pongo a continuación es una importación de la tabla "test.dbf" a PostgreSQL tarda menos 40 milisegundos en local:
Code: Select all | Expand
///////////////////////////////////////////////////////////////////////////////
// Proyecto: hdbc
// Fichero: test008.prg
// Autor: Manu Exposito
// Fecha:
// Descripcion: Traspasa test.dbf de los ejemplos de Harbour a SQL.
// Si no existe la bases de datos la crea.
// Si no existe la tabla test la crea.
// Uso de bindParam
///////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
#include "hdbc.ch"
#include "postgresql_connect.ch"
#define ID_CARGA 500
//------------------------------------------------------------------------------
// Programa principal
procedure main()
local oDb, e
local cCreaTable
TEXT INTO cCreaTable
CREATE TABLE IF NOT EXISTS test
(
id SERIAL,
first VARCHAR( 20 ),
last VARCHAR( 20 ),
street VARCHAR( 30 ),
city VARCHAR( 30 ),
state VARCHAR( 2 ),
zip VARCHAR( 10 ),
hiredate DATE,
married BOOLEAN,
age INTEGER,
salary DECIMAL( 9, 2 ),
notes VARCHAR( 70 ),
PRIMARY KEY ( id )
)
ENDTEXT
cls
msg( "Traspaso de datos..." )
try
oDb := THDbc():new( _DRIVER_ )
oDb:connect( _CONN_STRING_ )
oDb:exec( cCreaTable )
traspasa( oDb )
catch e
eval( errorBlock(), e )
finally
oDb:disconnect()
msg( "Esto es todo!!!" )
end
return
//------------------------------------------------------------------------------
// Usa sentencias preparadas en el lado del servidor y transacciones.
static procedure traspasa( oDb )
local n := 0, nSec
local oInsert
local first, last, street, city, state, zip, hiredate, married, age, salary, notes
local cSentencia := "INSERT INTO test ( first, last, street, city, state, zip, " + ;
"hiredate, married, age, salary, notes ) " + ;
"VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11 );"
if file( "test.dbf" )
use test new
oInsert := oDb:prepareStatement( cSentencia ) // Crea el objeto y prepara la sentencia
// Vincula las variables harbour con cada una de las "?" por su posicion
oInsert:bindParam( 1, @first )
oInsert:bindParam( 2, @last )
oInsert:bindParam( 3, @street )
oInsert:bindParam( 4, @city )
oInsert:bindParam( 5, @state )
oInsert:bindParam( 6, @zip )
oInsert:bindParam( 7, @hiredate )
oInsert:bindParam( 8, @married )
oInsert:bindParam( 9, @age )
oInsert:bindParam( 10, @salary )
oInsert:bindParam( 11, @notes )
nSec := hb_milliSeconds()
oDb:beginTrans()
while n < ID_CARGA
while test->( !eof() )
first := test->first
last := test->last
street := test->street
city := test->city
state := test->state
zip := test->zip
hiredate := test->hiredate
married := test->married
age := test->age
salary := test->salary
notes := test->notes
oInsert:execute()
++n
test->( dbskip( 1 ) )
end
test->( DbGoTop() )
end
oDb:commit()
nSec := hb_milliSeconds() - nSec
msg( "Se han pasado " + Hb_NToS( n ) + " registros en " + Hb_NToS( nSec ) + " milisegundos", "Uso de bindParam" )
else
msg( "Fichero test.dbf no existe" )
endif
return
//------------------------------------------------------------------------------
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Fri Mar 07, 2025 12:46 am
by xmanuel
Como podéis ver usa dos técnicas muy importantes en los lenguajes modernos:
- Las transacciones que garantizan que el proceso ha finalizado correctamente.
- Las sentencias preparadas en el lado del servidor que evitan enviar las sentencias como tramas en la red y evitan inyección de código lo que además de velocidad proporcionan seguridad total.
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Sun Apr 06, 2025 7:31 pm
by xmanuel
Si hay alguien interesado en HDBC y en alguna base de datos concreta estoy a vuestra disposición.
El que usa HDBC no se arrepiente y me da alas para seguir con la labor
Animaros!!!
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Tue Apr 08, 2025 2:19 am
by ramirezosvaldo2
Estimado Manuel
Buen dia,
Hey te acuerdas del Curso, dejamos pendientes por ver y como siempre
es un placer ver todo lo que has echo.
Saludos
Osvaldo Ramirez
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Tue Apr 08, 2025 4:46 pm
by quim_
No puedo hablar de HDBC pero viniendo de Manu, excelente programador y mejor persona, seguro que tiene que ser la bomba
Hace un par de años que utilizo THDO con MariaDB y SQLite en algún desarrollo y he tenido 0 problemas, va como un reloj suizo + un ferrari
La unica pena -para mi- es no haber probado los sistemas de Manu mucho antes
Sus productos son garantia de calidad, Enhorabuena !
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Tue Apr 08, 2025 7:04 pm
by lubin
Estimado Manu
Yo soy Usuario del Eagle1 con MYSQL que adquiri hace muchos años y luego me lo renovaste y actualizaste,, y aun sigo trabajando al 100% lo que me tienta a ver esta nueva de alternativa.
Mis consulta es :
1.Que tan dificil seria una migracion de Eagle1 a esta version HDBC o que cosas deberia de tener en cuenta.
2. Que diferencias hay teniendo presente que utilizo basicamente solo MySQL
3. Alguna referencia que es HDBC o HBO ,, son solo siglas del producto o tienen un significado especial
Muchas gracias
Saludos
Lubin Azahuanche
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Tue Apr 08, 2025 7:05 pm
by lubin
Estimado Manu
Yo soy Usuario del Eagle1 con MYSQL que adquiri hace muchos años y luego me lo renovaste y actualizaste,, y aun sigo trabajando al 100% lo que me tienta a ver esta nueva de alternativa.
Mis consulta es :
1.Que tan dificil seria una migracion de Eagle1 a esta version HDBC o que cosas deberia de tener en cuenta.
2. Que diferencias hay teniendo presente que utilizo basicamente solo MySQL
3. Alguna referencia que es HDBC o HBO ,, son solo siglas del producto o tienen un significado especial
Muchas gracias
Saludos
Lubin Azahuanche
Re: Presentamos HDBC – La Mejor Conexión a Bases de Datos para Harbour
Posted: Tue Apr 08, 2025 11:06 pm
by Lailton
Soy usuario del HDO desde la primera version. hoy lo tieno corriendo desde Win/Linux/Mac/iOS/Android.
Es una lib perfecta y muy simples de usar-la. la qualidade del projecto de Manu es muy adimiravel.
Lo tieno ahora iniciado lo uso de HDBC.
Sobre Lubin,
La diferencia de HDO y HDBC.
HDO tiene sido criado con language C y Harbour. super pontente y tiene suporte a MySQL/MariaDB/ODBC/SQLite/SQLCipher y lo HDORDD.
HDBC es una nueva herramienta com base en todos los conhecimento de Manu en Eagle1 + HDO + RDDPRO que tiene suporte a
SQLite/SQLCipher/PostgreSQL y escrita ahora C++ moderna!
La idea de Manu es portar todos los dados pero para eso necessitamos de persona interessada.
Se no hay persona que apoie lo projecto no vale la pena seguir con los demais driver.
Pero se tiver-mos mais usuarios la idea es aggregar SQL Server, Firebird, ODBC, MySQL/MariadB todo en la HDBC.
Manu es una persona y profissinal admiravel, su dedicacion ao projecto es fantastica.
seguramiente se tiver outros banco de dados necessario, Manu se proponhe a hacer-lo tambien.
No tieno usado Eagle1 no lo sei cual dificil seria una migracion, pero aseguro que HDO es muy simples e rapido!