mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 14:09:20 +02:00
* Patch from orinaudo@gmail.com:
+ 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(fields size) everytime git-svn-id: trunk@4822 -
This commit is contained in:
parent
dfd3b2503e
commit
0c669fbad0
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
This file is part of the Free Component Library (FCL)
|
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,
|
See the file COPYING.FPC, included in this distribution,
|
||||||
for details about the copyright.
|
for details about the copyright.
|
||||||
@ -10,13 +10,14 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
|
{$IFDEF FPC}
|
||||||
{$mode objfpc}
|
{$mode objfpc}
|
||||||
|
{$ENDIF FPC}
|
||||||
{$H+}
|
{$H+}
|
||||||
{
|
{
|
||||||
TMemDataset : In-memory dataset.
|
TMemDataset : In-memory dataset.
|
||||||
- Has possibility to copy Structure/Data from other dataset.
|
- Has possibility to copy Structure/Data from other dataset.
|
||||||
- Can load/save to/from stream.
|
- Can load/save to/from stream.
|
||||||
|
|
||||||
Ideas taken from THKMemTab Component by Harri Kasulke - Hamburg/Germany
|
Ideas taken from THKMemTab Component by Harri Kasulke - Hamburg/Germany
|
||||||
E-mail: harri.kasulke@okay.net
|
E-mail: harri.kasulke@okay.net
|
||||||
}
|
}
|
||||||
@ -30,6 +31,9 @@ uses
|
|||||||
SysUtils, Classes, DB;
|
SysUtils, Classes, DB;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
|
//Default size used when string size is 0
|
||||||
|
MEMDS_STRING_MAXSIZE = 200;
|
||||||
|
|
||||||
// Stream Markers.
|
// Stream Markers.
|
||||||
MarkerSize = SizeOf(Integer);
|
MarkerSize = SizeOf(Integer);
|
||||||
|
|
||||||
@ -67,6 +71,7 @@ type
|
|||||||
FCurrRecNo: integer;
|
FCurrRecNo: integer;
|
||||||
FIsOpen: boolean;
|
FIsOpen: boolean;
|
||||||
FFilterBuffer: PChar;
|
FFilterBuffer: PChar;
|
||||||
|
FFieldOffsetList : TList;
|
||||||
protected
|
protected
|
||||||
// Mandatory
|
// Mandatory
|
||||||
function AllocRecordBuffer: PChar; override;
|
function AllocRecordBuffer: PChar; override;
|
||||||
@ -118,7 +123,14 @@ type
|
|||||||
procedure MDSWriteRecord(Buffer:PChar;ARecNo:Integer);
|
procedure MDSWriteRecord(Buffer:PChar;ARecNo:Integer);
|
||||||
procedure MDSAppendRecord(Buffer:PChar);
|
procedure MDSAppendRecord(Buffer:PChar);
|
||||||
function MDSFilterRecord(Buffer: PChar): Boolean;
|
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
|
public
|
||||||
constructor Create(AOwner:tComponent); override;
|
constructor Create(AOwner:tComponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -226,6 +238,7 @@ constructor TMemDataset.Create(AOwner:tComponent);
|
|||||||
begin
|
begin
|
||||||
inherited create(aOwner);
|
inherited create(aOwner);
|
||||||
FStream:=TMemoryStream.Create;
|
FStream:=TMemoryStream.Create;
|
||||||
|
FFieldOffsetList := TList.Create;
|
||||||
FRecInfoSize:=SizeOf(TMTRecInfo);
|
FRecInfoSize:=SizeOf(TMTRecInfo);
|
||||||
FRecCount:=0;
|
FRecCount:=0;
|
||||||
FRecSize:=0;
|
FRecSize:=0;
|
||||||
@ -238,6 +251,7 @@ end;
|
|||||||
Destructor TMemDataset.Destroy;
|
Destructor TMemDataset.Destroy;
|
||||||
begin
|
begin
|
||||||
FStream.Free;
|
FStream.Free;
|
||||||
|
FFieldOffsetList.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -247,14 +261,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TMemDataset.MDSGetFieldOffset(FieldNo: integer): integer;
|
function TMemDataset.MDSGetFieldOffset(FieldNo: integer): integer;
|
||||||
|
|
||||||
var
|
|
||||||
I : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=0;
|
//FFieldOffsetList calculated once in createtable
|
||||||
for I:=1 to FieldNo-1 do
|
Result:=Integer(FFieldOffsetList.Items[FieldNo-1]);
|
||||||
Result:=Result+MDSGetFieldSize(I);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure TMemDataset.RaiseError(Fmt : String; Args : Array of const);
|
Procedure TMemDataset.RaiseError(Fmt : String; Args : Array of const);
|
||||||
@ -298,7 +307,7 @@ begin
|
|||||||
else
|
else
|
||||||
Buffer:=nil;
|
Buffer:=nil;
|
||||||
end;
|
end;
|
||||||
Result:=(Buffer<>nil);
|
Result:=Assigned(Buffer);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMemDataset.MDSReadRecord(Buffer:PChar;ARecNo:Integer); //Reads a Rec from Stream in Buffer
|
procedure TMemDataset.MDSReadRecord(Buffer:PChar;ARecNo:Integer); //Reads a Rec from Stream in Buffer
|
||||||
@ -334,23 +343,8 @@ end;
|
|||||||
|
|
||||||
procedure TMemDataset.InternalInitRecord(Buffer: PChar);
|
procedure TMemDataset.InternalInitRecord(Buffer: PChar);
|
||||||
|
|
||||||
var
|
|
||||||
I : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
for I:=1 to FieldCount do
|
FillChar(Buffer^,FRecSize,0);
|
||||||
case FieldDefs.Items[I-1].Datatype of
|
|
||||||
ftString: pChar(Buffer+MDSGetFieldOffset(I))^:=#0;
|
|
||||||
ftBoolean: pBoolean(Buffer+MDSGetFieldOffset(I))^:=False;
|
|
||||||
ftFloat: pFloat(Buffer+MDSGetFieldOffset(I))^:=0;
|
|
||||||
ftLargeint: PInt64(Buffer+MDSGetFieldOffset(I))^:=0;
|
|
||||||
ftSmallInt: pSmallInt(Buffer+MDSGetFieldOffset(I))^:=0;
|
|
||||||
ftInteger: pInteger(Buffer+MDSGetFieldOffset(I))^:=0;
|
|
||||||
ftCurrency: pFloat(Buffer+MDSGetFieldOffset(I))^:=0;
|
|
||||||
ftDate: pFloat(Buffer+MDSGetFieldOffset(I))^:=0;
|
|
||||||
ftTime: pFloat(Buffer+MDSGetFieldOffset(I))^:=0;
|
|
||||||
ftDateTime: pFloat(Buffer+MDSGetFieldOffset(I))^:=0;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMemDataset.InternalDelete;
|
procedure TMemDataset.InternalDelete;
|
||||||
@ -626,7 +620,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TMemDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult;
|
function TMemDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult;
|
||||||
|
|
||||||
var
|
var
|
||||||
Accepted: Boolean;
|
Accepted: Boolean;
|
||||||
|
|
||||||
@ -657,8 +650,8 @@ begin
|
|||||||
if result=grOK then
|
if result=grOK then
|
||||||
begin
|
begin
|
||||||
MDSReadRecord(Buffer, FCurrRecNo);
|
MDSReadRecord(Buffer, FCurrRecNo);
|
||||||
PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=FCurrRecNo;
|
MDSSetRecInfo( Buffer,bfCurrent,FCurrRecNo );
|
||||||
PRecInfo(Buffer+FRecInfoOffset)^.BookmarkFlag:=bfCurrent;
|
|
||||||
if (Filtered) then
|
if (Filtered) then
|
||||||
Accepted:=MDSFilterRecord(Buffer) //Filtering
|
Accepted:=MDSFilterRecord(Buffer) //Filtering
|
||||||
else
|
else
|
||||||
@ -721,36 +714,34 @@ var
|
|||||||
ReqBookmark: integer;
|
ReqBookmark: integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ReqBookmark:=PRecInfo(Buffer+FRecInfoOffset)^.Bookmark;
|
ReqBookmark:=MDSGetRecInfo(Buffer).Bookmark;
|
||||||
InternalGotoBookmark (@ReqBookmark);
|
InternalGotoBookmark (@ReqBookmark);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMemDataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;
|
function TMemDataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=PRecInfo(Buffer+FRecInfoOffset)^.BookmarkFlag;
|
Result:=MDSGetRecInfo(Buffer).BookmarkFlag;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMemDataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
|
procedure TMemDataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
PRecInfo(Buffer+FRecInfoOffset)^.BookmarkFlag := Value;
|
MDSSetRecInfo(Buffer,Value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMemDataset.GetBookmarkData(Buffer: PChar; Data: Pointer);
|
procedure TMemDataset.GetBookmarkData(Buffer: PChar; Data: Pointer);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if Data<>nil then
|
if Data<>nil then
|
||||||
PInteger(Data)^:=PRecInfo(Buffer+FRecInfoOffset)^.Bookmark;
|
PInteger(Data)^:=MDSGetRecInfo(Buffer).Bookmark;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMemDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
|
procedure TMemDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if Data<>nil then
|
if Data<>nil then
|
||||||
PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=PInteger(Data)^
|
MDSSetRecInfo(Buffer, PInteger(Data)^)
|
||||||
else
|
else
|
||||||
PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=0;
|
MDSSetRecInfo( Buffer, 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMemDataset.MDSFilterRecord(Buffer: PChar): Boolean;
|
function TMemDataset.MDSFilterRecord(Buffer: PChar): Boolean;
|
||||||
@ -768,6 +759,44 @@ begin
|
|||||||
RestoreState(SaveState);
|
RestoreState(SaveState);
|
||||||
end;
|
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 := Flag;
|
||||||
|
ARecInfo:=MDSGetRecInfo(Buffer);
|
||||||
|
ARecInfo.BookmarkFlag:=Flag;
|
||||||
|
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 := ABookmark;
|
||||||
|
//Unaligned(PRecInfo(Buffer+FRecInfoOffset)^).BookmarkFlag := Flag;
|
||||||
|
ARecInfo:=MDSGetRecInfo(Buffer);
|
||||||
|
ARecInfo.Bookmark:=ABookmark;
|
||||||
|
ARecInfo.BookmarkFlag:=Flag;
|
||||||
|
Move(ARecInfo,PRecInfo(Buffer+FRecInfoOffset)^,FRecInfoSize);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMemDataset.MDSSetRecInfo(Buffer: PChar;
|
||||||
|
ABookmark: Longint);
|
||||||
|
var ARecInfo: TMTRecInfo;
|
||||||
|
begin
|
||||||
|
//Unaligned(PRecInfo(Buffer+FRecInfoOffset)^).BookmarkFlag := ABookmark;
|
||||||
|
ARecInfo:=MDSGetRecInfo(Buffer);
|
||||||
|
ARecInfo.Bookmark:=ABookmark;
|
||||||
|
Move(ARecInfo,PRecInfo(Buffer+FRecInfoOffset)^,FRecInfoSize);
|
||||||
|
end;
|
||||||
|
|
||||||
Function TMemDataset.DataSize : Integer;
|
Function TMemDataset.DataSize : Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -796,20 +825,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMemDataset.CreateTable;
|
procedure TMemDataset.CreateTable;
|
||||||
|
|
||||||
var
|
var
|
||||||
I : integer;
|
i, iSize : Longint;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
FStream.Clear;
|
FStream.Clear;
|
||||||
FRecCount:=0;
|
FRecCount:=0;
|
||||||
FCurrRecNo:=-1;
|
FCurrRecNo:=-1;
|
||||||
FIsOpen:=False;
|
FIsOpen:=False;
|
||||||
FRecSize:=0;
|
iSize:=0;
|
||||||
for I:=1 to FieldDefs.Count do
|
for I:=1 to FieldDefs.Count do begin
|
||||||
FRecSize:=FRecSize+MDSGetFieldSize(I);
|
FFieldOffsetList.Add(Pointer(iSize));
|
||||||
FRecInfoOffset:=FRecSize;
|
iSize:=iSize+MDSGetFieldSize(I);
|
||||||
FRecSize:=FRecSize+FRecInfoSize;
|
end;
|
||||||
|
FRecInfoOffset:=iSize;
|
||||||
|
FRecSize:=iSize+FRecInfoSize;
|
||||||
FRecBufferSize:=FRecSize;
|
FRecBufferSize:=FRecSize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -857,7 +886,7 @@ end;
|
|||||||
Procedure TMemDataset.CopyFromDataset(DataSet : TDataSet; CopyData : Boolean);
|
Procedure TMemDataset.CopyFromDataset(DataSet : TDataSet; CopyData : Boolean);
|
||||||
|
|
||||||
Var
|
Var
|
||||||
I : Integer;
|
I, iDataSize : Integer;
|
||||||
F,F1,F2 : TField;
|
F,F1,F2 : TField;
|
||||||
L1,L2 : TList;
|
L1,L2 : TList;
|
||||||
N : String;
|
N : String;
|
||||||
@ -867,8 +896,12 @@ begin
|
|||||||
// NOT from fielddefs. The data may not be available in buffers !!
|
// NOT from fielddefs. The data may not be available in buffers !!
|
||||||
For I:=0 to Dataset.FieldCount-1 do
|
For I:=0 to Dataset.FieldCount-1 do
|
||||||
begin
|
begin
|
||||||
F:=Dataset.Fields[I];
|
F:=Dataset.Fields[I];
|
||||||
TFieldDef.Create(FieldDefs,F.FieldName,F.DataType,F.Size,F.Required,F.FieldNo);
|
if (F.DataType=ftString) and (F.Size=0)
|
||||||
|
then iDataSize:=MEMDS_STRING_MAXSIZE
|
||||||
|
else iDataSize:=F.Size;
|
||||||
|
|
||||||
|
TFieldDef.Create(FieldDefs,F.FieldName,F.DataType,iDataSize,F.Required,F.FieldNo);
|
||||||
end;
|
end;
|
||||||
CreateTable;
|
CreateTable;
|
||||||
If CopyData then
|
If CopyData then
|
||||||
|
Loading…
Reference in New Issue
Block a user