Sedna LogoBackground Top
 
Home  |  Getting Started  |  Documentation  |  Demo  |  Download  |  Support 

1.2 C API

libsedna is the C application programmer’s interface to Sedna XML DBMS. libsedna is a set of library functions that allow client programs to access one or more databases of Sedna XML DBMS and manipulate database data using database language (XQuery and XUpdate) described in Section 2.

libsedna library is supplied with two header files: "libsedna.h", "sp_defs.h". Client programs that use libsedna must include the header file libsedna.h, must link with the libsedna library and provide the compiler with the path to the directory where "libsedna.h", sp_defs.h files are stored.

For convenience three versions of libsedna are provided on the Windows operating system:

  1. libsednamt.lib - static multi-threaded version built with /MT option. Use it if you compile your project with /MT[d] option.
  2. libsednamd.lib - static multi-threaded version built with /MD option. Use it if you compile your project with /MD[d] option.
  3. sednamt.dll - dynamic version. sednamt.lib is import library.

On Unix-like operating systems the following versions of libsedna are provided:

  1. libsedna.so - dynamic shared library.
  2. libsedna.a - static version of the library.
  3. libsedna_pic.a - static version of the library with PIC enabled. You may need it to build drivers for Sedna which are based on libsedna.

1.2.1 Errors Handling

C API provides set of functions for sessions and transactions management, query and update statements execution, etc. If the function fails it returns negative value. In this case application can obtain the error message and code which help to understand the reason of the error occurred.

To get the last error message use SEgetLastErrorMsg function:

