Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Add query notification support to SqlClient (#20708)
Browse files Browse the repository at this point in the history
  • Loading branch information
corivera authored Jun 6, 2017
1 parent 768cd9c commit 27f4273
Show file tree
Hide file tree
Showing 23 changed files with 3,885 additions and 20 deletions.
2 changes: 1 addition & 1 deletion pkg/Microsoft.Private.PackageBaseline/packageIndex.json
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,7 @@
"4.1.0.0": "4.1.0",
"4.1.1.0": "4.3.0",
"4.2.0.0": "4.4.0",
"4.2.1.0": "4.5.0"
"4.3.0.0": "4.5.0"
}
},
"System.Data.SqlXml": {
Expand Down
2 changes: 1 addition & 1 deletion src/System.Data.SqlClient/dir.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\dir.props" />
<PropertyGroup>
<AssemblyVersion>4.2.1.0</AssemblyVersion>
<AssemblyVersion>4.3.0.0</AssemblyVersion>
<AssemblyKey>MSFT</AssemblyKey>
</PropertyGroup>
</Project>
76 changes: 76 additions & 0 deletions src/System.Data.SqlClient/ref/System.Data.SqlClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ public SqlMetaData(string name, System.Data.SqlDbType dbType, string database, s
public static Microsoft.SqlServer.Server.SqlMetaData InferFromValue(object value, string name) { throw null; }
}
}
namespace System.Data.Sql
{
public sealed partial class SqlNotificationRequest
{
public SqlNotificationRequest() { }
public SqlNotificationRequest(string userData, string options, int timeout) { }
public string Options { get { throw null; } set { } }
public int Timeout { get { throw null; } set { } }
public string UserData { get { throw null; } set { } }
}
}
namespace System.Data.SqlClient
{
public enum ApplicationIntent
Expand Down Expand Up @@ -331,6 +342,7 @@ public override void Cancel() { }
public System.Threading.Tasks.Task<System.Xml.XmlReader> ExecuteXmlReaderAsync() { throw null; }
public System.Threading.Tasks.Task<System.Xml.XmlReader> ExecuteXmlReaderAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
public override void Prepare() { }
public System.Data.Sql.SqlNotificationRequest Notification { get { throw null; } set { } }
}
public sealed partial class SqlConnection : System.Data.Common.DbConnection, System.ICloneable
{
Expand Down Expand Up @@ -426,6 +438,70 @@ protected override void OnRowUpdated(System.Data.Common.RowUpdatedEventArgs valu
protected override void OnRowUpdating(System.Data.Common.RowUpdatingEventArgs value) { }
object System.ICloneable.Clone() { throw null; }
}
public sealed partial class SqlDependency
{
public SqlDependency() { }
public SqlDependency(SqlCommand command) { }
public SqlDependency(SqlCommand command, string options, int timeout) { }
public bool HasChanges { get { throw null; } }
public string Id { get { throw null; } }
public event OnChangeEventHandler OnChange { add { } remove { } }
public void AddCommandDependency(SqlCommand command) { }
public static bool Start(string connectionString) { throw null; }
public static bool Start(string connectionString, string queue) { throw null; }
public static bool Stop(string connectionString) { throw null; }
public static bool Stop(string connectionString, string queue) { throw null; }
}
public delegate void OnChangeEventHandler(object sender, SqlNotificationEventArgs e);
public partial class SqlNotificationEventArgs : System.EventArgs
{
public SqlNotificationEventArgs(SqlNotificationType type, SqlNotificationInfo info, SqlNotificationSource source) { }
public SqlNotificationType Type { get { throw null; } }
public SqlNotificationInfo Info { get { throw null; } }
public SqlNotificationSource Source { get { throw null; } }
}
public enum SqlNotificationInfo
{
Truncate = 0,
Insert = 1,
Update = 2,
Delete = 3,
Drop = 4,
Alter = 5,
Restart = 6,
Error = 7,
Query = 8,
Invalid = 9,
Options = 10,
Isolation = 11,
Expired = 12,
Resource = 13,
PreviousFire = 14,
TemplateLimit = 15,
Merge = 16,
Unknown = -1,
AlreadyChanged = -2
}
public enum SqlNotificationSource
{
Data = 0,
Timeout = 1,
Object = 2,
Database = 3,
System = 4,
Statement = 5,
Environment = 6,
Execution = 7,
Owner = 8,
Unknown = -1,
Client = -2
}
public enum SqlNotificationType
{
Change = 0,
Subscribe = 1,
Unknown = -1
}
public sealed partial class SqlRowUpdatedEventArgs : System.Data.Common.RowUpdatedEventArgs
{
public SqlRowUpdatedEventArgs(DataRow row, IDbCommand command, StatementType statementType, System.Data.Common.DataTableMapping tableMapping)
Expand Down
27 changes: 27 additions & 0 deletions src/System.Data.SqlClient/src/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,33 @@
<data name="SQL_EnumeratedRecordFieldCountChanged" xml:space="preserve">
<value>Number of fields in record '{0}' does not match the number in the original record.</value>
</data>
<data name="SQLNotify_AlreadyHasCommand" xml:space="preserve">
<value>This SqlCommand object is already associated with another SqlDependency object.</value>
</data>
<data name="SqlDependency_DatabaseBrokerDisabled" xml:space="preserve">
<value>The SQL Server Service Broker for the current database is not enabled, and as a result query notifications are not supported. Please enable the Service Broker for this database if you wish to use notifications.</value>
</data>
<data name="SqlDependency_DefaultOptionsButNoStart" xml:space="preserve">
<value>When using SqlDependency without providing an options value, SqlDependency.Start() must be called prior to execution of a command added to the SqlDependency instance.</value>
</data>
<data name="SqlDependency_NoMatchingServerStart" xml:space="preserve">
<value>When using SqlDependency without providing an options value, SqlDependency.Start() must be called for each server that is being executed against.</value>
</data>
<data name="SqlDependency_NoMatchingServerDatabaseStart" xml:space="preserve">
<value>SqlDependency.Start has been called for the server the command is executing against more than once, but there is no matching server/user/database Start() call for current command.</value>
</data>
<data name="SqlDependency_EventNoDuplicate" xml:space="preserve">
<value>SqlDependency.OnChange does not support multiple event registrations for the same delegate.</value>
</data>
<data name="SqlDependency_IdMismatch" xml:space="preserve">
<value>No SqlDependency exists for the key.</value>
</data>
<data name="SqlDependency_InvalidTimeout" xml:space="preserve">
<value>Timeout specified is invalid. Timeout cannot be &lt; 0.</value>
</data>
<data name="SqlDependency_DuplicateStart" xml:space="preserve">
<value>SqlDependency does not support calling Start() with different connection strings having the same server, user, and database in the same app domain.</value>
</data>
<data name="SqlMetaData_InvalidSqlDbTypeForConstructorFormat" xml:space="preserve">
<value>The dbType {0} is invalid for this constructor.</value>
</data>
Expand Down
9 changes: 9 additions & 0 deletions src/System.Data.SqlClient/src/System.Data.SqlClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
<Compile Include="System\Data\ProviderBase\DbReferenceCollection.cs" />
<Compile Include="System\Data\ProviderBase\TimeoutTimer.cs" />
<Compile Include="System\Data\Sql\SqlMetaData.cs" />
<Compile Include="System\Data\Sql\SqlNotificationRequest.cs" />
<Compile Include="System\Data\SqlClient\ApplicationIntent.cs" />
<Compile Include="System\Data\SqlClient\LocalDBAPI.cs" />
<Compile Include="System\Data\SqlClient\ParameterPeekAheadValue.cs" />
Expand Down Expand Up @@ -113,6 +114,9 @@
<Compile Include="System\Data\SqlClient\SqlConnectionTimeoutErrorInternal.cs" />
<Compile Include="System\Data\SqlClient\SqlDataAdapter.cs" />
<Compile Include="System\Data\SqlClient\SqlDataReader.cs" />
<Compile Include="System\Data\SqlClient\SqlDependency.cs" />
<Compile Include="System\Data\SqlClient\SqlDependencyListener.cs" />
<Compile Include="System\Data\SqlClient\SqlDependencyUtils.cs" />
<Compile Include="System\Data\SqlClient\SqlEnums.cs" />
<Compile Include="System\Data\SqlClient\SqlError.cs" />
<Compile Include="System\Data\SqlClient\SqlErrorCollection.cs" />
Expand All @@ -123,6 +127,11 @@
<Compile Include="System\Data\SqlClient\SqlInternalConnectionTds.cs" />
<Compile Include="System\Data\SqlClient\sqlinternaltransaction.cs" />
<Compile Include="System\Data\SqlClient\SqlMetadataFactory.cs" />
<Compile Include="System\Data\SqlClient\SqlNotificationEventArgs.cs" />
<Compile Include="System\Data\SqlClient\SqlNotificationInfo.cs" />
<Compile Include="System\Data\SqlClient\SqlNotificationSource.cs" />
<Compile Include="System\Data\SqlClient\SqlNotificationType.cs" />
<Compile Include="System\Data\SqlClient\OnChangedEventHandler.cs" />
<Compile Include="System\Data\SqlClient\SqlParameter.cs" />
<Compile Include="System\Data\SqlClient\SqlParameterCollection.cs" />
<Compile Include="System\Data\SqlClient\SqlParameterCollectionHelper.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ internal static Exception ExceptionWithStackTrace(Exception e)
}
}

