diff --git a/src/NHibernate.Test/CfgTest/Loquacious/ConfigurationFixture.cs b/src/NHibernate.Test/CfgTest/Loquacious/ConfigurationFixture.cs index 06c608374ca..11f452b329d 100644 --- a/src/NHibernate.Test/CfgTest/Loquacious/ConfigurationFixture.cs +++ b/src/NHibernate.Test/CfgTest/Loquacious/ConfigurationFixture.cs @@ -1,3 +1,4 @@ +using System; using System.Data; using System.Data.SqlClient; using System.IO; @@ -12,12 +13,26 @@ using NHibernate.Linq; using NHibernate.Type; using NUnit.Framework; +using Environment = NHibernate.Cfg.Environment; namespace NHibernate.Test.CfgTest.Loquacious { [TestFixture] public class ConfigurationFixture { + [Test] + public void CanSetNotificationHandler() + { + //NH-3724 + EventHandler handler = (s, e) => {}; + var cfg = new Configuration().DataBaseIntegration(x => + { + x.WithNotificationHandler(handler); + }).Configure(); + + Assert.IsNotNull(cfg.NotificationHandler); + } + [Test] public void CompleteConfiguration() { diff --git a/src/NHibernate/AdoNet/ConnectionManager.cs b/src/NHibernate/AdoNet/ConnectionManager.cs index 5ace6b15a2f..e7f08638d0a 100644 --- a/src/NHibernate/AdoNet/ConnectionManager.cs +++ b/src/NHibernate/AdoNet/ConnectionManager.cs @@ -185,6 +185,11 @@ public DbConnection GetConnection() if (ownConnection) { connection = Factory.ConnectionProvider.GetConnection(); + //NH-3724 + if (Factory.Settings.NotificationHandler != null) + { + Factory.ConnectionProvider.Driver.AddNotificationHandler(connection, Factory.Settings.NotificationHandler); + } if (Factory.Statistics.IsStatisticsEnabled) { Factory.StatisticsImplementor.Connect(); diff --git a/src/NHibernate/Cfg/Configuration.cs b/src/NHibernate/Cfg/Configuration.cs index 06d1a168ee4..1126c18534c 100644 --- a/src/NHibernate/Cfg/Configuration.cs +++ b/src/NHibernate/Cfg/Configuration.cs @@ -183,6 +183,7 @@ protected void Reset() tableNameBinding = new Dictionary(); columnNameBindingPerTable = new Dictionary(); filtersSecondPasses = new Queue(); + NotificationHandler = null; } [Serializable] private class Mapping : IMapping @@ -1335,6 +1336,10 @@ public Configuration SetDefaultNamespace(string newDefaultNamespace) return this; } + //NH-3724 + [field: NonSerialized] + public Delegate NotificationHandler { get; set; } + /// /// Sets the default interceptor for use by all sessions. /// @@ -1723,6 +1728,8 @@ private Settings BuildSettings() // NH : Set configuration for IdGenerator SQL logging PersistentIdGeneratorParmsNames.SqlStatementLogger.FormatSql = result.SqlStatementLogger.FormatSql; PersistentIdGeneratorParmsNames.SqlStatementLogger.LogToStdout = result.SqlStatementLogger.LogToStdout; + //NH-3724 + result.NotificationHandler = NotificationHandler; return result; } diff --git a/src/NHibernate/Cfg/Loquacious/DbIntegrationConfigurationProperties.cs b/src/NHibernate/Cfg/Loquacious/DbIntegrationConfigurationProperties.cs index 55131818ab4..176c98557b2 100644 --- a/src/NHibernate/Cfg/Loquacious/DbIntegrationConfigurationProperties.cs +++ b/src/NHibernate/Cfg/Loquacious/DbIntegrationConfigurationProperties.cs @@ -1,3 +1,4 @@ +using System; using System.Data; using NHibernate.AdoNet; using NHibernate.Connection; @@ -19,6 +20,12 @@ public DbIntegrationConfigurationProperties(Configuration configuration) #region Implementation of IDbIntegrationConfigurationProperties + public void WithNotificationHandler(Delegate handler) + { + //NH-3724 + configuration.NotificationHandler = handler; + } + public void Dialect() where TDialect : Dialect.Dialect { configuration.SetProperty(Environment.Dialect, typeof(TDialect).AssemblyQualifiedName); diff --git a/src/NHibernate/Cfg/Loquacious/IDbIntegrationConfigurationProperties.cs b/src/NHibernate/Cfg/Loquacious/IDbIntegrationConfigurationProperties.cs index c39891a30bb..e1fe42f1804 100644 --- a/src/NHibernate/Cfg/Loquacious/IDbIntegrationConfigurationProperties.cs +++ b/src/NHibernate/Cfg/Loquacious/IDbIntegrationConfigurationProperties.cs @@ -1,3 +1,4 @@ +using System; using System.Data; using NHibernate.AdoNet; using NHibernate.Connection; @@ -15,6 +16,9 @@ public interface IDbIntegrationConfigurationProperties bool LogSqlInConsole { set; } bool LogFormattedSql { set; } + //NH-3724 + void WithNotificationHandler(Delegate handler); + void ConnectionProvider() where TProvider : IConnectionProvider; void Driver() where TDriver : IDriver; IsolationLevel IsolationLevel { set; } diff --git a/src/NHibernate/Cfg/Settings.cs b/src/NHibernate/Cfg/Settings.cs index f2057651d34..8fa62459917 100644 --- a/src/NHibernate/Cfg/Settings.cs +++ b/src/NHibernate/Cfg/Settings.cs @@ -32,6 +32,9 @@ public Settings() //private bool isJdbcBatchVersionedData; #endregion + + public Delegate NotificationHandler { get; internal set; } + public SqlStatementLogger SqlStatementLogger { get; internal set; } public int MaximumFetchDepth { get; internal set; } diff --git a/src/NHibernate/Driver/DriverBase.cs b/src/NHibernate/Driver/DriverBase.cs index c61008b4c2e..f0023611675 100644 --- a/src/NHibernate/Driver/DriverBase.cs +++ b/src/NHibernate/Driver/DriverBase.cs @@ -21,6 +21,22 @@ public abstract class DriverBase : IDriver, ISqlParameterFormatter private int commandTimeout; private bool prepareSql; + public virtual void AddNotificationHandler(IDbConnection con, Delegate handler) + { + //NH-3724 + if (handler != null) + { + var prop = con.GetType().GetEvent("InfoMessage"); + + if (prop == null) + { + throw new NotSupportedException("Current driver does not support notifications."); + } + + prop.AddEventHandler(con, handler); + } + } + public virtual void Configure(IDictionary settings) { // Command timeout diff --git a/src/NHibernate/Driver/IDriver.cs b/src/NHibernate/Driver/IDriver.cs index 8fdf6afaf7f..42e0f454533 100644 --- a/src/NHibernate/Driver/IDriver.cs +++ b/src/NHibernate/Driver/IDriver.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -36,6 +37,13 @@ public interface IDriver /// void Configure(IDictionary settings); + //NH-3724 + /// + /// Attaches an event handler for the notification event (InfoMessage in most ADO.NET drivers). + /// + /// + void AddNotificationHandler(IDbConnection con, Delegate handler); + /// /// Creates an uninitialized DbConnection object for the specific Driver /// diff --git a/src/NHibernate/Driver/IfxDriver.cs b/src/NHibernate/Driver/IfxDriver.cs index 0d3c3bebbd2..32a18f1d7c3 100644 --- a/src/NHibernate/Driver/IfxDriver.cs +++ b/src/NHibernate/Driver/IfxDriver.cs @@ -1,3 +1,6 @@ +using System; +using System.Data; + namespace NHibernate.Driver { /// diff --git a/src/NHibernate/Driver/MySqlDataDriver.cs b/src/NHibernate/Driver/MySqlDataDriver.cs index 8d7ab9023f1..21c8ce17350 100644 --- a/src/NHibernate/Driver/MySqlDataDriver.cs +++ b/src/NHibernate/Driver/MySqlDataDriver.cs @@ -1,5 +1,3 @@ -using System; - namespace NHibernate.Driver { /// diff --git a/src/NHibernate/Driver/NpgsqlDriver.cs b/src/NHibernate/Driver/NpgsqlDriver.cs index d9afe0822cc..f1fa03a4e97 100644 --- a/src/NHibernate/Driver/NpgsqlDriver.cs +++ b/src/NHibernate/Driver/NpgsqlDriver.cs @@ -1,3 +1,4 @@ +using System; using System.Data; using System.Data.Common; @@ -40,6 +41,12 @@ public NpgsqlDriver() : base( { } + public override void AddNotificationHandler(IDbConnection con, Delegate handler) + { + //NH-3724 + con.GetType().GetEvent("Notification").AddEventHandler(con, handler); + } + public override bool UseNamedPrefixInSql { get { return true; } diff --git a/src/NHibernate/Driver/OdbcDriver.cs b/src/NHibernate/Driver/OdbcDriver.cs index 6101d321a5e..24a1b94885d 100644 --- a/src/NHibernate/Driver/OdbcDriver.cs +++ b/src/NHibernate/Driver/OdbcDriver.cs @@ -17,6 +17,12 @@ namespace NHibernate.Driver /// public class OdbcDriver : DriverBase { + public override void AddNotificationHandler(IDbConnection con, Delegate handler) + { + //NH-3724 + (con as OdbcConnection).InfoMessage += (OdbcInfoMessageEventHandler)handler; + } + private static readonly IInternalLogger Log = LoggerProvider.LoggerFor(typeof(OdbcDriver)); private byte? _dbDateTimeScale; diff --git a/src/NHibernate/Driver/OleDbDriver.cs b/src/NHibernate/Driver/OleDbDriver.cs index cb0d00c63c8..4f87c034816 100644 --- a/src/NHibernate/Driver/OleDbDriver.cs +++ b/src/NHibernate/Driver/OleDbDriver.cs @@ -16,6 +16,12 @@ public OleDbDriver() { } + public override void AddNotificationHandler(IDbConnection con, Delegate handler) + { + //NH-3724 + (con as OleDbConnection).InfoMessage += (OleDbInfoMessageEventHandler)handler; + } + public override DbConnection CreateConnection() { return new OleDbConnection(); diff --git a/src/NHibernate/Driver/SQLite20Driver.cs b/src/NHibernate/Driver/SQLite20Driver.cs index 00cdf8b8be4..a54b408be68 100644 --- a/src/NHibernate/Driver/SQLite20Driver.cs +++ b/src/NHibernate/Driver/SQLite20Driver.cs @@ -1,39 +1,38 @@ -using System; using System.Data; using System.Data.Common; namespace NHibernate.Driver { - /// - /// NHibernate driver for the System.Data.SQLite data provider for .NET 2.0. - /// - /// - ///

- /// In order to use this driver you must have the System.Data.SQLite.dll assembly available - /// for NHibernate to load. This assembly includes the SQLite.dll or SQLite3.dll libraries. - ///

- ///

- /// You can get the System.Data.SQLite.dll assembly from http://sourceforge.net/projects/sqlite-dotnet2. - ///

- ///

- /// Please check http://www.sqlite.org/ for more information regarding SQLite. - ///

- ///
- public class SQLite20Driver : ReflectionBasedDriver - { - /// - /// Initializes a new instance of . - /// - /// - /// Thrown when the SQLite.NET assembly can not be loaded. - /// - public SQLite20Driver() : base( - "System.Data.SQLite", - "System.Data.SQLite", - "System.Data.SQLite.SQLiteConnection", - "System.Data.SQLite.SQLiteCommand") - { - } + /// + /// NHibernate driver for the System.Data.SQLite data provider for .NET 2.0. + /// + /// + ///

+ /// In order to use this driver you must have the System.Data.SQLite.dll assembly available + /// for NHibernate to load. This assembly includes the SQLite.dll or SQLite3.dll libraries. + ///

+ ///

+ /// You can get the System.Data.SQLite.dll assembly from http://sourceforge.net/projects/sqlite-dotnet2. + ///

+ ///

+ /// Please check http://www.sqlite.org/ for more information regarding SQLite. + ///

+ ///
+ public class SQLite20Driver : ReflectionBasedDriver + { + /// + /// Initializes a new instance of . + /// + /// + /// Thrown when the SQLite.NET assembly can not be loaded. + /// + public SQLite20Driver() : base( + "System.Data.SQLite", + "System.Data.SQLite", + "System.Data.SQLite.SQLiteConnection", + "System.Data.SQLite.SQLiteCommand") + { + } public override DbConnection CreateConnection() { @@ -57,34 +56,34 @@ private static void Connection_StateChange(object sender, StateChangeEventArgs e } } - public override bool UseNamedPrefixInSql - { - get { return true; } - } + public override bool UseNamedPrefixInSql + { + get { return true; } + } - public override bool UseNamedPrefixInParameter - { - get { return true; } - } + public override bool UseNamedPrefixInParameter + { + get { return true; } + } - public override string NamedPrefix - { - get { return "@"; } - } + public override string NamedPrefix + { + get { return "@"; } + } - public override bool SupportsMultipleOpenReaders - { - get { return false; } - } + public override bool SupportsMultipleOpenReaders + { + get { return false; } + } - public override IResultSetsCommand GetResultSetsCommand(Engine.ISessionImplementor session) - { - return new BasicResultSetsCommand(session); - } + public override IResultSetsCommand GetResultSetsCommand(Engine.ISessionImplementor session) + { + return new BasicResultSetsCommand(session); + } - public override bool SupportsMultipleQueries - { - get { return true; } - } - } + public override bool SupportsMultipleQueries + { + get { return true; } + } + } } \ No newline at end of file diff --git a/src/NHibernate/Driver/SqlClientDriver.cs b/src/NHibernate/Driver/SqlClientDriver.cs index fadec4ea5ab..ca1d4132bd2 100644 --- a/src/NHibernate/Driver/SqlClientDriver.cs +++ b/src/NHibernate/Driver/SqlClientDriver.cs @@ -1,3 +1,4 @@ +using System; using System.Data; using System.Data.Common; using System.Data.SqlClient; @@ -26,6 +27,12 @@ public class SqlClientDriver : DriverBase, IEmbeddedBatcherFactoryProvider public const byte MaxDateTime2 = 8; public const byte MaxDateTimeOffset = 10; + public override void AddNotificationHandler(IDbConnection con, Delegate handler) + { + //NH-3724 + (con as SqlConnection).InfoMessage += (SqlInfoMessageEventHandler) handler; + } + /// /// Creates an uninitialized object for /// the SqlClientDriver. diff --git a/src/NHibernate/Driver/SqlServerCeDriver.cs b/src/NHibernate/Driver/SqlServerCeDriver.cs index bc06f7f9aae..ae52f47fab4 100644 --- a/src/NHibernate/Driver/SqlServerCeDriver.cs +++ b/src/NHibernate/Driver/SqlServerCeDriver.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Data; using System.Data.Common; diff --git a/src/NHibernate/Driver/SybaseAseClientDriver.cs b/src/NHibernate/Driver/SybaseAseClientDriver.cs index eb73208ec1f..20d4acab372 100644 --- a/src/NHibernate/Driver/SybaseAseClientDriver.cs +++ b/src/NHibernate/Driver/SybaseAseClientDriver.cs @@ -1,6 +1,4 @@ -using System; - -namespace NHibernate.Driver +namespace NHibernate.Driver { /// /// This provides a driver for Sybase ASE 15 using the ADO.NET driver. @@ -17,7 +15,7 @@ public class SybaseAseClientDriver : ReflectionBasedDriver public SybaseAseClientDriver() : base("Sybase.AdoNet2.AseClient", "Sybase.Data.AseClient.AseConnection", "Sybase.Data.AseClient.AseCommand") { } - + public override string NamedPrefix { get { return "@"; }