KNOWLEDGE BASE
Log In    |    Knowledge Base    |    4D Home
Tech Tip: Compacting Live Datafile
PRODUCT: 4D | VERSION: 15.x | PLATFORM: Mac & Win
Published On: March 17, 2018

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
or
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)
//...