diff --git a/client/src/connection/itc/ItcLibraryAdapter.ts b/client/src/connection/itc/ItcLibraryAdapter.ts
index f84a5b864..6c3f3171f 100644
--- a/client/src/connection/itc/ItcLibraryAdapter.ts
+++ b/client/src/connection/itc/ItcLibraryAdapter.ts
@@ -59,27 +59,19 @@ class ItcLibraryAdapter implements LibraryAdapter {
count: -1,
};
}
-
public async getLibraries(): Promise<{
items: LibraryItem[];
count: number;
}> {
- const sql = `
- %let OUTPUT;
- proc sql;
- select catx(',', libname, readonly) as libname_target into: OUTPUT separated by '~'
- from sashelp.vlibnam order by libname asc;
- quit;
- %put &OUTPUT; %put ;
+ const code = `
+ $runner.GetLibraries()
`;
- const libNames = processQueryRows(
- await this.runCode(sql, "", ""),
- );
-
- const libraries = libNames.map((lineText): LibraryItem => {
- const [libName, readOnlyValue] = lineText.split(",");
+ const output = await executeRawCode(code);
+ const rawLibraries = JSON.parse(output).libraries;
+ const libraries = rawLibraries.map((row: string[]) => {
+ const [libName, readOnlyValue] = row;
return {
type: "library",
uid: libName,
@@ -161,24 +153,14 @@ class ItcLibraryAdapter implements LibraryAdapter {
items: LibraryItem[];
count: number;
}> {
- const sql = `
- %let OUTPUT;
- proc sql;
- select memname into: OUTPUT separated by '~'
- from sashelp.vtable
- where libname='${item.name!}'
- order by memname asc;
- quit;
- %put &OUTPUT; %put ;
- `;
-
- const tableNames = processQueryRows(
- await this.runCode(sql, "", ""),
- );
- const tables = tableNames.map((lineText): LibraryItem => {
- const [table] = lineText.split(",");
+ const code = `
+ $runner.GetTables("${item.name}")
+ `;
+ const output = await executeRawCode(code);
+ const rawTables = JSON.parse(output).tables;
+ const tables = rawTables.map((table: string): LibraryItem => {
return {
type: "table",
uid: `${item.name!}.${table}`,
diff --git a/client/src/connection/itc/script.ts b/client/src/connection/itc/script.ts
index eca30fff2..103931470 100644
--- a/client/src/connection/itc/script.ts
+++ b/client/src/connection/itc/script.ts
@@ -243,14 +243,14 @@ class SASRunner{
Write-Host "${LineCodes.ResultsFetchedCode}"
}
-
+
[void]GetDatasetRecords([string]$tableName, [int]$start = 0, [int]$limit = 100) {
$objRecordSet = New-Object -comobject ADODB.Recordset
$objRecordSet.ActiveConnection = $this.dataConnection # This is needed to set the properties for sas formats.
$objRecordSet.Properties.Item("SAS Formats").Value = "_ALL_"
$objRecordSet.Open(
- $tableName,
+ $tableName,
[System.Reflection.Missing]::Value, # Use the active connection
2, # adOpenDynamic
1, # adLockReadOnly
@@ -278,7 +278,7 @@ class SASRunner{
$objRecordSet.Close()
$objRecordSet.Open(
- "SELECT COUNT(1) FROM $tableName",
+ "SELECT COUNT(1) FROM $tableName",
$this.dataConnection, 3, 1, 1
) # adOpenStatic, adLockReadOnly, adCmdText
$count = $objRecordSet.Fields.Item(0).Value
@@ -295,8 +295,8 @@ class SASRunner{
$objRecordSet = New-Object -comobject ADODB.Recordset
$objRecordSet.ActiveConnection = $this.dataConnection
$query = @"
- select name, type, format
- from sashelp.vcolumn
+ select name, type, format
+ from sashelp.vcolumn
where libname='$libname' and memname='$memname';
"@
$objRecordSet.Open(
@@ -306,7 +306,7 @@ class SASRunner{
1, # adLockReadOnly
1 # adCmdText
)
-
+
$rows = $objRecordSet.GetRows()
$objRecordSet.Close()
@@ -533,5 +533,70 @@ class SASRunner{
Write-Host (@{success=$false; message=$Error[0].Exception.Message} | ConvertTo-Json)
}
}
+
+ [void]GetLibraries() {
+ $objRecordSet = New-Object -comobject ADODB.Recordset
+ $objRecordSet.ActiveConnection = $this.dataConnection
+ $query = @"
+ select distinct libname, readonly
+ from sashelp.vlibnam
+ order by libname asc
+"@
+ $objRecordSet.Open(
+ $query,
+ [System.Reflection.Missing]::Value, # Use the active connection
+ 2, # adOpenDynamic
+ 1, # adLockReadOnly
+ 1 # adCmdText
+ )
+
+ $records = [System.Collections.Generic.List[object[]]]::new()
+ while (-not $objRecordSet.EOF) {
+ $row = @()
+ for ($i = 0; $i -lt $objRecordSet.Fields.Count; $i++) {
+ $row += $objRecordSet.Fields.Item($i).Value
+ }
+ $records.Add($row)
+ $objRecordSet.MoveNext()
+ }
+ $objRecordSet.Close()
+
+ $result = New-Object psobject
+ $result | Add-Member -MemberType NoteProperty -Name "libraries" -Value $records
+ $result | Add-Member -MemberType NoteProperty -Name "count" -Value $records.Count
+
+ Write-Host $(ConvertTo-Json -Depth 10 -InputObject $result -Compress)
+ }
+
+ [void]GetTables([string]$libname) {
+ $objRecordSet = New-Object -comobject ADODB.Recordset
+ $objRecordSet.ActiveConnection = $this.dataConnection
+ $query = @"
+ select memname
+ from sashelp.vtable
+ where libname='$libname'
+ order by memname asc
+"@
+ $objRecordSet.Open(
+ $query,
+ [System.Reflection.Missing]::Value, # Use the active connection
+ 2, # adOpenDynamic
+ 1, # adLockReadOnly
+ 1 # adCmdText
+ )
+
+ $records = @()
+ while (-not $objRecordSet.EOF) {
+ $records += $objRecordSet.Fields.Item(0).Value
+ $objRecordSet.MoveNext()
+ }
+ $objRecordSet.Close()
+
+ $result = New-Object psobject
+ $result | Add-Member -MemberType NoteProperty -Name "tables" -Value $records
+ $result | Add-Member -MemberType NoteProperty -Name "count" -Value $records.Count
+
+ Write-Host $(ConvertTo-Json -Depth 10 -InputObject $result -Compress)
+ }
}
`;
diff --git a/client/test/connection/itc/ItcLibraryAdapter.test.ts b/client/test/connection/itc/ItcLibraryAdapter.test.ts
index a02ec6ec6..501dc9be3 100644
--- a/client/test/connection/itc/ItcLibraryAdapter.test.ts
+++ b/client/test/connection/itc/ItcLibraryAdapter.test.ts
@@ -11,16 +11,7 @@ import * as connection from "../../../src/connection";
import { MockSession } from "./Coderunner.test";
const mockOutput = () => ({
- LIBOUTPUT: `
-
-test1,yes~test2,no
-
-`,
"SELECT COUNT(1)": `1234`,
- TABLEOUTPUT: `
-
-test1~test2
-`,
});
class DatasetMockSession extends MockSession {
@@ -107,7 +98,6 @@ describe("ItcLibraryAdapter tests", () => {
});
it("loads libraries", async () => {
- const libraryAdapter = new ItcLibraryAdapter();
const expectedLibraries: LibraryItem[] = [
{
uid: "test1",
@@ -125,6 +115,17 @@ describe("ItcLibraryAdapter tests", () => {
},
];
+ const mockOutput = JSON.stringify({
+ libraries: [
+ ["test1", "yes"],
+ ["test2", "no"],
+ ],
+ count: 2,
+ });
+
+ sessionStub.returns(new DatasetMockSession([mockOutput]));
+
+ const libraryAdapter = new ItcLibraryAdapter();
const response = await libraryAdapter.getLibraries();
expect(response.items).to.eql(expectedLibraries);
@@ -227,7 +228,14 @@ describe("ItcLibraryAdapter tests", () => {
type: "library",
readOnly: true,
};
- const libraryAdapter = new ItcLibraryAdapter();
+
+ const mockOutput = JSON.stringify({
+ tables: ["test1", "test2"],
+ count: 2,
+ });
+
+ sessionStub.returns(new DatasetMockSession([mockOutput]));
+
const expectedTables: LibraryItem[] = [
{
library: "lib",
@@ -247,6 +255,7 @@ describe("ItcLibraryAdapter tests", () => {
},
];
+ const libraryAdapter = new ItcLibraryAdapter();
const response = await libraryAdapter.getTables(library);
expect(response.items).to.eql(expectedTables);