![]() |
Qorus Integration Engine® Enterprise Edition 6.0.27_prod
|
Back to the Developer's Guide Table of Contents
To work with a database, a datasource must be defined and known by the system.
For example, to acquire a shared DatasourcePool object for transaction management on the "billing"
datasource, use the UserApi::getDatasourcePool() method as in the following example:
If Qore user code enters a transaction with either Datasource or DatasourcePool objects and the thread is terminated (such as a workflow step or even a service call called from the network API) without closing the transaction, an exception will automatically be raised and the transaction will be rolled back.
To work with DB table data in a programmatic way, Qorus provides APIs that enable easy access to AbstractTable objects from the SqlUtil module, if the database driver is supported by SqlUtil.
The best API to use for working with DB table data is he DataProvider API, which provides generic APIs for working with enterprise integration patterns including with record-based DataProviders such as DB tables.
The following is an example of executing a stored procedure on an Oracle database and retrieving the results:
The following is an example of executing a function in an Oracle database and retrieving the result (note that you have to declare the variable type in the SQL):
The Qore Oracle driver needs to know the buffer type for all placeholder bind operations in advance. The placeholders can be found in the SQL strings in the two examples above as the text prefixed by ":". When no buffer type is given, the Oracle driver assumes a string buffer. To declare another buffer type, use the Qore Type constants as arguments in the position corresponding to the placeholder position in the SQL string.
For example, here is an example similar to the first example above using different buffer types for the return values:
Note that the MySQL, PostgreSQL, Sybase, and FreeTDS drivers do not require placeholder buffer specifications when executing stored procedures. For more examples of stored procedure calls and more information about connecting to other databases, see the Qore Programming Language Reference Manual.
The data streaming APIs provide high-level interfaces for the DataStream Protocol without need of the low level protocol interaction. DataStream socket I/O always takes place in a background thread, which allows the main thread to handle data operations in parallel with network I/O.
Streaming APIs are available for Qorus server objects (workflows, services, jobs) and also in the Qorus client.
The following classes provide APIs to stream data to/from remote Qorus instances:
Key | Default | Description |
block | 1000 (DB rows) or 16384 (FS bytes) | a block size for DataStream transmission chunks giving the row count for DB streams or the bytes count for filesystem streams |
encoding | "UTF-8" | the encoding of the target file; used in OMQ::FsRemoteSend |
loglevel | LL_INFO | the default logging level used in Qorus user code |
mode | 0644 | the file's creation mode as used in Qore::File::open2(); used in OMQ::FsRemoteSend |
queue_block_size | 2 | the number of blocks to queue for sending before the main data thread will block; used in OMQ::DbRemoteSend and OMQ::FsRemoteSend |
queue_size | block * 2 | the number of rows to queue before the main data thread will block; used in OMQ::DbRemoteReceive |
select | NOTHING | Complex Select Criteria structure used in OMQ::DbRemoteReceive |
timeout | 60s | a timeout in milliseconds for HTTP operations (ex: 120s ) |
A remote transaction can be performed in an external DB connected to a remote Qorus instance by using the system.sqlutil service to begin the transaction and then commit or abort it.
The OMQ::DbRemoteSend and OMQ::DbRemote classes will automatically start or continue a remote transaction by sending the "Qorus-Connection: Continue-Persistent"
header when opening the stream. The OMQ::DbRemoteReceive class will do the same if the "transaction"
option is set in the constructor() call.
Additionally, a call to OMQ::AbstractParallelStream::beginTransaction() can be made to explicitly start or continue a remote transaction in a remote database independently of any remote stream operations.
Remote transactions must be explicitly committed with a call to the sqlutil commit stream or to OMQ::DbRemoteSend::commit() or OMQ::DbRemoteReceive::commit() or OMQ::DbRemote::commit()
To abort a remote transaction, it's recommended to simply close the socket connection, particuarly because the HTTP connection could be in the middle of a stream action which would make HTTP messages impossible to send until the stream is completely sent or received. When the connection is closed, any streams in progress are immediately terminated and the remote transaction is automatically rolled back.