ZEOS database component like TDabatase or TIBDatabase

In this forum we will discuss things relating the ZEOSLib 6.6.x stable versions

Moderators: gto, EgonHugeist

una.bicicleta
Fresh Boarder
Fresh Boarder
Posts: 15
Joined: 28.03.2010, 17:52

ZEOS database component like TDabatase or TIBDatabase

Post by una.bicicleta »

Do ZEOS have a component like TDatabase (for BDE) or TIBDatabase (for IBExpress)? so I don't have to set the protocol, username and password for every ZConnection in my form ?

Thanks..!
seawolf
Zeos Dev Team *
Zeos Dev Team *
Posts: 385
Joined: 04.06.2008, 19:50
Contact:

Post by seawolf »

Zeos does not have a sort of TDatabase component and, at the moment, is a feature which will NOT be implemented in short/medium time
una.bicicleta
Fresh Boarder
Fresh Boarder
Posts: 15
Joined: 28.03.2010, 17:52

Post by una.bicicleta »

I see... , thanks for the answer.
I tried to create my own components based on TZConnection class, and this is my working component so far: TZDbConnection and TZTransaction.

Code: Select all

unit ZTransaction;

interface

{$I ZComponent.inc}

uses
  Types, SysUtils, Classes, ZDbcIntfs, DB, ZDbcAdoUtils,Forms,
  ZCompatibility, ZConnection, ZSequence, Dialogs;

type
  TZDbConnection = class;
  TZDbConnectionLink = class;

  TZDbConnectionLink = class(TObject)
  private
    FSender: TObject;
    FOnChange: TNotifyEvent;
  public
    destructor Destroy; override;
    procedure Change;
    dynamic;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property Sender: TObject read FSender write FSender;
  end;

  TZDbConnection = class(TComponent)
  protected
    FClients: tList;
    FProtocol: string;
    FHostName: string;
    FPort: Integer;
    FDatabase: string;
    FUser: string;
    FPassword: string;
    procedure UnregisterAllDataSets;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure RegisterChanges(Value: TZDbConnectionLink);
    procedure UnregisterChanges(Value: TZDbConnectionLink);
  published
    property Protocol: string read FProtocol write FProtocol;
    property HostName: string read FHostName write FHostName;
    property Port: Integer read FPort write FPort default 0;
    property Database: string read FDatabase write FDatabase;
    property User: string read FUser write FUser;
    property Password: string read FPassword write FPassword;
  end;

type
  TZTransaction = class(TZConnection)
  protected
    FDbConnection: TZDbConnection;
    FDbConnectionLink: TZDbConnectionLink;
    //FUser: string;
    //FProtocol: string;
    //FPassword: string;
    //FHostName: string;
    //FDatabase: string;
    procedure SetDbConnection(Value: TZDbConnection);
    //procedure loaded; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation);
      override;
  private
    function getUser: string;
    function getProtocol: string;
    function getPassword: string;
    function getHostName: string;
    function getDatabase: string;

  published
    property DBConnection: TZDbConnection read FDbConnection write SetDbConnection;

    property User: string read getUser;
    property Protocol: string read getProtocol ;
    property Password: string read getPassword ;
    property HostName: string read getHostName ;
    property Database: string read getDatabase ;
  public
  end;

implementation

// === { TZDbConnectionLink } ====================================================
destructor TZDbConnectionLink.Destroy;
begin
  if Sender is TZDbConnection then
    TZDbConnection(Sender).UnregisterChanges(Self);
  inherited Destroy;
end;

procedure TZDbConnectionLink.Change;
begin
  if Assigned(FOnChange) then
    FOnChange(Sender);
end;

// === { TZDbConnection } =============================================
constructor TZDbConnection.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FClients := tList.Create;
  // -- todo ----
  // property onChange event ???
end;

destructor TZDbConnection.Destroy;
begin
  UnregisterAllDataSets;
  FClients.Free;
  inherited Destroy;
end;

procedure TZDbConnection.UnregisterAllDataSets;
var
  I: Integer;
  Current: TZDbConnectionLink;
