Browse files

Synchronized with cvs Npgsql2.

Changes:

2012-01-12 16:44  fxjr

	* src/: Npgsql/Cache.cs, Npgsql/NpgsqlCommand.cs,
	  Npgsql/NpgsqlCommandBuilder.cs, Npgsql/NpgsqlConnector.cs,
	  Npgsql/NpgsqlConnectorPool.cs, Npgsql/NpgsqlState.cs,
	  Npgsql/PGUtil.cs, NpgsqlTypes/BitString.cs:
	  Applied Gildas Prime patch with Gendarme report corrections:

	  Avoid concatenating chars rule ( i.e Unneeded boxing) A recursive
	  method was found (Method remove in NpgsqlParameterCollection)
	  Disposable fields should be disposed Do not lock on this  (
	  lock(this) makes very difficult to ensure that the locking is
	  done correctly.) Ensure that local variables are disposed
	  surrounding them by using()

2012-01-10 01:14  fxjr

	* src/Npgsql/NpgsqlConnectorPool.cs:
	  Fixed tabulation.

2012-01-09 12:48  fxjr

	* src/Npgsql/NpgsqlConnectorPool.cs:
	  Fix [#1011138] Connection pooling performance suffers under heavy
	  load.  Rewritten connector pool logic in order to keep lock for
	  much less time and also with a higher granularity.  Thanks Andrew
	  for heads up.
  • Loading branch information...
1 parent b7eb671 commit 3fcafe6c1f64a6f0db335010a1f6b94f3bd8655e @franciscojunior franciscojunior committed Jan 18, 2012
View
7 src/Npgsql/Cache.cs
@@ -38,6 +38,7 @@ internal class Cache<TEntity> : LinkedList<KeyValuePair<string, TEntity>>
where TEntity : class
{
private int _cache_size = 20;
+ private object locker = new object();
/// <summary>
/// Set Cache Size. The default value is 20.
@@ -53,7 +54,7 @@ public int CacheSize
if (this.Count > _cache_size)
{
- lock (this)
+ lock (locker)
{
while (_cache_size < this.Count)
{
@@ -74,7 +75,7 @@ public int CacheSize
{
get
{
- lock (this)
+ lock (locker)
{
for (LinkedListNode<KeyValuePair<string, TEntity>> node = this.First; node != null; node = node.Next)
{
@@ -90,7 +91,7 @@ public int CacheSize
}
set
{
- lock (this)
+ lock (locker)
{
for (LinkedListNode<KeyValuePair<string, TEntity>> node = this.First; node != null; node = node.Next)
{
View
6 src/Npgsql/NpgsqlCommand.cs
@@ -1125,7 +1125,7 @@ private Boolean CheckFunctionNeedsColumnDefinitionList()
{
if ((p.Direction == ParameterDirection.Input) || (p.Direction == ParameterDirection.InputOutput))
{
- parameterTypes.Append(Connection.Connector.OidToNameMapping[p.TypeInfo.Name].OID + " ");
+ parameterTypes.Append(Connection.Connector.OidToNameMapping[p.TypeInfo.Name].OID.ToString() + " ");
}
if ((p.Direction == ParameterDirection.Output) || (p.Direction == ParameterDirection.InputOutput))
@@ -1380,11 +1380,11 @@ private String GetPrepareCommandText()
// The space in front of '$' fixes a parsing problem in 7.3 server
// which gives errors of operator when finding the caracters '=$' in
// prepare text
- textCommand = ReplaceParameterValue(textCommand, parameterName, " $" + (i + 1));
+ textCommand = ReplaceParameterValue(textCommand, parameterName, " $" + (i + 1).ToString());
}
else
{
- textCommand += " $" + (i + 1);
+ textCommand += " $" + (i + 1).ToString();
}
}
}
View
2 src/Npgsql/NpgsqlCommandBuilder.cs
@@ -165,7 +165,7 @@ public static void DeriveParameters(NpgsqlCommand command)
if (names != null && i < names.Length)
command.Parameters.Add(new NpgsqlParameter(":" + names[i], typeInfo.NpgsqlDbType));
else
- command.Parameters.Add(new NpgsqlParameter("parameter" + i + 1, typeInfo.NpgsqlDbType));
+ command.Parameters.Add(new NpgsqlParameter("parameter" + (i + 1).ToString(), typeInfo.NpgsqlDbType));
}
}
}
View
30 src/Npgsql/NpgsqlConnector.cs
@@ -365,7 +365,11 @@ internal Boolean IsValid()
String testValue = String.Format("Npgsql{0}{1}", testBytes[0], testBytes[1]);
//Query(new NpgsqlCommand("select 1 as ConnectionTest", this));
- String compareValue = (String) new NpgsqlCommand("select '" + testValue + "'", this).ExecuteScalar();
+ string compareValue = string.Empty;
+ using(NpgsqlCommand cmd = new NpgsqlCommand("select '" + testValue + "'", this))
+ {
+ compareValue = (string) cmd.ExecuteScalar();
+ }
if (compareValue != testValue)
return false;
@@ -396,7 +400,11 @@ internal void ReleaseResources()
internal void ReleaseRegisteredListen()
{
- Query(new NpgsqlCommand("unlisten *", this));
+ //Query(new NpgsqlCommand("unlisten *", this));
+ using(NpgsqlCommand cmd = new NpgsqlCommand("unlisten *", this))
+ {
+ Query(cmd);
+ }
}
/// <summary>
@@ -412,7 +420,11 @@ internal void ReleasePlansPortals()
{
try
{
- Query(new NpgsqlCommand(String.Format("deallocate \"{0}\";", _planNamePrefix + i), this));
+ //Query(new NpgsqlCommand(String.Format("deallocate \"{0}\";", _planNamePrefix + i), this));
+ using(NpgsqlCommand cmd = new NpgsqlCommand(String.Format("deallocate \"{0}\";", _planNamePrefix + i.ToString()), this))
+ {
+ Query(cmd);
+ }
}
// Ignore any error which may occur when releasing portals as this portal name may not be valid anymore. i.e.: the portal name was used on a prepared query which had errors.
@@ -717,8 +729,12 @@ internal void Open()
// This should not happen for protocol version 3+.
if (ServerVersion == null)
{
- NpgsqlCommand command = new NpgsqlCommand("set DATESTYLE TO ISO;select version();", this);
- ServerVersion = new Version(PGUtil.ExtractServerVersion((string) command.ExecuteScalar()));
+ //NpgsqlCommand command = new NpgsqlCommand("set DATESTYLE TO ISO;select version();", this);
+ //ServerVersion = new Version(PGUtil.ExtractServerVersion((string) command.ExecuteScalar()));
+ using(NpgsqlCommand command = new NpgsqlCommand("set DATESTYLE TO ISO;select version();", this))
+ {
+ ServerVersion = new Version(PGUtil.ExtractServerVersion((string) command.ExecuteScalar()));
+ }
}
// Adjust client encoding.
@@ -875,7 +891,7 @@ internal void CancelRequest()
///</summary>
internal String NextPortalName()
{
- return _portalNamePrefix + Interlocked.Increment(ref _portalIndex);
+ return _portalNamePrefix + Interlocked.Increment(ref _portalIndex).ToString();
}
@@ -884,7 +900,7 @@ internal String NextPortalName()
///</summary>
internal String NextPlanName()
{
- return _planNamePrefix + Interlocked.Increment(ref _planIndex);
+ return _planNamePrefix + Interlocked.Increment(ref _planIndex).ToString();
}
View
1,183 src/Npgsql/NpgsqlConnectorPool.cs
@@ -1,6 +1,6 @@
-// Copyright (C) 2002 The Npgsql Development Team
-// npgsql-general@gborg.postgresql.org
-// http://gborg.postgresql.org/project/npgsql/projdisplay.php
+// Copyright (C) 2002 The Npgsql Development Team
+// npgsql-general@gborg.postgresql.org
+// http://gborg.postgresql.org/project/npgsql/projdisplay.php
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose, without fee, and without a written
@@ -19,11 +19,11 @@
// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
-// ConnectorPool.cs
+// ConnectorPool.cs
// ------------------------------------------------------------------
-// Status
-// 0.00.0000 - 06/17/2002 - ulrich sprick - creation
-// - 05/??/2004 - Glen Parker<glenebob@nwlink.com> rewritten using
+// Status
+// 0.00.0000 - 06/17/2002 - ulrich sprick - creation
+// - 05/??/2004 - Glen Parker<glenebob@nwlink.com> rewritten using
// System.Queue.
using System;
@@ -35,591 +35,666 @@
namespace Npgsql
{
- /// <summary>
- /// This class manages all connector objects, pooled AND non-pooled.
- /// </summary>
- internal class NpgsqlConnectorPool
- {
- /// <summary>
- /// A queue with an extra Int32 for keeping track of busy connections.
- /// </summary>
- private class ConnectorQueue
- {
- /// <summary>
- /// Connections available to the end user
- /// </summary>
- public Queue<NpgsqlConnector> Available = new Queue<NpgsqlConnector>();
-
- /// <summary>
- /// Connections currently in use
- /// </summary>
- public Dictionary<NpgsqlConnector, object> Busy = new Dictionary<NpgsqlConnector, object>();
-
- public Int32 ConnectionLifeTime;
- public Int32 InactiveTime = 0;
- public Int32 MinPoolSize;
- }
-
- /// <value>Unique static instance of the connector pool
- /// mamager.</value>
- internal static NpgsqlConnectorPool ConnectorPoolMgr = new NpgsqlConnectorPool();
-
- public NpgsqlConnectorPool()
- {
- PooledConnectors = new Dictionary<string, ConnectorQueue>();
- Timer = new Timer(1000);
- Timer.AutoReset = false;
- Timer.Elapsed += new ElapsedEventHandler(TimerElapsedHandler);
- Timer.Start();
+ /// <summary>
+ /// This class manages all connector objects, pooled AND non-pooled.
+ /// </summary>
+ internal class NpgsqlConnectorPool
+ {
+ /// <summary>
+ /// A queue with an extra Int32 for keeping track of busy connections.
+ /// </summary>
+ private class ConnectorQueue
+ {
+ /// <summary>
+ /// Connections available to the end user
+ /// </summary>
+ public Queue<NpgsqlConnector> Available = new Queue<NpgsqlConnector>();
+
+ /// <summary>
+ /// Connections currently in use
+ /// </summary>
+ public Dictionary<NpgsqlConnector, object> Busy = new Dictionary<NpgsqlConnector, object>();
+
+ public Int32 ConnectionLifeTime;
+ public Int32 InactiveTime = 0;
+ public Int32 MinPoolSize;
+ }
+
+ /// <value>Unique static instance of the connector pool
+ /// mamager.</value>
+ internal static NpgsqlConnectorPool ConnectorPoolMgr = new NpgsqlConnectorPool();
+
+ private object locker = new object();
+
+
+ public NpgsqlConnectorPool()
+ {
+ PooledConnectors = new Dictionary<string, ConnectorQueue>();
+ Timer = new Timer(1000);
+ Timer.AutoReset = false;
+ Timer.Elapsed += new ElapsedEventHandler(TimerElapsedHandler);
+ Timer.Start();
- }
+ }
- ~NpgsqlConnectorPool()
- {
- Timer.Stop();
+ ~NpgsqlConnectorPool()
+ {
+ Timer.Stop();
- }
+ }
- private void TimerElapsedHandler(object sender, ElapsedEventArgs e)
- {
- NpgsqlConnector Connector;
+ private void TimerElapsedHandler(object sender, ElapsedEventArgs e)
+ {
+ NpgsqlConnector Connector;
try
{
- lock (this)
- {
- foreach (ConnectorQueue Queue in PooledConnectors.Values)
- {
- if (Queue.Available.Count > 0)
- {
- if (Queue.Available.Count + Queue.Busy.Count > Queue.MinPoolSize)
- {
- if (Queue.InactiveTime >= Queue.ConnectionLifeTime)
- {
- Int32 diff = Queue.Available.Count + Queue.Busy.Count - Queue.MinPoolSize;
- Int32 toBeClosed = (diff + 1) / 2;
- toBeClosed = Math.Min(toBeClosed, Queue.Available.Count);
-
- if (diff < 2)
- {
- diff = 2;
- }
- Queue.InactiveTime -= Queue.ConnectionLifeTime / (int)(Math.Log(diff) / Math.Log(2));
- for (Int32 i = 0; i < toBeClosed; ++i)
- {
- Connector = Queue.Available.Dequeue();
- Connector.Close();
- }
- }
- else
- {
- Queue.InactiveTime++;
- }
- }
- else
- {
- Queue.InactiveTime = 0;
- }
- }
- else
- {
- Queue.InactiveTime = 0;
- }
- }
- }
+ lock (locker)
+ {
+ foreach (ConnectorQueue Queue in PooledConnectors.Values)
+ {
+ lock (Queue)
+ {
+ if (Queue.Available.Count > 0)
+ {
+ if (Queue.Available.Count + Queue.Busy.Count > Queue.MinPoolSize)
+ {
+ if (Queue.InactiveTime >= Queue.ConnectionLifeTime)
+ {
+ Int32 diff = Queue.Available.Count + Queue.Busy.Count - Queue.MinPoolSize;
+ Int32 toBeClosed = (diff + 1) / 2;
+ toBeClosed = Math.Min(toBeClosed, Queue.Available.Count);
+
+ if (diff < 2)
+ {
+ diff = 2;
+ }
+
+ Queue.InactiveTime -= Queue.ConnectionLifeTime / (int)(Math.Log(diff) / Math.Log(2));
+
+ for (Int32 i = 0; i < toBeClosed; ++i)
+ {
+ Connector = Queue.Available.Dequeue();
+ Connector.Close();
+ }
+ }
+ else
+ {
+ Queue.InactiveTime++;
+ }
+ }
+ else
+ {
+ Queue.InactiveTime = 0;
+ }
+ }
+ else
+ {
+ Queue.InactiveTime = 0;
+ }
+ }
+ }
+ }
}
finally
{
Timer.Start();
-
}
- }
+ }
- /// <value>Map of index to unused pooled connectors, avaliable to the
- /// next RequestConnector() call.</value>
- /// <remarks>This hashmap will be indexed by connection string.
- /// This key will hold a list of queues of pooled connectors available to be used.</remarks>
- private readonly Dictionary<string, ConnectorQueue> PooledConnectors;
+ /// <value>Map of index to unused pooled connectors, avaliable to the
+ /// next RequestConnector() call.</value>
+ /// <remarks>This hashmap will be indexed by connection string.
+ /// This key will hold a list of queues of pooled connectors available to be used.</remarks>
+ private readonly Dictionary<string, ConnectorQueue> PooledConnectors;
- /*/// <value>Map of shared connectors, avaliable to the
+ /*/// <value>Map of shared connectors, avaliable to the
/// next RequestConnector() call.</value>
/// <remarks>This hashmap will be indexed by connection string.
/// This key will hold a list of shared connectors available to be used.</remarks>
// To be implemented
//private Dictionary<?, ?> SharedConnectors;*/
- /// <value>Timer for tracking unused connections in pools.</value>
- // I used System.Timers.Timer because of bad experience with System.Threading.Timer
- // on Windows - it's going mad sometimes and don't respect interval was set.
- private readonly Timer Timer;
-
- /// <summary>
- /// Searches the shared and pooled connector lists for a
- /// matching connector object or creates a new one.
- /// </summary>
- /// <param name="Connection">The NpgsqlConnection that is requesting
- /// the connector. Its ConnectionString will be used to search the
- /// pool for available connectors.</param>
- /// <returns>A connector object.</returns>
- public NpgsqlConnector RequestConnector(NpgsqlConnection Connection)
- {
- NpgsqlConnector Connector;
-
- if (Connection.Pooling)
- {
- Connector = RequestPooledConnector(Connection);
- }
- else
- {
- Connector = GetNonPooledConnector(Connection);
- }
-
- return Connector;
- }
-
- /// <summary>
- /// Find a pooled connector. Handle locking and timeout here.
- /// </summary>
- private NpgsqlConnector RequestPooledConnector(NpgsqlConnection Connection)
- {
- NpgsqlConnector Connector;
- Int32 timeoutMilliseconds = Connection.Timeout * 1000;
-
- lock (this)
- {
- Connector = RequestPooledConnectorInternal(Connection);
- }
-
- while (Connector == null && timeoutMilliseconds > 0)
- {
- Int32 ST = timeoutMilliseconds > 1000 ? 1000 : timeoutMilliseconds;
-
- Thread.Sleep(ST);
- timeoutMilliseconds -= ST;
-
- lock (this)
- {
- Connector = RequestPooledConnectorInternal(Connection);
- }
- }
-
- if (Connector == null)
- {
- if (Connection.Timeout > 0)
- {
- throw new Exception("Timeout while getting a connection from pool.");
- }
- else
- {
- throw new Exception("Connection pool exceeds maximum size.");
- }
- }
-
- return Connector;
- }
-
- /// <summary>
- /// Find a pooled connector. Handle shared/non-shared here.
- /// </summary>
- private NpgsqlConnector RequestPooledConnectorInternal(NpgsqlConnection Connection)
- {
- NpgsqlConnector Connector = null;
- Boolean Shared = false;
-
- // If sharing were implemented, I suppose Shared would be set based
- // on some property on the Connection.
-
- if (Shared)
- {
- // Connection sharing? What's that?
- throw new NotImplementedException("Internal: Shared pooling not implemented");
-
- }
- Connector = GetPooledConnector(Connection);
-
-
- return Connector;
- }
-
- private delegate void CleanUpConnectorDel(NpgsqlConnection Connection, NpgsqlConnector Connector);
-
- private void CleanUpConnectorMethod(NpgsqlConnection Connection, NpgsqlConnector Connector)
- {
- try
- {
- Connector.CurrentReader.Close();
- Connector.CurrentReader = null;
- ReleaseConnector(Connection, Connector);
- }
- catch
- {
- }
- }
-
- private void CleanUpConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
- {
- new CleanUpConnectorDel(CleanUpConnectorMethod).BeginInvoke(Connection, Connector, null, null);
- }
-
- /// <summary>
- /// Releases a connector, possibly back to the pool for future use.
- /// </summary>
- /// <remarks>
- /// Pooled connectors will be put back into the pool if there is room.
- /// Shared connectors should just have their use count decremented
- /// since they always stay in the shared pool.
- /// </remarks>
- /// <param name="Connector">The connector to release.</param>
- public void ReleaseConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
- {
- //We can only clean up a connector with a reader if the current thread hasn't been aborted
- //If it has then we need to just close it (ReleasePooledConnector will do this for an aborted thread)
- if (Connector.CurrentReader != null && (Thread.CurrentThread.ThreadState & (ThreadState.Aborted | ThreadState.AbortRequested)) == 0)
- {
- CleanUpConnector(Connection, Connector);
- }
- else if (Connector.Pooled)
- {
- ReleasePooledConnector(Connection, Connector);
- }
- else
- {
- UngetNonPooledConnector(Connection, Connector);
- }
- }
-
- /// <summary>
- /// Release a pooled connector. Handle locking here.
- /// </summary>
- private void ReleasePooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
- {
- lock (this)
- {
- ReleasePooledConnectorInternal(Connection, Connector);
- }
- }
-
- /// <summary>
- /// Release a pooled connector. Handle shared/non-shared here.
- /// </summary>
- private void ReleasePooledConnectorInternal(NpgsqlConnection Connection, NpgsqlConnector Connector)
- {
- if (!Connector.Shared)
- {
- UngetPooledConnector(Connection, Connector);
- }
- else
- {
- // Connection sharing? What's that?
- throw new NotImplementedException("Internal: Shared pooling not implemented");
- }
- }
-
- /// <summary>
- /// Create a connector without any pooling functionality.
- /// </summary>
- private static NpgsqlConnector GetNonPooledConnector(NpgsqlConnection Connection)
- {
- NpgsqlConnector Connector;
-
- Connector = CreateConnector(Connection);
+ /// <value>Timer for tracking unused connections in pools.</value>
+ // I used System.Timers.Timer because of bad experience with System.Threading.Timer
+ // on Windows - it's going mad sometimes and don't respect interval was set.
+ private readonly Timer Timer;
+
+ /// <summary>
+ /// Searches the shared and pooled connector lists for a
+ /// matching connector object or creates a new one.
+ /// </summary>
+ /// <param name="Connection">The NpgsqlConnection that is requesting
+ /// the connector. Its ConnectionString will be used to search the
+ /// pool for available connectors.</param>
+ /// <returns>A connector object.</returns>
+ public NpgsqlConnector RequestConnector(NpgsqlConnection Connection)
+ {
+ NpgsqlConnector Connector;
+
+ if (Connection.Pooling)
+ {
+ Connector = RequestPooledConnector(Connection);
+ }
+ else
+ {
+ Connector = GetNonPooledConnector(Connection);
+ }
+
+ return Connector;
+ }
+
+ /// <summary>
+ /// Find a pooled connector. Handle locking and timeout here.
+ /// </summary>
+ private NpgsqlConnector RequestPooledConnector(NpgsqlConnection Connection)
+ {
+ NpgsqlConnector Connector;
+ Int32 timeoutMilliseconds = Connection.Timeout * 1000;
+
+ // No need for this lock anymore
+ //lock (this)
+ {
+ Connector = RequestPooledConnectorInternal(Connection);
+ }
+
+ while (Connector == null && timeoutMilliseconds > 0)
+ {
+
+ Int32 ST = timeoutMilliseconds > 1000 ? 1000 : timeoutMilliseconds;
+
+ Thread.Sleep(ST);
+ timeoutMilliseconds -= ST;
+
+
+ //lock (this)
+ {
+ Connector = RequestPooledConnectorInternal(Connection);
+ }
+ }
+
+ if (Connector == null)
+ {
+ if (Connection.Timeout > 0)
+ {
+ throw new Exception("Timeout while getting a connection from pool.");
+ }
+ else
+ {
+ throw new Exception("Connection pool exceeds maximum size.");
+ }
+ }
+
+ return Connector;
+ }
+
+ /// <summary>
+ /// Find a pooled connector. Handle shared/non-shared here.
+ /// </summary>
+ private NpgsqlConnector RequestPooledConnectorInternal(NpgsqlConnection Connection)
+ {
+ NpgsqlConnector Connector = null;
+ Boolean Shared = false;
+
+ // If sharing were implemented, I suppose Shared would be set based
+ // on some property on the Connection.
+
+ if (Shared)
+ {
+ // Connection sharing? What's that?
+ throw new NotImplementedException("Internal: Shared pooling not implemented");
+
+ }
+ Connector = GetPooledConnector(Connection);
+
+
+ return Connector;
+ }
+
+ private delegate void CleanUpConnectorDel(NpgsqlConnection Connection, NpgsqlConnector Connector);
+
+ private void CleanUpConnectorMethod(NpgsqlConnection Connection, NpgsqlConnector Connector)
+ {
+ try
+ {
+ Connector.CurrentReader.Close();
+ Connector.CurrentReader = null;
+ ReleaseConnector(Connection, Connector);
+ }
+ catch
+ {
+ }
+ }
+
+ private void CleanUpConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
+ {
+ new CleanUpConnectorDel(CleanUpConnectorMethod).BeginInvoke(Connection, Connector, null, null);
+ }
+
+ /// <summary>
+ /// Releases a connector, possibly back to the pool for future use.
+ /// </summary>
+ /// <remarks>
+ /// Pooled connectors will be put back into the pool if there is room.
+ /// Shared connectors should just have their use count decremented
+ /// since they always stay in the shared pool.
+ /// </remarks>
+ /// <param name="Connector">The connector to release.</param>
+ public void ReleaseConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
+ {
+ //We can only clean up a connector with a reader if the current thread hasn't been aborted
+ //If it has then we need to just close it (ReleasePooledConnector will do this for an aborted thread)
+ if (Connector.CurrentReader != null && (Thread.CurrentThread.ThreadState & (ThreadState.Aborted | ThreadState.AbortRequested)) == 0)
+ {
+ CleanUpConnector(Connection, Connector);
+ }
+ else if (Connector.Pooled)
+ {
+ ReleasePooledConnector(Connection, Connector);
+ }
+ else
+ {
+ UngetNonPooledConnector(Connection, Connector);
+ }
+ }
+
+ /// <summary>
+ /// Release a pooled connector. Handle locking here.
+ /// </summary>
+ private void ReleasePooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
+ {
+ //lock (this)
+ {
+ ReleasePooledConnectorInternal(Connection, Connector);
+ }
+ }
+
+ /// <summary>
+ /// Release a pooled connector. Handle shared/non-shared here.
+ /// </summary>
+ private void ReleasePooledConnectorInternal(NpgsqlConnection Connection, NpgsqlConnector Connector)
+ {
+ if (!Connector.Shared)
+ {
+ UngetPooledConnector(Connection, Connector);
+ }
+ else
+ {
+ // Connection sharing? What's that?
+ throw new NotImplementedException("Internal: Shared pooling not implemented");
+ }
+ }
+
+ /// <summary>
+ /// Create a connector without any pooling functionality.
+ /// </summary>
+ private static NpgsqlConnector GetNonPooledConnector(NpgsqlConnection Connection)
+ {
+ NpgsqlConnector Connector;
+
+ Connector = CreateConnector(Connection);
Connector.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
Connector.CertificateSelectionCallback += Connection.CertificateSelectionCallbackDelegate;
Connector.CertificateValidationCallback += Connection.CertificateValidationCallbackDelegate;
Connector.PrivateKeySelectionCallback += Connection.PrivateKeySelectionCallbackDelegate;
- Connector.Open();
-
- return Connector;
- }
-
- /// <summary>
- /// Find an available pooled connector in the non-shared pool, or create
- /// a new one if none found.
- /// </summary>
- private NpgsqlConnector GetPooledConnector(NpgsqlConnection Connection)
- {
- ConnectorQueue Queue;
- NpgsqlConnector Connector = null;
-
- // Try to find a queue.
- if (!PooledConnectors.TryGetValue(Connection.ConnectionString, out Queue))
- {
- Queue = new ConnectorQueue();
- Queue.ConnectionLifeTime = Connection.ConnectionLifeTime;
- Queue.MinPoolSize = Connection.MinPoolSize;
- PooledConnectors[Connection.ConnectionString] = Queue;
- }
-
- if (Queue.Available.Count > 0)
- {
- // Found a queue with connectors. Grab the top one.
-
- // Check if the connector is still valid.
-
- Connector = Queue.Available.Dequeue();
- if (!Connector.IsValid())
- {
- Connector.Close();
-
- return GetPooledConnector(Connection); //Try again
- }
- Queue.Busy.Add(Connector, null);
- }
- else if (Queue.Available.Count + Queue.Busy.Count < Connection.MaxPoolSize)
- {
- Connector = CreateConnector(Connection);
-
- Connector.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
- Connector.CertificateSelectionCallback += Connection.CertificateSelectionCallbackDelegate;
- Connector.CertificateValidationCallback += Connection.CertificateValidationCallbackDelegate;
- Connector.PrivateKeySelectionCallback += Connection.PrivateKeySelectionCallbackDelegate;
-
- try
- {
- Connector.Open();
- }
- catch
- {
- Connector.Close();
-
- throw;
- }
-
-
- Queue.Busy.Add(Connector, null);
- }
-
- // Meet the MinPoolSize requirement if needed.
- if (Connection.MinPoolSize > 0)
- {
- while (Queue.Available.Count + Queue.Busy.Count < Connection.MinPoolSize)
- {
- NpgsqlConnector Spare = CreateConnector(Connection);
-
- Spare.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
- Spare.CertificateSelectionCallback += Connection.CertificateSelectionCallbackDelegate;
- Spare.CertificateValidationCallback += Connection.CertificateValidationCallbackDelegate;
- Spare.PrivateKeySelectionCallback += Connection.PrivateKeySelectionCallbackDelegate;
-
- Spare.Open();
-
- Spare.ProvideClientCertificatesCallback -= Connection.ProvideClientCertificatesCallbackDelegate;
- Spare.CertificateSelectionCallback -= Connection.CertificateSelectionCallbackDelegate;
- Spare.CertificateValidationCallback -= Connection.CertificateValidationCallbackDelegate;
- Spare.PrivateKeySelectionCallback -= Connection.PrivateKeySelectionCallbackDelegate;
-
- Queue.Available.Enqueue(Spare);
- }
- }
-
- return Connector;
- }
-
- /*
- /// <summary>
- /// Find an available shared connector in the shared pool, or create
- /// a new one if none found.
- /// </summary>
- private NpgsqlConnector GetSharedConnector(NpgsqlConnection Connection)
- {
- // To be implemented
-
- return null;
- }
- */
-
- private static NpgsqlConnector CreateConnector(NpgsqlConnection Connection)
- {
- return new NpgsqlConnector(Connection.ConnectionStringValues.Clone(), Connection.Pooling, false);
- }
-
-
- /// <summary>
- /// This method is only called when NpgsqlConnection.Dispose(false) is called which means a
- /// finalization. This also means, an NpgsqlConnection was leak. We clear pool count so that
- /// client doesn't end running out of connections from pool. When the connection is finalized, its underlying
- /// socket is closed.
- /// </summary>
- public void FixPoolCountBecauseOfConnectionDisposeFalse(NpgsqlConnection Connection)
- {
- ConnectorQueue Queue;
-
- // Prevent multithread access to connection pool count.
- lock (this)
- {
- // Try to find a queue.
+ Connector.Open();
+
+ return Connector;
+ }
+
+
+ /// <summary>
+ /// Find an available pooled connector in the non-shared pool, or create
+ /// a new one if none found.
+ /// </summary>
+ private NpgsqlConnector GetPooledConnector(NpgsqlConnection Connection)
+ {
+ ConnectorQueue Queue;
+ NpgsqlConnector Connector = null;
+
+
+ // We only need to lock all pools when trying to get one pool or create one.
+
+ lock (locker)
+ {
+
+ // Try to find a queue.
+ if (!PooledConnectors.TryGetValue(Connection.ConnectionString, out Queue))
+ {
+
+ Queue = new ConnectorQueue();
+ Queue.ConnectionLifeTime = Connection.ConnectionLifeTime;
+ Queue.MinPoolSize = Connection.MinPoolSize;
+ PooledConnectors[Connection.ConnectionString] = Queue;
+ }
+ }
+
+
+ // Now we can simply lock on the pool itself.
+ lock (Queue)
+ {
+
+
+ if (Queue.Available.Count > 0)
+ {
+ // Found a queue with connectors. Grab the top one.
+
+ // Check if the connector is still valid.
+
+ Connector = Queue.Available.Dequeue();
+ Queue.Busy.Add(Connector, null);
+ }
+ }
+
+ if (Connector != null)
+ {
+ if (!Connector.IsValid())
+ {
+ lock (Queue)
+ {
+ Queue.Busy.Remove(Connector);
+ }
+
+
+ Connector.Close();
+ return GetPooledConnector(Connection); //Try again
+ }
+
+ return Connector;
+ }
+
+
+ lock (Queue)
+ {
+
+ if (Queue.Available.Count + Queue.Busy.Count < Connection.MaxPoolSize)
+ {
+ Connector = CreateConnector(Connection);
+ Queue.Busy.Add(Connector, null);
+
+ }
+
+ }
+
+
+ if (Connector != null)
+ {
+
+ Connector.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
+ Connector.CertificateSelectionCallback += Connection.CertificateSelectionCallbackDelegate;
+ Connector.CertificateValidationCallback += Connection.CertificateValidationCallbackDelegate;
+ Connector.PrivateKeySelectionCallback += Connection.PrivateKeySelectionCallbackDelegate;
+
+ try
+ {
+ Connector.Open();
+ }
+ catch
+ {
+ lock (Queue)
+ {
+ Queue.Busy.Remove(Connector);
+ }
+
+ Connector.Close();
+
+ throw;
+ }
+
+
+ // Meet the MinPoolSize requirement if needed.
+ if (Connection.MinPoolSize > 1)
+ {
+
+ lock (Queue)
+ {
+
+ while (Queue.Available.Count + Queue.Busy.Count < Connection.MinPoolSize)
+ {
+ NpgsqlConnector Spare = CreateConnector(Connection);
+
+ Spare.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
+ Spare.CertificateSelectionCallback += Connection.CertificateSelectionCallbackDelegate;
+ Spare.CertificateValidationCallback += Connection.CertificateValidationCallbackDelegate;
+ Spare.PrivateKeySelectionCallback += Connection.PrivateKeySelectionCallbackDelegate;
+
+ Spare.Open();
+
+ Spare.ProvideClientCertificatesCallback -= Connection.ProvideClientCertificatesCallbackDelegate;
+ Spare.CertificateSelectionCallback -= Connection.CertificateSelectionCallbackDelegate;
+ Spare.CertificateValidationCallback -= Connection.CertificateValidationCallbackDelegate;
+ Spare.PrivateKeySelectionCallback -= Connection.PrivateKeySelectionCallbackDelegate;
+
+ Queue.Available.Enqueue(Spare);
+ }
+ }
+ }
+ }
+
+
+ return Connector;
+ }
+
+ /*
+ /// <summary>
+ /// Find an available shared connector in the shared pool, or create
+ /// a new one if none found.
+ /// </summary>
+ private NpgsqlConnector GetSharedConnector(NpgsqlConnection Connection)
+ {
+ // To be implemented
+
+ return null;
+ }
+ */
+
+ private static NpgsqlConnector CreateConnector(NpgsqlConnection Connection)
+ {
+ return new NpgsqlConnector(Connection.ConnectionStringValues.Clone(), Connection.Pooling, false);
+ }
+
+
+ /// <summary>
+ /// This method is only called when NpgsqlConnection.Dispose(false) is called which means a
+ /// finalization. This also means, an NpgsqlConnection was leak. We clear pool count so that
+ /// client doesn't end running out of connections from pool. When the connection is finalized, its underlying
+ /// socket is closed.
+ /// </summary>
+ public void FixPoolCountBecauseOfConnectionDisposeFalse(NpgsqlConnection Connection)
+ {
+ ConnectorQueue Queue;
+
+ // Prevent multithread access to connection pool count.
+ lock (locker)
+ {
+ // Try to find a queue.
if (PooledConnectors.TryGetValue(Connection.ConnectionString, out Queue) && Queue != null)
- {
- Queue.Busy.Remove(Connection.Connector);
- }
- }
- }
-
- /// <summary>
- /// Close the connector.
- /// </summary>
- /// <param name="Connection"></param>
- /// <param name="Connector">Connector to release</param>
- private static void UngetNonPooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
- {
+ {
+ Queue.Busy.Remove(Connection.Connector);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Close the connector.
+ /// </summary>
+ /// <param name="Connection"></param>
+ /// <param name="Connector">Connector to release</param>
+ private static void UngetNonPooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
+ {
Connector.ProvideClientCertificatesCallback -= Connection.ProvideClientCertificatesCallbackDelegate;
- Connector.CertificateSelectionCallback -= Connection.CertificateSelectionCallbackDelegate;
- Connector.CertificateValidationCallback -= Connection.CertificateValidationCallbackDelegate;
- Connector.PrivateKeySelectionCallback -= Connection.PrivateKeySelectionCallbackDelegate;
-
- if (Connector.Transaction != null)
- {
- Connector.Transaction.Cancel();
- }
-
- Connector.Close();
- }
-
- /// <summary>
- /// Put a pooled connector into the pool queue.
- /// </summary>
- /// <param name="Connector">Connector to pool</param>
- private void UngetPooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
- {
- ConnectorQueue queue;
-
- // Find the queue.
- if (!PooledConnectors.TryGetValue(Connection.ConnectionString, out queue) || queue == null)
- {
- Connector.Close(); // Release connection to postgres
- return; // Queue may be emptied by connection problems. See ClearPool below.
- }
+ Connector.CertificateSelectionCallback -= Connection.CertificateSelectionCallbackDelegate;
+ Connector.CertificateValidationCallback -= Connection.CertificateValidationCallbackDelegate;
+ Connector.PrivateKeySelectionCallback -= Connection.PrivateKeySelectionCallbackDelegate;
+
+ if (Connector.Transaction != null)
+ {
+ Connector.Transaction.Cancel();
+ }
+
+ Connector.Close();
+ }
+
+ /// <summary>
+ /// Put a pooled connector into the pool queue.
+ /// </summary>
+ /// <param name="Connector">Connector to pool</param>
+ private void UngetPooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
+ {
+ ConnectorQueue queue;
+
+ // Find the queue.
+ // As we are handling all possible queues, we have to lock everything...
+ lock (locker)
+ {
+ PooledConnectors.TryGetValue(Connection.ConnectionString, out queue);
+ }
+
+
+ if (queue == null)
+ {
+ Connector.Close(); // Release connection to postgres
+ return; // Queue may be emptied by connection problems. See ClearPool below.
+ }
Connector.ProvideClientCertificatesCallback -= Connection.ProvideClientCertificatesCallbackDelegate;
- Connector.CertificateSelectionCallback -= Connection.CertificateSelectionCallbackDelegate;
- Connector.CertificateValidationCallback -= Connection.CertificateValidationCallbackDelegate;
- Connector.PrivateKeySelectionCallback -= Connection.PrivateKeySelectionCallbackDelegate;
-
- bool inQueue = queue.Busy.ContainsKey(Connector);
- queue.Busy.Remove(Connector);
-
- if (!Connector.IsInitialized)
- {
- if (Connector.Transaction != null)
- {
- Connector.Transaction.Cancel();
- }
-
- Connector.Close();
- }
- else
- {
- if (Connector.Transaction != null)
- {
- try
- {
- Connector.Transaction.Rollback();
- }
- catch
- {
- Connector.Close();
- }
- }
- }
-
- if (Connector.State == ConnectionState.Open)
- {
- //If thread is good
- if ((Thread.CurrentThread.ThreadState & (ThreadState.Aborted | ThreadState.AbortRequested)) == 0)
- {
- // Release all resources associated with this connector.
- try
- {
- Connector.ReleaseResources();
- }
- catch (Exception)
- {
- //If the connector fails to release its resources then it is probably broken, so make sure we don't add it to the queue.
- // Usually it already won't be in the queue as it would of broken earlier
- inQueue = false;
- }
-
- if (inQueue)
- queue.Available.Enqueue(Connector);
- else
- Connector.Close();
- }
- else
- {
- //Thread is being aborted, this connection is possibly broken. So kill it rather than returning it to the pool
- Connector.Close();
- }
- }
- }
-
- /*
- /// <summary>
- /// Stop sharing a shared connector.
- /// </summary>
- /// <param name="Connector">Connector to unshare</param>
- private void UngetSharedConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
- {
- // To be implemented
- }
- */
-
- private static void ClearQueue(ConnectorQueue Queue)
- {
- if (Queue == null)
- {
- return;
- }
-
- while (Queue.Available.Count > 0)
- {
- NpgsqlConnector connector = Queue.Available.Dequeue();
-
- try
- {
- connector.Close();
- }
- catch
- {
- // Maybe we should log something here to say we got an exception while closing connector?
- }
- }
-
- //Clear the busy list so that the current connections don't get re-added to the queue
- Queue.Busy.Clear();
- }
-
-
- internal void ClearPool(NpgsqlConnection Connection)
- {
- // Prevent multithread access to connection pool count.
- lock (this)
- {
+ Connector.CertificateSelectionCallback -= Connection.CertificateSelectionCallbackDelegate;
+ Connector.CertificateValidationCallback -= Connection.CertificateValidationCallbackDelegate;
+ Connector.PrivateKeySelectionCallback -= Connection.PrivateKeySelectionCallbackDelegate;
+
+ bool inQueue = false;
+
+ lock (queue)
+ {
+ inQueue = queue.Busy.ContainsKey(Connector);
+ queue.Busy.Remove(Connector);
+ }
+
+ if (!Connector.IsInitialized)
+ {
+ if (Connector.Transaction != null)
+ {
+ Connector.Transaction.Cancel();
+ }
+
+ Connector.Close();
+ }
+ else
+ {
+ if (Connector.Transaction != null)
+ {
+ try
+ {
+ Connector.Transaction.Rollback();
+ }
+ catch
+ {
+ Connector.Close();
+ }
+ }
+ }
+
+ if (Connector.State == ConnectionState.Open)
+ {
+ //If thread is good
+ if ((Thread.CurrentThread.ThreadState & (ThreadState.Aborted | ThreadState.AbortRequested)) == 0)
+ {
+ // Release all resources associated with this connector.
+ try
+ {
+ Connector.ReleaseResources();
+ }
+ catch (Exception)
+ {
+ //If the connector fails to release its resources then it is probably broken, so make sure we don't add it to the queue.
+ // Usually it already won't be in the queue as it would of broken earlier
+ inQueue = false;
+ }
+
+ if (inQueue)
+ lock (queue)
+ {
+ queue.Available.Enqueue(Connector);
+ }
+ else
+ Connector.Close();
+ }
+ else
+ {
+ //Thread is being aborted, this connection is possibly broken. So kill it rather than returning it to the pool
+ Connector.Close();
+ }
+ }
+ }
+
+ /*
+ /// <summary>
+ /// Stop sharing a shared connector.
+ /// </summary>
+ /// <param name="Connector">Connector to unshare</param>
+ private void UngetSharedConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
+ {
+ // To be implemented
+ }
+ */
+
+ private static void ClearQueue(ConnectorQueue Queue)
+ {
+ if (Queue == null)
+ {
+ return;
+ }
+
+ while (Queue.Available.Count > 0)
+ {
+ NpgsqlConnector connector = Queue.Available.Dequeue();
+
+ try
+ {
+ connector.Close();
+ }
+ catch
+ {
+ // Maybe we should log something here to say we got an exception while closing connector?
+ }
+ }
+
+ //Clear the busy list so that the current connections don't get re-added to the queue
+ Queue.Busy.Clear();
+ }
+
+
+ internal void ClearPool(NpgsqlConnection Connection)
+ {
+ // Prevent multithread access to connection pool count.
+ lock (locker)
+ {
ConnectorQueue queue;
- // Try to find a queue.
+ // Try to find a queue.
if (PooledConnectors.TryGetValue(Connection.ConnectionString, out queue))
{
ClearQueue(queue);
PooledConnectors.Remove(Connection.ConnectionString);
}
- }
- }
-
-
- internal void ClearAllPools()
- {
- lock (this)
- {
- foreach (ConnectorQueue Queue in PooledConnectors.Values)
- {
- ClearQueue(Queue);
- }
+ }
+ }
+
+
+ internal void ClearAllPools()
+ {
+ lock (locker)
+ {
+ foreach (ConnectorQueue Queue in PooledConnectors.Values)
+ {
+ ClearQueue(Queue);
+ }
PooledConnectors.Clear();
- }
- }
- }
+ }
+ }
+ }
}
View
6 src/Npgsql/NpgsqlState.cs
@@ -128,7 +128,11 @@ public void TestNotify(NpgsqlConnector context)
case -1:
throw new EndOfStreamException();
case 'Z':
- context.Query(new NpgsqlCommand("UNLISTEN *", context));
+ //context.Query(new NpgsqlCommand("UNLISTEN *", context));
+ using(NpgsqlCommand cmd = new NpgsqlCommand("UNLISTEN *", context))
+ {
+ context.Query(cmd);
+ }
return;
}
}
View
6 src/Npgsql/PGUtil.cs
@@ -78,6 +78,9 @@ internal static class PGUtil
private static readonly byte[] THRASH_CAN = new byte[THRASH_CAN_SIZE];
private static readonly Encoding ENCODING_UTF8 = Encoding.UTF8;
+ private static readonly string NULL_TERMINATOR_STRING = '\x00'.ToString();
+
+
///<summary>
@@ -344,11 +347,12 @@ public static int PessimisticGetCharCount(byte[] buffer, int index, int count)
/// </summary>
public static void WriteString(String the_string, Stream network_stream)
{
+
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteString");
NpgsqlEventLog.LogMsg(resman, "Log_StringWritten", LogLevel.Debug, the_string);
- byte[] bytes = ENCODING_UTF8.GetBytes(the_string + '\x00');
+ byte[] bytes = ENCODING_UTF8.GetBytes(the_string + NULL_TERMINATOR_STRING);
network_stream.Write(bytes, 0, bytes.Length);
}
View
10 src/NpgsqlTypes/BitString.cs
@@ -671,18 +671,18 @@ public string ToString(string format)
case 'Y':
return ZeroPad(XFormatString(true, false), padTo).Insert(0, "X'").Append('\'').ToString();
case 'c':
- return ToString((_lastChunkLen %4 == 0 ? "y" : "g") + padTo);
+ return ToString((_lastChunkLen %4 == 0 ? "y" : "g") + padTo.ToString());
case 'C':
- return ToString((_lastChunkLen %4 == 0 ? "Y" : "G") + padTo);
+ return ToString((_lastChunkLen %4 == 0 ? "Y" : "G") + padTo.ToString());
case 'e':
- return ToString("E" + padTo).ToLowerInvariant();
+ return ToString("E" + padTo.ToString()).ToLowerInvariant();
case 'E':
if(_lastChunkLen == 1 && _chunks.Count == 1)
return (_chunks[0] & 0x80000000u) == 0 ? "0" : "1";//both safe in this case for all lengths, and allows for some backwards compatibility from threating bit(1) as if it were boolean.
else if(_lastChunkLen % 4 == 0)
- return ToString("Y" + padTo);
+ return ToString("Y" + padTo.ToString());
else if(Length < 9)
- return ToString("G" + padTo);
+ return ToString("G" + padTo.ToString());
else
{
StringBuilder sb = XFormatString(true, true).Insert(0, "X'");
View
73 testsuite/noninteractive/NUnit20/CommandTests.cs
@@ -1762,7 +1762,7 @@ public void MultipleQueriesFirstResultsetEmpty()
public void ConnectionStringWithInvalidParameterValue()
{
- NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;User Id=npgsql_tets;Password=j");
+ NpgsqlConnection conn = new NpgsqlConnection(TheConnectionString + ";userid=npgsql_tes;pooling=false");
NpgsqlCommand command = new NpgsqlCommand("select * from tablea", conn);
@@ -1784,23 +1784,22 @@ public void ConnectionStringWithInvalidParameterValue()
[ExpectedException(typeof(ArgumentException))]
public void InvalidConnectionString()
{
+
NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;User Id=npgsql_tests;Pooling:false");
- NpgsqlCommand command = new NpgsqlCommand("select * from tablea", conn);
-
- command.Connection.Open();
- command.ExecuteReader();
- command.Connection.Close();
+ conn.Open();
+
+
}
[Test]
public void AmbiguousFunctionParameterType()
{
- NpgsqlConnection conn = new NpgsqlConnection(TheConnectionString);
+ //NpgsqlConnection conn = new NpgsqlConnection(TheConnectionString);
- NpgsqlCommand command = new NpgsqlCommand("ambiguousParameterType(:a, :b, :c, :d, :e, :f)", conn);
+ NpgsqlCommand command = new NpgsqlCommand("ambiguousParameterType(:a, :b, :c, :d, :e, :f)", TheConnection);
command.CommandType = CommandType.StoredProcedure;
NpgsqlParameter p = new NpgsqlParameter("a", DbType.Int16);
p.Value = 2;
@@ -1821,47 +1820,39 @@ public void AmbiguousFunctionParameterType()
p.Value = "a";
command.Parameters.Add(p);
-
- command.Connection.Open();
command.ExecuteScalar();
- command.Connection.Close();
+
}
[Test]
public void AmbiguousFunctionParameterTypePrepared()
{
- using (NpgsqlConnection conn = new NpgsqlConnection(TheConnectionString))
- {
-
-
- NpgsqlCommand command = new NpgsqlCommand("ambiguousParameterType(:a, :b, :c, :d, :e, :f)", conn);
- command.CommandType = CommandType.StoredProcedure;
- NpgsqlParameter p = new NpgsqlParameter("a", DbType.Int16);
- p.Value = 2;
- command.Parameters.Add(p);
- p = new NpgsqlParameter("b", DbType.Int32);
- p.Value = 2;
- command.Parameters.Add(p);
- p = new NpgsqlParameter("c", DbType.Int64);
- p.Value = 2;
- command.Parameters.Add(p);
- p = new NpgsqlParameter("d", DbType.String);
- p.Value = "a";
- command.Parameters.Add(p);
- p = new NpgsqlParameter("e", DbType.String);
- p.Value = "a";
- command.Parameters.Add(p);
- p = new NpgsqlParameter("f", DbType.String);
- p.Value = "a";
- command.Parameters.Add(p);
+ NpgsqlCommand command = new NpgsqlCommand("ambiguousParameterType(:a, :b, :c, :d, :e, :f)", TheConnection);
+ command.CommandType = CommandType.StoredProcedure;
+ NpgsqlParameter p = new NpgsqlParameter("a", DbType.Int16);
+ p.Value = 2;
+ command.Parameters.Add(p);
+ p = new NpgsqlParameter("b", DbType.Int32);
+ p.Value = 2;
+ command.Parameters.Add(p);
+ p = new NpgsqlParameter("c", DbType.Int64);
+ p.Value = 2;
+ command.Parameters.Add(p);
+ p = new NpgsqlParameter("d", DbType.String);
+ p.Value = "a";
+ command.Parameters.Add(p);
+ p = new NpgsqlParameter("e", DbType.String);
+ p.Value = "a";
+ command.Parameters.Add(p);
+ p = new NpgsqlParameter("f", DbType.String);
+ p.Value = "a";
+ command.Parameters.Add(p);
- command.Connection.Open();
- command.Prepare();
- command.ExecuteScalar();
- //command.Connection.Close();
- }
+ command.Prepare();
+ command.ExecuteScalar();
+
}
@@ -2890,7 +2881,7 @@ public void ConnectionStringCommandTimeout()
- using (NpgsqlConnection conn = new NpgsqlConnection(TheConnectionString + ";CommandTimeout=180"))
+ using (NpgsqlConnection conn = new NpgsqlConnection(TheConnectionString + ";CommandTimeout=180;pooling=false"))
{
View
27 testsuite/noninteractive/NUnit20/ConnectionTests.cs
@@ -108,7 +108,7 @@ public void ConnectionRefused()
{
try
{
- NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;Port=44444;User Id=npgsql_tets;Password=j");
+ NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;Port=44444;User Id=npgsql_tets;Password=j;pooling=false");
conn.Open();
}
@@ -147,16 +147,17 @@ public void ConnectionStringWithSemicolonSignValue()
[Test]
public void SearchPathSupport()
{
-
- NpgsqlConnection conn = new NpgsqlConnection(TheConnectionString + ";searchpath=public");
- conn.Open();
-
- NpgsqlCommand c = new NpgsqlCommand("show search_path", conn);
-
- String searchpath = (String) c.ExecuteScalar();
- //Note, public is no longer implicitly added to paths, so this is no longer "public, public".
- Assert.AreEqual("public", searchpath );
-
+
+ using (NpgsqlConnection conn = new NpgsqlConnection(TheConnectionString + ";searchpath=public;pooling=false"))
+ {
+ conn.Open();
+
+ NpgsqlCommand c = new NpgsqlCommand("show search_path", conn);
+
+ String searchpath = (String)c.ExecuteScalar();
+ //Note, public is no longer implicitly added to paths, so this is no longer "public, public".
+ Assert.AreEqual("public", searchpath);
+ }
}
@@ -182,7 +183,7 @@ public void ConnectorNotInitializedException1000581()
}
- [Test]
+ //[Test]
public void UseAllConnectionsInPool()
{
List<NpgsqlConnection> openedConnections = new List<NpgsqlConnection>();
@@ -207,7 +208,7 @@ public void UseAllConnectionsInPool()
}
}
- [Test]
+ //[Test]
[ExpectedException(typeof(Exception))]
public void ExceedConnectionsInPool()
{
View
89 testsuite/noninteractive/NUnit20/DataReaderTests.cs
@@ -150,23 +150,24 @@ public void GetBytes()
[Test]
public void GetBytesSequential()
{
- NpgsqlCommand command = new NpgsqlCommand("select field_bytea from tablef where field_serial = 1;", TheConnection);
-
- NpgsqlDataReader dr = command.ExecuteReader(CommandBehavior.SequentialAccess);
-
- dr.Read();
- Byte[] result = new Byte[2];
-
-
- Int64 a = dr.GetBytes(0, 0, result, 0, 2);
- Int64 b = dr.GetBytes(0, result.Length, result, 0, 2);
-
- Assert.AreEqual('S', (Char)result[0]);
- Assert.AreEqual('.', (Char)result[1]);
- Assert.AreEqual(2, a);
- Assert.AreEqual(0, b);
-
- dr.Close();
+ NpgsqlCommand command = new NpgsqlCommand("select field_bytea from tablef where field_serial = 1;", TheConnection);
+
+ using (NpgsqlDataReader dr = command.ExecuteReader(CommandBehavior.SequentialAccess))
+ {
+
+ dr.Read();
+ Byte[] result = new Byte[2];
+
+
+ Int64 a = dr.GetBytes(0, 0, result, 0, 2);
+ Int64 b = dr.GetBytes(0, result.Length, result, 0, 2);
+
+ Assert.AreEqual('S', (Char)result[0]);
+ Assert.AreEqual('.', (Char)result[1]);
+ Assert.AreEqual(2, a);
+ Assert.AreEqual(0, b);
+
+ }
}
@@ -1014,11 +1015,11 @@ public void CleansupOkWithDisposeCalls()
}
-
- [Test]
- public void TestOutParameter2()
- {
- NpgsqlCommand command = new NpgsqlCommand("testoutparameter2", TheConnection);
+
+ [Test]
+ public void TestOutParameter2()
+ {
+ NpgsqlCommand command = new NpgsqlCommand("testoutparameter2", TheConnection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new NpgsqlParameter("@x", NpgsqlDbType.Integer)).Value = 1;
@@ -1040,28 +1041,28 @@ public void TestOutParameter2()
}
- }
-
- [Test]
- public void GetValueWithNullFields()
- {
- NpgsqlCommand command = new NpgsqlCommand("select * from tableb", TheConnection);
- using (NpgsqlDataReader dr = command.ExecuteReader())
- {
- dr.Read();
-
- Boolean result = dr.IsDBNull(2);
-
- Assert.IsTrue(result);
-
-
-
- }
-
-
-
-
- }
+ }
+
+ [Test]
+ public void GetValueWithNullFields()
+ {
+ NpgsqlCommand command = new NpgsqlCommand("select * from tableb", TheConnection);
+ using (NpgsqlDataReader dr = command.ExecuteReader())
+ {
+ dr.Read();
+
+ Boolean result = dr.IsDBNull(2);
+
+ Assert.IsTrue(result);
+
+
+
+ }
+
+
+
+
+ }
[Test]
View
4 testsuite/noninteractive/NUnit20/SystemTransactionsTest.cs
@@ -29,7 +29,7 @@ public void DistributedTransactionRollback()
{
int field_serial1;
int field_serial2;
- string connectionString = TheConnectionString + ";enlist=true";
+ string connectionString = TheConnectionString + ";enlist=true;pooling=false";
using (TransactionScope scope = new TransactionScope())
{
//UseStringParameterWithNoNpgsqlDbType
@@ -151,7 +151,7 @@ private void AssertRowNotExist(string columnName, int field_serial)
command.Parameters.Add(new NpgsqlParameter("p0", field_serial));
object result = command.ExecuteScalar();
Assert.AreEqual(null, result);
- }
+ }
[Test]
public void TwoDistributedInSequence()

0 comments on commit 3fcafe6

Please sign in to comment.