File system

When the GWA application is launched in the browser, a virtual UNIX-like file system emulation of your GWA application is created in memory.

By default, the following directories are created when a GWA starts:
  • /app directory contains the .42m modules and program resources (with possible subdirectories). The best way to access a resource in your application, regardless of mobile or desktop, is using base.Application.getProgramDir(). For example:
    VAR file_in_app_dir=os.Path.join(base.Application.getProgramDir(),"main.42")
    DISPLAY os.Path.exists(file_in_app_dir)
  • /fgl contains the Genero runtime assets.
  • /tmp is for temp files.
  • /home is the default working directory (pwd) where applications start. Each application has its own unique subdirectory in /home, /home/build_directory_basename – the build_directory_basename corresponds to the name of the program build directory.
    Tip: Setting the working directory

    The working directory can be changed to the /app directory using the gwabuildtool option --app-dir-is-pwd.

    The /home/build_directory_basename is also the "persistent" directory of the GWA because it stores data even if the application is restarted (or the browser is restarted). For more information about managing persistence in the GWA, go to Managing persistence in the file system.

These are the default directories; other directories can be created with the os.Path.mkdir function as needed.

Managing persistence in the file system

As directories in a GWA application are in memory, this means the lifetime of those directories is the same as the lifetime of the application. Understanding the file system will help you develop a strategy for making data persistent.

Before the GWA application starts, the file system emulation is populated with data provided by gwabuildtool. For example, the "/app" directory is populated with the data from the gwabuildtool --program-dir option.

The /home directory is excluded from the pre-population of the file system; all data which can be bundled lands in /app directory.

Home directory

Each application has a specific home directory, /home/build_directory_basename – the build_directory_basename corresponds to the name of the program build directory. The /home/build_directory_basename directory is the "persistent" directory of the GWA application, where the application state can be stored even if the application is restarted or the browser is restarted.

Data in the /home/build_directory_basename directory is stored in the browser cache, or to be more precise, in IndexedDB (external link) caches.

Therefore, if you want to store data, you must put your files in the /home/build_directory_basename directory using explicit channel operations such as os.Path.copy commands as shown in the next section.

Database persistence

Database persistence is managed via a SQLite database file, which must be placed in the /home directory.

If an SQLite database file needs to be created at application startup, you must write some 4GL code to create the file before calling the CONNECT instruction.

If your application comes with a predefined database, you must code to detect it exists at runtime, and if not present, you must copy the initial database(mydatabase.db in the example) bundled by gwabuildtool in the /app directory to the /home directory of the application as shown:
# check for database
VAR home_db="/home/mygwa/mydatabase.db"
#...
IF NOT os.Path.exists(home_db) THEN --Copy to home directory first time
  --the initial mydatabase.db is bundled by gwabuildtool into /app
  IF NOT os.Path.copy("/app/mydatabase.db", home_db) THEN
    DISPLAY "Can't copy initial db"
    EXIT PROGRAM 1
  END IF
END IF
# connect to database

Accidental clearing of the cache

Explicitly cleaning the browser cache for the site hosting a GWA application will remove all stored data of a GWA application.

As there is always the danger that an end user may clear browser cache and thus delete the contents of a GWA application /home directory unintentionally, your GWA application should be prepared to send the data to a REST server via REST API, or synchronise data with the server by other combinations of GWS calls.