Remove sql-bindings logic from sql-database-projects (#18754)

* remove sql-bindings logic from sql-database-projects
This commit is contained in:
Vasu Bhog
2022-03-17 11:36:28 -07:00
committed by GitHub
parent bdb81bc9b1
commit 80007a72cc
14 changed files with 2 additions and 1022 deletions

View File

@@ -1,102 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fse from 'fs-extra';
import * as path from 'path';
import * as vscode from 'vscode';
import * as utils from './utils';
import * as constants from './constants';
import { parseJson } from './parseJson';
/**
* Represents the settings in an Azure function project's local.settings.json file
*/
export interface ILocalSettingsJson {
IsEncrypted?: boolean;
Values?: { [key: string]: string };
Host?: { [key: string]: string };
ConnectionStrings?: { [key: string]: string };
}
/**
* copied and modified from vscode-azurefunctions extension
* @param localSettingsPath full path to local.settings.json
* @returns settings in local.settings.json. If no settings are found, returns default "empty" settings
*/
export async function getLocalSettingsJson(localSettingsPath: string): Promise<ILocalSettingsJson> {
if (await fse.pathExists(localSettingsPath)) {
const data: string = (await fse.readFile(localSettingsPath)).toString();
if (/[^\s]/.test(data)) {
try {
return parseJson(data);
} catch (error) {
throw new Error(constants.failedToParse(error.message));
}
}
}
return {
IsEncrypted: false // Include this by default otherwise the func cli assumes settings are encrypted and fails to run
};
}
/**
* Adds a new setting to a project's local.settings.json file
* modified from setLocalAppSetting code from vscode-azurefunctions extension
* @param projectFolder full path to project folder
* @param key Key of the new setting
* @param value Value of the new setting
* @returns true if successful adding the new setting, false if unsuccessful
*/
export async function setLocalAppSetting(projectFolder: string, key: string, value: string): Promise<boolean> {
const localSettingsPath: string = path.join(projectFolder, constants.azureFunctionLocalSettingsFileName);
const settings: ILocalSettingsJson = await getLocalSettingsJson(localSettingsPath);
settings.Values = settings.Values || {};
if (settings.Values[key] === value) {
// don't do anything if it's the same as the existing value
return true;
} else if (settings.Values[key]) {
const result = await vscode.window.showWarningMessage(constants.settingAlreadyExists(key), { modal: true }, constants.yesString);
if (result !== constants.yesString) {
// key already exists and user doesn't want to overwrite it
return false;
}
}
settings.Values[key] = value;
await fse.writeJson(localSettingsPath, settings, { spaces: 2 });
return true;
}
/**
* Gets the Azure Functions project that contains the given file if the project is open in one of the workspace folders
* @param fileUri file that the containing project needs to be found for
* @returns uri of project or undefined if project couldn't be found
*/
export async function getAFProjectContainingFile(fileUri: vscode.Uri): Promise<vscode.Uri | undefined> {
// get functions csprojs in the workspace
const projectPromises = vscode.workspace.workspaceFolders?.map(f => utils.getAllProjectsInFolder(f.uri, '.csproj')) ?? [];
const functionsProjects = (await Promise.all(projectPromises)).reduce((prev, curr) => prev.concat(curr), []).filter(p => isFunctionProject(path.dirname(p.fsPath)));
// look for project folder containing file if there's more than one
if (functionsProjects.length > 1) {
// TODO: figure out which project contains the file
// the new style csproj doesn't list all the files in the project anymore, unless the file isn't in the same folder
// so we can't rely on using that to check
console.error('need to find which project contains the file ' + fileUri.fsPath);
return undefined;
} else if (functionsProjects.length === 0) {
throw new Error(constants.noAzureFunctionsProjectsInWorkspace);
} else {
return functionsProjects[0];
}
}
// Use 'host.json' as an indicator that this is a functions project
// copied from verifyIsproject.ts in vscode-azurefunctions extension
export async function isFunctionProject(folderPath: string): Promise<boolean> {
return fse.pathExists(path.join(folderPath, constants.hostFileName));
}

View File

@@ -533,48 +533,3 @@ export const defaultDSP = targetPlatformToVersion.get(defaultTargetPlatform)!;
export function getTargetPlatformFromVersion(version: string): string {
return Array.from(targetPlatformToVersion.keys()).filter(k => targetPlatformToVersion.get(k) === version)[0];
}
// Insert SQL binding
export const hostFileName = 'host.json';
export const sqlExtensionPackageName = 'Microsoft.Azure.WebJobs.Extensions.Sql';
export const placeHolderObject = '[dbo].[table1]';
export const sqlBindingsHelpLink = 'https://github.com/Azure/azure-functions-sql-extension/blob/main/README.md';
export const passwordPlaceholder = '******';
export const input = localize('input', "Input");
export const output = localize('output', "Output");
export const selectBindingType = localize('selectBindingType', "Select type of binding");
export const selectAzureFunction = localize('selectAzureFunction', "Select an Azure function in the current file to add SQL binding to");
export const sqlTableOrViewToQuery = localize('sqlTableOrViewToQuery', "SQL table or view to query");
export const sqlTableToUpsert = localize('sqlTableToUpsert', "SQL table to upsert into");
export const connectionStringSetting = localize('connectionStringSetting', "Connection string setting name");
export const selectSetting = localize('selectSetting', "Select SQL connection string setting from local.settings.json");
export const connectionStringSettingPlaceholder = localize('connectionStringSettingPlaceholder', "Connection string setting specified in \"local.settings.json\"");
export const noAzureFunctionsInFile = localize('noAzureFunctionsInFile', "No Azure functions in the current active file");
export const noAzureFunctionsProjectsInWorkspace = localize('noAzureFunctionsProjectsInWorkspace', "No Azure functions projects found in the workspace");
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");
export const saveChangesInFile = localize('saveChangesInFile', "There are unsaved changes in the current file. Save now?");
export const save = localize('save', "Save");
export function settingAlreadyExists(settingName: string) { return localize('SettingAlreadyExists', 'Local app setting \'{0}\' already exists. Overwrite?', settingName); }
export function failedToParse(errorMessage: string) { return localize('failedToParse', 'Failed to parse "{0}": {1}.', azureFunctionLocalSettingsFileName, errorMessage); }
export function jsonParseError(error: string, line: number, column: number) { return localize('jsonParseError', '{0} near line "{1}", column "{2}"', error, line, column); }
export const moreInformation = localize('moreInformation', "More Information");
export const addPackageReferenceMessage = localize('addPackageReferenceMessage', 'To use SQL bindings, ensure your Azure Functions project has a reference to {0}', sqlExtensionPackageName);
export const addSqlBindingPackageError = localize('addSqlBindingPackageError', 'Error adding Sql Binding extension package to project');
export const failedToGetConnectionString = localize('failedToGetConnectionString', 'An error occurred generating the connection string for the selected connection');
export const connectionProfile = localize('connectionProfile', 'Select a connection profile');
export const userConnectionString = localize('userConnectionString', 'Enter connection string');
export const selectConnectionString = localize('selectConnectionString', 'Select SQL connection string method');
export const selectConnectionError = (err?: any) => err ? localize('selectConnectionError', "Failed to set connection string app setting: {0}", utils.getErrorMessage(err)) : localize('unableToSetConnectionString', "Failed to set connection string app setting");
export const includePassword = localize('includePassword', 'Do you want to include the password from this connection in your local.settings.json file?');
export const enterPasswordPrompt = localize('enterPasswordPrompt', 'Enter the password to be used for the connection string');
export const enterPasswordManually = localize('enterPasswordManually', 'Enter password or press escape to cancel');
export const userPasswordLater = localize('userPasswordLater', 'In order to user the SQL connection string later you will need to manually enter the password in your local.settings.json file.');
export const openFile = localize('openFile', "Open File");
export const closeButton = localize('closeButton', "Close");

View File

@@ -1,45 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// copied from vscode-azurefunctions extension
import * as jsonc from 'jsonc-parser';
import * as constants from './constants';
/**
* Parses and returns JSON
* Has extra logic to remove a BOM character if it exists and handle comments
*/
export function parseJson<T extends object>(data: string): T {
if (data.charCodeAt(0) === 0xFEFF) {
data = data.slice(1);
}
const errors: jsonc.ParseError[] = [];
const result: T = <T>jsonc.parse(data, errors, { allowTrailingComma: true });
if (errors.length > 0) {
const [line, column]: [number, number] = getLineAndColumnFromOffset(data, errors[0].offset);
throw new Error(constants.jsonParseError(jsonc.printParseErrorCode(errors[0].error), line, column));
} else {
return result;
}
}
export function getLineAndColumnFromOffset(data: string, offset: number): [number, number] {
const lines: string[] = data.split('\n');
let charCount: number = 0;
let lineCount: number = 0;
let column: number = 0;
for (const line of lines) {
lineCount += 1;
const lineLength: number = line.length + 1;
charCount += lineLength;
if (charCount >= offset) {
column = offset - (charCount - lineLength);
break;
}
}
return [lineCount, column];
}

View File

@@ -16,7 +16,6 @@ export enum TelemetryViews {
ProjectController = 'ProjectController',
SqlProjectPublishDialog = 'SqlProjectPublishDialog',
ProjectTree = 'ProjectTree',
SqlBindingsQuickPick = 'SqlBindingsQuickPick'
}
export enum TelemetryActions {
@@ -33,7 +32,5 @@ export enum TelemetryActions {
build = 'build',
updateProjectForRoundtrip = 'updateProjectForRoundtrip',
changePlatformType = 'changePlatformType',
updateSystemDatabaseReferencesInProjFile = 'updateSystemDatabaseReferencesInProjFile',
startAddSqlBinding = 'startAddSqlBinding',
finishAddSqlBinding = 'finishAddSqlBinding'
updateSystemDatabaseReferencesInProjFile = 'updateSystemDatabaseReferencesInProjFile'
}

View File

@@ -302,16 +302,6 @@ export async function getSchemaCompareService(): Promise<ISchemaCompareService>
}
}
export async function getAzureFunctionService(): Promise<vscodeMssql.IAzureFunctionsService> {
if (getAzdataApi()) {
// this isn't supported in ADS
throw new Error('Azure Functions service is not supported in Azure Data Studio');
} else {
const api = await getVscodeMssqlApi();
return api.azureFunctions;
}
}
export async function getVscodeMssqlApi(): Promise<vscodeMssql.IExtension> {
const ext = vscode.extensions.getExtension(vscodeMssql.extension.name) as vscode.Extension<vscodeMssql.IExtension>;
return ext.activate();
@@ -475,23 +465,6 @@ export async function detectCommandInstallation(command: string): Promise<boolea
return false;
}
/**
* Gets all the projects of the specified extension in the folder
* @param folder
* @param projectExtension project extension to filter on
* @returns array of project uris
*/
export async function getAllProjectsInFolder(folder: vscode.Uri, projectExtension: string): Promise<vscode.Uri[]> {
// path needs to use forward slashes for glob to work
const escapedPath = glob.escapePath(folder.fsPath.replace(/\\/g, '/'));
// filter for projects with the specified project extension
const projFilter = path.posix.join(escapedPath, '**', `*${projectExtension}`);
// glob will return an array of file paths with forward slashes, so they need to be converted back if on windows
return (await glob(projFilter)).map(p => vscode.Uri.file(path.resolve(p)));
}
export function validateSqlServerPortNumber(port: string | undefined): boolean {
if (!port) {
return false;