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); } }
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); } }
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; } }