📄 cdsutil.pas
字号:
unit CDSUtil;
interface
uses
DbClient, DbTables;
function RetrieveDeltas(const cdsArray : array of TClientDataset): Variant;
function RetrieveProviders(const cdsArray : array of TClientDataset): Variant;
procedure ReconcileDeltas(const cdsArray : array of TClientDataset; vDeltaArray: OleVariant);
procedure CDSApplyUpdates(ADatabase : TDatabase; var vDeltaArray: OleVariant; const vProviderArray: OleVariant);
implementation
uses
SysUtils, Provider,
{$IFDEF VER130}Midas{$ELSE}StdVcl{$ENDIF};
type
PArrayData = ^TArrayData;
TArrayData = array[0..1000] of Olevariant;
{Delta is the CDS.Delta on input. On return, Delta will contain a data packet}
{containing all of the records that could not be applied to the database.}
{Remember Delphi 5 needs the provider name, and this is passed in the 1 element}
{of the AProvider variant.}
procedure ApplyDelta(AProvider: OleVariant; var Delta : OleVariant);
var
ErrCount : integer;
OwnerData: OleVariant;
begin
if not VarIsNull(Delta) then
begin
// ScktSrvr does not support early-binding
{$IFDEF VER130}
Delta := (IDispatch(AProvider[0]) as IAppServer).AS_ApplyUpdates(AProvider[1], Delta, 0, ErrCount, OwnerData);
{$ELSE}
Delta := OleVariant(IDispatch(AProvider)).ApplyUpdates(Delta, 0, ErrCount);
{$ENDIF}
if ErrCount > 0 then
SysUtils.Abort; // This will cause Rollback in the calling procedure
end;
end;
{Server call}
procedure CDSApplyUpdates(ADatabase : TDatabase; var vDeltaArray: OleVariant; const vProviderArray: OleVariant);
var
i : integer;
LowArr, HighArr: integer;
P: PArrayData;
begin
{Wrap the updates in a transaction. If any step results in an error, raise}
{an exception, which will Rollback the transaction.}
ADatabase.Connected:=true;
ADatabase.StartTransaction;
try
LowArr:=VarArrayLowBound(vDeltaArray,1);
HighArr:=VarArrayHighBound(vDeltaArray,1);
P:=VarArrayLock(vDeltaArray);
try
for i:=LowArr to HighArr do
ApplyDelta(vProviderArray[i], P^[i]);
// ApplyDelta(IDispatch(vProviderArray[i]) as IProvider, P^[i]);
finally
VarArrayUnlock(vDeltaArray);
end;
ADatabase.Commit;
except
ADatabase.Rollback;
end;
end;
{Client side calls}
function RetrieveDeltas(const cdsArray : array of TClientDataset): Variant;
var
i : integer;
LowCDS, HighCDS : integer;
begin
Result:=NULL;
LowCDS:=Low(cdsArray);
HighCDS:=High(cdsArray);
for i:=LowCDS to HighCDS do
cdsArray[i].CheckBrowseMode;
Result:=VarArrayCreate([LowCDS, HighCDS], varVariant);
{Setup the variant with the changes (or NULL if there are none)}
for i:=LowCDS to HighCDS do
begin
if cdsArray[i].ChangeCount>0 then
Result[i]:=cdsArray[i].Delta else
Result[i]:=NULL;
end;
end;
{If we're using Delphi 5, then we need to return the provider name AND the
AppServer from this function. We will use ProviderName to call AS_ApplyUpdates
in the CDSApplyUpdates function later.}
function RetrieveProviders(const cdsArray : array of TClientDataset): Variant;
var
i: integer;
LowCDS, HighCDS: integer;
begin
Result:=NULL;
LowCDS:=Low(cdsArray);
HighCDS:=High(cdsArray);
Result:=VarArrayCreate([LowCDS, HighCDS], varVariant);
for i:=LowCDS to HighCDS do
{$IFDEF VER130}
Result[i]:=VarArrayOf([cdsArray[i].AppServer, cdsArray[i].ProviderName]);
{$ELSE}
Result[i]:=cdsArray[i].Provider;
{$ENDIF}
end;
procedure ReconcileDeltas(const cdsArray : array of TClientDataset; vDeltaArray: OleVariant);
var
bReconcile : boolean;
i: integer;
LowCDS, HighCDS : integer;
begin
LowCDS:=Low(cdsArray);
HighCDS:=High(cdsArray);
{If the previous step resulted in errors, Reconcile the error datapackets.}
bReconcile:=false;
for i:=LowCDS to HighCDS do
if not VarIsNull(vDeltaArray[i]) then begin
cdsArray[i].Reconcile(vDeltaArray[i]);
bReconcile:=true;
break;
end;
{Refresh the Datasets if needed}
if not bReconcile then
for i:=HighCDS downto LowCDS do begin
cdsArray[i].Reconcile(vDeltaArray[i]);
cdsArray[i].Refresh;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -