|
| Home | Getting Started | Documentation | Demo | Download | Support |
1.2 C APIlibsedna 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.2.1 Connecting to a Database
1.2.2 Setting session options 1.2.3 Transactions 1.2.4 Getting connection and transaction status 1.2.5 Executing Queries and Updates and Retrieving Result Data 1.2.6 Loading Data 1.2.7 Error Handling 1.2.8 Example Code 1.2.1 Connecting to a DatabaseBefore 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 optionsAn 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.
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 TransactionsAn 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:
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 statusAn 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 DataThere 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 DataXML 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 HandlingIf 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:
You can compile and run the example by following the steps listed below:
|