Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion samples/Common/ProductUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static List<Product> GetNewProducts(int num)
var product = new Product
{
ProductID = i,
Cost = 100,
Cost = 100 * i,
Name = "test"
};
products.Add(product);
Expand Down
3 changes: 2 additions & 1 deletion samples/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples.AddProductsCollector.Run(Microsoft.AspNetCore.Http.HttpRequest,Microsoft.Azure.WebJobs.ICollector{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})~Microsoft.AspNetCore.Mvc.IActionResult")]
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.OutputBindingSamples.TimerTriggerProducts.Run(Microsoft.Azure.WebJobs.TimerInfo,Microsoft.Extensions.Logging.ILogger,Microsoft.Azure.WebJobs.ICollector{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})")]
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.InputBindingSamples.GetProducts.Run(Microsoft.AspNetCore.Http.HttpRequest,System.Collections.Generic.IEnumerable{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})~Microsoft.AspNetCore.Mvc.IActionResult")]
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.InputBindingSamples.GetProductNamesView.Run(Microsoft.AspNetCore.Http.HttpRequest,System.Collections.Generic.IEnumerable{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.ProductName})~Microsoft.AspNetCore.Mvc.IActionResult")]
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.InputBindingSamples.GetProductNamesView.Run(Microsoft.AspNetCore.Http.HttpRequest,System.Collections.Generic.IEnumerable{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.ProductName})~Microsoft.AspNetCore.Mvc.IActionResult")]
[assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Unused parameter is required by functions binding", Scope = "member", Target = "~M:Microsoft.Azure.WebJobs.Extensions.Sql.Samples.InputBindingSamples.GetProductsStoredProcedureFromAppSetting.Run(Microsoft.AspNetCore.Http.HttpRequest,System.Collections.Generic.IEnumerable{Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common.Product})~Microsoft.AspNetCore.Mvc.IActionResult")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common;

namespace Microsoft.Azure.WebJobs.Extensions.Sql.Samples.InputBindingSamples
{
/// <summary>
/// This shows an example of a SQL Input binding that uses a stored procedure
/// from an app setting value to query for Products with a specific cost that is also defined as an app setting value.
/// </summary>
public static class GetProductsStoredProcedureFromAppSetting
{
[FunctionName("GetProductsStoredProcedureFromAppSetting")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "getproductsbycost")]
HttpRequest req,
[Sql("%Sp_SelectCost%",
CommandType = System.Data.CommandType.StoredProcedure,
Parameters = "@Cost=%ProductCost%",
ConnectionStringSetting = "SqlConnectionString")]
IEnumerable<Product> products)
{
return new OkObjectResult(products);
}
}
}
4 changes: 3 additions & 1 deletion samples/local.settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"SqlConnectionString": ""
"SqlConnectionString": "",
"Sp_SelectCost": "SelectProductsCost",
"ProductCost": 100
}
}
1 change: 1 addition & 0 deletions src/SqlAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public SqlAttribute(string commandText)
/// For an input binding, either a SQL query or stored procedure that will be run in the database referred to in the ConnectionString.
/// For an output binding, the table name.
/// </summary>
[AutoResolve]
public string CommandText { get; }

/// <summary>
Expand Down
35 changes: 35 additions & 0 deletions test/Integration/SqlInputBindingIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,26 @@ public async void GetProductsNameEmptyTest(int n, int cost)
Assert.Equal(expectedResponse, actualResponse, StringComparer.OrdinalIgnoreCase);
}

[Fact]
public async void GetProductsByCostTest()
{
this.StartFunctionHost(nameof(GetProductsStoredProcedureFromAppSetting));

// Generate T-SQL to insert n rows of data with cost
Product[] products = GetProducts(3, 100);
this.InsertProducts(products);
Product[] productsWithCost100 = GetProducts(1, 100);

// Run the function
HttpResponseMessage response = await this.SendInputRequest("getproductsbycost");

// Verify result
string expectedResponse = JsonConvert.SerializeObject(productsWithCost100);
string actualResponse = await response.Content.ReadAsStringAsync();

Assert.Equal(expectedResponse, actualResponse, StringComparer.OrdinalIgnoreCase);
}

[Fact]
public async void GetProductNamesViewTest()
{
Expand Down Expand Up @@ -132,6 +152,21 @@ private static Product[] GetProductsWithSameCost(int n, int cost)
return result;
}

private static Product[] GetProducts(int n, int cost)
{
var result = new Product[n];
for (int i = 1; i <= n; i++)
{
result[i - 1] = new Product
{
ProductID = i,
Name = "test",
Cost = cost * i
};
}
return result;
}

private static Product[] GetProductsWithSameCostAndName(int n, int cost, string name, int offset = 0)
{
var result = new Product[n];
Expand Down