下面是一个 InMemeryTable 的类,除了不支持 Blob 字段和 Secondary Index外,
可以如普通 Table一样操作。
unit Inmem;
interface
uses DBTables, WinTypes, WinProcs, DBITypes, DBIProcs, DB, SysUtils;
type TInMemoryTable = class(TTable)
private
hCursor: hDBICur;
procedure EncodeFieldDesc(var FieldDesc: FLDDesc;
const Name: string; DataType: TFieldType; Size: Word);
function CreateHandle: HDBICur; override;
public
procedure CreateTable;
end;
implementation
function TInMemoryTable.CreateHandle;
begin
Result := hCursor;
end;
procedure TInMemoryTable.EncodeFieldDesc(var FieldDesc: FLDDesc;
const Name: string; DataType: TFieldType; Size: Word);
const
TypeMap: array[TFieldType] of Byte = (
fldUNKNOWN, fldZSTRING, fldINT16, fldINT32, fldUINT16, fldBOOL,
fldFLOAT, fldFLOAT, fldBCD, fldDATE, fldTIME, fldTIMESTAMP, fldBYTES,
fldVARBYTES, fldINT32, fldBLOB, fldBLOB, fldBLOB, fldBLOB, fldBLOB,
fldBLOB, fldBLOB, fldCURSOR);
SubTypeMap: array[TFieldType] of Word = (
0, 0, 0, 0, 0, 0, 0, fldstMONEY, 0, 0, 0, 0, 0, 0, fldstAUTOINC,
fldstBINARY, fldstMEMO, fldstGRAPHIC, fldstFMTMEMO, fldstOLEOBJ,
fldstDBSOLEOBJ, fldstTYPEDBINARY, 0);
begin
with FieldDesc do
begin
AnsiToNative(Locale, Name, szName, SizeOf(szName) - 1);
iFldType := TypeMap[DataType];
iSubType := SubTypeMap[DataType];
case DataType of
ftString, ftBytes, ftVarBytes, ftBlob, ftMemo, ftGraphic,
ftFmtMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary:
iUnits1 := Size;
ftBCD:
begin
iUnits1 := 32;
iUnits2 := Size;
end;
end;
end;
end;
procedure TInMemoryTable.CreateTable;
var
I: Integer;
pFieldDesc: pFLDDesc;
szTblName: DBITBLNAME;
iFields: Word;
Dogs: pfldDesc;
begin
CheckInactive;
if FieldDefs.Count = 0 then
for I := 0 to FieldCount - 1 do
with Fields do
if not Calculated then
FieldDefs.Add(FieldName, DataType, Size, Required);
pFieldDesc := nil;
SetDBFlag(dbfTable, True);
try
AnsiToNative(Locale, TableName, szTblName, SizeOf(szTblName) - 1);
iFields := FieldDefs.Count;
pFieldDesc := AllocMem(iFields * SizeOf(FLDDesc));
for I := 0 to FieldDefs.Count - 1 do
with FieldDefs do
begin
EncodeFieldDesc(PFieldDescList(pFieldDesc)^, Name,
DataType, Size);
end;
Check(DbiCreateInMemTable(DBHandle, szTblName, iFields, pFieldDesc, hCursor));
finally
if pFieldDesc <> nil then FreeMem(pFieldDesc, iFields * SizeOf(FLDDesc));
SetDBFlag(dbfTable, False);
end;
end;
end.
具体的使用方法如下所示:
MyInMemoryTable := TInMemoryTable.Create(TestForm);
with MyInMemoryTable do begin
DatabaseName := 'DBDEMOS';
{ TableName can be anything - but cannot be blank or DBE will give you
an invalid parameter error }
TableName := 'xxx.db';
{ add a couple of fields }
FieldDefs.Add('Field1', ftString, 10, False);
FieldDefs.Add('Field2', ftString, 15, False);
CreateTable;
{ open the table }
Active := True;
{ add a couple of records }
InsertRecord(['This table', 'is in memory!']);
InsertRecord(['Check it', 'out!']);
{ link the grid on the form to this table }
InMemoryDataSource.DataSet := MyInMemoryTable;
end;。