11import * as vscode from 'vscode' ;
2- import { ExecutionResult , Row , TabularResult } from './driver' ;
2+ import { ExecutionResult } from './driver' ;
33import { globalConnPool , notebookType } from './main' ;
4+ import { resultToMarkdownTable } from './markdown' ;
45
56export class SQLNotebookController {
67 readonly controllerId = 'sql-notebook-executor' ;
@@ -77,19 +78,22 @@ export class SQLNotebookController {
7778 }
7879
7980 if ( typeof result === 'string' ) {
80- writeSuccess ( execution , result ) ;
81+ writeSuccess ( execution , [ [ text ( result ) ] ] ) ;
8182 return ;
8283 }
8384
8485 if (
8586 result . length === 0 ||
8687 ( result . length === 1 && result [ 0 ] . length === 0 )
8788 ) {
88- writeSuccess ( execution , 'Successfully executed query' ) ;
89+ writeSuccess ( execution , [ [ text ( 'Successfully executed query' ) ] ] ) ;
8990 return ;
9091 }
91- const tables = result . map ( resultToMarkdownTable ) ;
92- writeSuccess ( execution , tables , 'text/markdown' ) ;
92+
93+ writeSuccess ( execution , result . map ( item => [
94+ text ( resultToMarkdownTable ( item ) , "text/markdown" ) ,
95+ json ( item )
96+ ] ) ) ;
9397 }
9498}
9599
@@ -100,77 +104,17 @@ function writeErr(execution: vscode.NotebookCellExecution, err: string) {
100104 execution . end ( false , Date . now ( ) ) ;
101105}
102106
107+ const { text, json } = vscode . NotebookCellOutputItem ;
108+
103109function writeSuccess (
104110 execution : vscode . NotebookCellExecution ,
105- text : string | string [ ] ,
106- mimeType ?: string
111+ outputs : vscode . NotebookCellOutputItem [ ] [ ]
107112) {
108- const items = typeof text === 'string' ? [ text ] : text ;
109113 execution . replaceOutput (
110- items . map (
111- ( item ) =>
112- new vscode . NotebookCellOutput ( [
113- vscode . NotebookCellOutputItem . text ( item , mimeType ) ,
114- ] )
114+ outputs . map (
115+ ( items ) =>
116+ new vscode . NotebookCellOutput ( items )
115117 )
116118 ) ;
117119 execution . end ( true , Date . now ( ) ) ;
118120}
119-
120- function resultToMarkdownTable ( result : TabularResult ) : string {
121- if ( result . length < 1 ) {
122- return '*Empty Results Table*' ;
123- }
124-
125- const maxRows = getMaxRows ( ) ;
126- if ( result . length > maxRows ) {
127- result = result . slice ( 0 , maxRows ) ;
128- result . push (
129- Object . fromEntries ( Object . entries ( result ) . map ( ( pair ) => [ pair [ 0 ] , '...' ] ) )
130- ) ;
131- }
132- return `${ markdownHeader ( result [ 0 ] ) } \n${ result . map ( markdownRow ) . join ( '\n' ) } ` ;
133- }
134-
135- function getMaxRows ( ) : number {
136- const fallbackMaxRows = 25 ;
137- const maxRows : number | undefined = vscode . workspace
138- . getConfiguration ( 'SQLNotebook' )
139- . get ( 'maxResultRows' ) ;
140- return maxRows ?? fallbackMaxRows ;
141- }
142-
143- function serializeCell ( a : any ) : any {
144- try {
145- // serialize buffers as hex strings
146- if ( Buffer . isBuffer ( a ) ) {
147- return `0x${ a . toString ( 'hex' ) } ` ;
148- }
149- // attempt to serialize all remaining "object" values as JSON
150- if ( typeof a === 'object' ) {
151- return JSON . stringify ( a ) ;
152- }
153- if ( typeof a === 'string' ) {
154- return a . replace ( / \n / g, '\\n' ) . replace ( / \r / g, '\\r' ) ;
155- }
156- return a ;
157- } catch {
158- return a ;
159- }
160- }
161-
162- function markdownRow ( row : Row ) : string {
163- const middle = Object . entries ( row )
164- . map ( ( pair ) => pair [ 1 ] )
165- . map ( serializeCell )
166- . join ( ' | ' ) ;
167- return `| ${ middle } |` ;
168- }
169-
170- function markdownHeader ( obj : Row ) : string {
171- const keys = Object . keys ( obj ) . join ( ' | ' ) ;
172- const divider = Object . keys ( obj )
173- . map ( ( ) => '--' )
174- . join ( ' | ' ) ;
175- return `| ${ keys } |\n| ${ divider } |` ;
176- }
0 commit comments