fcl-db: bufdataset: make TFpcBinaryDatapacketReader more flexible hence descendant can override version preset in constructor and write in old format.

git-svn-id: trunk@25508 -
This commit is contained in:
lacak 2013-09-17 12:43:45 +00:00
parent 129fddf800
commit baa700925c

View File

@ -384,6 +384,21 @@ type
{ TFpcBinaryDatapacketReader } { TFpcBinaryDatapacketReader }
{ Format description:
Header:
Identification: 13 bytes: 'BinBufDataSet'
Version: 1 byte
FieldDefs:
Number of Fields: 2 bytes
For each FieldDef: Name, DisplayName, Size: 2 bytes, DataType: 2 bytes, ReadOnlyAttr: 1 byte
AutoInc Value: 4 bytes
Records:
Record header: each record begins with $fe: 1 byte
row state: 1 byte
update order: 4 bytes
Record data:
}
TFpcBinaryDatapacketReader = class(TDataPacketReader) TFpcBinaryDatapacketReader = class(TDataPacketReader)
private private
const const
@ -392,9 +407,11 @@ type
StringFieldTypes = [ftString,ftFixedChar,ftWideString,ftFixedWideChar]; StringFieldTypes = [ftString,ftFixedChar,ftWideString,ftFixedWideChar];
BlobFieldTypes = [ftBlob,ftMemo,ftWideMemo]; BlobFieldTypes = [ftBlob,ftMemo,ftWideMemo];
VarLenFieldTypes = StringFieldTypes + BlobFieldTypes + [ftBytes,ftVarBytes]; VarLenFieldTypes = StringFieldTypes + BlobFieldTypes + [ftBytes,ftVarBytes];
protected
var var
FVersion: byte; FVersion: byte;
public public
constructor Create(AStream : TStream); override;
procedure LoadFieldDefs(AFieldDefs : TFieldDefs; var AnAutoIncValue : integer); override; procedure LoadFieldDefs(AFieldDefs : TFieldDefs; var AnAutoIncValue : integer); override;
procedure StoreFieldDefs(AFieldDefs : TFieldDefs; AnAutoIncValue : integer); override; procedure StoreFieldDefs(AFieldDefs : TFieldDefs; AnAutoIncValue : integer); override;
procedure InitLoadRecords; override; procedure InitLoadRecords; override;
@ -2339,7 +2356,7 @@ begin
SetFieldIsNull(NullMask, blobbuf.BlobBuffer^.FieldNo-1) SetFieldIsNull(NullMask, blobbuf.BlobBuffer^.FieldNo-1)
else else
unSetFieldIsNull(NullMask, blobbuf.BlobBuffer^.FieldNo-1); unSetFieldIsNull(NullMask, blobbuf.BlobBuffer^.FieldNo-1);
blobbuf.BlobBuffer^.FieldNo := -1; blobbuf.BlobBuffer^.FieldNo := -1;
end; end;
@ -3515,6 +3532,12 @@ end;
{ TFpcBinaryDatapacketReader } { TFpcBinaryDatapacketReader }
constructor TFpcBinaryDatapacketReader.Create(AStream: TStream);
begin
inherited;
FVersion := 20; // default version 2.0
end;
procedure TFpcBinaryDatapacketReader.LoadFieldDefs(AFieldDefs: TFieldDefs; var AnAutoIncValue: integer); procedure TFpcBinaryDatapacketReader.LoadFieldDefs(AFieldDefs: TFieldDefs; var AnAutoIncValue: integer);
var FldCount : word; var FldCount : word;
@ -3555,7 +3578,7 @@ procedure TFpcBinaryDatapacketReader.StoreFieldDefs(AFieldDefs: TFieldDefs; AnAu
var i : integer; var i : integer;
begin begin
Stream.Write(FpcBinaryIdent2[1], length(FpcBinaryIdent2)); Stream.Write(FpcBinaryIdent2[1], length(FpcBinaryIdent2));
Stream.WriteByte(20); // version 2.0 Stream.WriteByte(FVersion);
Stream.WriteWord(AFieldDefs.Count); Stream.WriteWord(AFieldDefs.Count);
for i := 0 to AFieldDefs.Count -1 do with AFieldDefs[i] do for i := 0 to AFieldDefs.Count -1 do with AFieldDefs[i] do
@ -3608,11 +3631,11 @@ var
L: cardinal; L: cardinal;
B: TBytes; B: TBytes;
begin begin
case FVersion of with ADataset do
10: case FVersion of
Stream.ReadBuffer(ADataset.GetCurrentBuffer^, ADataset.FRecordSize); // Ugly because private members of ADataset are used... 10:
20: Stream.ReadBuffer(GetCurrentBuffer^, FRecordSize); // Ugly because private members of ADataset are used...
with ADataset do 20:
for i:=0 to FieldDefs.Count-1 do for i:=0 to FieldDefs.Count-1 do
begin begin
AField := Fields.FieldByNumber(FieldDefs[i].FieldNo); AField := Fields.FieldByNumber(FieldDefs[i].FieldNo);
@ -3634,7 +3657,7 @@ begin
AField.SetData(@B[0], False); // set it to the FilterBuffer AField.SetData(@B[0], False); // set it to the FilterBuffer
end; end;
end; end;
end; end;
end; end;
procedure TFpcBinaryDatapacketReader.StoreRecord(ADataset: TCustomBufDataset; procedure TFpcBinaryDatapacketReader.StoreRecord(ADataset: TCustomBufDataset;
@ -3652,24 +3675,28 @@ begin
Stream.WriteBuffer(AUpdOrder,sizeof(integer)); Stream.WriteBuffer(AUpdOrder,sizeof(integer));
// Record data // Record data
// Old 1.0 version: Stream.WriteBuffer(ADataset.GetCurrentBuffer^, ADataset.FRecordSize);
with ADataset do with ADataset do
for i:=0 to FieldDefs.Count-1 do case FVersion of
begin 10:
AField := Fields.FieldByNumber(FieldDefs[i].FieldNo); Stream.WriteBuffer(GetCurrentBuffer^, FRecordSize); // Old 1.0 version
if AField=nil then continue; 20:
if AField.DataType in StringFieldTypes then for i:=0 to FieldDefs.Count-1 do
Stream.WriteAnsiString(AField.AsString) begin
else AField := Fields.FieldByNumber(FieldDefs[i].FieldNo);
begin if AField=nil then continue;
B := AField.AsBytes; if AField.DataType in StringFieldTypes then
L := length(B); Stream.WriteAnsiString(AField.AsString)
if AField.DataType in VarLenFieldTypes then else
Stream.WriteDWord(L); begin
if L > 0 then B := AField.AsBytes;
Stream.WriteBuffer(B[0], L); L := length(B);
end; if AField.DataType in VarLenFieldTypes then
end; Stream.WriteDWord(L);
if L > 0 then
Stream.WriteBuffer(B[0], L);
end;
end;
end;
end; end;
procedure TFpcBinaryDatapacketReader.FinalizeStoreRecords; procedure TFpcBinaryDatapacketReader.FinalizeStoreRecords;