Пример #1
0
		/// <summary>
		/// Creates a prepared version of the command on a PostgreSQL server.
		/// </summary>
		public override void Prepare()
		{
			// Check the connection state.
			CheckConnectionState();

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

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

			if (!m_Connector.SupportsPrepare)
			{
				return; // Do nothing.
			}

			using (m_Connector.BlockNotificationThread())
			{
				try
				{
					// Use the extended query parsing...
					planName = m_Connector.NextPlanName();
					String portalName = m_Connector.NextPortalName();

					parse = new NpgsqlParse(planName, GetParseCommandText(), new Int32[] { });

					m_Connector.Parse(parse);

					// We need that because Flush() doesn't cause backend to send
					// ReadyForQuery on error. Without ReadyForQuery, we don't return 
					// from query extended processing.

					// We could have used Connector.Flush() which sends us back a
					// ReadyForQuery, but on postgresql server below 8.1 there is an error
					// with extended query processing which hinders us from using it.
					m_Connector.RequireReadyForQuery = false;
					m_Connector.Flush();


					// Description...
					NpgsqlDescribe describe = new NpgsqlDescribe('S', planName);


					m_Connector.Describe(describe);

					NpgsqlRowDescription returnRowDesc = m_Connector.Sync();

					Int16[] resultFormatCodes;


					if (returnRowDesc != null)
					{
						resultFormatCodes = new Int16[returnRowDesc.NumFields];

						for (int i = 0; i < returnRowDesc.NumFields; i++)
						{
							NpgsqlRowDescription.FieldData returnRowDescData = returnRowDesc[i];


							if (returnRowDescData.TypeInfo != null && returnRowDescData.TypeInfo.NpgsqlDbType == NpgsqlDbType.Bytea)
							{
								// Binary format
								resultFormatCodes[i] = (Int16)FormatCode.Binary;
							}
							else
							{
								// Text Format
								resultFormatCodes[i] = (Int16)FormatCode.Text;
							}
						}
					}
					else
					{
						resultFormatCodes = new Int16[] { 0 };
					}

					bind = new NpgsqlBind("", planName, new Int16[Parameters.Count], null, resultFormatCodes);
				}
				catch (IOException e)
				{
					throw ClearPoolAndCreateException(e);
				}
				catch
				{
					// As per documentation:
					// "[...] When an error is detected while processing any extended-query message,
					// the backend issues ErrorResponse, then reads and discards messages until a
					// Sync is reached, then issues ReadyForQuery and returns to normal message processing.[...]"
					// So, send a sync command if we get any problems.

					m_Connector.Sync();

					throw;
				}
			}
		}