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 (prepared == PrepareStatus.NeedsPrepare)
                {
                    PrepareInternal();
                }

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

                    query = NpgsqlQuery.Create(m_Connector.BackendProtocolVersion, commandText);

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

                    // Tell to mediator what command is being sent.
                    if (prepared == 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 = NpgsqlQuery.Create(m_Connector.BackendProtocolVersion, 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);
            }
        }
Exemple #2
0
        internal ForwardsOnlyDataReader GetReader(CommandBehavior cb)
        {
            try
            {
                CheckConnectionState();

                // reset any responses just before getting new ones
                Connector.Mediator.ResetResponses();

                // Set command timeout.
                m_Connector.Mediator.CommandTimeout = CommandTimeout;


                using (m_Connector.BlockNotificationThread())
                {
                    ForwardsOnlyDataReader reader;
                    if (parse == null)
                    {
                        reader = new ForwardsOnlyDataReader(m_Connector.QueryEnum(this), cb, this,
                                                            m_Connector.BlockNotificationThread(), false);
                        if (type == 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.
                            StringBuilder sb = new StringBuilder();
                            while (reader.Read())
                            {
                                sb.Append("fetch all from \"").Append(reader.GetString(0)).Append("\";");
                            }
                            sb.Append(";"); // Just in case the list of cursors is empty.

                            reader = new NpgsqlCommand(sb.ToString(), Connection).GetReader(reader._behavior);
                        }
                    }
                    else
                    {
                        BindParameters();
                        reader = new ForwardsOnlyDataReader(m_Connector.ExecuteEnum(new NpgsqlExecute(bind.PortalName, 0)), cb, this,
                                                            m_Connector.BlockNotificationThread(), true);
                    }
                    return reader;
                }
            }
            catch (IOException ex)
            {
                throw ClearPoolAndCreateException(ex);
            }
        }
Exemple #3
0
		internal ForwardsOnlyDataReader GetReader(CommandBehavior cb)
		{
			try
			{
				CheckConnectionState();

				var connector = Connector;

				if (PreparedQuery != null)
					connector.PrepareOrAdd(PreparedQuery, PreparedParams, text);

				// reset any responses just before getting new ones
				connector.Mediator.ResetResponses();

				// Set command timeout.
				connector.Mediator.CommandTimeout = CommandTimeout;


				using (connector.BlockNotificationThread())
				{
					ForwardsOnlyDataReader reader;
					if (parse == null)
					{
						reader = new ForwardsOnlyDataReader(connector.QueryEnum(this), cb, this,
															connector.BlockNotificationThread(), false);
						if (type == 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.
							StringBuilder sb = new StringBuilder();
							while (reader.Read())
							{
								sb.Append("fetch all from \"").Append(reader.GetString(0)).Append("\";");
							}
							sb.Append(";"); // Just in case the list of cursors is empty.

							//reader = new NpgsqlCommand(sb.ToString(), Connection).GetReader(reader._behavior);

							// 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.

							NpgsqlCommand c = new NpgsqlCommand(sb.ToString(), Connection);

							c.CommandTimeout = this.CommandTimeout;

							reader = c.GetReader(reader._behavior);

						}
					}
					else
					{
						BindParameters();
						reader = new ForwardsOnlyDataReader(connector.ExecuteEnum(new NpgsqlExecute(bind.PortalName, 0)), cb, this,
															connector.BlockNotificationThread(), true);
					}
					return reader;
				}
			}
			catch (IOException ex)
			{
				throw ClearPoolAndCreateException(ex);
			}
		}
        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 (prepared == PrepareStatus.NeedsPrepare)
                {
                    PrepareInternal();
                }

                if (prepared == 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 (prepared == 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;
            }
        }
        internal ForwardsOnlyDataReader GetReader(CommandBehavior cb)
        {
            CheckConnectionState();

            // reset any responses just before getting new ones
            Connector.Mediator.ResetResponses();

            // Set command timeout.
            m_Connector.Mediator.CommandTimeout = CommandTimeout;

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

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

                if (prepared == PrepareStatus.NotPrepared || prepared == PrepareStatus.V2Prepared)
                {
                    NpgsqlQuery query;

                    query = new NpgsqlQuery(m_Connector, GetCommandText());

                    // 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()
                    );

                    if (
                        type == 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(m_Connector, 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
                {
                    bool sendPortalDescribe = ! portalDescribeSent;

                    // Update the Bind object with current parameter data as needed.
                    BindParameters();

                    // Write the Bind message to the wire.
                    m_Connector.Bind(bind);

                    if (sendPortalDescribe)
                    {
                        NpgsqlDescribe portalDescribe = new NpgsqlDescribePortal(bind.PortalName);

                        // Write a Describe message to the wire.
                        m_Connector.Describe(portalDescribe);

                        portalDescribeSent = true;
                    }

                    // Finally, write the Execute and Sync messages to the wire.
                    m_Connector.Execute(execute);
                    m_Connector.Sync();

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

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

                    if (sendPortalDescribe)
                    {
                        // We sent a Describe message. If the query produces a result set,
                        // PG sent a row description, and the reader has now found it,
                        currentRowDescription = reader.CurrentDescription;
                    }
                }

                return reader;
            }
        }