ZOJ Problem Set - 1724
You are a top-secret, government-employed software engineer assigned to TOP-DOG, the latest military intelligence program. TOP-DOG handles everything from mapping out enemy territory and position to parsing highly encrypted messages from the Commander in Chief.
The operator of TOP-DOG needs to be able to transfer information from remote computer work-stations onto diskette in case of hardware problems or well-placed enemy fire. All TOP-DOG information is stored in the Oracattle database, but the only way to access the database is through the Dispatcher, an infamous and powerful software layer that only allows access to the database on a "need-to-know" basis. You are in charge of writing a piece of software which will get the desired information from the Oracattle database and store it on a "flat" file which will later be sent out to disk.
The first part of each case contains the desired tables to be exported. This part will simply contain the names of each table to be exported on separate lines. There will be no blank lines, and each table name will be unique.
For each table, you must search the second part which will contain all column names, types, and sizes (if VARCHAR) for each table in the Oracattle database. This is the only information which the Dispatcher allows you access to without begging.
Note that, for security reasons, not every table in the first part will always be available in the second part. Under each table name is the column name (one unique word), data type, and size (for VARCHAR), each separated by one space. The # sign indicates there are no more columns for the table. There will never be consecutive # signs immediately following each other, and each table will contain at least one column name with the size. The only four data types are VARCHAR, INT, DATE, and LONGINT.
An Oracattle SQL statement must be built in order to query the Dispatcher for the desired table data. The Oracattle SQL statement must be precisely built in order to keep the Dispatcher happy (we wouldn't want the Dispatcher to be confused). The statement begins with "SELECT", followed by each column name and generic data type in parenthesis, separated with commas, terminated with "FROM", the table name, and a semicolon. The generic data type is CHAR for VARCHAR and DATE, and NUM for INT and LONGINT. The generic name must be used because the Dispatcher only understands data as CHAR or NUM (it may be powerful, but it's not extremely intelligent). These SELECT statements must be put into the first part of the output.
If a table name cannot be found in the second part, a "<TABLE NOT FOUND>" statement must be substituted for the SELECT statement in the first part of the output. No blank lines are to be in this file, and only single spaces are to separate SELECT, column names, FROM, and the table name in the SELECT statements. The entire SELECT statement must be on one line.
Since you currently do not have access to the Dispatcher, we will assume that you have correctly built the first part of the output and that the Dispatcher has processed it and created the table information in the third part. This file contains the table name followed by the data from each row in the Oracattle Database table. "<NULL>" is returned for rows with empty fields.
Note that each line in the third part may contain any number of spaces between words unless it was declared as a NUM. Also, all data is returned by row and table name in the same order it was presented to the Dispatcher. If no data exists in the table, a # sign immediately follows the table name (as in GROUPSPI in the example data).
You must now finally integrate all the information you have received from the Dispatcher into the second part of the output. This part will contain all data needed to describe the database tables. This file will later be imported using the Oracattle SqlImporter (OSI), a text to database utility. Lucky for you, all you need to do is get the second part of the output into the OSI format. This can be a little tricky. The first argument to be supplied is the table name, followed by the number of columns in parentheses, followed by the number of records (rows) in parentheses (no spaces on this line).
Next comes the column name and then the data in quotation marks (a single space should separate the column name and it's data). When the maximum length of the column data is greater than 64, the size must also be supplied in parenthesis immediately following the column name (no space in-between). This is so OSI can allocate more memory for large data.
No blank lines are to exist in the second part of the output, and all data must remain on the same line as the column name (no end-of-line characters in-between quotation marks). Once this file has been created, you are all done! There will be a maximum of 100 columns in a single table, but there may exist any number of rows in a single table. The maximum column name and table name length is 25, and the maximum data length is 100. All input will always contain data in an the expected format (as described in these specifications), so there is no need for error checking. Remember, case is iMpOrTaNt - <NULL> is not the same as <null>.
Process to the end of file.
Source: Mid-Central USA 1996