This is HELP.TXT, the help file for CONVERT vers. 1.4 (C) 1988 Rodger L. Ellis. All rights reserved. Note 1: Text surrounded by braces ("{" and "}") is highlighted text. Note 2: Lines beginning with "|" are used only by the public (demo) version of CONVERT. Such lines are not presented when help is called for in the proprietary (full-featured) version. :WELCOME TO CONVERT Greetings from {Rodger L. Ellis}, the author of CONVERT.... | This is the public version of CONVERT. It offers all features of the | proprietary version of CONVERT with one limitation: record size is | limited to 64 bytes (the proprietary version can handle record sizes | up to 16k bytes -- see Section 13, below, for info on how to obtain | the proprietary version of CONVERT). This public version of CONVERT | may be freely distributed. | This text contains the following subjects: 1. Disclaimer 2. General Description 3. Background 4. What CONVERT Can Do 5. What CONVERT Cannot Do 6. Operation 7. The LOAD and SAVE Functions 8. The DIRECTORY Command 9. Automatic Operation 10. Reindexing Index Files 11. Sourcecode Availability 12. Feedback to the Author | 13. Obtaining the Proprietary Version of CONVERT {1. Disclaimer} The author makes no warranties as to the content of the CONVERT program and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. By your use of this program, you agree to hold the author harmless for any losses due to the use of the CONVERT program or its documentation. {2. General Description} CONVERT is a utility which converts Borland's TAccess data files from one format to another. TAccess files are files that have been created using Borland's Turbo Pascal Database Toolbox. CONVERT can convert TAccess version 1.xx files into TAccess version 4.xx files and vice versa. CONVERT can also convert a TAccess data file to a new TAccess data file of a different structure, with automatic conversion of data type when the source and destination records contain like field names but different data structures. {3. Background} Over the past several years, we have created a multitude of specialized database programs for clients using various versions of Borland's data- base toolboxes. As those programs evolved, new data structures were required. We spent a considerable amount of time writing custom utilities that would convert the clients' old data files into formats required by the new software. Now, with the advent of Turbo Pascal 4.0, we find that even more conversions are needed. Gimme a break! Wouldn't it be easier to write a general-purpose program that could handle all file conversions? Well, it wasn't necessarily easier, but we did it. It's called CONVERT. {4. What CONVERT Can Do} The best way to illustrate what CONVERT can do is to provide a few examples. Here goes.... Example 1: You have upgraded a client's program from TAccess 1.xx to TAccess 4.xx, and now the client's data files need to be converted. Run CONVERT to upgrade the client's data files. Example 2: Your client has requested that you increase the length of the ZIPcode field from 5 to 9 characters. Changing the software is no problem, but how do you convert the client's existing data file? Simple -- just run CONVERT. Example 3: The program you created for a client involves a data file that contains a string variable that actually represents a number. You thought that keeping this value as a string in the database would be the best way to handle things. Now, as you see that your program enhancements rely heavily upon that variable, you wish it had been defined as a real rather than a string. Changing the software is no problem, but what about the client's existing data file? Simple -- just run CONVERT and redefine the data type. Example 4: Your client has weeded his garden and now has zillions of unused records in his datafile. He was hoping to free up a couple megabytes on his hard disk in the process, but was surprised when the size of his datafile remained unchanged. You explain how record deletions work in TAccess. Then you break out the secret weapon -- CONVERT -- and perform a "conversion" with identical source and destination record definitions. Since CONVERT ignores deleted records, the resulting destination file will be nice and compact. {5. What CONVERT Cannot Do} CONVERT cannot convert index files. No biggie, though, because if you have done a thorough job in creating your TAccess application, the program will be able to create its own index files from the new data file. Read more on the subject of indexing in Section 10. {6. Operation} The basic operation of CONVERT is a 6-step process: 1. Press F3 and enter the source filename and database version. 2. Press F4 and enter the destination filename and database version. 3. Press F5 and enter the source file's record details. 4. Press F6 and enter the destination file's record details. 5. Hit ESC to return to the main menu. 6. Select "Convert" to perform the conversion. {7. The LOAD and SAVE Functions} Once the source and destination records have been defined, the definitions can be saved to a .CNV file by using the SAVE command. The definitions can be retrieved later by using the LOAD command. When the LOAD command is invoked, the program will display a pick list of all .CNV files. If you pick one of the files in the list, the program will load the source and destination files' details. {8. The DIRECTORY Command} The Directory command provides a scrollable directory display of the specified path. It has no particular significance to CONVERT per se, but simply provides a way to view directories without having to return to DOS. {9. Automatic Operation} CONVERT performs automatically when a .CNV file is specified as a parameter in the invoking DOS command line. For example, if you enter CONVERT FOOBAR at the C> prompt, CONVERT will automatically load FOOBAR.CNV, perform the file conversion, and exit back to DOS. Of course, in order for this to work, you must have already created the file FOOBAR.CNV by the SAVE command, and the source file specified in FOOBAR.CNV must be present in the current subdirectory. The value in having this automatic capability isn't so much for your own convenience but that of your clients who use your database applications. When the need arises to modify the structure of their database, you can prepare an update disk which not only contains the latest version of the application, but which also contains the mechanism to move their existing data into the new structure. Let's look at an example. Suppose you have created a simple TAccess database program for a client. The data file record contains a string[5] field called ZIP. After several months of operation, the client tells you that he needs the ZIP field expanded to handle 9-digit ZIP codes. You know that modifying the sourcecode is a very minor issue -- one that you can handle in a matter of a few minutes. You also know that those 2000 records the client has already keyed in represent a considerable expenditure of time on his part, and he doesn't EVEN want to hear that he has to key all his data in AGAIN. He doesn't need to, of course, because you have CONVERT. You create an update disk and send it to the client. He mounts the disk in the A: drive and runs UPDATE.BAT (or some such). When the smoke clears, he has your new program version on his hard disk and his data file is in the new format. UPDATE.BAT might look like this: COPY NEWPROG.EXE C:\DATABASE (copy your new program version to the applicable subdirectory on his hard disk) C: (go to drive C:) CD \DATABASE (go to the correct subdirectory) REN DATAFILE.DAT DATAFILE.OLD (rename his old data file to match the source filename you specified in FOOBAR.CNV; you had already specified DATAFILE.DAT as the destination filename in FOOBAR.CNV); A:CONVERT A:FOOBAR (perform the conversion) DEL DATAFILE.NDX (delete existing index file(s) -- see below for the rationale behind this) In actual practice, you would probably want to provide some backup entries in the UPDATE.BAT file to preserve existing conditions. {10. Reindexing Index Files} As I indicated previously, CONVERT is not designed to provide any index file conversions. There is really no need to do so, since any TAccess application worth its salt would have a reindex, or "repair" capability. Building a procedure to reindex a datafile is not difficult; an example is given in each of Borland's Database Toolbox manuals. While reindexing is no big deal, a potential problem exists. If you create TAccess database applications according to Borland's examples, your application will open the appropriate data file upon startup and, finding it, will open the appropriate index files. If the index files are in place, normal operation would ensue. However, you can't keep the old index files after you alter the data file because then everything would be out of sync. On the other hand, if you delete the old index files, your application will create all new files -- overwriting the new data file you just created with CONVERT! The solution is to provide for future changes in the data file structure up front by writing your initialization code to look for the data file and, having done that, look for the index files. If the data file is present but the index files are not, then create new index files using your reindex procedures. Compare the following examples: Original sourcecode (no conversion flexibility): OpenFile(DataF,'DATA.DAT',100); if OK then OpenIndex(DataX,'DATA.NDX',10,0); if not OK then MakeFile(DataF,'DATA.DAT',100); MakeIndex(DataX,'DATA.NDX',10,0); end; Recommended sourcecode (full conversion flexibility): OpenFile(DataF,'DATA.DAT',100); if OK then begin OpenIndex(DataX,'DATA.NDX',10,0); if not OK then Reindex(DataF); {Reindex should set OK=true if the} end; {..reindexing was successful} if not OK then begin MakeFile(DataF,'DATA.DAT',100); MakeIndex(DataX,'DATA.NDX',10,0); end; The second example will let you replace an old data file with one of a new structure using CONVERT, delete the existing index files, and automatically rebuild the index files the next time the application is run. {11. Sourcecode Availability} Sourcecode for CONVERT is available for $99. You will receive a 360k disk containing ALL sourcecode for ALL units, functions and procedures used in CONVERT, including {highlighted menu selection system} {scrolling directory} {scrolling PICK file selection system} {scrolling HELP system} {data type conversion schemes} {window management} When you purchase the sourcecode, you may freely extract any portions to include in your own programs. While you may sell or give away such programs without payment of royalty, no portion of the sourcecode itself may be sold, uploaded to BBS's, or otherwise given to another party without the express written authorization of Rodger L. Ellis. To order, send a check or money order to Rodger L. Ellis 740 W. 71st Avenue Anchorage, AK 99518 Please indicate that you wish to receive "CONVERT Sourcecode". Phone orders are welcome. Call (907) 349-6882. VISA/MC accepted. {12. Feedback to the Author} The author would appreciate feedback on this program. Send comments to: Author: Rodger L. Ellis CIS address: 75216,3223 GEnie address: CT Mail address: 740 W. 71st Avenue, Anchorage, AK 99518 USA Voice Phone: (907) 349-6882 Modem Phone: (907) 349-7996 | | {13. Obtaining the Proprietary Version of CONVERT} | | The proprietary version of CONVERT is available for $49 postpaid. The | product performs the same functions as the public version, except that | the maximum record size is 16384 bytes rather than 64 bytes. If you | think about how much time you would spend writing a conversion utility | co cope with database changes, you could probably justify the expense | in just one program rewrite. Use CONVERT twice, and you're money | ahead! | | To order, send a check or money order to | | Rodger L. Ellis | 740 W. 71st Avenue | Anchorage, AK 99518 | | Please indicate that you wish to receive "CONVERT". | Phone orders are welcome. Call (907) 349-6882. VISA/MC accepted. (end) :SOURCE FILE The {source file} is the file that you wish to convert. It must be a Turbo Access data file that was created with Borland's Database Toolbox version 1.xx or 4.xx, and it must contain at least one data record (in addition to the header record). First, enter the filename of the source file. Next, select the version by either tapping the spacebar or by entering the number 1 or 4. Exit the SOURCE FILE window to the Main Menu by pressing ESC, or go directly to another window by pressing the F4, F5 or F6 function key. (end) :DESTINATION FILE The {destination file} is the new file that will be created when you perform the conversion. It will be a Turbo Access data file suitable for use with Borland's Database Toolbox version 1.xx or 4.xx, depending upon which version you have specified in the DESTINATION FILE window. First, enter the filename of the destination file. The filename must be different than the source file's filename, since both files will be open simultaneously. Next, select the version by either tapping the spacebar or by entering the number 1 or 4. Exit the DESTINATION FILE window to the Main Menu by pressing ESC, or go directly to another window by pressing the F3, F5 or F6 function key. (end) :DATA RECORDS The DATA RECORD windows are used to define the names and data types of the variables that make up the data record of the source and destination files. This text contains the following subjects: 1. Editing 2. Variable Names 3. Data Type 4. Conversion Between Different Data Types {1. Editing} Use ^N (Ctrl-N) and ^Y (Ctrl-Y) in WordStar fashion to insert and delete lines in the source data record list. {2. Variable Names} A variable name is simply a label of up to 20 characters. It cannot contain spaces, and case is not significant. While it promotes clarity to use the same variable names that were used in defining the database record in the original sourcecode, there is no requirement to do so as far as the CONVERT program is concerned. The significance of the variable name is that it is used by CONVERT to check for like variable names in the source and destination data records. If a match is found, data is converted according to the conversion rules specified below. If no match is found, that part of the source data record is ignored. {3. Data Type} Each variable must be assigned a data type. You select the data type by tapping the spacebar until you see the one you want. The following data types are possible: boolean byte char integer longint real shortint string[] word ChrArr[] Rec[] All are standard Turbo Pascal data types except ChrArr[] and Rec[]. The {ChrArr[]} data type is a character array of 1 to 256 elements. It is used by some programmers in place of the string type because it provides the same information while consuming one less byte in the data record. Compare the hex representations of string[10] with ChrArr[10]: string[10] (11 bytes): 0A 54 45 53 54 00 00 00 00 00 00 .TEST...... ChrArr[10] (10 bytes): 54 45 53 54 20 20 20 20 20 20 TEST Note that the ChrArr is padded with the space character. A {Rec[]} is a blanket definition of a given number of bytes, the contents of which are unimportant to the CONVERT program. It is used to cover situations where you have a record defined within the database record, as in the following example: ========================================================================= Sourcecode Data Record CONVERT Source Data Record --------------------------------- ----------------------------- record Status longint Status : longint; LName string[20 ] LName : string[20]; FName string[12 ] FName : string[12]; Dollars Rec[16 ] Dollars : record Current : longint; Days30 : longint; Days60 : longint; Days90 : longint; end; end; ========================================================================= The next example of Rec[] usage shows how to handle data records that contain arrays: ========================================================================= Sourcecode Data Record CONVERT Source Data Record --------------------------------------- ----------------------------- record Status longint Status : longint; LName string[20 ] LName : string[20]; FName string[12 ] FName : string[12]; Remarks Rec[810 ] Remarks : array[1..10] of string[80]; end; ========================================================================= Finally, this example shows how the Rec[] data type can be used just for convenience: ========================================================================= Sourcecode Data Record CONVERT Source Data Record --------------------------------------- ----------------------------- record Status integer Status : integer; Misc Rec[99 ] LName : string[20]; FName : string[12]; Addr : string[30]; City : string[20]; State : string[2]; ZIP : string[9]; end; ========================================================================= We might use the above example to perform a straightforward data file conversion from TAccess vers. 1.xx format to 4.xx format. In that case, the only variable we need to individually define is Status because Status will be redefined as a longint in the destination data record. Then, when we perform the conversion process, the content of the Status field will be rewritten as a longint and the remainder of the source data record will be written as an intact block of 99 bytes. To accomplish this, the source and destination data records would be defined as follows: ========================================================================= Source Data Record Destination Data Record ---------------------------- ----------------------------- Status integer Status longint Misc Rec[99 ] Misc Rec[99 ] ========================================================================= {4. Conversion Between Different Data Types} One of the most powerful features of CONVERT is its ability to provide automatic conversion between different data types. The most common use of this feature is in converting TAccess version 1.xx data files to version 4.xx format, as was the case in the previous example. There, the integer Status field in the source file was converted to a longint Status field in the destination file. Conversion between different data types is {automatic} when the source and destination data record definitions contain the {same variable name} but {different data types}. Just about every conceivable data conversion can be accomplished. The following chart shows what happens when you define different data types for like variable names in the source and destination data records. Note that the special data type Rec[] is a straightforward, 1-for-1 conversion and cannot be used to convert from or to other data types. Conversions marked with a {*} are not feasible; they always produce a zero result. ========================================================================= SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- boolean byte 0 if false, 1 if true boolean char 'F' if false, 'T' if true boolean ChrArr 'FALSE' if false, 'TRUE' if true boolean integer 0 if false, 1 if true boolean longint 0 if false, 1 if true boolean real * always 0.0 boolean shortint 0 if false, 1 if true boolean string 'FALSE' if false, 'TRUE' if true boolean word 0 if false, 1 if true SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- byte boolean false if byte=0, otherwise true byte char Chr(byte) byte ChrArr value converted to numeric characters if room byte integer value converted to integer format byte longint value converted to longint format byte real value converted to real format byte shortint value converted to shortint format; if byte is > 127, the shortint is 127 byte string value converted to numeric string if room byte word value converted to word format SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- char boolean false if char in ['0','F','f'], otherwise true char byte Ord(char) char ChrArr first element contains char, padded w/ spaces char integer lo byte contains Ord(char), hi byte = 0 char longint first byte contains Ord(char), others = 0 char real * always 0.0 char shortint Ord(char) if char <= 127, otherwise 0 char string string of length 1 containing char char word lo byte contains Ord(char), hi byte = 0 SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- integer boolean false if integer = 0, otherwise true integer byte value converted to byte format; if integer is < 0, the byte is 0; if integer is > 255, the byte is 255 integer char * always a NUL character integer ChrArr value converted to numeric characters if room integer longint value converted to longint format integer real value converted to real format integer shortint value converted to shortint format; if integer is < -128, the shortint is -128; if integer is > 127, the shortint is 127 integer string value converted to numeric string if room integer word value converted to word format; if integer is < 0, word is 0 SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- longint boolean false if longint = 0, otherwise true longint byte value converted to byte format; if longint < 0, the byte is 0; if longint > 255, the byte is 255 longint char * always a NUL character longint ChrArr value converted to numeric characters if room longint integer value converted to integer format; if longint is < -32768, the integer is -32768; if longint is > 32767, the integer is 32767 longint real value converted to real format longint shortint value converted to shortint format; if longint is < -128, the shortint is -128; if longint is > 127, the shortint is 127 longint string value converted to numeric string if room longint word value converted to word format; if longint is < 0, the word is 0; if longint is > 65535, the word is 65535 SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- real boolean false if real = 0.0, otherwise true real byte value converted to real format real char * always a NUL character real ChrArr value converted to numeric characters if room real integer value rounded to an integer; if real is < -32768.0, the integer is -32768; if real is > 32767, the integer is 32767 real longint value rounded to a longint; if real is < -2147483647.0, the longint is -2147483647; if real is > 2147483647, the longint is 2147483647 real shortint value rounded to a shortint; if real is < -128, the shortint is -128; if real is > 127, the shortint is 127 real string value converted to scientific notation if room real word value rounded to a word; if real is < 0, the word is 0; if real is > 65535, the word is 65535 SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- shortint boolean false if shortint = 0, otherwise true shortint byte value converted to byte format; if shortint < 0, the byte is 0 shortint char * always a NUL character shortint ChrArr value converted to numeric characters if room shortint integer value converted to integer format shortint longint value converted to longint format shortint real value converted to real format shortint string value converted to numeric string if room shortint word value converted to word format; if shortint is < 0, the word is 0 SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- string boolean true if string = 'TRUE', otherwise false string byte if string is between '0' and '255', byte takes on string's value; otherwise 0 string char char = first character in string; if string length is 0, char is NUL character string ChrArr a character array, truncated or padded with spaces as necessary string integer if string is a numeric between '-32768' and '32767', integer takes on string's value; otherwise 0 string longint if string is a numeric between '-2147483647' and '2147483647', longint takes on string's value; otherwise 0 string real if a numeric string, real takes on value; otherwise 0.0 string shortint if string is a numeric between '-128' and '127', shortint takes on string's value; otherwise 0 string word if string is between '0' and '65535', word takes on string's value; otherwise 0 SOURCE DESTINATION RESULTANT ENTRY IN THE DESTINATION DATA FILE --------- ----------- ---------------------------------------------- word boolean false if word = 0, otherwise true word byte value converted to byte format; if word > 255 then byte = 255 word char * always a NUL character word ChrArr value converted to numeric characters if room word integer value converted to integer format; if word > 32767 then integer = 32767 word longint value converted to longint format word real value converted to real format word shortint value converted to shortint format; if word > 127 then shortint = 127 word string value converted to numeric string if room (end)