sqlFragments = PlaceholderParser.parsePlaceholder(databaseStreamSpec.getSqlWithSubsParams());
}
catch (PlaceholderParseException ex)
{
String text = "Error parsing SQL";
throw new ExprValidationException(text + ", reason: " + ex.getMessage());
}
// Assemble a PreparedStatement and parameter list
String preparedStatementText = createPreparedStatement(sqlFragments);
SQLParameterDesc parameterDesc = getParameters(sqlFragments);
if (log.isDebugEnabled())
{
log.debug(".createDBEventStream preparedStatementText=" + preparedStatementText +
" parameterDesc=" + parameterDesc);
}
// Get a database connection
String databaseName = databaseStreamSpec.getDatabaseName();
DatabaseConnectionFactory databaseConnectionFactory;
ColumnSettings metadataSetting;
try
{
databaseConnectionFactory = databaseConfigService.getConnectionFactory(databaseName);
metadataSetting = databaseConfigService.getQuerySetting(databaseName);
}
catch (DatabaseConfigException ex)
{
String text = "Error connecting to database '" + databaseName + '\'';
log.error(text, ex);
throw new ExprValidationException(text + ", reason: " + ex.getMessage());
}
Connection connection;
try
{
connection = databaseConnectionFactory.getConnection();
}
catch (DatabaseConfigException ex)
{
String text = "Error connecting to database '" + databaseName + '\'';
log.error(text, ex);
throw new ExprValidationException(text + ", reason: " + ex.getMessage());
}
// On default setting, if we detect Oracle in the connection then don't query metadata from prepared statement
ConfigurationDBRef.MetadataOriginEnum metaOriginPolicy = metadataSetting.getMetadataRetrievalEnum();
if (metaOriginPolicy == ConfigurationDBRef.MetadataOriginEnum.DEFAULT)
{
String connectionClass = connection.getClass().getName();
if ((connectionClass.toLowerCase().contains("oracle") || (connectionClass.toLowerCase().contains("timesten"))))
{
// switch to sample statement if we are dealing with an oracle connection
metaOriginPolicy = ConfigurationDBRef.MetadataOriginEnum.SAMPLE;
}
}
QueryMetaData queryMetaData;
try
{
if ((metaOriginPolicy == ConfigurationDBRef.MetadataOriginEnum.METADATA) || (metaOriginPolicy == ConfigurationDBRef.MetadataOriginEnum.DEFAULT))
{
queryMetaData = getPreparedStmtMetadata(connection, parameterDesc.getParameters(), preparedStatementText, metadataSetting);
}
else
{
String sampleSQL;
boolean isGivenMetadataSQL = true;
if (databaseStreamSpec.getMetadataSQL() != null)
{
sampleSQL = databaseStreamSpec.getMetadataSQL();
isGivenMetadataSQL = true;
if (log.isInfoEnabled())
{
log.info(".createDBStatementView Using provided sample SQL '" + sampleSQL + "'");
}
}
else
{
// Create the sample SQL by replacing placeholders with null and
// SAMPLE_WHERECLAUSE_PLACEHOLDER with a "where 1=0" clause
sampleSQL = createSamplePlaceholderStatement(sqlFragments);
if (log.isInfoEnabled())
{
log.info(".createDBStatementView Using un-lexed sample SQL '" + sampleSQL + "'");
}
// If there is no SAMPLE_WHERECLAUSE_PLACEHOLDER, lexical analyse the SQL
// adding a "where 1=0" clause.
if (parameterDesc.getBuiltinIdentifiers().length != 1)
{
sampleSQL = lexSampleSQL(sampleSQL);
if (log.isInfoEnabled())
{
log.info(".createDBStatementView Using lexed sample SQL '" + sampleSQL + "'");
}
}
}
// finally get the metadata by firing the sample SQL
queryMetaData = getExampleQueryMetaData(connection, parameterDesc.getParameters(), sampleSQL, metadataSetting, isGivenMetadataSQL);
}
}
catch (ExprValidationException ex)
{
try
{
connection.close();
}
catch (SQLException e)
{
// don't handle
}
throw ex;
}
// Close connection
try
{
connection.close();
}
catch (SQLException e)
{
String text = "Error closing connection";
log.error(text, e);
throw new ExprValidationException(text + ", reason: " + e.getMessage());
}
// Create event type
// Construct an event type from SQL query result metadata
Map<String, Object> eventTypeFields = new HashMap<String, Object>();
int columnNum = 1;
for (Map.Entry<String, DBOutputTypeDesc> entry : queryMetaData.getOutputParameters().entrySet())
{
String name = entry.getKey();
DBOutputTypeDesc dbOutputDesc = entry.getValue();
Class clazz;
if (dbOutputDesc.getOptionalBinding() != null)
{
clazz = dbOutputDesc.getOptionalBinding().getType();
}
else
{
clazz = SQLTypeMapUtil.sqlTypeToClass(dbOutputDesc.getSqlType(), dbOutputDesc.getClassName());
}
if (columnTypeConversionHook != null) {
Class newValue = columnTypeConversionHook.getColumnType(new SQLColumnTypeContext(databaseStreamSpec.getDatabaseName(), databaseStreamSpec.getSqlWithSubsParams(), name, clazz, dbOutputDesc.getSqlType(), columnNum));
if (newValue != null) {
clazz = newValue;
}
}
eventTypeFields.put(name, clazz);
columnNum++;
}
EventType eventType;
if (outputRowConversionHook == null) {
eventType = eventAdapterService.createAnonymousMapType(eventTypeFields);
}
else {
Class carrierClass = outputRowConversionHook.getOutputRowType(new SQLOutputRowTypeContext(databaseStreamSpec.getDatabaseName(), databaseStreamSpec.getSqlWithSubsParams(), eventTypeFields));
if (carrierClass == null) {
throw new ExprValidationException("Output row conversion hook returned no type");
}
eventType = eventAdapterService.addBeanType(carrierClass.getName(), carrierClass, false, false, false);
}
// Get a proper connection and data cache
ConnectionCache connectionCache;
DataCache dataCache;
try
{
connectionCache = databaseConfigService.getConnectionCache(databaseName, preparedStatementText);
dataCache = databaseConfigService.getDataCache(databaseName, epStatementHandle);
}
catch (DatabaseConfigException e)
{
String text = "Error obtaining cache configuration";
log.error(text, e);
throw new ExprValidationException(text + ", reason: " + e.getMessage());
}
PollExecStrategyDBQuery dbPollStrategy = new PollExecStrategyDBQuery(eventAdapterService,
eventType, connectionCache, preparedStatementText, queryMetaData.getOutputParameters(), columnTypeConversionHook, outputRowConversionHook, enableJDBCLogging);