We may use GetOptionalParam and SetOptionalParam methods to access the optional parameters in TClientDataSet instance. However, if we do not know ahead of what parameters are available, these 2 methods serve no purpose to enumerate a list of available parameters.
Unit
DBClient.pas defines the following:
type
TCustomClientDataSet = class(TWideDataSet)
private
FDSBase: IDSBase;
protected
property DSBase: IDSBase read FDSBase write FDSBase;
end;
TClientDataSet = class(TCustomClientDataSet)
end;
Unit
DSInst.pas defines the following:
DSProps = packed record
szName : MIDASPATH; { Name, if any }
iFields : Integer; { Number of columns }
iRecBufSize : Integer; { Size of record buffer }
iBookMarkSize : Integer; { Size of bookmark }
bReadOnly : LongBool; { Dataset is not updateable }
iIndexes : Integer; { Number of indexes on dataset }
iOptParams : Integer; { Number of optional parameters }
bDelta : LongBool; { This is a delta dataset }
iLCID : Integer; { Language used }
iUnused : packed array[0..7] of Integer; { Reserved }
end;
function GetOptParameter( { Returns optional parameter (unknown to dataset) }
iNo : LongWord; { Number 1..iOptAttr }
iFldNo : LongWord; { 0 if not field attribute }
var ppName : Pointer; { returns ptr to name }
var piType : LongWord; { returns type }
var piLen : LongWord; { returns length }
var ppValue : Pointer { returns ptr to value }
): DBResult; stdcall;
We may attempt to use the above definition to enumerate a list of available optional parameters in TClientDataSet instance.
Before we proceed, there is an obstacle to solve. The DSBase property is protected. To overcome it, we can define a class helper function to access the protected property.
type
TClientDataSetHelper = class helper for TClientDataSet
public
function GetDSBase: IDSBase;
end;
function TClientDataSetHelper.GetDSBase: IDSBase;
begin
Result := DSBase;
end;
The following code shows how to retrieve available optional params.
var D: TClientDataSet;
p: DSProps;
pName, pValue: PChar;
pType, pLen: LongWord;
iResult: word;
begin
D := TClientDataSet.Create(nil);
try
D.FieldDefs.Add('Name', ftString, 20);
D.CreateDataSet;
D.SetOptionalParam('Param1', 'FirstValue', True);
D.SetOptionalParam('Param2', 'SecondValue', True);
ZeroMemory(@p, SizeOf(p));
D.GetDSBase.GetProps(p);
Assert(p.iOptParams = 2);
pName := nil;
pValue := nil;
iResult := D.GetDSBase.GetOptParameter(1, 0, pointer(pName), pType, pLen, pointer(pValue));
Assert(iResult = 0);
Assert(string(pName) = 'Param1');
Assert((pType and dsTypeBitsMask) shr dsSizeBitsLen = dsfldZSTRING);
Assert(pLen = 11);
Assert(string(pValue) = 'FirstValue');
pName := nil;
pValue := nil;
iResult := D.GetDSBase.GetOptParameter(2, 0, pointer(pName), pType, pLen, pointer(pValue));
Assert(iResult = 0);
Assert(string(pName) = 'Param2');
Assert((pType and dsTypeBitsMask) shr dsSizeBitsLen = dsfldZSTRING);
Assert(pLen = 12);
Assert(string(pValue) = 'SecondValue');
finally
D.Free;
end;
end;