char* SEgetLastErrorMsg(SednaConnection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type (see 1.2.2, Connecting to a Database section for details on how to obtain a connection instance).

The function SEgetLastErrorCode returns the last error code occurred in the session:

int SEgetLastErrorCode(struct SednaConnection *conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type (see 1.2.2, Connecting to a Database section for details on how to obtain a connection instance).

1.2.2 Connecting to a Database

Before working with Sedna an application has to declare variable of the SednaConnection type and initialize it in the following manner:

struct SednaConnection conn = SEDNA_CONNECTION_INITIALIZER;

Note 1 The initialization with SEDNA_CONNECTION_INITIALIZER is mandatory for Sedna version 0.5 and earlier.

To start working with Sedna an application has to open a session via establishing an authenticated connection with the server using SEconnect:

int SEconnect(SednaConnection* conn,  
              const char* url,  
              const char* db_name,  
              const char* login,  
              const char* password)

Parameters:

  • conn - is a pointer to an instance of SednaConnection type, that is associated with a session. The instance of SednaConnection type is initialized by the SEconnect if the session is open successfully.
  • url - the name of the computer where the Sedna DBMS is running. This parameter may contain a port number. If the port number is not specified, the default port number (5050) is used.
  • db_name - the name of the database to connect to.
  • login - user login.
  • password - user password.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_SESSION_OPEN - connection to the database is established, authentication passed successfully.

If the function fails, the return value is negative and session is not opened:

  • SEDNA_AUTHENTICATION_FAILED - authentication failed.
  • SEDNA_OPEN_SESSION_FAILED - failed to open session.
  • SEDNA_ERROR - some error occurred.

To access multiple databases at one time or to better process its complex logic an application can have several sessions open at one time.

When an application finished it’s work with the database, it must close the session. SEclose finishes the session and closes the connection to the server. SEclose also frees resources that were equipped by the call to SEconnect function, that is for every successful call to SEconnect there must be a call to SEclose in the client program. You must call SEclose both when application finishes its work with the database, and when application cannot work with the database anymore due to some error.

int SEclose(SednaConnection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type, associated with a session to be closed.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_SESSION_CLOSED - session closed successfully.

If the function fails, the return value is negative:

  • SEDNA_CLOSE_SESSION_FAILED - session closed with errors.
  • SEDNA_ERROR - some error occurred.

1.2.3 Setting Session Options

An application can set attributes that govern aspects of a session using SEsetConnectionAttr:

int SEsetConnectionAttr(struct SednaConnection *conn,  
                        enum SEattr attr,  
                        const void* attrValue,  
                        int attrValueLength)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type, associated with a session to be closed.
  • attr - an attribute to set (one of the predefined Sedna connection attributes listed below).
  • attrValue - a pointer to the value to be associated with the attribute.
  • attrValueLength - a length of the value in bytes.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_SET_ATTRIBUTE_SUCCEEDED - the attribute was set successfully.

If the function fails, the return value is negative:

  • SEDNA_ERROR - some error occurred.

Supported attributes:

  • SEDNA_ATTR_AUTOCOMMIT Autocommit mode is the default transaction management mode of the Sedna server (SEDNA_AUTOCOMMIT_OFF is the default value of this attribute). Every XQuery or update statement is committed or rolled back when it completes. If a statement completes successfully, it is committed; if it encounters any error, it is rolled back. A connection to an instance of the Sedna database operates in autocommit mode whenever this default mode has not been overridden by setting this attribute into SEDNA_AUTOCOMMIT_OFF value.


    Atrribute values Value size


    SEDNA_ATTR_AUTOCOMMIT_ON,
    SEDNA_ATTR_AUTOCOMMIT_OFFsizeof(int)


  • SEDNA_ATTR_SESSION_DIRECTORY connection attribute defines the session directory. If this attribute is set, paths in the LOAD statement 2.4 or LOAD MODULE are evaluated relative to the session directory.


    Atrribute valuesSize of value


    path to directory length of path


  • SEDNA_ATTR_DEBUG connection attribute turns on/off query debug mode. Query debug mode is off by default. Note: SEDNA_ATTR_DEBUG connection attribute must be set only after SEconnect has been called on the conn.


    Atrribute values Value size


    SEDNA_ATTR_DEBUG_ON,
    SEDNA_ATTR_DEBUG_OFFsizeof(int)


  • SEDNA_ATTR_CONCURRENCY_TYPE connection attribute changes the mode of the next transactions. Transaction can be set to run as READ-ONLY (SEDNA_READONLY_TRANSACTION) or UPDATE-transaction (SEDNA_UPDATE_TRANSACTION). READ-ONLY transactions have one major benefit: they never wait for other transactions (they do not have to acquire any document/collection locks). However they might access slightly obsolete state of the database (for example, they probably would not see the most recent committed updates). You should use READ-ONLY transactions in a highly concurrent environment. Notice that the current transaction, if any, will be forcefully committed.


    Atrribute values Value size


    SEDNA_READONLY_TRANSACTION,
    SEDNA_UPDATE_TRANSACTION sizeof(int)


  • SEDNA_ATTR_QUERY_EXEC_TIMEOUT connection attribute allows to set the limit on query execution time. If set, for each next query in this session, query execution will be stopped if it lasts longer than timeout set. In this case transaction in bounds of which the query run is rollback. By default (value 0) there is no any timeout for query execution, that is a query can be executed as long as needed.


    Atrribute valuesValue size


    time in seconds sizeof(int)


  • SEDNA_ATTR_MAX_RESULT_SIZE connection attribute allows to set the limit on query result size. If this attribute is set, the server will cut the result data if its size exceeds the specified limit. By default, result data that is passed from server in response to user query can be of unlimited size.


    Atrribute valuesValue size


    size in bytes sizeof(int)


  • SEDNA_LOG_AMOUNT connection attribute changes the mode of logical logging for the following transactions in the same session. Transaction can be set to run in full log mode (SEDNA_LOG_FULL) or reduced log mode (SEDNA_LOG_LESS). The former means transaction writes much less log info during bulk loads. Also, when such transaction commits the checkpoint is made, which might greatly reduce recovery time. There is a caveat, however: such transaction always runs in exclusive mode, which means there can be no concurrent transactions. Before it starts it waits for other concurrent transactions to finish. In turn, all other transactions will not start until exlusive transaction finishes. You should use this option with care, since it effectively stalls any concurrent activity. The main purpose of such transactions is to bulk-load data. The other possible use-case includes transactions performing heavy update operations. Since checkpoint will be made when such transaction commits, it might reduce recovery time in case of database crash. Otherwise, you should not use this option since you will not gain anything. Notice also that the current transaction in the same session, if any, will be forcefully committed. The default value for this attribute is SEDNA_LOG_FULL.


    Atrribute values Value size


    SEDNA_LOG_LESS,
    SEDNA_LOG_FULL sizeof(int)


An application can retrieve current value of hte connection attributes using SEgetConnectionAttr:

int SEgetConnectionAttr(struct SednaConnection *conn,  
                        enum SEattr attr,  
                        void* attrValue,  
                        int* attrValueLength);

Parameters:

  • conn - a pointer to an instance of the SednaConnection type, associated with a session to be closed.
  • attr - an attribute to retrieve.
  • attrValue - a pointer to memory in which to return the current value of the attribute specified by attr.
  • attrValueLength - a length of the retrieved value in bytes.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_GET_ATTRIBUTE_SUCCEEDED - the attribute was retrieved successfully.

If the function fails, the return value is negative:

  • SEDNA_ERROR - some error occurred.

To reset all connection attributes to default values use:

int SEresetAllConnectionAttr(struct SednaConnection *conn);

Parameters:

  • conn - a pointer to an instance of the SednaConnection type, associated with a session to be closed.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_RESET_ATTRIBUTES_SUCCEEDED - attributes has been reset successfully.

If the function fails, the return value is negative:

  • SEDNA_ERROR - some error occurred.

1.2.4 Transactions Management

An application can execute queries and updates against the specified database only in the scope of a transaction. That is, once a session has been opened, an application can begin a transaction, execute statements and commit this transaction. In a session transactions are processed sequentially. That is, application must commit an ongoing transaction before beginning a new one.

There are two ways to manage transactions in Sedna sessions: autocommit mode and manual-commit mode:

  • Autocommit mode. Each individual statement is committed when it completes successfully. When running in autocommit mode no other transaction management functions are needed. By default, Sedna sessions are run in autocommit mode.
  • Manual-commit mode. Transaction boundaries are specified explicitly by means of SEbegin, SEcommit and SErollback functions. All statements between the call to SEbegin and SEcommit/SErollback are included in the same transaction.

An application can switch between the two modes using SEsetConnectionAttr and SEgetConnectionAttr functions (see 1.2.3) for SEDNA_ATTR_AUTOCOMMIT attribute.

To specify transaction boundaries application uses SEbegin, SEcommit and SErollback functions. SEbegin function starts new transaction in the provided session:

int SEbegin(SednaConnection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_BEGIN_TRANSACTION_SUCCEEDED - transaction has been successfully started.

If the function fails, the return value is negative:

  • SEDNA_BEGIN_TRANSACTION_FAILED - failed to start a transaction.
  • SEDNA_ERROR - some error occurred.

SEcommit function commits the current transaction:

int SEcommit(SednaConnection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_COMMIT_TRANSACTION_SUCCEEDED - transaction has been committed.

If the function fails, the return value is negative:

  • SEDNA_COMMIT_TRANSACTION_FAILED - failed to commit transaction.
  • SEDNA_ERROR - some error occurred.

SErollback function rollbacks the current transaction:

int SErollback(SednaCommection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_ROLLBACK_TRANSACTION_SUCCEEDED - transaction has been rollbacked.

If the function fails, the return value is negative:

  • SEDNA_ROLLBACK_TRANSACTION_FAILED - failed to rollback transaction.
  • SEDNA_ERROR - some error occurred.

1.2.5 Getting Connection and Transaction Status

An application can obtain the connection status by SEconnectionStatus function:

int SEconnectionStatus(SednaConnection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.

Return values:

  • SEDNA_CONNECTION_OK - specified connection is open and functions ok.
  • SEDNA_CONNECTION_CLOSED - specified connection is closed. This could be either after the call to SEclose function, or before the call to SEconnect function.
  • SEDNA_CONNECTION_FAILED - specified connection has been failed. (Note: in this case you should call SEclose function to release resources).

An application may obtain the transaction status by SEtransactionStatus function:

int SEtransactionStatus(SednaConnection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.

Return values:

  • SEDNA_TRANSACTION_ACTIVE - specified connection runs transaction.
  • SEDNA_NO_TRANSACTION - specified connection does not run transaction. This could be for example when previous transaction has been committed and a new one has not begun yet.

1.2.6 Executing Queries and Updates

There are two functions to execute a statement (query or update): SEexecute function and SEexecuteLong function. First one reads statement from a C-string, the second reads long statement from a provided file. To get trace (fn:trace XQuery function) and debug information application may implement custom debug handler and set it using function: SEsetDebugHandler.

int SEexecute(SednaConnection* conn, const char* query)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.
  • query - a null-terminated string with an XQuery or XUpdate statement.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_QUERY_SUCCEEDED - specified query succeeded and result data can be retrieved.
  • SEDNA_UPDATE_SUCCEEDED - specified update succeeded.
  • SEDNA_BULK_LOAD_SUCCEEDED - specified update (bulk load 2.4) succeeded.

If the function fails, the return value is negative:

  • SEDNA_QUERY_FAILED - specified query failed.
  • SEDNA_UPDATE_FAILED - specified update failed.
  • SEDNA_BULK_LOAD_FAILED - bulk load failed.
  • SEDNA_ERROR - some error occurred.

If the statement is really long, and you prefer to pass it to the Sedna directly from a file use SEexecuteLong function.

int SEexecuteLong(SednaConnection* conn,  
                  const char* query_file_path)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.
  • query_file - a path to the file with a statement to execute.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_QUERY_SUCCEEDED - specified query succeeded and result data can be retrieved.
  • SEDNA_UPDATE_SUCCEEDED - specified update succeeded.
  • SEDNA_BULK_LOAD_SUCCEEDED - specified update (bulk load 2.4) succeeded.

If the function fails, the return value is negative:

  • SEDNA_QUERY_FAILED - specified query failed.
  • SEDNA_UPDATE_FAILED - specified update failed.
  • SEDNA_BULK_LOAD_FAILED - bulk load failed.
  • SEDNA_ERROR - some error occurred.

If SEexecute function or SEexecuteLong function return SEDNA_QUERY_SUCCEEDED, the result data can be retrieved. The result of XQuery query evaluation is a sequence of items, where every item is represented as a string. Use the SEnext function to iterate over the sequence and SEgetData function to retrieve the current item of the sequence.

int SEnext(SednaConnection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_NEXT_ITEM_SUCCEEDED - moving to the next item succeeded, and the item can be retrieved.

If the function fails or the is no result items available to retrieve, the return value is negative:

  • SEDNA_NEXT_ITEM_FAILED - failed to get next item.
  • SEDNA_RESULT_END - the result sequence is ended, no result data to retrieve.
  • SEDNA_NO_ITEM - there was no succeeded query that produced the result data, no result data to retrieve.
  • SEDNA_ERROR - some error occurred.

SEgetData function retrieves current item from the result sequence:

int SEgetData(SednaConnection* conn,  
              char* buf,  
              int bytes_to_read)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.
  • buf - pointer to the buffer that receives the data got from the server.
  • bytes_to_read - number of bytes to be read from the server into the buffer.

Return values:

If the function succeeds, the return value is non-negative:

  • number of bytes actually read from the server and put into the buffer.
  • zero - no data was read from the server and put into the buffer because of the item end. (use SEnext to move to the next item of the result).

If the function fails, the return value is negative:

  • SEDNA_GET_DATA_FAILED - failed to get data.
  • SEDNA_ERROR - some error occurred.

Since version 1.5 Sedna supports reporting tracing information (fn:trace XQuery function). To handle tracing information while retrieving result data use debug handler debug_handler_t and SEsetDebugHandler function:

void SEsetDebugHandler(struct SednaConnection *conn,  
                       debug_handler_t debug_handler)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.
  • debug_handler - a pointer to your own defined function of the following type: void (*debug_handler_t)(int subtype, const char *msg) where subtype is a type of debug information (currently only SEDNA_QUERY_TRACE_INFO is supported), msg is a buffer with debug information.

For example the following debug handler prints out debug iformation to the stdout:

void my_debug_handler(enum SEdebugType subtype,  
                      const char *msg) {  
  printf("TRACE: ");  
  printf("subtype(%d), msg: %s\n", subtype, msg);  
}

If the debug handler is not defined by the application, trace information is ignored.

1.2.7 Loading Data

XML data can be loaded into a database using "LOAD" statement of the Data Manipulation Language (see 2.4). Besides, libsedna library provides SEloadData and SEendLoadData functions to load well-formed XML documents divided into parts of any convenient size.

SEloadData functions loads a chunk of an XML document:

int SEloadData(SednaConnection* conn,  
               const char* buf,  
               int bytes_to_load,  
               const char* doc_name,  
               const char* col_name)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.
  • buf - a buffer with chunk of an XML document to load.
  • bytes_to_load - number of bytes to load.
  • doc_name - name of the document in a database the data loads to.
  • col_name - name of the collection in the case if document is loaded into the collection, NULL if document is loaded as a standalone one.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_DATA_CHUNK_LOADED - chunk of an XML document loaded successfully.

If the function fails, the return value is negative:

  • SEDNA_ERROR - some error occurred. Data is not loaded.

When the whole document is loaded using SEloadData, application must use SEendLoadData to notify server that transfer of an XML document is finished:

int SEendLoadData(SednaConnection* conn)

Parameters:

  • conn - a pointer to an instance of the SednaConnection type.

Return values:

If the function succeeds, the return value is positive:

  • SEDNA_BULK_LOAD_SUCCEEDED - XML document was successfully loaded into the database.

If the function fails, the return value is negative:

  • SEDNA_BULK_LOAD_FAILED - failed to load XML document into the database.
  • SEDNA_ERROR - some error occurred.

1.2.8 Example Code
#include "libsedna.h"  
#include "stdio.h"  
 
int handle_error(SednaConnection* conn,  
                 const char* op,  
                 int close_connection) {  
    printf("%s failed: \n%s\n", op, SEgetLastErrorMsg(conn));  
    if(close_connection == 1) SEclose(conn);  
    return -1;  
}  
 
int main() {  
  struct SednaConnection conn = SEDNA_CONNECTION_INITIALIZER;  
  int bytes_read, res, value;  
  char buf[1024];  
 
  /* Turn off autocommit mode */  
  value = SEDNA_AUTOCOMMIT_OFF;  
  res = SEsetConnectionAttr(&conn, SEDNA_ATTR_AUTOCOMMIT,  
                            (void*)&value, sizeof(int));  
 
  /* Connect to the database */  
  res = SEconnect(&conn, "localhost", "test_db",  
                  "SYSTEM", "MANAGER");  
  if(res != SEDNA_SESSION_OPEN)  
    return handle_error(&conn, "Connection", 0);  
 
  /* Begin a new transaction */  
  res = SEbegin(&conn);  
  if(res != SEDNA_BEGIN_TRANSACTION_SUCCEEDED)  
    return handle_error(&conn, "Transaction begin", 1);  
 
  /* Load file "region.xml" into the document "region" */  
  res = SEexecute(&conn, "LOAD ’region.xml’ ’region’");  
  if(res != SEDNA_BULK_LOAD_SUCCEEDED)  
    return handle_error(&conn, "Bulk load", 1);  
 
  /* Execute XQuery statement */  
  res = SEexecute(&conn, "doc(’region’)/*/*");  
  if(res != SEDNA_QUERY_SUCCEEDED)  
    return handle_error(&conn, "Query", 1);  
 
  /* Iterate and print the result sequence */  
  while((res = SEnext(&conn)) != SEDNA_RESULT_END) {  
    if (res == SEDNA_ERROR)  
      return handle_error(&conn, "Getting item", 1);  
 
    do {  
      bytes_read = SEgetData(&conn, buf, sizeof(buf) - 1);  
      if(bytes_read == SEDNA_ERROR)  
        return handle_error(&conn, "Getting item", 1);  
      buf[bytes_read] = ’\0’;  
      printf("%s\n", buf);  
    } while(bytes_read > 0);  
  }  
 
  /* Drop document "region" */  
  res = SEexecute(&conn, "DROP DOCUMENT ’region’");  
  if(res != SEDNA_UPDATE_SUCCEEDED)  
    return handle_error(&conn, "Drop document", 1);  
 
  /* Commit transaction */  
  res = SEcommit(&conn);  
  if(res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)  
    return handle_error(&conn, "Commit", 1);  
 
  /* Close connection */  
  res = SEclose(&conn);  
  if(res != SEDNA_SESSION_CLOSED)  
    return handle_error(&conn, "Close", 0);  
 
  return 0;  
}

The full version of this example program can be found in:

[win:] INSTALL_DIR\examples\api\c\Client.c  
[nix:] INSTALL_DIR/examples/api/c/Client.c

Here INSTALL_DIR refers to the directory where Sedna is installed.

Before running the example make sure that the Sedna DBMS is installed and do the following steps:

  1. Start Sedna by running the following command:
    se_gov

    If Sedna is started successfully it prints ”GOVERNOR has been started in the background mode”.

  2. Create a new database testdb by running the following command:
    se_cdb testdb

    If the database is created successfully it prints ”The database ’testdb’ has been created successfully”.

  3. Start the testdb database by running the following command:
    se_sm testdb

    If the database is started successfully it prints ”SM has been started in the background mode”.

You can compile and run the example by following the steps listed below:

  1. To compile the example use:
        [win:] Clientbuild.bat  
        [nix:] ./Clientbuild.sh

    located in the same folder as Client.c.

  2. To run the compiled example use:
        [win:] Client.exe  
        [nix:] ./Client

    located in the same folder as Client.c.