Converting PowerBrowse from Legacy to ABC

by Alan Telford

Published 2000-12-12    Printer-friendly version

Advertisement

The Clarion Reference Library

Programming Objects In Clarion

Programming Objects in Clarion is a special Clarion Magazine edition of Russ Eggen's widely-acclaimed book on object-oriented programming and ABC. 250 pages.

Buy Now!

Do you have an application that you would like to convert to ABC but haven't? Would you like some guidelines for when to convert and what to convert? Do you have existing legacy templates with no ABC equivalent e.g. PowerBrowse? All of the above? Well keep reading - this article highlights some of the problems in converting large applications over to ABC, gives some homegrown Laws of conversion, and then solves the legacy PowerBrowse problem.

But first, some history. I may not be an expert at conversion but I certainly do have experience. I first started programming 6.5 years ago. My first job was to write a conversion program to carry data over from a legacy program to the TopSpeed file format (six weeks). My second job was to convert the legacy program into Clarion for Dos 3.0 (one to two years)

My third job was to take the recently converted Clarion for Dos program and convert it (again!) into Clarion for Windows (I first started converting with CW1.5 but didn't actually release it until CW2003)

My current job is to maintain the existing application (now in C55rc2), while releasing add-on functionality every three to four months.

On my Todo list: Convert from Legacy to ABC; Convert from TopSpeed into SQL; Convert from procedural code to object-oriented code; Convert, convert, convert ...

I've wanted to convert to ABC for nearly 12-18 months now, but I haven't. Why not? The cost! Who's going to pay for it? The user doesn't pay for conversions - after all, a conversion should affect the internal structure and program organization (which the user doesn't see) while hopefully not affecting the windows and reports (which the user does see).

The next big problem is time, or lack of it. In my case the software package I've written is used by McDonald's Family Restaurants to manage their back office functions from payroll, inventory control, cash management and staff rostering through to basic accounting. It's rather large and consists of over 20 DLLs in main stream use, and another 10-20 utility DLLs or EXEs for occasional use. Like many multi-DLL applications there is one common DLL which contains all file declarations and global data. If I converted to ABC I would have to first convert the files DLL which would instantly stop all the other DLLs from working. So the conversion is all or nothing. And in my estimation it would take two to four months to convert my application. I don't have time to stop the clock and convert them all, while still releasing new functionality every three to four months.

If I do convert I will of course encounter the next problem. BUGS, BUGS, BUGS... A once stable application that has been tampered with will inevitably have some new bugs. Conversions are definitely risky, and the biggest risk is the users would see this as a backward step instead of a forwards step, and decide to take their business elsewhere. What is a programmer to do?

Enter my laws of conversion.

Law 1: Don't Convert

If you can get away without doing a conversion, then don't convert. Anytime you change the code, you decrease the stability of the code, and increase the possibility of bugs.

If it still works, and the user doesn't want it updated, then leave it alone. Converting costs time and money so don't do it.

Sometimes unfortunately, you can't leave the application alone:

  • Your last legacy programmer is about to leave, and there will be no one left to maintain the legacy application
  • You have a lot of changes to make or new features to add to an application, and you wish to write these using ABC
  • You've run out of work?
  • You have spare time on your hands?
  • You're starting to feel the pressure as SoftVelocity says that C55 is the last release that will support the Legacy templates.

In these cases then I advise ...

Law 2: Do The Bare Minimum

If you have to convert, then do as little as possible. The less you change, the less you will have to fix later. As I read my version notes, I find that some of my procedures haven't been changed in three to four years, and are unlikely to change in the next three to four years either. Guess what? The code in these procedures is working fine. It's running like clockwork.

Other procedures seem to need changing every few months, and you guessed it - that is where most of the bugs occur.

So do the smallest amount of change possible required to convert, and you will hopefully minimize the number of new bugs that you introduce.

But what if the bare minimum doesn't cut it? What if a particular browse requires some major new functionality? This is where the old 80-20 rule comes in. 80% of the time you can get by with the minimum. The other 20% of the time you have to apply the next law.

Law 3: Don't Convert - Rewrite

Laws 1 and 2 are designed to save you time which you can then spend on Law 3.

When I look at my original Clarion for Dos code I wrote when I was first learning, I want to curl up and die. Looking at code I wrote two years ago is not so serious but usually embarrassing. Even in code I wrote six months ago I can usually see room for improvement. I don't know about you but there's very little code I'm 100% satisfied with. If I have to convert some code, and converting involves risk, then I might as well use the opportunity to redesign and rewrite the code so I'll be happy with it (for at least another six months anyway).

This option is particularly good if you're adding new features which you can charge the customer for, because then they end up paying for the conversion.

The above three laws are fairly general, and should serve you well for many types of conversions. For the specific Legacy to ABC conversion Simon Brewer wrote some great articles in July and August about how to start. I very much enjoyed his articles, but was left wondering what to do about the dreaded ...

PowerBrowse

I recently read a newsgroup comment: "Free of PowerBrowse at last - Yeah". Nice for some I suppose. Why all this strong antipathy towards a third party template?

  • it's legacy,
  • it's been abandoned (no ongoing development),
  • it still has bugs (fortunately none that bother my users too much)
  • there's no ABC conversion program provided

With Law 2 in mind - do as little as possible - I set to thinking how I could convert the 162 PowerBrowse legacy procedures in my application into ABC format with as little work, and as much safety, as possible.

Wouldn't it be nice if there was an ABC PowerBrowse, with the same embed points? Then I could just export from legacy, tweak the TXA and import into ABC. But how do I do this? Enter the plan.

  1. Take a PowerBrowse procedure and copy the code into a SOURCE procedure.
  2. Compile the procedure to see what needs changing
  3. Make the changes
  4. Test to see if it works
  5. Study the templates to see how to automate the changes
  6. Modify the templates
  7. Test again

Armed with the plan, I started my PowerBrowse conversion.

1. Take a PowerBrowse procedure and copy the code into a SOURCE procedure.

First I created a basic PowerBrowse procedure with single sort order, locator, and inline entry but no embedded source.

Then I created an ABC app, using the same dictionary, and added a source procedure. Then, using cut and paste, I copied all the data declarations from my PowerBrowse into the data embed, and all the program code into the code embed.

My PowerBrowse now existed (without any templates) in an ABC app. This is a bit like the traditional one-way templates that other languages provide. Once my PowerBrowse is in source code I have to maintain it via source, and can't use the template power any more.

2. Compile the procedure to see what needs changing

Then I took the brave step and compiled: There were only 14 errors, which fell into four groups.

  • Opening and closing the file
  • Saving and restoring the window position
  • Standard error messages
  • Relational update/delete of file (for inline entry)

I began to feel hopeful - this could work?!

3. Make the changes

The next step was to solve each of the 14 errors by replacing the problem legacy code with new ABC code which did the same job.

Opening and closing of the file (five errors)

Legacy file opening code:

IF <FileName>::Used = 0
  CheckOpen(<FileName>,1)
END
BIND(M40:RECORD)
<FileName>::Used += 1

Legacy file closing code:

<FileName>::Used -= 1
IF <FileName>::Used = 0 THEN CLOSE(<FileName>).

This translates into the following ABC code:

Relate:<FileName>.Open
Relate:<FileName>.Close

After making the above changes to the source procedure the results were: five errors down, and nine to go.

Saving and restoring the window position (two errors)

Legacy code:

INIRestoreWindow('BrowseName','IniFile.ini')
INISaveWindow('BrowseName','IniFile.ini')

A quick look at a standard ABC browse reveals the code required:

INIMgr.Fetch('BrowseName',QuickWindow)
INIMgr.Update('BrowseName',QuickWindow)

Standard error messages (four errors)

Legacy code:

Button# = StandardWarning(Warn:UpdateError)
Button# = StandardWarning(Warn:SaveOnCancel)
Confirm# = StandardWarning(Warn:StandardDelete)
CASE StandardWarning(Warn:DeleteError)

A normal legacy browse wouldn't have these messages at all - in fact the job would already be finished. These occur because PowerBrowse has edit-in-place functionality just like the ABC browses do, except about a hundred times easier to use (well, that's a slight exaggeration)

ABC has a GlobalErrors class to handle these sort of error messages. By comparing the legacy error messages with those in "ABERROR.TRN" I came up with the following replacements:

Button# = GlobalErrors.Message(Msg:RetrySave,Button:Yes|
  +Button:No+Button:Cancel,Button:Cancel)
