Pascal Data Objects

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.