예제 #1
0
        /// <summary>
        /// Gets the SQL fragments.
        /// </summary>
        /// <param name="databaseStreamSpec">The database stream spec.</param>
        /// <returns></returns>
        private static IList<PlaceholderParser.Fragment> GetSqlFragments(
            DBStatementStreamSpec databaseStreamSpec)
        {
            IList<PlaceholderParser.Fragment> sqlFragments;
            try {
                sqlFragments = PlaceholderParser.ParsePlaceholder(databaseStreamSpec.SqlWithSubsParams);
            }
            catch (PlaceholderParseException ex) {
                const string text = "Error parsing SQL";
                throw new ExprValidationException(text + ", reason: " + ex.Message, ex);
            }

            return sqlFragments;
        }
예제 #2
0
        public void TestDBStatementViewFactory()
        {
            DBStatementStreamSpec spec = new DBStatementStreamSpec("s0", ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                                                                   "mydb", "select * from mytesttable where mybigint=${idnum}", null);

            EventCollection eventCollection = DatabasePollingViewableFactory.CreateDBStatementView(
                "id", 1, spec,
                SupportDatabaseService.MakeService(),
                SupportEventAdapterService.Service, null, null, null, null, true);

            Assert.AreEqual(typeof(long?), eventCollection.EventType.GetPropertyType("mybigint"));
            Assert.AreEqual(typeof(string), eventCollection.EventType.GetPropertyType("myvarchar"));
            Assert.AreEqual(typeof(bool?), eventCollection.EventType.GetPropertyType("mybool"));
            Assert.AreEqual(typeof(decimal?), eventCollection.EventType.GetPropertyType("mynumeric"));
            Assert.AreEqual(typeof(decimal?), eventCollection.EventType.GetPropertyType("mydecimal"));
        }
예제 #3
0
        public void TestDBStatementViewFactory()
        {
            var container = SupportContainer.Instance;
            var spec      = new DBStatementStreamSpec("s0", ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                                                      "mydb", "select * from mytesttable where mybigint=${idnum}", null);

            EventCollection eventCollection = DatabasePollingViewableFactory.CreateDBStatementView(
                1, 1, spec,
                SupportDatabaseService.MakeService(),
                container.Resolve <EventAdapterService>(),
                null, null, null, null, true, new DataCacheFactory(),
                SupportStatementContextFactory.MakeContext(container));

            Assert.AreEqual(typeof(long?), eventCollection.EventType.GetPropertyType("mybigint"));
            Assert.AreEqual(typeof(string), eventCollection.EventType.GetPropertyType("myvarchar"));
            Assert.AreEqual(typeof(bool?), eventCollection.EventType.GetPropertyType("mybool"));
            Assert.AreEqual(typeof(decimal?), eventCollection.EventType.GetPropertyType("mynumeric"));
            Assert.AreEqual(typeof(decimal?), eventCollection.EventType.GetPropertyType("mydecimal"));
        }
예제 #4
0
        /// <summary>
        /// Creates the event type fields.
        /// </summary>
        /// <param name="databaseStreamSpec">The database stream spec.</param>
        /// <param name="columnTypeConversionHook">The column type conversion hook.</param>
        /// <param name="queryMetaData">The query meta data.</param>
        /// <returns></returns>
        private static IDictionary<string, object> CreateEventTypeFields(
            DBStatementStreamSpec databaseStreamSpec,
            SQLColumnTypeConversion columnTypeConversionHook,
            QueryMetaData queryMetaData)
        {
            IDictionary<string, object> eventTypeFields = new Dictionary<string, object>();
            var columnNum = 1;
            foreach (var entry in queryMetaData.OutputParameters) {
                var name = entry.Key;
                var dbOutputDesc = entry.Value;

                Type clazz;
                if (dbOutputDesc.OptionalBinding != null) {
                    clazz = dbOutputDesc.OptionalBinding.DataType;
                }
                else {
                    clazz = dbOutputDesc.DataType;
                }

                if (columnTypeConversionHook != null) {
                    var newValue = columnTypeConversionHook.GetColumnType(
                        new SQLColumnTypeContext(
                            databaseStreamSpec.DatabaseName,
                            databaseStreamSpec.SqlWithSubsParams,
                            name,
                            clazz,
                            dbOutputDesc.SqlType,
                            columnNum));

                    if (newValue != null) {
                        clazz = newValue;
                    }
                }

                eventTypeFields.Put(name, clazz);
                columnNum++;
            }

            return eventTypeFields;
        }
