Re: Using LIKE to define records in 4GL
Posted in 1995
John, Thanks for pointing out that this discussion has been aired in the [recent] past. I only gained access to the list again aftera 3 year sabatical [couldn't get at it from the previous company]. I should have clarified my statements when I posted them. It was partly a frustration mail caused by the fact that I am forever running into situations where they *don't* do what you said [re main], and include a GLOBALS in it! Thanks for reminding me that a 'DATABASE EFFECT' is only applicable to the source file containing MAIN. I have not tested it, but perhaps you can confirm the following: If you include a globals file in a non-main module where the globals file has a NON-PROCEDURAL database statement, do you suffer from the same problems you get if its included in main or not? Personally I recommend coding programs in a similar manner to the way you describe. I solve the problem of batch vs form based apps by making main a stub function in the way you describe.All applications write log messages to an error log and [optionally] to the display as well. The standard_options function sets a flag to indicate that the program is non interactive inter_active = FALSE. This prevents errors being displayed by the common error handler display_err. The fatal_err function is used as standard in all WHENEVER ERROR handling, and this function calls display_err. display_err checks the inter_active flag and only displays an error to the screen if it is set. As a standard, the common open_mainwindow function must be called BEFORE any screen i/o is performed. This function sets inter_active to true, This function opens a window using the open_window function which sets up a standard window and other variables that hold information about the screen size. This is used by the error and message handlers in determining where to display menus, messages and errors. The main point I was trying to make here is that this mechanism has solved the problem (for me) of having a common main and difficulties with error/display handling. Because all windows and i/o are handled using library functions which check to see if the program is an interactive or batch program, the appropriate actions can be taken to handle either situation more or less transparently from the programmers point of view. If you are interested in the sources for these functions (with some bugs still to be found no doubt), I will be happy to send you a copy. They are all in one source file (I am presently in the process of changing this). Mark Denham BBC London, UK Mark.Denham@bbc.co.uk ---------- From: johnl To: Mark.Denham; informix-list Subject: Re: Using LIKE to define records in 4GL Date: 28 July 1995 12:49 This subject was discussed extensively at the end of January 1995 (starting on the 24th or 25th according to my records). Maybe you should go and read the archive records of that discussion. Cathy Kipp has summarised the conclusions of that adequately in a recent posting. I'm going to pick up on a common misconception which is tangential to the rest of the discussion. Again, this has been dealt with previously, but it bears reiteration. >From: Mark Denham <Mark.Denham@bbc.co.uk> >Date: Fri, 28 Jul 95 10:31:00 PDT >X-Informix-List-Id: <list.7064> > >I feel like an argument. Has anyone got any views on the use of LIKE to >define RECORDS in 4GL, or any limitations on how you use it based on >personal experience? > >To start the ball rolling I hate it and where I can insist that it is not >used. I particularly dislike its use in GLOBALS files! > >Here are my reasons: > >1) When used in the globals file, it results in the runtime app opening > the db and attempting to locate the tables of interest. In an > environment where you have multiple copies of the db, not necessarily > with the same name, this method forces you to have to recompile the > programs for each db, or to have a dummy db that is used to compile and > is left in existance in each db enviroment. If your programs need to run in a multi-database environment, you have to write them more carefully than you do in a single-database environment. Mark's observation about the database being present at run-time is only correct if the MAIN program is compiled with a non-procedural DATABASE statement in the source file. The program does not check at run-time whether the tables which were referenced at compile-time are present or have the same type. It simply executes the statements on the assumption that they are present, relying on the Engine to complain if they aren't, or if the structure has changed too much. If you are designing your code to work with different databases selected at run-time, your archetypal MAIN program should look like: -- No GLOBALS here, and no DATABASE statement here either! MAIN DEFER INTERRUPT DEFER QUIT -- Or maybe not CALL standard_options() CALL main_program() END MAIN DEFER statements are only allowed in MAIN, which is why they are present. Because this code has no DATABASE statement in it, no database is selected automatically. The function standard_options() is responsible for a number of startup operations, one of which is selecting the run-time database. It can also be used to set standard options, such as the various function keys (hence it's name), and it can start the error log, and it can do security checking and anything else that is necessary. The operational code for the application is in the function main_program() which is written in a separate file. You might or might not want to add a CLEAR SCREEN and an EXIT PROGRAM 0 after the call to main_program(). This technique means that you can have test and production versions of the database, possibly with the same name in different OnLine systems, or with different names in the same OnLine system. You can have a separate database for each company in a group run by a holding company, etc. If I was doing production coding and in charge of standards, this structure would be be used in all my projects. Indeed, the code for MAIN might even be in a library, and no programmer would ever write a MAIN program; they would use the library version. In practice, it isn't quite that simple since there are interactive programs which have a screen attached, and batch programs (typically run by cron) which don't necessarily have a screen attached, and you may need different startup sequences for the two, but the general idea is definitely valid. I have used standard options functions extensively, but I've never gone as far as enforcing the startup sequence by insisting that MAIN is dragged out of a library. Going back to the original question; for the source code in the files which do not contain MAIN, you will need to have a database around when the code is compiled in order to pick up the correct types of the fields you have defined LIKE particular columns (this is good because it means that if the column changes type, your code changes type too -- see Cathy's comments). The compile time database ne