📄 provider.pas
字号:
else
raise EDSWriter.CreateFmt(ErrMsg, ['']);
end;
end;
for i := 0 to DataSet.FieldList.Count - 1 do
with DataSet.FieldList[i] do
begin
try
AddSQLExprAttr(ExprParser, DefaultExpression, '', FullName, i + 1,
ctDefault, False);
except
if Name <> '' then
ErrMsg := Format('%s: %s',[Name, SDefExprFail]) else
if DataSet.Name <> '' then
ErrMsg := Format('%s.%s: %s',[DataSet.Name, FullName, SDefExprFail]) else
ErrMsg := Format('%s: %s', [FullName, SDefExprFail]);
if ExceptObject is Exception then
raise EDSWriter.CreateFmt(ErrMsg, [Exception(ExceptObject).Message])
else
raise EDSWriter.CreateFmt(ErrMsg, ['']);
end;
try
AddSQLExprAttr(ExprParser, ImportedConstraint, ConstraintErrorMessage,
FullName, i + 1, ctField, False);
AddSQLExprAttr(ExprParser, CustomConstraint, ConstraintErrorMessage,
FullName, i + 1, ctField, False);
except
if Name <> '' then
ErrMsg := Format('%s: %s',[Name, SFieldConstFail]) else
if DataSet.Name <> '' then
ErrMsg := Format('%s.%s: %s',[DataSet.Name, FullName, SFieldConstFail]) else
ErrMsg := Format('%s: %s', [FullName, SFieldConstFail]);
if ExceptObject is Exception then
raise EDSWriter.CreateFmt(ErrMsg, [Exception(ExceptObject).Message])
else
raise EDSWriter.CreateFmt(ErrMsg, ['']);
end;
end;
finally
ExprParser.Free;
end;
end;
procedure TDataPacketWriter.AddIndexDefs(DataSet: TDataSet; const Info: TInfoArray);
var
FieldList, CaseList, DescList: TList;
function GetKeyData(Index: TIndexDef): OleVariant;
var
i: Integer;
x: Integer;
begin
with Index do
begin
FieldList.Clear;
CaseList.Clear;
DescList.Clear;
DataSet.GetFieldList(FieldList, Fields);
DataSet.GetFieldList(CaseList, CaseInsFields);
DataSet.GetFieldList(DescList, DescFields);
Result := VarArrayCreate([0, FieldList.Count - 1], varInteger);
for i := 0 to FieldList.Count - 1 do
begin
x := GetFieldIdx(TField(FieldList[i]).FieldName, Info);
if (CaseList.IndexOf(FieldList[i]) <> -1) or
((i = 0) and (FieldList.Count = 1) and (ixCaseInSensitive in Options)) then
x := x or dskeyCASEINSENSITIVE;
if (DescList.IndexOf(FieldList[i]) <> -1) or
((i = 0) and (FieldList.Count = 1) and (ixDescending in Options)) then
x := x or dskeyDESCENDING;
Result[i] := x;
end;
end;
end;
var
i: Integer;
DefIdx, KeyIndex: TIndexDef;
IndexDefs: TIndexDefs;
KeyList: OleVariant;
KeyFields: string;
begin
FieldList := TList.Create;
try
CaseList := TList.Create;
try
DescList := TList.Create;
try
{ Get the DEFAULT_ORDER }
if not (poRetainServerOrder in Options) then
DefIdx := IProviderSupport(DataSet).PSGetDefaultOrder
else
DefIdx := nil;
if Assigned(DefIdx) then
try
KeyList := GetKeyData(DefIdx);
AddAttribute(pcktAttrArea, szDEFAULT_ORDER, KeyList, False);
finally
DefIdx.Free;
end;
KeyFields := IProviderSupport(DataSet).PSGetKeyFields;
IndexDefs := IProviderSupport(DataSet).PSGetIndexDefs([ixUnique]);
try
if KeyFields <> '' then
begin
{ PRIMARY_KEY is used to define the keyfields }
KeyList := NULL;
if Assigned(IndexDefs) then
begin
KeyIndex := IndexDefs.GetIndexForFields(KeyFields, False);
if Assigned(KeyIndex) then
begin
KeyList := GetKeyData(KeyIndex);
KeyIndex.Free;{ KeyIndex is already used, remove it from the list }
end;
end;
if VarIsNull(KeyList) then
begin
DataSet.GetFieldList(FieldList, KeyFields);
KeyList := VarArrayCreate([0, FieldList.Count - 1], varSmallInt);
for i := 0 to FieldList.Count - 1 do
KeyList[i] := GetFieldIdx(TField(FieldList[i]).FieldName, Info);
end;
if not VarIsNull(KeyList) then
AddAttribute(pcktAttrArea, szPRIMARY_KEY, KeyList, False);
end;
if Assigned(IndexDefs) then
for i := 0 to IndexDefs.Count - 1 do
with IndexDefs[i] do
begin
KeyList := GetKeyData(IndexDefs[i]);
AddAttribute(pcktAttrArea, szUNIQUE_KEY, KeyList, False);
end;
finally
IndexDefs.Free;
end;
finally
DescList.Free;
end;
finally
CaseList.Free;
end;
finally
FieldList.Free;
end;
end;
procedure TDataPacketWriter.AddFieldLinks(const Info: TInfoArray);
var
MasterFields, DetailFields: TList;
i, j: Integer;
LinkFields: Variant;
begin
MasterFields := TList.Create;
try
DetailFields := TList.Create;
try
for i := 0 to High(Info) do
if Info[i].IsDetail and (Info[i].Field = nil) then
begin
Info[i].DataSet.GetDetailLinkFields(MasterFields, DetailFields);
if (MasterFields.Count > 0) and (MasterFields.Count <= DetailFields.Count) then
begin
LinkFields := VarArrayCreate([0, MasterFields.Count * 2], varSmallInt);
LinkFields[0] := Info[i].LocalFieldIndex;
for j := 0 to MasterFields.Count - 1 do
LinkFields[j + 1] := GetFieldIdx(TField(MasterFields[j]).FieldName,
Info);
for j := 0 to MasterFields.Count - 1 do
LinkFields[j + MasterFields.Count + 1] :=
GetFieldIdx(TField(DetailFields[j]).FieldName, TInfoArray(Info[i].FieldInfos));
AddAttribute(pcktAttrArea, szMD_FIELDLINKS, LinkFields, False);
end;
end;
finally
DetailFields.Free;
end;
finally
MasterFields.Free;
end;
end;
procedure TDataPacketWriter.WriteMetaData(DataSet: TDataSet; const Info: TInfoArray;
IsReference: Boolean);
var
i, MDOptions: Integer;
begin
for i := 0 to High(Info) do
AddColumn(Info[i]);
if (poReadOnly in Options) or IsReference then
AddAttribute(pcktAttrArea, szREADONLY, True, False);
if (poDisableEdits in Options) then
AddAttribute(pcktAttrArea, szDISABLE_EDITS, True, False);
if (poDisableInserts in Options) then
AddAttribute(pcktAttrArea, szDISABLE_INSERTS, True, False);
if (poDisableDeletes in Options) then
AddAttribute(pcktAttrArea, szDISABLE_DELETES, True, False);
if (poNoReset in Options) then
AddAttribute(pcktAttrArea, szNO_RESET_CALL, True, False);
if Constraints then
AddConstraints(DataSet);
AddIndexDefs(DataSet, Info);
AddFieldLinks(Info);
MDOptions := 0;
if poCascadeDeletes in Options then MDOptions := dsCASCADEDELETES;
if poCascadeUpdates in Options then MDOptions := MDOptions or dsCASCADEUPDATES;
if MDOptions <> 0 then
AddAttribute(pcktAttrArea, szMD_SEMANTICS, MDOptions, True);
AddDataSetAttributes(DataSet);
if Info <> FPutFieldInfo then
Check(FIDSWriter.AddAttribute(pcktAttrArea, nil, 0, 0, nil));
end;
procedure TDataPacketWriter.RefreshPutProcs(ADataSet: TDataSet; var Info: TInfoArray);
procedure RefreshInfo(ADataSet: TDataSet; AField: TField; var Info: TPutFieldInfo);
var
j: Integer;
begin
Info.Field := AField;
if AField = nil then
Info.DataSet := ADataSet
else
begin
Info.DataSet := AField.DataSet;
if AField.DataType = ftADT then
begin
with TADTField(AField) do
for j := 0 to FieldCount - 1 do
RefreshInfo(ADataSet, Fields[j], TInfoArray(Info.FieldInfos)[j]);
end;
end;
end;
var
i: Integer;
List: TList;
begin
List := TList.Create;
try
ADataSet.GetDetailDataSets(List);
for i := 0 to ADataSet.FieldCount - 1 do
RefreshInfo(ADataSet, ADataSet.Fields[i], Info[i]);
for i := 0 to List.Count - 1 do
RefreshInfo(TDataSet(List[i]), nil, Info[ADataSet.FieldCount + i]);
finally
List.Free;
end;
end;
function TDataPacketWriter.InitPutProcs(ADataSet: TDataSet;
var GlobalIdx: Integer): TInfoArray;
procedure InitInfoStruct(var Info: TPutFieldInfo; AField: TField;
var GlobalIdx, LocalIdx: Integer);
begin
FillChar(Info, SizeOf(Info), 0);
with Info do
begin
IsDetail := AField = nil;
Field := AField;
Inc(GlobalIdx);
LocalFieldIndex := LocalIdx;
Inc(LocalIdx);
if Field <> nil then
begin
FieldNo := Field.FieldNo;
Size := Field.DataSize;
DataSet := Field.DataSet;
end;
end;
end;
procedure InitFieldProc(ADataSet: TDataSet; AField: TField;
var Info: TPutFieldInfo; var GlobalIdx, LocalIdx: Integer);
var
i: Integer;
NestedIdx: Integer;
begin
with Info do
begin
InitInfoStruct(Info, AField, GlobalIdx, LocalIdx);
if AField = nil then { Linked dataset }
begin
Opened := not ADataSet.Active;
if Opened then ADataSet.Open;
DataSet := ADataSet;
PutProc := PutDataSetField;
TInfoArray(FieldInfos) := InitPutProcs(DataSet, GlobalIdx);
end else
begin
case Field.DataType of
ftString, ftFixedChar, ftGUID:
begin
PutProc := PutStringField;
Dec(Size); { Don't count the null terminator }
end;
ftWideString:
begin
PutProc := PutWideStringField;
Size := AField.Size * 2;
end;
ftVarBytes:
begin
PutProc := PutVarBytesField;
Dec(Size, 2); { Don't write size bytes }
end;
ftADT:
with TADTField(Field) do
begin
PutProc := PutADTField;
SetLength(TInfoArray(FieldInfos), FieldCount);
for i := 0 to FieldCount - 1 do
InitFieldProc(ADataSet, Fields[i], TInfoArray(FieldInfos)[i],
GlobalIdx, LocalIdx);
end;
ftArray:
with TArrayField(Field) do
begin
PutProc := PutArrayField;
SetLength(TInfoArray(FieldInfos), 1);
NestedIdx := LocalIdx;
InitFieldProc(ADataSet, Fields[0], TInfoArray(FieldInfos)[0],
GlobalIdx, LocalIdx);
LocalIdx := (LocalIdx - NestedIdx) * (FieldCount - 1) + LocalIdx;
end;
ftDataSet, ftReference:
with TDataSetField(Field).NestedDataSet do
begin
PutProc := PutDataSetField;
NestedIdx := 1;
SetLength(TInfoArray(FieldInfos), FieldCount);
for i := 0 to FieldCount - 1 do
InitFieldProc(TDataSetField(Field).NestedDataSet, Fields[i],
TInfoArray(FieldInfos)[i], GlobalIdx, NestedIdx);
end;
ftSmallint, ftInteger, ftWord, ftBoolean, ftFloat, ftCurrency, ftBCD,
ftDate, ftTime, ftDateTime, ftAutoInc, ftLargeint, ftBytes, ftTimeStamp, ftFMTBcd:
PutProc := PutField;
ftBlob, ftMemo, ftGraphic, ftFmtMemo, ftParadoxOle,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -