I copied this from your suggested code snippets when I was asking for a RemoteDB connection to Firebird...
I't was the only way to catch and log the Connect and Disconnect events of our mobile devices that I had to trace and log...
type
TphxRemoteDBModule = class(TRemoteDBModule)
and the connection module:
unit data.ConnectionModule;
interface
uses
Aurelius.Drivers.Interfaces,
Aurelius.SQL.Firebird,
Aurelius.Schema.Firebird,
Aurelius.Drivers.FireDac,
System.SysUtils, System.Classes, System.StrUtils,
FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Phys.IBWrapper,
FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, Data.DB,
FireDAC.Comp.Client, FireDAC.Phys.FB, FireDAC.Phys.FBDef,
FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt,
FireDAC.Comp.DataSet,
units.Common, units.Logme, FireDAC.VCLUI.Wait;
type
TFireDacFirebirdConnection = class(TDataModule)
Connection: TFDConnection;
procedure ConnectionAfterConnect(Sender: TObject);
procedure ConnectionLost(Sender: TObject);
procedure ConnectionAfterDisconnect(Sender: TObject);
procedure ConnectionError(ASender, AInitiator: TObject; var AException: Exception);
procedure ConnectionLogin(AConnection: TFDCustomConnection; AParams: TFDConnectionDefParams);
procedure ConnectionRecover(ASender, AInitiator: TObject; AException: Exception; var AAction: TFDPhysConnectionRecoverAction);
procedure ConnectionRestored(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject); // solo un wrapper a PostMemoLog, ma sempre via API PostMessage !
private
public
class function CreateConnection: IDBConnection;
class function CreateFactory: IDBConnectionFactory;
end;
implementation
{%CLASSGROUP 'Vcl.Controls.TControl'}
uses
Aurelius.Drivers.Base, data.Module;
{$R *.dfm}
{ TMyConnectionModule }
class function TFireDacFirebirdConnection.CreateFactory: IDBConnectionFactory;
begin
Result := TDBConnectionFactory.Create(
function: IDBConnection
begin
Result := CreateConnection;
end
);
end;
procedure TFireDacFirebirdConnection.DataModuleDestroy(Sender: TObject);
begin //** Disabled!
LogStep(5008, 'Destroy - FireDac DISCONNECTED');
end;
class function TFireDacFirebirdConnection.CreateConnection: IDBConnection;
var
aDataModule: TFireDacFirebirdConnection;
begin
aDataModule := TFireDacFirebirdConnection.Create(nil);
(*
When you create an IDBConnection interface using a component adapter,
usually the adapter will automatically retrieve the correct SQL dialect to use.
in some situations, the adapter is not able to identify the correct
dialect (for example, when you are using ODBC)In this case, when creating the adapter,
you can use an overloaded constructor that allows you to specify the SQL
dialect to use: 'Firebird'.
*)
aDataModule.Connection.Params.Database := dataMain.SysDBpath; // 'C:\PhxDB\PHXnew.FDB'; //S.Chiara TN
aDataModule.Connection.Connected := True; // sembra non necessario.
Result := TFireDacConnectionAdapter.Create(aDataModule.Connection, 'Firebird', aDataModule);
(*
It's possible that you already have your database-access component
configured in a TDataModule and you don't want to create it from code. In this
case, you can just create a new instance of the data module and return the
IDBConnection associated to the component.
***
But you must be sure to destroy the data module (not only the database-access component) to avoid memory leaks !
***
*)
end;
procedure TFireDacFirebirdConnection.ConnectionAfterConnect(Sender: TObject);
begin //** Disabled!
LogStep(5000, 'FireDac CONNECTED');
end;
procedure TFireDacFirebirdConnection.ConnectionAfterDisconnect(Sender: TObject);
begin //** Disabled!
LogStep(5001, 'FireDac DISCONNECT');
// "RemoteDB server is destroying the database component when the client asks for disconnection.
// In that case, the AfterDisconnect event is not fired"
end;
procedure TFireDacFirebirdConnection.ConnectionError(ASender, AInitiator: TObject; var AException: Exception);
var
exMsg: string;
begin
if (AException is EIBNativeException) and (ContainsText(AException.Message, 'attempt to store duplicate value')
or ContainsText(AException.Message, 'violation of PRIMARY or UNIQUE KEY') ) then begin
exMsg := 'FireDac Insert skipped, Duplicate record in PhxDB >> ';
// Qui posso solo fare un parsing dell' AException
// per cercare keyword specifiche che mi interessano, tipo "duplicate value" o "violation of PRIMARY" !
end
else begin
// Se Exception generica, segnalo errore.
exMsg := 'FireDac ERROR >> ';
end;
// sempre Log su db e memo!
exMsg := exMsg + '#class:'+ AException.ClassName +' #msg:'+AException.Message;
LogDevEvent(5006, svERROR, StringReplace(exMsg, sLineBreak, ', ', [rfReplaceAll] )); // Elimina i CR+LF spesso presenti nelle Db Exceptions, per visualizzazione lineare !
end;
procedure TFireDacFirebirdConnection.ConnectionLogin(AConnection: TFDCustomConnection; AParams: TFDConnectionDefParams);
begin
LogStep(5003, 'FireDac Login');
end;
procedure TFireDacFirebirdConnection.ConnectionLost(Sender: TObject);
begin
LogDevEvent(5002, svWARNING, 'LOST FireDac Connection !');
end;
procedure TFireDacFirebirdConnection.ConnectionRecover(ASender, AInitiator: TObject; AException: Exception; var AAction: TFDPhysConnectionRecoverAction);
begin
LogStep(5004, 'FireDac Connection Recover');
end;
procedure TFireDacFirebirdConnection.ConnectionRestored(Sender: TObject);
begin
LogStep(5005, 'FireDac Connection Restored');
end;
end.