void ProcessRawQuery() { _queries.Clear(); switch (CommandType) { case CommandType.Text: SqlQueryParser.ParseRawQuery(CommandText, _connection == null || _connection.UseConformantStrings, _parameters, _queries); if (_queries.Count > 1 && _parameters.Any(p => p.IsOutputDirection)) { throw new NotSupportedException("Commands with multiple queries cannot have out parameters"); } break; case CommandType.TableDirect: _queries.Add(new NpgsqlStatement("SELECT * FROM " + CommandText, new List <NpgsqlParameter>())); break; case CommandType.StoredProcedure: var numInput = _parameters.Count(p => p.IsInputDirection); var sb = new StringBuilder(); sb.Append("SELECT * FROM "); sb.Append(CommandText); sb.Append('('); for (var i = 1; i <= numInput; i++) { sb.Append('$'); sb.Append(i); if (i < numInput) { sb.Append(','); } } sb.Append(')'); _queries.Add(new NpgsqlStatement(sb.ToString(), _parameters.Where(p => p.IsInputDirection).ToList())); break; default: throw PGUtil.ThrowIfReached(); } }
/// <summary> /// Creates a prepared version of the command on a PostgreSQL server. /// </summary> public override void Prepare() { Prechecks(); if (Parameters.Any(p => !p.IsTypeExplicitlySet)) { throw new InvalidOperationException("NpgsqlCommand.Prepare method requires all parameters to have an explicitly set type."); } _connector = Connection.Connector; Log.Debug("Prepare command", _connector.Id); using (_connector.StartUserAction()) { DeallocatePrepared(); ProcessRawQuery(); for (var i = 0; i < _queries.Count; i++) { var query = _queries[i]; ParseMessage parseMessage; DescribeMessage describeMessage; if (i == 0) { parseMessage = _connector.ParseMessage; describeMessage = _connector.DescribeMessage; } else { parseMessage = new ParseMessage(); describeMessage = new DescribeMessage(); } query.PreparedStatementName = _connector.NextPreparedStatementName(); _connector.AddMessage(parseMessage.Populate(query, _connector.TypeHandlerRegistry)); _connector.AddMessage(describeMessage.Populate(StatementOrPortal.Statement, query.PreparedStatementName)); } _connector.AddMessage(SyncMessage.Instance); _connector.SendAllMessages(); _queryIndex = 0; while (true) { var msg = _connector.ReadSingleMessage(); switch (msg.Code) { case BackendMessageCode.CompletedResponse: // prepended messages, e.g. begin transaction case BackendMessageCode.ParseComplete: case BackendMessageCode.ParameterDescription: continue; case BackendMessageCode.RowDescription: var description = (RowDescriptionMessage)msg; FixupRowDescription(description, _queryIndex == 0); _queries[_queryIndex++].Description = description; continue; case BackendMessageCode.NoData: _queries[_queryIndex++].Description = null; continue; case BackendMessageCode.ReadyForQuery: Contract.Assume(_queryIndex == _queries.Count); IsPrepared = true; return; default: throw _connector.UnexpectedMessageReceived(msg.Code); } } } }