begin
  for I := FClients.Count - 1 downto 0 do
  begin
    Current := TZDbConnectionLink(FClients[I]);
    FClients.Remove(Current);
    //try
      // Current.Connection := nil; ???
    //except
      // Ignore.
    //end;
  end;
end;

procedure TZDbConnection.RegisterChanges(Value: TZDbConnectionLink);
begin
  Value.Sender := Self;
  if FClients <> nil then
    FClients.Add(Value);
end;

procedure TZDbConnection.UnregisterChanges(Value: TZDbConnectionLink);
var
  I: Integer;
begin
  if FClients <> nil then
    for I := 0 to FClients.Count - 1 do
      if FClients[I] = Value then
      begin
        Value.Sender := nil;
        FClients.Delete(I);
        Break;
      end;
end;

// === { TZTransaction } =============================================
procedure TZTransaction.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);

  if (Operation = opRemove) then
  begin
    if (AComponent is TDataset) then
      UnregisterDataSet(TDataset(AComponent));
    if (AComponent is TZSequence) then
      UnregisterSequence(TZSequence(AComponent));
    if (AComponent = FDbConnection) then
      FDbConnection := nil;
  end;
end;

function ReplaceComponentReference(This, NewReference: TComponent;
  var VarReference: TComponent): Boolean;
begin
  Result := (VarReference <> NewReference) and Assigned(This);
  if Result then
  begin
    if Assigned(VarReference) then
      VarReference.RemoveFreeNotification(This);
    VarReference := NewReference;
    if Assigned(VarReference) then
      VarReference.FreeNotification(This);
  end;
end;

procedure TZTransaction.SetDbConnection(Value: TZDbConnection);
begin
  if FDbConnection <> Value then
  begin
    FDbConnection := Value;
    if FDbConnection <> nil then
    begin
      FUser := FDbConnection.User;
      FProtocol := FDbConnection.Protocol;
      FPassword := FDbConnection.Password;
      FHostName := FDbConnection.HostName;
      FDatabase := FDbConnection.Database;
    end
  end;
end;

function TZTransaction.getUser: string;
begin
  if FDbConnection <> nil then
  begin
    FUser := FDbConnection.User;
    Result := FUser;
  end
  else
    FUser := '';
end;

function TZTransaction.getProtocol: string;
begin
  if FDbConnection <> nil then
  begin
    FProtocol := FDbConnection.Protocol;
    Result := FProtocol;
  end
  else
    FProtocol := '';
end;

function TZTransaction.getPassword: string;
begin
  if FDbConnection <> nil then
  begin
    FPassword := FDbConnection.Password;
    Result := FPassword;
  end
  else
    FPassword := '';
end;

function TZTransaction.getHostName: string;
begin
  if FDbConnection <> nil then
  begin
    FHostName := FDbConnection.HostName;
    Result := FHostName;
  end
  else
    FHostName := '';
end;

function TZTransaction.getDatabase: string;
begin
  if FDbConnection <> nil then
  begin
    FDatabase := FDbConnection.Database;
    Result := FDatabase;
  end
  else
    FDatabase := '';
end;

end.
I make some modification in ZPropertyEditor.pas too for TZDbConnection database and protocol.
I really appreciate if anyone can help me to remove unnecessary code and improve this component.

Thanks....!
una.bicicleta
Fresh Boarder
Fresh Boarder
Posts: 15
Joined: 28.03.2010, 17:52

Post by una.bicicleta »

Another fix for my component:

Code: Select all

unit ZTransaction;

interface
{$I ZComponent.inc}

uses
  Types, SysUtils, Classes, ZDbcIntfs, DB, ZDbcAdoUtils,Forms,
  ZCompatibility, ZConnection, ZSequence, Dialogs, ZDbConnection;

type
  TZTransaction = class(TZConnection)
  protected
    FZDbConnection: TZDbConnection;
    FZDbConnectionLink: TZDbConnectionLink;
    procedure SetDbConnection(Value: TZDbConnection);
    procedure Notification(AComponent: TComponent; Operation: TOperation);
      override;
  private
    function getUser: string;
    function getProtocol: string;
    function getPassword: string;
    function getHostName: string;
    function getDatabase: string;
    procedure DoZDbConnectionChange(Sender: TObject);
  published
    property DBConnection: TZDbConnection read FZDbConnection write SetDbConnection;

    property User: string read getUser;
    property Protocol: string read getProtocol ;
    property Password: string read getPassword ;
    property HostName: string read getHostName ;
    property Database: string read getDatabase ;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

