@@ -10,7 +10,9 @@ import {
1010 Disposable
1111} from "vscode" ;
1212import { JobManager } from "../../../config" ;
13- import { SelfCodeNode } from "./nodes" ;
13+ import { SelfCodeNode , SelfIleStackFrame } from "./nodes" ;
14+ import { openExampleCommand } from "../../examples/exampleBrowser" ;
15+ import { SQLExample } from "../../examples" ;
1416
1517type ChangeTreeDataEventType = SelfCodeTreeItem | undefined | null | void ;
1618
@@ -42,14 +44,14 @@ export class selfCodesResultsView implements TreeDataProvider<any> {
4244 this . setRefreshEnabled ( false , true ) ;
4345 } ) ,
4446 vscode . commands . registerCommand ( `vscode-db2i.self.copySqlStatement` , async ( item : SelfCodeTreeItem ) => {
45- if ( item && item . selfCodeNode . STMTTEXT ) {
46- await vscode . env . clipboard . writeText ( item . selfCodeNode . STMTTEXT ) ;
47+ if ( item && item . error . STMTTEXT ) {
48+ await vscode . env . clipboard . writeText ( item . error . STMTTEXT ) ;
4749 vscode . window . showInformationMessage ( `SQL statement copied to clipboard.` ) ;
4850 }
4951 } ) ,
5052 vscode . commands . registerCommand ( `vscode-db2i.self.displayDetails` , async ( item : SelfCodeTreeItem ) => {
51- if ( item && item . selfCodeNode ) {
52- const jsonData = JSON . stringify ( item . selfCodeNode , null , 2 ) ;
53+ if ( item && item . error ) {
54+ const jsonData = JSON . stringify ( item . error , null , 2 ) ;
5355 const document = await vscode . workspace . openTextDocument ( {
5456 content : jsonData ,
5557 language : `json`
@@ -81,13 +83,18 @@ export class selfCodesResultsView implements TreeDataProvider<any> {
8183 async getSelfCodes ( ) : Promise < SelfCodeNode [ ] > {
8284 const selected = JobManager . getSelection ( ) ;
8385 if ( selected ) {
84- const content = `SELECT job_name, user_name, reason_code, logged_time, logged_sqlstate, logged_sqlcode, matches, stmttext,
85- message_text, message_second_level_text
86- FROM qsys2.sql_error_log, lateral
87- (select * from TABLE(SYSTOOLS.SQLCODE_INFO(logged_sqlcode)))
86+ const content = `SELECT
87+ job_name, user_name, reason_code, logged_time, logged_sqlstate, logged_sqlcode, matches, stmttext, message_text, message_second_level_text,
88+ program_library, program_name, program_type, module_name, client_applname, client_programid, initial_stack
89+ FROM qsys2.sql_error_log, lateral (select * from TABLE(SYSTOOLS.SQLCODE_INFO(logged_sqlcode)))
8890 where user_name = current_user
8991 order by logged_time desc` ;
90- const data : SelfCodeNode [ ] = await JobManager . runSQL < SelfCodeNode > ( content , undefined ) ;
92+
93+ const data : SelfCodeNode [ ] = ( await JobManager . runSQL < SelfCodeNode > ( content ) ) . map ( ( row ) => ( {
94+ ...row ,
95+ INITIAL_STACK : JSON . parse ( row . INITIAL_STACK as unknown as string )
96+ } ) ) ;
97+
9198 return data ;
9299 }
93100 return ;
@@ -100,28 +107,20 @@ export class selfCodesResultsView implements TreeDataProvider<any> {
100107 getTreeItem ( element : any ) : TreeItem | Thenable < TreeItem > {
101108 return element ;
102109 }
103- async getChildren ( element ?: any ) : Promise < any [ ] > {
110+
111+ async getChildren ( element ?: SelfCodeTreeItem | SelfErrorStackItem ) : Promise < any [ ] > {
104112 if ( element ) {
105- return [ ] ;
113+ if ( element instanceof SelfCodeTreeItem ) {
114+ return element . getChilden ( ) ;
115+ } else if ( element instanceof SelfErrorStackItem ) {
116+ return element . getChildren ( ) ;
117+ }
106118 } else {
107119 const selfCodes = await this . getSelfCodes ( ) ;
108120
109121 if ( selfCodes ) {
110122 return selfCodes . map ( ( error ) => {
111- const label = `${ error . LOGGED_SQLSTATE } (${ error . LOGGED_SQLCODE } ) ${ error . REASON_CODE != null ? error . REASON_CODE : "" } ` ;
112- const details = `${ error . MESSAGE_TEXT } ` ; // ${error.MATCHES < 100 ? hitsTxt : '💯'.padStart(10, ' ')} 🔥`;
113- const hoverMessage = new vscode . MarkdownString (
114- `**SQL Statement💻:** ${ error . STMTTEXT } \n\n---\n\n**SQL Job🛠️:** ${ error . JOB_NAME } \n\n---\n\n**Occurrences🔥:** ${ error . MATCHES } \n\n---\n\n**Details✏️:** ${ error . MESSAGE_SECOND_LEVEL_TEXT } `
115- ) ;
116- hoverMessage . isTrusted = true ;
117- const treeItem = new SelfCodeTreeItem (
118- label ,
119- details ,
120- hoverMessage ,
121- vscode . TreeItemCollapsibleState . None ,
122- error
123- ) ;
124- treeItem . contextValue = `selfCodeNode` ;
123+ const treeItem = new SelfCodeTreeItem ( error ) ;
125124 return treeItem ;
126125 } ) ;
127126 }
@@ -148,24 +147,117 @@ export class selfCodesResultsView implements TreeDataProvider<any> {
148147 }
149148}
150149export class SelfCodeTreeItem extends TreeItem {
151- selfCodeNode : SelfCodeNode ;
152-
153150 constructor (
154- public readonly errorMessage : string ,
155- public readonly details : string ,
156- public readonly hoverMessage : vscode . MarkdownString ,
157- public readonly collapsibleState : vscode . TreeItemCollapsibleState ,
158- error : SelfCodeNode
151+ public error : SelfCodeNode
159152 ) {
160- super ( errorMessage , collapsibleState ) ;
161- this . selfCodeNode = error ;
162- this . tooltip = hoverMessage ; // Hover text
163- this . description = details ; // Additional details shown in the tree view
153+ const label = `${ error . LOGGED_SQLSTATE } (${ error . LOGGED_SQLCODE } ) ${ error . REASON_CODE != null ? error . REASON_CODE : "" } ` ;
154+ super ( label , vscode . TreeItemCollapsibleState . Collapsed ) ;
155+
156+ const hover = new vscode . MarkdownString (
157+ [
158+ `**💻 SQL Statement:** ${ error . STMTTEXT } ` ,
159+ `` , `` ,
160+ `---` ,
161+ `` , `` ,
162+ `**🛠️ SQL Job:** ${ error . JOB_NAME } ` ,
163+ `` , `` ,
164+ `---` ,
165+ `` , `` ,
166+ `**🔥 Occurrences:** ${ error . MATCHES } ` ,
167+ `` , `` ,
168+ `---` ,
169+ `` , `` ,
170+ `**✏️ Details:** ${ error . MESSAGE_SECOND_LEVEL_TEXT } `
171+ ] . join ( `\n` )
172+ ) ;
173+ hover . isTrusted = true ;
174+
175+ this . tooltip = hover ;
176+
177+ this . description = error . MESSAGE_TEXT ; // Additional details shown in the tree view
164178 this . resourceUri = vscode . Uri . from ( {
165179 scheme : `selfCodeTreeView` ,
166180 path : error . MATCHES . toString ( )
167181 } )
182+
168183 this . iconPath = error . LOGGED_SQLCODE < 0 ? new vscode . ThemeIcon ( `error` ) : new vscode . ThemeIcon ( `warning` ) ;
184+ this . contextValue = `selfCodeNode` ;
185+ }
186+
187+ getChilden ( ) : TreeItem [ ] {
188+ const validStack = this . error . INITIAL_STACK . initial_stack
189+ . sort ( ( a , b ) => a . ORD - b . ORD ) // Ord, low to high
190+ . filter ( ( stack ) => stack . LIB !== `QSYS` ) ;
191+
192+ const items = [
193+ new SelfErrorStatementItem ( this . error . STMTTEXT ) ,
194+ new SelfErrorNodeItem ( `Job` , this . error . JOB_NAME ) ,
195+ new SelfErrorNodeItem ( `Client Name` , this . error . CLIENT_APPLNAME ) ,
196+ new SelfErrorNodeItem ( `Client Program` , this . error . CLIENT_PROGRAMID ) ,
197+ new SelfErrorNodeItem ( `Object` , `${ this . error . PROGRAM_LIBRARY } /${ this . error . PROGRAM_NAME } (${ this . error . PROGRAM_TYPE } , ${ this . error . MODULE_NAME } )` ) ,
198+ ]
199+
200+ if ( validStack . length > 0 ) {
201+ items . push ( new SelfErrorStackItem ( validStack ) ) ;
202+ }
203+
204+ return items ;
205+ }
206+ }
207+
208+ class SelfErrorStatementItem extends TreeItem {
209+ constructor ( statement : string ) {
210+ super ( `Statement` , vscode . TreeItemCollapsibleState . None ) ;
211+ this . iconPath = new vscode . ThemeIcon ( `database` ) ;
212+ this . description = statement ;
213+
214+ const hoverable = new vscode . MarkdownString ( ) ;
215+ hoverable . appendCodeblock ( statement , `sql` ) ;
216+ this . tooltip = hoverable ;
217+
218+ const example : SQLExample = {
219+ name : `Statement` ,
220+ content : [ statement ]
221+ }
222+
223+ this . command = {
224+ command : openExampleCommand ,
225+ title : `Open example` ,
226+ arguments : [ example ]
227+ } ;
228+ }
229+ }
230+
231+ class SelfErrorNodeItem extends TreeItem {
232+ constructor ( label : string , description : string ) {
233+ super ( label , vscode . TreeItemCollapsibleState . None ) ;
234+ this . iconPath = new vscode . ThemeIcon ( `info` ) ;
235+ this . description = description ;
236+ }
237+ }
238+
239+ class SelfErrorStackItem extends TreeItem {
240+ constructor ( private stack : SelfIleStackFrame [ ] ) {
241+ super ( `Stack` , vscode . TreeItemCollapsibleState . Collapsed ) ;
242+ this . iconPath = new vscode . ThemeIcon ( `debug` ) ;
243+ this . contextValue = `selfCodeStack` ;
244+
245+ this . resourceUri = vscode . Uri . from ( {
246+ scheme : `selfCodeTreeView` ,
247+ path : stack . length . toString ( )
248+ } )
249+ }
250+
251+ getChildren ( ) : SelfErrorStackFrameItem [ ] {
252+ return this . stack . map ( ( stackCall ) => new SelfErrorStackFrameItem ( stackCall ) ) ;
253+ }
254+ }
255+
256+ class SelfErrorStackFrameItem extends TreeItem {
257+ constructor ( stackCall : SelfIleStackFrame ) {
258+ super ( `${ stackCall . PROC } :${ stackCall . STMT } ` , vscode . TreeItemCollapsibleState . None ) ;
259+ this . description = `${ stackCall . LIB } /${ stackCall . PGM } (${ stackCall . TYPE } , ${ stackCall . MODULE } )` ;
260+ this . contextValue = `selfCodeStackCall` ;
169261 }
170262}
171263
@@ -185,8 +277,7 @@ export class SelfTreeDecorationProvider implements FileDecorationProvider {
185277
186278 if ( ! isNaN ( errorCount ) && errorCount > 0 ) {
187279 return {
188- badge : errorCount < 100 ? errorCount . toString ( ) : '💯' ,
189- tooltip : `Occurrences: ${ errorCount } `
280+ badge : errorCount < 100 ? errorCount . toString ( ) : '💯'
190281 }
191282 }
192283 }
0 commit comments