import BaseCommand from "../common/baseCommand" ; import * as vscode from 'vscode' ; import * as EasyXml from 'easyxml' ; import * as csv from 'csv-stringify' ; import { SaveTableQuickPickItem } from "../common/IConnQuickPick" ; import { Global } from "../common/global" ; import { QueryResults } from "../common/database" ; export class saveResultCommand extends BaseCommand { async run ( uri ) { let results = Global . ResultManager . activeWinResults ; if ( ! results ) { vscode . window . showWarningMessage ( 'Unable to save data - dataset not found' ) ; return ; } let resultIndex = 0 ; if ( results . length > 1 ) { let tables = [ ] ; for ( let i = 1 ; i <= results . length ; i ++ ) { tables . push ( { label : 'Table ' + i , index : i - 1 } ) ; } let selected = await vscode . window . showQuickPick ( tables ) ; if ( ! selected ) return ; resultIndex = selected . index ; } if ( results [ resultIndex ] . rowCount < 1 ) { vscode . window . showWarningMessage ( 'Unable to save data - table has no data' ) ; return ; } let formats = [ 'json' , 'xml' , 'csv' ] ; let selFormat = await vscode . window . showQuickPick ( formats ) ; if ( ! selFormat ) return ; let fileData = null ; if ( selFormat === 'json' ) { let data = transformResult ( results [ resultIndex ] ) ; fileData = JSON . stringify ( data , null , 2 ) ; } else if ( selFormat === 'xml' ) { var ser = new EasyXml ( { singularize : true , rootElement : 'results' , dateFormat : 'ISO' , manifest : true } ) ; let data = transformResult ( results [ resultIndex ] ) ; fileData = ser . render ( data ) ; } else if ( selFormat === 'csv' ) { let columns = transformColumns ( results [ resultIndex ] . fields ) ; let csvError = false ; fileData = await new Promise < string > ( ( resolve ) => { csv ( results [ resultIndex ] . rows , { header : true , columns : columns , cast : { boolean : ( value ) : string => { return value ? 'true' : 'false' ; } } } , ( err , output ) => { if ( err ) { csvError = err ; resolve ( '' ) ; return ; } resolve ( output ) ; } ) ; } ) ; } try { let doc = await vscode . workspace . openTextDocument ( { language : selFormat } ) ; let editor = await vscode . window . showTextDocument ( doc , 1 , false ) ; let result = await editor . edit ( edit => edit . insert ( new vscode . Position ( 0 , 0 ) , fileData ) ) ; if ( ! result ) vscode . window . showErrorMessage ( 'Error occurred opening content in editor' ) ; } catch ( err ) { vscode . window . showErrorMessage ( err ) ; } } } function transformResult ( result ) { let columns = transformColumns ( result . fields ) ; return result . rows . map ( ( row ) => transformData ( columns , row ) ) ; } function transformData ( fields , row ) { let newRow = { } ; fields . forEach ( field => { newRow [ field . name ] = row [ field . index ] ; } ) ; return newRow ; } function transformColumns ( fields ) { let transformedFields = [ ] ; let fieldCounts = { } ; fields . forEach ( ( field , idx ) => { if ( fieldCounts . hasOwnProperty ( field . name ) ) { fieldCounts [ field . name ] ++ ; transformedFields . push ( { ... field , name : field . name + '_' + fieldCounts [ field . name ] , header : field . name , key : field . name , index : idx , } ) ; } else { fieldCounts [ field . name ] = 0 ; transformedFields . push ( { ... field , header : field . name , key : field . name , index : idx } ) ; } } ) ; return transformedFields ; } type MappedField = QueryResults [ 'fields' ] [ 0 ] & { header : string ; index : number ; key : string ; } ; type RowRecord = Record < string , any > ;