/// <summary> /// Make a new pair of resources. /// </summary> /// <returns>pair of resources</returns> protected Pair<DbDriver, DbDriverCommand> MakeNew() { Log.Info(".MakeNew Obtaining new connection and statement"); try { // Get the driver DbDriver dbDriver = _databaseConnectionFactory.Driver; // Get the command DbDriverCommand dbCommand = dbDriver.CreateCommand(_sqlFragments, null, _contextAttributes); return new Pair<DbDriver, DbDriverCommand>(dbDriver, dbCommand); } catch (DatabaseConfigException ex) { throw new EPException("Error obtaining connection", ex); } }
/// <summary> /// Gets the query meta data. /// </summary> /// <param name="databaseStreamSpec">The database stream spec.</param> /// <param name="databaseConfigService">The database config service.</param> /// <param name="dbCommand">The database command.</param> /// <param name="contextAttributes">The context attributes.</param> /// <returns></returns> private static QueryMetaData GetQueryMetaData( DBStatementStreamSpec databaseStreamSpec, DatabaseConfigService databaseConfigService, DbDriverCommand dbCommand, IEnumerable <Attribute> contextAttributes) { // Get a database connection var databaseName = databaseStreamSpec.DatabaseName; //DatabaseConnectionFactory databaseConnectionFactory = GetDatabaseConnectionFactory(databaseConfigService, databaseName); var metadataSetting = dbCommand.MetaDataSettings; QueryMetaData queryMetaData; try { // On default setting, if we detect Oracle in the connection then don't query metadata from prepared statement var metaOriginPolicy = metadataSetting.MetadataRetrievalEnum; if (metaOriginPolicy == ConfigurationDBRef.MetadataOriginEnum.DEFAULT) { // Ask the driver how it interprets the default meta origin policy; the // esper code has a specific hook for Oracle. We have moved this into // the driver to avoid specifically coding behavior to a driver. metaOriginPolicy = dbCommand.Driver.DefaultMetaOriginPolicy; } switch (metaOriginPolicy) { case ConfigurationDBRef.MetadataOriginEnum.METADATA: case ConfigurationDBRef.MetadataOriginEnum.DEFAULT: queryMetaData = dbCommand.MetaData; break; case ConfigurationDBRef.MetadataOriginEnum.SAMPLE: { var parameterDesc = dbCommand.ParameterDescription; String sampleSQL; if (databaseStreamSpec.MetadataSQL != null) { sampleSQL = databaseStreamSpec.MetadataSQL; if (Log.IsInfoEnabled) { Log.Info(".GetQueryMetaData 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(dbCommand.Fragments); if (Log.IsInfoEnabled) { Log.Info(".GetQueryMetaData 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.BuiltinIdentifiers.Count != 1) { sampleSQL = LexSampleSQL(sampleSQL); if (Log.IsInfoEnabled) { Log.Info(".GetQueryMetaData Using lexed sample SQL '" + sampleSQL + "'"); } } } // finally get the metadata by firing the sample SQL queryMetaData = GetExampleQueryMetaData( dbCommand.Driver, sampleSQL, metadataSetting, contextAttributes); } break; default: throw new ArgumentException( "MetaOriginPolicy contained an unhandled value: #" + metaOriginPolicy); } } catch (DatabaseConfigException ex) { var text = "Error connecting to database '" + databaseName + '\''; Log.Error(text, ex); throw new ExprValidationException(text + ", reason: " + ex.Message, ex); } return(queryMetaData); }
private IList<EventBean> Execute( DbDriverCommand driverCommand, object lookupValuePerStream) { var hasLogging = _factory.IsEnableLogging && ADO_PERF_LOG.IsInfoEnabled; using (var myDriverCommand = driverCommand.Clone()) { var dbCommand = myDriverCommand.Command; if (ExecutionPathDebugLog.IsDebugEnabled && Log.IsInfoEnabled) { Log.Info(".execute Executing prepared statement '{0}'", dbCommand.CommandText); } DbParameter dbParam; // set parameters SQLInputParameterContext inputParameterContext = null; if (_columnTypeConversionHook != null) { inputParameterContext = new SQLInputParameterContext(); } var mk = _factory.InputParameters.Length == 1 ? null : (HashableMultiKey) lookupValuePerStream; for (var i = 0; i < _factory.InputParameters.Length; i++) { try { object parameter; if (mk == null) { parameter = lookupValuePerStream; } else { parameter = mk.Keys[i]; } if (ExecutionPathDebugLog.IsDebugEnabled && Log.IsInfoEnabled) { Log.Info( ".Execute Setting parameter " + " to " + parameter + " typed " + ((parameter == null) ? "null" : parameter.GetType().Name)); } if (_columnTypeConversionHook != null) { inputParameterContext.ParameterNumber = i + 1; inputParameterContext.ParameterValue = parameter; parameter = _columnTypeConversionHook.GetParameterValue(inputParameterContext); } dbParam = dbCommand.Parameters[i]; dbParam.Value = parameter ?? DBNull.Value; } catch (DbException ex) { throw new EPException("Error setting parameter " + i, ex); } } // execute try { // generate events for result set IList<EventBean> rows = new List<EventBean>(); using (var dataReader = dbCommand.ExecuteReader()) { try { SQLColumnValueContext valueContext = null; if (_columnTypeConversionHook != null) { valueContext = new SQLColumnValueContext(); } SQLOutputRowValueContext rowContext = null; if (_outputRowConversionHook != null) { rowContext = new SQLOutputRowValueContext(); } var rowNum = 0; if (dataReader.HasRows) { // Determine how many fields we will be receiving var fieldCount = dataReader.FieldCount; // Allocate a buffer to hold the results of the row var rawData = new object[fieldCount]; // Convert the names of columns into ordinal indices and prepare // them so that we only have to incur this cost when we first notice // the reader has rows. if (_dbInfoList == null) { _dbInfoList = new List<DbInfo>(); foreach (var entry in _outputTypes) { var dbInfo = new DbInfo(); dbInfo.Name = entry.Key; dbInfo.Ordinal = dataReader.GetOrdinal(dbInfo.Name); dbInfo.OutputTypeDesc = entry.Value; dbInfo.Binding = entry.Value.OptionalBinding; _dbInfoList.Add(dbInfo); } } var fieldNames = new string[fieldCount]; for (var ii = 0; ii < fieldCount; ii++) { fieldNames[ii] = dataReader.GetName(ii); } // Anyone know if the ordinal will always be the same every time // the query is executed; if so, we could certainly cache this // dbInfoList so that we only have to do that once for the lifetime // of the statement. while (dataReader.Read()) { var colNum = 1; DataMap row = new Dictionary<string, object>(); // Get all of the values for the row in one shot dataReader.GetValues(rawData); // Convert the items into raw row objects foreach (var dbInfo in _dbInfoList) { var value = rawData[dbInfo.Ordinal]; if (value == DBNull.Value) { value = null; } else if (dbInfo.Binding != null) { value = dbInfo.Binding.GetValue(value, dbInfo.Name); } else if (value.GetType() != dbInfo.OutputTypeDesc.DataType) { value = Convert.ChangeType(value, dbInfo.OutputTypeDesc.DataType); } if (_columnTypeConversionHook != null) { valueContext.ColumnName = fieldNames[colNum - 1]; valueContext.ColumnNumber = colNum; valueContext.ColumnValue = value; value = _columnTypeConversionHook.GetColumnValue(valueContext); } row[dbInfo.Name] = value; colNum++; } EventBean eventBeanRow = null; if (_outputRowConversionHook == null) { eventBeanRow = _agentInstanceContext.EventBeanTypedEventFactory .AdapterForTypedMap( row, _factory.EventType); } else { rowContext.Values = row; rowContext.RowNum = rowNum; var rowData = _outputRowConversionHook.GetOutputRow(rowContext); if (rowData != null) { eventBeanRow = _agentInstanceContext.EventBeanTypedEventFactory .AdapterForTypedObject( rowData, (BeanEventType) _factory.EventType); } } if (eventBeanRow != null) { rows.Add(eventBeanRow); rowNum++; } } } } catch (DbException ex) { throw new EPException( "Error reading results for statement '" + _factory.PreparedStatementText + "'", ex); } } return rows; } catch (DbException ex) { throw new EPException("Error executing statement '" + _factory.PreparedStatementText + "'", ex); } } }
/// <summary> /// Gets the query meta data. /// </summary> /// <param name="databaseStreamSpec">The database stream spec.</param> /// <param name="services"></param> /// <param name="dbCommand">The database command.</param> /// <param name="parameterDesc"></param> /// <param name="contextAttributes">context attributes</param> /// <returns></returns> private static QueryMetaData GetQueryMetaData( DBStatementStreamSpec databaseStreamSpec, StatementCompileTimeServices services, DbDriverCommand dbCommand, SQLParameterDesc parameterDesc, IEnumerable<Attribute> contextAttributes) { // On default setting, if we detect Oracle in the connection then don't query metadata from prepared statement var metadataSetting = dbCommand.MetaDataSettings; // On default setting, if we detect Oracle in the connection then don't query metadata from prepared statement var metaOriginPolicy = metadataSetting.MetadataRetrievalEnum; if (metaOriginPolicy == MetadataOriginEnum.DEFAULT) { // Ask the driver how it interprets the default meta origin policy; the // esper code has a specific hook for Oracle. We have moved this into // the driver to avoid specifically coding behavior to a driver. metaOriginPolicy = dbCommand.Driver.DefaultMetaOriginPolicy; } QueryMetaData queryMetaData; switch (metaOriginPolicy) { case MetadataOriginEnum.METADATA: case MetadataOriginEnum.DEFAULT: queryMetaData = dbCommand.MetaData; // REWRITE: queryMetaData = GetPreparedStmtMetadata( // connection, parameterDesc.Parameters, preparedStatementText, metadataSetting); break; case MetadataOriginEnum.SAMPLE: { string sampleSQL; if (databaseStreamSpec.MetadataSQL != null) { sampleSQL = databaseStreamSpec.MetadataSQL; if (Log.IsInfoEnabled) { Log.Info(".GetQueryMetaData 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 // REWRITE: sampleSQL = CreateSamplePlaceholderStatement(sqlFragments); sampleSQL = CreateSamplePlaceholderStatement(dbCommand.Fragments); if (Log.IsInfoEnabled) { Log.Info(".GetQueryMetaData 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.BuiltinIdentifiers.Count != 1) { sampleSQL = services.CompilerServices.LexSampleSQL(sampleSQL); if (Log.IsInfoEnabled) { Log.Info(".GetQueryMetaData Using lexed sample SQL '" + sampleSQL + "'"); } } } // finally get the metadata by firing the sample SQL queryMetaData = GetExampleQueryMetaData( dbCommand.Driver, sampleSQL, metadataSetting, contextAttributes); break; } default: throw new ArgumentException( "MetaOriginPolicy Contained an unhandled value: #" + metaOriginPolicy); } return queryMetaData; }