[fpc-devel] [Fwd: TMemDataset : pb & suggestions]
Oro06
orinaudo at gmail.com
Sat Oct 7 19:31:15 CEST 2006
.patch for memds, tested on win32 and wince
+4 methods added to encapsulate RecInfo access (that was causing =
alignement troubles in several places under wince)
+const added to define size (now 200) when string Field with zero size =
are copied from other datasets
+cache added for fields offset instead of recalculating sum(fileds size) =
everytime
regards
or
-------------- next part --------------
Index: memds.pp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- memds.pp (revision 4818)
+++ memds.pp (working copy)
@@ -1,6 +1,6 @@
{
This file is part of the Free Component Library (FCL)
- Copyright (c) 1999-2000 by the Free Pascal development team
+ Copyright (c) 1999-2006 by the Free Pascal development team
=
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
@@ -10,13 +10,14 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
=
**********************************************************************}
+{$IFDEF FPC}
{$mode objfpc}
+{$ENDIF FPC}
{$H+}
{
TMemDataset : In-memory dataset.
- Has possibility to copy Structure/Data from other dataset.
- Can load/save to/from stream.
-
Ideas taken from THKMemTab Component by Harri Kasulke - Hamburg/Germany
E-mail: harri.kasulke at okay.net
}
@@ -30,6 +31,9 @@
SysUtils, Classes, DB;
=
Const
+ //Default size used when string size is 0
+ MEMDS_STRING_MAXSIZE =3D 200;
+
// Stream Markers.
MarkerSize =3D SizeOf(Integer);
=
@@ -67,6 +71,7 @@
FCurrRecNo: integer;
FIsOpen: boolean;
FFilterBuffer: PChar;
+ FFieldOffsetList : TList;
protected
// Mandatory
function AllocRecordBuffer: PChar; override;
@@ -118,7 +123,14 @@
procedure MDSWriteRecord(Buffer:PChar;ARecNo:Integer);
procedure MDSAppendRecord(Buffer:PChar);
function MDSFilterRecord(Buffer: PChar): Boolean;
-
+ function MDSGetRecInfo(Buffer: PChar): TMTRecInfo;
+ procedure MDSSetRecInfo(Buffer: PChar;
+ Flag: TBookmarkFlag); =
+ procedure MDSSetRecInfo(Buffer: PChar;
+ Flag: TBookmarkFlag;
+ ABookmark: Longint); =
+ procedure MDSSetRecInfo(Buffer: PChar;
+ ABookmark: Longint); =
public
constructor Create(AOwner:tComponent); override;
destructor Destroy; override;
@@ -226,6 +238,7 @@
begin
inherited create(aOwner);
FStream:=3DTMemoryStream.Create;
+ FFieldOffsetList :=3D TList.Create;
FRecInfoSize:=3DSizeOf(TMTRecInfo);
FRecCount:=3D0;
FRecSize:=3D0;
@@ -238,6 +251,7 @@
Destructor TMemDataset.Destroy;
begin
FStream.Free;
+ FFieldOffsetList.Free;
inherited Destroy;
end;
=
@@ -247,14 +261,9 @@
end;
=
function TMemDataset.MDSGetFieldOffset(FieldNo: integer): integer;
-
-var
- I : integer;
-
begin
- Result:=3D0;
- for I:=3D1 to FieldNo-1 do
- Result:=3DResult+MDSGetFieldSize(I);
+ //FFieldOffsetList calculated once in createtable
+ Result:=3DInteger(FFieldOffsetList.Items[FieldNo-1]);
end;
=
Procedure TMemDataset.RaiseError(Fmt : String; Args : Array of const);
@@ -298,7 +307,7 @@
else
Buffer:=3Dnil;
end;
- Result:=3D(Buffer<>nil);
+ Result:=3DAssigned(Buffer);
end;
=
procedure TMemDataset.MDSReadRecord(Buffer:PChar;ARecNo:Integer); //Read=
s a Rec from Stream in Buffer
@@ -334,23 +343,8 @@
=
procedure TMemDataset.InternalInitRecord(Buffer: PChar);
=
-var
- I : integer;
-
begin
- for I:=3D1 to FieldCount do
- case FieldDefs.Items[I-1].Datatype of
- ftString: pChar(Buffer+MDSGetFieldOffset(I))^:=3D#0;
- ftBoolean: pBoolean(Buffer+MDSGetFieldOffset(I))^:=3DFalse;
- ftFloat: pFloat(Buffer+MDSGetFieldOffset(I))^:=3D0;
- ftLargeint: PInt64(Buffer+MDSGetFieldOffset(I))^:=3D0;
- ftSmallInt: pSmallInt(Buffer+MDSGetFieldOffset(I))^:=3D0;
- ftInteger: pInteger(Buffer+MDSGetFieldOffset(I))^:=3D0;
- ftCurrency: pFloat(Buffer+MDSGetFieldOffset(I))^:=3D0;
- ftDate: pFloat(Buffer+MDSGetFieldOffset(I))^:=3D0;
- ftTime: pFloat(Buffer+MDSGetFieldOffset(I))^:=3D0;
- ftDateTime: pFloat(Buffer+MDSGetFieldOffset(I))^:=3D0;
- end;
+ FillChar(Buffer^,FRecSize,0);
end;
=
procedure TMemDataset.InternalDelete;
@@ -626,7 +620,6 @@
end;
=
function TMemDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: =
Boolean): TGetResult;
-
var
Accepted: Boolean;
=
@@ -657,8 +650,8 @@
if result=3DgrOK then
begin
MDSReadRecord(Buffer, FCurrRecNo);
- PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=3DFCurrRecNo;
- PRecInfo(Buffer+FRecInfoOffset)^.BookmarkFlag:=3DbfCurrent;
+ MDSSetRecInfo( Buffer,bfCurrent,FCurrRecNo );
+
if (Filtered) then
Accepted:=3DMDSFilterRecord(Buffer) //Filtering
else
@@ -721,36 +714,34 @@
ReqBookmark: integer;
=
begin
- ReqBookmark:=3DPRecInfo(Buffer+FRecInfoOffset)^.Bookmark;
+ ReqBookmark:=3DMDSGetRecInfo(Buffer).Bookmark;
InternalGotoBookmark (@ReqBookmark);
end;
=
function TMemDataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;
-
begin
- Result:=3DPRecInfo(Buffer+FRecInfoOffset)^.BookmarkFlag;
+ Result:=3DMDSGetRecInfo(Buffer).BookmarkFlag;
end;
=
procedure TMemDataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
-
begin
- PRecInfo(Buffer+FRecInfoOffset)^.BookmarkFlag :=3D Value;
+ MDSSetRecInfo(Buffer,Value);
end;
=
procedure TMemDataset.GetBookmarkData(Buffer: PChar; Data: Pointer);
=
begin
if Data<>nil then
- PInteger(Data)^:=3DPRecInfo(Buffer+FRecInfoOffset)^.Bookmark;
+ PInteger(Data)^:=3DMDSGetRecInfo(Buffer).Bookmark;
end;
=
procedure TMemDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
=
begin
if Data<>nil then
- PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=3DPInteger(Data)^
+ MDSSetRecInfo(Buffer, PInteger(Data)^)
else
- PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=3D0;
+ MDSSetRecInfo( Buffer, 0);
end;
=
function TMemDataset.MDSFilterRecord(Buffer: PChar): Boolean;
@@ -768,6 +759,44 @@
RestoreState(SaveState);
end;
=
+function TMemDataset.MDSGetRecInfo(Buffer: PChar): TMTRecInfo;
+begin
+ Move(PRecInfo(Buffer+FRecInfoOffset)^,Result,FRecInfoSize);
+end;
+
+procedure TMemDataset.MDSSetRecInfo(Buffer: PChar;
+ Flag: TBookmarkFlag);
+var ARecInfo: TMTRecInfo;
+begin
+ //Unaligned(PRecInfo(Buffer+FRecInfoOffset)^).BookmarkFlag :=3D Flag;
+ ARecInfo:=3DMDSGetRecInfo(Buffer);
+ ARecInfo.BookmarkFlag:=3DFlag;
+ Move(ARecInfo,PRecInfo(Buffer+FRecInfoOffset)^,FRecInfoSize);
+end;
+
+procedure TMemDataset.MDSSetRecInfo(Buffer: PChar;
+ Flag: TBookmarkFlag;
+ ABookmark: Longint);
+var ARecInfo: TMTRecInfo;
+begin
+ //Unaligned(PRecInfo(Buffer+FRecInfoOffset)^).Bookmark :=3D ABookmark;
+ //Unaligned(PRecInfo(Buffer+FRecInfoOffset)^).BookmarkFlag :=3D Flag;
+ ARecInfo:=3DMDSGetRecInfo(Buffer);
+ ARecInfo.Bookmark:=3DABookmark;
+ ARecInfo.BookmarkFlag:=3DFlag;
+ Move(ARecInfo,PRecInfo(Buffer+FRecInfoOffset)^,FRecInfoSize);
+end;
+
+procedure TMemDataset.MDSSetRecInfo(Buffer: PChar;
+ ABookmark: Longint);
+var ARecInfo: TMTRecInfo;
+begin
+ //Unaligned(PRecInfo(Buffer+FRecInfoOffset)^).BookmarkFlag :=3D ABookmar=
k;
+ ARecInfo:=3DMDSGetRecInfo(Buffer);
+ ARecInfo.Bookmark:=3DABookmark;
+ Move(ARecInfo,PRecInfo(Buffer+FRecInfoOffset)^,FRecInfoSize);
+end;
+
Function TMemDataset.DataSize : Integer;
=
begin
@@ -796,20 +825,20 @@
end;
=
procedure TMemDataset.CreateTable;
-
var
- I : integer;
-
+ i, iSize : Longint;
begin
FStream.Clear;
FRecCount:=3D0;
FCurrRecNo:=3D-1;
FIsOpen:=3DFalse;
- FRecSize:=3D0;
- for I:=3D1 to FieldDefs.Count do
- FRecSize:=3DFRecSize+MDSGetFieldSize(I);
- FRecInfoOffset:=3DFRecSize;
- FRecSize:=3DFRecSize+FRecInfoSize;
+ iSize:=3D0;
+ for I:=3D1 to FieldDefs.Count do begin
+ FFieldOffsetList.Add(Pointer(iSize));
+ iSize:=3DiSize+MDSGetFieldSize(I);
+ end;
+ FRecInfoOffset:=3DiSize;
+ FRecSize:=3DiSize+FRecInfoSize;
FRecBufferSize:=3DFRecSize;
end;
=
@@ -857,7 +886,7 @@
Procedure TMemDataset.CopyFromDataset(DataSet : TDataSet; CopyData : Boole=
an);
=
Var
- I : Integer;
+ I, iDataSize : Integer;
F,F1,F2 : TField;
L1,L2 : TList;
N : String;
@@ -867,8 +896,12 @@
// NOT from fielddefs. The data may not be available in buffers !!
For I:=3D0 to Dataset.FieldCount-1 do
begin
- F:=3DDataset.Fields[I];
- TFieldDef.Create(FieldDefs,F.FieldName,F.DataType,F.Size,F.Required,F.=
FieldNo);
+ F:=3DDataset.Fields[I];
+ if (F.DataType=3DftString) and (F.Size=3D0)
+ then iDataSize:=3DMEMDS_STRING_MAXSIZE
+ else iDataSize:=3DF.Size;
+
+ TFieldDef.Create(FieldDefs,F.FieldName,F.DataType,iDataSize,F.Require=
d,F.FieldNo);
end;
CreateTable;
If CopyData then
More information about the fpc-devel
mailing list