/// <summary> /// Adds a <see cref="NpgsqlParameter">NpgsqlParameter</see> to the <see cref="NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the specified parameter name and value. /// </summary> /// <param name="parameterName">The name of the <see cref="NpgsqlParameter">NpgsqlParameter</see>.</param> /// <param name="value">The Value of the <see cref="NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param> /// <param name="parameterType">One of the NpgsqlDbType values.</param> /// <param name="size">The length of the column.</param> /// <param name="sourceColumn">The name of the source column.</param> /// <returns>The paramater that was added.</returns> public NpgsqlParameter AddWithValue(string parameterName, NpgsqlDbType parameterType, int size, string sourceColumn, object value) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "AddWithValue", parameterName, parameterType, size, sourceColumn, value); NpgsqlParameter param = new NpgsqlParameter(parameterName, parameterType, size, sourceColumn); param.Value = value; return(this.Add(param)); }
public void PrepareTransaction() { if (!_prepared) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "PrepareTransaction"); NpgsqlConnection connection = GetConnection(); NpgsqlCommand.ExecuteBlind(connection.Connector, string.Format("PREPARE TRANSACTION '{0}'", _txName)); _prepared = true; } }
/// <summary> /// This method writes a set of bytes to the stream. It also enables logging of them. /// </summary> public static Stream WriteBytesNullTerminated(this Stream stream, byte[] the_bytes) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteBytes"); NpgsqlEventLog.LogMsg("Log_BytesWritten", LogLevel.Debug, the_bytes); stream.Write(the_bytes, 0, the_bytes.Length); stream.WriteByte(0); return(stream); }
/// <summary> /// Initializes a new instance of the <see cref="NpgsqlParameter">NpgsqlParameter</see> /// </summary> /// <param m_Name="parameterName">The m_Name of the parameter to map.</param> /// <param m_Name="parameterType">One of the <see cref="UnityNpgsqlTypes.NpgsqlDbType">NpgsqlDbType</see> values.</param> /// <param m_Name="size">The length of the parameter.</param> /// <param m_Name="sourceColumn">The m_Name of the source column.</param> public NpgsqlParameter(String parameterName, NpgsqlDbType parameterType, Int32 size, String sourceColumn) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, parameterType, size, source_column); this.ParameterName = parameterName; NpgsqlDbType = parameterType; //Allow the setter to catch any exceptions. this.size = size; source_column = sourceColumn; }
/// <summary> /// Creates a prepared version of the command on a PostgreSQL server. /// </summary> public override void Prepare() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Prepare"); // Check the connection state. CheckConnectionState(); UnPrepare(); PrepareInternal(); }
/// <summary> /// Removes all items from the collection. /// </summary> public override void Clear() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Clear"); foreach (NpgsqlParameter toRemove in this.InternalList) { // clean up the parameter so it can be added to another command if required. toRemove.Collection = null; } this.InternalList.Clear(); this.InvalidateHashLookups(); }
///<summary> /// This method writes a string to the network stream. /// </summary> public static Stream WriteString(this Stream stream, String theString) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteString"); NpgsqlEventLog.LogMsg("Log_StringWritten", LogLevel.Debug, theString); byte[] bytes = BackendEncoding.UTF8Encoding.GetBytes(theString); stream.Write(bytes, 0, bytes.Length); return(stream); }
/// <summary> /// When a connection is closed within an enclosing TransactionScope and the transaction /// hasn't been promoted, we defer the actual closing until the scope ends. /// </summary> internal void PromotableLocalTransactionEnded() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "PromotableLocalTransactionEnded"); if (_postponingDispose) { Dispose(true); } else if (_postponingClose) { ReallyClose(); } }
/// <summary> /// Removes the specified <see cref="NpgsqlParameter">NpgsqlParameter</see> from the collection. /// </summary> /// <param name="parameterName">The name of the <see cref="NpgsqlParameter">NpgsqlParameter</see> to remove from the collection.</param> public void Remove(string parameterName) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Remove", parameterName); int index = IndexOf(parameterName); if (index < 0) { throw new InvalidOperationException("No parameter with the specified name exists in the collection"); } RemoveAt(index); }
/// <summary> /// Begins a database transaction with the specified isolation level. /// </summary> /// <param name="level">The <see cref="System.Data.IsolationLevel">isolation level</see> under which the transaction should run.</param> /// <returns>A <see cref="NpgsqlTransaction">NpgsqlTransaction</see> /// object representing the new transaction.</returns> /// <remarks> /// Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. /// There's no support for nested transactions. /// </remarks> public new NpgsqlTransaction BeginTransaction(IsolationLevel level) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "BeginTransaction", level); CheckConnectionOpen(); if (connector.Transaction != null) { throw new InvalidOperationException("Exception_NoNestedTransactions"); } return(new NpgsqlTransaction(this, level)); }
/// <summary> /// Opens a database connection with the property settings specified by the /// <see cref="NpgsqlConnection.ConnectionString">ConnectionString</see>. /// </summary> public override void Open() { // If we're postponing a close (see doc on this variable), the connection is already // open and can be silently reused if (_postponingClose) { return; } CheckConnectionClosed(); NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open"); // Check if there is any missing argument. if (!settings.ContainsKey(Keywords.Host)) { throw new ArgumentException("Exception_MissingConnStrArg: " + Keywords.Host); } if (!settings.ContainsKey(Keywords.UserName) && !settings.ContainsKey(Keywords.IntegratedSecurity)) { throw new ArgumentException("Exception_MissingConnStrArg: " + Keywords.UserName); } // Get a Connector, either from the pool or creating one ourselves. if (Pooling) { connector = NpgsqlConnectorPool.ConnectorPoolMgr.RequestConnector(this); } else { connector = new NpgsqlConnector(this); connector.Open(); } connector.Notice += NoticeDelegate; connector.Notification += NotificationDelegate; if (SyncNotification) { connector.AddNotificationThread(); } if (Enlist) { Promotable.Enlist(Transaction.Current); } OpenCounter++; this.OnStateChange(new StateChangeEventArgs(ConnectionState.Closed, ConnectionState.Open)); }
public void CommitTransaction() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CommitTransaction"); NpgsqlConnection connection = GetConnection(); if (_prepared) { NpgsqlCommand.ExecuteBlind(connection.Connector, string.Format("COMMIT PREPARED '{0}'", _txName)); } else { NpgsqlCommand.ExecuteBlind(connection.Connector, NpgsqlQuery.CommitTransaction); } }
private byte[] GetExecuteCommandText() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetPreparedCommandText"); MemoryStream result = new MemoryStream(); result.WriteString("EXECUTE {0}", planName); if (parameters.Count != 0) { result.WriteByte((byte)ASCIIBytes.ParenLeft); for (int i = 0; i < Parameters.Count; i++) { var p = Parameters[i]; if (i > 0) { result.WriteByte((byte)ASCIIBytes.Comma); } // Add parentheses wrapping parameter value before the type cast to avoid problems with Int16.MinValue, Int32.MinValue and Int64.MinValue // See bug #1010543 result.WriteByte((byte)ASCIIBytes.ParenLeft); byte[] serialization; serialization = p.TypeInfo.ConvertToBackend(p.Value, false, Connector.NativeToBackendTypeConverterOptions); result .WriteBytes(serialization) .WriteBytes((byte)ASCIIBytes.ParenRight); if (p.UseCast) { PGUtil.WriteString(result, string.Format("::{0}", p.TypeInfo.CastName)); if (p.TypeInfo.UseSize && (p.Size > 0)) { result.WriteString("({0})", p.Size); } } } result.WriteByte((byte)ASCIIBytes.ParenRight); } return(result.ToArray()); }
///<summary> /// This method writes a C NULL terminated string to the network stream. /// It appends a NULL terminator to the end of the String. /// </summary> public static Stream WriteStringNullTerminated(this Stream stream, String format, params object[] parameters) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteStringNullTerminated"); string theString = string.Format(format, parameters); NpgsqlEventLog.LogMsg("Log_StringWritten", LogLevel.Debug, theString); byte[] bytes = BackendEncoding.UTF8Encoding.GetBytes(theString); stream.Write(bytes, 0, bytes.Length); stream.WriteByte(0); return(stream); }
/// <summary> /// Rolls back a transaction from a pending state. /// </summary> public override void Rollback() { CheckDisposed(); if (_conn == null) { throw new InvalidOperationException("Exception_NoTransaction"); } NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Rollback"); NpgsqlCommand.ExecuteBlindSuppressTimeout(_conn.Connector, NpgsqlQuery.RollbackTransaction); _conn.Connector.Transaction = null; _conn = null; }
/// <summary> /// Used to execute internal commands. /// </summary> internal NpgsqlCommand(String cmdText, NpgsqlConnector connector, int CommandTimeout = 20) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME); planName = String.Empty; commandText = cmdText; this.m_Connector = connector; this.CommandTimeout = CommandTimeout; commandType = CommandType.Text; // Removed this setting. It was causing too much problem. // Do internal commands really need different timeout setting? // Internal commands aren't affected by command timeout value provided by user. // timeout = 20; }
///<summary> /// This method checks the connection state to see if the connection /// is set or it is open. If one of this conditions is not met, throws /// an InvalidOperationException ///</summary> private void CheckConnectionState() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CheckConnectionState"); // Check the connection state. if (Connector == null || Connector.State == ConnectionState.Closed) { throw new InvalidOperationException("Exception_ConnectionNotOpen"); } if (Connector.State != ConnectionState.Open) { throw new InvalidOperationException( "There is already an open DataReader associated with this Command which must be closed first."); } }
/// <summary> /// Releases the connection to the database. If the connection is pooled, it will be /// made available for re-use. If it is non-pooled, the actual connection will be shutdown. /// </summary> public override void Close() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Close"); if (connector == null) { return; } if (promotable != null && promotable.InLocalTransaction) { _postponingClose = true; return; } ReallyClose(); }
/// <summary> /// Inserts a <see cref="NpgsqlParameter">NpgsqlParameter</see> into the collection at the specified index. /// </summary> /// <param name="index">The zero-based index where the parameter is to be inserted within the collection.</param> /// <param name="oValue">The <see cref="NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param> public override void Insert(int index, object oValue) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Insert", index, oValue); CheckType(oValue); NpgsqlParameter value = oValue as NpgsqlParameter; if (value.Collection != null) { throw new InvalidOperationException("The parameter already belongs to a collection"); } value.Collection = this; this.InternalList.Insert(index, value); this.InvalidateHashLookups(); }
/// <summary> /// Initializes a new instance of the <see cref="NpgsqlParameter">NpgsqlParameter</see> /// class with the parameter m_Name and a value of the new <b>NpgsqlParameter</b>. /// </summary> /// <param m_Name="parameterName">The m_Name of the parameter to map.</param> /// <param m_Name="value">An <see cref="System.Object">Object</see> that is the value of the <see cref="NpgsqlParameter">NpgsqlParameter</see>.</param> /// <remarks> /// <p>When you specify an <see cref="System.Object">Object</see> /// in the value parameter, the <see cref="System.Data.DbType">DbType</see> is /// inferred from the .NET Framework type of the <b>Object</b>.</p> /// <p>When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter. /// This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType. /// Use <code> Convert.ToInt32(value) </code> for example to have compiler calling the correct constructor.</p> /// </remarks> public NpgsqlParameter(String parameterName, object value) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, value); this.ParameterName = parameterName; this.Value = value; /*if ((this.value == null) || (this.value == DBNull.Value)) * { * // don't really know what to do - leave default and do further exploration * // Default type for null values is String. * this.value = DBNull.Value; * type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String)); * } * else if (!NpgsqlTypesHelper.TryGetNativeTypeInfo(value.GetType(), out type_info)) * { * throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value.GetType())); * }*/ }
/// <summary> /// Initializes a new instance of the <see cref="NpgsqlCommand">NpgsqlCommand</see> class with the text of the query, a <see cref="NpgsqlConnection">NpgsqlConnection</see>, and the <see cref="NpgsqlTransaction">NpgsqlTransaction</see>. /// </summary> /// <param name="cmdText">The text of the query.</param> /// <param name="connection">A <see cref="NpgsqlConnection">NpgsqlConnection</see> that represents the connection to a PostgreSQL server.</param> /// <param name="transaction">The <see cref="NpgsqlTransaction">NpgsqlTransaction</see> in which the <see cref="NpgsqlCommand">NpgsqlCommand</see> executes.</param> public NpgsqlCommand(String cmdText, NpgsqlConnection connection, NpgsqlTransaction transaction) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME); planName = String.Empty; commandText = cmdText; Connection = connection; if (connection != null && m_Connector != null) { // Note: DefaultCommandTimeout currently only gets read from the very first connection's connector. // If we later change the command's connection with the Connection property, we don't read it again. // Need a better mechanism. CommandTimeout = m_Connector.DefaultCommandTimeout; } commandType = CommandType.Text; this.Transaction = transaction; SetCommandTimeout(); }
/// <summary> /// Gets a value indicating whether a <see cref="NpgsqlParameter">NpgsqlParameter</see> with the specified parameter name exists in the collection. /// </summary> /// <param name="parameterName">The name of the <see cref="NpgsqlParameter">NpgsqlParameter</see> object to find.</param> /// <param name="parameter">A reference to the requested parameter is returned in this out param if it is found in the list. This value is null if the parameter is not found.</param> /// <returns><b>true</b> if the collection contains the parameter and param will contain the parameter; otherwise, <b>false</b>.</returns> public bool TryGetValue(string parameterName, out NpgsqlParameter parameter) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "TryGetValue", parameterName); int index = IndexOf(parameterName); if (index != -1) { parameter = InternalList[index]; return(true); } else { parameter = null; return(false); } }
///<summary> /// This method writes a C NULL terminated byte[] limited in length to the /// backend server. /// It pads the string with null bytes to the size specified. /// </summary> public static Stream WriteLimBytes(this Stream network_stream, byte[] bytes, Int32 n) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteLimBytes"); if (bytes.Length > n) { throw new ArgumentOutOfRangeException("bytes", bytes, "LimStringWriteTooLarge"); } network_stream.Write(bytes, 0, bytes.Length); //pad with zeros. if (bytes.Length < n) { bytes = new byte[n - bytes.Length]; network_stream.Write(bytes, 0, bytes.Length); } return(network_stream); }
/// <summary> /// Executes a SQL statement against the connection and returns the number of rows affected. /// </summary> /// <returns>The number of rows affected if known; -1 otherwise.</returns> public override Int32 ExecuteNonQuery() { //We treat this as a simple wrapper for calling ExecuteReader() and then //update the records affected count at every call to NextResult(); NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteNonQuery"); int?ret = null; using (NpgsqlDataReader rdr = GetReader(CommandBehavior.SequentialAccess)) { do { int thisRecord = rdr.RecordsAffected; if (thisRecord != -1) { ret = (ret ?? 0) + thisRecord; } lastInsertedOID = rdr.LastInsertedOID ?? lastInsertedOID; }while (rdr.NextResult()); } return(ret ?? -1); }
/// <summary> /// Attempts to cancel the execution of a <see cref="NpgsqlCommand">NpgsqlCommand</see>. /// </summary> /// <remarks>This Method isn't implemented yet.</remarks> public override void Cancel() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Cancel"); try { // get copy for thread safety of null test NpgsqlConnector connector = Connector; if (connector != null) { connector.CancelRequest(); } } catch (IOException) { Connection.ClearPool(); } catch (NpgsqlException) { // Cancel documentation says the Cancel doesn't throw on failure } }
/// <summary> /// Releases all resources used by the /// <see cref="NpgsqlConnection">NpgsqlConnection</see>. /// </summary> /// <param name="disposing"><b>true</b> when called from Dispose(); /// <b>false</b> when being called from the finalizer.</param> protected override void Dispose(bool disposing) { if (disposed) { return; } _postponingDispose = false; if (disposing) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Dispose"); Close(); if (_postponingClose) { _postponingDispose = true; return; } } base.Dispose(disposing); disposed = true; }
///<summary> /// This method writes a C NULL terminated string limited in length to the /// backend server. /// It pads the string with null bytes to the size specified. /// </summary> public static Stream WriteLimString(this Stream network_stream, String the_string, Int32 n) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteLimString"); //Note: We do not know the size in bytes until after we have converted the string. byte[] bytes = BackendEncoding.UTF8Encoding.GetBytes(the_string); if (bytes.Length > n) { throw new ArgumentOutOfRangeException("the_string", the_string, "LimStringWriteTooLarge"); } network_stream.Write(bytes, 0, bytes.Length); //pad with zeros. if (bytes.Length < n) { bytes = new byte[n - bytes.Length]; network_stream.Write(bytes, 0, bytes.Length); } return(network_stream); }
/// <summary> /// Used when a connection is closed /// </summary> public void Prepare() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Prepare"); if (_inTransaction) { // may not be null if Promote or Enlist is called first if (_callbacks == null) { _callbacks = new NpgsqlTransactionCallbacks(_connection); } _callbacks.PrepareTransaction(); if (_npgsqlTx != null) { // cancel the NpgsqlTransaction since this will // be handled by a two phase commit. _npgsqlTx.Cancel(); _npgsqlTx.Dispose(); _npgsqlTx = null; _connection.PromotableLocalTransactionEnded(); } } }
public byte[] Promote() { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Promote"); _rm = CreateResourceManager(); // may not be null if Prepare or Enlist is called first if (_callbacks == null) { _callbacks = new NpgsqlTransactionCallbacks(_connection); } byte[] token = _rm.Promote(_callbacks); // mostly likely case for this is the transaction has been prepared. if (_npgsqlTx != null) { // cancel the NpgsqlTransaction since this will // be handled by a two phase commit. _npgsqlTx.Cancel(); _npgsqlTx.Dispose(); _npgsqlTx = null; _connection.PromotableLocalTransactionEnded(); } return(token); }
public void Enlist(Transaction tx) { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Enlist"); if (tx != null) { _isolationLevel = tx.IsolationLevel; if (!tx.EnlistPromotableSinglePhase(this)) { // must already have a durable resource // start transaction _npgsqlTx = _connection.BeginTransaction(ConvertIsolationLevel(_isolationLevel)); _inTransaction = true; _rm = CreateResourceManager(); _callbacks = new NpgsqlTransactionCallbacks(_connection); _rm.Enlist(_callbacks, TransactionInterop.GetTransmitterPropagationToken(tx)); // enlisted in distributed transaction // disconnect and cleanup local transaction _npgsqlTx.Cancel(); _npgsqlTx.Dispose(); _npgsqlTx = null; } } }