Compile the whole buffer
This commit is contained in:
@@ -16,7 +16,7 @@ export class FolderNode {
|
||||
|
||||
export class ConnectionNode {
|
||||
|
||||
constructor(public name:string, public host:string, public port:Number, public schema:String, public username:String, public password:String) {
|
||||
constructor(public name:string, public host:string, public port:number, public schema:string, public username:string, public password:string) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export class ConnectionProvider implements TreeDataProvider<TreeNode>, TextDocum
|
||||
label: element.name,
|
||||
collapsibleState: void 0,
|
||||
command: {
|
||||
command: 'selectConnection',
|
||||
command: 'frog.selectConnection',
|
||||
arguments: [element],
|
||||
title: 'Open Connection'
|
||||
}
|
||||
|
154
src/extension.ts
154
src/extension.ts
@@ -5,43 +5,20 @@ import * as vscode from 'vscode';
|
||||
import { ConnectionProvider, ConnectionNode } from './connections'
|
||||
import { TextDocumentContentProvider } from './resultsetview'
|
||||
import { BlockDetector } from './editorsupport'
|
||||
import { SessionManager } from './sessionmanager'
|
||||
|
||||
const { spawn } = require('child_process');
|
||||
const extensionName = "frog";
|
||||
|
||||
let currentConnection : ConnectionNode = null;
|
||||
let dbSession = null;
|
||||
|
||||
let sessionManager : SessionManager = null;
|
||||
let rowLimit = 50;
|
||||
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
let previewUri = vscode.Uri.parse('frog-view://authority/resultset');
|
||||
|
||||
let statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
statusBarItem.text = 'Frog: No connection'
|
||||
statusBarItem.show()
|
||||
context.subscriptions.push(statusBarItem);
|
||||
|
||||
sessionManager = new SessionManager(context);
|
||||
|
||||
const connectionProvider = new ConnectionProvider();
|
||||
let myOutputChannel = vscode.window.createOutputChannel('SQL Query Results');
|
||||
context.subscriptions.push(myOutputChannel);
|
||||
|
||||
let diagnosticCollection = vscode.languages.createDiagnosticCollection(extensionName);
|
||||
context.subscriptions.push(diagnosticCollection);
|
||||
|
||||
vscode.window.registerTreeDataProvider('connections', connectionProvider);
|
||||
|
||||
let provider = new TextDocumentContentProvider();
|
||||
let registration = vscode.workspace.registerTextDocumentContentProvider('frog-view', provider);
|
||||
|
||||
// Use the console to output diagnostic information (console.log) and errors (console.error)
|
||||
// This line of code will only be executed once when your extension is activated
|
||||
console.log('Congratulations, your extension "frog" is now active!');
|
||||
|
||||
let disposable = vscode.commands.registerCommand('frog.executeSnippet', () => {
|
||||
// The code you place here will be executed every time your command is executed
|
||||
|
||||
let disposable = vscode.commands.registerCommand('frog.executeSnippet', () => {
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
|
||||
if (!editor) return;
|
||||
@@ -54,117 +31,42 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
let text = editor.document.getText(editor.selection);
|
||||
|
||||
if (!dbSession) {
|
||||
if (!currentConnection) {
|
||||
vscode.window.showWarningMessage('No connection selected');
|
||||
return;
|
||||
}
|
||||
|
||||
let extPath = vscode.extensions.getExtension("todie.frog").extensionPath;
|
||||
dbSession = spawn("java", ['-jar', extPath + '/frog-runner.jar', currentConnection.host, currentConnection.port, currentConnection.schema, currentConnection.username, currentConnection.password]);
|
||||
|
||||
let outputBuffer = "";
|
||||
|
||||
dbSession.stdout.on('data', (data) => {
|
||||
outputBuffer += data.toString();
|
||||
|
||||
try {
|
||||
let json = JSON.parse(outputBuffer);
|
||||
|
||||
//console.log(json);
|
||||
|
||||
const diagnostics = [];
|
||||
let cd = json['columnDefinitions']
|
||||
|
||||
if (!json['rows']) {
|
||||
if ('dbOutput' in json) {
|
||||
myOutputChannel.append(json['dbOutput'].map((x) => `DB: ${x}\n`).join(''));
|
||||
}
|
||||
if (json['userErrors']) {
|
||||
myOutputChannel.append("Errors found:\n");
|
||||
|
||||
const document = vscode.window.activeTextEditor.document;
|
||||
|
||||
for (let error of json['userErrors'][0]['lines']) {
|
||||
let range = document.lineAt(selection.start.line + error['line'] - 1).range;
|
||||
let diagnostic = new vscode.Diagnostic(range, error['text'], vscode.DiagnosticSeverity.Error);
|
||||
diagnostic.source = extensionName;
|
||||
diagnostic.code = "code";
|
||||
diagnostics.push(diagnostic);
|
||||
myOutputChannel.append(error['line'] + ": " + error['text'] + "\n");
|
||||
}
|
||||
|
||||
diagnosticCollection.set(document.uri, diagnostics);
|
||||
} else if (json['exception']) {
|
||||
myOutputChannel.append("Exception caught: " + json['exceptionMessage'] + "\n");
|
||||
} else if ("affectedRows" in json) {
|
||||
myOutputChannel.append(json['affectedRows'] + " rows affected.\n");
|
||||
} else {
|
||||
myOutputChannel.append("SQL executed successfully.\n");
|
||||
}
|
||||
} else {
|
||||
provider.setData(json);
|
||||
provider.update(previewUri);
|
||||
|
||||
vscode.commands.executeCommand('vscode.previewHtml', previewUri, vscode.ViewColumn.Two, 'Result Set View').then((success) => {
|
||||
}, (reason) => {
|
||||
vscode.window.showErrorMessage(reason);
|
||||
});
|
||||
|
||||
myOutputChannel.append("Query successful.\n");
|
||||
}
|
||||
|
||||
myOutputChannel.append("-- " + new Date() + " -------------------------------\n");
|
||||
outputBuffer = "";
|
||||
statusBarItem.text = currentConnection.name + " (Connected)";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
statusBarItem.text = currentConnection.name + " (Connected)";
|
||||
});
|
||||
|
||||
dbSession.stderr.on('data', (data) => {
|
||||
myOutputChannel.show(true);
|
||||
myOutputChannel.append(data.toString());
|
||||
});
|
||||
|
||||
dbSession.on('close', (code) => {
|
||||
console.log(`child process exited with code ${code}`);
|
||||
dbSession = null;
|
||||
});
|
||||
}
|
||||
|
||||
if (!text) {
|
||||
vscode.window.showInformationMessage('No text selected');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
myOutputChannel.append("-- " + new Date() + " -------------------------------\n"); //Executing: '" + text + "'\n");
|
||||
let input = { "sql": text, "rowLimit": 30 };
|
||||
dbSession.stdin.write(JSON.stringify(input) + "\n--- END ---\n");
|
||||
statusBarItem.text = currentConnection.name + " (Connected, Query running...)";
|
||||
sessionManager.execute(text, rowLimit);
|
||||
});
|
||||
context.subscriptions.push(disposable);
|
||||
|
||||
context.subscriptions.push(disposable, registration);
|
||||
disposable = vscode.commands.registerCommand('frog.compileFile', () => {
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
|
||||
const text = editor.document.getText();
|
||||
|
||||
sessionManager.execute(text, rowLimit);
|
||||
});
|
||||
context.subscriptions.push(disposable);
|
||||
|
||||
function changeSession(node: ConnectionNode) {
|
||||
currentConnection = node;
|
||||
statusBarItem.text = node.name;
|
||||
if (dbSession) {
|
||||
dbSession.stdin.end();
|
||||
dbSession = null;
|
||||
}
|
||||
sessionManager.currentConnection = node;
|
||||
}
|
||||
|
||||
vscode.commands.registerCommand('selectConnection', (node: ConnectionNode) => {
|
||||
if (!dbSession) {
|
||||
changeSession(node)
|
||||
disposable = vscode.commands.registerCommand('frog.setRowLimit', (args : Object) => {
|
||||
rowLimit = args['rowLimit'];
|
||||
vscode.window.showInformationMessage(`Row limit set to ${args['rowLimit']}`);
|
||||
});
|
||||
context.subscriptions.push(disposable);
|
||||
|
||||
vscode.commands.registerCommand('frog.selectConnection', (node: ConnectionNode) => {
|
||||
if (!sessionManager.isSessionActive()) {
|
||||
sessionManager.currentConnection = node;
|
||||
} else {
|
||||
vscode.window.showInformationMessage(`You want to change the connection to '${node.name}'. Sure?`, 'Yes')
|
||||
.then( (selection) => {
|
||||
if (selection == 'Yes') {
|
||||
changeSession(node);
|
||||
sessionManager.currentConnection = node;
|
||||
}
|
||||
}, (reason) => {})
|
||||
}
|
||||
@@ -173,5 +75,5 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate() {
|
||||
if (dbSession) dbSession.stdin.end();
|
||||
sessionManager.closeSession();
|
||||
}
|
@@ -16,9 +16,18 @@ export class TextDocumentContentProvider implements vscode.TextDocumentContentPr
|
||||
border: solid 1px white;
|
||||
padding: 3px;
|
||||
}
|
||||
#limitBox a {
|
||||
color: white;
|
||||
padding: 3px;
|
||||
}
|
||||
</style>`
|
||||
|
||||
let text = `<body>${styles}<table><tr>`
|
||||
const choosableLimits = [2,10,50]
|
||||
let limitBox = '<div id="limitBox"><p>Limit Results: '
|
||||
+ choosableLimits.map((limit) =>
|
||||
`<a href="${encodeURI('command:frog.setRowLimit?{"rowLimit": ' + limit + '}')}">${limit}</a>`).join('') + '</p></div>'
|
||||
|
||||
let text = `<body>${styles}${limitBox}<table><tr>`
|
||||
text += this._data['columnDefinitions'].map((x) => `<th>${x['name']}</th>`).join('')
|
||||
text += '</tr>'
|
||||
text += this._data['rows'].map((r) =>
|
||||
|
142
src/sessionmanager.ts
Normal file
142
src/sessionmanager.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { ConnectionNode } from './connections'
|
||||
import { spawn } from 'child_process'
|
||||
import { TextDocumentContentProvider } from './resultsetview'
|
||||
|
||||
const extensionName = "frog";
|
||||
const previewUri = vscode.Uri.parse('frog-view://authority/resultset');
|
||||
|
||||
export class SessionManager {
|
||||
private _currentConnection : ConnectionNode
|
||||
private outputChannel
|
||||
private diagnosticCollection;
|
||||
private statusBarItem
|
||||
private dbSession
|
||||
private provider
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
|
||||
this.outputChannel = vscode.window.createOutputChannel('SQL Query Results');
|
||||
context.subscriptions.push(this.outputChannel);
|
||||
|
||||
this.diagnosticCollection = vscode.languages.createDiagnosticCollection(extensionName);
|
||||
context.subscriptions.push(this.diagnosticCollection);
|
||||
|
||||
this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
this.statusBarItem.text = 'Frog: No connection'
|
||||
this.statusBarItem.show()
|
||||
context.subscriptions.push(this.statusBarItem);
|
||||
|
||||
this.provider = new TextDocumentContentProvider();
|
||||
let registration = vscode.workspace.registerTextDocumentContentProvider('frog-view', this.provider);
|
||||
}
|
||||
|
||||
public set currentConnection(c : ConnectionNode) {
|
||||
this.statusBarItem.text = c.name;
|
||||
if (this.dbSession) this.closeSession();
|
||||
}
|
||||
|
||||
public get currentConnection() : ConnectionNode {
|
||||
return this.currentConnection;
|
||||
}
|
||||
|
||||
public isSessionActive() : boolean {
|
||||
return this.dbSession;
|
||||
}
|
||||
|
||||
public closeSession() {
|
||||
if (!this.dbSession) return;
|
||||
|
||||
this.dbSession.stdin.end();
|
||||
this.dbSession = null;
|
||||
}
|
||||
|
||||
public check() {
|
||||
if (!this.currentConnection) {
|
||||
vscode.window.showWarningMessage('No connection selected');
|
||||
return;
|
||||
}
|
||||
|
||||
let extPath = vscode.extensions.getExtension("todie.frog").extensionPath;
|
||||
this.dbSession = spawn("java", ['-jar', extPath + '/frog-runner.jar', this.currentConnection.host, this.currentConnection.port.toString(), this.currentConnection.schema, this.currentConnection.username, this.currentConnection.password]);
|
||||
|
||||
let outputBuffer = "";
|
||||
|
||||
this.dbSession.stdout.on('data', (data) => {
|
||||
outputBuffer += data.toString();
|
||||
|
||||
try {
|
||||
let json = JSON.parse(outputBuffer);
|
||||
|
||||
const diagnostics = [];
|
||||
let cd = json['columnDefinitions']
|
||||
|
||||
if (!json['rows']) {
|
||||
if ('dbOutput' in json) {
|
||||
this.outputChannel.append(json['dbOutput'].map((x) => `DB: ${x}\n`).join(''));
|
||||
}
|
||||
if (json['userErrors']) {
|
||||
this.outputChannel.append("Errors found:\n");
|
||||
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
const document = editor.document;
|
||||
|
||||
for (let error of json['userErrors'][0]['lines']) {
|
||||
let range = document.lineAt(editor.selection.start.line + error['line'] - 1).range;
|
||||
let diagnostic = new vscode.Diagnostic(range, error['text'], vscode.DiagnosticSeverity.Error);
|
||||
diagnostic.source = extensionName;
|
||||
diagnostic.code = "code";
|
||||
diagnostics.push(diagnostic);
|
||||
this.outputChannel.append(error['line'] + ": " + error['text'] + "\n");
|
||||
}
|
||||
|
||||
this.diagnosticCollection.set(document.uri, diagnostics);
|
||||
} else if (json['exception']) {
|
||||
this.outputChannel.append("Exception caught: " + json['exceptionMessage'] + "\n");
|
||||
} else if ("affectedRows" in json) {
|
||||
this.outputChannel.append(json['affectedRows'] + " rows affected.\n");
|
||||
} else {
|
||||
this.outputChannel.append("SQL executed successfully.\n");
|
||||
}
|
||||
} else {
|
||||
this.provider.setData(json);
|
||||
this.provider.update(previewUri);
|
||||
|
||||
vscode.commands.executeCommand('vscode.previewHtml', previewUri, vscode.ViewColumn.Two, 'Result Set View').then((success) => {
|
||||
}, (reason) => {
|
||||
vscode.window.showErrorMessage(reason);
|
||||
});
|
||||
|
||||
this.outputChannel.append("Query successful.\n");
|
||||
}
|
||||
|
||||
this.outputChannel.append("-- " + new Date() + " -------------------------------\n");
|
||||
outputBuffer = "";
|
||||
this.statusBarItem.text = this.currentConnection.name + " (Connected)";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
this.statusBarItem.text = this.currentConnection.name + " (Connected)";
|
||||
});
|
||||
|
||||
this.dbSession.stderr.on('data', (data) => {
|
||||
this.outputChannel.show(true);
|
||||
this.outputChannel.append(data.toString());
|
||||
});
|
||||
|
||||
this.dbSession.on('close', (code) => {
|
||||
console.log(`child process exited with code ${code}`);
|
||||
this.dbSession = null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public execute(text : string, rowLimit : number) {
|
||||
this.check();
|
||||
|
||||
this.outputChannel.append("-- " + new Date() + " -------------------------------\n"); //Executing: '" + text + "'\n");
|
||||
let input = { "sql": text, "rowLimit": rowLimit };
|
||||
this.dbSession.stdin.write(JSON.stringify(input) + "\n--- END ---\n");
|
||||
this.statusBarItem.text = this.currentConnection.name + " (Connected, Query running...)";
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user