Class helper je známá věc, ale co třeba takový Record helper?
Poprvé se to objevilo jako mizerně dokumentovaná věc v BDS 2006 v Delphi for .NET. A teprve následně se to propagovalo do verze Win32. Tady měl Borland zpoždění - .NET verze byla vždycky o krok napřed.
I mějme nějaký příkladný záznam např. tento:
type
{ TZazPoj }
//je to jen příklad – musí být deklarován jako PACKED !!
TZazPoj = packed record
{tohle je vychytávka na záznamy, sem ukládám, že jsou složky záznamu OK, a nemusím testovat další políčka}
FillOK: Boolean;
FVERSE: Word;
{zde jsou data}
FID: Integer;
//stringy musí mít velikost, je to vlastně ShortString
FSMLOUVA: string[20];
FJMENO: string[48];
{případně další složky nebo vnořené záznamy…}
public
procedure Clear;
end;
{ TZazPoj }
procedure TZazPoj.Clear; //je to dobré i pro variantní záznamy
begin
//v případě ne-PACKED nelze tímto jednoduchým způsobem mazat řetězce a pole!
FillChar(Self, SizeOf(Self), 0);
end;
Nic moc, ale na ukázku to stačí. No a zde můžeme využít nový „dodaný“ kód a z venku pozměnit funkčnost (tento kód je plně funkční, napsaný v Delphi XE, ale je to funkční i v Delphi 2007).
Helper se píše úplně stejně jako pro class, ale klíčové slůvko class se nahradí record. Pro použití, pokud samozřejmě bude v jiné unitě než deklarace záznamu (pak to nemá smysl, může to být vloženo rovnou jako metody do záznamu), musí být tento unit uveden v uses jednotky, kde má být použit, pravidla viditelnosti jsou stejná jako pro class helper.
type
TZazPojStore = record helper for TZazPoj
public
procedure SaveToBlob(Table: TDataset; BlobName: string);
function LoadFromBlob(Table: TDataset; BlobName: string): Boolean;
end;
{ TZazPojStore }
function TZazPojStore.LoadFromBlob(Table: TDataset; BlobName: string): Boolean;
var
blobF: TBlobField;
bs: TStream;
begin
Result := False;
if Table.FieldByName(BlobName).IsBlob then
begin
blobF := Table.FieldByName(BlobName) as TBlobField;
bs := Table.CreateBlobStream(blobF, bmRead);
try
bs.Read(Self, SizeOf(Self));
Result := True;
finally
bs.Free;
end;
end;
end;
procedure TZazPojStore.SaveToBlob(Table: TDataSet; BlobName: string);
var
blobF: TBlobField;
bs: TStream;
begin
blobF := Table.FieldByName(BlobName) as TBlobField;
bs := Table.CreateBlobStream(blobF, bmWrite);
try
bs.Write(Self, SizeOf(Self));
finally
bs.Free;
end;
end;
A použití je snadné, viz načtení i uložení (stavy pro vložení nebo editaci si jistě každý dělá po svém)
var
MUJREC: TZazPoj;
Načtení záznamu z DB
Připojení je nastaveno v tomto případě rovnou z DBGridu (ZAZPOJGrid) přes datasource na dataset.
MUJREC.LoadFromBlob(ZAZPOJGrid.DataSource.DataSet, 'DATAREC');
Uložení záznamu do DB
MUJREC.SaveToBlob(ZAZPOJGrid.DataSource.DataSet, 'DATAREC');