JDBC Adapter

JDBC Adapter

Functionality

The JDBC adapter allows TrustBuilder to send SQL-statements to a database.

Prerequisites

JNDI The database identification relies on data sources retrieved by means of the Java Naming and Directory Interface (JNDI). Data sources may be configured in an application server, and can include information such as database reference, user name and password. For standalone use, including unit tests, data sources may be created programmatically and bound to the proper JNDI names before running the application. In addition to these basic properties, other, non-functional properties may typically be configured on an application server, like the connection pool size and the size of the SQL statement cache.

Configuration

AdapterUniqueID

Unique name assigned to this adapter; the name is used to reference the adapter in the workflow. The ID has following requirements:

  • START with a letter or _ (underscore)
  • FOLLOWED by a combination of following characters: Letter, Number, '.' (dot), '-' (dash), '_' (underscore)

Unsupported Features
Not every database driver supports all the features provided by the JDBC interface. The UnsupportedFeatures parameter actually accepts a comma-separated list of options to be ignored. Specifying an unknown feature will result in a configuration error.

  • QueryTimeout: In particular, setting the query timeout in requests (either explicitly or by default) may fail. Hence this option may be disabled globally as follows. If this option is omitted, query timeouts will be set by default (either limited or unlimited as described in the query specification).

DataSource
The data source field must represent a valid JNDI name identifying a data source. Failure to do so will lead to a fatal error during engine configuration.

DataSource URL The data source can also be a JDNI url.

jdbc:postgresql://localhost/dbname 

Setting the username and password will encrypt the user password in the config file. This way you can avoid exposing the password in your application server context files.

Workflow Settings

A request for the adapter is prepared by specifying the following properties/scripts in the adapter activity:

  • Input Property: the variable containing the instructions the adapter have to execute
  • Output Property: the variable the adapter will store the response in after execution
  • Before Adapter Script: script that will be executed before calling the adapter
  • After Adapter Script: script that will be executed after the adapter fulfilled its task

Request - API

jdbcSelectRequest Creates a JDBC SELECT-request:

jdbcSelectRequest(SQL SELECT statement, SQL arguments) 

Where:

  • SQL SELECT statement: Non-null, non-empty string, can contain questionmarks that will be replaced by the SQL arguments
  • SQL arguments: Allow the use of variables in the SQL Select Statement

Example:

jdbcSelectRequest("SELECT * FROM Emp WHERE employee_id = ?", employeeId) 

jdbcUpdateRequest (aliases jdbcInsertRequest and jdbcDeleteRequest) Creates a JDBC request with zero or more updates:

jdbcUpdateRequest(SQL UPDATE statement, SQL arguments) 

Where:

  • SQL SELECT statement: Non-null, non-empty string, can contain question marks that will be replaced by the SQL arguments
  • SQL arguments:Allow the use of bind variables in the SQL Select Statement

Example:

jdbcUpdateRequest("DELETE * FROM Emp WHERE employee_id = ?",employeeId) 

jdbcQuery Create a JDBC query if multiple queries are required in batch / transaction (see jdbcMultiUpdateRequest)

jdbcQuery(SQL statement, SQL arguments) 

Where:

  • SQL SELECT statement: Non-null, non-empty string, can contain questionmarks that will be replaced by the SQL arguments
  • SQL arguments:Allow the use of bind variables in the SQL Select Statement

Example:

var query1 = jdbcQuery("INSERT INTO Dept VALUES(?)",name);
var query2 = jdbcQuery("INSERT INTO Emp VALUES(?, ?, ?)",name, email ,employeeId);

jdbcMultiUpdateRequest

Create a JDBC request with one or more jdbcQuery objects.

jdbcMultiUpdateRequest([query1,query2]) 

Where:

  • queries to execute: queries to be executed in the same transaction, seperated with a comma

Example:

var q1 = tb.jdbcQuery("UPDATE PERSON set name = ? WHERE NAME = ?",'SMITH','SMITH2');
// Do the same query but with different parameters
q1.addParametersToBatch('John','John2');

var q2 = tb.jdbcQuery("DELETE * FROM PERSON WHERE NAME = ?",'SMITH');

var update = tb.jdbcMultiUpdateRequest([q1,q2]);
update.setAutoCommit(true)
update.setQueryTimeout(5);

Response - API

Common Properties The response API can be applied to the variable specified in the "output property" (see "Workflow Settings"): to verify whether the action performed by the adapter was successful, to query for the data returned by the adapter.

All responses have four properties in common:

  • status Status flag indicating whether the response is ok (0) or not (1).
  • substatus Response specific number indicating what the problem was, eg. http status code
  • message Response specific message in case there was a problem (can be null)
  • rc Return Code, a human readable code based on the substatus

The status flag indicates whether a request was valid yes or no; consequently, the message or return code (rc) can be used to give the end-user a reasonable explanation or send the information to the underlying logging system.

Adapter Specific Properties

size Number of rows being returned
getRows() Returns 2 dimensional array with the results
getRow(rowno) Returns array with the result of row number (rowno)
getItemAsDate(rowitem) Returns item from database as javascript Date

