File saving

Entire file (SAVE)} This command can only be used if your file is memory-based. It makes sure that there is an up to date version of your file on disk. The record in the buffer is implemented first. The filename and devicename are changed if passed. If no filedevice passed and no default filedevice exists, and saving to just the filename doesn't work, then the file is saved to the data_use device. You can also state the overwrite status (over). If this is zero and the medium-file already exists, an error will be reported. If over is set, then the medium-file will be overwritten. The medium-file will get the _ddf extension. This extension never has to be specified.
Sbasic
    SAVEfile #bufferid, filename, filedevice, over
    filename : [string]
    filedevice : [string]
    over : short[0]
Assembler
    SAVE
    bufferid
    optional string filename
    optional string filedevice
    short overwrite status
C
    long savefile(long bufferid, char *filename,
                  char *filedevice, short over);
  
errors, code,   meaning
itnf    -7      invalid bufferid
drfl    -11     drive full
fex     -8      file already exists
...             any other file i/o error

BACKup} This command can be used to make a backup of a file. There are two reasons for this: making a backup of a disk-based file, or to preserve the filename and filedevice (which SAVE overwrites when changed). The other way to make a backup of your files is by closing the file and copying it manually, this is however not as easy as using this command. When making a backup of a disk-based file, it is impossible to put the backup on another disk in the same drive. This routine always makes a backup of the entire file, and is actually just an implementation of this \basic\ program:
DEFine PROCedure backup(bid, name$, dev$, over)
    keep=bufferID : DEFbuffer=bid
    keepi=indexID : DEFindex=0
    keepv=VIEWstatus : SETVIEWstatus 1
    dd_err=0
    SAVEinit name$, dev$, over
    IF dd_err THEN RETURN
    FIRSTrec
    REPeat loop
        SAVErec : IF dd_err THEN EXIT loop
        NEXTrec : IF dd_err THEN EXIT loop
    END REPeat loop
    SAVEfinish
    SETVIEWSTATUS keepv : DEFbuffer keep : DEFindex keepi
END DEFine backup
This program changes the viewstatus to view only as this makes sure that all records are actually saved. This program does however not return any error, contrary to the routine in the engine. It does show how to make sure that all statusses are preserved when the routine ends. A similar routine could be implemented if you want to save all the record in a certain index, or if you want to save only certain fields.
Sbasic
    BACKfile #bufferid, filename, filedevice, over
    filename : [string]
    filedevice : [string]
    over : short[0]
Assembler
    BACK
    bufferid
    optional string filename
    optional string filedevice
    short overwrite status
C
    long backfile(long bufferid, char *filename,
                  char *filedevice, short over);
  
errors, code,   meaning
itnf    -7      invalid bufferid
drfl    -11     drive full
fex     -8      file already exists
fdiu    -9      Save Record Sequence channels still open
...             any other file i/o error

Save record sequence} Save record sequence is very important as is can be used to save only a part of a file, with preservation of recordid's, and also as it is the only way in which you can make a backup of a disk-based file without removing all buffers for that file. Note that there can only be one save record sequence for each buffer at any given moment. If you want to start another save record sequence on the same buffer, then the previous save record sequence has to be finished. \subsubsection{SAVe record sequence Initialise} Open the file for the save record sequence for the given buffer. If no filedevice passed, and opening just the filename doesn't work, then the medium-file is opened on the DATA\_USE device. You can also state the overwrite status (over). If this is zero and the medium-file already exists, an error will be reported. If over is set, then the medium-file will be overwritten. The medium-file will get the {\tt \_ddf} extension. This extension never has to be specified.
Sbasic
    SAVEinit #bufferid, filename, filedevice, over
    filename : string
    filedevice : [string]
    over : short[0]
Assembler
    SAVI
    bufferid
    string filename
    optional string filedevice
    short overwrite status
C
    long saveinit(long bufferid, char *filename,
                  char *filedevice, short over);
  
errors, code,   meaning
itnf    -7      invalid bufferid
drfl    -11     drive full
fex     -8      file already exists
fdiu    -9      in use, there is still a channel open, should call SAVEfinish
...             any other file i/o error
\subsubsection{SAVe Record} The current record will be saved. You have to make sure that every record is only implemented once, or you will have problems when loading. A record has to have been implemented if you want to save it (it has to have a recordID). This routine also takes the IRS into account. Also note that the channel should be closed with SAVEfinish if an error occurs.
Sbasic
    SAVErec #bufferid
Assembler
    SAVR
    bufferid
C
    long saverec(long bufferid);
  
errors, code,   meaning
itnf    -7      invalid bufferid
drfl    -11     drive full
orng    -4      this is a new record, not accepted
...             any other file i/o error
\subsubsection{SAVe record sequence Finish} Close the file for the save record sequence for the given buffer.
Sbasic
    SAVEfinish #bufferid
Assembler
    SAVF
    bufferid
C
    long savefinish(long bufferid);
  
errors, code,   meaning
itnf    -7      invalid bufferid

Merging another file} On some accasions it may be necesary to merge in another file to the current one, and although there is no extension to do this, we hereby supply a routine which should do the trick. It is the routine which was actually incorporated in the \DATAdesign\ main program. This routine has the advantage of putting fields which already existed (same name) at the same place, and creating new fields for the others. So you should take care with the fieldnames (even more because they are case dependant). On the other hand the routine we present here lacks some error trapping, and it also doesn't check whether the fields in the different files have actually got the same fieldtype. This may cause some strange effects. Only the actual merging is handled here. The file `merge' is merged in with the current file. Two more variables have to be set: 'buffer' which contains the address of some memory which can be used to copy the fields, and 'maxlen' which is the length of this buffer. This buffer can be allocated and released with the lines buffer=ALCHP(maxlen) RECHP buffer So here is the actual routine:
dd_err=0
nrf=NRfields(#merge)
REMark array with fieldid in old file, fieldid in current file
DIM ref(nrf,2): ref(0,1)=0 : ref(0,2)=0
REMark add the fields
j=0
FOR i=1 TO nrf
    name$=CYCLEfields(#merge,j,t)
    ADDfield name$,t
    ref(i,1)=j : ref(i,2)=fieldID(name$)
END FOR i
REMark copy all the fields
FIRSTrec #merge
REPeat loop
    NEWrec
    FOR i=0 to nrf
        length=GETfield(#merge, ref(i,1), maxlen, buffer)
        SETfield ref(i,2), length, buffer
    END FOR i
    IMPLEMENT
    NEXTrec #merge
    IF dd_err THEN EXIT loop
END REPeat loop
PROGS, Professional & Graphical Software
last edited September 3, 1996