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 under 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.

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

This function opens a session to the database, using the following 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.

login - user name.

password - user password.

SEconnect returns:

positive values:

SEDNA_SESSION_OPEN - connection to the database is established, authentication is passed successfully, and session is opened.

negative values:

SEDNA_AUTHENTICATION_FAILED - authentication was not passed, session is not open.

SEDNA_OPEN_SESSION_FAILED - failed to open session.

SEDNA_ERROR - some error is occurred, session is not open.

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 finishes its work with the database, it must close the session. SEclose finishes the session and closes the connection to the server. SEclose also frees resourses 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.

SEclose returns:

positive value:

SEDNA_SESSION_CLOSED - session is closed succeffully.

negative values:

SEDNA_CLOSE_SESSION_FAILED - session was closed with errors.

SEDNA_ERROR - some error occurred.

1.2.2 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 predifined 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.

SEsetConnectionAttr returns:

positive value:

SEDNA_SET_ATTRIBUTE_SUCCEEDED - the attribute was set successfully.

negative value:

SEDNA_ERROR - some error occurred.





Attribute AttributeV alueAttributeV alueLength



SEDNA_ATTR_AUTOCOMMIT SEDNA_AUTOCOMMIT_ON, sizeof(int)
SEDNA_AUTOCOMMIT_OFF



SEDNA_ATTR_SESSION_DIRECTORY path to directory length of path



SEDNA_ATTR_DEBUG SEDNA_DEBUG_ON, sizeof(int)
SEDNA_DEBUG_OFF



SEDNA_ATTR_CONCURRENCY_TYPESEDNA_READONLY_TRANSACTION, sizeof(int)
SEDNA_UPDATE_TRANSACTION



SEDNA_ATTR_QUERY_EXEC_TIMEOUT time in seconds sizeof(int)



SEDNA_ATTR_MAX_RESULT_SIZE size in bytes sizeof(int)



SEDNA_LOG_AMMOUNT SEDNA_LOG_LESS, sizeof(int)
SEDNA_LOG_FULL




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

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

The 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.

The 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 there is no any timeout for query execution, that is a query can be executed as long as needed.

The 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 reponse to user query can be of unlimited size.

The SEDNA_LOG_AMMOUNT connection attribute changes the mode of logical logging of the next transactions. Transaction can be set to run in full log mode (SEDNA_LOG_FULL) or reduced log mode (SEDNA_LOG_LESS). The latter means transaction will be writing much less log info during bulk loads. However this comes with penalty of longer commits. You should not use this option for transactions without bulk loads since it would not have any effect. Notice that the current transaction, if any, will be forcefully committed. The default is SEDNA_LOG_FULL.

An application can get 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.

SEgetConnectionAttr returns:

positive value:

SEDNA_GET_ATTRIBUTE_SUCCEEDED - the attribute was retrieved successfully.

negative value:

SEDNA_ERROR - some error occurred.

To reset all connection attributes to their 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.

SEresetAllConnectionAttr returns:

positive value:

SEDNA_RESET_ATTRIBUTES_SUCCEEDED - attributes has been reset successfully.

negative value:

SEDNA_ERROR - some error occurred.

1.2.3 Transactions

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 applcation can switch between the two modes using SEsetConnectionAttr and SEgetConnectionAttr functions for SEDNA_ATTR_AUTOCOMMIT attribute

To specify transaction boundaries application uses SEbegin, SEcommit SErollback functions:

int SEbegin(SednaConnection* conn)

parameters:

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

SEbegin returns:

positive value:

SEDNA_BEGIN_TRANSACTION_SUCCEEDED - transaction is begun.

negative value:

SEDNA_BEGIN_TRANSACTION_FAILED - failed to begin a transaction.

SEDNA_ERROR - some error occurred.

int SEcommit(SednaConnection* conn)

parameters:

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

SEcommit returns:

positive value:

SEDNA_COMMIT_TRANSACTION_SUCCEEDED - transaction is committed.

negative value:

SEDNA_COMMIT_TRANSACTION_FAILED - failed to commit transaction.

SEDNA_ERROR - some error occurred.

int SErollback(SednaCommection* conn)

parameters:

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

SErollback returns:

positive value:

SEDNA_ROLLBACK_TRANSACTION_SUCCEEDED - rollback transaction succeeded.

negative value:

SEDNA_ROLLBACK_TRANSACTION_FAILED - failed to rollback transaction.

SEDNA_ERROR - some error occurred.

1.2.4 Getting connection and transaction status

An application can know the connection status by calling to SEconnectionStatus function:

int SEconnectionStatus(SednaConnection* conn)

parameters:

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

returns:

positive 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.

negative values:

SEDNA_CONNECTION_FAILED - specified connection has failed. (Note: in this case you should call SEclose function as it releases resources.)

An application can know the transaction status by calling to SEtransactionStatus function:

int SEtransactionStatus(SednaConnection* conn)

parameters:

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

returns:

positive 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 been begun yet.

1.2.5 Executing Queries and Updates and Retrieving Result Data

There are two functions to execute a statement (query or update): SEexecute function and SEexecuteLong function.

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 query or XUpdate update statement.

returns:

positive values:

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- see Section 2) succeeded.

negative values:

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 query to execute.

returns:

positive values:

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- see Section 2) succeeded.

negative values:

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 returns 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 current item of the sequence.

int SEnext(SednaConnection* conn)

parameters:

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

returns:

positive values:

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

negative values:

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.

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.

returns:

positive values:

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)

negative values:

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

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 put the debug information to stdout.

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

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

1.2.6 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 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 XML document.

bytes_to_load - number of bytes to load.

