[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