mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Fix headers being exported twice from notebooks (#21195)
* fix headers being exported twice * simplify * fix test
This commit is contained in:
@@ -129,10 +129,6 @@ export class SerializationService implements ISerializationService {
|
|||||||
let index = 0;
|
let index = 0;
|
||||||
let startRequestParams = this.createStartRequest(serializationRequest, index);
|
let startRequestParams = this.createStartRequest(serializationRequest, index);
|
||||||
index = index + startRequestParams.rows.length;
|
index = index + startRequestParams.rows.length;
|
||||||
// Adjust row index based on whether or not header row is included
|
|
||||||
if (serializationRequest.includeHeaders) {
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
|
|
||||||
let startResult = await provider.startSerialization(startRequestParams);
|
let startResult = await provider.startSerialization(startRequestParams);
|
||||||
|
|
||||||
|
|||||||
@@ -466,26 +466,14 @@ export class DataResourceDataProvider implements IGridDataProvider {
|
|||||||
if (endIndex > maxRow) {
|
if (endIndex > maxRow) {
|
||||||
endIndex = maxRow;
|
endIndex = maxRow;
|
||||||
}
|
}
|
||||||
let result: ICellValue[][] = [];
|
|
||||||
if (includeHeaders) {
|
return [].concat(this._rows.slice(index, endIndex).map(row => {
|
||||||
result.push(columns.map(col => {
|
|
||||||
let headerData: azdata.DbCellValue;
|
|
||||||
headerData = {
|
|
||||||
displayValue: col.columnName,
|
|
||||||
isNull: false,
|
|
||||||
invariantCultureDisplayValue: col.columnName
|
|
||||||
};
|
|
||||||
return headerData;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
result = result.concat(this._rows.slice(index, endIndex).map(row => {
|
|
||||||
if (this.isSelected(singleSelection)) {
|
if (this.isSelected(singleSelection)) {
|
||||||
return row.slice(singleSelection.fromCell, singleSelection.toCell + 1);
|
return row.slice(singleSelection.fromCell, singleSelection.toCell + 1);
|
||||||
} else {
|
} else {
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This code path uses the serialization service which uses a different request parameter
|
// This code path uses the serialization service which uses a different request parameter
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia
|
|||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { CellModel } from 'sql/workbench/services/notebook/browser/models/cell';
|
import { CellModel } from 'sql/workbench/services/notebook/browser/models/cell';
|
||||||
import { createandLoadNotebookModel } from 'sql/workbench/contrib/notebook/test/browser/cellToolbarActions.test';
|
import { createandLoadNotebookModel } from 'sql/workbench/contrib/notebook/test/browser/cellToolbarActions.test';
|
||||||
|
import { TestConfigurationService } from 'sql/platform/connection/test/common/testConfigurationService';
|
||||||
|
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||||
|
|
||||||
export class TestSerializationProvider implements azdata.SerializationProvider {
|
export class TestSerializationProvider implements azdata.SerializationProvider {
|
||||||
providerId: string;
|
providerId: string;
|
||||||
@@ -31,11 +33,11 @@ export class TestSerializationProvider implements azdata.SerializationProvider {
|
|||||||
// Write data to file
|
// Write data to file
|
||||||
async startSerialization(requestParams: azdata.SerializeDataStartRequestParams): Promise<azdata.SerializeDataResult> {
|
async startSerialization(requestParams: azdata.SerializeDataStartRequestParams): Promise<azdata.SerializeDataResult> {
|
||||||
let data: string = '';
|
let data: string = '';
|
||||||
|
if (requestParams.includeHeaders) {
|
||||||
|
data = requestParams.columns.map(c => c.name).join(' ') + '\n';
|
||||||
|
}
|
||||||
requestParams.rows.forEach((row) => {
|
requestParams.rows.forEach((row) => {
|
||||||
row.forEach((element) => {
|
data += row.map(c => c.displayValue).join(' ') + '\n';
|
||||||
data += element.displayValue + ' ';
|
|
||||||
});
|
|
||||||
data += '\n';
|
|
||||||
});
|
});
|
||||||
await fs.promises.writeFile(requestParams.filePath, data);
|
await fs.promises.writeFile(requestParams.filePath, data);
|
||||||
return Promise.resolve({ succeeded: true, messages: undefined });
|
return Promise.resolve({ succeeded: true, messages: undefined });
|
||||||
@@ -53,6 +55,7 @@ suite('Data Resource Data Provider', function () {
|
|||||||
let serializationService: SerializationService;
|
let serializationService: SerializationService;
|
||||||
let instantiationService: TypeMoq.Mock<InstantiationService>;
|
let instantiationService: TypeMoq.Mock<InstantiationService>;
|
||||||
let cellModel = TypeMoq.Mock.ofType(CellModel);
|
let cellModel = TypeMoq.Mock.ofType(CellModel);
|
||||||
|
let configurationService = new TestConfigurationService();
|
||||||
|
|
||||||
// Create test data with two rows and two columns
|
// Create test data with two rows and two columns
|
||||||
let source: IDataResource = {
|
let source: IDataResource = {
|
||||||
@@ -82,7 +85,7 @@ suite('Data Resource Data Provider', function () {
|
|||||||
serializationService.registerProvider('MSSQL', new TestSerializationProvider());
|
serializationService.registerProvider('MSSQL', new TestSerializationProvider());
|
||||||
serializer = new ResultSerializer(
|
serializer = new ResultSerializer(
|
||||||
undefined, // IQueryManagementService
|
undefined, // IQueryManagementService
|
||||||
undefined, // IConfigurationService
|
configurationService,
|
||||||
editorService.object,
|
editorService.object,
|
||||||
contextService,
|
contextService,
|
||||||
fileDialogService,
|
fileDialogService,
|
||||||
@@ -108,24 +111,34 @@ suite('Data Resource Data Provider', function () {
|
|||||||
serializationService,
|
serializationService,
|
||||||
instantiationService.object
|
instantiationService.object
|
||||||
);
|
);
|
||||||
|
configurationService.updateValue('queryEditor', {
|
||||||
|
results: {
|
||||||
|
saveAsCsv: {
|
||||||
|
includeHeaders: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, ConfigurationTarget.USER);
|
||||||
let noHeadersFile = URI.file(path.join(tempFolderPath, 'result_noHeaders.csv'));
|
let noHeadersFile = URI.file(path.join(tempFolderPath, 'result_noHeaders.csv'));
|
||||||
let fileDialogServiceStub = sinon.stub(fileDialogService, 'showSaveDialog').returns(Promise.resolve(noHeadersFile));
|
let fileDialogServiceStub = sinon.stub(fileDialogService, 'showSaveDialog').returns(Promise.resolve(noHeadersFile));
|
||||||
let serializerStub = sinon.stub(serializer, 'getBasicSaveParameters').returns(<azdata.SaveResultsRequestParams>{ resultFormat: SaveFormat.CSV as string, includeHeaders: false });
|
|
||||||
await dataResourceDataProvider.serializeResults(SaveFormat.CSV, undefined);
|
await dataResourceDataProvider.serializeResults(SaveFormat.CSV, undefined);
|
||||||
fileDialogServiceStub.restore();
|
fileDialogServiceStub.restore();
|
||||||
serializerStub.restore();
|
|
||||||
|
|
||||||
|
configurationService.updateValue('queryEditor', {
|
||||||
|
results: {
|
||||||
|
saveAsCsv: {
|
||||||
|
includeHeaders: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, ConfigurationTarget.USER);
|
||||||
let withHeadersFile = URI.file(path.join(tempFolderPath, 'result_withHeaders.csv'));
|
let withHeadersFile = URI.file(path.join(tempFolderPath, 'result_withHeaders.csv'));
|
||||||
fileDialogServiceStub = sinon.stub(fileDialogService, 'showSaveDialog').returns(Promise.resolve(withHeadersFile));
|
fileDialogServiceStub = sinon.stub(fileDialogService, 'showSaveDialog').returns(Promise.resolve(withHeadersFile));
|
||||||
serializerStub = sinon.stub(serializer, 'getBasicSaveParameters').returns(<azdata.SaveResultsRequestParams>{ resultFormat: SaveFormat.CSV as string, includeHeaders: true });
|
|
||||||
await dataResourceDataProvider.serializeResults(SaveFormat.CSV, undefined);
|
await dataResourceDataProvider.serializeResults(SaveFormat.CSV, undefined);
|
||||||
fileDialogServiceStub.restore();
|
fileDialogServiceStub.restore();
|
||||||
serializerStub.restore();
|
|
||||||
|
|
||||||
const noHeadersResult = await fs.readFile(noHeadersFile.fsPath);
|
const noHeadersResult = await fs.readFile(noHeadersFile.fsPath);
|
||||||
assert.strictEqual(noHeadersResult.toString(), '1 2 \n3 4 \n', 'result data should not include headers');
|
assert.strictEqual(noHeadersResult.toString(), '1 2\n3 4\n', 'result data should not include headers');
|
||||||
|
|
||||||
const withHeadersResult = await fs.readFile(withHeadersFile.fsPath);
|
const withHeadersResult = await fs.readFile(withHeadersFile.fsPath);
|
||||||
assert.strictEqual(withHeadersResult.toString(), 'col1 col2 \n1 2 \n3 4 \n', 'result data should include headers');
|
assert.strictEqual(withHeadersResult.toString(), 'col1 col2\n1 2\n3 4\n', 'result data should include headers');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user