/// <summary> /// Creates a new connection. If this is the first connection, it also creates an extra /// "Keep Alive" connection to keep the database open. /// If <paramref name="usePooledConnection"/> is true, than if this connection has been opened before, /// the connection from the pool will be returned rather than creating a new one. /// </summary> /// <param name="db">The database instance that will be used to create a connection.</param> /// <param name="usePooledConnection">If true, return an already created connection for this object. If /// false, always create a new one.</param> /// <returns>A new connection.</returns> public static DatabaseConnectionWrapper CreateConnection(SqlCeDatabase db, bool usePooledConnection) { string connectionString = db.ConnectionStringWithoutCredentials; DatabaseConnectionWrapper connection; lock (connections) { if (!connections.TryGetValue(connectionString, out connection)) { // // We have to test this again in case another thread added a connection. // if (!connections.ContainsKey(connectionString)) { DbConnection keepAliveConnection = new SqlCeConnection(); db.SetConnectionString(keepAliveConnection); keepAliveConnection.Open(); connection = new DatabaseConnectionWrapper(keepAliveConnection); connections.Add(connectionString, connection); } } if (usePooledConnection) { connection.AddRef(); return(connection); } return(new DatabaseConnectionWrapper(new SqlCeConnection())); } }
private int ExecuteNonQueryFanout(DatabaseConnectionWrapper wrapper, DbCommand command) { long?federationKey = 0; while (federationKey != null) { ExecuteFederationCommand(wrapper.Connection, FederationType.Member, federationKey, false); DoExecuteNonQueryWithRetry(command); using (DbCommand fCommand = _dbProviderFactory.CreateCommand()) { fCommand.CommandText = "SELECT CAST(range_high as bigint) FROM sys.federation_member_distributions"; PrepareCommand(fCommand, wrapper.Connection); object key = DoExecuteScalarWithRetry(fCommand); if (key != DBNull.Value) { federationKey = Convert.ToInt64(key); } else { federationKey = null; } } } return(0); }
/// <summary> /// Finishes asynchronous execution of a Transact-SQL statement, returning the requested data as XML. /// </summary> /// <param name="asyncResult"> /// <para>The <see cref="IAsyncResult"/> returned by a call to any overload of <see cref="BeginExecuteXmlReader(DbCommand, AsyncCallback, object)"/>.</para> /// </param> /// <seealso cref="ExecuteXmlReader(DbCommand)"/> /// <seealso cref="BeginExecuteXmlReader(DbCommand, AsyncCallback, object)"/> /// <seealso cref="BeginExecuteXmlReader(DbCommand, DbTransaction, AsyncCallback, object)"/> /// <returns> /// <para>An <see cref="XmlReader"/> object that can be used to fetch the resulting XML data.</para> /// </returns> public XmlReader EndExecuteXmlReader(IAsyncResult asyncResult) { var daabAsyncResult = (DaabAsyncResult)asyncResult; var command = (SqlCommand)daabAsyncResult.Command; try { XmlReader reader = command.EndExecuteXmlReader(daabAsyncResult.InnerAsyncResult); if (command.Transaction == null) { using (var wrapper = new DatabaseConnectionWrapper(command.Connection)) { return(new RefCountingXmlReader(wrapper, reader)); } } return(reader); } catch (Exception) { if (command.Transaction == null) { // for a reader, the standard cleanup will not close the connection, so it needs to be closed // in the catch block if necessary command.Connection.Close(); } throw; } finally { CleanupConnectionFromAsyncOperation(daabAsyncResult); } }
public void GetConnection(object parameter) { Transaction transaction = (Transaction)parameter; Transaction.Current = transaction; Connection = TransactionScopeConnections.GetConnection(db); }
/// <devdoc> /// This is a private method that will build the Oracle package name if your stored procedure /// has proper prefix and postfix. /// This functionality is include for /// the portability of the architecture between SQL and Oracle datbase. /// This method also adds the reference cursor to the command writer if not already added. /// </devdoc> private void PrepareCWRefCursor(DbCommand command) { if (command == null) { throw new ArgumentNullException(nameof(command)); } if (CommandType.StoredProcedure == command.CommandType) { // Check for ref. cursor in the command writer, if it does not exist, add a know reference cursor out // of "cur_OUT" if (!CommandHasCursorParameter(command)) { using (DatabaseConnectionWrapper wrapper = GetWrappedConnection()) { using (DbCommand cmd = base.GetStoredProcCommand(command.CommandText)) { PrepareCommand(cmd, wrapper.Connection); DeriveParameters(cmd); foreach (var param in cmd.Parameters) { if ((param as OracleParameter).OracleDbType == OracleDbType.RefCursor) { #pragma warning disable 612, 618 AddParameter(command as OracleCommand, RefCursorName, OracleDbType.RefCursor, 0, ParameterDirection.Output, true, 0, 0, String.Empty, DataRowVersion.Default, Convert.DBNull); #pragma warning restore 612, 618 } } } } } } }
internal RefCountingOracleDataReaderWrapper( DatabaseConnectionWrapper connection, OracleDataReader innerReader) : base(innerReader) { this.connection = connection; this.connection.AddRef(); }
public void GetTransactionScopeConnection() { using (TransactionScope scope = new TransactionScope()) { Current = Transaction.Current; Connection = TransactionScopeConnections.GetConnection(db); } }
/// <summary> /// <para>Creates a connection for this database.</para> /// </summary> /// <remarks> /// This method has been overridden to support keeping a single connection open until you /// explicitly close it with a call to <see cref="CloseSharedConnection"/>. /// </remarks> /// <returns> /// <para>The <see cref="DbConnection"/> for this database.</para> /// </returns> /// <seealso cref="DbConnection"/> public override DbConnection CreateConnection() { using (DatabaseConnectionWrapper wrapper = SqlCeConnectionPool.CreateConnection(this)) { wrapper.AddRef(); wrapper.Connection.ConnectionString = ConnectionString; return(wrapper.Connection); } }
/// <summary> /// SQL Server CE provides a new type of data reader, the <see cref="SqlCeResultSet"/>, that provides /// new abilities and better performance over a standard reader. This method provides access to /// this reader. /// </summary> /// <remarks> /// The <see cref="SqlCeResultSet"/> returned from this method will close the connection on dispose. /// </remarks> /// <param name="command"> /// The command that contains the SQL SELECT statement to execute. /// </param> /// <param name="options">Controls how the <see cref="SqlCeResultSet"/> behaves.</param> /// <param name="parameters">An option set of <see cref="DbParameter"/> parameters.</param> /// <returns>The reader in the form of a <see cref="SqlCeResultSet"/>.</returns> public virtual SqlCeResultSet ExecuteResultSet(DbCommand command, ResultSetOptions options, params DbParameter[] parameters) { using (DatabaseConnectionWrapper wrapper = GetOpenConnection()) { AddParameters(command, parameters); PrepareCommand(command, wrapper.Connection); return(new SqlCeResultSetWrapper(wrapper, DoExecuteResultSet((SqlCeCommand)command, options))); } }
public void AddRefRequiresExtraClose() { var wrapper = new DatabaseConnectionWrapper(connection); using(wrapper.AddRef()) { } AssertNotDisposed(wrapper); }
/// <summary> /// Executes the <see cref="OracleCommand"/> and returns a new <see cref="XmlReader"/>. /// </summary> /// <param name="command">The <see cref="OracleCommand"/> to execute.</param> /// <returns>An <see cref="XmlReader"/> object.</returns> /// <remarks> /// Unlike other Execute... methods that take a <see cref="DbCommand"/> instance, this method /// does not set the command behavior to close the connection when you close the reader. /// That means you'll need to close the connection yourself, by calling the /// command.Connection.Close() method. /// <para> /// There is one exception to the rule above. If you're using <see cref="TransactionScope"/> to provide /// implicit transactions, you should NOT close the connection on this reader when you're /// done. Only close the connection if <see cref="Transaction"/>.Current is null. /// </para> /// </remarks> public XmlReader ExecuteXmlReader(DbCommand command) { OracleCommand oracleCommand = CheckIfOracleCommand(command); DatabaseConnectionWrapper wrapper = GetOpenConnection(); PrepareCommand(oracleCommand, wrapper.Connection); return(DoExecuteXmlReader(oracleCommand)); }
public void ConnectionIsClosedWhenDisposingWrapper() { DatabaseConnectionWrapper wrapper; using(wrapper = new DatabaseConnectionWrapper(connection)) { } AssertDisposed(wrapper); }
public override IDataReader ExecuteReader(DbCommand command) { using (DatabaseConnectionWrapper wrapper = GetOpenConnection()) { ExecuteFederationCommand(wrapper.Connection); PrepareCommand(command, wrapper.Connection); IDataReader realReader = DoExecuteReaderWithRetry(command, CommandBehavior.Default); return(CreateWrappedReader(wrapper, realReader)); } }
/// <summary> /// Gets a "wrapped" connection that will be not be disposed if a transaction is /// active (created by creating a <see cref="TransactionScope"/> instance). The /// connection will be disposed when no transaction is active. /// </summary> /// <returns></returns> protected override DatabaseConnectionWrapper GetOpenConnection() { DatabaseConnectionWrapper connection = TransactionScopeConnections.GetConnection(this); if (connection != null) { connection.AddRef(); } return(connection ?? GetWrappedConnection()); }
public void ConnectionIsClosedWhenDisposingWrapper() { DatabaseConnectionWrapper wrapper; using (wrapper = new DatabaseConnectionWrapper(connection)) { } AssertDisposed(wrapper); }
public XmlReader ExecuteXmlReader(DbCommand command) { SqlCommand sqlCommand = SqlDatabase.CheckIfSqlCommand(command); using (DatabaseConnectionWrapper openConnection = this.GetOpenConnection()) { Database.PrepareCommand(command, openConnection.Connection); return((XmlReader) new RefCountingXmlReader(openConnection, this.DoExecuteXmlReader(sqlCommand))); } }
public void PoolShouldCloseSharedConnection() { TestConnectionString testConnection = new TestConnectionString(); SqlCeDatabase db = new SqlCeDatabase(testConnection.ConnectionString); using (DatabaseConnectionWrapper connection = SqlCeConnectionPool.CreateConnection(db)) {} Assert.AreEqual(1, TestableSqlCeConnectionPool.PoolSize); SqlCeConnectionPool.CloseSharedConnection(db); Assert.AreEqual(0, TestableSqlCeConnectionPool.PoolSize); }
public void AddRefRequiresExtraClose() { var wrapper = new DatabaseConnectionWrapper(connection); using (wrapper.AddRef()) { } AssertNotDisposed(wrapper); }
public void ShouldNotAddConnectionToPoolIfOpenFails() { SqlCeDatabase db = new SqlCeDatabase("Data Source='invalid.sdf'"); try { DatabaseConnectionWrapper connection = SqlCeConnectionPool.CreateConnection(db); } catch (SqlCeException) {} Assert.AreEqual(0, TestableSqlCeConnectionPool.PoolSize); }
public void GetConnection_ShouldReturnDifferentConnectionForDifferentConnectionStrings() { Database db2 = new SqlDatabase(db.ConnectionString.ToString() + ";Persist Security Info=false;"); using (TransactionScope scope = new TransactionScope()) { DatabaseConnectionWrapper connection1 = TransactionScopeConnections.GetConnection(db); DatabaseConnectionWrapper connection2 = TransactionScopeConnections.GetConnection(db2); Assert.AreNotSame(connection1, connection2); } }
public void GetConnectionAddsConnectionToPool() { TestConnectionString testConnection = new TestConnectionString(); SqlCeDatabase db = new SqlCeDatabase(testConnection.ConnectionString); using (DatabaseConnectionWrapper connection = SqlCeConnectionPool.CreateConnection(db)) { Assert.IsNotNull(connection); Assert.AreEqual(1, TestableSqlCeConnectionPool.PoolSize); } }
public void GetConnectionOpensConnectionInPool() { TestConnectionString testConnection = new TestConnectionString(); SqlCeDatabase db = new SqlCeDatabase(testConnection.ConnectionString); using (DatabaseConnectionWrapper connection = SqlCeConnectionPool.CreateConnection(db)) { DatabaseConnectionWrapper keepAlive = TestableSqlCeConnectionPool.GetConnection(0); Assert.AreEqual(ConnectionState.Open, keepAlive.Connection.State); } }
public void ConnectionShouldRemainInPoolAfterReturnedConnectionDisposed() { TestConnectionString testConnection = new TestConnectionString(); SqlCeDatabase db = new SqlCeDatabase(testConnection.ConnectionString); using (DatabaseConnectionWrapper connection = SqlCeConnectionPool.CreateConnection(db)) {} DatabaseConnectionWrapper keepAlive = TestableSqlCeConnectionPool.GetConnection(0); Assert.AreEqual(ConnectionState.Open, keepAlive.Connection.State); }
public void GetConnectionReturnsDifferentConnectionThanOneInPool() { TestConnectionString testConnection = new TestConnectionString(); SqlCeDatabase db = new SqlCeDatabase(testConnection.ConnectionString); using (DatabaseConnectionWrapper connection = SqlCeConnectionPool.CreateConnection(db)) { DatabaseConnectionWrapper keepAlive = TestableSqlCeConnectionPool.GetConnection(0); Assert.AreNotSame(connection, keepAlive); } }
public void DatabaseShouldCloseSharedConnection() { TestConnectionString file = new TestConnectionString(); SqlCeDatabase database = new SqlCeDatabase(file.ConnectionString); using (DatabaseConnectionWrapper connection = SqlCeConnectionPool.CreateConnection(database)) {} Assert.AreEqual(1, TestableSqlCeConnectionPool.PoolSize); database.CloseSharedConnection(); Assert.AreEqual(0, TestableSqlCeConnectionPool.PoolSize); }
public void GetConnection_ShouldGetDifferentConnectionOnDifferentThreads() { using (TransactionScope scope = new TransactionScope()) { DatabaseConnectionWrapper connection = TransactionScopeConnections.GetConnection(db); ThreadTests tests = new ThreadTests(); Thread thread = new Thread(tests.GetTransactionScopeConnection); thread.Start(); thread.Join(); Assert.AreNotSame(connection, tests.Connection); } }
public void GetConnection_ShouldGetSameConnectionWhenOtherThreadUsesSameTransaction() { using (TransactionScope scope = new TransactionScope()) { DatabaseConnectionWrapper connection = TransactionScopeConnections.GetConnection(db); ThreadTests tests = new ThreadTests(); Thread thread = new Thread(tests.GetConnection); thread.Start(Transaction.Current); thread.Join(); Assert.AreSame(connection, tests.Connection); Assert.AreEqual(ConnectionState.Open, tests.Connection.Connection.State); } }
public void Supress_ShouldReturnNullConnection() { using (TransactionScope scope1 = new TransactionScope(TransactionScopeOption.RequiresNew)) { DatabaseConnectionWrapper connection = TransactionScopeConnections.GetConnection(db); Assert.IsNotNull(connection); using (TransactionScope scope2 = new TransactionScope(TransactionScopeOption.Suppress)) { Assert.IsNull(TransactionScopeConnections.GetConnection(db)); } } }
public void GetConnectionReturnsNewConnectionButHasOnlyOneInPool() { TestConnectionString testConnection = new TestConnectionString(); SqlCeDatabase db = new SqlCeDatabase(testConnection.ConnectionString); using (DatabaseConnectionWrapper connection1 = SqlCeConnectionPool.CreateConnection(db)) { using (DatabaseConnectionWrapper connection2 = SqlCeConnectionPool.CreateConnection(db)) { Assert.AreNotSame(connection1, connection2); Assert.AreEqual(1, TestableSqlCeConnectionPool.PoolSize); } } }
/// <summary> /// Executes an INSERT statement and given the identity of /// the row that was inserted for identity tables. /// </summary> /// <param name="sqlCommand">The SQL statement to execute.</param> /// <param name="lastAddedId">The identity value for the last row added, or <see cref="DBNull"/>.</param> /// <param name="parameters">Zero or more parameters.</param> /// <returns>The number of rows affected.</returns> public virtual int ExecuteNonQuerySql(string sqlCommand, out int lastAddedId, params DbParameter[] parameters) { using (DatabaseConnectionWrapper wrapper = GetOpenConnection()) { using (DbCommand command = GetSqlStringCommand(sqlCommand)) { AddParameters(command, parameters); PrepareCommand(command, wrapper.Connection); int result = DoExecuteNonQuery(command); lastAddedId = GetLastId(wrapper.Connection); return(result); } } }
public void GetConnectionWithPoolingReturnsSameConnection() { TestConnectionString testConnection = new TestConnectionString(); SqlCeDatabase db = new SqlCeDatabase(testConnection.ConnectionString); using (DatabaseConnectionWrapper connection1 = SqlCeConnectionPool.CreateConnection(db, true)) { using (DatabaseConnectionWrapper connection2 = SqlCeConnectionPool.CreateConnection(db, true)) { Assert.AreSame(connection1, connection2); Assert.AreEqual(1, TestableSqlCeConnectionPool.PoolSize); } } }
public DatabaseConnectionWrapper GetOpenedSqlConnection2() { DatabaseConnectionWrapper wrapper; if (Transaction.Current != null) { wrapper = TransactionScopeConnections.GetConnection(new SqlDatabase(this.connectionString)); } else { wrapper = new DatabaseConnectionWrapper(GetOpenedSqlConnection()); } return(wrapper); }
public void MultipleDisposesCleanupMultipleAddRefs() { // Start at refcount 1 var wrapper = new DatabaseConnectionWrapper(connection); wrapper.AddRef(); wrapper.AddRef(); wrapper.Dispose(); AssertNotDisposed(wrapper); wrapper.Dispose(); AssertNotDisposed(wrapper); wrapper.Dispose(); AssertDisposed(wrapper); }
public SqlCeResultSetWrapper(DatabaseConnectionWrapper connection, SqlCeResultSet innerResultSet) { this.connection = connection; this.connection.AddRef(); this.InnerResultSet = innerResultSet; }
/// <summary> /// All data readers get wrapped in objects so that they properly manage connections. /// Some derived Database classes will need to create a different wrapper, so this /// method is provided so that they can do this. /// </summary> /// <param name="connection">Connection + refcount.</param> /// <param name="innerReader">The reader to wrap.</param> /// <returns>The new reader.</returns> protected override IDataReader CreateWrappedReader(DatabaseConnectionWrapper connection, IDataReader innerReader) { return new RefCountingOracleDataReaderWrapper(connection, (OracleDataReader) innerReader); }
public RefCountingXmlReader(DatabaseConnectionWrapper connection, XmlReader innerReader) { this.connection = connection; this.innerReader = innerReader; this.connection.AddRef(); }
private void AssertNotDisposed(DatabaseConnectionWrapper wrapper) { Assert.IsFalse(wrapper.IsDisposed); Assert.AreEqual(ConnectionState.Open, connection.State); }
/// <summary> /// Creates a new connection. If this is the first connection, it also creates an extra /// "Keep Alive" connection to keep the database open. /// If <paramref name="usePooledConnection"/> is true, than if this connection has been opened before, /// the connection from the pool will be returned rather than creating a new one. /// </summary> /// <param name="db">The database instance that will be used to create a connection.</param> /// <param name="usePooledConnection">If true, return an already created connection for this object. If /// false, always create a new one.</param> /// <returns>A new connection.</returns> public static DatabaseConnectionWrapper CreateConnection(SqlCeDatabase db, bool usePooledConnection) { string connectionString = db.ConnectionStringWithoutCredentials; DatabaseConnectionWrapper connection; lock (connections) { if (!connections.TryGetValue(connectionString, out connection)) { // // We have to test this again in case another thread added a connection. // if (!connections.ContainsKey(connectionString)) { DbConnection keepAliveConnection = new SqlCeConnection(); db.SetConnectionString(keepAliveConnection); keepAliveConnection.Open(); connection = new DatabaseConnectionWrapper(keepAliveConnection); connections.Add(connectionString, connection); } } if (usePooledConnection) { connection.AddRef(); return connection; } return new DatabaseConnectionWrapper(new SqlCeConnection()); } }
internal RefCountingOracleDataReaderWrapper(DatabaseConnectionWrapper connection, OracleDataReader innerReader) : base(innerReader) { this.connection = connection; this.connection.AddRef(); }
public void GetConnection(object parameter) { Transaction transaction = (Transaction)parameter; Transaction.Current = transaction; Connection = TransactionScopeConnections.GetConnection(db); }
public void GetTransactionScopeConnection() { using (TransactionScope scope = new TransactionScope()) { Current = Transaction.Current; Connection = TransactionScopeConnections.GetConnection(db); } }
/// <summary> /// Finishes asynchronous execution of a Transact-SQL statement, returning the requested data as XML. /// </summary> /// <param name="asyncResult"> /// <para>The <see cref="IAsyncResult"/> returned by a call to any overload of <see cref="BeginExecuteXmlReader(DbCommand, AsyncCallback, object)"/>.</para> /// </param> /// <seealso cref="ExecuteXmlReader(DbCommand)"/> /// <seealso cref="BeginExecuteXmlReader(DbCommand, AsyncCallback, object)"/> /// <seealso cref="BeginExecuteXmlReader(DbCommand, DbTransaction, AsyncCallback, object)"/> /// <returns> /// <para>An <see cref="XmlReader"/> object that can be used to fetch the resulting XML data.</para> /// </returns> public XmlReader EndExecuteXmlReader(IAsyncResult asyncResult) { var daabAsyncResult = (DaabAsyncResult)asyncResult; var command = (SqlCommand)daabAsyncResult.Command; try { XmlReader reader = command.EndExecuteXmlReader(daabAsyncResult.InnerAsyncResult); instrumentationProvider.FireCommandExecutedEvent(daabAsyncResult.StartTime); if(command.Transaction == null) { using (var wrapper = new DatabaseConnectionWrapper(command.Connection)) { return new RefCountingXmlReader(wrapper, reader); } } return reader; } catch (Exception e) { instrumentationProvider.FireCommandFailedEvent(command.CommandText, ConnectionStringNoCredentials, e); if (command.Transaction == null) { // for a reader, the standard cleanup will not close the connection, so it needs to be closed // in the catch block if necessary command.Connection.Close(); } throw; } finally { CleanupConnectionFromAsyncOperation(daabAsyncResult); } }
private void AssertDisposed(DatabaseConnectionWrapper wrapper) { Assert.IsTrue(wrapper.IsDisposed); Assert.AreEqual(ConnectionState.Closed, connection.State); }