Clean up shared tree provider code

1. Rename files to match class names
1. Remove some unused imports
This commit is contained in:
Eric Jizba 2017-11-27 15:50:16 -08:00
Родитель 9d3c2c3320
Коммит d2456cf343
13 изменённых файлов: 343 добавлений и 175 удалений

147
package-lock.json сгенерированный
Просмотреть файл

@ -3622,6 +3622,153 @@
}
}
},
"vscode-azureextensionui": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.3.0.tgz",
"integrity": "sha512-ECvOEiRn5qWWlOTS8PYmOspyaa5eOJWCBU0VIxzabcVd9l4el4SVaInKg4N/YrbjqOvIVQ09uchqvVBGVQixpQ==",
"requires": {
"azure-arm-resource": "3.0.0-preview",
"ms-rest": "2.2.2",
"ms-rest-azure": "2.4.5",
"opn": "5.1.0",
"vscode-nls": "2.0.2"
},
"dependencies": {
"@types/node": {
"version": "8.0.53",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz",
"integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ=="
},
"@types/request": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.0.8.tgz",
"integrity": "sha512-fp8gsp0Qlq5wRas4UDjzayBxzWtQVcIumsMaHnNJzrk1Skx4WRpX5/HchSdZZf5/3Jp9m59EUBIGSI6mQEMOOg==",
"requires": {
"@types/form-data": "2.2.0",
"@types/node": "8.0.53"
}
},
"adal-node": {
"version": "0.1.25",
"resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.25.tgz",
"integrity": "sha1-ZVQ1CrQpFIcABMRcDWREjz2/zQM=",
"requires": {
"@types/node": "8.0.53",
"async": "2.5.0",
"date-utils": "1.2.21",
"jws": "3.1.4",
"request": "2.82.0",
"underscore": "1.8.3",
"uuid": "3.1.0",
"xmldom": "0.1.27",
"xpath.js": "1.0.7"
}
},
"async": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
"integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
"requires": {
"lodash": "4.17.4"
}
},
"azure-arm-resource": {
"version": "3.0.0-preview",
"resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz",
"integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==",
"requires": {
"ms-rest": "2.2.2",
"ms-rest-azure": "2.4.5"
}
},
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
},
"ms-rest-azure": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.4.5.tgz",
"integrity": "sha512-O6ho+0EQB0QcRhR5SnTdfRols5WW8FoPCikUwWPQU4f5YOtu/eFNuEZjrsLeIZ06HV2erKh2KH1kUyMHXe1jTw==",
"requires": {
"@types/node": "8.0.53",
"@types/uuid": "3.4.2",
"adal-node": "0.1.25",
"async": "2.5.0",
"moment": "2.18.1",
"ms-rest": "2.2.7",
"uuid": "3.1.0"
},
"dependencies": {
"ms-rest": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.2.7.tgz",
"integrity": "sha512-mpzbZaeYSN7OaKHW0qUbI2pDZ47oddjGJK6AzjRh7UZ7doFlr1LrgMEWQAiZDDFO9jE8usmCOz4kqWATJq/+nQ==",
"requires": {
"@types/node": "8.0.53",
"@types/request": "2.0.8",
"@types/uuid": "3.4.3",
"duplexer": "0.1.1",
"is-buffer": "1.1.6",
"is-stream": "1.1.0",
"moment": "2.18.1",
"request": "2.83.0",
"through": "2.3.8",
"tunnel": "0.0.5",
"uuid": "3.1.0"
},
"dependencies": {
"@types/uuid": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.3.tgz",
"integrity": "sha512-5fRLCYhLtDb3hMWqQyH10qtF+Ud2JnNCXTCZ+9ktNdCcgslcuXkDTkFcJNk++MT29yDntDnlF1+jD+uVGumsbw==",
"requires": {
"@types/node": "8.0.53"
}
}
}
},
"request": {
"version": "2.83.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
"integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
"requires": {
"aws-sign2": "0.7.0",
"aws4": "1.6.0",
"caseless": "0.12.0",
"combined-stream": "1.0.5",
"extend": "3.0.1",
"forever-agent": "0.6.1",
"form-data": "2.3.1",
"har-validator": "5.0.3",
"hawk": "6.0.2",
"http-signature": "1.2.0",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.17",
"oauth-sign": "0.8.2",
"performance-now": "2.1.0",
"qs": "6.5.1",
"safe-buffer": "5.1.1",
"stringstream": "0.0.5",
"tough-cookie": "2.3.3",
"tunnel-agent": "0.6.0",
"uuid": "3.1.0"
}
}
}
},
"tough-cookie": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
"integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
"requires": {
"punycode": "1.4.1"
}
}
}
},
"vscode-extension-telemetry": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz",

