From fda2c3753116a07f99ed53cccf06be0a8ce6c4c8 Mon Sep 17 00:00:00 2001 From: Kim Santiago <31145923+kisantia@users.noreply.github.com> Date: Wed, 31 Aug 2022 15:39:53 -0700 Subject: [PATCH] the fix open in designer menu item is not available after script is updated with newly added create table statements (#20522) * make open in designer available after a script is updated with a new create table statement * uppercase --- .../src/controllers/mainController.ts | 3 +- .../src/controllers/projectController.ts | 43 ++++++++++++++++++- .../src/models/tree/fileFolderTreeItem.ts | 6 +-- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/extensions/sql-database-projects/src/controllers/mainController.ts b/extensions/sql-database-projects/src/controllers/mainController.ts index 257af6d1c6..62e077d2bf 100644 --- a/extensions/sql-database-projects/src/controllers/mainController.ts +++ b/extensions/sql-database-projects/src/controllers/mainController.ts @@ -17,7 +17,7 @@ import { WorkspaceTreeItem } from 'dataworkspace'; import * as constants from '../common/constants'; import { SqlDatabaseProjectProvider } from '../projectProvider/projectProvider'; import { EntryType, GenerateProjectFromOpenApiSpecOptions, ItemType } from 'sqldbproj'; -import { TableFileNode } from '../models/tree/fileFolderTreeItem'; +import { FileNode, TableFileNode } from '../models/tree/fileFolderTreeItem'; import { ProjectRootTreeItem } from '../models/tree/projectTreeItem'; import { getAzdataApi } from '../common/utils'; @@ -88,6 +88,7 @@ export default class MainController implements vscode.Disposable { this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.exclude', async (node: WorkspaceTreeItem) => { return this.projectsController.exclude(node); })); this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.changeTargetPlatform', async (node: WorkspaceTreeItem) => { return this.projectsController.changeTargetPlatform(node); })); this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.validateExternalStreamingJob', async (node: WorkspaceTreeItem) => { return this.projectsController.validateExternalStreamingJob(node); })); + this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.openFileWithWatcher', async (fileSystemUri: vscode.Uri, node: FileNode) => { return this.projectsController.openFileWithWatcher(fileSystemUri, node); })); this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.openInDesigner', async (node: WorkspaceTreeItem) => { if (node?.element instanceof TableFileNode) { const tableFileNode = node.element as TableFileNode; diff --git a/extensions/sql-database-projects/src/controllers/projectController.ts b/extensions/sql-database-projects/src/controllers/projectController.ts index 4d97cc78a7..415044ae40 100644 --- a/extensions/sql-database-projects/src/controllers/projectController.ts +++ b/extensions/sql-database-projects/src/controllers/projectController.ts @@ -65,6 +65,11 @@ export enum TaskExecutionMode { export type AddDatabaseReferenceSettings = ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings; +interface FileWatcherStatus { + fileWatcher: vscode.FileSystemWatcher; + containsCreateTableStatement: boolean; +} + /** * Controller for managing lifecycle of projects */ @@ -78,7 +83,8 @@ export class ProjectsController { private azureSqlClient: AzureSqlClient; private autorestHelper: AutorestHelper; - projFileWatchers = new Map(); + private projFileWatchers = new Map(); + private fileWatchers = new Map(); constructor(private _outputChannel: vscode.OutputChannel) { this.netCoreTool = new NetCoreTool(this._outputChannel); @@ -890,6 +896,41 @@ export class ProjectsController { } } + /** + * Opens a file in the editor and adds a file watcher to check if a create table statement has been added + * @param fileSystemUri uri of file + * @param node node of file in the tree + */ + public async openFileWithWatcher(fileSystemUri: vscode.Uri, node: FileNode): Promise { + await vscode.commands.executeCommand(constants.vscodeOpenCommand, fileSystemUri); + const projectTargetVersion = (node.root as ProjectRootTreeItem).project.getProjectTargetVersion(); + const initiallyContainsCreateTableStatement = await utils.fileContainsCreateTableStatement(fileSystemUri.fsPath, projectTargetVersion); + + const fileWatcher: vscode.FileSystemWatcher = vscode.workspace.createFileSystemWatcher(fileSystemUri.fsPath); + this.fileWatchers.set(fileSystemUri.fsPath, { fileWatcher: fileWatcher, containsCreateTableStatement: initiallyContainsCreateTableStatement }); + + fileWatcher.onDidChange(async (uri: vscode.Uri) => { + const afterContainsCreateTableStatement = await utils.fileContainsCreateTableStatement(fileSystemUri.fsPath, projectTargetVersion); + const previousStatus = this.fileWatchers.get(uri.fsPath)?.containsCreateTableStatement; + + // if the contains create table statement status is different, reload the project so that the "Open in Designer" menu option + // on the file node is there if a create table statement has been added or removed if it's been removed + if (previousStatus !== afterContainsCreateTableStatement) { + utils.getDataWorkspaceExtensionApi().refreshProjectsTree(); + this.fileWatchers.get(uri.fsPath)!.containsCreateTableStatement = afterContainsCreateTableStatement; + } + }); + + // stop watching for changes to the file after it's closed + const closeSqlproj = vscode.workspace.onDidCloseTextDocument((d) => { + if (this.fileWatchers.has(d.uri.fsPath)) { + this.fileWatchers.get(d.uri.fsPath)?.fileWatcher.dispose(); + this.fileWatchers.delete(d.uri.fsPath); + closeSqlproj.dispose(); + } + }); + } + /** * Reloads the given project. Throws an error if given project is not a valid open project. * @param context diff --git a/extensions/sql-database-projects/src/models/tree/fileFolderTreeItem.ts b/extensions/sql-database-projects/src/models/tree/fileFolderTreeItem.ts index 847d2909e3..996cda0ff9 100644 --- a/extensions/sql-database-projects/src/models/tree/fileFolderTreeItem.ts +++ b/extensions/sql-database-projects/src/models/tree/fileFolderTreeItem.ts @@ -60,9 +60,9 @@ export class FileNode extends BaseProjectTreeItem { const treeItem = new vscode.TreeItem(this.fileSystemUri, vscode.TreeItemCollapsibleState.None); treeItem.command = { - title: 'Open file', - command: 'vscode.open', - arguments: [this.fileSystemUri] + title: 'Open file with file watcher', + command: 'sqlDatabaseProjects.openFileWithWatcher', + arguments: [this.fileSystemUri, this] }; treeItem.contextValue = DatabaseProjectItemType.file;