<title>The SQLite4 Run-Time Environment</title>

An instance of the <b>sqlite4_env</b> 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().

<h2>Methods Of The Run-time Environment Object</h2>

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):

<blockquote><pre>
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, ...);
</pre></blockquote>

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.  

<h2>Managing Run-time Environment Objects</h2>

The default run-time environment can be obtained using the following
interface:

<blockquote><pre>
sqlite4_env *sqlite4_env_default(void);
</pre></blockquote>

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:

<blockquote><pre>
sqlite4_env_config(pNew, SQLITE_ENVCONFIG_INIT, pTemplate);
</pre></blockquote>

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:

<blockquote><pre>
int sqlite4_initialize(sqlite4_env*);
</pre></blockquote>

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:

<blockquote><pre>
int sqlite4_shutdown(sqlite4_env*);
</pre></blockquote>

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().
