You have to create methods TSPLoginUser.SaveToStream(
// save
bstream := dm.iboQuery1.CreateBlobStr
bstream.SaveToStream(strea
// load
stream := dm.IBOQuery1.CreateBlobStr
stream.LoadFromStream(stre
Main Topics
Browse All TopicsHi,
I would like to save a object that I created to database. I got this far looking at other solutions on EE (Save object in data base, Q_11075005).
I have created a Firebird database with two fields (Supplier_ID - Integer, sup_option - Binary BLOB).
The code below works not 100%. In Button1Click I write my object to database. The record is created and all looks good. But when I read the blob field from DB to populate my user object (Button2Click) none of the properties of the object are set.
One thing I have noticed is that 'sizeof(usr)' (Button1Click) always returns 4, no matter how long I make my Fullname and Password properties. Is this correct? I guess this is my problem. Only 4 bytes of my object are written to the DB.
procedure TForm_Main.Button1Click(Se
var
usr : TSPLoginUser;
bstream : TStream;
begin
//The object that I would like to store in the DB
usr := TSPLoginUser.Create;
usr.Username := 'addey';
usr.Fullname := 'Jacques';
usr.Password := 'password';
//Open query and create new record.
dm.IBOQuery1.Open;
dm.IBOQuery1.Append;
dm.IBOQuery1SUPPLIER_ID.Va
bstream := dm.iboQuery1.CreateBlobStr
bstream.Write(usr,sizeof(u
dm.IBOQuery1.Post;
dm.IBOQuery1.Close;
end;
procedure TForm_Main.Button2Click(Se
var
usr : TSPLoginUser;
stream : TStream;
begin
dm.IBOQuery1.Open;
stream := dm.IBOQuery1.CreateBlobStr
stream.Read(usr,sizeof(usr
dm.IBOQuery1.Close;
end;
Thanks!
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
You have to create methods TSPLoginUser.SaveToStream(
// save
bstream := dm.iboQuery1.CreateBlobStr
bstream.SaveToStream(strea
// load
stream := dm.IBOQuery1.CreateBlobStr
stream.LoadFromStream(stre
if you make your class TComponent descentant then you can use the
TSream.WriteComponent and TStream.ReadComponent methods.
(but first you must call once RegisterClass(TSPLoginUser
I have made an example for using this routines
just put a btnSave, btnLoad, memo1, memo2 on a form and use the code for the unit as below
of course you can skip the conversion from to string and keep the binary format of the component
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btnSave: TButton;
btnLoad: TButton;
Memo1: TMemo;
Memo2: TMemo;
procedure btnSaveClick(Sender: TObject);
procedure btnLoadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TTestClass = class(TComponent)
private
FPassword: string;
FFullname: string;
FUsername: string;
published
property Fullname: string read FFullname write FFullname;
property Username: string read FUsername write FUsername;
property Password: string read FPassword write FPassword;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function ComponentToString(Componen
var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(C
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStre
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free;
end;
finally
BinStream.Free
end;
end;
function StringToComponent(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStre
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(ni
finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;
procedure TForm1.btnSaveClick(Sender
var
tc: TTestClass;
begin
tc := TTestClass.Create(nil);
tc.Username := 'kemanetzis';
tc.Fullname := 'Michael Kemanetzis';
tc.password := '12345678';
Memo1.Lines.Text := ComponentToString(tc);
tc.free;
end;
procedure TForm1.btnLoadClick(Sender
var
tc: TTestClass;
begin
tc := StringToComponent(Memo1.Li
Memo2.Lines.Text := tc.Username+#13#10+tc.Full
tc.free;
end;
initialization
RegisterClass(TTestClass);
end.
and check this
http://www.experts-exchang
it is the same with more complexity
Thanks for all the help.
I origionally did not want to make my class a TComponent decendant. I thought that all the inherited functionality would make my class use more resources, and I wouldn't have used it anyway, except for WriteComponent and ReadComponent.
So, this is what I have done:
I have to classes, my business object (TSP_PriceListImportOption
TSP_PriceListImportOption = class
private
_data : ISPPriceListImportOption_D
public
_new : boolean;
SupplierID : integer;
StartAtRow : integer;
ItemCodeCol : integer;
PriceCol : integer;
DescriptionCol : integer;
UseMultipleTabs : boolean;
TabsToSkip : TStrings;
NotAvailablePrice : string;
DescSpanRows : boolean;
constructor Create(DAO : ISPPriceListImportOption_D
procedure Save();
end;
Within my data access object I created two procedures, WriteToStream and ReadFromStream.
The constructor calls the ReadFromStream procedure in my data access object, and the Save procedure the WriteToStram procedure.
procedure TSPPriceListImportOption_F
plio: TSP_PriceListImportOption)
var
len, i, cnt : integer;
str : string;
begin
//Write the first few integer properties to the stream.
stream.Write(plio.Supplier
stream.Write(plio.StartAtR
stream.Write(plio.ItemCode
stream.Write(plio.PriceCol
stream.Write(plio.Descript
//Whether multiple tabs should be scanned
len := StrToInt(BoolToStr(plio.Us
stream.Write(len, sizeof(len));
//Write to the stream each tab that should not be scanned.
cnt := plio.TabsToSkip.Count;
stream.Write(cnt,sizeof(cn
for i := 0 to cnt-1 do begin
str := plio.TabsToSkip.Strings[i]
len := length(str); // get the length of the address
Stream.Write(len, sizeof(len)); // write length of address
Stream.Write(str[1], len); // write the address
end;
//Not Available Price value
str := plio.NotAvailablePrice;
len := length(str);
stream.Write(len,sizeof(le
stream.Write(str[1],len);
//Does the description span multiple lines
len := StrToInt(BoolToStr(plio.De
stream.Write(len, sizeof(len));
end;
procedure TSPPriceListImportOption_F
plio: TSP_PriceListImportOption)
var
len,i,cnt : integer;
str : string;
begin
stream.Read(plio.SupplierI
stream.Read(plio.StartAtRo
stream.Read(plio.ItemCodeC
stream.Read(plio.PriceCol,
stream.Read(plio.Descripti
stream.Read(len,sizeof(len
plio.UseMultipleTabs := StrToBool(IntToStr(len));
stream.Read(cnt,sizeof(cnt
for i := 0 to cnt-1 do begin
stream.Read(len,sizeof(len
setLength(str, len);
stream.Read(str[1],len);
plio.TabsToSkip.Add(str);
end;
//Not Available Price value
stream.Read(len,sizeof(len
setLength(str, len);
stream.Read(str[1],len);
plio.NotAvailablePrice := str;
//Does the description span multiple rows
stream.Read(len,sizeof(len
plio.DescSpanRows := StrToBool(IntToStr(len));
end;
This seems to do the job and my object is saved to DB.
Business Accounts
Answer for Membership
by: kretzschmarPosted on 2005-11-16 at 21:20:17ID: 15309443
>Only 4 bytes of my object are written to the DB.
ofcourse, you store only tha current valid pointer to your object
you need to write a writer/reader for your object to store/restore the content
meikl ;-)