fix jslint problems and added config
This commit is contained in:
Родитель
23c4f7647a
Коммит
bd509ff7a7
|
@ -191,8 +191,9 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "node ./node_modules/vscode/bin/compile -p ./",
|
||||
"compile": "npm run lint && node ./node_modules/vscode/bin/compile -p ./",
|
||||
"compile_watch": "node ./node_modules/vscode/bin/compile -watch -p ./",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
||||
"postinstall": "node ./node_modules/vscode/bin/install",
|
||||
"lint": "tslint src/**/*.ts"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,23 +2,20 @@
|
|||
import vscode = require('vscode');
|
||||
import Constants = require('../models/constants');
|
||||
import Utils = require('../models/utils');
|
||||
import { RecentConnections } from '../models/recentConnections';
|
||||
import Interfaces = require('../models/interfaces');
|
||||
import { ConnectionUI } from '../views/connectionUI'
|
||||
import { ConnectionUI } from '../views/connectionUI';
|
||||
import StatusView from '../views/statusView';
|
||||
|
||||
var mssql = require('mssql');
|
||||
const mssql = require('mssql');
|
||||
|
||||
export default class ConnectionManager
|
||||
{
|
||||
export default class ConnectionManager {
|
||||
private _context: vscode.ExtensionContext;
|
||||
private _statusView: StatusView;
|
||||
private _connection;
|
||||
private _connectionCreds: Interfaces.IConnectionCredentials;
|
||||
private _connectionUI: ConnectionUI;
|
||||
|
||||
constructor(context: vscode.ExtensionContext, statusView: StatusView)
|
||||
{
|
||||
constructor(context: vscode.ExtensionContext, statusView: StatusView) {
|
||||
this._context = context;
|
||||
this._statusView = statusView;
|
||||
this._connectionUI = new ConnectionUI();
|
||||
|
@ -32,51 +29,44 @@ export default class ConnectionManager
|
|||
return this._connection;
|
||||
}
|
||||
|
||||
private get connectionUI() {
|
||||
private get connectionUI(): ConnectionUI {
|
||||
return this._connectionUI;
|
||||
}
|
||||
|
||||
private get statusView() {
|
||||
private get statusView(): StatusView {
|
||||
return this._statusView;
|
||||
}
|
||||
|
||||
get isConnected() {
|
||||
get isConnected(): boolean {
|
||||
return this._connection && this._connection.connected;
|
||||
}
|
||||
|
||||
// close active connection, if any
|
||||
public onDisconnect()
|
||||
{
|
||||
return new Promise<any>((resolve, reject) =>
|
||||
{
|
||||
if(this.isConnected) {
|
||||
public onDisconnect(): Promise<any> {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
if (this.isConnected) {
|
||||
this._connection.close();
|
||||
}
|
||||
|
||||
this._connection = null;
|
||||
this._connectionCreds = null;
|
||||
this._connection = undefined;
|
||||
this._connectionCreds = undefined;
|
||||
this.statusView.notConnected();
|
||||
resolve(true);
|
||||
});
|
||||
}
|
||||
|
||||
// let users pick from a picklist of connections
|
||||
public onNewConnection()
|
||||
{
|
||||
public onNewConnection(): Promise<boolean> {
|
||||
const self = this;
|
||||
return new Promise<boolean>((resolve, reject) =>
|
||||
{
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
// show connection picklist
|
||||
self.connectionUI.showConnections()
|
||||
.then(function(connectionCreds)
|
||||
{
|
||||
.then(function(connectionCreds): void {
|
||||
// close active connection
|
||||
self.onDisconnect().then(function()
|
||||
{
|
||||
self.onDisconnect().then(function(): void {
|
||||
// connect to the server/database
|
||||
self.connect(connectionCreds)
|
||||
.then(function()
|
||||
{
|
||||
.then(function(): void {
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
|
@ -85,25 +75,23 @@ export default class ConnectionManager
|
|||
}
|
||||
|
||||
// create a new connection with the connectionCreds provided
|
||||
public connect(connectionCreds: Interfaces.IConnectionCredentials)
|
||||
{
|
||||
public connect(connectionCreds: Interfaces.IConnectionCredentials): Promise<any> {
|
||||
const self = this;
|
||||
return new Promise<any>((resolve, reject) =>
|
||||
{
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
const connection = new mssql.Connection(connectionCreds);
|
||||
self.statusView.connecting(connectionCreds);
|
||||
connection.connect()
|
||||
.then(function() {
|
||||
.then(function(): void {
|
||||
self._connectionCreds = connectionCreds;
|
||||
self._connection = connection;
|
||||
self.statusView.connectSuccess(connectionCreds);
|
||||
resolve();
|
||||
})
|
||||
.catch(function(err) {
|
||||
.catch(function(err): void {
|
||||
self.statusView.connectError(connectionCreds, err);
|
||||
Utils.showErrorMsg(Constants.gMsgError + err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,33 +16,28 @@ export default class MainController implements vscode.Disposable {
|
|||
private _statusview: StatusView;
|
||||
private _connectionMgr: ConnectionManager;
|
||||
|
||||
constructor(context: vscode.ExtensionContext)
|
||||
{
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
this._context = context;
|
||||
}
|
||||
|
||||
private registerCommand(command: string)
|
||||
{
|
||||
private registerCommand(command: string): void {
|
||||
const self = this;
|
||||
this._context.subscriptions.push(vscode.commands.registerCommand(command, () => {
|
||||
self._event.emit(command);
|
||||
}));
|
||||
}
|
||||
|
||||
dispose()
|
||||
{
|
||||
dispose(): void {
|
||||
this.deactivate();
|
||||
}
|
||||
|
||||
public deactivate()
|
||||
{
|
||||
public deactivate(): void {
|
||||
Utils.logDebug(Constants.gExtensionDeactivated);
|
||||
this.onDisconnect();
|
||||
this._statusview.dispose();
|
||||
}
|
||||
|
||||
public activate()
|
||||
{
|
||||
public activate(): void {
|
||||
const self = this;
|
||||
|
||||
// register VS Code commands
|
||||
|
@ -68,29 +63,23 @@ export default class MainController implements vscode.Disposable {
|
|||
}
|
||||
|
||||
// Close active connection, if any
|
||||
private onDisconnect()
|
||||
{
|
||||
private onDisconnect(): Promise<any> {
|
||||
return this._connectionMgr.onDisconnect();
|
||||
}
|
||||
|
||||
// Let users pick from a list of connections
|
||||
public onNewConnection()
|
||||
{
|
||||
public onNewConnection(): Promise<boolean> {
|
||||
return this._connectionMgr.onNewConnection();
|
||||
}
|
||||
|
||||
// get the T-SQL query from the editor, run it and show output
|
||||
public onRunQuery()
|
||||
{
|
||||
if(!Utils.isEditingSqlFile())
|
||||
{
|
||||
public onRunQuery(): void {
|
||||
if (!Utils.isEditingSqlFile()) {
|
||||
Utils.showWarnMsg(Constants.gMsgOpenSqlFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
const self = this;
|
||||
let qr = new QueryRunner(self._connectionMgr, self._statusview, self._outputContentProvider);
|
||||
qr.onRunQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
'use strict';
|
||||
import vscode = require('vscode');
|
||||
import path = require('path');
|
||||
import fs = require('fs');
|
||||
import Utils = require('../models/utils');
|
||||
import Constants = require('../models/constants');
|
||||
import Interfaces = require('../models/interfaces');
|
||||
var express = require('express');
|
||||
const express = require('express');
|
||||
|
||||
export default class LocalWebService
|
||||
{
|
||||
export default class LocalWebService {
|
||||
private app = express();
|
||||
static _servicePort: string;
|
||||
static _vscodeExtensionPath: string;
|
||||
static _htmlContentLocation = "src/views/htmlcontent";
|
||||
static _htmlContentLocation = 'src/views/htmlcontent';
|
||||
static _staticContentPath: string;
|
||||
|
||||
constructor(extensionPath: string)
|
||||
{
|
||||
constructor(extensionPath: string) {
|
||||
// add static content for express web server to serve
|
||||
LocalWebService._vscodeExtensionPath = extensionPath;
|
||||
LocalWebService._staticContentPath = path.join(extensionPath, LocalWebService._htmlContentLocation);
|
||||
|
@ -37,20 +33,18 @@ export default class LocalWebService
|
|||
return LocalWebService._vscodeExtensionPath;
|
||||
}
|
||||
|
||||
static getEndpointUri(type: Interfaces.ContentType): string
|
||||
{
|
||||
return this.serviceUrl + "/" + Interfaces.ContentTypes[type];
|
||||
static getEndpointUri(type: Interfaces.ContentType): string {
|
||||
return this.serviceUrl + '/' + Interfaces.ContentTypes[type];
|
||||
}
|
||||
|
||||
addHandler(type: Interfaces.ContentType, handler: (req, res) => void) {
|
||||
let segment = "/" + Interfaces.ContentTypes[type];
|
||||
addHandler(type: Interfaces.ContentType, handler: (req, res) => void): void {
|
||||
let segment = '/' + Interfaces.ContentTypes[type];
|
||||
this.app.get(segment, handler);
|
||||
}
|
||||
|
||||
start()
|
||||
{
|
||||
start(): void {
|
||||
const port = this.app.listen(0).address().port; // 0 = listen on a random port
|
||||
Utils.logDebug(Constants.gMsgLocalWebserviceStarted + port);
|
||||
LocalWebService._servicePort = port.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
'use strict';
|
||||
import * as events from 'events';
|
||||
import vscode = require('vscode');
|
||||
|
||||
import Constants = require('../models/constants');
|
||||
|
@ -9,11 +8,10 @@ import Interfaces = require('../models/interfaces');
|
|||
import ConnectionManager from './connectionManager';
|
||||
import StatusView from '../views/statusView';
|
||||
|
||||
var async = require("async");
|
||||
var mssql = require('mssql');
|
||||
const async = require('async');
|
||||
const mssql = require('mssql');
|
||||
|
||||
export default class QueryRunner
|
||||
{
|
||||
export default class QueryRunner {
|
||||
private _connectionMgr: ConnectionManager;
|
||||
private _outputProvider: SqlOutputContentProvider;
|
||||
private _errorEncountered = false;
|
||||
|
@ -21,8 +19,7 @@ export default class QueryRunner
|
|||
private _resultsets: Interfaces.ISqlResultset[] = [];
|
||||
private _statusView: StatusView;
|
||||
|
||||
constructor(connectionMgr: ConnectionManager, statusView: StatusView, outputProvider: SqlOutputContentProvider)
|
||||
{
|
||||
constructor(connectionMgr: ConnectionManager, statusView: StatusView, outputProvider: SqlOutputContentProvider) {
|
||||
this._connectionMgr = connectionMgr;
|
||||
this._statusView = statusView;
|
||||
this._outputProvider = outputProvider;
|
||||
|
@ -40,39 +37,33 @@ export default class QueryRunner
|
|||
return this._connectionMgr;
|
||||
}
|
||||
|
||||
private get statusView() {
|
||||
private get statusView(): any {
|
||||
return this._statusView;
|
||||
}
|
||||
|
||||
private get outputProvider() {
|
||||
private get outputProvider(): any {
|
||||
return this._outputProvider;
|
||||
}
|
||||
|
||||
// get T-SQL text from the editor window, run it and show output
|
||||
public onRunQuery()
|
||||
{
|
||||
public onRunQuery(): void {
|
||||
const self = this;
|
||||
if(self.connectionManager.isConnected)
|
||||
{
|
||||
if (self.connectionManager.isConnected) {
|
||||
// already connected - run query
|
||||
Utils.logDebug(Constants.gMsgRunQueryConnectionActive)
|
||||
Utils.logDebug(Constants.gMsgRunQueryConnectionActive);
|
||||
self.runQuery();
|
||||
}
|
||||
else if(self.connectionManager.connectionCredentials)
|
||||
{
|
||||
} else if (self.connectionManager.connectionCredentials) {
|
||||
// connected previously but not connected now - reconnect with saved connection info
|
||||
Utils.logDebug(Constants.gMsgRunQueryConnectionDisconnected)
|
||||
Utils.logDebug(Constants.gMsgRunQueryConnectionDisconnected);
|
||||
self.connectionManager.connect(self.connectionManager.connectionCredentials)
|
||||
.then(function() {
|
||||
.then(function(): void {
|
||||
self.runQuery();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// not connected - prompt for a new connection
|
||||
Utils.logDebug(Constants.gMsgRunQueryNoConnection)
|
||||
Utils.logDebug(Constants.gMsgRunQueryNoConnection);
|
||||
self.connectionManager.onNewConnection()
|
||||
.then(function() {
|
||||
.then(function(): void {
|
||||
self.runQuery();
|
||||
});
|
||||
}
|
||||
|
@ -80,37 +71,31 @@ export default class QueryRunner
|
|||
|
||||
// Helper to execute selected T-SQL text in the editor or the entire contents if no selection
|
||||
// Executes queries in batches separated by "GO;"
|
||||
private runQuery()
|
||||
{
|
||||
private runQuery(): void {
|
||||
const self = this;
|
||||
|
||||
// Good info on sync vs. async in node: http://book.mixu.net/node/ch7.html
|
||||
// http://www.sebastianseilund.com/nodejs-async-in-practice
|
||||
let sqlBatches = self.getSqlBatches();
|
||||
if(sqlBatches && sqlBatches.length > 0)
|
||||
{
|
||||
if (sqlBatches && sqlBatches.length > 0) {
|
||||
// called by async.js when all batches have finished executing
|
||||
var done = function(err)
|
||||
{
|
||||
let done = function(err): void {
|
||||
// all batches executed
|
||||
Utils.logDebug(Constants.gMsgRunQueryAllBatchesExecuted);
|
||||
self.statusView.executedQuery();
|
||||
|
||||
if(err)
|
||||
{
|
||||
if (err) {
|
||||
Utils.logDebug(Constants.gMsgRunQueryError + err.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
self.outputProvider.updateContent(self.messages, self.resultSets);
|
||||
}
|
||||
};
|
||||
|
||||
// called by async.js for each sqlBatch
|
||||
var iterator = function(sqlBatch, callback)
|
||||
{
|
||||
let iterator = function(sqlBatch, callback): void {
|
||||
self.executeBatch(sqlBatch, self.connectionManager.connection)
|
||||
.then(function(resolution)
|
||||
{
|
||||
.then(function(resolution): void {
|
||||
Utils.logDebug(Constants.gMsgRunQueryAddBatchResultsets + sqlBatch);
|
||||
let recordsets = resolution.recordsets;
|
||||
let requestRowsAffected = resolution.requestRowsAffected;
|
||||
|
@ -118,15 +103,14 @@ export default class QueryRunner
|
|||
|
||||
callback(); // call 'callback' to indicate this iteration is done and to proceed to the next one
|
||||
})
|
||||
.catch(function(err)
|
||||
{
|
||||
.catch(function(err): void {
|
||||
self._errorEncountered = true;
|
||||
Utils.logDebug(Constants.gMsgRunQueryAddBatchError + sqlBatch);
|
||||
self.addError(err);
|
||||
|
||||
callback(); // call 'callback' to indicate this iteration is done and to proceed to the next one
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
self._errorEncountered = false;
|
||||
self._messages = [];
|
||||
|
@ -139,15 +123,13 @@ export default class QueryRunner
|
|||
}
|
||||
|
||||
// Helper to execute T-SQL (selected text or the entire contents of the editor)
|
||||
private executeBatch(sqlText, connection)
|
||||
{
|
||||
return new Promise<any>((resolve, reject) =>
|
||||
{
|
||||
private executeBatch(sqlText, connection): Promise<any> {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
Utils.logDebug(Constants.gMsgRunQueryExecutingBatch + sqlText);
|
||||
const request = new mssql.Request(connection);
|
||||
request.multiple = true; // enable multiple recordsets
|
||||
request.batch(sqlText, function(err, recordsets, rowsAffected) {
|
||||
if(err) {
|
||||
request.batch(sqlText, function(err, recordsets, rowsAffected): void {
|
||||
if (err) {
|
||||
reject (err);
|
||||
}
|
||||
|
||||
|
@ -160,16 +142,12 @@ export default class QueryRunner
|
|||
// Simple "GO" parser
|
||||
// Looks at text in the active document and produces batches of T-SQL statements delimited by 'GO'
|
||||
// GO needs to be on a separate line by itself and may have an optional ';' after it
|
||||
private getSqlBatches()
|
||||
{
|
||||
private getSqlBatches(): string[] {
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
let textInEditor = "";
|
||||
if(editor.selection.isEmpty)
|
||||
{
|
||||
let textInEditor = '';
|
||||
if (editor.selection.isEmpty) {
|
||||
textInEditor = editor.document.getText();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
textInEditor = editor.document.getText(editor.selection);
|
||||
}
|
||||
|
||||
|
@ -184,20 +162,19 @@ export default class QueryRunner
|
|||
// /igm = ignore case, global, multi0line
|
||||
|
||||
// start by assuming no "GO"s exist
|
||||
let sqlBatches = [];
|
||||
let sqlBatches: string[] = [];
|
||||
textInEditor = textInEditor.trim();
|
||||
if(textInEditor) {
|
||||
if (textInEditor) {
|
||||
sqlBatches.push(textInEditor);
|
||||
}
|
||||
|
||||
// Select all lines not containing "GO" on a line by itself
|
||||
let matches = textInEditor.split(/^\s*GO;*\s*$/igm);
|
||||
if(matches && matches.length > 0)
|
||||
{
|
||||
if (matches && matches.length > 0) {
|
||||
// Found some "GO"s
|
||||
sqlBatches = matches.filter( (element) => {
|
||||
element.trim;
|
||||
return element != "";
|
||||
return element !== '';
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -205,100 +182,87 @@ export default class QueryRunner
|
|||
return sqlBatches;
|
||||
}
|
||||
|
||||
private addError(error: any)
|
||||
{
|
||||
private addError(error: any): void {
|
||||
const self = this;
|
||||
if(!error) {
|
||||
if (!error) {
|
||||
return;
|
||||
}
|
||||
|
||||
let errMsg = "";
|
||||
errMsg += error.number ? "Msg " + error.number + ", " : "";
|
||||
errMsg += error.class ? "Level " + error.class + ", " : "";
|
||||
errMsg += error.state ? "State " + error.state + ", " : "";
|
||||
errMsg += error.lineNumber ? "Line " + error.lineNumber : "";
|
||||
errMsg += " : " + error.message;
|
||||
let errMsg = '';
|
||||
errMsg += error.number ? 'Msg ' + error.number + ', ' : '';
|
||||
errMsg += error.class ? 'Level ' + error.class + ', ' : '';
|
||||
errMsg += error.state ? 'State ' + error.state + ', ' : '';
|
||||
errMsg += error.lineNumber ? 'Line ' + error.lineNumber : '';
|
||||
errMsg += ' : ' + error.message;
|
||||
self.addMessage(errMsg);
|
||||
}
|
||||
|
||||
public addMessage(message: string)
|
||||
{
|
||||
public addMessage(message: string): void {
|
||||
const self = this;
|
||||
self._messages.push( { messageText: message.toString() });
|
||||
}
|
||||
|
||||
private addResultsets(recordsets, requestRowsAffected)
|
||||
{
|
||||
private addResultsets(recordsets, requestRowsAffected): void {
|
||||
const self = this;
|
||||
if(!recordsets || recordsets.length === 0)
|
||||
{
|
||||
if(requestRowsAffected)
|
||||
{
|
||||
self.addMessage( "(" + requestRowsAffected + Constants.gExecuteQueryRowsAffected + ")" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!recordsets || recordsets.length === 0) {
|
||||
if (requestRowsAffected) {
|
||||
self.addMessage( '(' + requestRowsAffected + Constants.gExecuteQueryRowsAffected + ')' );
|
||||
} else {
|
||||
self.addMessage(Constants.gExecuteQueryCommandCompleted);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// process recordsets
|
||||
for(let recordsetIndex in recordsets)
|
||||
{
|
||||
let currentRecordset = recordsets[recordsetIndex];
|
||||
for (let i = 0; i < recordsets.length; i++) {
|
||||
let currentRecordset = recordsets[i];
|
||||
|
||||
let rowsAffected = self.getRowsAffected(currentRecordset);
|
||||
self.addMessage( "(" + rowsAffected + Constants.gExecuteQueryRowsAffected + ")" );
|
||||
self.addMessage( '(' + rowsAffected + Constants.gExecuteQueryRowsAffected + ')' );
|
||||
|
||||
let columnMetadata = self.getColumnMetadata(currentRecordset);
|
||||
let rowsInResultset = self.getRowsInResultset(currentRecordset);
|
||||
self._resultsets.push( { columns: columnMetadata, rows: rowsInResultset, executionPlanXml: "" } );
|
||||
self._resultsets.push( { columns: columnMetadata, rows: rowsInResultset, executionPlanXml: '' } );
|
||||
}
|
||||
}
|
||||
|
||||
// return rowsAffected for recordset
|
||||
private getRowsAffected(recordset: any)
|
||||
{
|
||||
private getRowsAffected(recordset: any): any {
|
||||
let rowsAffected = 0;
|
||||
if(recordset.rowsAffected) {
|
||||
if (recordset.rowsAffected) {
|
||||
rowsAffected = recordset.rowsAffected;
|
||||
}
|
||||
|
||||
if(!rowsAffected) {
|
||||
if (!rowsAffected) {
|
||||
rowsAffected = recordset.length;
|
||||
}
|
||||
return rowsAffected;
|
||||
}
|
||||
|
||||
// return column metadata for recordset
|
||||
private getColumnMetadata(recordset: any)
|
||||
{
|
||||
private getColumnMetadata(recordset: any): any[] {
|
||||
let columnMetadata = [];
|
||||
for(let columnIndex in recordset.columns)
|
||||
{
|
||||
let columnName = recordset.columns[columnIndex].name;
|
||||
if(!columnName) {
|
||||
columnName = "";
|
||||
for (let i = 0; i < recordset.columns.length; i++) {
|
||||
let columnName = recordset.columns[i].name;
|
||||
if (!columnName) {
|
||||
columnName = '';
|
||||
}
|
||||
|
||||
let columnMetadataRender = <Interfaces.IBackgridColumnMetadata> {
|
||||
name: columnName,
|
||||
label: columnName,
|
||||
cell: "string" // format all columns as string for display in backgrid
|
||||
}
|
||||
cell: 'string' // format all columns as string for display in backgrid
|
||||
};
|
||||
columnMetadata.push(columnMetadataRender);
|
||||
}
|
||||
return columnMetadata;
|
||||
}
|
||||
|
||||
// return column metadata for recordset
|
||||
private getRowsInResultset(recordset: any)
|
||||
{
|
||||
private getRowsInResultset(recordset: any): any[] {
|
||||
const self = this;
|
||||
let rowsInResultset = [];
|
||||
for(let row of recordset)
|
||||
{
|
||||
for (let row of recordset) {
|
||||
self.formatRowData(row);
|
||||
rowsInResultset.push(row);
|
||||
}
|
||||
|
@ -306,27 +270,20 @@ export default class QueryRunner
|
|||
}
|
||||
|
||||
// convert data in row to string values that can be displayed
|
||||
private formatRowData(row: any)
|
||||
{
|
||||
for (let col in row)
|
||||
{
|
||||
let value = row[col];
|
||||
if (value instanceof Date)
|
||||
{
|
||||
row[col] = value.toISOString();
|
||||
}
|
||||
else if ((value instanceof Buffer) || (value instanceof Object))
|
||||
{
|
||||
let formattedValue = "0x" + value.toString('hex');
|
||||
if(formattedValue.length > 128) {
|
||||
private formatRowData(row: any): void {
|
||||
for (let i = 0; i < row.length; i++) {
|
||||
let value = row[i];
|
||||
if (value instanceof Date) {
|
||||
row[i] = value.toISOString();
|
||||
} else if ((value instanceof Buffer) || (value instanceof Object)) {
|
||||
let formattedValue = '0x' + value.toString('hex');
|
||||
if (formattedValue.length > 128) {
|
||||
formattedValue = formattedValue.slice(0, 128);
|
||||
}
|
||||
row[col] = formattedValue;
|
||||
}
|
||||
else if(value === null)
|
||||
{
|
||||
row[col] = "NULL";
|
||||
row[i] = formattedValue;
|
||||
} else if (value === undefined) {
|
||||
row[i] = 'NULL';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,17 +6,15 @@ let controller: MainController = undefined;
|
|||
|
||||
// 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)
|
||||
{
|
||||
export function activate(context: vscode.ExtensionContext): void {
|
||||
controller = new MainController(context);
|
||||
context.subscriptions.push(controller);
|
||||
controller.activate();
|
||||
context.subscriptions.push(controller);
|
||||
controller.activate();
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate()
|
||||
{
|
||||
if(controller) {
|
||||
export function deactivate(): void {
|
||||
if (controller) {
|
||||
controller.deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,121 +3,114 @@ import Constants = require('./constants');
|
|||
import Interfaces = require('./interfaces');
|
||||
|
||||
// Fix up connection settings if we're connecting to Azure SQL
|
||||
export function fixupConnectionCredentials(connCreds: Interfaces.IConnectionCredentials): Interfaces.IConnectionCredentials
|
||||
{
|
||||
if(!connCreds.server) {
|
||||
connCreds.server = "";
|
||||
export function fixupConnectionCredentials(connCreds: Interfaces.IConnectionCredentials): Interfaces.IConnectionCredentials {
|
||||
if (!connCreds.server) {
|
||||
connCreds.server = '';
|
||||
}
|
||||
|
||||
if(!connCreds.database) {
|
||||
connCreds.database = "";
|
||||
if (!connCreds.database) {
|
||||
connCreds.database = '';
|
||||
}
|
||||
|
||||
if(!connCreds.user) {
|
||||
connCreds.user = "";
|
||||
if (!connCreds.user) {
|
||||
connCreds.user = '';
|
||||
}
|
||||
|
||||
if(!connCreds.password) {
|
||||
connCreds.password = "";
|
||||
if (!connCreds.password) {
|
||||
connCreds.password = '';
|
||||
}
|
||||
|
||||
if(!connCreds.connectionTimeout) {
|
||||
if (!connCreds.connectionTimeout) {
|
||||
connCreds.connectionTimeout = Constants.gDefaultConnectionTimeout;
|
||||
}
|
||||
|
||||
if(!connCreds.requestTimeout) {
|
||||
if (!connCreds.requestTimeout) {
|
||||
connCreds.requestTimeout = Constants.gDefaultRequestTimeout;
|
||||
}
|
||||
|
||||
// default values for advanced options
|
||||
if(!connCreds.options) {
|
||||
connCreds.options = {encrypt: false, appName: Constants.gExtensionName}
|
||||
if (!connCreds.options) {
|
||||
connCreds.options = {encrypt: false, appName: Constants.gExtensionName};
|
||||
}
|
||||
|
||||
// default value for encrypt
|
||||
if(!connCreds.options.encrypt) {
|
||||
if (!connCreds.options.encrypt) {
|
||||
connCreds.options.encrypt = false;
|
||||
}
|
||||
|
||||
// default value for appName
|
||||
if(!connCreds.options.appName) {
|
||||
if (!connCreds.options.appName) {
|
||||
connCreds.options.appName = Constants.gExtensionName;
|
||||
}
|
||||
|
||||
if(isAzureDatabase(connCreds.server))
|
||||
{
|
||||
if (isAzureDatabase(connCreds.server)) {
|
||||
// always encrypt connection if connecting to Azure SQL
|
||||
connCreds.options.encrypt = true;
|
||||
|
||||
// Ensure minumum connection timeout if connecting to Azure SQL
|
||||
if(connCreds.connectionTimeout < Constants.gAzureSqlDbConnectionTimeout) {
|
||||
if (connCreds.connectionTimeout < Constants.gAzureSqlDbConnectionTimeout) {
|
||||
connCreds.connectionTimeout = Constants.gAzureSqlDbConnectionTimeout;
|
||||
}
|
||||
|
||||
// Ensure minumum request timeout if connecting to Azure SQL
|
||||
if(connCreds.requestTimeout < Constants.gAzureSqlDbRequestTimeout) {
|
||||
if (connCreds.requestTimeout < Constants.gAzureSqlDbRequestTimeout) {
|
||||
connCreds.requestTimeout = Constants.gAzureSqlDbRequestTimeout;
|
||||
}
|
||||
}
|
||||
return connCreds;
|
||||
}
|
||||
|
||||
// return true if server name ends with ".database.windows.net"
|
||||
function isAzureDatabase(server: string) {
|
||||
// return true if server name ends with '.database.windows.net'
|
||||
function isAzureDatabase(server: string): boolean {
|
||||
return (server ? server.endsWith(Constants.gSqlDbPrefix) : false);
|
||||
}
|
||||
|
||||
export function dump(connCreds: Interfaces.IConnectionCredentials): string {
|
||||
let contents = "server=" + (connCreds.server ? connCreds.server : "null") +
|
||||
" | database=" + (connCreds.database ? connCreds.database : "null") +
|
||||
" | username=" + (connCreds.user ? connCreds.user : "null") +
|
||||
" | encrypt=" + connCreds.options.encrypt +
|
||||
" | connectionTimeout=" + connCreds.connectionTimeout +
|
||||
" | connectionTimeout=" + connCreds.requestTimeout;
|
||||
let contents = 'server=' + (connCreds.server ? connCreds.server : 'null') +
|
||||
' | database=' + (connCreds.database ? connCreds.database : 'null') +
|
||||
' | username=' + (connCreds.user ? connCreds.user : 'null') +
|
||||
' | encrypt=' + connCreds.options.encrypt +
|
||||
' | connectionTimeout=' + connCreds.connectionTimeout +
|
||||
' | connectionTimeout=' + connCreds.requestTimeout;
|
||||
return contents;
|
||||
}
|
||||
|
||||
// compare connections porperties, except for password
|
||||
export function equals(connCreds: Interfaces.IConnectionCredentials, theOther: Interfaces.IConnectionCredentials): boolean
|
||||
{
|
||||
let equal = (connCreds.server == theOther.server) &&
|
||||
(connCreds.database == theOther.database) &&
|
||||
(connCreds.user == theOther.user) &&
|
||||
(connCreds.options.encrypt == theOther.options.encrypt) &&
|
||||
(connCreds.connectionTimeout == theOther.connectionTimeout) &&
|
||||
(connCreds.requestTimeout == theOther.requestTimeout);
|
||||
export function equals(connCreds: Interfaces.IConnectionCredentials, theOther: Interfaces.IConnectionCredentials): boolean {
|
||||
let equal = (connCreds.server === theOther.server) &&
|
||||
(connCreds.database === theOther.database) &&
|
||||
(connCreds.user === theOther.user) &&
|
||||
(connCreds.options.encrypt === theOther.options.encrypt) &&
|
||||
(connCreds.connectionTimeout === theOther.connectionTimeout) &&
|
||||
(connCreds.requestTimeout === theOther.requestTimeout);
|
||||
return equal;
|
||||
}
|
||||
|
||||
export function getPicklistLabel(connCreds: Interfaces.IConnectionCredentials): string
|
||||
{
|
||||
export function getPicklistLabel(connCreds: Interfaces.IConnectionCredentials): string {
|
||||
return connCreds.server;
|
||||
}
|
||||
|
||||
export function getPicklistDescription(connCreds: Interfaces.IConnectionCredentials): string
|
||||
{
|
||||
return "[" +
|
||||
"database: " + (connCreds.database ? connCreds.database : "<connection default>") +
|
||||
", username: " + (connCreds.user ? connCreds.user : "<prompt>") +
|
||||
"]";
|
||||
export function getPicklistDescription(connCreds: Interfaces.IConnectionCredentials): string {
|
||||
return '[' +
|
||||
'database: ' + (connCreds.database ? connCreds.database : '<connection default>') +
|
||||
', username: ' + (connCreds.user ? connCreds.user : '<prompt>') +
|
||||
']';
|
||||
}
|
||||
|
||||
export function getPicklistDetails(connCreds: Interfaces.IConnectionCredentials): string
|
||||
{
|
||||
return "[" +
|
||||
"encrypt connection: " + (connCreds.options.encrypt ? "true" : "false") +
|
||||
", connection timeout: " + connCreds.connectionTimeout + " ms" +
|
||||
", request timeout: " + connCreds.requestTimeout + " ms" +
|
||||
"]";
|
||||
export function getPicklistDetails(connCreds: Interfaces.IConnectionCredentials): string {
|
||||
return '[' +
|
||||
'encrypt connection: ' + (connCreds.options.encrypt ? 'true' : 'false') +
|
||||
', connection timeout: ' + connCreds.connectionTimeout + ' ms' +
|
||||
', request timeout: ' + connCreds.requestTimeout + ' ms' +
|
||||
']';
|
||||
}
|
||||
|
||||
export function getTooltip(connCreds: Interfaces.IConnectionCredentials): string
|
||||
{
|
||||
return "server: " + connCreds.server + "\r\n" +
|
||||
"database: " + (connCreds.database ? connCreds.database : "<connection default>") + "\r\n" +
|
||||
"username: " + connCreds.user + "\r\n" +
|
||||
"encrypt connection: " + (connCreds.options.encrypt ? "true" : "false") + "\r\n" +
|
||||
"connection timeout: " + connCreds.connectionTimeout + " ms\r\n" +
|
||||
"request timeout: " + connCreds.requestTimeout + " ms\r\n" +
|
||||
"appName: " + connCreds.options.appName;
|
||||
}
|
||||
export function getTooltip(connCreds: Interfaces.IConnectionCredentials): string {
|
||||
return 'server: ' + connCreds.server + '\r\n' +
|
||||
'database: ' + (connCreds.database ? connCreds.database : '<connection default>') + '\r\n' +
|
||||
'username: ' + connCreds.user + '\r\n' +
|
||||
'encrypt connection: ' + (connCreds.options.encrypt ? 'true' : 'false') + '\r\n' +
|
||||
'connection timeout: ' + connCreds.connectionTimeout + ' ms\r\n' +
|
||||
'request timeout: ' + connCreds.requestTimeout + ' ms\r\n' +
|
||||
'appName: ' + connCreds.options.appName;
|
||||
}
|
||||
|
|
|
@ -1,87 +1,89 @@
|
|||
// constants
|
||||
export const gLanguageId = "sql";
|
||||
export const gExtensionName = "vscode-mssql";
|
||||
export const gOutputChannelName = "MSSQL";
|
||||
export const gLanguageId = 'sql';
|
||||
export const gExtensionName = 'vscode-mssql';
|
||||
export const gOutputChannelName = 'MSSQL';
|
||||
|
||||
export const gCmdRunQuery = 'extension.runQuery';
|
||||
export const gCmdConnect = 'extension.connect';
|
||||
export const gCmdDisconnect = 'extension.disconnect';
|
||||
|
||||
export const gSqlDbPrefix = ".database.windows.net";
|
||||
export const gSqlDbPrefix = '.database.windows.net';
|
||||
export const gDefaultConnectionTimeout = 15000;
|
||||
export const gDefaultRequestTimeout = 15000;
|
||||
export const gAzureSqlDbConnectionTimeout = 30000;
|
||||
export const gAzureSqlDbRequestTimeout = 30000;
|
||||
export const gAzureDatabase = "Azure";
|
||||
export const gAzureDatabase = 'Azure';
|
||||
|
||||
export const gOutputContentTypeRoot = 'root';
|
||||
export const gOutputContentTypeMessages = "messages";
|
||||
export const gOutputContentTypeMessages = 'messages';
|
||||
export const gOutputContentTypeResultsetMeta = 'resultsetsMeta';
|
||||
export const gOutputContentTypeColumns = 'columns'
|
||||
export const gOutputContentTypeRows = 'rows'
|
||||
export const gOutputServiceLocalhost = "http://localhost:";
|
||||
export const gOutputContentTypeColumns = 'columns';
|
||||
export const gOutputContentTypeRows = 'rows';
|
||||
export const gOutputServiceLocalhost = 'http://localhost:';
|
||||
export const gMsgContentProviderSqlOutputHtml = 'sqlOutput.ejs';
|
||||
|
||||
export const gConfigLogDebugInfo = "logDebugInfo";
|
||||
export const gConfigMyConnections = "connections";
|
||||
export const gConfigLogDebugInfo = 'logDebugInfo';
|
||||
export const gConfigMyConnections = 'connections';
|
||||
|
||||
// localizable strings
|
||||
export const gConfigMyConnectionsNoServerName = "Missing server name in user preferences connection: ";
|
||||
export const gConfigMyConnectionsNoServerName = 'Missing server name in user preferences connection: ';
|
||||
|
||||
export const gMsgLocalWebserviceStaticContent = "LocalWebService: added static html content path: ";
|
||||
export const gMsgLocalWebserviceStaticContent = 'LocalWebService: added static html content path: ';
|
||||
export const gMsgLocalWebserviceStarted = 'LocalWebService listening on port ';
|
||||
export const gMsgRunQueryAllBatchesExecuted = 'runQuery: all batches executed';
|
||||
export const gMsgRunQueryError = 'runQuery: error: ';
|
||||
export const gMsgRunQueryExecutingBatch = 'runQuery: executeBatch called with SQL: '
|
||||
export const gMsgRunQueryAddBatchResultsets = 'runQuery: adding resultsets for batch: '
|
||||
export const gMsgRunQueryAddBatchError = 'runQuery: adding error message for batch: '
|
||||
export const gMsgRunQueryExecutingBatch = 'runQuery: executeBatch called with SQL: ';
|
||||
export const gMsgRunQueryAddBatchResultsets = 'runQuery: adding resultsets for batch: ';
|
||||
export const gMsgRunQueryAddBatchError = 'runQuery: adding error message for batch: ';
|
||||
export const gMsgRunQueryConnectionActive = 'runQuery: active connection is connected, using it to run query';
|
||||
export const gMsgRunQueryConnectionDisconnected = 'runQuery: active connection is disconnected, reconnecting';
|
||||
export const gMsgRunQueryNoConnection = 'runQuery: no active connection - prompting for user';
|
||||
|
||||
export const gMsgContentProviderOnContentUpdated = "Content provider: onContentUpdated called";
|
||||
export const gMsgContentProviderOnContentUpdated = 'Content provider: onContentUpdated called';
|
||||
export const gMsgContentProviderOnRootEndpoint = 'LocalWebService: Root end-point called';
|
||||
export const gMsgContentProviderOnResultsEndpoint = "LocalWebService: ResultsetsMeta endpoint called";
|
||||
export const gMsgContentProviderOnResultsEndpoint = 'LocalWebService: ResultsetsMeta endpoint called';
|
||||
export const gMsgContentProviderOnMessagesEndpoint = 'LocalWebService: Messages end-point called';
|
||||
export const gMsgContentProviderOnColumnsEndpoint = "LocalWebService: Columns end-point called for index = ";
|
||||
export const gMsgContentProviderOnRowsEndpoint = "LocalWebService: Rows end-point called for index = ";
|
||||
export const gMsgContentProviderOnClear = "Content provider: clear called";
|
||||
export const gMsgContentProviderOnColumnsEndpoint = 'LocalWebService: Columns end-point called for index = ';
|
||||
export const gMsgContentProviderOnRowsEndpoint = 'LocalWebService: Rows end-point called for index = ';
|
||||
export const gMsgContentProviderOnClear = 'Content provider: clear called';
|
||||
export const gMsgContentProviderOnUpdateContent = 'Content provider: updateContent called';
|
||||
export const gMsgContentProviderProvideContent = 'Content provider: provideTextDocumentContent called: ';
|
||||
|
||||
export const gExtensionActivated = "activated.";
|
||||
export const gExtensionDeactivated = "de-activated.";
|
||||
export const gMsgOpenSqlFile = "To use this command, Open a .sql file -or- Change editor language to 'SQL' -or- Select some T-SQL text in the active SQL editor.";
|
||||
export const gExtensionActivated = 'activated.';
|
||||
export const gExtensionDeactivated = 'de-activated.';
|
||||
export const gMsgOpenSqlFile = `To use this command, Open a .sql file -or-
|
||||
Change editor language to "SQL" -or-
|
||||
Select some T-SQL text in the active SQL editor.`;
|
||||
|
||||
export const gRecentConnectionsPlaceholder = "Choose a connection from the list below";
|
||||
export const gMsgNoConnectionsInSettings = "To use this command, add connection information to VS Code User or Workspace settings.";
|
||||
export const gLabelOpenGlobalSettings = "Open Global Settings";
|
||||
export const gLabelOpenWorkspaceSettings = "Open Workspace Settings";
|
||||
export const gRecentConnectionsPlaceholder = 'Choose a connection from the list below';
|
||||
export const gMsgNoConnectionsInSettings = 'To use this command, add connection information to VS Code User or Workspace settings.';
|
||||
export const gLabelOpenGlobalSettings = 'Open Global Settings';
|
||||
export const gLabelOpenWorkspaceSettings = 'Open Workspace Settings';
|
||||
|
||||
export const gServerPrompt = "Server name";
|
||||
export const gServerPlaceholder = "hostname\\instance or <server>.database.windows.net";
|
||||
export const gDatabasePrompt = "Database name";
|
||||
export const gDatabasePlaceholder = "optional database to connect to (default depends on server configuration, typically 'master')";
|
||||
export const gUsernamePrompt = "Username";
|
||||
export const gUsernamePlaceholder = "username (SQL Authentication)";
|
||||
export const gPasswordPrompt = "Password";
|
||||
export const gPasswordPlaceholder = "Password (SQL Authentication)";
|
||||
export const gServerPrompt = 'Server name';
|
||||
export const gServerPlaceholder = 'hostname\\instance or <server>.database.windows.net';
|
||||
export const gDatabasePrompt = 'Database name';
|
||||
export const gDatabasePlaceholder = 'optional database to connect to (default depends on server configuration, typically "master")';
|
||||
export const gUsernamePrompt = 'Username';
|
||||
export const gUsernamePlaceholder = 'username (SQL Authentication)';
|
||||
export const gPasswordPrompt = 'Password';
|
||||
export const gPasswordPlaceholder = 'Password (SQL Authentication)';
|
||||
|
||||
export const gMsgIsRequired = " is required.";
|
||||
export const gMsgRetry = "Retry";
|
||||
export const gMsgError = "Error: ";
|
||||
export const gMsgIsRequired = ' is required.';
|
||||
export const gMsgRetry = 'Retry';
|
||||
export const gMsgError = 'Error: ';
|
||||
|
||||
export const gNotConnectedLabel = "Not connected";
|
||||
export const gNotConnectedTooltip = "Click to connect to a database";
|
||||
export const gConnectingLabel = "Connecting";
|
||||
export const gConnectingTooltip = "Connecting to: ";
|
||||
export const gConnectedLabel = "Connected.";
|
||||
export const gConnectErrorLabel = "Connection error!";
|
||||
export const gConnectErrorTooltip = "Error connecting to: ";
|
||||
export const gConnectErrorCode = "Errorcode: ";
|
||||
export const gConnectErrorMessage = "ErrorMessage: ";
|
||||
export const gExecuteQueryLabel = "Executing query ";
|
||||
export const gExecuteQueryErrorLabel = "Query completed with errors";
|
||||
export const gExecuteQuerySuccessLabel = "Query executed successfully";
|
||||
export const gExecuteQueryRowsAffected = " row(s) affected";
|
||||
export const gExecuteQueryCommandCompleted = "Command(s) completed successfully.";
|
||||
export const gNotConnectedLabel = 'Not connected';
|
||||
export const gNotConnectedTooltip = 'Click to connect to a database';
|
||||
export const gConnectingLabel = 'Connecting';
|
||||
export const gConnectingTooltip = 'Connecting to: ';
|
||||
export const gConnectedLabel = 'Connected.';
|
||||
export const gConnectErrorLabel = 'Connection error!';
|
||||
export const gConnectErrorTooltip = 'Error connecting to: ';
|
||||
export const gConnectErrorCode = 'Errorcode: ';
|
||||
export const gConnectErrorMessage = 'ErrorMessage: ';
|
||||
export const gExecuteQueryLabel = 'Executing query ';
|
||||
export const gExecuteQueryErrorLabel = 'Query completed with errors';
|
||||
export const gExecuteQuerySuccessLabel = 'Query executed successfully';
|
||||
export const gExecuteQueryRowsAffected = ' row(s) affected';
|
||||
export const gExecuteQueryCommandCompleted = 'Command(s) completed successfully.';
|
||||
|
|
|
@ -3,8 +3,7 @@ import vscode = require('vscode');
|
|||
import Constants = require('./constants');
|
||||
|
||||
// interfaces
|
||||
export enum ContentType
|
||||
{
|
||||
export enum ContentType {
|
||||
Root = 0,
|
||||
Messages = 1,
|
||||
ResultsetsMeta = 2,
|
||||
|
@ -18,50 +17,44 @@ Constants.gOutputContentTypeColumns, Constants.gOutputContentTypeRows];
|
|||
// mssql.config wrapped into an interface for us to use more easily
|
||||
// Provided by the user when creating a new database connection
|
||||
// See this for more info: http://pekim.github.io/tedious/api-connection.html
|
||||
export interface IConnectionCredentials
|
||||
{
|
||||
server: string;
|
||||
database: string;
|
||||
user: string;
|
||||
password: string;
|
||||
connectionTimeout: number;
|
||||
requestTimeout: number;
|
||||
options: { encrypt: boolean, appName: string }
|
||||
export interface IConnectionCredentials {
|
||||
server: string;
|
||||
database: string;
|
||||
user: string;
|
||||
password: string;
|
||||
connectionTimeout: number;
|
||||
requestTimeout: number;
|
||||
options: { encrypt: boolean, appName: string };
|
||||
};
|
||||
|
||||
export interface IConnectionCredentialsQuickPickItem extends vscode.QuickPickItem {
|
||||
connectionCreds: IConnectionCredentials;
|
||||
}
|
||||
connectionCreds: IConnectionCredentials;
|
||||
};
|
||||
|
||||
// Obtained from an active connection to show in the status bar
|
||||
export interface IConnectionProperties
|
||||
{
|
||||
serverVersion: string;
|
||||
currentUser: string;
|
||||
currentDatabase: string;
|
||||
export interface IConnectionProperties {
|
||||
serverVersion: string;
|
||||
currentUser: string;
|
||||
currentDatabase: string;
|
||||
};
|
||||
|
||||
export interface IBackgridColumnMetadata
|
||||
{
|
||||
name: string,
|
||||
label: string,
|
||||
cell: string
|
||||
export interface IBackgridColumnMetadata {
|
||||
name: string;
|
||||
label: string;
|
||||
cell: string;
|
||||
}
|
||||
|
||||
export interface ISqlResultsetMeta
|
||||
{
|
||||
columnsUri: string,
|
||||
rowsUri: string
|
||||
export interface ISqlResultsetMeta {
|
||||
columnsUri: string;
|
||||
rowsUri: string;
|
||||
};
|
||||
|
||||
export interface ISqlMessage
|
||||
{
|
||||
messageText: string
|
||||
export interface ISqlMessage {
|
||||
messageText: string;
|
||||
};
|
||||
|
||||
export interface ISqlResultset
|
||||
{
|
||||
columns: any[],
|
||||
rows: any[],
|
||||
executionPlanXml: string
|
||||
};
|
||||
export interface ISqlResultset {
|
||||
columns: any[];
|
||||
rows: any[];
|
||||
executionPlanXml: string;
|
||||
};
|
||||
|
|
|
@ -5,16 +5,13 @@ import ConnInfo = require('./connectionInfo');
|
|||
import Interfaces = require('./interfaces');
|
||||
import Utils = require('../models/utils');
|
||||
|
||||
export class RecentConnections
|
||||
{
|
||||
export class RecentConnections {
|
||||
// Load connections from user preferences and return them as a formatted picklist
|
||||
public getPickListItems()
|
||||
{
|
||||
public getPickListItems(): Promise<Interfaces.IConnectionCredentialsQuickPickItem[]> {
|
||||
const self = this;
|
||||
return new Promise<Interfaces.IConnectionCredentialsQuickPickItem[]>((resolve, reject) =>
|
||||
{
|
||||
return new Promise<Interfaces.IConnectionCredentialsQuickPickItem[]>((resolve, reject) => {
|
||||
self.loadConnections()
|
||||
.then(function(connections)
|
||||
.then(function(connections): void
|
||||
{
|
||||
const pickListItems = connections.map( (item: Interfaces.IConnectionCredentials) => {
|
||||
return <Interfaces.IConnectionCredentialsQuickPickItem> {
|
||||
|
@ -22,7 +19,7 @@ export class RecentConnections
|
|||
description: ConnInfo.getPicklistDescription(item),
|
||||
detail: ConnInfo.getPicklistDetails(item),
|
||||
connectionCreds: item
|
||||
}
|
||||
};
|
||||
});
|
||||
resolve(pickListItems);
|
||||
});
|
||||
|
@ -30,31 +27,24 @@ export class RecentConnections
|
|||
}
|
||||
|
||||
// Load connections from user preferences
|
||||
private loadConnections()
|
||||
{
|
||||
const self = this;
|
||||
return new Promise<Interfaces.IConnectionCredentials[]>((resolve, reject) =>
|
||||
{
|
||||
private loadConnections(): Promise<Interfaces.IConnectionCredentials[]> {
|
||||
return new Promise<Interfaces.IConnectionCredentials[]>((resolve, reject) => {
|
||||
// Load connections from user preferences
|
||||
// Per this https://code.visualstudio.com/Docs/customization/userandworkspace
|
||||
// Settings defined in workspace scope overwrite the settings defined in user scope
|
||||
let connections: Interfaces.IConnectionCredentials[] = [];
|
||||
let config = vscode.workspace.getConfiguration(Constants.gExtensionName);
|
||||
let configValues = config[Constants.gConfigMyConnections];
|
||||
for (var index = 0; index < configValues.length; index++)
|
||||
{
|
||||
for (let index = 0; index < configValues.length; index++) {
|
||||
let element = configValues[index];
|
||||
if(element.server && element.server.trim() && !element.server.trim().startsWith("{{"))
|
||||
{
|
||||
if (element.server && element.server.trim() && !element.server.trim().startsWith('{{')) {
|
||||
let connection = ConnInfo.fixupConnectionCredentials(element);
|
||||
connections.push(connection);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.logDebug(Constants.gConfigMyConnectionsNoServerName + " index (" + index + "): " + element.toString());
|
||||
} else {
|
||||
Utils.logDebug(Constants.gConfigMyConnectionsNoServerName + ' index (' + index + '): ' + element.toString());
|
||||
}
|
||||
}
|
||||
resolve(connections);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,13 @@ class QueryResultSet {
|
|||
public messages: string[] = [];
|
||||
public resultsets: Interfaces.ISqlResultset[] = [];
|
||||
|
||||
constructor(messages : string[], resultsets : Interfaces.ISqlResultset[]){
|
||||
constructor(messages: string[], resultsets: Interfaces.ISqlResultset[]) {
|
||||
this.messages = messages;
|
||||
this.resultsets = resultsets;
|
||||
}
|
||||
}
|
||||
|
||||
export class SqlOutputContentProvider implements vscode.TextDocumentContentProvider
|
||||
{
|
||||
export class SqlOutputContentProvider implements vscode.TextDocumentContentProvider {
|
||||
private _queryResultsMap: Map<string, QueryResultSet> = new Map<string, QueryResultSet>();
|
||||
public static providerName = 'tsqloutput';
|
||||
public static providerUri = vscode.Uri.parse('tsqloutput://');
|
||||
|
@ -28,101 +27,93 @@ export class SqlOutputContentProvider implements vscode.TextDocumentContentProvi
|
|||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
public onContentUpdated() {
|
||||
public onContentUpdated(): void {
|
||||
Utils.logDebug(Constants.gMsgContentProviderOnContentUpdated);
|
||||
this._onDidChange.fire(SqlOutputContentProvider.providerUri);
|
||||
}
|
||||
|
||||
constructor(context: vscode.ExtensionContext)
|
||||
{
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
const self = this;
|
||||
|
||||
// create local express server
|
||||
this._service = new LocalWebService(context.extensionPath);
|
||||
|
||||
// add http handler for '/'
|
||||
this._service.addHandler(Interfaces.ContentType.Root, function(req, res) {
|
||||
this._service.addHandler(Interfaces.ContentType.Root, function(req, res): void {
|
||||
Utils.logDebug(Constants.gMsgContentProviderOnRootEndpoint);
|
||||
let uri : string = req.query.uri;
|
||||
res.render(path.join(LocalWebService.staticContentPath, Constants.gMsgContentProviderSqlOutputHtml), {uri:uri});
|
||||
let uri: string = req.query.uri;
|
||||
res.render(path.join(LocalWebService.staticContentPath, Constants.gMsgContentProviderSqlOutputHtml), {uri: uri});
|
||||
});
|
||||
|
||||
// add http handler for '/resultsetsMeta' - return metadata about columns & rows in multiple resultsets
|
||||
this._service.addHandler(Interfaces.ContentType.ResultsetsMeta, function(req, res) {
|
||||
this._service.addHandler(Interfaces.ContentType.ResultsetsMeta, function(req, res): void {
|
||||
|
||||
Utils.logDebug(Constants.gMsgContentProviderOnResultsEndpoint);
|
||||
let resultsetsMeta: Interfaces.ISqlResultsetMeta[] = [];
|
||||
let uri : string = req.query.uri;
|
||||
for (var index = 0; index < self._queryResultsMap.get(uri).resultsets.length; index ++)
|
||||
{
|
||||
let uri: string = req.query.uri;
|
||||
for (let index = 0; index < self._queryResultsMap.get(uri).resultsets.length; index ++) {
|
||||
resultsetsMeta.push( <Interfaces.ISqlResultsetMeta> {
|
||||
columnsUri: "/" + Constants.gOutputContentTypeColumns + "?id=" + index.toString(),
|
||||
rowsUri: "/" + Constants.gOutputContentTypeRows + "?id=" + index.toString()
|
||||
columnsUri: '/' + Constants.gOutputContentTypeColumns + '?id=' + index.toString(),
|
||||
rowsUri: '/' + Constants.gOutputContentTypeRows + '?id=' + index.toString()
|
||||
});
|
||||
}
|
||||
let json = JSON.stringify(resultsetsMeta);
|
||||
//Utils.logDebug(json);
|
||||
// Utils.logDebug(json);
|
||||
res.send(json);
|
||||
});
|
||||
|
||||
// add http handler for '/messages' - return all messages as a JSON string
|
||||
this._service.addHandler(Interfaces.ContentType.Messages, function(req, res) {
|
||||
this._service.addHandler(Interfaces.ContentType.Messages, function(req, res): void {
|
||||
Utils.logDebug(Constants.gMsgContentProviderOnMessagesEndpoint);
|
||||
let uri : string = req.query.uri;
|
||||
let uri: string = req.query.uri;
|
||||
let json = JSON.stringify(self._queryResultsMap.get(uri).messages);
|
||||
//Utils.logDebug(json);
|
||||
// Utils.logDebug(json);
|
||||
res.send(json);
|
||||
});
|
||||
|
||||
// add http handler for '/columns' - return column metadata as a JSON string
|
||||
this._service.addHandler(Interfaces.ContentType.Columns, function(req, res) {
|
||||
var id = req.query.id;
|
||||
this._service.addHandler(Interfaces.ContentType.Columns, function(req, res): void {
|
||||
let id = req.query.id;
|
||||
Utils.logDebug(Constants.gMsgContentProviderOnColumnsEndpoint + id);
|
||||
let uri : string = req.query.uri;
|
||||
let uri: string = req.query.uri;
|
||||
let columnMetadata = self._queryResultsMap.get(uri).resultsets[id].columns;
|
||||
let json = JSON.stringify(columnMetadata);
|
||||
//Utils.logDebug(json);
|
||||
// Utils.logDebug(json);
|
||||
res.send(json);
|
||||
});
|
||||
|
||||
// add http handler for '/rows' - return rows end-point for a specific resultset
|
||||
this._service.addHandler(Interfaces.ContentType.Rows, function(req, res) {
|
||||
var id = req.query.id;
|
||||
this._service.addHandler(Interfaces.ContentType.Rows, function(req, res): void {
|
||||
let id = req.query.id;
|
||||
Utils.logDebug(Constants.gMsgContentProviderOnRowsEndpoint + id);
|
||||
let uri : string = req.query.uri;
|
||||
let uri: string = req.query.uri;
|
||||
let json = JSON.stringify(self._queryResultsMap.get(uri).resultsets[id].rows);
|
||||
//Utils.logDebug(json);
|
||||
// Utils.logDebug(json);
|
||||
res.send(json);
|
||||
});
|
||||
|
||||
// start express server on localhost and listen on a random port
|
||||
try
|
||||
{
|
||||
try {
|
||||
this._service.start();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
} catch (error) {
|
||||
Utils.showErrorMsg(error);
|
||||
throw(error);
|
||||
}
|
||||
}
|
||||
|
||||
private clear(uri:string)
|
||||
{
|
||||
private clear(uri: string): void {
|
||||
Utils.logDebug(Constants.gMsgContentProviderOnClear);
|
||||
this._queryResultsMap.delete(uri);
|
||||
}
|
||||
|
||||
public show(uri : string, title : string)
|
||||
{
|
||||
vscode.commands.executeCommand('vscode.previewHtml', uri, vscode.ViewColumn.Two, "SQL Query Results: " + title);
|
||||
public show(uri: string, title: string): void {
|
||||
vscode.commands.executeCommand('vscode.previewHtml', uri, vscode.ViewColumn.Two, 'SQL Query Results: ' + title);
|
||||
}
|
||||
|
||||
public updateContent(messages, resultsets)
|
||||
{
|
||||
public updateContent(messages, resultsets): string {
|
||||
Utils.logDebug(Constants.gMsgContentProviderOnUpdateContent);
|
||||
let title : string = Utils.getActiveTextEditor().document.fileName;
|
||||
let uri : string = SqlOutputContentProvider.providerUri + title;
|
||||
let title: string = Utils.getActiveTextEditor().document.fileName;
|
||||
let uri: string = SqlOutputContentProvider.providerUri + title;
|
||||
this.clear(uri);
|
||||
this.show(uri, title);
|
||||
this._queryResultsMap.set(uri, new QueryResultSet(messages, resultsets));
|
||||
|
@ -131,8 +122,7 @@ export class SqlOutputContentProvider implements vscode.TextDocumentContentProvi
|
|||
}
|
||||
|
||||
// Called by VS Code exactly once to load html content in the preview window
|
||||
public provideTextDocumentContent(uri: vscode.Uri): string
|
||||
{
|
||||
public provideTextDocumentContent(uri: vscode.Uri): string {
|
||||
Utils.logDebug(Constants.gMsgContentProviderProvideContent + uri.toString());
|
||||
|
||||
// return dummy html content that redirects to 'http://localhost:<port>' after the page loads
|
||||
|
@ -149,4 +139,4 @@ export class SqlOutputContentProvider implements vscode.TextDocumentContentProvi
|
|||
<body></body>
|
||||
</html>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,11 @@ import vscode = require('vscode');
|
|||
import Constants = require('./constants');
|
||||
|
||||
// Return 'true' if the active editor window has a .sql file, false otherwise
|
||||
export function isEditingSqlFile()
|
||||
{
|
||||
export function isEditingSqlFile(): boolean {
|
||||
let sqlFile = false;
|
||||
let editor = getActiveTextEditor();
|
||||
if(editor)
|
||||
{
|
||||
if (editor.document.languageId == Constants.gLanguageId)
|
||||
{
|
||||
if (editor) {
|
||||
if (editor.document.languageId === Constants.gLanguageId) {
|
||||
sqlFile = true;
|
||||
}
|
||||
}
|
||||
|
@ -18,60 +15,49 @@ export function isEditingSqlFile()
|
|||
}
|
||||
|
||||
// Return the active text editor if there's one
|
||||
export function getActiveTextEditor()
|
||||
{
|
||||
export function getActiveTextEditor(): vscode.TextEditor {
|
||||
let editor = undefined;
|
||||
if(vscode.window && vscode.window.activeTextEditor)
|
||||
{
|
||||
if (vscode.window && vscode.window.activeTextEditor) {
|
||||
editor = vscode.window.activeTextEditor;
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
// Helper to log messages to "MSSQL" output channel
|
||||
export function logToOutputChannel(msg: any)
|
||||
{
|
||||
export function logToOutputChannel(msg: any): void {
|
||||
let outputChannel = vscode.window.createOutputChannel(Constants.gOutputChannelName);
|
||||
outputChannel.show();
|
||||
if(msg instanceof Array)
|
||||
{
|
||||
if (msg instanceof Array) {
|
||||
msg.forEach(element => {
|
||||
outputChannel.appendLine(element.toString());
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
outputChannel.appendLine(msg.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to log debug messages
|
||||
export function logDebug(msg: any)
|
||||
{
|
||||
export function logDebug(msg: any): void {
|
||||
let config = vscode.workspace.getConfiguration(Constants.gExtensionName);
|
||||
let logDebugInfo = config[Constants.gConfigLogDebugInfo];
|
||||
if(logDebugInfo == true)
|
||||
{
|
||||
if (logDebugInfo === true) {
|
||||
let currentTime = new Date().toLocaleTimeString();
|
||||
let outputMsg = "[" + currentTime + "]: " + msg ? msg.toString() : "";
|
||||
let outputMsg = '[' + currentTime + ']: ' + msg ? msg.toString() : '';
|
||||
console.log(outputMsg);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to show an info message
|
||||
export function showInfoMsg(msg: string)
|
||||
{
|
||||
vscode.window.showInformationMessage(Constants.gExtensionName + ": " + msg );
|
||||
export function showInfoMsg(msg: string): void {
|
||||
vscode.window.showInformationMessage(Constants.gExtensionName + ': ' + msg );
|
||||
}
|
||||
|
||||
// Helper to show an warn message
|
||||
export function showWarnMsg(msg: string)
|
||||
{
|
||||
vscode.window.showWarningMessage(Constants.gExtensionName + ": " + msg );
|
||||
export function showWarnMsg(msg: string): void {
|
||||
vscode.window.showWarningMessage(Constants.gExtensionName + ': ' + msg );
|
||||
}
|
||||
|
||||
// Helper to show an error message
|
||||
export function showErrorMsg(msg: string)
|
||||
{
|
||||
vscode.window.showErrorMessage(Constants.gExtensionName + ": " + msg );
|
||||
}
|
||||
export function showErrorMsg(msg: string): void {
|
||||
vscode.window.showErrorMessage(Constants.gExtensionName + ': ' + msg );
|
||||
}
|
||||
|
|
|
@ -1,39 +1,29 @@
|
|||
'use strict';
|
||||
import vscode = require('vscode');
|
||||
import ConnInfo = require('../models/connectionInfo');
|
||||
import Constants = require('../models/constants');
|
||||
import Utils = require('../models/utils');
|
||||
import { RecentConnections } from '../models/recentConnections';
|
||||
import Interfaces = require('../models/interfaces');
|
||||
|
||||
var async = require("async");
|
||||
let async = require('async');
|
||||
|
||||
export class ConnectionUI
|
||||
{
|
||||
export class ConnectionUI {
|
||||
// Helper to let user choose a connection from a picklist
|
||||
// Return the ConnectionInfo for the user's choice
|
||||
public showConnections()
|
||||
{
|
||||
public showConnections(): Promise<Interfaces.IConnectionCredentials> {
|
||||
const self = this;
|
||||
return new Promise<Interfaces.IConnectionCredentials>((resolve, reject) =>
|
||||
{
|
||||
return new Promise<Interfaces.IConnectionCredentials>((resolve, reject) => {
|
||||
let recentConnections = new RecentConnections();
|
||||
recentConnections.getPickListItems()
|
||||
.then((picklist: Interfaces.IConnectionCredentialsQuickPickItem[]) =>
|
||||
{
|
||||
if(picklist.length == 0)
|
||||
{
|
||||
.then((picklist: Interfaces.IConnectionCredentialsQuickPickItem[]) => {
|
||||
if (picklist.length === 0) {
|
||||
// No recent connections - prompt to open user settings or workspace settings to add a connection
|
||||
self.openUserOrWorkspaceSettings();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// We have recent connections - show them in a picklist
|
||||
self.showConnectionsPickList(picklist)
|
||||
.then(selection =>
|
||||
{
|
||||
if(!selection) {
|
||||
.then(selection => {
|
||||
if (!selection) {
|
||||
return false;
|
||||
}
|
||||
resolve(selection);
|
||||
|
@ -44,36 +34,31 @@ export class ConnectionUI
|
|||
}
|
||||
|
||||
// Helper to prompt user to open VS Code user settings or workspace settings
|
||||
private openUserOrWorkspaceSettings()
|
||||
{
|
||||
private openUserOrWorkspaceSettings(): void {
|
||||
let openGlobalSettingsItem: vscode.MessageItem = {
|
||||
"title": Constants.gLabelOpenGlobalSettings
|
||||
'title': Constants.gLabelOpenGlobalSettings
|
||||
};
|
||||
|
||||
let openWorkspaceSettingsItem: vscode.MessageItem = {
|
||||
"title": Constants.gLabelOpenWorkspaceSettings
|
||||
'title': Constants.gLabelOpenWorkspaceSettings
|
||||
};
|
||||
|
||||
vscode.window.showWarningMessage(Constants.gExtensionName + ": " + Constants.gMsgNoConnectionsInSettings, openGlobalSettingsItem, openWorkspaceSettingsItem)
|
||||
.then((selectedItem: vscode.MessageItem) =>
|
||||
{
|
||||
if (selectedItem === openGlobalSettingsItem)
|
||||
{
|
||||
vscode.commands.executeCommand("workbench.action.openGlobalSettings");
|
||||
}
|
||||
else if (selectedItem === openWorkspaceSettingsItem)
|
||||
{
|
||||
vscode.commands.executeCommand("workbench.action.openWorkspaceSettings");
|
||||
vscode.window.showWarningMessage(Constants.gExtensionName
|
||||
+ ': '
|
||||
+ Constants.gMsgNoConnectionsInSettings, openGlobalSettingsItem, openWorkspaceSettingsItem)
|
||||
.then((selectedItem: vscode.MessageItem) => {
|
||||
if (selectedItem === openGlobalSettingsItem) {
|
||||
vscode.commands.executeCommand('workbench.action.openGlobalSettings');
|
||||
} else if (selectedItem === openWorkspaceSettingsItem) {
|
||||
vscode.commands.executeCommand('workbench.action.openWorkspaceSettings');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Helper to let user choose a connection from a picklist
|
||||
private showConnectionsPickList(pickList: Interfaces.IConnectionCredentialsQuickPickItem[])
|
||||
{
|
||||
private showConnectionsPickList(pickList: Interfaces.IConnectionCredentialsQuickPickItem[]): Promise<Interfaces.IConnectionCredentials> {
|
||||
const self = this;
|
||||
return new Promise<Interfaces.IConnectionCredentials>((resolve, reject) =>
|
||||
{
|
||||
return new Promise<Interfaces.IConnectionCredentials>((resolve, reject) => {
|
||||
// init picklist options
|
||||
let opts: vscode.QuickPickOptions = {
|
||||
matchOnDescription: true,
|
||||
|
@ -82,15 +67,12 @@ export class ConnectionUI
|
|||
|
||||
// show picklist
|
||||
vscode.window.showQuickPick(pickList, opts)
|
||||
.then(selection =>
|
||||
{
|
||||
if(selection != null)
|
||||
{
|
||||
.then(selection => {
|
||||
if (selection !== undefined) {
|
||||
// user chose a connection from picklist. Prompt for mandatory info that's missing (e.g. username and/or password)
|
||||
let connectionCreds = selection.connectionCreds;
|
||||
self.promptForMissingInfo(connectionCreds).then((resolvedConnectionCreds) =>
|
||||
{
|
||||
if(!resolvedConnectionCreds) {
|
||||
self.promptForMissingInfo(connectionCreds).then((resolvedConnectionCreds) => {
|
||||
if (!resolvedConnectionCreds) {
|
||||
return false;
|
||||
}
|
||||
resolve(resolvedConnectionCreds);
|
||||
|
@ -101,21 +83,17 @@ export class ConnectionUI
|
|||
}
|
||||
|
||||
// Prompt user for missing details in the given IConnectionCredentials
|
||||
private promptForMissingInfo(connectionCreds: Interfaces.IConnectionCredentials)
|
||||
{
|
||||
private promptForMissingInfo(connectionCreds: Interfaces.IConnectionCredentials): Promise<Interfaces.IConnectionCredentials> {
|
||||
const self = this;
|
||||
return new Promise<Interfaces.IConnectionCredentials>((resolve, reject) =>
|
||||
{
|
||||
return new Promise<Interfaces.IConnectionCredentials>((resolve, reject) => {
|
||||
// called by async.js when all functions have finished executing
|
||||
var final = function(err, self, results)
|
||||
{
|
||||
if(err) {
|
||||
let final = function(err, object, results): boolean {
|
||||
if (err) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
resolve(results); // final connectionCreds with all the missing inputs filled in
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// call each of these functions in a waterfall and pass parameters from one to the next
|
||||
// See this for more info: https://github.com/caolan/async#waterfall
|
||||
|
@ -127,27 +105,19 @@ export class ConnectionUI
|
|||
}
|
||||
|
||||
// Helper to prompt for username
|
||||
private promptForUsername(self, connectionCreds: Interfaces.IConnectionCredentials, callback)
|
||||
{
|
||||
if(connectionCreds.user)
|
||||
{
|
||||
private promptForUsername(self, connectionCreds: Interfaces.IConnectionCredentials, callback): void {
|
||||
if (connectionCreds.user) {
|
||||
// we already have a username - tell async.js to proceed to the next function
|
||||
callback(null, self, connectionCreds);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(undefined, self, connectionCreds);
|
||||
} else {
|
||||
// we don't have a username, prompt the user to enter it
|
||||
let usernameInputOptions: vscode.InputBoxOptions = {placeHolder: Constants.gUsernamePlaceholder, prompt: Constants.gUsernamePrompt};
|
||||
self.promptUser(usernameInputOptions)
|
||||
.then((input) =>
|
||||
{
|
||||
if(input)
|
||||
{
|
||||
.then((input) => {
|
||||
if (input) {
|
||||
connectionCreds.user = input;
|
||||
callback(null, self, connectionCreds); // tell async.js to proceed to the next function
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(undefined, self, connectionCreds); // tell async.js to proceed to the next function
|
||||
} else {
|
||||
// user cancelled - raise an error and abort the wizard
|
||||
callback(true, self, connectionCreds);
|
||||
}
|
||||
|
@ -156,27 +126,19 @@ export class ConnectionUI
|
|||
}
|
||||
|
||||
// Helper to prompt for password
|
||||
private promptForPassword(self, connectionCreds: Interfaces.IConnectionCredentials, callback)
|
||||
{
|
||||
if(connectionCreds.password)
|
||||
{
|
||||
private promptForPassword(self, connectionCreds: Interfaces.IConnectionCredentials, callback): void {
|
||||
if (connectionCreds.password) {
|
||||
// we already have a password - tell async.js to proceed to the next function
|
||||
callback(null, self, connectionCreds);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(undefined, self, connectionCreds);
|
||||
} else {
|
||||
// we don't have a password, prompt the user to enter it
|
||||
let passwordInputOptions: vscode.InputBoxOptions = {placeHolder: Constants.gPasswordPlaceholder, prompt: Constants.gPasswordPrompt, password: true};
|
||||
self.promptUser(passwordInputOptions)
|
||||
.then((input) =>
|
||||
{
|
||||
if(input)
|
||||
{
|
||||
.then((input) => {
|
||||
if (input) {
|
||||
connectionCreds.password = input;
|
||||
callback(null, self, connectionCreds); // tell async.js to proceed to the next function
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(undefined, self, connectionCreds); // tell async.js to proceed to the next function
|
||||
} else {
|
||||
// user cancelled - raise an error and abort the wizard
|
||||
callback(true, self, connectionCreds);
|
||||
}
|
||||
|
@ -186,32 +148,24 @@ export class ConnectionUI
|
|||
|
||||
// Helper to prompt user for input
|
||||
// If the input is a mandatory inout then keeps prompting the user until cancelled
|
||||
private promptUser(options: vscode.InputBoxOptions, mandatoryInput = true)
|
||||
{
|
||||
return new Promise<string>((resolve, reject) =>
|
||||
{
|
||||
var prompt = () =>
|
||||
{
|
||||
vscode.window.showInputBox(options).then((input) =>
|
||||
{
|
||||
if ((!input || !input.trim()) && mandatoryInput)
|
||||
{
|
||||
// Prompt user to re-enter if this is a mandatory input
|
||||
vscode.window.showWarningMessage(options.prompt + Constants.gMsgIsRequired, Constants.gMsgRetry).then((choice) =>
|
||||
{
|
||||
if (choice === Constants.gMsgRetry) {
|
||||
prompt();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
resolve(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
prompt();
|
||||
});
|
||||
}
|
||||
}
|
||||
// private promptUser(options: vscode.InputBoxOptions, mandatoryInput = true): Promise<string> {
|
||||
// return new Promise<string>((resolve, reject) => {
|
||||
// let prompt = () => {
|
||||
// vscode.window.showInputBox(options).then((input) => {
|
||||
// if ((!input || !input.trim()) && mandatoryInput) {
|
||||
// // Prompt user to re-enter if this is a mandatory input
|
||||
// vscode.window.showWarningMessage(options.prompt + Constants.gMsgIsRequired, Constants.gMsgRetry).then((choice) => {
|
||||
// if (choice === Constants.gMsgRetry) {
|
||||
// prompt();
|
||||
// }
|
||||
// });
|
||||
// return false;
|
||||
// } else {
|
||||
// resolve(input);
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
// prompt();
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -2,31 +2,26 @@ import vscode = require('vscode');
|
|||
import Constants = require('../models/constants');
|
||||
import ConnInfo = require('../models/connectionInfo');
|
||||
import Interfaces = require('../models/interfaces');
|
||||
import Utils = require('../models/utils');
|
||||
|
||||
export default class StatusView implements vscode.Disposable
|
||||
{
|
||||
export default class StatusView implements vscode.Disposable {
|
||||
private _statusConnection: vscode.StatusBarItem;
|
||||
private _statusQuery: vscode.StatusBarItem;
|
||||
private tm;
|
||||
|
||||
constructor()
|
||||
{
|
||||
constructor() {
|
||||
this.createStatusBar();
|
||||
}
|
||||
|
||||
dispose()
|
||||
{
|
||||
dispose(): void {
|
||||
this._statusConnection.dispose();
|
||||
this._statusConnection = null;
|
||||
this._statusConnection = undefined;
|
||||
this._statusQuery.dispose();
|
||||
this._statusQuery = null;
|
||||
this._statusQuery = undefined;
|
||||
clearInterval(this.tm);
|
||||
}
|
||||
|
||||
// Create status bar item if needed
|
||||
private createStatusBar()
|
||||
{
|
||||
private createStatusBar(): void {
|
||||
if (!this._statusConnection) {
|
||||
this._statusConnection = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
}
|
||||
|
@ -35,39 +30,35 @@ export default class StatusView implements vscode.Disposable
|
|||
this._statusQuery = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
}
|
||||
|
||||
if(this.tm) {
|
||||
if (this.tm) {
|
||||
clearInterval(this.tm);
|
||||
}
|
||||
}
|
||||
|
||||
public show()
|
||||
{
|
||||
if(this._statusConnection) {
|
||||
public show(): void {
|
||||
if (this._statusConnection) {
|
||||
this._statusConnection.show();
|
||||
}
|
||||
if(this._statusQuery) {
|
||||
if (this._statusQuery) {
|
||||
this._statusQuery.show();
|
||||
}
|
||||
}
|
||||
|
||||
public notConnected()
|
||||
{
|
||||
public notConnected(): void {
|
||||
this.createStatusBar();
|
||||
this._statusQuery.hide();
|
||||
this._statusConnection.hide();
|
||||
}
|
||||
|
||||
public connecting(connCreds: Interfaces.IConnectionCredentials)
|
||||
{
|
||||
public connecting(connCreds: Interfaces.IConnectionCredentials): void {
|
||||
this.createStatusBar();
|
||||
this._statusConnection.command = null;
|
||||
this._statusConnection.command = undefined;
|
||||
this._statusConnection.tooltip = Constants.gConnectingTooltip + ConnInfo.getTooltip(connCreds);
|
||||
this._statusConnection.show();
|
||||
this.showProgress(Constants.gConnectingLabel, this._statusConnection);
|
||||
}
|
||||
|
||||
public connectSuccess(connCreds: Interfaces.IConnectionCredentials)
|
||||
{
|
||||
public connectSuccess(connCreds: Interfaces.IConnectionCredentials): void {
|
||||
this.createStatusBar();
|
||||
this._statusConnection.command = Constants.gCmdConnect;
|
||||
this._statusConnection.text = connCreds.server;
|
||||
|
@ -75,44 +66,41 @@ export default class StatusView implements vscode.Disposable
|
|||
this._statusConnection.show();
|
||||
}
|
||||
|
||||
public connectError(connCreds: Interfaces.IConnectionCredentials, error: any)
|
||||
{
|
||||
public connectError(connCreds: Interfaces.IConnectionCredentials, error: any): void {
|
||||
this.createStatusBar();
|
||||
this._statusConnection.command = Constants.gCmdConnect;
|
||||
this._statusConnection.text = Constants.gConnectErrorLabel;
|
||||
this._statusConnection.tooltip = Constants.gConnectErrorTooltip + connCreds.server + "\n" +
|
||||
Constants.gConnectErrorCode + error.code + "\n" +
|
||||
this._statusConnection.tooltip = Constants.gConnectErrorTooltip + connCreds.server + '\n' +
|
||||
Constants.gConnectErrorCode + error.code + '\n' +
|
||||
Constants.gConnectErrorMessage + error.message;
|
||||
this._statusConnection.show();
|
||||
}
|
||||
|
||||
public executingQuery(connCreds: Interfaces.IConnectionCredentials)
|
||||
{
|
||||
public executingQuery(connCreds: Interfaces.IConnectionCredentials): void {
|
||||
this.createStatusBar();
|
||||
this._statusQuery.command = null;
|
||||
this._statusQuery.command = undefined;
|
||||
this._statusQuery.tooltip = Constants.gExecuteQueryLabel;
|
||||
this._statusQuery.show();
|
||||
this.showProgress(Constants.gExecuteQueryLabel, this._statusQuery);
|
||||
}
|
||||
|
||||
public executedQuery()
|
||||
{
|
||||
public executedQuery(): void {
|
||||
this.createStatusBar();
|
||||
this._statusQuery.hide();
|
||||
}
|
||||
|
||||
private showProgress(statusText: string, statusBarItem: vscode.StatusBarItem)
|
||||
{
|
||||
private showProgress(statusText: string, statusBarItem: vscode.StatusBarItem): void {
|
||||
let index = 0;
|
||||
let progressTicks = [ '|', '/', '-', '\\'];
|
||||
this.tm = setInterval(() => {
|
||||
index++;
|
||||
if (index > 3)
|
||||
if (index > 3) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
let progressTick = progressTicks[index];
|
||||
statusBarItem.text = statusText + " " + progressTick;
|
||||
statusBarItem.text = statusText + ' ' + progressTick;
|
||||
statusBarItem.show();
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
{
|
||||
"rules": {
|
||||
"align": [
|
||||
true,
|
||||
"parameters",
|
||||
"statements"
|
||||
],
|
||||
"ban": false,
|
||||
"class-name": true,
|
||||
"comment-format": [
|
||||
true,
|
||||
"check-space"
|
||||
],
|
||||
"curly": true,
|
||||
"eofline": true,
|
||||
"forin": true,
|
||||
"indent": [
|
||||
true,
|
||||
"spaces"
|
||||
],
|
||||
"interface-name": true,
|
||||
"jsdoc-format": true,
|
||||
"label-position": true,
|
||||
"label-undefined": true,
|
||||
"max-line-length": [
|
||||
true,
|
||||
160
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
false,
|
||||
"static-before-instance",
|
||||
"variables-before-functions"
|
||||
],
|
||||
"no-any": false,
|
||||
"no-arg": true,
|
||||
"no-bitwise": true,
|
||||
"no-conditional-assignment": true,
|
||||
"no-consecutive-blank-lines": false,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-construct": true,
|
||||
"no-constructor-vars": false,
|
||||
"no-debugger": true,
|
||||
"no-duplicate-key": true,
|
||||
"no-duplicate-variable": true,
|
||||
"no-empty": true,
|
||||
"no-eval": true,
|
||||
"no-inferrable-types": false,
|
||||
"no-internal-module": true,
|
||||
"no-null-keyword": true,
|
||||
"no-require-imports": false,
|
||||
"no-shadowed-variable": true,
|
||||
"no-string-literal": false,
|
||||
"no-switch-case-fall-through": false,
|
||||
"no-trailing-whitespace": true,
|
||||
"no-unreachable": true,
|
||||
"no-unused-expression": false,
|
||||
"no-unused-variable": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-var-keyword": true,
|
||||
"no-var-requires": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [
|
||||
true,
|
||||
"check-open-brace",
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-finally",
|
||||
"check-whitespace"
|
||||
],
|
||||
"quotemark": [
|
||||
true,
|
||||
"single",
|
||||
"avoid-escape"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": true,
|
||||
"switch-default": true,
|
||||
"trailing-comma": [
|
||||
true,
|
||||
{
|
||||
"multiline": "never",
|
||||
"singleline": "never"
|
||||
}
|
||||
],
|
||||
"triple-equals": [
|
||||
true,
|
||||
"allow-null-check"
|
||||
],
|
||||
"typedef": [
|
||||
true,
|
||||
"call-signature",
|
||||
"property-declaration"
|
||||
],
|
||||
"typedef-whitespace": [
|
||||
true,
|
||||
{
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
}
|
||||
],
|
||||
"use-strict": false,
|
||||
"variable-name": [
|
||||
true,
|
||||
"allow-leading-underscore",
|
||||
"ban-keywords"
|
||||
],
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"
|
||||
]
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче