Mimer SQL C API

Mimer SQL C API is a native C library suitable for tool integration and application development in environments where API standardization is not a requirement. The following characteristics describe the API:

  • Simplicity
  • Platform independence
  • Small footprint
  • Tight fit with the Mimer SQL application/database communication model.

The Mimer SQL C API also comes in a micro environment edition under the name Mimer SQL Micro C API, which is mainly targeted for memory and CPU constrained environments. This variant is referred to as the Micro API.

Hereinafter, the Mimer SQL C API is referred to as the Mimer API. In most cases, the Mimer API and the Micro API are identical, but there are differences, for example in the number of data types supported. Please see the Programmer’s Manual part of the Mimer SQL Documentation Set for further details in this matter in and all other information given in this article.

Architecture

The Mimer API routines may be divided into four major categories, depending on how they are used. These routine categories are:

  • Session management – These routines manages a database session including connect, disconnect and transaction handling.
  • Statement management – Once a session has been established, an application uses statements to interact with the database. Statements are defined using the SQL language and may be specified directly or created on the server in advance using the CREATE STATEMENT command.
  • Input data management – Used to supply input parameter data to statements.
  • Output data management – Obtains result sets and statement output parameter data.

Character String Formats

API routines having string parameters come in different flavors depending on which character string format is used. The rationale is that the base routine considers all strings to be null terminated wchar_t * strings.

If a routine has string parameters, there is a companion routine suffixed with C, which accepts the string parameters as null terminated char * strings, where the character set is defined by the current locale.

Companion routines suffixed with 8 have the string format UTF-8, regardless of locale settings.

Session Management

In the Mimer API, the following routines are used for managing sessions; beginning and ending sessions, and beginning and ending transactions:

  • MimerBeginSession[C|8]
  • MimerEndSession
  • MimerBeginTransaction
  • MimerEndTransaction

The flow of calls should be according to the below. First, a session is started using a call to MimerBeginSession (or MimerBeginSession8 or MimerBeginSessionC, depending on the data types supplied).

Then database operations take place, either separately (in auto-committed transactions), or grouped in explicit transactions. The boundaries of an explicit transaction are marked using the calls to MimerBeginTransaction and MimerEndTransaction.

This process continues until the application terminates its database session through a call to MimerEndSession.

MimerBeginSession[C|8]
loop
{
    MimerBeginTransaction
    <statement and data management routines>
    MimerEndTransaction
}
MimerEndSession

Statement Management

The routines used to manage statements are:

  • MimerAddBatch
  • MimerBeginStatement[C|8]
  • MimerEndStatement
  • MimerExecute
  • MimerOpenCursor
  • MimerFetch
  • MimerFetchScroll
  • MimerFetchSkip
  • MimerCloseCursor
  • MimerCurrentRow
  • MimerExecuteStatement[C|8]

Which routines to use basically depends on if the statement has input or output parameters, and if a result set is returned or not.

No input or output parameters, no result set

The MimerExecuteStatement[C|8] routine is mainly intended for DDL statements (i.e. Data Definition Language statements, e.g. create and drop table.) However, it can also be used for UPDATE, INSERT, DELETE and CALL statements without parameters.

MimerExecuteStatement[C|8]

Input or output parameters, but no result set

The MimerExecute routine is used for INSERT, UPDATE and DELETE statements, assignments (SET), and procedure calls which do not return a result set.

MimerBeginStatement[C|8]
<data input routines>
MimerExecute
<data output routines>
MimerEndStatement

Result set producing statements

Result sets are returned by SELECT statements, as well as by calls to result set procedures. A result set is accessed using a cursor.

MimerBeginStatement[C|8]
<data input routines>
MimerOpenCursor
loop
{
    MimerFetch/MimerFetchSkip/MimerFetchScroll
    <data output routines>
}
MimerCloseCursor
MimerEndStatement

Data Input Routines

Input data management routines are used to supply input parameter data to statements. The data management routines to set input parameter data are:

  • MimerSetBinary
  • MimerSetBlobData
  • MimerSetBoolean
  • MimerSetDouble
  • MimerSetFloat
  • MimerSetInt32
  • MimerSetInt64
  • MimerSetLob
  • MimerSetNclobData[C|8]
  • MimerSetNull
  • MimerSetString[C|8]
  • MimerSetStringLen[C|8]

Data Output Routines

The output data management routines used to obtain statement results are:

  • MimerGetBinary
  • MimerGetBlobData
  • MimerGetBoolean
  • MimerGetDouble
  • MimerGetFloat
  • MimerGetInt32
  • MimerGetInt64
  • MimerGetLob
  • MimerGetNclobData[C|8]
  • MimerGetString[C|8]
  • MimerIsNull

Array Operations

The Mimer API supports the use of array fetch operations. Array fetching means that multiple rows are fetched from the server in one request. This will improve performance at the expense of memory consumption. MimerSetArraySize may be used to control the minimum number of rows to be fetched in each request. MimerRowSize may be used to determine the maximum number of bytes each row consumes. By multiplying the array size with the maximum row size a maximum array fetch memory consumption value can be obtained.

