An instance of the sqlite4_env object defines the run-time environment for SQLite4. By "run-time environment" we mean things such as:
- How to create and use mutexes
- How to allocate heap memory
- Interfaces to the underlying operating system
- Logging facilities
- The available Key/Value storage backends
- Start-time options
Basically, the sqlite4_env object defines how SQLite4 interacts with the rest of the application.
Builds for unix and windows come with a built-in sqlite4_env object that is appropriate for most applications. And so in most cases, the programmer never has to think about the run-time environment; the default setup will work great. But some speciallized applications may want to alter the environment to accommodate their particular needs. For example, the application might want to use a memory allocator other than the default malloc()/free()/realloc() from the standard library. Or, the application might want to define an alternative key/value storage engine to use on the backend of SQLite4. In these cases, the application can either customize the built-in default sqlite4_env object, or create its own sqlite4_env objects to use in place of the default.
An sqlite4_env object is not constant. It contains state information, such as the current state of the PRNG and the state of various mutexes. SQLite4 contains no global variables, except for the single built-in default sqlite4_env object. All global state is contained within sqlite4_env objects.
An sqlite4_env object is opaque; its internal structure is not visible to the application. The content of an sqlite4_env object is controlled indirectly through methods, such as sqlite4_env_config().
Methods Of The Run-time Environment Object
A number of interfaces in SQLite4 require a pointer to an sqlite4_env object as their first parameter. Think of these interfaces as methods of the sqlite4_env object. Examples include (but are not limited to):
int sqlite4_env_config(sqlite4_env*, int op, ...); int sqlite4_open(sqlite4_env*, const char *zFilename, sqlite4 **, ...); void *sqlite4_malloc(sqlite4_env*, sqlite4_size_t); void *sqlite4_realloc(sqlite4_env*, void*, sqlite4_size_t); void sqlite4_free(sqlite4_env*, void*); char *sqlite4_mprintf(sqlite4_env*, const char *zFormat, ...); int sqlite4_randomness(sqlite4_env*, int amt, unsigned char *buf); void sqlite4_log(sqlite4_env*, int errCode, const char *zFormat, ...);
Any interface that takes a pointer to an sqlite4_env object will accept a NULL pointer. When a NULL pointer is seen on an sqlite4_env method, the built-in default sqlite4_env object is used.
Managing Run-time Environment Objects
The default run-time environment can be obtained using the following interface:
sqlite4_env *sqlite4_env_default(void);
To create a new, customized sqlite4_env object, an application should first allocate space for the object. Space can be allocated on the heap or on the stack or as BSS. The amount of space allocated must be at least sqlite4_env_size() bytes. The space requirements will vary depending on the release of SQLite and on the compile-time options used to build SQLite, so it is important that applications always check the size returned from sqlite4_env_size().
To initialize a new sqlite4_object, use:
sqlite4_env_config(pNew, SQLITE_ENVCONFIG_INIT, pTemplate);
The sqlite4_env_config(.., SQLITE_ENVCONFIG_INIT,...) interface copies the settings from a preexisting sqlite4_env object (which can be a NULL pointer to indicate the default environment) into the new environment object.
After being initialized, the application can make customizations to the new sqlite4_env object using additional calls to sqlite4_env_config(). Once customization is complete, the application should activate the environment using:
int sqlite4_initialize(sqlite4_env*);
Every sqlite4_env object should be exactly activated prior to use. Even the built-in default sqlite4_env objects should be activated by a call to sqlite4_initialize() with a NULL argument. Many of the customizations must occur prior to activation. If these customizations are attempted after activation, sqlite4_env_config() will return SQLITE_MISUSE.
To safely modify the an sqlite4_env object after it has been activated, it should first be deactivated using:
int sqlite4_shutdown(sqlite4_env*);
All database connections should be closed and all memory allocates free and all other resources associated with the environment should be released prior to invoking sqlite4_shutdown().