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 DDsavefile(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
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 Sbasic 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 DDbackfile(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 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.
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 _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 DDsaveinit(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
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 DDsaverec(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
Close the file for the save record sequence for the given buffer.
Sbasic SAVEfinish #bufferid Assembler SAVF bufferid C long DDsavefinish(long bufferid); errors, code, meaning itnf -7 invalid bufferid
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 bufferSo 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