Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
29 changes: 1 addition & 28 deletions extensions/sql-bindings/src/common/azureFunctionsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as os from 'os';
import * as fs from 'fs';
import * as vscode from 'vscode';
import * as path from 'path';
Expand Down Expand Up @@ -133,32 +132,6 @@ export async function getAzureFunctionsExtensionApi(): Promise<AzureFunctionsExt
}
}

/**
* TODO REMOVE defaultSqlBindingTextLines
* Overwrites the Azure function methods body to work with the binding
* @param filePath is the path for the function file (.cs for C# functions)
*/
export function overwriteAzureFunctionMethodBody(filePath: string): void {
let defaultBindedFunctionText = fs.readFileSync(filePath, 'utf-8');
// Replace default binding text
let newValueLines = defaultBindedFunctionText.split(os.EOL);
const defaultFunctionTextToSkip = new Set(constants.defaultSqlBindingTextLines);
let replacedValueLines = [];
for (let defaultLine of newValueLines) {
// Skipped lines
if (defaultFunctionTextToSkip.has(defaultLine.trimStart())) {
continue;
} else if (defaultLine.trimStart() === constants.defaultBindingResult) { // Result change
replacedValueLines.push(defaultLine.replace(constants.defaultBindingResult, constants.sqlBindingResult));
} else {
// Normal lines to be included
replacedValueLines.push(defaultLine);
}
}
defaultBindedFunctionText = replacedValueLines.join(os.EOL);
fs.writeFileSync(filePath, defaultBindedFunctionText, 'utf-8');
}

/**
* Gets the azure function project for the user to choose from a list of projects files
* If only one project is found that project is used to add the binding to
Expand Down Expand Up @@ -276,7 +249,7 @@ export async function addNugetReferenceToProjectFile(selectedProjectFile: string
export async function addConnectionStringToConfig(connectionString: string, projectFile: string): Promise<void> {
const settingsFile = await getSettingsFile(projectFile);
if (settingsFile) {
await setLocalAppSetting(path.dirname(settingsFile), constants.sqlConnectionString, connectionString);
await setLocalAppSetting(path.dirname(settingsFile), constants.sqlConnectionStringSetting, connectionString);
}
}

Expand Down
16 changes: 3 additions & 13 deletions extensions/sql-bindings/src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,12 @@ const localize = nls.loadMessageBundle();

// Azure Functions
export const azureFunctionsExtensionName = 'ms-azuretools.vscode-azurefunctions';
export const sqlConnectionString = 'SqlConnectionString';
export const linkToAzureFunctionExtension = 'https://docs.microsoft.com/azure/azure-functions/functions-develop-vs-code';
export const sqlBindingsDoc = 'https://aka.ms/sqlbindings';
export const defaultSqlBindingTextLines =
[
'log.LogInformation(\"C# HTTP trigger function processed a request.\");',
'string name = req.Query[\"name\"];',
'string requestBody = await new StreamReader(req.Body).ReadToEndAsync();',
'dynamic data = JsonConvert.DeserializeObject(requestBody);',
'name = name ?? data?.name;',
'string responseMessage = string.IsNullOrEmpty(name) ? \"This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.\" : $\"Hello, {name}. This HTTP triggered function executed successfully.\";'
];
export const defaultBindingResult = 'return new OkObjectResult(responseMessage);';
export const sqlBindingResult = `return new OkObjectResult(result);`;
export const sqlConnectionStringSetting = 'SqlConnectionString';
export const sqlExtensionPackageName = 'Microsoft.Azure.WebJobs.Extensions.Sql';
export const inputTemplateID = 'SqlInputBinding';
export const outputTemplateID = 'SqlOutputBinding';
export const functionNameTitle = localize('functionNameTitle', 'Function Name');
export const selectProject = localize('selectProject', 'Select the Azure Function project for the SQL Binding');
export const azureFunctionsExtensionNotFound = localize('azureFunctionsExtensionNotFound', 'The Azure Functions extension is required to create a new Azure Function with SQL binding but is not installed, install it now?');
Expand Down Expand Up @@ -65,7 +56,6 @@ export const noAzureFunctionsProjectsInWorkspace = localize('noAzureFunctionsPro
export const addPackage = localize('addPackage', "Add Package");
export const createNewLocalAppSetting = localize('createNewLocalAppSetting', 'Create new local app setting');
export const createNewLocalAppSettingWithIcon = `$(add) ${createNewLocalAppSetting}`;
export const sqlConnectionStringSetting = 'SqlConnectionString';
export const valueMustNotBeEmpty = localize('valueMustNotBeEmpty', "Value must not be empty");
export const enterConnectionStringSettingName = localize('enterConnectionStringSettingName', "Enter connection string setting name");
export const enterConnectionString = localize('enterConnectionString', "Enter connection string");
Expand Down
42 changes: 19 additions & 23 deletions extensions/sql-bindings/src/services/azureFunctionsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export async function createAzureFunction(connectionString: string, schema: stri
// because of an AF extension API issue, we have to get the newly created file by adding a watcher
// issue: https://github.com/microsoft/vscode-azurefunctions/issues/2908
const newFunctionFileObject = azureFunctionsUtils.waitForNewFunctionFile(projectFile);
let functionFile: string;
let functionName: string;

try {
Expand All @@ -71,41 +70,38 @@ export async function createAzureFunction(connectionString: string, schema: stri
return;
}

// create C# HttpTrigger
// select input or output binding
const selectedBinding = await azureFunctionsUtils.promptForBindingType();

if (!selectedBinding) {
return;
}

// set the templateId based on the selected binding type
let templateId: string = selectedBinding.type === BindingType.input ? constants.inputTemplateID : constants.outputTemplateID;
let objectName = utils.generateQuotedFullName(schema, table);

// create C# Azure Function with SQL Binding
await azureFunctionApi.createFunction({
language: 'C#',
templateId: 'HttpTrigger',
templateId: templateId,
functionName: functionName,
functionSettings: {
connectionStringSetting: constants.sqlConnectionStringSetting,
...(selectedBinding.type === BindingType.input && { object: objectName }),
...(selectedBinding.type === BindingType.output && { table: objectName })
},
folderPath: projectFile
});

// check for the new function file to be created and dispose of the file system watcher
const timeoutForFunctionFile = utils.timeoutPromise(constants.timeoutAzureFunctionFileError);
functionFile = await Promise.race([newFunctionFileObject.filePromise, timeoutForFunctionFile]);
await Promise.race([newFunctionFileObject.filePromise, timeoutForFunctionFile]);
} finally {
newFunctionFileObject.watcherDisposable.dispose();
}

// select input or output binding
const selectedBinding = await azureFunctionsUtils.promptForBindingType();

if (!selectedBinding) {
return;
}

await azureFunctionsUtils.addNugetReferenceToProjectFile(projectFile);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this? I thought the template added this for us as well.

Copy link
Contributor Author

@VasuBhog VasuBhog Mar 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, just checked this. The template does add the NuGet reference.

<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Sql" Version="0.1.131-preview" />

await azureFunctionsUtils.addConnectionStringToConfig(connectionString, projectFile);

let objectName = utils.generateQuotedFullName(schema, table);
await addSqlBinding(
selectedBinding.type,
functionFile,
functionName,
objectName,
constants.sqlConnectionString
);

azureFunctionsUtils.overwriteAzureFunctionMethodBody(functionFile);
}
}

Expand Down