// === { TZTransaction } =============================================
constructor TZTransaction.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FZDbConnectionLink := TZDbConnectionLink.Create;
  FZDbConnectionLink.OnChange := DoZDbConnectionChange;
end;

procedure TZTransaction.DoZDbConnectionChange(Sender: TObject);
begin
  if (Sender is TZDbConnection) then
  begin
    FUser := (Sender as TZDbConnection).User;
    FProtocol := (Sender as TZDbConnection).Protocol;
    FPassword := (Sender as TZDbConnection).Password;
    FHostName := (Sender as TZDbConnection).HostName;
    FDatabase := (Sender as TZDbConnection).Database;
  end;
end;

destructor TZTransaction.Destroy;
begin
  FZDbConnectionLink.Free;
  inherited Destroy;
end;

procedure TZTransaction.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);

  if (Operation = opRemove) then
  begin
    if (AComponent is TDataset) then
      UnregisterDataSet(TDataset(AComponent));
    if (AComponent is TZSequence) then
      UnregisterSequence(TZSequence(AComponent));
    if (AComponent = FZDbConnection) then
      FZDbConnection := nil;
  end;
end;

procedure TZTransaction.SetDbConnection(Value: TZDbConnection);
begin
  FZDbConnection := Value;
  if Value <> nil then
  begin
      FUser := FZDbConnection.User;
      FProtocol := FZDbConnection.Protocol;
      FPassword := FZDbConnection.Password;
      FHostName := FZDbConnection.HostName;
      FDatabase := FZDbConnection.Database;
  end;
end;

function TZTransaction.getUser: string;
begin
  if FZDbConnection <> nil then
  begin
    FUser := FZDbConnection.User;
    Result := FUser;
  end
  else
    FUser := '';
end;

function TZTransaction.getProtocol: string;
begin
  if FZDbConnection <> nil then
  begin
    FProtocol := FZDbConnection.Protocol;
    Result := FProtocol;
  end
  else
    FProtocol := '';
end;

function TZTransaction.getPassword: string;
begin
  if FZDbConnection <> nil then
  begin
    FPassword := FZDbConnection.Password;
    Result := FPassword;
  end
  else
    FPassword := '';
end;

function TZTransaction.getHostName: string;
begin
  if FZDbConnection <> nil then
  begin
    FHostName := FZDbConnection.HostName;
    Result := FHostName;
  end
  else
    FHostName := '';
end;

function TZTransaction.getDatabase: string;
begin
  if FZDbConnection <> nil then
  begin
    FDatabase := FZDbConnection.Database;
    Result := FDatabase;
  end
  else
    FDatabase := '';
end;

end.

Code: Select all

unit ZDbConnection;

interface
{$I ZComponent.inc}

uses
  Types, SysUtils, Classes, ZDbcIntfs, DB, ZDbcAdoUtils,Forms,
  ZCompatibility, ZConnection, ZSequence, Dialogs;

type
  TZDbConnection = class;
  TZDbConnectionLink = class;

  TZDbConnectionLink = class(TObject)
  private
    FSender: TObject;
    FOnChange: TNotifyEvent;
  public
    destructor Destroy; override;
    procedure Change;
    dynamic;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property Sender: TObject read FSender write FSender;
  end;

  TZDbConnection = class(TComponent)
  protected
    FClients: tList;
    FProtocol: string;
    FHostName: string;
    FPort: Integer;
    FDatabase: string;
    FUser: string;
    FPassword: string;
    procedure UnregisterAllDataSets;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure RegisterChanges(Value: TZDbConnectionLink);
    procedure UnregisterChanges(Value: TZDbConnectionLink);
  published
    property Protocol: string read FProtocol write FProtocol;
    property HostName: string read FHostName write FHostName;
    property Port: Integer read FPort write FPort default 0;
    property Database: string read FDatabase write FDatabase;
    property User: string read FUser write FUser;
    property Password: string read FPassword write FPassword;
    // -- todo ----
    // add another property or event ?
  end;

implementation

// === { TZDbConnectionLink } ====================================================

destructor TZDbConnectionLink.Destroy;
begin
  if Sender is TZDbConnection then
    TZDbConnection(Sender).UnregisterChanges(Self);
  inherited Destroy;
end;

procedure TZDbConnectionLink.Change;
begin
  if Assigned(FOnChange) then
    FOnChange(Sender);
end;


// === { TZDbConnection } =============================================
constructor TZDbConnection.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FClients := tList.Create;
end;

destructor TZDbConnection.Destroy;
begin
  UnregisterAllDataSets;
  FClients.Free;
  inherited Destroy;
end;

procedure TZDbConnection.UnregisterAllDataSets;
var
  I: Integer;
  Current: TZDbConnectionLink;
begin
  for I := FClients.Count - 1 downto 0 do
  begin
    Current := TZDbConnectionLink(FClients[I]);
    FClients.Remove(Current);
    //try
      // Current.Connection := nil; ???
    //except
      // Ignore.
    //end;
  end;
end;

procedure TZDbConnection.RegisterChanges(Value: TZDbConnectionLink);
begin
  Value.Sender := Self;
  if FClients <> nil then
    FClients.Add(Value);
end;

procedure TZDbConnection.UnregisterChanges(Value: TZDbConnectionLink);
var
  I: Integer;
begin
  if FClients <> nil then
    for I := 0 to FClients.Count - 1 do
      if FClients[I] = Value then
      begin
        Value.Sender := nil;
        FClients.Delete(I);
        Break;
      end;
end;

end.
Hope someone can improved this components. thanks
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Hi,

Can you explain me the exact advantage of these new components? I don't see the immediate positive effects just from the code.

Mark
Image
una.bicicleta
Fresh Boarder
Fresh Boarder
Posts: 15
Joined: 28.03.2010, 17:52

Post by una.bicicleta »

I use ZDbConnection to store User, Password, Database, Port and Protocol.
Every Ztransaction which connected to ZDbConnection in design or run time, didn't have to provide with the same User,Password or Database again.

In my project design, I use 1 ZDbConnection in Data Module, and ZTransaction in other forms. By changing ZdbConnection properties in Data Module, every ZTransaction properties in the other form will be changed too.
(sorry for my English)

This is my recent source code for the component

Code: Select all

unit ZDbConnection;

interface
{$I ZComponent.inc}

uses
  Types, SysUtils, Classes, ZDbcIntfs, DB, ZDbcAdoUtils,Forms,
  ZCompatibility, ZConnection, ZSequence, Dialogs;

type
  TZDbConnection = class;
  TZDbConnectionLink = class;

  TZDbConnectionLink = class(TObject)
  private
    FSender: TObject;
    FOnChange: TNotifyEvent;
  public
    destructor Destroy; override;
    procedure Change;
    dynamic;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property Sender: TObject read FSender write FSender;
  end;

  TZDbConnection = class(TComponent)
  private
    FOnChange: TNotifyEvent;
    procedure DoChange(Sender: TObject);
    procedure Change;
  protected
    FClients: tList;
    FProtocol: string;
    FHostName: string;
    FPort: Integer;
    FDatabase: string;
    FUser: string;
    FPassword: string;
    procedure UnregisterAllDataSets;
    procedure SetUser(const Value: string);
    procedure SetPassword(const Value: string);
    procedure SetProtocol(const Value: string);
    procedure SetHostName(const Value: string);
    procedure SetPort(const Value: integer);
    procedure SetDatabase(const Value: string);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure RegisterChanges(Value: TZDbConnectionLink);
    procedure UnregisterChanges(Value: TZDbConnectionLink);
  published
    property Protocol: string read FProtocol write SetProtocol;
    property HostName: string read FHostName write SetHostName;
    property Port: Integer read FPort write SetPort default 0;
    property Database: string read FDatabase write SetDatabase;
    property User: string read FUser write SetUser;
    property Password: string read FPassword write SetPassword;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    // -- todo ----
    // add another property or event ?
  end;