internal static void TraceExceptionWithoutRethrow(Exception e)
{
Debug.Assert(ADP.IsCatchableExceptionType(e), "Invalid exception type, should have been re-thrown!");
TraceException("<comm.ADP.TraceException|ERR|CATCH> '%ls'\n", e);
}

//
// COM+ exceptions
//
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Data.Common;
using System.Data.SqlClient;

namespace System.Data.Sql
{
public sealed class SqlNotificationRequest
{
private string _userData;
private string _options;
private int _timeout;

public SqlNotificationRequest()
: this(null, null, SQL.SqlDependencyTimeoutDefault) { }

public SqlNotificationRequest(string userData, string options, int timeout)
{
UserData = userData;
Timeout = timeout;
Options = options;
}

public string Options
{
get
{
return _options;
}
set
{
if ((null != value) && (ushort.MaxValue < value.Length))
{
throw ADP.ArgumentOutOfRange(string.Empty, nameof(Options));
}
_options = value;
}
}

public int Timeout
{
get
{
return _timeout;
}
set
{
if (0 > value)
{
throw ADP.ArgumentOutOfRange(string.Empty, nameof(Timeout));
}
_timeout = value;
}
}

public string UserData
{
get
{
return _userData;
}
set
{
if ((null != value) && (ushort.MaxValue < value.Length))
{
throw ADP.ArgumentOutOfRange(string.Empty, nameof(UserData));
}
_userData = value;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace System.Data.SqlClient
{
public delegate void OnChangeEventHandler(object sender, SqlNotificationEventArgs e);
}
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ private Task<BulkCopySimpleResultSet> CreateAndExecuteInitialQueryAsync(out Bulk
{
string TDSCommand = CreateInitialQuery();

Task executeTask = _parser.TdsExecuteSQLBatch(TDSCommand, this.BulkCopyTimeout, _stateObj, sync: !_isAsyncBulkCopy, callerHasConnectionLock: true);
Task executeTask = _parser.TdsExecuteSQLBatch(TDSCommand, this.BulkCopyTimeout, null, _stateObj, sync: !_isAsyncBulkCopy, callerHasConnectionLock: true);

if (executeTask == null)
{
Expand Down Expand Up @@ -743,7 +743,7 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i

private Task SubmitUpdateBulkCommand(string TDSCommand)
{
Task executeTask = _parser.TdsExecuteSQLBatch(TDSCommand, this.BulkCopyTimeout, _stateObj, sync: !_isAsyncBulkCopy, callerHasConnectionLock: true);
Task executeTask = _parser.TdsExecuteSQLBatch(TDSCommand, this.BulkCopyTimeout, null, _stateObj, sync: !_isAsyncBulkCopy, callerHasConnectionLock: true);

if (executeTask == null)
{
Expand Down
Loading

0 comments on commit 27f4273

Please sign in to comment.