doc_name - name of the document in 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.

returns:

positive values:

SEDNA_DATA_CHUNK_LOADED - chunk of XML document was loaded.

negative values:

SEDNA_ERROR - some error occurred. Data were not loaded.

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

int SEendLoadData(SednaConnection* conn)

parameters:

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

returns:

positive values:

SEDNA_BULK_LOAD_SUCCEEDED - XML document was successfully loaded into the database.

negative values:

SEDNA_BULK_LOAD_FAILED - Failed to load XML document into the database.

SEDNA_ERROR - some error occurred.

1.2.7 Error Handling

If the function returns negative value, application can get the error message and code.

To get last error message use:

SEgetLastErrorMsg function:

char* SEgetLastErrorMsg(SednaConnection* conn)

parameters:

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

The function returns the information about the last error occurred in this session.

To get last error code use:

SEgetLastErrorCode function:

int SEgetLastErrorCode(struct SednaConnection *conn)

parameters:

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

The function returns the code of a last error occurred in this session.

1.2.8 Example Code
#include "libsedna.h"  
#include <stdio.h>  
 
int main()  
{  
    struct SednaConnection conn = SEDNA_CONNECTION_INITIALIZER;  
    int bytes_read, res, value;  
    char buf[1024];  
 
    const char* url = "localhost";  
    const char* db_name = "testdb";  
    const char* login = "SYSTEM";  
    const char* password = "MANAGER";  
 
    printf("Client started.\n");  
 
    value = SEDNA_AUTOCOMMIT_OFF;  
    res = SEsetConnectionAttr(&conn, SEDNA_ATTR_AUTOCOMMIT, (void*)&value, sizeof(int));  
 
    //connecting to database "testdb" with login "SYSTEM", password "MANAGER"  
    res = SEconnect(&conn, url, db_name, login, password);  
    if(res != SEDNA_SESSION_OPEN)  
    {  
        printf("Session starting failed: \n%s\n", SEgetLastErrorMsg(&conn));  
        return -1;  
    }  
 
    //begin transaction  
    res = SEbegin(&conn);  
    if(res != SEDNA_BEGIN_TRANSACTION_SUCCEEDED)  
    {  
        printf("Begin transaction failed: \n%s\n", SEgetLastErrorMsg(&conn));  
        //closing session  
        SEclose(&conn);  
        return -1;  
    }  
 
    // load data from file "region.xml" into the document "region"  
    res = SEexecute(&conn, "LOAD \"region.xml\" \"region\"");  
    if(res != SEDNA_BULK_LOAD_SUCCEEDED)  
    {  
        printf("Bulk load failed: \n%s\n", SEgetLastErrorMsg(&conn));  
        // closing session  
        SEclose(&conn);  
        return -1;  
    }  
 
    // execute XQuery query  
    res = SEexecute(&conn, "document(\"region\")/*/*");  
    if(res != SEDNA_QUERY_SUCCEEDED)  
    {  
        printf("Query failed: \n%s\n", SEgetLastErrorMsg(&conn));  
        //closing session  
        SEclose(&conn);  
        return -1;  
    }  
 
    // iterate over the result sequence and retrieve the result data  
    while((res = SEnext(&conn)) != SEDNA_RESULT_END)  
    {  
        if (res == SEDNA_ERROR)  
        {  
            printf("Failed to get next result item from server: \n%s\n",  
                    SEgetLastErrorMsg(&conn));  
            //closing session  
            SEclose(&conn);  
            return -1;  
        }  
 
        printf("\nresult item:\n");  
        do  
        {  
            bytes_read = SEgetData(&conn, buf, 1024 - 1);  
            if(bytes_read == SEDNA_ERROR)  
            {  
                printf("Failed to get result data from server: \n%s\n",  
                        SEgetLastErrorMsg(&conn));  
                //closing session  
                SEclose(&conn);  
                return -1;  
            }  
            buf[bytes_read] = ’\0’;  
          printf("%s", buf);  
 
        }while(bytes_read > 0);  
     printf("\n");  
    }  
 
    // Drop document "region"  
    res = SEexecute(&conn, "DROP DOCUMENT \"region\"");  
    if(res != SEDNA_UPDATE_SUCCEEDED)  
    {  
        printf("Drop document failed: \n%s\n", SEgetLastErrorMsg(&conn));  
        // closing session  
        SEclose(&conn);  
        return -1;  
    }  
 
    //commiting transaction  
    res = SEcommit(&conn);  
    if(res != SEDNA_COMMIT_TRANSACTION_SUCCEEDED)  
    {  
        printf("Commit transaction failed: \n%s\n",  
                SEgetLastErrorMsg(&conn));  
        //closing session  
        SEclose(&conn);  
        return -1;  
    }  
 
    //closing session  
    res = SEclose(&conn);  
    if(res != SEDNA_SESSION_CLOSED)  
    {  
        printf("An error occured while trying to close session: \n%s\n",  
                SEgetLastErrorMsg(&conn));  
        return -1;  
    }  
 
    return 0;  
}

The source code of this example program can be found in

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

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

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 runing 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. In the file Client.c, the url parameter specifies the name of the computer where the server is running. If Sedna DBMS is not running on the same computer edit the file Client.c to set the value of the url parameter. This looks as something like the following:
    const char* url = "computer-name";

    if Sedna DBMS is running on the same computer you do not need to edit this parameter.

  2. To compile the example use
    [win:] Clientbuild.bat

    [nix:] Clientbuild.sh

    located in the same folder as Client.c.

  3. To run the compiled example use
    [win:] Client.exe

    [nix:] Client

    located in the same folder as Client.c.