Spectrum Securifile Jon Ellis with a data handler that does away with arrays. Securifile is a flexible machine-code data handling program which illustrates the best of the different approaches to data storage. Broadly speaking, most database programs for the Spectrum can be divided into three categories according to flexi- bility. The first category are these programs designed for specific data, and require modification before the data can be altered. An example is a program I wrote to test all of our computer games and information about them such as their controls. The information was held in data lines, and was read as required. When a new game needed to be added, the program had to be loaded, altered and then resaved. To alter the program so that it could store data on a subject such as a book col- lection, a major rewrite would be necessary. To a user who knew nothing about programming, the program would merely provide a fixed set of information with no scope of change. The second category consists of programs which declare a large array at the beginning, and you input data into the elements of that array. These elements can then be sorted, listed, printed etc. The whole array can be saved on tape and reloaded when required. These programs have the major advantage in that data on any subject can be stored and handled. This means that two users can use the same program skeleton to handle wildly different sets of data. There are, however, several major disadvantages of this approach: the form of each item is dictated at the begin- ning of the program by the dimensions of the array; the programs are often written in Basic and their sort routines are therefore slow; there is little scope for cross-refer- encing etc. When such programs are implemented on the Spectrum, another major disadvantage appears - they waste a lot of space. This is due to the way that the Spectrum handles both string and number arrays. If there are any unused elements in an array then the Spectrum will fill these with either spaces or zeros as applicable. This means that if one piece of data is significantly longer than the rest, the array will have to be dimensioned for the longest item, and so space will be wasted at the end of the other items. This bulking out is known as Pro- crustean assignment and is a prime example of fixed length record storage. The programs in the third category do away with arrays and their accompanying disadvantages and use a variable length record system. This means that only the data is stored and little space is wasted. These programs are the most flexible, imposing few constraints on the data to be stored. These programs are, however, difficult to write, especially in Basic. To design a database system we should look at the fea- tures we would like it to have. Some of the factors to be taken into consideration are: # Memory consumption. The program should be as small as possible, maximising space available for the data, which itself should be stored as efficiently as possible. # As few constraints on the makeup of the file as is possible. The database should be able to handle items of different formats within the same file. # The program should offer the following basic functions: i) The ability to append an item to the file. ii) The ability to delete an item from the file. iii) The ability to edit an item. iv) The ability to store the file on some backup storage - tape, Microdrive. v) The ability to list the items. vi) The ability to sort into alphabetical order. # A more advanced database program might also provide some extra features such as cross-referencing between items, printer compatibility, a choice of storage media, sublist extraction, file security, network communications using the ZX Net. Bearing in mind all these points, I developed Securifile. Securifile would be included in category three. It uses a variable-length record storage technique to provide many facilities in a memory-efficient fashion. Securifile is a reasonably large program as far as typing in goes, 4040 bytes of machine code and data, starting from 25000. This leaves only 2925 bytes available for data on a 16K Spectrum, but a massive 35693 bytes are free on a 48K Spectrum. You need a 48K Spectrum to enter Securifile from the listings, but tape copies will run quite happily on the 16K machine. Securifile offers 14 functions from a menu, each of which being accessed by pressing the key indicated in red on the menu. Before going on to the detailed breakdown of each function, some explanation of various features of the program is encessary. These features are not actually functions, merely subroutines which are used by several functions. The screen editor: This is a major routine used by the add item and change item functions to allow you to input an item to the file. The editor presents you with a screen and a cursor which may be moved around using the keys 5, 6, 7 and 8 with Caps Shift. At the top of the screen there is a space for you to put the key field - KF - of your item, and also a space for the tag field - TF. To move the cursor up to the top line, you will have to place it below one of these spaces and then press up. Caps Shift 2 will change the state of the Caps Lock, indicated by the bar in the top right corner - green = Caps Lock on, blue = off. Caps Shift 1 will wipe the screen, giving you a blank page. This function is queried. To place a character at the current cursor position, just type the appropriate character. To delete a character, move the cursor to the offending character and type a space over the top. Character such as |, which were previously obtained using extended mode, are now available using symbol shift and the appropriate key - © is symbol shift Q. The following characters should not be used in either the key field or the tag field, although they may be used free- ly within the item itself: ©, |, /, [, ], {, }, _. Querying: Drastic instructions are queried by the message "Are you sure? Y/N". Only if you press Y will the instruc- tion be executed, any other key results in the instruction being disregarded. Input of keyfields etc.: There will be many times when Securifile wants a piece of information such as the key field of an item to be deleted, or the filename for a cassette save. At these times you will be prompted to enter the information. The characters that you type will be printed on the screen. All of this input is in lower case. To obtain capitals you will have to use the Caps Shift key as on a typewriter; there is no Caps Lock. You may use delete - Caps 0 - to correct a mistake. Any spare places should be bulked out with spaces. Break can be pressed at almost any time, and it will abort the function, returning you to the menu. However, Break should not be pressed while a tape function is in operation, indicated by the flashing blue/red border or the blue/yellow lines. This could result in the corruption of your file. The reports "Tape recovery error" which may occur during the load, save and header reading functions is slightly ambiguous. It may mean either of two things: the program is expecting a header block and has read some other tape block by mistake, or there has been a genuine tape error. The menu gives the following functions: 1) Add an item. When you select this function you are presented with a blank screen and the cursor of the screen editor. When you have finished making up your item, you should move the cursor to the last character and press ENTER. If the key field of the new item is already that of an existing item, then the program will present you with a choice of changing the new item's key field - press C - or deleting the old item - press D. 2) Change an item. Apart from the fact that this function will prompt for a key field, and will then display that item, this is the same as the add item function in opera- tion. 3) Delete an item. This function prompts for a key field of an item, and will delete it from the file if it exists. 4) Extract sublist. This is possibly the most powerful function of Securifile. When you select this function it will prompt for the tag field pattern that qualify an item for being part of the sublist. This is best explained by means of an example: Suppose that your file consists of a mixture of bills for the past three years. The bills are for electricity, gas and water. You have decided that the first character of the tag field on any item will be either E, G or W - depen- ding on the subject of the bill - the second and third characters will indicate the month of receipt of the bill - e.g. May = 05, November = 11 - and the fourth and fifth characters will denote the year, e.g. 84. The remaining three characters will be undefined. Now, using this func- tion you could ask for a list of all gas bills by using the search pattern G_______. The _ character indicates that that particular character in the pattern is not signifi- cant. To extract a list of all bills in June, the pattern would be _06_____. All bills in June 1984 would require the pattern _0684___. Note that the pattern of eight _ charac- ters is the equivalent of listing all items. When either the screen is full or the list is complete the program will wait for you to press X before continuing. 5) Header catalogue. For security, Securifile stores its files on tape using a non-standard format, which is however quite similar to that used for saving programs on tape - a short header block containing the program filename, followed by a block containing the program proper. This function will read the header blocks created by the Securi- file save routine. It will print the filename of that file on tape, this being the name you must quote in order to load that file, and may also print Locked underneath the filename. This indicates that the password security option is locking that file, and that you will need to know the correct password in order to load the file. 6) Key field sort. This function sorts the list of key fields into alphabetical order. 7) List items. This function lists the key field and tag field of every item in the file, pausing after each screen for you to inspect the list. Press X to continue listing. 8) Printer toggle. This function toggles the printer option between On and Off. If the printer toggle is On, then output from the following functions is also dumped to the ZX Printer: Extract sublist, List items, View item. 9) Quit. This function is queried before Securifile quits and control is returned non-destructively to Basic. 10) Recover file from tape. This option allows you to re- load a previously saved file from tape. It will prompt for the 10-character filename that the file was saved under. You should use the header catalogue function to find the exact filename if you cannot remember it. The specified header will then be loaded. If the file is locked you will have to stop the tape and enter the correct 10-letter password before the program will load the rest of the file. Unprotected files will load straight through without stopping. 11) Save file onto tape. This option allows the current file to be saved on tape. It prompts for a 10-character filename under which the file is to be saved. The program then asks if you want to restrict access to the file. If you press "Y" then you will be prompted for a 10-character password which will secure that file. When you have entered this, or if you choose to have an unprotected file, the program will display the message "Ready tape & press any key". You should set up the recorder and start the tape recor- ding before pressing a key. The file saves in two bursts with about a two second gap between them. The file is saved in a coded form. After saving, the program will ask you to rewind the tape and press V when ready; the file will then be verified. A successful verification is indicated by a return to the menu. An unsuccessful verification will dis- play the message "Tape recovery error". Rewind and try again. 12) Tag field sort. This function sorts the items in the file into alphabetical order by their tag fields. 13) View item. This option will prompt for the key field of the item to be displayed, and will show the whole item on the screen if it exists. 14) Wipe file. This option is queried and if executed will wipe the current file, returning the internal pointers to their original positions.