Wednesday, 9 January 2013

Migration from Delphi 6 to Delphi XE3

Welcome back! It's been 2 and a half years since I last posted on this blog. Although it is partly down to the usual "too much work" and "kids keep me busy", it's largely because even after all this time, I'm still on Delphi 6(!), and so had nothing new to report. That's right, we never managed to find the time to migrate to Delphi 2009.

Not for much longer though. We've taken the decision that in March/April this year, myself and the development team are going to take the plunge, and finally upgrade from Delphi 6. Not to Delphi 2009 as I originally wrote about though. This time, we're going straight to the very latest version, Delphi XE3.

This has come about not only because our hand has been forced by some of the third-party components we use (TMS Component Pack, ReportBuilder, Raize Components) - none of the new versions of these support Delphi 6 - but also because we're starting to think about mobile development. Delphi XE3 offers decent distributed database architecture with DataSnap which we can make use of to write some terrific companion mobile apps for our software.

It is somewhat of a relief to see that dbGo (ADO) is still well supported with Delphi XE3, vindicating the decision I made a few years ago to switch over to that from ODBCExpress. This will form the largest part of our migration process, as we have to move all existing components over to the dbGo equivalent. However, we have established how to do this without any real complications, and so it will just be more time-consuming than difficult.

Of course, there will still be the Unicode effect that came when Delphi 2009 was released, "breaking" existing code. But this has been well documented by Delphi luminaries such as +Bob Swart, +Marco Cantù and +Cary Jensen, and so this will present no real issues.

The superb ReportBuilder Enterprise by Digital Metaphors stores the database connectivity information within the report file itself, so I have already written a utility that replaces the ODBCExpress details with that of ADO. This will instantly convert our 250 standard reports, as well as the countless reports written using the built-in report writer by users for themselves.

The largest task at hand is converting our "plug-ins". When I first joined the company over 14 years ago, my task was to rewrite the software to convert it from Unix to Windows. There were multiple versions of the software for each customer, based on their bespoke requirements. I vowed this would not be allowed to happen to the Windows version of the software, and so developed the plug-in architecture which allows bespoke functionality to appear within the core software, as if it were standard. To this day it works perfectly, however its success has grown much larger than I ever anticipated, meaning there are now over 100 plug-ins for various customers and other "extra" features that we can provide. Each of these is a separate Delphi project, and so this will be enormously time consuming to migrate these.

But it will be worth it. We will finally be on a development platform that can provide us with "modern" features, whilst giving us opportunities to develop in other areas as well.

I'll keep posting as I come across any interesting areas during the move! I'd love to hear from you if you have done anything similar and have any "gotchas" you'd like to share.

5 comments:

OckZoNoz said...

I just went through something similar: converting a 15 year old program from D2007 to DXE3 (my only target is Win32).

Upgrading ReportBuilder, TMS Pack+Diagram+Chart, and IBObjects was straight forward.

All in all it mostly was time consuming rather than difficult. Took me about a week for 350k lines.

Regarding Unicode: If a string contains binary data it's useful to declare it as RawByteString -- that way you'll get nice compiler warnings if you try to treat it as a normal string.

I had a few places where I managed such strings in a TStringList. I changed those to either use TList or -- where I relied on a key=binary_value pattern inside the string list -- applied a simple hack of converting from RawByteString to hex encoded string, then stored the hex string in a TStringList.

The second most common change for me was to change stuff like "if (ch in setOfChar) then" to "if CharInSet(ch, setOfChar) then".

I have gotten rid of most compiler warnings and now almost everything is working again -- I broke some stuff during refactoring but that has nothing to do with upgrading Delphi and the component libraries.

Good luck with your upgrade!

OckZoNoz said...

The comments section doesn't like generics :)

*changed those to either use "generic TList with type parameter RawByteString"

GreatDayDan said...

I will be interested in seeing how you get this done. I have just started a contract, working on upgrading from Delphi 5 to Delphi XE3. :)

Unknown said...

@Unknown, thanks for the excellent tips, really appreciate it. @GreatDayDan, will keep you posted!

alcalde said...

It's been 14 years. Was there any reevaluation of development technology to ascertain whether Delphi is still the best choice for the project?