diff --git a/Worker.Extensions.Sql/src/SqlChange.cs b/Worker.Extensions.Sql/src/SqlChange.cs new file mode 100644 index 000000000..55775b1b2 --- /dev/null +++ b/Worker.Extensions.Sql/src/SqlChange.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Functions.Worker.Extensions.Sql +{ + /// + /// Represents the changed row in the user table. + /// + /// POCO class representing the row in the user table + public sealed class SqlChange + { + /// + /// Initializes a new instance of the class. + /// + /// Change operation + /// POCO representing the row in the user table on which the change operation took place + public SqlChange(SqlChangeOperation operation, T item) + { + this.Operation = operation; + this.Item = item; + } + + /// + /// Change operation (insert, update, or delete). + /// + public SqlChangeOperation Operation { get; } + + /// + /// POCO representing the row in the user table on which the change operation took place. If the change + /// operation is , then only the properties corresponding to the primary + /// keys will be populated. + /// + public T Item { get; } + } + + /// + /// Represents the type of change operation in the table row. + /// + public enum SqlChangeOperation + { + Insert, + Update, + Delete + } +} \ No newline at end of file diff --git a/Worker.Extensions.Sql/src/SqlTriggerAttribute.cs b/Worker.Extensions.Sql/src/SqlTriggerAttribute.cs new file mode 100644 index 000000000..db9549ca1 --- /dev/null +++ b/Worker.Extensions.Sql/src/SqlTriggerAttribute.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using Microsoft.Azure.Functions.Worker.Extensions.Abstractions; + +namespace Microsoft.Azure.Functions.Worker.Extensions.Sql +{ + public sealed class SqlTriggerAttribute : TriggerBindingAttribute + { + /// + /// Initializes a new instance of the class, which triggers the function when any changes on the specified table are detected. + /// + /// Name of the table to watch for changes. + /// The name of the app setting where the SQL connection string is stored + public SqlTriggerAttribute(string tableName, string connectionStringSetting) + { + this.TableName = tableName ?? throw new ArgumentNullException(nameof(tableName)); + this.ConnectionStringSetting = connectionStringSetting ?? throw new ArgumentNullException(nameof(connectionStringSetting)); + } + + /// + /// Name of the app setting containing the SQL connection string. + /// + public string ConnectionStringSetting { get; } + + /// + /// Name of the table to watch for changes. + /// + public string TableName { get; } + } +} \ No newline at end of file diff --git a/samples/samples-outofproc/Microsoft.Azure.WebJobs.Extensions.Sql.SamplesOutOfProc.csproj b/samples/samples-outofproc/Microsoft.Azure.WebJobs.Extensions.Sql.SamplesOutOfProc.csproj index 3a23a8f3f..ea36391ba 100644 --- a/samples/samples-outofproc/Microsoft.Azure.WebJobs.Extensions.Sql.SamplesOutOfProc.csproj +++ b/samples/samples-outofproc/Microsoft.Azure.WebJobs.Extensions.Sql.SamplesOutOfProc.csproj @@ -11,6 +11,7 @@ + diff --git a/samples/samples-outofproc/TriggerBindingSamples/ProductsTrigger.cs b/samples/samples-outofproc/TriggerBindingSamples/ProductsTrigger.cs new file mode 100644 index 000000000..e155ba700 --- /dev/null +++ b/samples/samples-outofproc/TriggerBindingSamples/ProductsTrigger.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Extensions.Sql; +using Microsoft.Azure.WebJobs.Extensions.Sql.SamplesOutOfProc.Common; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using System; + +namespace Microsoft.Azure.WebJobs.Extensions.Sql.SamplesOutOfProc.TriggerBindingSamples +{ + public class ProductsTrigger + { + private static readonly Action _loggerMessage = LoggerMessage.Define(LogLevel.Information, eventId: new EventId(0, "INFO"), formatString: "{Message}"); + + [Function("ProductsTrigger")] + public static void Run( + [SqlTrigger("[dbo].[Products]", "SqlConnectionString")] + IReadOnlyList> changes, FunctionContext context) + { + // The output is used to inspect the trigger binding parameter in test methods. + if (changes != null && changes.Count > 0) + { + _loggerMessage(context.GetLogger("ProductsTrigger"), "SQL Changes: " + JsonConvert.SerializeObject(changes), null); + } + } + } +} diff --git a/samples/samples-outofproc/packages.lock.json b/samples/samples-outofproc/packages.lock.json index b6f05b287..7698d5885 100644 --- a/samples/samples-outofproc/packages.lock.json +++ b/samples/samples-outofproc/packages.lock.json @@ -65,6 +65,12 @@ "Microsoft.Azure.Functions.Worker.Sdk.Generators": "1.0.0-preview1" } }, + "Newtonsoft.Json": { + "type": "Direct", + "requested": "[13.0.2, )", + "resolved": "13.0.2", + "contentHash": "R2pZ3B0UjeyHShm9vG+Tu0EBb2lC8b0dFzV9gVn50ofHXh9Smjk6kTn7A/FdAsC8B5cKib1OnGYOXxRBz5XQDg==" + }, "Azure.Core": { "type": "Transitive", "resolved": "1.24.0", diff --git a/test/Integration/SqlTriggerBindingIntegrationTests.cs b/test/Integration/SqlTriggerBindingIntegrationTests.cs index e33bdefd3..e13f24227 100644 --- a/test/Integration/SqlTriggerBindingIntegrationTests.cs +++ b/test/Integration/SqlTriggerBindingIntegrationTests.cs @@ -31,7 +31,7 @@ public SqlTriggerBindingIntegrationTests(ITestOutputHelper output = null) : base /// [Theory] [SqlInlineData()] - [UnsupportedLanguages(SupportedLanguages.Java, SupportedLanguages.OutOfProc)] + [UnsupportedLanguages(SupportedLanguages.Java)] public async Task SingleOperationTriggerTest(SupportedLanguages lang) { this.SetChangeTrackingForTable("Products");