Added connection management
This commit is contained in:
BIN
frog-runner.jar
BIN
frog-runner.jar
Binary file not shown.
17
package.json
17
package.json
@@ -21,7 +21,11 @@
|
|||||||
{
|
{
|
||||||
"command": "extension.executeSnippet",
|
"command": "extension.executeSnippet",
|
||||||
"title": "Execute SQL Snippet"
|
"title": "Execute SQL Snippet"
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"command": "selectConnection",
|
||||||
|
"title": "Selects the connection to use"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"keybindings": [{
|
"keybindings": [{
|
||||||
"command": "extension.executeSnippet",
|
"command": "extension.executeSnippet",
|
||||||
@@ -36,6 +40,17 @@
|
|||||||
"name": "Connections"
|
"name": "Connections"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"configuration": {
|
||||||
|
"type": "object",
|
||||||
|
"title": "Frog configuration",
|
||||||
|
"properties": {
|
||||||
|
"frog.connections": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"description": "Set connections to use"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { ExtensionContext, TreeDataProvider, EventEmitter, TreeItem, Event, window, TreeItemCollapsibleState, Uri, commands, workspace, TextDocumentContentProvider, CancellationToken, ProviderResult } from 'vscode';
|
import { ExtensionContext, TreeDataProvider, EventEmitter, TreeItem, Event, window, TreeItemCollapsibleState, Uri, commands, workspace, TextDocumentContentProvider, CancellationToken, ProviderResult } from 'vscode';
|
||||||
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
interface IEntry {
|
interface IEntry {
|
||||||
@@ -6,65 +7,90 @@ interface IEntry {
|
|||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TreeNode = ConnectionNode | FolderNode
|
||||||
|
|
||||||
|
export class FolderNode {
|
||||||
|
constructor(public name:string, public children : TreeNode[]) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class ConnectionNode {
|
export class ConnectionNode {
|
||||||
|
|
||||||
constructor(private _name:string, private _uri:string) {
|
constructor(public name:string, public host:string, public port:Number, public schema:String, public username:String, public password:String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public get name(): string {
|
|
||||||
return this._name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get uri(): string {
|
|
||||||
return this._name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ConnectionModel {
|
export class ConnectionModel {
|
||||||
|
|
||||||
public get roots(): Thenable<ConnectionNode[]> {
|
constructor(public data:any) {
|
||||||
let list : ConnectionNode[] = [
|
}
|
||||||
new ConnectionNode("swdev", "foobar"),
|
|
||||||
new ConnectionNode("swint", "foobar")
|
|
||||||
];
|
|
||||||
|
|
||||||
|
private traverse(data) : TreeNode[] {
|
||||||
|
return data['items'].map( (x) => {
|
||||||
|
if (x['type'] == 'connection') {
|
||||||
|
return new ConnectionNode(x['name'], x['host'], x['port'], x['sid'], x['username'], x['password'])
|
||||||
|
} else {
|
||||||
|
return new FolderNode(x['name'], this.traverse(x))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get roots(): Thenable<TreeNode[]> {
|
||||||
|
let list : TreeNode[] = this.traverse(this.data);
|
||||||
return new Promise((c, e) => c(list));
|
return new Promise((c, e) => c(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChildren(node: ConnectionNode): Thenable<ConnectionNode[]> {
|
public getChildren(node: TreeNode): Thenable<TreeNode[]> {
|
||||||
return new Promise((c, e) => []);
|
if (node instanceof FolderNode) {
|
||||||
|
return new Promise((c, e) => c(node.children));
|
||||||
|
} else {
|
||||||
|
return new Promise((c, e) => c([]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ConnectionProvider implements TreeDataProvider<ConnectionNode>, TextDocumentContentProvider {
|
export class ConnectionProvider implements TreeDataProvider<TreeNode>, TextDocumentContentProvider {
|
||||||
|
|
||||||
private _onDidChangeTreeData: EventEmitter<any> = new EventEmitter<any>();
|
private _onDidChangeTreeData: EventEmitter<any> = new EventEmitter<any>();
|
||||||
readonly onDidChangeTreeData: Event<any> = this._onDidChangeTreeData.event;
|
readonly onDidChangeTreeData: Event<any> = this._onDidChangeTreeData.event;
|
||||||
|
|
||||||
private model: ConnectionModel;
|
private model: ConnectionModel;
|
||||||
|
|
||||||
public getTreeItem(element: ConnectionNode): TreeItem {
|
public getTreeItem(element: TreeNode): TreeItem {
|
||||||
return {
|
if (element instanceof FolderNode) {
|
||||||
label: element.name,
|
return {
|
||||||
collapsibleState: void 0,
|
label: element.name,
|
||||||
command: {
|
collapsibleState: TreeItemCollapsibleState.Collapsed,
|
||||||
command: 'openConnection',
|
command: void 0
|
||||||
arguments: [element.uri],
|
|
||||||
title: 'Open Connection'
|
|
||||||
}
|
}
|
||||||
};
|
} else {
|
||||||
|
return {
|
||||||
|
label: element.name,
|
||||||
|
collapsibleState: void 0,
|
||||||
|
command: {
|
||||||
|
command: 'selectConnection',
|
||||||
|
arguments: [element],
|
||||||
|
title: 'Open Connection'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChildren(element?: ConnectionNode): ConnectionNode[] | Thenable<ConnectionNode[]> {
|
public getChildren(element?: TreeNode): TreeNode[] | Thenable<TreeNode[]> {
|
||||||
if (!element) {
|
if (!element) {
|
||||||
if (!this.model) {
|
if (!this.model) {
|
||||||
this.model = new ConnectionModel();
|
let data = require(os.homedir() + '/.frog.json');
|
||||||
|
this.model = new ConnectionModel(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.model.roots;
|
return this.model.roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
if (element instanceof FolderNode) {
|
||||||
|
return element.children;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public provideTextDocumentContent(uri: Uri, token: CancellationToken): ProviderResult<string> {
|
public provideTextDocumentContent(uri: Uri, token: CancellationToken): ProviderResult<string> {
|
||||||
|
@@ -8,7 +8,8 @@ import { TextDocumentContentProvider } from './resultsetview'
|
|||||||
const { spawn } = require('child_process');
|
const { spawn } = require('child_process');
|
||||||
const extensionName = "frog";
|
const extensionName = "frog";
|
||||||
|
|
||||||
var dbSession = null;
|
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
|
||||||
@@ -16,6 +17,11 @@ var dbSession = null;
|
|||||||
export function activate(context: vscode.ExtensionContext) {
|
export function activate(context: vscode.ExtensionContext) {
|
||||||
let previewUri = vscode.Uri.parse('frog-view://authority/resultset');
|
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);
|
||||||
|
|
||||||
const connectionProvider = new ConnectionProvider();
|
const connectionProvider = new ConnectionProvider();
|
||||||
let myOutputChannel = vscode.window.createOutputChannel('SQL Query Results');
|
let myOutputChannel = vscode.window.createOutputChannel('SQL Query Results');
|
||||||
context.subscriptions.push(myOutputChannel);
|
context.subscriptions.push(myOutputChannel);
|
||||||
@@ -47,8 +53,13 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
let text = editor.document.getText(selection);
|
let text = editor.document.getText(selection);
|
||||||
|
|
||||||
if (!dbSession) {
|
if (!dbSession) {
|
||||||
|
if (!currentConnection) {
|
||||||
|
vscode.window.showWarningMessage('No connection selected');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let extPath = vscode.extensions.getExtension("todie.frog").extensionPath;
|
let extPath = vscode.extensions.getExtension("todie.frog").extensionPath;
|
||||||
dbSession = spawn("java", ['-jar', extPath + '/frog-runner.jar', '172.19.23.18', '1521', 'aax2sm', 'aax2sm', 'aax2sm']);
|
dbSession = spawn("java", ['-jar', extPath + '/frog-runner.jar', currentConnection.host, currentConnection.port, currentConnection.schema, currentConnection.username, currentConnection.password]);
|
||||||
|
|
||||||
let outputBuffer = "";
|
let outputBuffer = "";
|
||||||
|
|
||||||
@@ -81,6 +92,8 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
diagnosticCollection.set(document.uri, diagnostics);
|
diagnosticCollection.set(document.uri, diagnostics);
|
||||||
} else if (json['exception']) {
|
} else if (json['exception']) {
|
||||||
myOutputChannel.append("Exception caught: " + json['exceptionMessage'] + "\n");
|
myOutputChannel.append("Exception caught: " + json['exceptionMessage'] + "\n");
|
||||||
|
} else if ("affectedRows" in json) {
|
||||||
|
myOutputChannel.append(json['affectedRows'] + " rows affected.\n");
|
||||||
} else {
|
} else {
|
||||||
myOutputChannel.append("SQL executed successfully.\n");
|
myOutputChannel.append("SQL executed successfully.\n");
|
||||||
}
|
}
|
||||||
@@ -101,6 +114,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
|
statusBarItem.text = currentConnection.name + " (Connected)";
|
||||||
});
|
});
|
||||||
|
|
||||||
dbSession.stderr.on('data', (data) => {
|
dbSession.stderr.on('data', (data) => {
|
||||||
@@ -125,6 +139,20 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context.subscriptions.push(disposable, registration);
|
context.subscriptions.push(disposable, registration);
|
||||||
|
|
||||||
|
vscode.commands.registerCommand('selectConnection', (node: ConnectionNode) => {
|
||||||
|
vscode.window.showInformationMessage(`You want to change the connection to '${node.name}'. Sure?`, 'Yes')
|
||||||
|
.then( (selection) => {
|
||||||
|
if (selection == 'Yes') {
|
||||||
|
currentConnection = node;
|
||||||
|
statusBarItem.text = node.name;
|
||||||
|
if (dbSession) {
|
||||||
|
dbSession.stdin.end();
|
||||||
|
dbSession = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, (reason) => {})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// this method is called when your extension is deactivated
|
// this method is called when your extension is deactivated
|
||||||
|
Reference in New Issue
Block a user