To create a new Database in an Environment, you need a valid Environment
handle. Then call ups_env_create_db
with this Environment handle.
ups_status_t
ups_env_create_db (ups_env_t *env, ups_db_t **db, uint16_t name,
uint32_t flags, ups_parameter_t *params);
API reference of ups_env_create_db
The third parameter of ups_env_create_db
is the name of the new
Database – a unique identifier in this Environment. The values 0 and
everything above (including) 0xf000 are reserved and forbidden to use.
The last parameter of ups_env_create_db
, param
, is another variable
length parameter list. It’s worth pointing out that there is a number of
interesting settings that you can (should) set in order to improve the
performance of upscaledb. More precisely, you can describe your key and
record data, and upscaledb will automatically optimize its internal
memory structures for your data. These settings are optional, but they are
essential if you want to max out the performance. Here’s a list of possible
options - look at the API documentation of ups_env_create_db
for a more
authoritative list.
The parameter UPS_PARAM_KEY_TYPE
describes the key type; the following
values are available:
UPS_TYPE_UINT8
: keys are 8 bit (1 byte) charactersUPS_TYPE_UINT16
: keys are 16 bit (2 byte) numbersUPS_TYPE_UINT32
: keys are 32 bit (4 byte) numbersUPS_TYPE_UINT64
: keys are 64 bit (8 byte) numbersUPS_TYPE_REAL32
: keys are 32 bit (single precision) floating point numbersUPS_TYPE_REAL64
: keys are 64 bit (double precision) floating point numbersUPS_TYPE_BINARY
: keys are arbitrary binary data, and sorted with a built-in sort function based on memcmp (); use UPS_PARAM_KEY_SIZE
to specify a constant key size, otherwise the keys have variable lengthUPS_TYPE_CUSTOM
: same as UPS_TYPE_BINARY
, but uses a user-provided callback function for sorting. Can be used in combination with UPS_PARAM_KEY_SIZE
In addition, you can use UPS_PARAM_RECORD_SIZE
to specify a fixed
record size, if all your records have the same size. If your record
size and key size are small enough, then @@upscaledb will squeeze the
records into the B-Tree instead of allocating extra blob storage. This
can have a tremendous performance advantage. (You can use the tool
upsinfo_ to check whether the records are stored inline or not.)
Here is a short example, copied from samples/env1.c. It creates a database for 32bit (4 byte) numeric keys.
#define DBNAME_CUSTOMER 1
ups_db_t *db;
ups_status_t st;
ups_parameter_t param[] = {
{UPS_PARAM_KEY_TYPE, UPS_TYPE_UINT32},
{0, 0}
};
st = ups_env_create_db(env, &db, DBNAME_CUSTOMER, 0, ¶m[0]);
if (st != UPS_SUCCESS) {
printf ("error %d (%s)\n", st, ups_strerror (st));
exit (–1);
}
You can now use the Database handle as you normally do, i.e. for Cursor
operations or inserting/erasing values etc. To close the Database, use
ups_db_close
.
Record Number Databases automatically assign keys in ascending order to newly inserted Database items. This can be compared to the “auto-increment” column in an SQL database. The first item to be inserted gets the key “1”, the second gets “2”, the third “3” etc.
These keys are automatically assigned by upscaledb. Therefore, when
inserting items to a Record Number Database, ups_db_insert
and
ups_cursor_insert
expect either “empty” keys (with size 0 and data
pointing to NULL), or a user-allocated 8-byte key. The file
samples/db4.c demonstrates the use of Record Number Databases.
To create a Record Number Database, call ups_env_create_db
with the
flag UPS_RECORD_NUMBER
.
Here is a small snippet showing how to create a Record Number Database:
st = ups_env_create_db(env, &db, DBNAME_CUSTOMER, UPS_RECORD_NUMBER, 0);
if (st != UPS_SUCCESS) {
printf ("error %d (%s)\n", st, ups_strerror (st));
exit (–1);
}
You can rename Databases in an Environment with ups_env_rename_db
.
This function is declared as follows:
ups_status_t
ups_env_rename_db (ups_env_t *env, uint16_t oldname,
uint16_t newname, uint32_t flags);
API reference for ups_env_rename_db
No error occurs if the Database with the original name is already open.
The function returns UPS_DATABASE_NOT_FOUND
if the Database with the
old name is not found, and UPS_DATABASE_ALREADY_EXISTS
if a Database
with the new name already exists.
Unlike calls to ups_env_rename_db
, ups_env_erase_db
makes sure that
the Database, which you want to delete, is not open. If the Database is
still open, error UPS_DATABASE_ALREADY_OPEN
is returned. Otherwise,
the Database is deleted from the Environment. This can be a costly
operation, because all the allocated file pages are moved to the
freelist, in order to reuse them at a later stage.
ups_status_t
ups_env_erase_db (ups_env_t *env, uint16_t name, uint32_t flags);
API reference for ups_env_erase_db
It is not possible to call this function on an In-Memory Environment.
For In-Memory Environments, it is sufficient to just close the Database
with ups_db_close
. This will immediately free all allocated memory
blocks.
To close an Environment, use ups_env_close
. The handle will be
invalidated, and all allocated resources are released.
The flag UPS_AUTO_CLEANUP
automatically closes all open Databases (and
their Cursors) of this Environment. Otherwise you have to call
ups_db_close
for each opened Database to avoid memory leaks.
ups_status_t ups_env_close (ups_env_t *env, uint32_t flags);
API reference for ups_env_close
The following code will close the Environment handle and all associated Database handles.
st = ups_env_close (env, UPS_AUTO_CLEANUP);
if (st != UPS_SUCCESS) {
printf ("error %d (%s)\n", st, ups_strerror (st));
exit (–1);
}