internal static void ExecuteBlindSuppressTimeout(NpgsqlConnector connector, NpgsqlQuery query)
        {
            // Block the notification thread before writing anything to the wire.
            using (var blocker = connector.BlockNotificationThread())
            {
                // Write the Query message to the wire.
                connector.Query(query);

                // Flush, and wait for and discard all responses.
                connector.ProcessAndDiscardBackendResponses();
            }
        }
        /// <summary>
        /// Special adaptation of ExecuteBlind() that sets statement_timeout.
        /// This exists to prevent Connector.SetBackendCommandTimeout() from calling Command.ExecuteBlind(),
        /// which will cause an endless recursive loop.
        /// </summary>
        /// <param name="connector"></param>
        /// <param name="timeout">Timeout in seconds.</param>
        internal static void ExecuteSetStatementTimeoutBlind(NpgsqlConnector connector, int timeout)
        {
            NpgsqlQuery query;

            // Optimize for a few common timeout values.
            switch (timeout)
            {
            case 10:
                query = NpgsqlQuery.SetStmtTimeout10Sec;
                break;

            case 20:
                query = NpgsqlQuery.SetStmtTimeout20Sec;
                break;

            case 30:
                query = NpgsqlQuery.SetStmtTimeout30Sec;
                break;

            case 60:
                query = NpgsqlQuery.SetStmtTimeout60Sec;
                break;

            case 90:
                query = NpgsqlQuery.SetStmtTimeout90Sec;
                break;

            case 120:
                query = NpgsqlQuery.SetStmtTimeout120Sec;
                break;

            default:
                query = new NpgsqlQuery(string.Format("SET statement_timeout = {0}", timeout * 1000));
                break;
            }

            // Write the Query message to the wire.
            connector.Query(query);

            // Flush, and wait for and discard all responses.
            connector.ProcessAndDiscardBackendResponses();
        }
Пример #3
0
 internal void Query(NpgsqlQuery query)
 {
     CurrentState.Query(this, query);
 }
Пример #4
0
        public override void Query(NpgsqlConnector context, NpgsqlQuery query)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Query");

            query.WriteToStream(context.Stream);
        }
Пример #5
0
 public virtual void Query(NpgsqlConnector context, NpgsqlQuery query)
 {
     throw new InvalidOperationException("Internal Error! " + this);
 }
        internal ForwardsOnlyDataReader GetReader(CommandBehavior cb)
        {
            CheckConnectionState();

            // Block the notification thread before writing anything to the wire.
            using (m_Connector.BlockNotificationThread())
            {
                IEnumerable <IServerResponseObject> responseEnum;
                ForwardsOnlyDataReader reader;

                m_Connector.SetBackendCommandTimeout(CommandTimeout);

                if (PrepareStatus == PrepareStatus.NeedsPrepare)
                {
                    PrepareInternal();
                }

                if (PrepareStatus == PrepareStatus.NotPrepared)
                {
                    NpgsqlQuery query;
                    byte[]      commandText = GetCommandText();

                    query = new NpgsqlQuery(commandText);

                    // Write the Query message to the wire.
                    m_Connector.Query(query);

                    // Tell to mediator what command is being sent.
                    if (PrepareStatus == PrepareStatus.NotPrepared)
                    {
                        m_Connector.Mediator.SetSqlSent(commandText, NpgsqlMediator.SQLSentType.Simple);
                    }
                    else
                    {
                        m_Connector.Mediator.SetSqlSent(preparedCommandText, NpgsqlMediator.SQLSentType.Execute);
                    }

                    // Flush and wait for responses.
                    responseEnum = m_Connector.ProcessBackendResponsesEnum();

                    // Construct the return reader.
                    reader = new ForwardsOnlyDataReader(
                        responseEnum,
                        cb,
                        this,
                        m_Connector.BlockNotificationThread()
                        );

                    if (
                        commandType == CommandType.StoredProcedure &&
                        reader.FieldCount == 1 &&
                        reader.GetDataTypeName(0) == "refcursor"
                        )
                    {
                        // When a function returns a sole column of refcursor, transparently
                        // FETCH ALL from every such cursor and return those results.
                        StringWriter sw = new StringWriter();
                        string       queryText;

                        while (reader.Read())
                        {
                            sw.WriteLine("FETCH ALL FROM \"{0}\";", reader.GetString(0));
                        }

                        reader.Dispose();

                        queryText = sw.ToString();

                        if (queryText == "")
                        {
                            queryText = ";";
                        }

                        // Passthrough the commandtimeout to the inner command, so user can also control its timeout.
                        // TODO: Check if there is a better way to handle that.

                        query = new NpgsqlQuery(queryText);

                        // Write the Query message to the wire.
                        m_Connector.Query(query);

                        // Flush and wait for responses.
                        responseEnum = m_Connector.ProcessBackendResponsesEnum();

                        // Construct the return reader.
                        reader = new ForwardsOnlyDataReader(
                            responseEnum,
                            cb,
                            this,
                            m_Connector.BlockNotificationThread()
                            );
                    }
                }
                else
                {
                    // Update the Bind object with current parameter data as needed.
                    BindParameters();

                    // Write the Bind, Execute, and Sync message to the wire.
                    m_Connector.Bind(bind);
                    m_Connector.Execute(execute);
                    m_Connector.Sync();

                    // Tell to mediator what command is being sent.
                    m_Connector.Mediator.SetSqlSent(preparedCommandText, NpgsqlMediator.SQLSentType.Execute);

                    // Flush and wait for responses.
                    responseEnum = m_Connector.ProcessBackendResponsesEnum();

                    // Construct the return reader, possibly with a saved row description from Prepare().
                    reader = new ForwardsOnlyDataReader(
                        responseEnum,
                        cb,
                        this,
                        m_Connector.BlockNotificationThread(),
                        true,
                        currentRowDescription
                        );
                }

                return(reader);
            }
        }