예제 #5
0
        /// <summary>
        /// Creates the viewable for polling via database SQL query.
        /// </summary>
        /// <param name="statementId">The statement id.</param>
        /// <param name="streamNumber">is the stream number of the view</param>
        /// <param name="databaseStreamSpec">provides the SQL statement, database name and additional info</param>
        /// <param name="databaseConfigService">for getting database connection and settings</param>
        /// <param name="eventAdapterService">for generating event beans from database information</param>
        /// <param name="epStatementAgentInstanceHandle">The ep statement agent instance handle.</param>
        /// <param name="contextAttributes">The db attributes.</param>
        /// <param name="columnTypeConversionHook">The column type conversion hook.</param>
        /// <param name="outputRowConversionHook">The output row conversion hook.</param>
        /// <param name="enableAdoLogging">if set to <c>true</c> [enable JDBC logging].</param>
        /// <param name="dataCacheFactory">The data cache factory.</param>
        /// <param name="statementContext">The statement context.</param>
        /// <returns>
        /// viewable providing poll functionality
        /// </returns>
        /// <exception cref="ExprValidationException">the validation failed</exception>
        public static HistoricalEventViewable CreateDBStatementView(
            int statementId,
            int streamNumber,
            DBStatementStreamSpec databaseStreamSpec,
            DatabaseConfigService databaseConfigService,
            EventAdapterService eventAdapterService,
            EPStatementAgentInstanceHandle epStatementAgentInstanceHandle,
            IEnumerable <Attribute> contextAttributes,
            SQLColumnTypeConversion columnTypeConversionHook,
            SQLOutputRowConversion outputRowConversionHook,
            bool enableAdoLogging,
            DataCacheFactory dataCacheFactory,
            StatementContext statementContext)
        {
            // Parse the SQL for placeholders and text fragments
            var            sqlFragments = GetSqlFragments(databaseStreamSpec);
            IList <String> invocationInputParameters = new List <string>();

            foreach (var fragment in sqlFragments)
            {
                if ((fragment.IsParameter) && (fragment.Value != SAMPLE_WHERECLAUSE_PLACEHOLDER))
                {
                    invocationInputParameters.Add(fragment.Value);
                }
            }

            // Get the database information
            var databaseName = databaseStreamSpec.DatabaseName;
            var dbDriver     = GetDatabaseConnectionFactory(databaseConfigService, databaseName).Driver;
            var dbCommand    = dbDriver.CreateCommand(
                sqlFragments,
                GetMetaDataSettings(databaseConfigService, databaseName),
                contextAttributes);

            if (Log.IsDebugEnabled)
            {
                Log.Debug(".CreateDBStatementView dbCommand=" + dbCommand);
            }

            var queryMetaData = GetQueryMetaData(
                databaseStreamSpec,
                databaseConfigService,
                dbCommand,
                contextAttributes);

            Func <SQLColumnTypeContext, Type> columnTypeConversionFunc = null;

            if (columnTypeConversionHook != null)
            {
                columnTypeConversionFunc = columnTypeConversionHook.GetColumnType;
            }

            Func <SQLOutputRowTypeContext, Type> outputRowConversionFunc = null;

            if (outputRowConversionHook != null)
            {
                outputRowConversionFunc = outputRowConversionHook.GetOutputRowType;
            }

            // Construct an event type from SQL query result metadata
            var eventType = CreateEventType(
                statementId,
                streamNumber,
                queryMetaData,
                eventAdapterService,
                databaseStreamSpec,
                columnTypeConversionFunc,
                outputRowConversionFunc);

            // Get a proper connection and data cache
            ConnectionCache connectionCache;
            DataCache       dataCache;

            try
            {
                connectionCache = databaseConfigService.GetConnectionCache(
                    databaseName, dbCommand.PseudoText, contextAttributes);
                dataCache = databaseConfigService.GetDataCache(
                    databaseName, statementContext, epStatementAgentInstanceHandle, dataCacheFactory, streamNumber);
            }
            catch (DatabaseConfigException e)
            {
                const string text = "Error obtaining cache configuration";
                Log.Error(text, e);
                throw new ExprValidationException(text + ", reason: " + e.Message, e);
            }

            var dbPollStrategy = new PollExecStrategyDBQuery(
                eventAdapterService,
                eventType,
                connectionCache,
                dbCommand.CommandText,
                queryMetaData.OutputParameters,
                columnTypeConversionHook,
                outputRowConversionHook);

            return(new DatabasePollingViewable(
                       streamNumber,
                       invocationInputParameters,
                       dbPollStrategy,
                       dataCache,
                       eventType));
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <summary>
        /// Creates an event type from the query meta data.
        /// </summary>
        /// <param name="statementId">The statement id.</param>
        /// <param name="streamNumber">The stream number.</param>
        /// <param name="queryMetaData">The query meta data.</param>
        /// <param name="eventAdapterService">The event adapter service.</param>
        /// <param name="databaseStreamSpec">The database stream spec.</param>
        /// <param name="columnTypeConversionHook">The column type conversion hook.</param>
        /// <param name="outputRowConversionHook">The output row conversion hook.</param>
        /// <returns></returns>
        private static EventType CreateEventType(
            int statementId,
            int streamNumber,
            QueryMetaData queryMetaData,
            EventAdapterService eventAdapterService,
            DBStatementStreamSpec databaseStreamSpec,
            Func <SQLColumnTypeContext, Type> columnTypeConversionHook,
            Func <SQLOutputRowTypeContext, Type> outputRowConversionHook)
        {
            var columnNum       = 1;
            var eventTypeFields = new Dictionary <String, Object>();

            foreach (var entry in queryMetaData.OutputParameters)
            {
                var name         = entry.Key;
                var dbOutputDesc = entry.Value;

                Type clazz;
                if (dbOutputDesc.OptionalBinding != null)
                {
                    clazz = dbOutputDesc.OptionalBinding.DataType;
                }
                else
                {
                    clazz = dbOutputDesc.DataType;
                }

                if (columnTypeConversionHook != null)
                {
                    var newValue = columnTypeConversionHook.Invoke(
                        new SQLColumnTypeContext(
                            databaseStreamSpec.DatabaseName,
                            databaseStreamSpec.SqlWithSubsParams,
                            name, clazz,
                            dbOutputDesc.SqlType,
                            columnNum));
                    if (newValue != null)
                    {
                        clazz = newValue;
                    }
                }

                eventTypeFields[name] = clazz.GetBoxedType();
                columnNum++;
            }

            EventType eventType;

            if (outputRowConversionHook == null)
            {
                var outputEventType = statementId + "_dbpoll_" + streamNumber;
                eventType = eventAdapterService.CreateAnonymousMapType(outputEventType, eventTypeFields, true);
            }
            else
            {
                var carrierClass = outputRowConversionHook.Invoke(
                    new SQLOutputRowTypeContext(
                        databaseStreamSpec.DatabaseName,
                        databaseStreamSpec.SqlWithSubsParams,
                        eventTypeFields));
                if (carrierClass == null)
                {
                    throw new ExprValidationException("Output row conversion hook returned no type");
                }

                eventType = eventAdapterService.AddBeanType(carrierClass.FullName, carrierClass, false, false, false);
            }

            return(eventType);
        }
예제 #8
0
        public static HistoricalEventViewableDatabaseForge CreateDBStatementView(
            int streamNum,
            DBStatementStreamSpec databaseStreamSpec,
            SQLColumnTypeConversion columnTypeConversionHook,
            SQLOutputRowConversion outputRowConversionHook,
            StatementBaseInfo statementBaseInfo,
            StatementCompileTimeServices services,
            IEnumerable<Attribute> contextAttributes)
        {
            // Parse the SQL for placeholders and text fragments
            var sqlFragments = GetSqlFragments(databaseStreamSpec);
            var invocationInputParameters = new List<string>();
            foreach (var fragment in sqlFragments) {
                if ((fragment.IsParameter) && (fragment.Value != SAMPLE_WHERECLAUSE_PLACEHOLDER)) {
                    invocationInputParameters.Add(fragment.Value);
                }
            }

            // Assemble a PreparedStatement and parameter list
            var preparedStatementText = CreatePreparedStatement(sqlFragments);
            var parameterDesc = GetParameters(sqlFragments);
            if (Log.IsDebugEnabled) {
                Log.Debug(
                    ".CreateDBStatementView preparedStatementText=" +
                    preparedStatementText +
                    " parameterDesc=" +
                    parameterDesc);
            }

            // Get a database connection
            var databaseName = databaseStreamSpec.DatabaseName;
            var dbDriver = services.DatabaseConfigServiceCompileTime
                .GetConnectionFactory(databaseName)
                .Driver;
            var dbCommand = dbDriver.CreateCommand(
                sqlFragments,
                GetMetaDataSettings(services, databaseName),
                contextAttributes);

            if (Log.IsDebugEnabled) {
                Log.Debug(".CreateDBStatementView dbCommand=" + dbCommand);
            }

            var queryMetaData = GetQueryMetaData(
                databaseStreamSpec,
                services,
                dbCommand,
                parameterDesc,
                contextAttributes);

            Func<SQLColumnTypeContext, Type> columnTypeConversionFunc =
                columnTypeConversionHook != null
                    ? columnTypeConversionHook.GetColumnType
                    : (Func<SQLColumnTypeContext, Type>) null;
            Func<SQLOutputRowTypeContext, Type> outputRowConversionFunc =
                outputRowConversionHook != null
                    ? outputRowConversionHook.GetOutputRowType
                    : (Func<SQLOutputRowTypeContext, Type>) null;

            // Construct an event type from SQL query result metadata
            var eventType = CreateEventType(
                streamNum,
                queryMetaData,
                services,
                databaseStreamSpec,
                columnTypeConversionHook,
                outputRowConversionHook,
                statementBaseInfo);

            services.EventTypeCompileTimeRegistry.NewType(eventType);

            return new HistoricalEventViewableDatabaseForge(
                streamNum,
                eventType,
                databaseName,
                queryMetaData.InputParameters.ToArray(),
                preparedStatementText,
                queryMetaData.OutputParameters);
        }
예제 #9
0
        /// <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;
        }