Button# = GlobalErrors.Message(Msg:SaveRecord,Button:Yes|
  +Button:No+Button:Cancel,Button:Cancel)

The Warn:StandardDelete and Warn:DeleteError are handled directly by calling the ABC relational delete method and didn't need replacements.

Keep in mind Law 2: I'm not trying to improve the PowerBrowse code at all, simply get it working under ABC as quickly as possible.

Relational update/delete of file (three errors)

Legacy code:

RISnap:<FileName>
Error# = RIUpdate:<FileName>()
IF RIDelete:<FileName>()

The first line is used by Legacy templates to setup for cascade updates. This is handled automatically by ABC templates therefore a replacement is not needed. The other two lines translate to:

Error# = Relate:<FileName>.Update()
IF Relate:<FileName>.delete(1) = LEVEL:Benign

The relational delete in ABC is a great improvement, because the one call handles prompting the user to confirm the delete, retrying the delete if unsuccessful, and informing the user of any failure. So one line in ABC replaced 19 lines in legacy. Hmmm - maybe this ABC isn't so bad after all.

After I made the above changes to the source procedure, the ABC application compiled successfully.

4. Test to see if it works

With much anticipation I ran the application and tested the functionality.

Browse worked fine. Locators worked fine. Inline entry worked fine.

YES! YES! YES! IT WORKED!

