Handle undefined nodeInfo for top-level database objects (#24298)

This commit is contained in:
Cory Rivera 2023-09-06 14:12:07 -07:00 коммит произвёл GitHub
Родитель 9f4e19f3db
Коммит 32817ae52e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 65 добавлений и 46 удалений

Просмотреть файл

@ -69,40 +69,52 @@ async function handleNewObjectDialogCommand(context: azdata.ObjectExplorerContex
if (!connectionUri) {
return;
}
let objectType: ObjectManagement.NodeType;
switch (context.nodeInfo!.objectType) {
case FolderType.ApplicationRoles:
objectType = ObjectManagement.NodeType.ApplicationRole;
break;
case FolderType.DatabaseRoles:
objectType = ObjectManagement.NodeType.DatabaseRole;
break;
case FolderType.ServerLevelLogins:
objectType = ObjectManagement.NodeType.ServerLevelLogin;
break;
case FolderType.ServerLevelServerRoles:
objectType = ObjectManagement.NodeType.ServerLevelServerRole;
break;
case FolderType.Users:
objectType = ObjectManagement.NodeType.User;
break;
case FolderType.Databases:
objectType = ObjectManagement.NodeType.Database;
break;
}
// Fall back to node type in case the user right clicked on an object instead of a folder
if (!objectType) {
switch (context.nodeInfo!.nodeType) {
case ObjectManagement.NodeType.ApplicationRole:
case ObjectManagement.NodeType.DatabaseRole:
case ObjectManagement.NodeType.ServerLevelLogin:
case ObjectManagement.NodeType.ServerLevelServerRole:
case ObjectManagement.NodeType.User:
case ObjectManagement.NodeType.Database:
objectType = context.nodeInfo!.nodeType as ObjectManagement.NodeType;
if (context.nodeInfo) {
switch (context.nodeInfo.objectType) {
case FolderType.ApplicationRoles:
objectType = ObjectManagement.NodeType.ApplicationRole;
break;
default:
throw new Error(objectManagementLoc.NoDialogFoundError(context.nodeInfo!.nodeType, context.nodeInfo!.objectType));
case FolderType.DatabaseRoles:
objectType = ObjectManagement.NodeType.DatabaseRole;
break;
case FolderType.ServerLevelLogins:
objectType = ObjectManagement.NodeType.ServerLevelLogin;
break;
case FolderType.ServerLevelServerRoles:
objectType = ObjectManagement.NodeType.ServerLevelServerRole;
break;
case FolderType.Users:
objectType = ObjectManagement.NodeType.User;
break;
case FolderType.Databases:
objectType = ObjectManagement.NodeType.Database;
break;
}
// Fall back to node type in case the user right clicked on an object instead of a folder
if (!objectType) {
switch (context.nodeInfo.nodeType) {
case ObjectManagement.NodeType.ApplicationRole:
case ObjectManagement.NodeType.DatabaseRole:
case ObjectManagement.NodeType.ServerLevelLogin:
case ObjectManagement.NodeType.ServerLevelServerRole:
case ObjectManagement.NodeType.User:
case ObjectManagement.NodeType.Database:
objectType = context.nodeInfo.nodeType as ObjectManagement.NodeType;
break;
default:
throw new Error(objectManagementLoc.NoDialogFoundError(context.nodeInfo.nodeType, context.nodeInfo.objectType));
}
}
} else {
// Node info will be missing for top level connection items like servers and databases, so make a best guess here based on connection info.
// If we don't have a database name, then we have to assume it's a server node, which isn't valid for the New Object command.
if (context.connectionProfile?.databaseName?.length > 0) {
objectType = ObjectManagement.NodeType.Database;
} else {
throw new Error(objectManagementLoc.NotSupportedError(ObjectManagement.NodeType.Server));
}
}
@ -111,7 +123,7 @@ async function handleNewObjectDialogCommand(context: azdata.ObjectExplorerContex
const options: ObjectManagementDialogOptions = {
connectionUri: connectionUri,
isNewObject: true,
database: context.connectionProfile!.databaseName!,
database: context.connectionProfile?.databaseName,
objectType: objectType,
objectName: '',
parentUrn: parentUrn,
@ -122,7 +134,7 @@ async function handleNewObjectDialogCommand(context: azdata.ObjectExplorerContex
}
catch (err) {
TelemetryReporter.createErrorEvent2(ObjectManagementViewName, TelemetryActions.OpenNewObjectDialog, err).withAdditionalProperties({
objectType: context.nodeInfo!.nodeType
objectType: objectType
}).send();
console.error(err);
await vscode.window.showErrorMessage(objectManagementLoc.OpenNewObjectDialogError(objectManagementLoc.getNodeTypeDisplayName(objectType), getErrorMessage(err)));
@ -329,14 +341,16 @@ async function handleDropDatabase(context: azdata.ObjectExplorerContext, service
}
try {
const parentUrn = await getParentUrn(context);
const objectName = context.nodeInfo?.label ?? context.connectionProfile.databaseName;
const objectUrn = context.nodeInfo?.metadata?.urn ?? `Server/Database[@Name='${escapeSingleQuotes(context.connectionProfile.databaseName)}']`;
const options: ObjectManagementDialogOptions = {
connectionUri: connectionUri,
isNewObject: false,
database: context.connectionProfile!.databaseName!,
objectType: context.nodeInfo.nodeType as ObjectManagement.NodeType,
objectName: context.nodeInfo.label,
objectType: ObjectManagement.NodeType.Database,
objectName: objectName,
parentUrn: parentUrn,
objectUrn: context.nodeInfo!.metadata!.urn,
objectUrn: objectUrn,
objectExplorerContext: context
};
const dialog = new DropDatabaseDialog(service, options);
@ -344,7 +358,7 @@ async function handleDropDatabase(context: azdata.ObjectExplorerContext, service
}
catch (err) {
TelemetryReporter.createErrorEvent2(ObjectManagementViewName, TelemetryActions.OpenDropDatabaseDialog, err).withAdditionalProperties({
objectType: context.nodeInfo!.nodeType
objectType: ObjectManagement.NodeType.Database
}).send();
console.error(err);
await vscode.window.showErrorMessage(objectManagementLoc.OpenDropDatabaseDialogError(getErrorMessage(err)));
@ -380,12 +394,16 @@ async function getConnectionUri(context: azdata.ObjectExplorerContext): Promise<
return connectionUri;
}
async function getParentUrn(context: azdata.ObjectExplorerContext): Promise<string> {
let node = undefined;
let currentNodePath = context.nodeInfo!.parentNodePath;
do {
node = await azdata.objectexplorer.getNode(context.connectionProfile!.id, currentNodePath);
currentNodePath = node?.parentNodePath;
} while (node && currentNodePath && !node.metadata?.urn);
return node?.metadata?.urn;
async function getParentUrn(context: azdata.ObjectExplorerContext): Promise<string | undefined> {
let parentUrn: string = undefined;
if (context.nodeInfo) {
let node = undefined;
let currentNodePath = context.nodeInfo.parentNodePath;
do {
node = await azdata.objectexplorer.getNode(context.connectionProfile!.id, currentNodePath);
currentNodePath = node?.parentNodePath;
} while (node && currentNodePath && !node.metadata?.urn);
parentUrn = node?.metadata?.urn;
}
return parentUrn;
}

Просмотреть файл

@ -27,6 +27,7 @@ export const DatabaseRoleTypeDisplayName: string = localize('objectManagement.Da
export const DatabaseRoleTypeDisplayNameInTitle: string = localize('objectManagement.DatabaseRoleTypeDisplayNameInTitle', "Database Role");
export const DatabaseTypeDisplayNameInTitle: string = localize('objectManagement.DatabaseDisplayNameInTitle', "Database");
export function NoDialogFoundError(nodeType: string, objectType: string): string { return localize('objectManagement.noDialogFoundError', "Could not find a supported dialog for node type '{0}' and object type '{1}'.", nodeType, objectType); }
export function NotSupportedError(objectType: string): string { return localize('objectManagement.notSupportedError', "This command is not supported for object type '{0}'.", objectType); }
// Shared Strings
export const FailedToRetrieveConnectionInfoErrorMessage: string = localize('objectManagement.noConnectionUriError', "Failed to retrieve the connection information, please reconnect and try again.")