예제 #10
0
        /// <summary>
        /// Creates an event type from the query meta data.
        /// </summary>
        /// <param name="streamNum"></param>
        /// <param name="queryMetaData">The query meta data.</param>
        /// <param name="services"></param>
        /// <param name="databaseStreamSpec">The database stream spec.</param>
        /// <param name="columnTypeConversionHook">The column type conversion hook.</param>
        /// <param name="outputRowConversionHook">The output row conversion hook.</param>
        /// <param name="base"></param>
        private static EventType CreateEventType(
            int streamNum,
            QueryMetaData queryMetaData,
            StatementCompileTimeServices services,
            DBStatementStreamSpec databaseStreamSpec,
            SQLColumnTypeConversion columnTypeConversionHook,
            SQLOutputRowConversion outputRowConversionHook,
            StatementBaseInfo @base)
        {
            var eventTypeFields = CreateEventTypeFields(
                databaseStreamSpec,
                columnTypeConversionHook,
                queryMetaData);

            var eventTypeName = services.EventTypeNameGeneratorStatement.GetAnonymousDBHistorical(streamNum);

            EventType eventType;
            Func<EventTypeApplicationType, EventTypeMetadata> metadata = appType => new EventTypeMetadata(
                eventTypeName,
                @base.ModuleName,
                EventTypeTypeClass.DBDERIVED,
                appType,
                NameAccessModifier.TRANSIENT,
                EventTypeBusModifier.NONBUS,
                false,
                EventTypeIdPair.Unassigned());
            if (outputRowConversionHook == null) {
                eventType = BaseNestableEventUtil.MakeMapTypeCompileTime(
                    metadata.Invoke(EventTypeApplicationType.MAP),
                    eventTypeFields,
                    null,
                    null,
                    null,
                    null,
                    services.BeanEventTypeFactoryPrivate,
                    services.EventTypeCompileTimeResolver);
            }
            else {
                var carrierClass = outputRowConversionHook.GetOutputRowType(
                    new SQLOutputRowTypeContext(
                        databaseStreamSpec.DatabaseName,
                        databaseStreamSpec.SqlWithSubsParams,
                        eventTypeFields));
                if (carrierClass == null) {
                    throw new ExprValidationException("Output row conversion hook returned no type");
                }

                var stem = services.BeanEventTypeStemService.GetCreateStem(carrierClass, null);
                eventType = new BeanEventType(
                    services.Container,
                    stem,
                    metadata.Invoke(EventTypeApplicationType.CLASS),
                    services.BeanEventTypeFactoryPrivate,
                    null,
                    null,
                    null,
                    null);
            }

            return eventType;
        }