WDO MySQL - Configurazione¶
Ci sono tre modi per avviare il pool MySQL. Quello consigliato è il dichiarativo da config.json.
Metodo 1 - Dichiarativo (consigliato)¶
Aggiungi la sezione databases in www/config.json:
{
"databases": {
"mysql": {
"driver": "mysql",
"host": "127.0.0.1",
"user": "harbour",
"pwd": "hb1234",
"db": "employees",
"port": 3306,
"pool_size": 5,
"timeout_ms": 5000,
"ping": true,
"read_timeout_s": 30,
"connect_timeout_s": 10,
"berror": "WDO_DefaultErrorHandler"
}
}
}
In app.prg con hixstyle non hai bisogno di altro: Start() chiama automaticamente HIX_InitPoolsFromConfig() e HIX_EndPoolsFromConfig().
In app senza hixstyle:
PROCEDURE Main()
LOCAL oSrv := THixServer():New()
HIX_ConfigAppLoad( "www/config.json" )
HIX_InitPoolsFromConfig() // interrompe se qualche pool fallisce (default)
oSrv:Start()
IF oSrv:hThread != NIL
hb_threadJoin( oSrv:hThread )
ENDIF
HIX_EndPoolsFromConfig()
RETURN
Pool multipli¶
Puoi dichiarare più database con chiavi distinte:
{
"databases": {
"mysql": { "driver": "mysql", "host": "127.0.0.1", ... },
"analytics": { "driver": "mariadb", "host": "10.0.0.42", ... }
}
}
Negli handler: WDO_Get("mysql") e WDO_Get("analytics") coesistono nello stesso processo.
Campi disponibili¶
| Campo | Default | Descrizione |
|---|---|---|
driver |
(obbligatorio) | "mysql" o "mariadb" (case-insensitive) |
host |
"localhost" |
IP o hostname del server |
user |
"" |
Utente di autenticazione |
pwd |
"" |
Password |
db |
"" |
Database di default |
port |
3306 |
Porta TCP |
pool_size |
5 |
Numero di connessioni all'avvio |
timeout_ms |
5000 |
Tempo massimo di attesa in WDO_Get() (0 = infinito) |
ping |
true |
Ping prima di consegnare ogni slot; riconnette se è inattivo |
read_timeout_s |
30 |
Timeout di lettura/scrittura del socket MySQL in secondi (0 = senza timeout). Limita il blocco in recv() quando un thread figlio del dispatcher supera exec_timeout_ms; senza di esso la connessione diventa zombie e lo slot non torna mai al pool |
connect_timeout_s |
10 |
Timeout della fase di connessione al server in secondi (0 = senza timeout). Evita che l'avvio del pool rimanga bloccato se il server MySQL non risponde |
debug |
false |
Se un pool ha "debug": true, HIX_Dbg() globale viene attivato: dbg.log registra Acquire/Release del pool e ogni HIX_Dbg() strumentato nei controller. dbg.log viene svuotato all'avvio. Solo in sviluppo — ha costo di I/O. |
berror |
- | Nome della funzione Harbour per gestire gli errori del pool |
dll |
- | Percorso esplicito alla DLL (override della risoluzione automatica) |
Relazione con exec_timeout_ms
read_timeout_s deve essere maggiore della query legittima più lenta e in linea con exec_timeout_ms del dispatcher (in hix.json). Se aumenti exec_timeout_ms, aumenta anche read_timeout_s: se una query dura più del socket read timeout, MySQL restituirà errore prima che la query termini.
berror di default
"berror": "WDO_DefaultErrorHandler" è già incluso nella lib: registra l'errore con le() e restituisce 500 se c'è una richiesta attiva. Sufficiente per la maggior parte dei progetti.
Metodo 2 - Programmatico hash¶
WDO_InitPoolMySqlEx( "mysql", { ;
"host" => hb_GetEnv( "DB_HOST" ), ;
"user" => hb_GetEnv( "DB_USER" ), ;
"pwd" => hb_GetEnv( "DB_PWD" ), ;
"db" => "employees", ;
"pool_size" => 10, ;
"timeout_ms" => 5000, ;
"ping" => .T., ;
"berror" => "WDO_DefaultErrorHandler" ;
} )
Utile quando le credenziali vengono lette da variabili d'ambiente o segreti.
Metodo 3 - Posizionale (legacy)¶
WDO_InitPoolMySql( "localhost", "harbour", "hb1234", "employees", 3306, ;
5, /* pool_size */ ;
5000, /* timeout_ms */ ;
.T., /* ping */ ;
{|oErr, oConn| WdoErrorHandler( oErr, oConn ) } )
Registra il pool sotto la chiave fissa "MYSQL". Compatibile con codice precedente alla v2.3.01.
DLL - driver MySQL vs MariaDB¶
Il driver richiede la libreria client del protocollo MySQL:
"driver" |
DLL Windows | SO Linux |
|---|---|---|
"mysql" |
libmysql64.dll |
libmysqlclient.so |
"mariadb" |
libmariadb64.dll |
libmariadb.so |
Precedenza di risoluzione della DLL¶
Il driver cerca la libreria in questo ordine (priorità maggiore prima):
- Campo
"dll"inconfig.json- percorso assoluto esplicito per pool. - Variabile d'ambiente
WDO_LIB_MYSQL- percorso assoluto al file. - Variabile d'ambiente
WDO_PATH_MYSQL- directory; il driver aggiunge il nome canonico. - Directory dell'eseguibile (
hb_DirBase()). - PATH di sistema - nome canonico senza percorso.
Diagnostica¶
oSrv:AddRouteGet( "dbinfo", "/dbinfo", {||
LOCAL oConn := WDO_Get( "mysql" )
IF oConn == NIL ; RETURN USendError( 503, "pool unavailable" ) ; ENDIF
USendJson( { ;
"dll_source" => oConn:DllSource(), ;
"dll_path" => oConn:DllPath(), ;
"server" => oConn:mysql_get_server_info() ;
} )
oConn:Close()
} )
DllSource() restituisce "override", "WDO_LIB_MYSQL", "WDO_PATH_MYSQL", "exedir" o "default".
Se la DLL non viene trovata¶
Il pool fallisce all'avvio e scrive in console:
Con HIX_InitPoolsFromConfig(.T.) il server si interrompe. Con .F. continua, ma WDO_Get("mysql") restituirà NIL e gli handler risponderanno con 503.
Gestore degli errori personalizzato¶
Se hai bisogno di logica custom (alert Slack, metriche, ecc.), definisci una funzione pubblica:
FUNCTION WdoErrorHandler( oErr, oConn )
HB_SYMBOL_UNUSED( oConn )
le( "[WDO] " + oErr:description + " @ " + oErr:operation )
IF HIX_GetRequest() != NIL
USendError( 500, "DB error: " + oErr:description )
ENDIF
RETURN NIL
E referenziala nel JSON: