Olá PessoALL.
Estou agora mostrando a vocês como criar a camada de acesso genérica por meio do ADO.
Vejam que há uma diferença entre os parâmetros dos objetos TADOQuery e o usado em nossa camada.
Mas com uma solução simples temos como contornar esse problema.

Boa programação a todos.

Qualquer dúvida, sugestão, crítica, elogio mandem para RENEUECE@IG.COM.BR.


unit uADOConnection;

interface

{
Autor.: Renato Correia de Matos
Email.: reneuece@ig.com.br or renato@istudar.com.br
Data..: 25/03/2009
Obs...: Esse artigo faz parte do grupo www.istudar.com.br e foi
        criado por mim para ajudar a galerinha a se livrar ou se
        tornar reféns de drivers de conexão. Por favor! Mantenham
        essas informações. Vocês poderão usar as dicas aqui contidas
        em seus projetos sem qualquer custo. Apenas mantenham minhas credencias.
Email:. reneuece@ig.com.br or renato@istudar.com.br


Author: Renato Correia de Matos
Email.: reneuece@ig.com.br or renato@istudar.com.br
Date..: 03/25/2009
Obs...: I created this article to help any programmer to be free from any connection driver.
        It is published on www.istudar.com.br. You can use this article in your projects
        without any costs. I would like you just to put my name or email on it.
}

uses uConnection, // unidade que contem as interfaces
     Classes, DB, ADODB;

type
  // camada para controle da conexão
  TADOConn = class(TADOConnection, IConnection)
  public
    function getComponent: TComponent;

    // controle de conexão
    procedure Open;
    procedure Close;
    function isConnected: boolean;

    // controle de transação
    procedure StarTransaction;
    procedure Commit;
    procedure Rollback;
    function InTransaction: Boolean;

    // criador de queries
    function CreateQuery: IQuery;

    // parâmetros de conexão
    function getParams: TStrings;
    function getFramework: TFramework;

    property Params: TStrings read getParams;
  end;

  // camada para execução de consultas
  TMyADOQuery = class(TADOQuery, IQuery)
  private
    FoConn: IConnection;

  protected
    function ParameterToParam(loCollection: TParams;Value: TParameter): TParam; virtual;

  public
    function Conn: IConnection;

    // controle de conexão
    procedure Open;
    procedure Close;
    function isActive: boolean;

    // execução de comandos
    function ExecSQL: Integer;
    function DataSet: TDataSet;

    // comandos sql
    function getSQL: TStrings;
    procedure setSQL(Value: TStrings);
    function getParams: TParams;
    function getFields: TFields;
    function FieldByName(Name: String): TField;

    property SQL: TStrings read getSQL write setSQL;
    property Fields: TFields read getFields;
  end;

implementation

{ TADOConn }

procedure TADOConn.StarTransaction;
begin
  if not InTransaction then
    StarTransaction;
end;

function TADOConn.getFramework: TFramework;
begin
  result := fwBDE;
end;

procedure TADOConn.Open;
begin
  TADOConnection(Self).LoginPrompt := false;
  TADOConnection(Self).Open;
end;

function TADOConn.CreateQuery: IQuery;
begin
  result := TMyADOQuery.Create(Self);
end;

procedure TADOConn.Commit;
begin
  if InTransaction then
    Commit;
end;

procedure TADOConn.Close;
begin
  TADOConnection(Self).Close;
end;

function TADOConn.getComponent: TComponent;
begin
  result := self;
end;

function TADOConn.getParams: TStrings;
begin
  result := TStringList.Create;
  result.Add(TADOConnection(Self).ConnectionString);
end;

function TADOConn.isConnected: boolean;
begin
  result := TADOConnection(Self).Connected;
end;

procedure TADOConn.Rollback;
begin
  if InTransaction then
    Rollback;
end;

function TADOConn.InTransaction: Boolean;
begin
  result := TADOConnection(Self).InTransaction;
end;

{ TMyADOQuery }

function TMyADOQuery.DataSet: TDataSet;
begin
  result := self;
end;

function TMyADOQuery.FieldByName(Name: String): TField;
begin
  result := TMyADOQuery(Self).FieldByName(Name);
end;

function TMyADOQuery.ExecSQL: Integer;
begin
  TMyADOQuery(Self).ExecSQL;
  result := TMyADOQuery(Self).RowsAffected;
end;

function TMyADOQuery.getSQL: TStrings;
begin
  result := TMyADOQuery(Self).SQL;
end;

procedure TMyADOQuery.Open;
begin
  TMyADOQuery(Self).Connection := (Conn.getComponent as TADOConn);
  TMyADOQuery(Self).Open;
end;

function TMyADOQuery.Conn: IConnection;
begin
  result := FoConn;
end;

function TMyADOQuery.isActive: boolean;
begin
  result := TMyADOQuery(Self).Active;
end;

procedure TMyADOQuery.Close;
begin
  TMyADOQuery(Self).Close;
end;

function TMyADOQuery.getParams: TParams;
var
  lnCont: Integer;
  loParam: TParam;
begin
  // neste ponto do programa aparece o primeiro obstáculo
  // estamos trabalhando com TParams e o AdoQuery não trabalha com isso
  // ele usa um outro modelo de parâmetros chamado TParameters
  // Para resolver temos duas opções:
  // 1. Converter de TParameter para TParam
  // 2. Criar uma Interface IParameter e então implementá-la conforme o tipo
  //    de objeto usado. A segunda opção é mais elegante. Iremos implementar
  //    essa classe usando as duas opções para que vocês possam acompanhar de perto
  //    o que está acontecendo.
  //
  // Vamos iniciar pela primeira que é mais prática neste ponto do projeto
  result := TParams.Create();
  for lnCont := 0 to TMyADOQuery(Self).Parameters.Count - 1 do
    begin
    loParam := ParameterToParam(result, TMyADOQuery(Self).Parameters[lnCont]);
    result.AddParam(loParam);
    end;
end;

procedure TMyADOQuery.setSQL(Value: TStrings);
begin
  TMyADOQuery(Self).SQL.Assign(Value);
end;

function TMyADOQuery.getFields: TFields;
begin
  result := TMyADOQuery(Self).Fields;
end;

function TMyADOQuery.ParameterToParam(loCollection: TParams; Value: TParameter): TParam;
begin
  result := TParam.Create(loCollection);

  // TParam.ParamType: ptUnknown, ptInput, ptOutput, ptInputOutput, ptResult
  // TParameter.Direction: pdUnknown, pdInput, pdOutput, pdInputOutput, pdReturnValue
  case value.Direction of
    pdUnknown     : result.ParamType := ptUnknown;
    pdInput       : result.ParamType := ptInput;
    pdOutput      : result.ParamType := ptOutput;
    pdInputOutput : result.ParamType := ptInputOutput;
    pdReturnValue : result.ParamType := ptResult;
  end;

  // nome
  result.Name := value.Name;

  // value
  result.Value := value.Value;
end;

end.