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