Compile the whole buffer

sql-parser
Thorsten Muerell 7 years ago
parent 26c0df18cb
commit 14db6108f2

@ -23,15 +23,31 @@
"title": "Execute SQL Snippet" "title": "Execute SQL Snippet"
}, },
{ {
"command": "selectConnection", "command": "frog.compileFile",
"title": "Compiles the current file"
},
{
"command": "frog.selectConnection",
"title": "Selects the connection to use" "title": "Selects the connection to use"
},
{
"command": "frog.setRowLimit",
"title": "Sets the row limit"
} }
], ],
"keybindings": [{ "keybindings": [
{
"command": "frog.executeSnippet", "command": "frog.executeSnippet",
"key": "ctrl+enter", "key": "ctrl+enter",
"mac": "ctrl+enter" "mac": "ctrl+enter"
}], },
{
"command": "frog.compileFile",
"key": "ctrl+alt+c",
"mac": "ctrl+alt+c"
}
],
"views": { "views": {
"explorer": [ "explorer": [
{ {

@ -16,7 +16,7 @@ export class FolderNode {
export class ConnectionNode { 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, label: element.name,
collapsibleState: void 0, collapsibleState: void 0,
command: { command: {
command: 'selectConnection', command: 'frog.selectConnection',
arguments: [element], arguments: [element],
title: 'Open Connection' title: 'Open Connection'
} }

@ -5,43 +5,20 @@ import * as vscode from 'vscode';
import { ConnectionProvider, ConnectionNode } from './connections' import { ConnectionProvider, ConnectionNode } from './connections'
import { TextDocumentContentProvider } from './resultsetview' import { TextDocumentContentProvider } from './resultsetview'
import { BlockDetector } from './editorsupport' import { BlockDetector } from './editorsupport'
import { SessionManager } from './sessionmanager'
const { spawn } = require('child_process'); let sessionManager : SessionManager = null;
const extensionName = "frog"; let rowLimit = 50;
let currentConnection : ConnectionNode = null;
let dbSession = null;
// this method is called when your extension is activated // this method is called when your extension is activated
// your extension is activated the very first time the command is executed // your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) { export function activate(context: vscode.ExtensionContext) {
let previewUri = vscode.Uri.parse('frog-view://authority/resultset'); sessionManager = new SessionManager(context);
let statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
statusBarItem.text = 'Frog: No connection'
statusBarItem.show()
context.subscriptions.push(statusBarItem);
const connectionProvider = new ConnectionProvider(); 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); 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', () => { let disposable = vscode.commands.registerCommand('frog.executeSnippet', () => {
// The code you place here will be executed every time your command is executed
let editor = vscode.window.activeTextEditor; let editor = vscode.window.activeTextEditor;
if (!editor) return; if (!editor) return;
@ -54,117 +31,42 @@ export function activate(context: vscode.ExtensionContext) {
let text = editor.document.getText(editor.selection); let text = editor.document.getText(editor.selection);
if (!dbSession) { if (!text) {
if (!currentConnection) { vscode.window.showInformationMessage('No text selected');
vscode.window.showWarningMessage('No connection selected');
return; return;
} }
let extPath = vscode.extensions.getExtension("todie.frog").extensionPath; sessionManager.execute(text, rowLimit);
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);
}); });
context.subscriptions.push(disposable);
myOutputChannel.append("Query successful.\n"); disposable = vscode.commands.registerCommand('frog.compileFile', () => {
} let editor = vscode.window.activeTextEditor;
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) => { const text = editor.document.getText();
myOutputChannel.show(true);
myOutputChannel.append(data.toString());
});
dbSession.on('close', (code) => { sessionManager.execute(text, rowLimit);
console.log(`child process exited with code ${code}`);
dbSession = null;
}); });
} context.subscriptions.push(disposable);
if (!text) { function changeSession(node: ConnectionNode) {
vscode.window.showInformationMessage('No text selected'); sessionManager.currentConnection = node;
return;
} }
disposable = vscode.commands.registerCommand('frog.setRowLimit', (args : Object) => {
myOutputChannel.append("-- " + new Date() + " -------------------------------\n"); //Executing: '" + text + "'\n"); rowLimit = args['rowLimit'];
let input = { "sql": text, "rowLimit": 30 }; vscode.window.showInformationMessage(`Row limit set to ${args['rowLimit']}`);
dbSession.stdin.write(JSON.stringify(input) + "\n--- END ---\n");
statusBarItem.text = currentConnection.name + " (Connected, Query running...)";
}); });
context.subscriptions.push(disposable);
context.subscriptions.push(disposable, registration); vscode.commands.registerCommand('frog.selectConnection', (node: ConnectionNode) => {
if (!sessionManager.isSessionActive()) {
function changeSession(node: ConnectionNode) { sessionManager.currentConnection = node;
currentConnection = node;
statusBarItem.text = node.name;
if (dbSession) {
dbSession.stdin.end();
dbSession = null;
}
}
vscode.commands.registerCommand('selectConnection', (node: ConnectionNode) => {
if (!dbSession) {
changeSession(node)
} else { } else {
vscode.window.showInformationMessage(`You want to change the connection to '${node.name}'. Sure?`, 'Yes') vscode.window.showInformationMessage(`You want to change the connection to '${node.name}'. Sure?`, 'Yes')
.then( (selection) => { .then( (selection) => {
if (selection == 'Yes') { if (selection == 'Yes') {
changeSession(node); sessionManager.currentConnection = node;
} }
}, (reason) => {}) }, (reason) => {})
} }
@ -173,5 +75,5 @@ export function activate(context: vscode.ExtensionContext) {
// this method is called when your extension is deactivated // this method is called when your extension is deactivated
export function deactivate() { export function deactivate() {
if (dbSession) dbSession.stdin.end(); sessionManager.closeSession();
} }

@ -16,9 +16,18 @@ export class TextDocumentContentProvider implements vscode.TextDocumentContentPr
border: solid 1px white; border: solid 1px white;
padding: 3px; padding: 3px;
} }
#limitBox a {
color: white;
padding: 3px;
}
</style>` </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 += this._data['columnDefinitions'].map((x) => `<th>${x['name']}</th>`).join('')
text += '</tr>' text += '</tr>'
text += this._data['rows'].map((r) => text += this._data['rows'].map((r) =>

@ -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...)";
}
}
Loading…
Cancel
Save