diff --git a/src/sql/platform/serialization/common/serializationService.ts b/src/sql/platform/serialization/common/serializationService.ts index 4c8b2b5443..be33078ca0 100644 --- a/src/sql/platform/serialization/common/serializationService.ts +++ b/src/sql/platform/serialization/common/serializationService.ts @@ -129,10 +129,6 @@ export class SerializationService implements ISerializationService { let index = 0; let startRequestParams = this.createStartRequest(serializationRequest, index); 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); diff --git a/src/sql/workbench/contrib/notebook/browser/outputs/gridOutput.component.ts b/src/sql/workbench/contrib/notebook/browser/outputs/gridOutput.component.ts index 35bde46445..0aed970cbb 100644 --- a/src/sql/workbench/contrib/notebook/browser/outputs/gridOutput.component.ts +++ b/src/sql/workbench/contrib/notebook/browser/outputs/gridOutput.component.ts @@ -466,26 +466,14 @@ export class DataResourceDataProvider implements IGridDataProvider { if (endIndex > maxRow) { endIndex = maxRow; } - let result: ICellValue[][] = []; - if (includeHeaders) { - 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 => { + + return [].concat(this._rows.slice(index, endIndex).map(row => { if (this.isSelected(singleSelection)) { return row.slice(singleSelection.fromCell, singleSelection.toCell + 1); } else { return row; } })); - return result; }; // This code path uses the serialization service which uses a different request parameter diff --git a/src/sql/workbench/contrib/notebook/test/browser/dataResourceDataProvider.test.ts b/src/sql/workbench/contrib/notebook/test/browser/dataResourceDataProvider.test.ts index 8f458d8c25..e124da93d8 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/dataResourceDataProvider.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/dataResourceDataProvider.test.ts @@ -23,6 +23,8 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia import { URI } from 'vs/base/common/uri'; import { CellModel } from 'sql/workbench/services/notebook/browser/models/cell'; 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 { providerId: string; @@ -31,11 +33,11 @@ export class TestSerializationProvider implements azdata.SerializationProvider { // Write data to file async startSerialization(requestParams: azdata.SerializeDataStartRequestParams): Promise { let data: string = ''; + if (requestParams.includeHeaders) { + data = requestParams.columns.map(c => c.name).join(' ') + '\n'; + } requestParams.rows.forEach((row) => { - row.forEach((element) => { - data += element.displayValue + ' '; - }); - data += '\n'; + data += row.map(c => c.displayValue).join(' ') + '\n'; }); await fs.promises.writeFile(requestParams.filePath, data); return Promise.resolve({ succeeded: true, messages: undefined }); @@ -53,6 +55,7 @@ suite('Data Resource Data Provider', function () { let serializationService: SerializationService; let instantiationService: TypeMoq.Mock; let cellModel = TypeMoq.Mock.ofType(CellModel); + let configurationService = new TestConfigurationService(); // Create test data with two rows and two columns let source: IDataResource = { @@ -82,7 +85,7 @@ suite('Data Resource Data Provider', function () { serializationService.registerProvider('MSSQL', new TestSerializationProvider()); serializer = new ResultSerializer( undefined, // IQueryManagementService - undefined, // IConfigurationService + configurationService, editorService.object, contextService, fileDialogService, @@ -108,24 +111,34 @@ suite('Data Resource Data Provider', function () { serializationService, instantiationService.object ); + configurationService.updateValue('queryEditor', { + results: { + saveAsCsv: { + includeHeaders: false + } + } + }, ConfigurationTarget.USER); let noHeadersFile = URI.file(path.join(tempFolderPath, 'result_noHeaders.csv')); let fileDialogServiceStub = sinon.stub(fileDialogService, 'showSaveDialog').returns(Promise.resolve(noHeadersFile)); - let serializerStub = sinon.stub(serializer, 'getBasicSaveParameters').returns({ resultFormat: SaveFormat.CSV as string, includeHeaders: false }); await dataResourceDataProvider.serializeResults(SaveFormat.CSV, undefined); fileDialogServiceStub.restore(); - serializerStub.restore(); + configurationService.updateValue('queryEditor', { + results: { + saveAsCsv: { + includeHeaders: true + } + } + }, ConfigurationTarget.USER); let withHeadersFile = URI.file(path.join(tempFolderPath, 'result_withHeaders.csv')); fileDialogServiceStub = sinon.stub(fileDialogService, 'showSaveDialog').returns(Promise.resolve(withHeadersFile)); - serializerStub = sinon.stub(serializer, 'getBasicSaveParameters').returns({ resultFormat: SaveFormat.CSV as string, includeHeaders: true }); await dataResourceDataProvider.serializeResults(SaveFormat.CSV, undefined); fileDialogServiceStub.restore(); - serializerStub.restore(); 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); - 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'); }); });