implementation

// === { TZDbConnectionLink } ====================================================
destructor TZDbConnectionLink.Destroy;
begin
  if Sender is TZDbConnection then
    TZDbConnection(Sender).UnregisterChanges(Self);
  inherited Destroy;
end;

procedure TZDbConnectionLink.Change;
begin
  if Assigned(FOnChange) then
    FOnChange(Sender);
end;


// === { TZDbConnection } =============================================
constructor TZDbConnection.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FClients := tList.Create;
end;

destructor TZDbConnection.Destroy;
begin
  UnregisterAllDataSets;
  FClients := nil;
  FClients.Free;
  inherited Destroy;
end;

procedure TZDbConnection.DoChange(Sender: TObject);
begin
  Change;
end;

procedure TZDbConnection.Change;
  var i:Integer;
      Current: TZDbConnectionLink;
begin
  if Assigned(FOnChange) then
  begin
    FOnChange(Self);
  end;
  if FClients <> nil then
    for I := 0 to FClients.Count - 1 do
      TZDbConnectionLink(FClients[I]).Change;
end;

procedure TZDbConnection.SetUser(const Value: string);
begin
  if FUser <> Value then
  begin
    FUser := Value;
    Change;
  end;
end;

procedure TZDbConnection.SetPassword(const Value: string);
begin
  if FPassword <> Value then
  begin
    FPassword := Value;
    Change;
  end;
end;

procedure TZDbConnection.SetProtocol(const Value: string);
begin
  if FProtocol <> Value then
  begin
    FProtocol := Value;
    Change;
  end;
end;

procedure TZDbConnection.SetHostName(const Value: string);
begin
  if FHostName <> Value then
  begin
    FHostName := Value;
    Change;
  end;
end;

procedure TZDbConnection.SetDatabase(const Value: string);
begin
  if FDatabase <> Value then
  begin
    FDatabase := Value;
    Change;
  end;
end;

procedure TZDbConnection.SetPort(const Value: integer);
begin
  if FPort <> Value then
  begin
    FPort := Value;
    Change;
  end;
end;

procedure TZDbConnection.UnregisterAllDataSets;
var
  I: Integer;
  Current: TZDbConnectionLink;
begin
  for I := FClients.Count - 1 downto 0 do
  begin
    Current := TZDbConnectionLink(FClients[I]);
    FClients.Remove(Current);
//    try
//       Current := nil;
//    except
//       //Ignore
//    end;
  end;
end;

procedure TZDbConnection.RegisterChanges(Value: TZDbConnectionLink);
begin
  Value.Sender := Self;
  if FClients <> nil then
    FClients.Add(Value);
end;

procedure TZDbConnection.UnregisterChanges(Value: TZDbConnectionLink);
var
  I: Integer;
begin
  if FClients <> nil then
    for I := 0 to FClients.Count - 1 do
      if FClients[I] = Value then
      begin
        Value.Sender := nil;
        FClients.Delete(I);
        Break;
      end;
end;

end.

Code: Select all

unit ZTransaction;

interface
{$I ZComponent.inc}

uses
  Types, SysUtils, Messages, Classes, ZDbcIntfs, DB, ZDbcAdoUtils,Forms,
  ZCompatibility, ZConnection, ZSequence, Dialogs, ZDbConnection;

const  CM_ZDBCONNECTIONCHANGED = WM_USER + 100;
const  CM_ZDBCONNECTIONCHANGE  = WM_USER + 101;

type
  TMsgZDbConnecitionChange = record
    Msg: Cardinal;
    Sender: TComponent;
    ZDbConnection: TZDbConnection;
    Result: Longint;
  end;

