4D has a function that allows the datafile to be compacted. This is useful to reduce the size of a datafile that sees a number of changes relating to removal or size changes of records.
The datafile can be compacted from MSC in the Compact Section:
When a compact is performed this way MSC will automatically close the database and perform the operation.
A datafile can also be compacted through code using the Compact data file command. However this command cannot be used on a the currently used live datafile as the command cannot replace the datafile or perform a restart. Instead to perform a compact on the datafile the database should be restarted with a temporary/compacting state datafile, perform the compact, then restarted with the compacted datafile.
Below is an example utility method implementing this:
// Method: UtilAutoCompact // // Description: Method to automatically compact // the currently active datafile // // Parameters: // $1 - Boolean: Optional Selector to let // method know that this is being called // from the startup method so that it either // or cleans up instead of performing the // automated compact endlessly // //---------------------------------------------------- C_BOOLEAN($1;$startUp_b) C_TEXT($dataFolder_t) C_TEXT($dataFileName_t) C_TEXT($tempDataName_t) C_TEXT($origDataPath_t) C_TEXT($tempFolder_t) C_TEXT($result_t) If (Count parameters=1) $startUp_b:=$1 Else $startUp_b:=False End if $dataFolder_t:=Get 4D folder(Data folder) $dataFileName_t:=Replace string(Data file;$dataFolder_t;"") $tempDataName_t:="tempCompact.4DD" If ($dataFileName_t=$tempDataName_t) $origDataPath_t:=Document to text($dataFolder_t+"info.txt") $result_t:=Compact data file(Structure file;$origDataPath_t) If (OK=1) OPEN DATA FILE($origDataPath_t) End if Else $tempFolder_t:=$dataFolder_t+"tempCompact"+Folder separator If ($startUp_b=True) If (Test path name($tempFolder_t)=Is a folder) DELETE FOLDER($tempFolder_t;Delete with contents) End if Else CREATE FOLDER($tempFolder_t) If (OK=1) TEXT TO DOCUMENT($tempFolder_t+"info.txt";Data file) CREATE DATA FILE($tempFolder_t+$tempDataName_t) End if End if End if |
The code can be called anytime any where using
UtilAutoCompact |
UtilAutoCompact(False) |
Then the On Startup Database method should check the opened datafile and perform the compact if the temporary datafile was opened or clean up the temp files if they exist using the following.
// Method: On Startup Method //... UtilAutoCompact(True) //... |