Delphi Component Serialization - delphi

Has anyone run into issues serializing components into a file and reading them back, specifically in the area where the component vendor upgrades the VCL components. For example a file serialized with DelphiX and then years later read back with delphiY. Do the serialization formats change and if so what can be done to prevent errors reading in the componets when upgrading.

The built-in RTTI based system for serializing published properties is vulnerable to changes in the components. Going forwards is manageable as long as old properties are kept in new objects. I.e. you leave the property interface as is, but can toss away the contents if you like. Going backwards is worse - as a newer version saved property can't be opened in older version load, and that will be a problem.
There are components / libs (http://www.torry.net/quicksearchd.php?String=RTTI&Title=Yes) that can add serialization in XML format and this may help a bit as you can choose to skip content you don't know.
You still need to be mindful about how you design your published content and should probably find a way to "ignore but propagate" content that your current version don't understand. This will allow you to open and change a file in a newer format while attempting to keep newer attributes, instead of stripping them.

Formats will defintely change, as vendors will add features to their components. Serialization simply loops over all published properties and saves them to a stream. When they are read back, each of the properties that is read from the stream will be set back to the component. If the property does not exist anymore, you have a problem. I don't think you can do anything about that besides some basic exception handling.
Best way to guarantee compatibility is to do your own serialization.

Thanks for the reply. I was trying to avoid custom serialization and take advantage of the each component serialization technique, but with the lack opf any way to "patch" an upgrade to a new component format I guess custom serialization is the only method.

Related

Making object model available via Automation in Delphi: what’s the easiest way?

We’re rewriting a calculation core from scratch in Delphi, and we’re looking for ways to let other people write code against it.
Automation seems a fairly safe way to get this done. One use we’re thinking of is making it available to VBA/Office, and also generating a .NET assembly (based on the Automation object, that's easy).
But the code should still be easy to use from Delphi, since we’ll be writing our (desktop) UI with that.
Now I’ve been looking into creating an Automation server in Delphi, and it looks like quite a hassle to have to design the components in the Type Library wizard, and then generate the base code.
The calculations we’re having to implement are described in official rules and regulations that are still not ratified, and so could still change before we’re done — they very probably will, perhaps quite extensively. Waiting for the final version is not an option.
An alternative way could be to finish the entire object model first, and write a separate Automation server which only describes the top-level object, switch $METHODINFO ON, and use TObjectDispatch to return all the subordinate objects. As I see it, that would entail having to write wrappers to return the objects by IDispatch interface. Since there's over a 100 different classes in there, that doesn’t look like an attractive option.
Edit: TObjectDispatch is smart enough to wrap any objects returned by properties and methods as well; so only the top object(s) would need to be wrapped. Lack of a complete type library does mean only late-binding is possible, however.
Is there an other, easier (read: hassle-free) way to write a COM-accessible object model in Delphi?
You don't have to use the type library designer. You can write or generate (e.g. from RTTI of your Delphi classes) a .ridl file and add it to your Automation library project.
Generating interface description from RTTI is a great idea! After you have your interfaces generated you can generate a delphi unit from them and implementing in your classes. Of course the majority are implemented already since you have generated the interfaces from those classes after all. The late binding resolution can be done after that by hand using RTTI and implementing IDispatch and IDispatchEx in a common baseclass of the scriptable classes.

Help with Delphi DFM generation based on Database Tables (Scaffolding?)

I'm new to delphi and I'm looking up on ways to learn more about delphi underlying technology plus make something useful here in my job in the process, also if anyone has any tip or see anyway i can improve my idea please fell free to speak your mind...
i want to do make some kind of Scaffolding for dfms, the ideia is the following: i want to generate based on a firebird database table - with well defined domains - the bulk of the Form .
I think the idea is too simple or i'm not seeing the big picture that makes it difficult, i'm trying not to reinvent the well, i've looked up on google but without good results, so if anyone could giveme a direction here i would be most grateful.
UPDATE:
#Larry Lustig thanks, i didn't think about delphi frameworks - i'm going to look them up.
i know something about form objects/handling and database metadata, but i'm unfamiliar with serilizing delphi objects to the HD. Any tips on Serialization and delphi frameworks (opensource so i could take a look :) ) would be welcome!
Sounds like an interesting idea.
Instead of writing a DFM form manually on disk I would use the following approach:
Get the structure of your table by examining the meta data.
Create a TForm and add a control to it for each column you want to represent.
Use Delphi's built in serialization to save the form to disk.
I haven't done this myself, but there are a number of run-time design frameworks that work using this idea.
This would only make sense if you need to build a lot of forms at design time. You can't use the DFM's in your executable's. If you want to build the forms runtime, I suggest you go with Larry Lustig's answer.
We have taken this one step further... we don't build forms. We only write the classes, add some attributes and create the forms at runtime. Users can change this preset form layout during runtime and save their own layout. Data binding between the controls and the database is done with the excellent tiOPF framework. Maybe something you can consider to use as well.

Replacing non-visual components with code

Is "Replacing non-visual components with code" a proven optimization technique in Delphi 7. Mainly with respect to Database Access.
The Web site you cite talks about replacing a dialog-box component with code that would display the dialog box without the use of any component. The alternative is to write a couple of lines of code to set up and display a dialog box whenever you need one, and to skip the component altogether. It's not really an optimization in speed or size, though. It's not a speed optimization since your code would do exactly what a component would have done anyway, and it's not a size optimization because the space any one component occupies in a program is negligible.
Database components aren't so easily replaceable as dialog-box components. Nearly everything in Delphi is designed to use descendants of the standard database components. If you don't use the components, then you won't be using any of Delphi's database capabilities at all. You can use the database libraries' native APIs if you wish, but I think that would be foolish if your goal is really optimization and you haven't identified the components as the source of your program's non-optimal behavior. Consider how much time and effort it would take you to rewrite your program without the database components.
I don't see how a form-based dataset/query/table/etc., would be faster or slower than one created in code. However, I like to put them in code as it's easier to maintain. I've seen screens with SQL embedded in a component, and then it's overridden in the code. Then I have to stop and investigate to determine which SQL is actually in effect. Sometimes the SQL in the form is good, sometimes it's used for a while and then trumped by the code, sometimes it's never active and the SQL is trumped in the formcreate. So I have to determine whether this is by design, or just sloppy leftovers. Also, it's easy to miss SQL changes in code reviews if they're in the .DFM and not the .PAS. i.e. I don't always look at the .DFM because I'm not interested in whether a label caption changed or a button moved.
So while it's nice for prototyping, when it comes to production code, you're better off having all of your database logic (SQL, table and field definitions) in the .pas file.
Update: I have finally given CnPack a try. Among the dozens of goodies, is a brilliant tool called "convert selected components to code". Form Design Wizard | More... | Convert Selected Components To Code. It does it all for you.
This is not a matter of being a component or not a component. If it comes to database access then BDE is extremely slow so changing it for sth else is a good move.
By the way - optimization is not about 'proven techniques' - it's about identifying a problem and solving it. If the problem happens to be slow db access then this is what you have to change.
Generally no. There is no additional overhead in using a non-visual component. It is created very quickly and works at runtime exactly at the same speed as one "created in code".

Delphi object persistence, what is the best way

I have developed application for drawing some shapes (lines mostly) , now i need to be able to store sketch to a file, I know that delphi has build in routines for object persistence, but I have never used it.
Can someone tell me can object persistence be used if i have to persist object that have also references to other objects (that will be stored to), I have TLine object which can be connected to other TLine object etc.
Is it better to use this feature or write custom procedure to store/read object to/from file.
The built in object persistance is primarily designed for use in streaming components to a dfm, the work that you would need to do to persist your sketch would not benefit very much from that mechanism.
I think that you would be better off coming up with a custom scheme.
One method that I have used in the past is to store my object properties in an XML file writing a custom "save" routine which adds to a passed IXMLNode, and a new constructor which reads from a passed IXMLNode. I store component as a node, and the properties as attributes (unless the property is another object, then it would be a child node).
I believe there are some routines in the Delphi Jedi project which will handle component streaming for you, but I have not used them directly as most of my XML streaming has been done by hand since my objects were extremely simple and could be rendered with only a handful of properties.
I use the TI Object persistence framework (tiopf.com). I wrote the overview at http://tiopf.sourceforge.net/Doc/overview/index.shtml.
It will let you save objects and lists to xml, csv, databases etc. It handles child objects automatically.
If you are interested, use the svn version, not the sourceforge download as it has more features (inc partial D 2009 support).
You also can use the famous hibernate know from java.
the delphi port you can find here:
dHibernate
JSON is a new and very compact way to store objects. Two libraries are available for Delphi: SuperObject and lkJSON.
With NativeXML from http://www.simdesign.nl/xml.html I accomplished to read/write delphi in-memory objects from/to XML code. Very nice, very easy, with demo included here: http://www.simdesign.nl/forum/download/file.php?id=236

Lightweight Store Mechanisms

I'm about to write a small utility to organze and tag my mp3s.
What is the best way to store small amounts of data. More importantly, are there databases which exist where I don't need to install a client/server environment, I just include the library and I'm good?
I could use XML, but I'm afraid that the file size would become large and hard to handle, not to mention keeping the memory footprint small.
Thanks
EDIT: I haven't decided on the language, I wanted to make my decision independent of platform. If I had to choose, most likely .NET, second Java, third C++.
My apologies, this is for a Windows App.
On Windows you can use the built-in esent database engine. There is an API you can use from C++
http://blogs.msdn.com/windowssdk/archive/2008/10/23/esent-extensible-storage-engine-api-in-the-windows-sdk.aspx
There is also a managed interop layer that you can use from C# code:
http://www.codeplex.com/ManagedEsent
Which language/platform are you talking about?
In the Java world I prefer using embedded databases such as HSQLDB, H2 or JavaDB (f.k.a. Derby).
They don't need installing and still provide the simple access you're used to from a "real" DBMS.
In the C/Python/Unixy world SQLite is a hot contender in that area.
Another option is the various forms of the Berkeley database (eg, db3, db4, SleepyCat.)
SQLITE if you want the pain of a relational DB without a server install or hassle.
I would use one of the many text-serialization formats. I personally think that YAML 1.1 is the most powerful (built-in support for referential object graphs) and easiest to read/modify by a human (parsing is a bear, use a library such as PyYAML or JYaml or some .NET libaray).
Otherwise XML or JSON are adequate file formats.
Whichever format you use, just compress the file if you're concerned about disk usage. If you're worried about in-memory usage, then I don't see how your serialization format matters...
Have a look at Prevayler - it's a serialization persistence framework (use xstream etc if you want to human-read your data), which is really fast, does not require annotations and "just works". Some basic info:
It does impose a more rigorous transaction pattern, as it does not give you automatic rollback:
Ensure transaction will succeed (with current state of system) - e.g. does it make sense now?
[transaction is added to queue], and stored (for power reset etc)
transaction is executed and applied to the object structure.
Writes of 1000's of transactions/sec
Reads of 100,000's transactions/sec
I haven't used it much, but it's sooo much nicer to use for small projects (persisting any serializable object is so nice)
Oh - as for every one saying "what platform you running on?", Prevayler (java) has/had ports to quite a few platforms, but I can't find a decent list :(. I remember that there were around 5-7, but can only remember .NET.
If you're planning on storing everything in memory while your program does work on it, then serializing to a file using a basic load() and save() function that you write would be fine, and less pain than a full on DB.
In Java that can be done using standard Serialization (or can serialize to and from XML to make it somewhat human readable and editable).
It shouldn't affect your memory footprint at all as it is merely saving and restoring your objects. You just won't get transactions and random access and queries and all that good stuff.
you could even use xml, json, an .ini file... a text file even
I would advise a SQL like database (such as SQLLite). Today your requirements might make a full SQL database seem silly. But you never know how much this "little project" will grow over the years. When it does grow to the point where you have to have a SQL engine, you will be glad you didn't just serialize some Java objects or store stuff in JSON format.

Resources