mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-22 01:25:38 -05:00
[SQL Migration] Allow folders inside blob containers (#21952)
* WIP * WIP * WIP - add new property to blob * Add error messages * Fix undefined for offline scenario * Add support for offline scenario * Clean up * vbump extension * remove >1 level deep folders * fix [object] object issue * Remove unnecessary asyncs * don't allow >1 level deep for offline scenario lastBackupFile
This commit is contained in:
@@ -705,6 +705,15 @@ export async function getAzureSqlMigrationServices(account?: Account, subscripti
|
||||
return [];
|
||||
}
|
||||
|
||||
export interface Blob {
|
||||
resourceGroup: azureResource.AzureResourceResourceGroup;
|
||||
storageAccount: azureResource.AzureGraphResource;
|
||||
blobContainer: azureResource.BlobContainer;
|
||||
storageKey: string;
|
||||
lastBackupFile?: string;
|
||||
folderName?: string;
|
||||
}
|
||||
|
||||
export async function getBlobContainer(account?: Account, subscription?: azureResource.AzureResourceSubscription, storageAccount?: azure.StorageAccount): Promise<azureResource.BlobContainer[]> {
|
||||
let blobContainers: azureResource.BlobContainer[] = [];
|
||||
try {
|
||||
@@ -722,7 +731,14 @@ export async function getBlobLastBackupFileNames(account?: Account, subscription
|
||||
let lastFileNames: azureResource.Blob[] = [];
|
||||
try {
|
||||
if (account && subscription && storageAccount && blobContainer) {
|
||||
lastFileNames = await azure.getBlobs(account, subscription, storageAccount, blobContainer.name);
|
||||
const blobs = await azure.getBlobs(account, subscription, storageAccount, blobContainer.name);
|
||||
|
||||
blobs.forEach(blob => {
|
||||
// only show at most one folder deep
|
||||
if ((blob.name.split('/').length === 1 || blob.name.split('/').length === 2) && !lastFileNames.includes(blob)) {
|
||||
lastFileNames.push(blob);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
logError(TelemetryViews.Utils, 'utils.getBlobLastBackupFileNames', e);
|
||||
@@ -731,6 +747,64 @@ export async function getBlobLastBackupFileNames(account?: Account, subscription
|
||||
return lastFileNames;
|
||||
}
|
||||
|
||||
export async function getBlobFolders(account?: Account, subscription?: azureResource.AzureResourceSubscription, storageAccount?: azure.StorageAccount, blobContainer?: azureResource.BlobContainer): Promise<string[]> {
|
||||
let folders: string[] = [];
|
||||
try {
|
||||
if (account && subscription && storageAccount && blobContainer) {
|
||||
const blobs = await azure.getBlobs(account, subscription, storageAccount, blobContainer.name);
|
||||
|
||||
blobs.forEach(blob => {
|
||||
let folder: string = '';
|
||||
|
||||
if (blob.name.split('/').length === 1) {
|
||||
folder = '/'; // no folder (root)
|
||||
} else if (blob.name.split('/').length === 2) {
|
||||
folder = blob.name.split('/')[0]; // one folder deep
|
||||
}
|
||||
|
||||
if (folder && !folders.includes(folder)) {
|
||||
folders.push(folder);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
logError(TelemetryViews.Utils, 'utils.getBlobLastBackupFolders', e);
|
||||
}
|
||||
folders.sort();
|
||||
return folders;
|
||||
}
|
||||
|
||||
export function getBlobContainerNameWithFolder(blob: Blob, isOfflineMigration: boolean): string {
|
||||
const blobContainerName = blob.blobContainer.name;
|
||||
|
||||
if (isOfflineMigration) {
|
||||
const lastBackupFile = blob.lastBackupFile;
|
||||
if (!lastBackupFile || lastBackupFile.split('/').length !== 2) {
|
||||
return blobContainerName;
|
||||
}
|
||||
|
||||
// for offline scenario, take the folder name out of the blob name and add it to the container name instead
|
||||
return blobContainerName + '/' + lastBackupFile.split('/')[0];
|
||||
} else {
|
||||
const folderName = blob.folderName;
|
||||
if (!folderName || folderName === '/' || folderName === 'undefined') {
|
||||
return blobContainerName;
|
||||
}
|
||||
|
||||
// for online scenario, take the explicitly provided folder name
|
||||
return blobContainerName + '/' + folderName;
|
||||
}
|
||||
}
|
||||
|
||||
export function getLastBackupFileNameWithoutFolder(blob: Blob) {
|
||||
const lastBackupFile = blob.lastBackupFile;
|
||||
if (!lastBackupFile || lastBackupFile.split('/').length !== 2) {
|
||||
return lastBackupFile;
|
||||
}
|
||||
|
||||
return lastBackupFile.split('/')[1];
|
||||
}
|
||||
|
||||
export function getAzureResourceDropdownValues(
|
||||
azureResources: { location: string, id: string, name: string }[],
|
||||
location: azureResource.AzureLocation | undefined,
|
||||
@@ -762,12 +836,16 @@ export function getResourceDropdownValues(resources: { id: string, name: string
|
||||
|| [{ name: '', displayName: resourceNotFoundMessage }];
|
||||
}
|
||||
|
||||
export async function getAzureTenantsDropdownValues(tenants: Tenant[]): Promise<CategoryValue[]> {
|
||||
export function getAzureTenantsDropdownValues(tenants: Tenant[]): CategoryValue[] {
|
||||
if (!tenants || !tenants.length) {
|
||||
return [{ name: '', displayName: constants.ACCOUNT_SELECTION_PAGE_NO_LINKED_ACCOUNTS_ERROR }];
|
||||
}
|
||||
|
||||
return tenants?.map(tenant => { return { name: tenant.id, displayName: tenant.displayName }; })
|
||||
|| [{ name: '', displayName: constants.ACCOUNT_SELECTION_PAGE_NO_LINKED_ACCOUNTS_ERROR }];
|
||||
}
|
||||
|
||||
export async function getAzureLocationsDropdownValues(locations: azureResource.AzureLocation[]): Promise<CategoryValue[]> {
|
||||
export function getAzureLocationsDropdownValues(locations: azureResource.AzureLocation[]): CategoryValue[] {
|
||||
if (!locations || !locations.length) {
|
||||
return [{ name: '', displayName: constants.NO_LOCATION_FOUND }];
|
||||
}
|
||||
@@ -776,11 +854,24 @@ export async function getAzureLocationsDropdownValues(locations: azureResource.A
|
||||
|| [{ name: '', displayName: constants.NO_LOCATION_FOUND }];
|
||||
}
|
||||
|
||||
export async function getBlobLastBackupFileNamesValues(blobs: azureResource.Blob[]): Promise<CategoryValue[]> {
|
||||
export function getBlobLastBackupFileNamesValues(blobs: azureResource.Blob[]): CategoryValue[] {
|
||||
if (!blobs || !blobs.length) {
|
||||
return [{ name: '', displayName: constants.NO_BLOBFILES_FOUND }];
|
||||
}
|
||||
|
||||
return blobs?.map(blob => { return { name: blob.name, displayName: blob.name }; })
|
||||
|| [{ name: '', displayName: constants.NO_BLOBFILES_FOUND }];
|
||||
}
|
||||
|
||||
export function getBlobFolderValues(folders: string[]): CategoryValue[] {
|
||||
if (!folders || !folders.length) {
|
||||
return [{ name: '', displayName: constants.NO_BLOBFOLDERS_FOUND }];
|
||||
}
|
||||
|
||||
return folders?.map(folder => { return { name: folder, displayName: folder }; })
|
||||
|| [{ name: '', displayName: constants.NO_BLOBFOLDERS_FOUND }];
|
||||
}
|
||||
|
||||
export async function updateControlDisplay(control: Component, visible: boolean, displayStyle: DisplayType = 'inline'): Promise<void> {
|
||||
const display = visible ? displayStyle : 'none';
|
||||
control.display = display;
|
||||
|
||||
Reference in New Issue
Block a user