Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,15 @@
"command": "psl.previewDocumentation",
"title": "Preview Documentation",
"category": "PSL"
},
{
"command": "psl.dbaView",
"title": "DBA View",
"category": "PSL",
"icon": {
"dark": "icons/dark/triangle-right.svg",
"light": "icons/light/triangle-right.svg"
}
}
],
"menus": {
Expand Down Expand Up @@ -603,6 +612,10 @@
}
],
"editor/title": [
{
"command": "psl.dbaView",
"group": "navigation@-207"
},
{
"command": "psl.previewDocumentation",
"group": "navigation@-206",
Expand Down
217 changes: 217 additions & 0 deletions src/dbaView/activate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import * as path from 'path';
import * as vscode from 'vscode';
import { EnvironmentConfig, workspaceQuickPick } from '../common/environment';
import * as utils from '../hostCommands/hostCommandUtils';
import { MtmConnection } from '../mtm/mtm';

let extensionPath: string;

interface WebviewResources {
app: vscode.Uri;
vue: vscode.Uri;
jquery: vscode.Uri;
bootstrap: vscode.Uri;
style: vscode.Uri;
}

export function activate(context: vscode.ExtensionContext) {
extensionPath = context.extensionPath;

context.subscriptions.push(
vscode.commands.registerCommand('psl.dbaView', dbaViewHandler),
)
}

async function dbaViewHandler(context: utils.ExtensionCommandContext) {
const environment = await getEnvironmentFromContext(context);

if (!environment) return;

const panel = vscode.window.createWebviewPanel(
'dbaView', // Identifies the type of the webview. Used internally
'DBA Viewer', // Title of the panel displayed to the user
vscode.ViewColumn.One, // Editor column to show the new webview panel in.
{
enableScripts: true,
localResourceRoots: [vscode.Uri.file(path.join(extensionPath, 'webview_resources'))],
} // Webview options. More on these later.
);

panel.webview.html = getWebviewContent({
app: getResourceUri('app.js'),
vue: getResourceUri('vue.js'),
jquery: getResourceUri('jquery.min.js'),
bootstrap: getResourceUri('bootstrap.min.css'),
style: getResourceUri('style.css'),
});

panel.webview.onDidReceiveMessage(

async message => {
console.log("Receiving a message!",message);
switch (message.what) {
case 'tables':
const tablesConnection = new MtmConnection();
await tablesConnection.open(environment.host, environment.port, environment.user, environment.password);
const tablesResult = await tablesConnection.sqlQuery('SELECT FID,ALIAS,DES from DBTBL1');
panel.webview.postMessage(buildAnswer('TABLES',['name','alias','description'],tablesResult));
break;
case 'columns':
const queryTable = message.table;
const columnsConnection = new MtmConnection();
await columnsConnection.open(environment.host, environment.port, environment.user, environment.password);
const columnsResult = await columnsConnection.sqlQuery('SELECT DI,ALIAS,DES FROM DBTBL1D WHERE FID=\''+queryTable+'\'');
panel.webview.postMessage(buildAnswer('COLUMNS',['name','alias','description'],columnsResult));
break;

}
}
);
}


function buildAnswer(what, fields, value) {
//separate by lines
var dataArray = [];
//TODO: Apply filter to remove literals
var forParsing = value.split('\n');

forParsing.forEach(line => {
var splittedLine = line.split('\t');
let obj: any = {};
var counter = 0;
fields.forEach(field => {
obj[field]=splittedLine[counter];
counter++;
});
dataArray.push(obj);
});



return {
id: what,
data: dataArray
}
}

function getResourceUri(resourceName: string) {
const onDiskPath = vscode.Uri.file(path.join(extensionPath, 'webview_resources', resourceName));
return onDiskPath.with({ scheme: 'vscode-resource' });
}

async function getEnvironmentFromContext(context: utils.ExtensionCommandContext) {
const c = utils.getFullContext(context);
let environments: EnvironmentConfig[];
try {
let fsPath: string;
if (c.mode === utils.ContextMode.EMPTY) {
const quickPick = await workspaceQuickPick();
if (!quickPick) return;
fsPath = quickPick.fsPath;
}
else fsPath = c.fsPath;
environments = await utils.getEnvironment(fsPath);
}
catch (e) {
utils.logger.error(`${utils.icons.ERROR} Invalid environment configuration ${e.message}`);
return;
}
if (environments.length === 0) {
utils.logger.error(`${utils.icons.ERROR} No environments selected.`);
return;
}
return utils.getCommandEnvConfigQuickPick(environments);
}

function getWebviewContent(resources: WebviewResources) {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DBA Viewer</title>
<link rel="stylesheet" href="${ resources.bootstrap.toString() }">
<link rel="stylesheet" href="${ resources.style.toString() }">
</head>
<body>
<div id="app">
<div class="container table-responsive" id="table-list">
<div id="table_group" class="form-group">
<input id="table_query" class="form-control" placeholder="Table" name="query" v-model="searchQuery">
</div>
<tables-grid
:tables="tables"
:columns="gridColumns"
:filter-key="searchQuery">
</tables-grid>
</div>
<div class="container table-responsive" id="column-list">
<div id="column_group" class="form-group">
<input id="column_query" class="form-control" placeholder="Columns" name="query" v-model="searchColQuery">
</div>
<columns-grid
:tables="columns"
:columns="gridColumns"
:filter-key="searchColQuery">
</columns-grid>
</div>
<div class="container" id="table-details">
TABLE DETAILS
</div>
<div class="container" id="column-details">
COLUMN DETAILS
</div>
</div>
</body>
<script src="${ resources.vue.toString() }"></script>
<script type="text/x-template" id="tables-tpl">
<table class="fixed_headers">
<thead class="thead-dark">
<tr>
<th v-for="key in columns"
@click="sortBy(key)"
:class="{ active: sortKey == key }">
{{ key | capitalize }}
<span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="entry in filteredTables" :id=entry.name v-on:click.prevent="selectTable(entry.name)">
<td v-for="key in columns">
{{entry[key]}}
</td>
</tr>
</tbody>
</table>
</script>
<script type="text/x-template" id="columns-tpl">
<table class="fixed_headers">
<thead class="thead-dark">
<tr>
<th v-for="key in columns"
@click="sortBy(key)"
:class="{ active: sortKey == key }">
{{ key | capitalize }}
<span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="entry in filteredColumns" :id=entry.name v-on:click.prevent="selectColumn(entry.name)">
<td v-for="key in columns">
{{entry[key]}}
</td>
</tr>
</tbody>
</table>
</script>
<script src="${resources.jquery.toString()}"></script>
<script src="${resources.app.toString()}"></script>


</html>`;
}
3 changes: 3 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as terminal from './common/terminal';
import * as hostEnvironment from './common/environment';
import * as hostCommands from './hostCommands/activate';
import * as languageFeatures from './language/activate';
import * as dbaView from './dbaView/activate';

export const PSL_MODE: vscode.DocumentFilter = { language: 'psl', scheme: 'file' };
export const BATCH_MODE: vscode.DocumentFilter = { language: 'profileBatch', scheme: 'file' };
Expand All @@ -22,6 +23,8 @@ export function activate(context: vscode.ExtensionContext) {
terminal.activate(context);

languageFeatures.activate(context);

dbaView.activate(context);
}


Expand Down
3 changes: 2 additions & 1 deletion src/hostCommands/activate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { runCoverageHandler, runPSLHandler, runTestHandler, registerCustomRunCon
import { sendElementHandler, sendTableHandler } from './send';
import { testCompileHandler } from './testCompile';


const PROFILE_ELEMENTS = [
'.FKY',
'.G',
Expand Down Expand Up @@ -46,7 +47,7 @@ export function activate(context: vscode.ExtensionContext) {
{ id: 'psl.refreshTable', callback: refreshTableHandler },
// Custom commands
{ id: `psl.${testContext.command}`, callback: runTestHandler },
{ id: `psl.${coverageContext.command}`, callback: runCoverageHandler },
{ id: `psl.${coverageContext.command}`, callback: runCoverageHandler }
];

for (const command of commands) {
Expand Down
4 changes: 2 additions & 2 deletions src/hostCommands/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ async function getElement(fsPath: string) {
utils.logger.error(`${utils.icons.ERROR} ${icon} No environments selected.`);
return;
}
let choice = await utils.getCommandenvConfigQuickPick(envs);
let choice = await utils.getCommandEnvConfigQuickPick(envs);
if (!choice) return;
env = choice;
utils.logger.info(`${utils.icons.WAIT} ${icon} ${path.basename(fsPath)} GET from ${env.name}`);
Expand Down Expand Up @@ -160,7 +160,7 @@ async function getTable(tableName: string, targetDirectory: string, workpacePath
utils.logger.error(`${utils.icons.ERROR} ${icon} No environments selected.`);
return;
}
let choice = await utils.getCommandenvConfigQuickPick(envs);
let choice = await utils.getCommandEnvConfigQuickPick(envs);
if (!choice) return;
env = choice; utils.logger.info(`${utils.icons.WAIT} ${icon} ${tableName} TABLE GET from ${env.name}`);
let connection = await utils.getConnection(env);
Expand Down
4 changes: 2 additions & 2 deletions src/hostCommands/hostCommandUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function getFullContext(context: ExtensionCommandContext | undefined): Ho
mode = ContextMode.EMPTY;
return { fsPath, mode };
}
if ((!context || !context.fsPath) && activeTextEditor) {
if ((!context || !context.fsPath) && activeTextEditor && !activeTextEditor.document.fileName.startsWith('extension-output')) {
fsPath = activeTextEditor.document.fileName;
mode = ContextMode.FILE;
return { fsPath, mode }
Expand Down Expand Up @@ -111,7 +111,7 @@ export async function getEnvironment(fsPath: string): Promise<environment.Enviro
}
}

export async function getCommandenvConfigQuickPick(envs: environment.EnvironmentConfig[]): Promise<environment.EnvironmentConfig | undefined> {
export async function getCommandEnvConfigQuickPick(envs: environment.EnvironmentConfig[]): Promise<environment.EnvironmentConfig | undefined> {
let items: environment.LaunchQuickPick[] = envs.map(env => {
return { label: env.name, description: '', env: env };
})
Expand Down
4 changes: 2 additions & 2 deletions src/hostCommands/refresh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async function refreshElement(fsPath: string) {
utils.logger.error(`${utils.icons.ERROR} ${icon} No environments selected.`);
return;
}
let choice = await utils.getCommandenvConfigQuickPick(envs);
let choice = await utils.getCommandEnvConfigQuickPick(envs);
if (!choice) return;
env = choice;
utils.logger.info(`${utils.icons.WAIT} ${icon} ${path.basename(fsPath)} REFRESH from ${env.name}`);
Expand Down Expand Up @@ -92,7 +92,7 @@ async function refreshTable(tableName: string, targetDirectory: string) {
let env;
await utils.executeWithProgress(`${icon} ${tableName} TABLE REFRESH`, async () => {
let envs = await utils.getEnvironment(targetDirectory);
let choice = await utils.getCommandenvConfigQuickPick(envs);
let choice = await utils.getCommandEnvConfigQuickPick(envs);
if (!choice) return;
env = choice;
utils.logger.info(`${utils.icons.WAIT} ${icon} ${tableName} TABLE REFRESH from ${env.name}`);
Expand Down
2 changes: 2 additions & 0 deletions src/mtm/mtm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ export class MtmConnection {
let fileDetails = utils.getObjectType(fileName);
let tableReturnString = fileDetails.fileBaseName + String.fromCharCode(1) + await this._get(fileName)
let selectStatement = `SELECT COUNT(DI) FROM DBTBL1D WHERE FID='${fileDetails.fileName}' `;
// Setting this.recordCount allows SQL to fetch more than the default number of values
// We need to find a way to generalize the logic here for other queries
this.recordCount = Number(await this._sqlQuery(selectStatement))
selectStatement = `SELECT DI FROM DBTBL1D WHERE FID='${fileDetails.fileName}'`;
returnString = await this._sqlQuery(selectStatement)
Expand Down
Loading