Note: since all items are rendered in javascript as strings, blob are rendered in their hex notation, date/time objects are rendered as "yyyy-MM-dd HH:mm:ss.S" where either date or time can be missing depending of the database type.

Response Codes

Status Substatus Description
0 0 OK
>0 1 SQL Error
>1 Unknown error

Additional Notes

Load Balancing The adapter does not support load balancing.

Request - API

The following parameters can be given along:

  • setAutoCommit: indicates whether transactions will be committed implicitly (yes) or in non-autocommit mode (no). Default behavior: autocommit.
  • setQueryTimeout: timeout in seconds
  • setMaxRows: maximum results that will be returned

Working with dates

Converting a database timestamp can be done with the following javascript function

//date = timestamp received from database e.g: 2013-09-13 12:49:42.837
function parseDatabaseDate(date){
    var parts = date.split(' '),
        dt = parts[0].split('-'),
        ts = parts[1].split(':'),
        sms = ts[2].split('.');
    return new Date(dt[0],dt[1],dt[2],ts[0],ts[1],sms[0],sms[1]);
}

//converting to epoch
//select datefield from table where id='id'
var dbDate = workItem.databaseOutput.getRow(0)[0];
var myDate = parseDatabaseDate(dbDate);
var epochDate = myDate.getTime();

Example

Example 1 - jdbcSelectRequest

Request

function JDBCSelectEmployee(workItem){
   var employeeId = workItem.employeeId;
   var sql="SELECT * FROM Emp WHERE employee_id = ?";
   // We need to prepare the input of the adapter, this is stored in the workItem
   workItem.jdbcInput = tb.jdbcSelectRequest(sql,employeeId); 

   // Maximum returned results
   workItem.jdbcInput.setMaxRows(10);
   // Timeout in seconds
   workItem.jdbcInput.setQueryTimeout(5);
}

Response

var getUsersQueryResponse = workItem.jdbcGetUsersQueryResponse;
//setting errormessage and code in the workItem
workItem.code = getUsersQueryResponse.rc;
workItem.message = getUsersQueryResponse.message;

if(getUsersQueryResponse.status == 0){      
    for(var i = 0;i<getUsersQueryResponse.size;i++){
         if(getUsersQueryResponse.getRow(i) != null){
            var rowOut = getUsersQueryResponse.getRow(i);
            tb.log('Row '+i+' = '+rowOut);  
         }
     }
 }

Example 2 - jdbcUpdateRequest

Request

function JDBCDeleteEmployee(workItem){
  var employeeId = workIem.employeeId;
  workItem.jdbcInput = tb.jdbcUpdateRequest("DELETE * FROM Emp WHERE employee_id = ?",employeeId); //Remove an employee with prepared statements
  workItem.jdbcInput.setAutoCommit(true); // We want this done directly, not in an transaction
  workItem.jdbcInput.setQueryTimeout(5); // Set the timeout of the query 
}

Response

if(jdbcOutput.status == 0){     
    tb.log('Delete successful');
}

Example 3 - jdbcMultiUpdateRequest

Request

function JDBCMultiUpdateEmployee(workItem){
    var employeeId = workIem.employeeId;
    var name = workItem.name;
    var email = workItem.email;
    var q1 = tb.jdbcQuery("INSERT INTO Emp VALUES(?, ?, ? )",name, email ,employeeId );
    q1.addParametersToBatch('smith','jsmit@acme.org','44344'); // Add a new query with different parameters
    var q2 = tb.jdbcQuery("DELETE * FROM Emp WHERE NAME = ?",name); // Remove the added employee

    var update = tb.jdbcMultiUpdateRequest([q1,q2]); // This will run the query
    update.setAutoCommit(true)
    update.setQueryTimeout(5);
}

Response

if(jdbcOutput.status == 0){     
    tb.log('insert / Delete successful');
}

Tomcat datasource examples

To use the JDBC adapter in your tomcat installation you must set the resources. Adjust your Trustbuilder context xml file for the resource and your environment.

Postgres

tb.xml
<Resource name="jdbc/auth" auth="Container" type="javax.sql.DataSource"
       username="authuserr"
       password="*******"
       driverClassName="org.postgresql.Driver"
       url="jdbc:postgresql://localhost:5432/auth"
       maxActive="20"
       maxIdle="10"
       validationQuery="select 1" />

Microsoft SQL

tb.xml
<Resource name="jdbc/auth" auth="Container" type="javax.sql.DataSource"
     username="Trustbuilderuser"
     password="password"
     driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
     url="jdbc:sqlserver://SQLTWA\VLB;DatabaseName=Trustbuilder" />

Add the jdbc adapter in your config.xml with the correct datasource

<stb:Adapter stb:id="auth" xsi:type="stb:JdbcAdapter">
    <stb:DataSource>java:comp/env/jdbc/auth</stb:DataSource>
</stb:Adapter>
Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

0 comments

Please sign in to leave a comment.