Friday, March 28, 2008

ADD2QDIR

Think about where Internet Basic has been. New let's think about where it could go.
I remember when we all coded:

READ(1,000) KEY="" EXCP=FUGETABOUTIT
FUGETABOUTIT:

The FILE statement makes it much easier and cleaner to code:
FILE (0) POS=BOF. No meaningless EXCP or pointless statement label is necessary.

Getting to the beginning of the file is really a special case. The more general statement is:

READ(OrdDet,0000) KEY=Ornbr$ EXCP=FUGETABOUTIT
FUGETABOUTIT:

The Exception is meaningless because the Order Detail file is keyed by Order Number and Line Number and the READ can never (should never?) succeed.

The POSITION statement makes this construction unnecessary.

POSITION (OrdDet) KEY = Ornbr$

I never code an EXCP on a POSITION statement even though the documentation shows one. The documentation does not specify what conditions could trigger a exception; the only one I can think of is File Not Open and I would want that to cause a crash.

The CLEARFILE statement comes close to addressing the complications of:

ERASE "FILENAME" EXCP=NEXTLINE
NEXTLINE:
CREATE "FILENAME" .....
OPEN (1) "FILENAME"

Sadly the CLEARFILE statement has its own limitations. Recently we learned that CLEARFILE, which does not include an EXCP argument, is oblivious to file contention. If the file being cleared is open by another user, Comet will chop that user off and clear the file. Signature recommends LOCKing the file before clearing it.

Recently I found myself doing a lot of work with files imported into Comet from Windows applications. Internet Basic has a way to add a file to a Comet QDIR from inside an application program, but the method is awkward and results in spaghetti code.


OPEN (1) "FOREIGN" EXCP=OPNERR
. process data here
..
..
OPNERR: !Open fails on file being imported
CREATE "FOREIGN",T,DIR="XXX",EXCP=CRERR
CRERR: !Create error
If EXCP=13 !Ah ha, the file exists
Goto ... !Now it's in the QDIR
Endif

You might be tempted, I was, to code an AGAIN statement to get back to the OPEN. After all that's where all the stuff started. That wont work because it was the CREATE that trip the Exception that triggered the pseudo-create. Sadly you need a label that is almost as useless as the statement labels we used to code for POSITIONs and still do for ERASE/CREATE pairs.

I want an ADD2QDIR that needs no EXCP. Then I can OPEN foreign files without jumping all over the place.





Friday, March 21, 2008

Data base design

I'm working with a system I did not create. Now I have the reputation of being excessively critical of OPC (other people's code) so please bear with my tirade - you may find a grain of truth in this rant despite my nasty and critical nature. In this system there is an Order Header file called O1A, and Order Detail file called O1 and an Item/Warehouse file called I1B. No surprise there. Now here's where I get all bent out of shape. All three of these files have a field called Warehouse and all three use the same variable - the same name.

I guess I should be used to that approach. The Qantel/Comet file scheme, which is really different from the COBOL file organization scheme, lends itself to defining the same variable in more than one file.

In COBOL the data record is read into a memory block in the application program space. That space is mapped to variables: the first 6 bytes are the customer account number, the next 30 are the name, and so forth. In Comet the record is read into some invisible space in the OpSYS and then the variables are parsed into named variables.

The COBOL scheme makes it IMPOSSIBLE to use the same variable name in more than one record. It is simply not possible as the name points to a specific memory block. The same logic applies in Access, SQL, Oracle and, I expect, in all other databases.

The Qantel/Comet format scheme is a result of the small memory design of the 1970's and 1980's. Consider how much memory this approach saves. If you have the "same" data in more than one file, think Order Number, you need only one variable and you save all the assignment statements that would be required to set the Order Number in the many files where it exists.
But in the forty years since the Q machine came on the scene, memory has gotten so cheap that it is almost free. And there are problems with the common variable approach.

The Comet scheme results in hidden assignment statements; reading and writing records that are defined with the same variables causes these fields to be filled "behind the curtain." I hate this because I can't tell which program updates a variable and all the Seeks and Searches don't help. Magic assignment statements behind the curtain can be so frustrating.

And then there is the file integrity issue. I so clearly remember the time a program I wrote read an O1A record keyed by Order Number + "B" into the format that was defined as:
1511 Format ___
ORNBR$;__
"A";_

I LOST THE LITERAL "A". Comparisons to the constant, the literal, "A" failed. It took me a very long time to realize that I had clobbered the location containing the literal A with a B.

Since then I have seen data corruption problems migrate through a system changing order numbers almost at random. One corrupt record, with the wrong data in the Order Number field, can destroy a database in the most amazing way. And the best way to start this is to write a record with the wrong format. That'll do you really nicely.

I have more I want to say about database design and variable naming, but it will have to wait for another time.

Labels:

Friday, March 7, 2008

Naming Variables

OK, tell me again why you are restricting variable names to eight characters. You've always done it that way. #FILES limits you to eight bytes. Long names are too hard to type correctly.

#CFILES, which is where you should be now, does not limit the IB name to eight bytes. You may wonder what the limit is. I know I did so I checked the documentation: http://www.signature.net/dbmanager.html. Of course I did not find out because there is no reference to the maximum length of the IB name, but it is surely longer than eight bytes.

And UltraEdit will help with entering those long variable names. The magic is the less than well documented AutoComplete feature in UE. You invoke it with Ctrl+Space. The full explanation can be found in the UE help by searching for Auto Completion. I found it by searching for Ctrl+Space. It's great but it's not perfect. Of course, UE does not look in USEFILEs or INCLUDE files. That's a bummer. And UE only looks back. In other words, if the first reference to a variable is below your current location in the file, the Auto Completion feature does not work. Now I'm still on version 10 but the promotional material on the UltraEdit site reads just like the current HELP text - UE looks backward through 50K for auto completion help.

UltraEdit has another quirk that you need to know. The program sees periods as an end-of-word marker. So, if you have a long variable name like MAX.STRING.LEN UltraEdit will not help you. Try it yourself. Start UE. Load up FILEFIND.INC from WDL. Type MAX and press CTRL+SPACE. Bummer.

So here's my rant. Use longer and more descriptive variable names. Don't punctuate the names with periods. Learn to use UltraEdit's not-so-fabulous Auto Completion. You'll be glad you did.