function TPDO.connect (dsn, user_id, password: AnsiString): Boolean; overload;
function TPDO.connect (dsn, user_id, password: AnsiString; CustomListener: TZAbstractLoggingListener): Boolean; overload;
This overloaded method establishes a connection to the database. Both versions accept a Database Source Name, a user ID, and a password. These DSN strings are driver dependent, so look up the keywords. The second version adds an optional logging listener.
procedure dbtest; var db: TPDO; begin db := TPDO.create; if (db.connect('pdo:mysql-4.1://host=localhost;dbname=testdb','testuser','testpasswd')) then writeln ('connection succeeded.') else writeln ('connection failed.'); db.disconnect; db.free; end;
It's not strictly necessarily to disconnect a connection. Any open connection will be closed when the TPO object is freed.
The logging listener provides a way to handle errors and normal feedback from the TPO object. Normally this would log the messages to a file or perhaps a TMemo object. Here's the defined interface and abstract object:
{** Defines an interface to accept logging events. } IZLoggingListener = interface (IInterface) ['{53559F5F-AC22-4DDC-B2EA-45D21ADDD2D4}'] procedure LogEvent(Event: TZLoggingEvent); end; TZAbstractLoggingListener = class(TInterfacedObject, IZLoggingListener) public procedure LogEvent (Event: TZLoggingEvent); virtual; abstract; end; {** Defines a time or the message. } TZLoggingCategory = (lcConnect, lcDisconnect, lcTransaction, lcExecute, lcOther, lcPrepStmt, lcExecPrepStmt); {** Defines a object for logging event. } TZLoggingEvent = class (TObject) private FCategory: TZLoggingCategory; FProtocol: string; FMessage: string; FErrorCode: Integer; FError: string; FTimestamp: TDateTime; public constructor Create(Category: TZLoggingCategory; Protocol: string; Msg: string; ErrorCode: Integer; Error: string); function AsString: string; property Category: TZLoggingCategory read FCategory; property Protocol: string read FProtocol; property Message: string read FMessage; property ErrorCode: Integer read FErrorCode; property Error: string read FError; property Timestamp: TDateTime read FTimestamp; end;
Once the custom logging listener is defined (outside the scope of PDO), a handle to it can be passed to the database connection. The DSN must be prefixed by "PDO:" followed by the desired driver, e.g. "mysql-4.1". The list of available drivers can be obtained with the TPDO.getAvailableDrivers function.
unit dbTestor; interface uses PDO, PDOStatement, PDOLogging, StdCtrls, SysUtils; type TMyLogListener = Class (TZAbstractLoggingListener) public myLogFile: Textfile; myLogFilePath: Ansistring; procedure LogEvent(Event: TZLoggingEvent); override; end; procedure dbtest; implementation procedure TMyLogListener.LogEvent(Event: TZLoggingEvent); var logline: AnsiString; LogIt: Boolean; begin if (Event.ErrorCode <> 0) then begin {$IFDEF BINARY_RELEASE} LogIt := true; {$ENDIF} logline := Event.AsString; if (Event.Category = lcConnect) then logline := Format ('%s%s: %s', [AnsiUppercase( FormatDateTime('dd mmm yy/',Date)), FormatDateTime('hh:nn:ss', Time),'Remote database connection failure']); end; {$IFNDEF BINARY_RELEASE} LogIt := true; Logline := 'DEBUG: ' + Event.AsString; {$ENDIF} if (LogIt and assigned(myMemo)) then begin AssignFile (self.myLogFile, self.myLogFilePath); if FileExists (self.myLogFilePath) then Append (self.myLogFile) else Rewrite (self.myLogFile); try Writeln (self.myLogFile, logline); finally CloseFile (self.myLogFile); end; end; end; procedure dbtest; var db: TPDO; listener: TMyLogListener; begin db := TPDO.create; listener := TMyLogListener.create; listener.myLogFilePath := ExtractFilePath(Application.EXEName); listener.myLogFile := listener.myLogFilePath + 'mylog.txt'; if (db.connect('PDO:pgsql-8.1://host=10.0.0.154;port=5467;dname=elphants','smith','jellybeans',listener)) then writeln ('connection succeeded.') else writeln ('connection failed.'); db.disconnect; db.free; end; end.