Просмотреть файл

Просмотреть файл

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IAzureNode } from "vscode-azureextensionui";
import { ICosmosEditor } from "../../DocumentEditor";
import { ICosmosEditor } from "../../CosmosEditorManager";
import { RetrievedDocument } from "documentdb";
import { DocDBDocumentTreeItem } from "../tree/DocDBDocumentTreeItem";

Просмотреть файл

@ -6,23 +6,18 @@
'use strict';
import * as vscode from 'vscode';
import * as _ from 'underscore';
import * as fs from 'fs';
import * as path from 'path';
import * as copypaste from 'copy-paste';
import * as util from "./util";
import * as cpUtil from './utils/cp';
import { AzureAccount } from './azure-account.api';
import { ErrorData } from './ErrorData';
import { CosmosDBCommands } from './commands';
import { AzureTreeDataProvider, IAzureNode, IAzureParentNode, UserCancelledError } from 'vscode-azureextensionui';
import { MongoCommands } from './mongo/commands';
import { MongoDatabaseTreeItem, MongoCollectionTreeItem } from './mongo/nodes';
import { DocDBAccountTreeItemBase } from './docdb/tree/DocDBAccountTreeItemBase';
import MongoDBLanguageClient from './mongo/languageClient';
import { Reporter } from './telemetry';
import { CosmosEditorManager } from './DocumentEditor';
import { CosmosEditorManager } from './CosmosEditorManager';
import { GraphViewsManager } from "./graph/GraphViewsManager";
import { CosmosDBAccountProvider } from './tree/CosmosDBAccountProvider';
import { AttachedServersTreeItem } from './tree/AttachedServersTreeItem';
@ -33,15 +28,12 @@ import { MongoDocumentTreeItem } from './mongo/tree/MongoDocumentTreeItem';
import { MongoDocumentNodeEditor } from './mongo/editors/MongoDocumentNodeEditor';
import { MongoCollectionNodeEditor } from './mongo/editors/MongoCollectionNodeEditor';
import { DocDBDocumentNodeEditor } from './docdb/editors/DocDBDocumentNodeEditor';
import { MongoDatabaseTreeItem } from './mongo/tree/MongoDatabaseTreeItem';
import { MongoCollectionTreeItem } from './mongo/tree/MongoCollectionTreeItem';
let connectedDb: IAzureParentNode<MongoDatabaseTreeItem> = null;
let languageClient: MongoDBLanguageClient = null;
let explorer: AzureTreeDataProvider;
let graphViewsManager: GraphViewsManager;
enum DocumentType {
Mongo,
DocDB
};
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(new Reporter(context));

14
src/mongo/MongoCommand.ts Normal file
Просмотреть файл

@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
export interface MongoCommand {
range: vscode.Range;
text: string;
collection?: string;
name: string;
arguments?: string;
}

Просмотреть файл

