views:

491

answers:

4

Hi Folks: I am trying to make an AlarmSystem in Delphi 7, Windows XP. I have to register alarms in a Database (MS SQL Server 2000). But what if the server is down??? Well, I can imagine that I have to persist objects of TAlarm type. So, how can I do this? Maybe inheriting from TComponent??? Please, how can I do this??

Thanks a lot.

I am sorry about my English.

Here you have more info... TAlarm is a class that descends from TObject, basically. There are 10 more classes that descend from TAlarm (some types of alarms). TAlarm has a field named FParams : TParams, and the child classes only have an Execute method. The field FParams can be of different types: TAlarmX1_Params, TAlarmX2_Params, etc, etc, etc.

A: 

You could persist the information in an XML or INI file locally. That doesn't require changing what TAlarm descends from. You would need to manually persist and restore all the properties that you wish to persist locally though. Shouldn't be that complicated.

Jim McKeeth
I'm sorry my friend, but I have never persisted objects. Please, tell me where I can find any tutorial or manual about persistence. How can I persist the information locally in an XML or INI file?? give an example please. Thanks very much.
DelphiProgrammer
+3  A: 

You can inheriting from TPersistent and then you can use the TJvAppXMLFileStorage (JVCL) component to serialize the TAlarm class.

Save a Object

uses
  JvAppXMLStorage;

Procedure SaveMyObject(MyAlarm : TAlarm)
var
  MyStore: TJvAppXMLFileStorage;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.WritePersistent('', MyAlarm);
    MyStore.Xml.SaveToFile('C:\MyAlarm.xml');
  finally
    MyStore.Free;
  end;
end;

Restore a Object

uses
  JvAppXMLStorage;

Procedure LoadMyObject(MyAlarm : TAlarm)
var
  MyStore: TJvAppXMLFileStorage;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\MyAlarm.xml';        
    MyStore.Xml.LoadFromFile('C:\MyAlarm.xml');
    MyStore.ReadPersistent('', MyAlarm);
  finally
    MyStore.Free;
  end;
end;

UPDATE

If you need to persist more than one object to the XML file you must assign a path (unique id) to the WritePersistent and ReadPersistent methods.

See this example,

Multiple Persist

Procedure SaveMyObjects(MyObjects : Array of TComponent);
var
  MyStore: TJvAppXMLFileStorage;
  i      : integer;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    for i := Low(MyObjects) to High(MyObjects) do
     MyStore.WritePersistent(MyObjects[i].Name, MyObjects[i]); //In this case i use the name property of the component.
    MyStore.Xml.SaveToFile('C:\Tools\MyAlarm.xml');
   finally
    MyStore.Free;
  end;
end;

to save the components

SaveMyObjects([Button1,Button2,Edit1,Edit2]);

Multiple LOAD

Procedure LoadMyObjects(MyObjects:Array of TComponent);
var
  MyStore    : TJvAppXMLFileStorage;
  i          : integer;

begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\Tools\MyAlarm.xml';
    MyStore.Xml.LoadFromFile('C:\Tools\MyAlarm.xml');
    for i := Low(MyObjects) to High(MyObjects) do
      MyStore.ReadPersistent(MyObjects[i].Name, MyObjects[i]);
  finally
    MyStore.Free;
  end;
end;

To restore the properties

LoadMyObjects([Button1,Button2,Edit1,Edit2]);

Another option to load

Procedure LoadMyObjectById(Id:String;MyObject:TComponent); //using the id of the object
var
  MyStore    : TJvAppXMLFileStorage;
  i          : integer;

begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\Tools\MyAlarm.xml';
    MyStore.Xml.LoadFromFile('C:\Tools\MyAlarm.xml');
   MyStore.ReadPersistent(id, MyObject);
  finally
    MyStore.Free;
  end;
end;

you must run it this way

LoadMyObjectById(Button1.Name,Button1); //Again using the Name property.

I hope this example will be useful ;)

RRUZ
I see no code that assigns a new value to the `MyAlarm` arguments, so why are they passed by reference?
Rob Kennedy
Rob you are right, in this case is not necessary to use VAR.
RRUZ
Ok, that's right... but what if I have to persist more than one object?? How to read more than one object from the XML???
DelphiProgrammer
You can use a tObjectList to hold onto your multiple objects and iterate thru the list for writing.
skamradt
Skamradt, TObjectList doesn't descend from TPersistent, so it can't be used in the given function. Furthermore, Yulien seems to have tried saving more than one object using Rruz's function, but each object overwrites the previous. See the follow-up question: http://stackoverflow.com/questions/1673741/persisting-more-than-one-object-in-delphi-7-closed
Rob Kennedy
A: 

If the server where you're supposed to be saving your data to is down, the best course of action is usually to cause the operation to fail and return an error. This way you don't need two separate sets of serialization code, both of which have to be kept in sync with each other, and a way to take your local data and upload it to the server once it's back up.

Plus, if your app depends on a remote server, it's likely that the user won't be able to do much with it offline anyway, so this isn't as bad of an idea as it may dound at first from a user-interface perspective.

Mason Wheeler
A: 

I used a local database, an Access mdb file accessed thru ADO, with the same schema than the server. When connection recovers, I did a synchronization. But, nowadays, I have dropped this technique; wnen connection is lost or server is down, the application fails.

PA