type
  TZTransaction = class(TZConnection)
  protected
    FZDbConnection: TZDbConnection;
    FZDbConnectionLink: TZDbConnectionLink;
    procedure SetDbConnection(Value: TZDbConnection);
    procedure Notification(AComponent: TComponent; Operation: TOperation);
      override;
  private
    function getUser: string;
    function getProtocol: string;
    function getPassword: string;
    function getHostName: string;
    function getDatabase: string;
    procedure DoZDbConnectionChange(Sender: TObject);
    procedure ParentZDbConnectionChange(var Msg: TMessage);
  published
    property DBConnection: TZDbConnection read FZDbConnection write SetDbConnection;

    property User: string read getUser;
    property Protocol: string read getProtocol ;
    property Password: string read getPassword ;
    property HostName: string read getHostName ;
    property Database: string read getDatabase ;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

procedure InternalZDBConnectionChanged(AControl: TComponent; AZdbConnection: TZDbConnection);
var
  Msg: TMsgZDbConnecitionChange;
begin
  Msg.Msg := CM_ZDBCONNECTIONCHANGED;
  Msg.Sender := AControl;
  Msg.ZDbConnection := AZdbConnection;
  Msg.Result := 0;
  //AControl.Broadcast(Msg);
end;

// === { TZTransaction } =============================================
constructor TZTransaction.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FZDbConnectionLink := TZDbConnectionLink.Create;
  FZDbConnectionLink.OnChange := DoZDbConnectionChange;
end;

destructor TZTransaction.Destroy;
begin
  FZDbConnectionLink.Free;
  inherited Destroy;
end;

procedure TZTransaction.DoZDbConnectionChange(Sender: TObject);
begin
  if (Sender is TZDbConnection) then
  begin
    FUser := (Sender as TZDbConnection).User;
    FProtocol := (Sender as TZDbConnection).Protocol;
    FPassword := (Sender as TZDbConnection).Password;
    FHostName := (Sender as TZDbConnection).HostName;
    FDatabase := (Sender as TZDbConnection).Database;
  end;
end;

procedure TZTransaction.ParentZDbConnectionChange(var Msg: TMessage);
begin
  InternalZDBConnectionChanged(Self, FZDbConnection);
end;

procedure TZTransaction.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);

  if (Operation = opRemove) then
  begin
    if (AComponent is TDataset) then
      UnregisterDataSet(TDataset(AComponent));
    if (AComponent is TZSequence) then
      UnregisterSequence(TZSequence(AComponent));
    if (AComponent = FZDbConnection) then
      FZDbConnection := nil;
  end;
end;

procedure TZTransaction.SetDbConnection(Value: TZDbConnection);
begin
  if FZDbConnection<>nil then
    FZDbConnection.UnRegisterChanges(FZDbConnectionLink);

  FZDbConnection := Value;
  if Value <> nil then
  begin
    FZDbConnection.RegisterChanges(FZDbConnectionLink);
    FUser := FZDbConnection.User;
    FProtocol := FZDbConnection.Protocol;
    FPassword := FZDbConnection.Password;
    FHostName := FZDbConnection.HostName;
    FDatabase := FZDbConnection.Database;
  end;
  InternalZDBConnectionChanged(Self, Value);
end;

function TZTransaction.getUser: string;
begin
  if FZDbConnection <> nil then
  begin
    FUser := FZDbConnection.User;
    Result := FUser;
  end
  else
    FUser := '';
end;

function TZTransaction.getProtocol: string;
begin
  if FZDbConnection <> nil then
  begin
    FProtocol := FZDbConnection.Protocol;
    Result := FProtocol;
  end
  else
    FProtocol := '';
end;

function TZTransaction.getPassword: string;
begin
  if FZDbConnection <> nil then
  begin
    FPassword := FZDbConnection.Password;
    Result := FPassword;
  end
  else
    FPassword := '';
end;

function TZTransaction.getHostName: string;
begin
  if FZDbConnection <> nil then
  begin
    FHostName := FZDbConnection.HostName;
    Result := FHostName;
  end
  else
    FHostName := '';
end;

function TZTransaction.getDatabase: string;
begin
  if FZDbConnection <> nil then
  begin
    FDatabase := FZDbConnection.Database;
    Result := FDatabase;
  end
  else
    FDatabase := '';
end;

end.
Thanks.
Luzcka
Fresh Boarder
Fresh Boarder
Posts: 5
Joined: 23.03.2008, 22:10

