Once the database is opened and connected, SQL access to the database is performed via a SQL database “engine” structure defined as type
database_t
. This structure is used, for all calls to themcosql_*
functions. The database engine can be created in two ways depending on how the application wants to manage dynamic memory allocations.The simplest method is demonstrated in the following code snippet:
/* Create a SQL engine */ rc = (MCO_RET)mcoapi_create_engine(db, &engine); if ( MCO_S_OK == rc ) { /* Do database processing ... */ /* Destroy the SQL engine */ rc = (MCO_RET)mcoapi_destroy_engine( engine ); /* Disconnect from and close the database, then free database memory */ rc = mco_db_disconnect(db); rc = mco_db_close(db_name); free( dev.dev.conv.ptr ); }The pair of functions
mcoapi_create_engine()
andmcoapi_destroy_engine()
take care of all initialization and cleanup associated with the SQL database engine. However, it is still the application’s responsibility to disconnect from and close the database as well as to free the database memory. Using this method, the standard C runtime dynamic memory allocation functionsmalloc()
andfree()
are called internally by the eXtremeSQL runtime for all SQL processing; i.e. parsing and compiling SQL statements, producing result sets, etc.Since these memory requirements can be large and unpredictable, some applications prefer to manage the dynamic memory with custom memory management functions. To allow for this, a second method is provided as demonstrated in the following snippet:
#define ALLOC_QUANTUM 1024*1024 #define ALLOC_RETAIN 8*1024*1024 /* define custom memory management functions */ void * mem_alloc( size_t n_bytes ) { buffer = (void*)malloc( n_bytes ); printf("\n\n\tmem_alloc(): %u bytes allocated at address 0x%" INT8_FORMAT "x\n", (unsigned int)n_bytes, (int64_t)buffer); return buffer; } void mem_free( void * buf ) { printf("\n\tmem_free(): memory freed at address 0x%" INT8_FORMAT "x\n", (int64_t)buf); free(buf); } /* connect to the database by name */ rc = mco_db_connect( db_name, &db ); if ( MCO_S_OK == rc ) { /* Set SQL memory allocator to custom malloc/free */ rs = mcosql_initialize_dynamic_memory_manager( &mem_alloc, &mem_free, ALLOC_QUANTUM, ALLOC_RETAIN); /* Initialize eXtremeDB SQL mapper */ rs = mcoapi_initialize(db); /* Open SQL engine */ rs = mcosql_open( &engine ); /* Do normal database processing ... */ /* Close SQL engine and disconnect from database */ rs = mcosql_close( engine ); } /* close the database, shutdown runtime and free database memory */ rc = mco_db_close(db_name); mco_runtime_stop(); free( dev.dev.conv.ptr );Note the following in this example code:
- two custom memory management functions
mem_alloc()
andmem_free()
are defined (these are simple examples that use standardmalloc()
andfree()
with a printf() to display the memory operation; clearly more sophisticated custom memory management is possible).- the function
mcosql_initialize_dynamic_memory_manager()
is called to register and initialize the custom functions with the eXtremeSQL runtime. The two pre-defined argumentsALLOC_QUANTUM
andALLOC_RETAIN
provide the runtime with necessary allocation block size and total memory allocation size values.- the function
mcoapi_initialize(db)
is called to map runtime internals to the SQL database engine.- after these preparatory steps, the SQL database engine is now created using function
mcosql_open( &engine )
.- when the SQL database engine is initialized in this way, the function
mcosql_close()
is called to disconnect the database and “destroy” the engine (NB: It is not necessary to callmco_db_disconnect()
as is required when usingmcoapi_create_engine()
andmcoapi_destroy_engine()
, however it is necessary to callmco_db_close()
to close the database).- The return code variable
rs
is used to distinguish SQL return codes from the eXtremeDB runtime codes in variablerc
. SQL return codes are defined in the header file “include/sql/sqlc.h
”, whereas eXtremeDB runtime codes are defined in “include/mco.h
”.