unit dbClone;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, BDE,{DbiErrs, DbiTypes, DbiProcs,} DB, DBTables;

type
  { Component for wrapping any provided cursor }
  TCursorTable = class(TTable)
  private
    { Private declarations }
    FCursor :HDBICur;
  protected
    { Protected declarations }
    function CreateHandle: HDBICur; override;
  public
    { Public declarations }
    Procedure Sync( Cursor :HDBICur );

{$IFDEF VER90}
    Procedure SyncTable( DataSet :TDataSet );
{$ELSE}
    Procedure SyncTable( DataSet :TBDEDataSet );
{$ENDIF}						   

    { These properties shouldn't be published anymore }
    Property TableName;
    property IndexFieldNames;
    property IndexName;
    property MasterFields;
    property MasterSource;
    {property UpdateMode;}
    { --------------------- New property, runtime only }
    Property Cursor :HDBICur Read FCursor Write FCursor;
  end;

procedure Register;

implementation

uses DBConsts;

procedure Register;
begin
  RegisterComponents('Data Access', [TCursorTable]);
end;

{ ------------------------------------------------------------------------- }
{ Utility routines }

function CheckOpen(Status: DBIResult): Boolean;
begin
  case Status of
    DBIERR_NONE:
      Result := True;
    DBIERR_NOTSUFFTABLERIGHTS:
      begin
        if not Session.GetPassword then
          DbiError(Status);
        Result := False;
      end;
  else
    DbiError(Status);
  end;
end;

{ ------------------------------------------------------------------------- }
{ Component for wrapping any provided cursor }
function TCursorTable.CreateHandle: HDBICur;
begin
  if Not Assigned(FCursor) Then
     Raise Exception.Create('Cursor property (Runtime) must be set before table can be open');

  while not CheckOpen(
        DbiCloneCursor( FCursor, ReadOnly, False{bUniDirectional},
                        Result)
        ) do {Retry};
end;

Procedure TCursorTable.Sync( Cursor :HDBICur );
Var Status: DBIResult;
Begin
  if Not Active and Assigned(FCursor) Then
    begin
      FCursor := Cursor;
      Active := True;
    end;
  CheckBrowseMode;
  CursorPosChanged;
  Status := DbiSetToCursor ( Handle, Cursor );
  If Status<>DBIERR_NONE then
    DbiError(Status);
  Resync([rmExact, rmCenter]);
End;

{$IFDEF VER90}
Procedure TCursorTable.SyncTable( DataSet :TDataSet );
{$ELSE}
Procedure TCursorTable.SyncTable( DataSet :TBDEDataSet );
{$ENDIF}	
Begin
  if Active Then
    DataSet.Resync( [] );
  Sync( DataSet.Handle );
End;

end.

