Uso no xHarbou no ambiente Windows, criando um objeto ADO para manipular DB com SQL, segue abaixo meus códigos de conexão (com ajuda do Quintas).
Código: Selecionar todos
#define AD_USE_CLIENT 3
#include "Gas.ch"
#include "Fileio.ch"
#include "ADO.CH" // inicializa constantes manifestas
/////////////////////////////////////////////////////////////////////////////
FUNCTION PostgreSQLConnection( cServer, cUser, cPassword, cDatabase, cPort )
LOCAL cnConnection
Default( @cPort, '5432')
If InternetCheca()
cnConnection := CreateObject( "ADODB.Connection" )
cnConnection:ConnectionString := "Driver={PostgreSQL ODBC Driver(UNICODE)}"+;
";Server=" + cServer +;
";Port=" + cPort+;
";Database=" + cDatabase +;
";Uid=" + cUser +;
";Pwd=" + cPassword
cnConnection:CursorLocation := AD_USE_CLIENT
cnConnection:CommandTimeOut := 600 // seconds
cnConnection:ConnectionTimeOut := 600 // seconds
Try
cnConnection:open()
CATCH oError
cnConnection := CreateObject( "ADODB.Connection" )
cnConnection:ConnectionString := "Driver={PostgreSQL Unicode}"+;
";Server=" + cServer +;
";Port=" + cPort+;
";Database=" + cDatabase +;
";Uid=" + cUser +;
";Pwd=" + cPassword
cnConnection:CursorLocation := AD_USE_CLIENT
cnConnection:CommandTimeOut := 600 // seconds
cnConnection:ConnectionTimeOut := 600 // seconds
Try
cnConnection:open()
CATCH oError
msg := 'ADODB: 905'+HB_Eol()
msg += 'Aviso..: Não consegui Abrir com o Banco de dados PostgreSQL.'+HB_Eol()
msg += '- Verifique em Fontes ODBC se existr os Driver "PostgeSQL Unicode" ou "PostGreSQL ODBC Driver(UNICODE)".'+HB_Eol()
msg += '- Acesse a central de downloads (central.simplesinformatica.com) e baixe na aba de "Utilitários" o Driver de Conexão e instale-o para completar esta ação.'+HB_Eol()
msg += HB_Eol()+cl_getError(oError, .t., cnConnection)
MsgAtencao ( msg )
cnConnection := nil
End
End
Endif
RETURN cnConnection
////////////////////////////////////////////////////////////////////////////////
//Abre a conexão
Function OpenConexaoPGSql()
Local msg := '', r := .t., oError
Begin Sequence
If Type( 'oCn' ) <> 'O'
oCN := PostgreSQLConnection( mServerDB, mDbUser, mSenhaPG, mDbName, mServerPort )
If Ocn = Nil
r := .f.
Endif
Else
If oCn:state <> adStateOpen
oCN := PostgreSQLConnection( mServerDB, mDbUser, mSenhaPG, mDbName, mServerPort )
If Ocn = Nil
r := .f.
Endif
EndIf
EndIf
If Valtype(oCn) = 'O'
GetActiveState()
EndIf
End Sequence
Return r
Function GetStatusConexaoDB()
Local r := 'OFF'
If Type( 'oCn' ) = 'O'
If oCn:state = adStateOpen
r := 'ON'
EndIf
Else
r := 'NUL'
EndIf
Return r
//Busca dados dos IPs
//https://raphaleao.medium.com/monitorando-conex%C3%B5es-no-postgresql-com-pg-stat-activity-daf4ae171d47
Procedure GetActiveState()
//Local mExecute, oRs, msg, mRet, i
Local mJson, mHash := {=>}, x
aActiveState := {}
mJson := SendGetPing( mApiUtilitarioAuthorization )
hb_jsonDecode(mJson, @mHash)
If mHash <> nil
If Len( mHash ) > 0
AAdd(aActiveState, {;
HGet(mHash, 'remote_ip'),;
HGet(mHash, 'timestamp');
})
Else
AAdd(aActiveState, {;
'',;
'';
})
Endif
Else
AAdd(aActiveState, {;
'',;
'';
})
Endif
/*
Begin Sequence
aActiveState := {}
//mExecute := "SELECT * FROM pg_stat_activity;"
mExecute := "WITH current_connection AS ("
mExecute += " SELECT pg_backend_pid() AS pid"
mExecute += ") "
mExecute += "SELECT"
mExecute += " a.pid,"
mExecute += " a.client_addr,"
mExecute += " a.state,"
mExecute += " a.query_start "
mExecute += "FROM"
mExecute += " pg_stat_activity a "
mExecute += "JOIN"
mExecute += " current_connection c ON a.pid = c.pid;"
Try
oRs := oCn:Execute( mExecute )
CATCH oError
msg := 'ADODB: 007' + CRLF
msg += 'Aviso..: Não consegui a espressão SQL para verificar os IPs.' + CRLF
msg += CRLF + cl_getError(oError, .t., oCn)
msgError ( msg, .t. )
mRet := .f.
Break
End
oRs:MoveFirst()
For i := 1 To oRs:RecordCount()
If !Empty( oRs:Fields("query_start"):Value)
AAdd(aActiveState, {;
oRs:Fields("pid"):Value,; //Número do processo que está em execução
oRs:Fields("query_start"):Value,; //Data e hora de início da execução do processo.
oRs:Fields("client_addr"):Value,; //Endereço ip de onde está sendo solicitado o comando.
oRs:Fields("state"):Value; //Status do comando
})
EndIf
oRs:MoveNext()
Next
aSort(aActiveState,,, { |x, y| x[2] > y[2]} )
If oRs:state = adStateOpen
oRs:Close()
EndIf
End Sequence
*/
Return
PS. Vá mudando conforme sua necessidade, tipo, se vai abrir um banco de dados ou dois, se vai permanecer com o mesmo banco aberto, essas coisas.
Abraços