@ -7,17 +7,16 @@ import * as vscode from 'vscode';
import { ParseTree } from 'antlr4ts/tree/ParseTree';
import { ANTLRInputStream as InputStream } from 'antlr4ts/ANTLRInputStream';
import { CommonTokenStream } from 'antlr4ts/CommonTokenStream';
import { MongoCommand, MongoCollectionTreeItem, MongoDatabaseTreeItem } from './nodes';
import * as mongoParser from './grammar/mongoParser';
import { MongoVisitor } from './grammar/visitors';
import { mongoLexer } from './grammar/mongoLexer';
import * as util from './../util';
import { CosmosEditorManager } from '../DocumentEditor';
import { Collection } from 'mongodb';
import { CosmosEditorManager } from '../CosmosEditorManager';
import { IAzureParentNode } from 'vscode-azureextensionui';
import { MongoDocumentTreeItem } from './tree/MongoDocumentTreeItem';
import { MongoFindResultEditor } from './editors/MongoFindResultEditor';
import { MongoFindOneResultEditor } from './editors/MongoFindOneResultEditor';
import { MongoCommand } from './MongoCommand';
import { MongoDatabaseTreeItem } from './tree/MongoDatabaseTreeItem';
export class MongoCommands {
public static async executeCommandFromActiveEditor(database: IAzureParentNode<MongoDatabaseTreeItem>, extensionPath, editorManager: CosmosEditorManager): Promise<void> {

Просмотреть файл

@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MongoCollectionTreeItem } from "../nodes";
import { IAzureParentNode, IAzureNode } from "vscode-azureextensionui";
import { IMongoDocument, MongoDocumentTreeItem } from "../tree/MongoDocumentTreeItem";
import { ICosmosEditor } from "../../DocumentEditor";
import { ICosmosEditor } from "../../CosmosEditorManager";
import { MongoCollectionTreeItem } from "../tree/MongoCollectionTreeItem";
export class MongoCollectionNodeEditor implements ICosmosEditor<IMongoDocument[]> {
private _collectionNode: IAzureParentNode<MongoCollectionTreeItem>;

Просмотреть файл

@ -5,7 +5,7 @@
import { IAzureNode } from "vscode-azureextensionui";
import { IMongoDocument, MongoDocumentTreeItem } from "../tree/MongoDocumentTreeItem";
import { ICosmosEditor } from "../../DocumentEditor";
import { ICosmosEditor } from "../../CosmosEditorManager";
export class MongoDocumentNodeEditor implements ICosmosEditor<IMongoDocument> {
private _collectionNode: IAzureNode<MongoDocumentTreeItem>;

Просмотреть файл

@ -3,10 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MongoCollectionTreeItem, MongoDatabaseTreeItem } from "../nodes";
import { IAzureParentNode, IAzureNode } from "vscode-azureextensionui";
import { IMongoDocument, MongoDocumentTreeItem } from "../tree/MongoDocumentTreeItem";
import { ICosmosEditor } from "../../DocumentEditor";
import { ICosmosEditor } from "../../CosmosEditorManager";
import { MongoDatabaseTreeItem } from "../tree/MongoDatabaseTreeItem";
import { MongoCollectionTreeItem } from "../tree/MongoCollectionTreeItem";
export class MongoFindOneResultEditor implements ICosmosEditor<IMongoDocument> {
private _databaseNode: IAzureParentNode<MongoDatabaseTreeItem>;

Просмотреть файл

@ -3,12 +3,14 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MongoCollectionTreeItem, MongoCommand, MongoDatabaseTreeItem } from "../nodes";
import { IAzureParentNode } from "vscode-azureextensionui";
import { IMongoDocument, MongoDocumentTreeItem } from "../tree/MongoDocumentTreeItem";
import { Collection } from "mongodb";
import { MongoCollectionNodeEditor } from "./MongoCollectionNodeEditor";
import { ICosmosEditor } from "../../DocumentEditor";
import { ICosmosEditor } from "../../CosmosEditorManager";
import { MongoDatabaseTreeItem } from "../tree/MongoDatabaseTreeItem";
import { MongoCommand } from "../MongoCommand";
import { MongoCollectionTreeItem } from "../tree/MongoCollectionTreeItem";
export class MongoFindResultEditor implements ICosmosEditor<IMongoDocument[]> {
private _databaseNode: IAzureParentNode<MongoDatabaseTreeItem>;

Просмотреть файл

@ -7,7 +7,7 @@ import * as vscode from 'vscode';
import * as path from 'path';
import { MongoClient, Db } from 'mongodb';
import { IAzureParentTreeItem, IAzureTreeItem, IAzureNode, UserCancelledError } from 'vscode-azureextensionui';
import { MongoDatabaseTreeItem } from '../nodes';
import { MongoDatabaseTreeItem } from './MongoDatabaseTreeItem';
export class MongoAccountTreeItem implements IAzureParentTreeItem {
public static contextValue: string = "cosmosDBMongoServer";

Просмотреть файл

@ -8,148 +8,9 @@ import * as vm from 'vm';
import * as path from 'path';
import * as _ from 'underscore';
import { MongoClient, Db, Collection, Cursor, ObjectID, InsertOneWriteOpResult } from 'mongodb';
import { Shell } from './shell';
import { IAzureParentTreeItem, IAzureTreeItem, IAzureNode, UserCancelledError } from 'vscode-azureextensionui';
import { DialogBoxResponses, DefaultBatchSize } from '../constants';
import { IMongoDocument, MongoDocumentTreeItem } from './tree/MongoDocumentTreeItem';
export interface MongoCommand {
range: vscode.Range;
text: string;
collection?: string;
name: string;
arguments?: string;
}
export class MongoDatabaseTreeItem implements IAzureParentTreeItem {
public static contextValue: string = "mongoDb";
public readonly contextValue: string = MongoDatabaseTreeItem.contextValue;
public readonly childTypeLabel: string = "Collection";
public readonly connectionString: string;
private readonly _databaseName: string;
private readonly _accountConnectionString: string;
private readonly _parentId: string;
constructor(databaseName: string, accountConnectionString: string, parentId: string) {
this._databaseName = databaseName;
this._accountConnectionString = accountConnectionString;
this._parentId = parentId;
const uri: vscode.Uri = vscode.Uri.parse(accountConnectionString);
this.connectionString = `${uri.scheme}://${uri.authority}/${this._databaseName}?${uri.query}`;
}
public get label(): string {
return this._databaseName;
}
public get id(): string {
return `${this._parentId}/${this._databaseName}`;
}
get iconPath(): any {
return {
light: path.join(__filename, '..', '..', '..', '..', 'resources', 'icons', 'theme-agnostic', 'Database.svg'),
dark: path.join(__filename, '..', '..', '..', '..', 'resources', 'icons', 'theme-agnostic', 'Database.svg')
};
}
public hasMoreChildren(): boolean {
return false;
}
public async loadMoreChildren(_node: IAzureNode, _clearCache: boolean): Promise<IAzureTreeItem[]> {
const db: Db = await this.getDb();
const collections: Collection[] = await db.collections();
return collections.map(collection => new MongoCollectionTreeItem(this.connectionString, collection, this.id));
}
public async createChild(_node: IAzureNode, showCreatingNode: (label: string) => void): Promise<IAzureTreeItem> {
const collectionName = await vscode.window.showInputBox({
placeHolder: "Collection Name",
prompt: "Enter the name of the collection",
ignoreFocusOut: true
});
if (collectionName) {
showCreatingNode(collectionName);
return await this.createCollection(collectionName);
}
throw new UserCancelledError();
}
public async deleteTreeItem(_node: IAzureNode): Promise<void> {
const message: string = `Are you sure you want to delete database '${this.label}'?`;
const result = await vscode.window.showWarningMessage(message, DialogBoxResponses.Yes);
if (result === DialogBoxResponses.Yes) {
const db = await this.getDb();
await db.dropDatabase();
} else {
throw new UserCancelledError();
}
}
public async getDb(): Promise<Db> {
return await MongoClient.connect(this.connectionString);
}
executeCommand(command: MongoCommand): Thenable<string> {
if (command.collection) {
return this.getDb()
.then(db => {
const collection = db.collection(command.collection);
if (collection) {
const result = new MongoCollectionTreeItem(this.connectionString, collection, command.arguments).executeCommand(command.name, command.arguments);
if (result) {
return result;
}
}
return reportProgress(this.executeCommandInShell(command), 'Executing command');
});
}
if (command.name === 'createCollection') {
return reportProgress(this.createCollection(stripQuotes(command.arguments)).then(() => JSON.stringify({ 'Created': 'Ok' })), 'Creating collection');
} else {
return reportProgress(this.executeCommandInShell(command), 'Executing command');
}
}
async createCollection(collectionName: string): Promise<MongoCollectionTreeItem> {
const db: Db = await this.getDb();
const newCollection: Collection = db.collection(collectionName);
// db.createCollection() doesn't create empty collections for some reason
// However, we can 'insert' and then 'delete' a document, which has the side-effect of creating an empty collection
const result = await newCollection.insertOne({});
await newCollection.deleteOne({ _id: result.insertedId });
return new MongoCollectionTreeItem(this.connectionString, newCollection, this.id);
}
executeCommandInShell(command: MongoCommand): Thenable<string> {
return this.getShell().then(shell => shell.exec(command.text));
}
private getShell(): Promise<Shell> {
const shellPath = <string>vscode.workspace.getConfiguration().get('mongo.shell.path')
if (!shellPath) {
return <Promise<null>>vscode.window.showInputBox({
placeHolder: "Configure the path to mongo shell executable",
ignoreFocusOut: true
}).then(value => vscode.workspace.getConfiguration().update('mongo.shell.path', value, true)
.then(() => this.createShell(value)));
} else {
return this.createShell(shellPath);
}
}
private async createShell(shellPath: string): Promise<Shell> {
return <Promise<null>>Shell.create(shellPath, this._accountConnectionString)
.then(shell => {
return shell.useDatabase(this._databaseName).then(() => shell);
}, error => vscode.window.showErrorMessage(error));
}
}
import { DialogBoxResponses, DefaultBatchSize } from '../../constants';
import { IMongoDocument, MongoDocumentTreeItem } from './MongoDocumentTreeItem';
export class MongoCollectionTreeItem implements IAzureParentTreeItem {
public static contextValue: string = "MongoCollection";
@ -195,8 +56,8 @@ export class MongoCollectionTreeItem implements IAzureParentTreeItem {
get iconPath(): any {
return {
light: path.join(__filename, '..', '..', '..', '..', 'resources', 'icons', 'theme-agnostic', 'Collection.svg'),
dark: path.join(__filename, '..', '..', '..', '..', 'resources', 'icons', 'theme-agnostic', 'Collection.svg'),
light: path.join(__filename, '..', '..', '..', '..', '..', 'resources', 'icons', 'theme-agnostic', 'Collection.svg'),
dark: path.join(__filename, '..', '..', '..', '..', '..', 'resources', 'icons', 'theme-agnostic', 'Collection.svg'),
};
}
@ -353,11 +214,3 @@ function parseJSContent(content: string): any {
throw error.message;
}
}
function stripQuotes(term: string): string {
if ((term.startsWith('\'') && term.endsWith('\''))
|| (term.startsWith('"') && term.endsWith('"'))) {
return term.substring(1, term.length - 1);
}
return term;
}

Просмотреть файл

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as path from 'path';
import { MongoClient, Db, Collection } from 'mongodb';
import { Shell } from '../shell';
import { IAzureParentTreeItem, IAzureTreeItem, IAzureNode, UserCancelledError } from 'vscode-azureextensionui';
import { DialogBoxResponses } from '../../constants';
import { MongoCollectionTreeItem } from './MongoCollectionTreeItem';
import { MongoCommand } from '../MongoCommand';
export class MongoDatabaseTreeItem implements IAzureParentTreeItem {
public static contextValue: string = "mongoDb";
public readonly contextValue: string = MongoDatabaseTreeItem.contextValue;
public readonly childTypeLabel: string = "Collection";
public readonly connectionString: string;
private readonly _databaseName: string;
private readonly _accountConnectionString: string;
private readonly _parentId: string;
constructor(databaseName: string, accountConnectionString: string, parentId: string) {
this._databaseName = databaseName;
this._accountConnectionString = accountConnectionString;
this._parentId = parentId;
const uri: vscode.Uri = vscode.Uri.parse(accountConnectionString);
this.connectionString = `${uri.scheme}://${uri.authority}/${this._databaseName}?${uri.query}`;
}
public get label(): string {
return this._databaseName;
}
public get id(): string {
return `${this._parentId}/${this._databaseName}`;
}
get iconPath(): any {
return {
light: path.join(__filename, '..', '..', '..', '..', '..', 'resources', 'icons', 'theme-agnostic', 'Database.svg'),
dark: path.join(__filename, '..', '..', '..', '..', '..', 'resources', 'icons', 'theme-agnostic', 'Database.svg')
};
}
public hasMoreChildren(): boolean {
return false;
}
public async loadMoreChildren(_node: IAzureNode, _clearCache: boolean): Promise<IAzureTreeItem[]> {
const db: Db = await this.getDb();
const collections: Collection[] = await db.collections();
return collections.map(collection => new MongoCollectionTreeItem(this.connectionString, collection, this.id));
}
public async createChild(_node: IAzureNode, showCreatingNode: (label: string) => void): Promise<IAzureTreeItem> {
const collectionName = await vscode.window.showInputBox({
placeHolder: "Collection Name",
prompt: "Enter the name of the collection",
ignoreFocusOut: true
});
if (collectionName) {
showCreatingNode(collectionName);
return await this.createCollection(collectionName);
}
throw new UserCancelledError();
}
public async deleteTreeItem(_node: IAzureNode): Promise<void> {
const message: string = `Are you sure you want to delete database '${this.label}'?`;
const result = await vscode.window.showWarningMessage(message, DialogBoxResponses.Yes);
if (result === DialogBoxResponses.Yes) {
const db = await this.getDb();
await db.dropDatabase();
} else {
throw new UserCancelledError();
}
}
public async getDb(): Promise<Db> {
return await MongoClient.connect(this.connectionString);
}
executeCommand(command: MongoCommand): Thenable<string> {
if (command.collection) {
return this.getDb()
.then(db => {
const collection = db.collection(command.collection);
if (collection) {
const result = new MongoCollectionTreeItem(this.connectionString, collection, command.arguments).executeCommand(command.name, command.arguments);
if (result) {
return result;
}
}
return reportProgress(this.executeCommandInShell(command), 'Executing command');
});
}
if (command.name === 'createCollection') {
return reportProgress(this.createCollection(stripQuotes(command.arguments)).then(() => JSON.stringify({ 'Created': 'Ok' })), 'Creating collection');
} else {
return reportProgress(this.executeCommandInShell(command), 'Executing command');
}
}
async createCollection(collectionName: string): Promise<MongoCollectionTreeItem> {
const db: Db = await this.getDb();
const newCollection: Collection = db.collection(collectionName);
// db.createCollection() doesn't create empty collections for some reason
// However, we can 'insert' and then 'delete' a document, which has the side-effect of creating an empty collection
const result = await newCollection.insertOne({});
await newCollection.deleteOne({ _id: result.insertedId });
return new MongoCollectionTreeItem(this.connectionString, newCollection, this.id);
}
executeCommandInShell(command: MongoCommand): Thenable<string> {
return this.getShell().then(shell => shell.exec(command.text));
}
private getShell(): Promise<Shell> {
const shellPath = <string>vscode.workspace.getConfiguration().get('mongo.shell.path')
if (!shellPath) {
return <Promise<null>>vscode.window.showInputBox({
placeHolder: "Configure the path to mongo shell executable",
ignoreFocusOut: true
}).then(value => vscode.workspace.getConfiguration().update('mongo.shell.path', value, true)
.then(() => this.createShell(value)));
} else {
return this.createShell(shellPath);
}
}
private async createShell(shellPath: string): Promise<Shell> {
return <Promise<null>>Shell.create(shellPath, this._accountConnectionString)
.then(shell => {
return shell.useDatabase(this._databaseName).then(() => shell);
}, error => vscode.window.showErrorMessage(error));
}
}
function reportProgress<T>(promise: Thenable<T>, title: string): Thenable<T> {
return vscode.window.withProgress<T>({
location: vscode.ProgressLocation.Window,
title
}, (progress) => {
return promise;
})
}
function stripQuotes(term: string): string {
if ((term.startsWith('\'') && term.endsWith('\''))
|| (term.startsWith('"') && term.endsWith('"'))) {
return term.substring(1, term.length - 1);
}
return term;
}