Skip to content

Commit 84130a2

Browse files
committed
feat(LibraryNavigator): added ITC Support
Signed-off-by: Kishan Patel <[email protected]>
1 parent 468e3c4 commit 84130a2

File tree

6 files changed

+84
-102
lines changed

6 files changed

+84
-102
lines changed

client/src/components/LibraryNavigator/index.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -126,30 +126,6 @@ class LibraryNavigator implements SubscriptionProvider {
126126
}
127127
},
128128
),
129-
commands.registerCommand(
130-
"SAS.showTableColumns",
131-
async (item: LibraryItem) => {
132-
try {
133-
const tableInfo = await this.libraryDataProvider.getTableInfo(item);
134-
const columns = await this.libraryDataProvider.fetchColumns(item);
135-
136-
this.webviewManager.render(
137-
new TablePropertiesViewer(
138-
this.extensionUri,
139-
item.uid,
140-
tableInfo,
141-
columns,
142-
true, // Show columns tab
143-
),
144-
`columns-${item.uid}`,
145-
);
146-
} catch (error) {
147-
window.showErrorMessage(
148-
`Failed to load table columns: ${error.message}`,
149-
);
150-
}
151-
},
152-
),
153129
commands.registerCommand("SAS.collapseAllLibraries", () => {
154130
commands.executeCommand(
155131
"workbench.actions.treeView.librarydataprovider.collapseAll",

client/src/connection/itc/ItcLibraryAdapter.ts

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class ItcLibraryAdapter implements LibraryAdapter {
5050
$runner.GetColumns("${item.library}", "${item.name}")
5151
`;
5252
const output = await executeRawCode(code);
53-
const columns = JSON.parse(output).map((column) => ({
53+
const rawColumns = JSON.parse(output);
54+
const columns = rawColumns.map((column) => ({
5455
...column,
5556
type: getColumnIconType(column),
5657
}));
@@ -114,20 +115,8 @@ class ItcLibraryAdapter implements LibraryAdapter {
114115
start: number,
115116
limit: number,
116117
): Promise<TableData> {
117-
// We only need the columns for the first page of results
118-
const columns =
119-
start === 0
120-
? {
121-
columns: ["INDEX"].concat(
122-
(await this.getColumns(item)).items.map((column) => column.name),
123-
),
124-
}
125-
: {};
126-
127118
const { rows } = await this.getRows(item, start, limit);
128119

129-
rows.unshift(columns);
130-
131120
// Fetching csv doesn't rely on count. Instead, we get the count
132121
// upfront via getTableRowCount
133122
return { rows, count: -1 };
@@ -197,25 +186,54 @@ class ItcLibraryAdapter implements LibraryAdapter {
197186
}
198187

199188
public async getTableInfo(item: LibraryItem): Promise<TableInfo> {
200-
const code = `
201-
$runner.GetTableInfo("${item.library}", "${item.name}")
202-
`;
203-
const output = await executeRawCode(code);
204-
const tableInfo = JSON.parse(output);
189+
try {
190+
// Use the PowerShell GetTableInfo function which queries sashelp.vtable
191+
const code = `
192+
$runner.GetTableInfo("${item.library}", "${item.name}")
193+
`;
194+
const output = await executeRawCode(code);
195+
const tableInfo = JSON.parse(output);
205196

206-
return {
207-
name: tableInfo.name,
208-
type: tableInfo.type,
209-
creationTimeStamp: tableInfo.creationTimeStamp,
210-
modifiedTimeStamp: tableInfo.modifiedTimeStamp,
211-
rowCount: tableInfo.rowCount,
212-
columnCount: tableInfo.columnCount,
213-
compressionRoutine: tableInfo.compressionRoutine,
214-
label: tableInfo.label,
215-
engine: tableInfo.engine,
216-
extendedType: tableInfo.extendedType,
217-
libref: tableInfo.libref,
218-
};
197+
return {
198+
name: tableInfo.name || item.name,
199+
libref: tableInfo.libref || item.library,
200+
type: tableInfo.type || "DATA",
201+
label: tableInfo.label || "",
202+
engine: "", // Not available in sashelp.vtable for SAS 9.4
203+
extendedType: tableInfo.extendedType || "",
204+
rowCount: tableInfo.rowCount || 0,
205+
columnCount: tableInfo.columnCount || 0,
206+
logicalRecordCount: tableInfo.rowCount || 0,
207+
physicalRecordCount: tableInfo.rowCount || 0,
208+
recordLength: 0, // Not available in vtable
209+
bookmarkLength: 0, // Not available in vtable
210+
compressionRoutine: tableInfo.compressionRoutine || "",
211+
encoding: "", // Not available in vtable
212+
creationTimeStamp: tableInfo.creationTimeStamp || "",
213+
modifiedTimeStamp: tableInfo.modifiedTimeStamp || "",
214+
};
215+
} catch (error) {
216+
console.warn("Failed to get table info:", error);
217+
// If anything fails, return basic info
218+
return {
219+
name: item.name,
220+
libref: item.library,
221+
type: "DATA",
222+
label: "",
223+
engine: "",
224+
extendedType: "",
225+
rowCount: 0,
226+
columnCount: 0,
227+
logicalRecordCount: 0,
228+
physicalRecordCount: 0,
229+
recordLength: 0,
230+
bookmarkLength: 0,
231+
compressionRoutine: "",
232+
encoding: "",
233+
creationTimeStamp: "",
234+
modifiedTimeStamp: "",
235+
};
236+
}
219237
}
220238

221239
protected async executionHandler(

client/src/connection/itc/script.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,10 @@ class SASRunner{
295295
$objRecordSet = New-Object -comobject ADODB.Recordset
296296
$objRecordSet.ActiveConnection = $this.dataConnection
297297
$query = @"
298-
select name, type, format
298+
select name, type, format, label, length, varnum
299299
from sashelp.vcolumn
300-
where libname='$libname' and memname='$memname';
300+
where libname='$libname' and memname='$memname'
301+
order by varnum;
301302
"@
302303
$objRecordSet.Open(
303304
$query,
@@ -318,6 +319,9 @@ class SASRunner{
318319
name = $rows[0, $i]
319320
type = $rows[1, $i]
320321
format = $rows[2, $i]
322+
label = $rows[3, $i]
323+
length = $rows[4, $i]
324+
varnum = $rows[5, $i]
321325
}
322326
$parsedRows += $parsedRow
323327
}
@@ -585,7 +589,7 @@ class SASRunner{
585589
$objRecordSet.ActiveConnection = $this.dataConnection
586590
$query = @"
587591
select memname, memtype, crdate, modate, nobs, nvar, compress,
588-
memlabel, engine, typemem, filesize, delobs
592+
memlabel, typemem, filesize, delobs
589593
from sashelp.vtable
590594
where libname='$libname' and memname='$memname';
591595
"@
@@ -607,10 +611,9 @@ class SASRunner{
607611
$result | Add-Member -MemberType NoteProperty -Name "columnCount" -Value $objRecordSet.Fields.Item(5).Value
608612
$result | Add-Member -MemberType NoteProperty -Name "compressionRoutine" -Value $objRecordSet.Fields.Item(6).Value
609613
$result | Add-Member -MemberType NoteProperty -Name "label" -Value $objRecordSet.Fields.Item(7).Value
610-
$result | Add-Member -MemberType NoteProperty -Name "engine" -Value $objRecordSet.Fields.Item(8).Value
611-
$result | Add-Member -MemberType NoteProperty -Name "extendedType" -Value $objRecordSet.Fields.Item(9).Value
612-
$result | Add-Member -MemberType NoteProperty -Name "fileSize" -Value $objRecordSet.Fields.Item(10).Value
613-
$result | Add-Member -MemberType NoteProperty -Name "deletedObs" -Value $objRecordSet.Fields.Item(11).Value
614+
$result | Add-Member -MemberType NoteProperty -Name "extendedType" -Value $objRecordSet.Fields.Item(8).Value
615+
$result | Add-Member -MemberType NoteProperty -Name "fileSize" -Value $objRecordSet.Fields.Item(9).Value
616+
$result | Add-Member -MemberType NoteProperty -Name "deletedObs" -Value $objRecordSet.Fields.Item(10).Value
614617
$result | Add-Member -MemberType NoteProperty -Name "libref" -Value $libname
615618
}
616619
$objRecordSet.Close()

client/src/panels/TablePropertiesViewer.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class TablePropertiesViewer extends WebView {
3333
<head>
3434
<meta charset="UTF-8">
3535
<meta name="viewport" content="width=device-width, initial-scale=1.0">
36-
<title>Table ${this.showColumns ? "Columns" : "Properties"}</title>
36+
<title>Table Properties</title>
3737
<style>
3838
body {
3939
font-family: var(--vscode-font-family);
@@ -50,31 +50,35 @@ class TablePropertiesViewer extends WebView {
5050
margin: 0 auto;
5151
}
5252
53-
.tab-container {
53+
.tabs {
54+
display: flex;
5455
border-bottom: 1px solid var(--vscode-panel-border);
5556
margin-bottom: 16px;
5657
}
5758
5859
.tab {
59-
display: inline-block;
60-
padding: 8px 16px;
61-
margin-right: 4px;
62-
background: var(--vscode-tab-inactiveBackground);
63-
border: 1px solid var(--vscode-panel-border);
64-
border-bottom: none;
60+
padding: 10px 20px;
6561
cursor: pointer;
66-
color: var(--vscode-tab-inactiveForeground);
62+
border: none;
63+
background: none;
64+
color: var(--vscode-foreground);
65+
border-bottom: 2px solid transparent;
66+
font-family: inherit;
67+
font-size: inherit;
68+
}
69+
70+
.tab:hover {
71+
background-color: var(--vscode-list-hoverBackground);
6772
}
6873
6974
.tab.active {
70-
background: var(--vscode-tab-activeBackground);
75+
border-bottom-color: var(--vscode-focusBorder);
7176
color: var(--vscode-tab-activeForeground);
72-
border-bottom: 1px solid var(--vscode-tab-activeBackground);
73-
margin-bottom: -1px;
7477
}
7578
7679
.tab-content {
7780
display: none;
81+
padding: 20px 0;
7882
}
7983
8084
.tab-content.active {
@@ -120,38 +124,34 @@ class TablePropertiesViewer extends WebView {
120124
<div class="container">
121125
<h1>Table: ${this.tableName}</h1>
122126
123-
<div class="tab-container">
124-
<div class="tab ${!this.showColumns ? "active" : ""}" onclick="showTab('properties')">
125-
General
126-
</div>
127-
<div class="tab ${this.showColumns ? "active" : ""}" onclick="showTab('columns')">
128-
Columns
129-
</div>
127+
<div class="tabs">
128+
<button class="tab active" onclick="showTab('properties')">General</button>
129+
<button class="tab" onclick="showTab('columns')">Columns</button>
130130
</div>
131131
132-
<div id="properties" class="tab-content ${!this.showColumns ? "active" : ""}">
132+
<div id="properties" class="tab-content active">
133133
${this.generatePropertiesContent()}
134134
</div>
135135
136-
<div id="columns" class="tab-content ${this.showColumns ? "active" : ""}">
136+
<div id="columns" class="tab-content">
137137
${this.generateColumnsContent()}
138138
</div>
139139
</div>
140140
141141
<script>
142142
function showTab(tabName) {
143143
// Hide all tab contents
144-
const tabContents = document.querySelectorAll('.tab-content');
145-
tabContents.forEach(content => content.classList.remove('active'));
144+
const contents = document.querySelectorAll('.tab-content');
145+
contents.forEach(content => content.classList.remove('active'));
146146
147147
// Remove active class from all tabs
148148
const tabs = document.querySelectorAll('.tab');
149149
tabs.forEach(tab => tab.classList.remove('active'));
150150
151-
// Show the selected tab content
151+
// Show selected tab content
152152
document.getElementById(tabName).classList.add('active');
153153
154-
// Add active class to the clicked tab
154+
// Add active class to clicked tab
155155
event.target.classList.add('active');
156156
}
157157
</script>

package.json

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -819,11 +819,6 @@
819819
"title": "%commands.SAS.showTableProperties%",
820820
"category": "SAS"
821821
},
822-
{
823-
"command": "SAS.showTableColumns",
824-
"title": "%commands.SAS.showTableColumns%",
825-
"category": "SAS"
826-
},
827822
{
828823
"command": "SAS.notebook.new",
829824
"shortTitle": "%commands.SAS.notebook.new.short%",
@@ -947,11 +942,6 @@
947942
"when": "viewItem =~ /table-/ && view == librarydataprovider",
948943
"group": "properties@0"
949944
},
950-
{
951-
"command": "SAS.showTableColumns",
952-
"when": "viewItem =~ /table-/ && view == librarydataprovider",
953-
"group": "properties@1"
954-
},
955945
{
956946
"command": "SAS.content.addFolderResource",
957947
"when": "viewItem =~ /createChild/ && view == contentdataprovider",
@@ -1205,10 +1195,6 @@
12051195
"when": "false",
12061196
"command": "SAS.showTableProperties"
12071197
},
1208-
{
1209-
"when": "false",
1210-
"command": "SAS.showTableColumns"
1211-
},
12121198
{
12131199
"when": "false",
12141200
"command": "SAS.content.downloadResource"

package.nls.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
"commands.SAS.deleteTable": "Delete",
1414
"commands.SAS.download": "Download",
1515
"commands.SAS.showTableProperties": "Properties",
16-
"commands.SAS.showTableColumns": "Columns",
1716
"commands.SAS.emptyRecycleBin": "Empty Recycle Bin",
1817
"commands.SAS.file.new": "New SAS File",
1918
"commands.SAS.file.new.short": "SAS File",

0 commit comments

Comments
 (0)