Post by Luzcka »

The password storage is very dangerous... if it is necessary try encrypt and decrypt it inside Get_ and Set_ methods! :wink:
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Well, I'm not really a library or OO expert, but my feelings are this should be solved by eventually adding a 'TZConnectionGroup' (or something similar) and extending the TZConnection component, allowing to 'Connect/join' a TZConnection to a 'TZConnectionGroup' XOR provide it's own connection details.
Looks a little as if you also did that, but why calling the ConnectionGroup 'DbConnection' and the ZTransaction is a TZonnection descedant

Mark
Image
una.bicicleta
Fresh Boarder
Fresh Boarder
Posts: 15
Joined: 28.03.2010, 17:52

Post by una.bicicleta »

Thanks Luzcka and Mark,

I want to make ZTransaction works for every Zeos version, so using ZConnection as ZTransaction base class is the simple way to do that,
and the reason why I choose 'ZDbConnection' name, not 'ZDatabase', because I'm worried that someday my component name (assuming I use ZDatabase name) will conflict with another Zeos component when Zeos implement a new component call 'ZDatabase'. ZConnectionGroup make sense to me now :)

To encrypt the password in ZDbConnection, I should make some change in ZTransaction like Mark suggestion, not as ZConnection descendant anymore, because the password in ZConnection was not encrypted (ZTransaction is descendant from ZConnection) and I still can't find a good way to hide published properties from the base class. Maybe it's easier for me to copy ZConnection source code and make some modifications to create ZTransaction component.
What do you think? should I stick to TZConnection descendant or not?
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Luzcka,
Why is the password storage less safe than in the normal ZConnection? There we don't encrypt it either.

una.bicicleta,
What do you think about adding a TZConnectionGroup component and a TZGroupedConnection TZConnection descendant?
In that last component you can hide the connection properties that are provided by the connectiongroup component.
I don't want to add them to the official 6.6 version, but that can easily be solved by you when you provide a separate add-on package to zeoslib 6.6 as I think the units made for Zeoslib 7 are perfectly compatible with zeoslib 6.

Do you want to do this job?


Mark
Image
una.bicicleta
Fresh Boarder
Fresh Boarder
Posts: 15
Joined: 28.03.2010, 17:52

Post by una.bicicleta »

I'm glad if Zeos wants to add TZConnectionGroup and TZGroupedConnection to Zeoslib 7.
And thanks for the offer, but I don't think I'm quite capable to do this job. Hiding published properties in TZGroupedConnection base class (TZConnection) is still impossible for me. Maybe someone who have more experience than me can build that components easily.

Thank you.
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Have a look how it's done with TZQuery like components (ZDataset.pas).

Just rename TZConnection to TZAbstractConnection, including functionality of TZConnection and TZGroupedConnection. Make the properties that are not to be published for both components protected. Inherit and publish the right protected properties from the parent class.

Mark
Image
una.bicicleta
Fresh Boarder
Fresh Boarder
Posts: 15
Joined: 28.03.2010, 17:52

Post by una.bicicleta »

Ok, I'll do it.
Of course, I still need a lot of help from you and Zeos community.
I'll post the component source in here later.
una.bicicleta
Fresh Boarder
Fresh Boarder
Posts: 15
Joined: 28.03.2010, 17:52

Post by una.bicicleta »

I've got a new problem,
ZTable, ZQuery and ZReadOnlyQuery can't use TZGroupedConnection as their connection because TZGroupedConnection parent class now is TZAbstractConnection and not TZConnection.

I can re-create TZconnection base on TZAbstractConnection class, but now I have to remove all ZConnection from USES files. It just make this thing more complicated.
Luzcka
Fresh Boarder
Fresh Boarder
Posts: 5
Joined: 23.03.2008, 22:10

Post by Luzcka »

Hi Mdaems!

The passwords stored in memory should be encrypted, since the memory can be scanned for malware, the best course would not store the password, but a hash, but this does not apply in this case.
The storage of passwords is not recommended and is considered a security hole ... I can not say that storing passwords is less dangerous in a layer (class) to another, I can only say that should be protected.
Post Reply