MimerFetch will internally fetch as many rows as possible and refill the internal buffer when needed. MimerNext on the other hand will return rows until all the rows in the internal buffer have been returned, it will not call the server to fetch more rows. The purpose of MimerNext is to have a fetch routine that is guaranteed context switch free.

The Mimer API also supports supplying parameters in arrays. Parameter arrays are specified by call MimerAddBatch during the parameter build-up sequence. MimerAddBatch adds the current set of parameters to be executed on the next MimerExecute call making room for another set of parameters to be specified by subsequent calls to for example MimerSetString.

Transactions

All operations on the database participate in a transaction. By default, operations are committed as soon as possible, which in practice means immediately after each INSERT, UPDATE or DELETE. A common term for this is that statements are automatically committed (autocommit).

If several operations are to be grouped together into one single transaction, the transaction boundaries must be defined by calls to MimerBeginTransaction and MimerEndTransaction.

Transactions may abort. A transaction abort is a rollback forced by the system. A transaction abort occurs when a conflict with another session has been detected, for example when two transactions have been reading and updating the same data. The database system must decide to abort one of them and to save the other one to storage. The session seeing the aborted transaction must take some action depending on this, perhaps trying to update the database once again.

Issuing large transactions puts a special burden on the database server since read- and write-sets may grow large, thus consuming memory. The read- and write-sets are logs maintaining a record of what active transactions have done. Large read- and write-sets also has the implication that they put a larger overall burden on the database server since it may take time to manage them, particularly if they grow so large that they are written to flash or magnetic memories.

Error Handling

Upon return, all routines return an integer value. In most cases the value zero (MIMER_SUCCESS) is used to indicates success. In some cases a positive value is used to indicate success with additional information. Negative values always indicate an error condition. The negative values are standard Mimer SQL error codes, which are listed in Appendix B Return Codes found in the Programmer’s Manual part of the Mimer SQL Documentation Set.

The acronyms for the Mimer API specific return codes can be found in the mimerrors.h header file.

The macro MIMER_SUCCEEDED may be used to detect a call which has either succeeded, or succeeded with additional information (a positive value). Negating this macro may be used to detect an error.

The error condition MIMER_SEQUENCE_ERROR has a special meaning. It will be returned when an illegal call has been made. The Mimer API will enforce a strict sequence of allowed calls. For example, MimerGetString may not be called before MimerFetch has been called. MIMER_SEQUENCE_ERROR is returned when illegal sequences of calls are detected.

Error Handling Example

The below example function shows how a function uses the return value from a Mimer API function call to determine success or failure.

/**
* Function which executes the statement OUR_STATEMENT
*
* On failure, the error code is written to stdout.
*/
#include "mimerapi.h"
int example1(MimerSession session)
{
    int32_t err,end_err=MIMER_SUCCESS;
    MimerStatement statement;
    err = MimerBeginStatement(session,L"OUR_STATEMENT",0,&statement);
    if (MIMER_SUCCEEDED(err)) {
        err = MimerExecute(statement);
        end_err = MimerEndStatement(&statement);
    }
    if (!MIMER_SUCCEEDED(err) || !MIMER_SUCCEEDED(end_err)) {
        printf("Error %d, end error %d.\n",err,end_err);
    }
}

Memory Management

Throughout the Mimer API, routines are designed and implemented to allow callers not to worry about memory management. The rule is that the required buffers are allocated to their minimum size, and released as soon as they are not needed anymore.

For example, when starting a statement, information about its parameters, if it returns a result set, result set columns and their type are attached to the statement handle. This block of memory is released when the statement is released.

Memory for keeping parameters and result set columns are allocated either when the applications starts setting input parameters, or when the statement is executed (MimerExecute), or the cursor is opened (MimerOpenCursor).

When the statement is executed, the database server reads the parameters that have been set, and if there are no result set or output parameters returned, the Mimer API will release the memory promptly. If there are output parameters, or result set data, memory to keep this information is retained until the statement or cursor is closed.

Header Files Provided

When using the Mimer API, the mimerapi.h header file should always be included. For example, this file declares the API routines and also the handle types to be used, i.e. MimerSession, MimerStatement, MimerLob and MimerHandle. In addition, it defines a number of symbols that can be used for a convenient and instructive C coding.

Other files that are provided are the mimerror.h and mimstdint.h files, which both are automatically included by the mimerapi.h file. The mimstdint.h file arranges the necessary measure for using the int16_t, int32_t and int64_t data types that are recommended for, and used by, the Mimer API. The mimerrors.h file defines C symbols for a couple of error codes that may be used when programming with the Mimer API.

C symbols used in example code are defined in these header files.

For further reading, please see the Mimer SQL C API chapter in the Programmer’s Manual part of the Mimer SQL Documentation Set.