With two hours work (reading those ABC manuals) my PowerBrowse was in an ABC application, but stored in a SOURCE template. Remembering Law 2 (Do the bare minimum) this would be a good-enough solution for 80% of the PowerBrowse procedures I have. They don't need to be changed. But I like a bit more elegance so I also completed the following steps:

  1. Study the templates to see how to automate the changes
  2. Modify the templates
  3. Test again

Now I have a set of equivalent templates which allow PowerBrowse procedures to run under ABC as easily as under Legacy. Click the link at the end of the file to download an install program which installs both the Legacy and ABC PowerBrowse templates with libraries using C55 Gold.

My new ABC PowerBrowse still has a lot of legacy file handling code, but its all Clarion code which compiles and works. That's good enough for me.

Note: The original germ of this idea came to me as I looked at the UnivReport template from Larry Teames of CPCS reporting fame. When Larry upgraded from Legacy to ABC he used Law 2. He didn't rewrite the whole templates using an OOP class, but simply made his templates coexist with the ABC templates, and call ABC calls when needed. My first reaction when discovering this was "That's a bit cheeky!" I felt a bit cheated. Then I noticed one immediate benefit. There were no conversion problems with UnivReport procedures. Exactly the same embed points exist under ABC as under Legacy. There was no new OOP reporting system to learn - my legacy system worked fine under ABC. I figured if Larry could do it for his templates, then I could do it for PowerBrowse.

Some intrepid users might consider doing the same for the Clarion Legacy templates. Wouldn't that make an interesting proposition: an ABC compatible version of Legacy templates which allowed us to use our existing Legacy procedures inside new ABC applications. This might be pushing it, but it's certainly an interesting idea! I've wanted to use some of the new ABC file handing code in my legacy procedures for a long time. This would enable me to do it.

Editor's note: Both Larry and Alan's approaches are similar to the OOP design pattern known as "Adapter." This is a class that allows two classes with incompatible interfaces to communicate. The analogy isn't perfect since in this case templates are used and there is procedural legacy code on one side of the equation, but the principle is well-established in software design.

Back to PowerBrowse: how do I actually manage the conversion now?

Converting via TXA

Now that the ABC PowerBrowse template support is there it's a straightforward job to convert from Legacy to ABC.

  1. Use File|Selective Export to export all PowerBrowse procedures in an application to a TXA file.
    Note - just choose PowerBrowse procedures, no Forms or Windows or any other template types.
  2. Load the TXA into the editor.
  3. Do the following global search and replaces

Old

New

FROM ToolCraft PowerBrowse

FROM TCraftAbc PowerBrowse

NAME ToolCraft

NAME TCraftAbc

NAME Clarion CloseButton

NAME TCraftAbc CloseButton

Save the modified TXA

  1. Create a new ABC application using the same dictionary, or use an existing ABC application (as long as the same dictionary is used)
  2. Add the PowerBrowseLibrary global extension template to the ABC application.
  3. Import the modified TXA into your ABC application.
  4. Compile

Obviously I've simplified the process as this ignores any embedded code. If this code is incompatible with ABC then you will find out about it. The big difference is that now you don't have to worry about the template-generated PowerBrowse code.

Summary

Keep in mind my three laws of conversion:

Law 1: Don't (if you can get away without converting then don't convert)

Law 2: Do The Bare Minimum (minimize risk of new bugs by changing as little as possible)

Law 3: Don't Convert - Rewrite (if you need to make major changes then rewrite the procedure using your greater experience and insight you've gained over the previous few months).

I don't recommend that you create new ABC browses in PowerBrowse format. This is simply a method for carrying the existing PowerBrowses into ABC. There are still a few bugs in PowerBrowse and nobody is fixing them, so don't make the problem any bigger than it already is. Remember that this approach is just a great application of Law 2: Do the Bare Minimum.

Now you have the luxury of converting ABC PowerBrowses to ABC Browses as and when you need to.

Download the C5 templates

Download the C5.5 templates

For the most recent version see Alan Telford's home page at:

http://homepages.paradise.net.nz/alantelf/


Alan Telford has been programming in Clarion since 1994. He is the Chief Software Developer at Maxtel Software Ltd, a New Zealand software company specializing in writing back office computer solutions for McDonald's Family Restaurants and other similar markets.

Printer-friendly version

Reader Comments

To add a comment to this article you must log in.

 
 

Search

 

Advanced Search
Topical Index

Related Articles

Subscribe to
ClarionMag

One year: $189

(includes all back issues since '99)

Renewals from $139

Two years: $289

Renewals from $239

More Info

Subscribe Now!

ClarionMag Blog

RSS Feeds

Updates via Email

Enter your Email


Powered by FeedBlitz

Quick Links