- Show mongo as an explorer view
- Implement connect to database feature - Implement new scrapbook feature - Remove the linking between scrapbook and explorer - Create an untitled file for result
This commit is contained in:
Родитель
4696ee6826
Коммит
6058bf0705
78
package.json
78
package.json
|
@ -25,13 +25,6 @@
|
|||
],
|
||||
"main": "./out/src/extension",
|
||||
"contributes": {
|
||||
"views": [
|
||||
{
|
||||
"id": "mongoExplorer",
|
||||
"label": "Mongo",
|
||||
"icon": "resources/icons/database.png"
|
||||
}
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"id": "mongo",
|
||||
|
@ -54,20 +47,11 @@
|
|||
}
|
||||
],
|
||||
"commands": [
|
||||
{
|
||||
"command": "mongo.resource.onClick",
|
||||
"title": "Open Mongo Shell Editor"
|
||||
},
|
||||
{
|
||||
"category": "Mongo",
|
||||
"command": "mongo.execute",
|
||||
"title": "Execute Script"
|
||||
},
|
||||
{
|
||||
"category": "Mongo",
|
||||
"command": "mongo.executeLine",
|
||||
"title": "Execute Script at cursor"
|
||||
},
|
||||
{
|
||||
"category": "Mongo",
|
||||
"command": "mongo.addServer",
|
||||
|
@ -81,6 +65,34 @@
|
|||
"category": "Mongo",
|
||||
"command": "mongo.removeServer",
|
||||
"title": "Remove Server"
|
||||
},
|
||||
{
|
||||
"category": "Mongo",
|
||||
"command": "mongo.connect",
|
||||
"title": "Connect"
|
||||
},
|
||||
{
|
||||
"category": "Mongo",
|
||||
"command": "mongo.connectDb",
|
||||
"title": "Connect Database"
|
||||
},
|
||||
{
|
||||
"category": "Mongo",
|
||||
"command": "mongo.newScrapbook",
|
||||
"title": "New Scrapbook",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/addFile.svg",
|
||||
"dark": "resources/icons/dark/addFile.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"category": "Mongo",
|
||||
"command": "mongo.refreshExplorer",
|
||||
"title": "Refresh",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/refresh.svg",
|
||||
"dark": "resources/icons/dark/refresh.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
|
@ -88,35 +100,49 @@
|
|||
{
|
||||
"command": "mongo.execute",
|
||||
"when": "resourceLangId==mongo"
|
||||
},
|
||||
{
|
||||
"command": "mongo.executeLine",
|
||||
"when": "resourceLangId==mongo"
|
||||
}
|
||||
],
|
||||
"view/title": [
|
||||
{
|
||||
"command": "mongo.refreshExplorer",
|
||||
"when": "view == mongoExplorer",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "mongo.addServer",
|
||||
"when": "view == mongoExplorer",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "mongo.newScrapbook",
|
||||
"when": "view == mongoExplorer",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"view/resource": [
|
||||
{
|
||||
"command": "mongo.removeServer",
|
||||
"when": "view == mongoExplorer",
|
||||
"when": "view == mongoExplorer && resource == mongoServer",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "mongo.connect",
|
||||
"when": "view == mongoExplorer && resource == mongoDb",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "mongo.connect",
|
||||
"when": "view == mongoExplorer && resource == mongoDb"
|
||||
}
|
||||
]
|
||||
},
|
||||
"keybindings": [
|
||||
{
|
||||
"command": "mongo.execute",
|
||||
"key": "shift+f8"
|
||||
},
|
||||
{
|
||||
"command": "mongo.executeLine",
|
||||
"key": "f8"
|
||||
"key": "cmd+`",
|
||||
"when": "resourceLangId==mongo"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#C5C5C5" points="12,3 8,3 8,4 11,4 11,7 14,7 14,14 6,14 6,8 5,8 5,15 15,15 15,6"/><path fill="#89D185" d="M7 3.018h-2v-2.018h-1.981v2.018h-2.019v1.982h2.019v2h1.981v-2h2v-1.982z"/></svg>
|
После Ширина: | Высота: | Размер: 419 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#2D2D30"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#C5C5C5"/></svg>
|
После Ширина: | Высота: | Размер: 986 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon points="13,2 8,2 6,2 6,0 2,0 2,2 0,2 0,6 2,6 2,8 4,8 4,16 16,16 16,5" fill="#F6F6F6"/><polygon points="12,3 8,3 8,4 11,4 11,7 14,7 14,14 6,14 6,8 5,8 5,15 15,15 15,6" fill="#424242"/><path d="M7 3.018h-2v-2.018h-1.981v2.018h-2.019v1.982h2.019v2h1.981v-2h2v-1.982z" fill="#388A34"/><polygon points="11,7 11,4 8,4 8,6 6,6 6,8 6,14 14,14 14,7" fill="#F0EFF1"/></svg>
|
После Ширина: | Высота: | Размер: 435 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#F6F6F6"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#424242"/></svg>
|
После Ширина: | Высота: | Размер: 986 B |
|
@ -2,31 +2,34 @@
|
|||
|
||||
import * as vscode from 'vscode';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { MongoExplorer } from './mongo/explorer';
|
||||
import { MongoCommands, ResultDocument } from './mongo/commands';
|
||||
import { MongoCommands } from './mongo/commands';
|
||||
import { Model, Database, Server, IMongoResource } from './mongo/mongo';
|
||||
import MongoDBLanguageClient from './mongo/languageClient';
|
||||
|
||||
let connectedDb: Database = null;
|
||||
let languageClient: MongoDBLanguageClient = null;
|
||||
let model: Model;
|
||||
let mongoDocumentCounter = 0;
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
const languageClient = new MongoDBLanguageClient(context);
|
||||
|
||||
// Create the storage folder
|
||||
if (context.storagePath) {
|
||||
createStorageFolder(context).then(() => {
|
||||
const outputChannel = vscode.window.createOutputChannel('Mongo');
|
||||
const model = new Model({ extensionContext: context, outputChannel });
|
||||
const resultDocument = new ResultDocument(context);
|
||||
languageClient = new MongoDBLanguageClient(context);
|
||||
model = new Model(context.storagePath);
|
||||
|
||||
// Mongo Tree View
|
||||
const treeDataProvider = new MongoExplorer(model);
|
||||
const treeView = vscode.window.createTreeView('mongoExplorer', treeDataProvider);
|
||||
context.subscriptions.push(treeView);
|
||||
const disposable = treeDataProvider.onChange((node) => treeView.refresh(node));
|
||||
const view = vscode.window.createExplorerView('mongoExplorer', 'Mongo', treeDataProvider);
|
||||
context.subscriptions.push(view);
|
||||
const disposable = treeDataProvider.onChange((node) => view.refresh(node));
|
||||
context.subscriptions.push(new vscode.Disposable(() => disposable.dispose()))
|
||||
|
||||
// Commands
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.addServer', () => { MongoCommands.addServer(model) }));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.addServer', () => addServer()));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.refreshExplorer', () => view.refresh(model)));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.removeServer', (element: IMongoResource) => {
|
||||
if (element instanceof Server) {
|
||||
model.remove(element.id);
|
||||
|
@ -34,34 +37,62 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
model.remove(element.server.id);
|
||||
}
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.resource.onClick', (element: IMongoResource) => {
|
||||
if (element instanceof Database) {
|
||||
languageClient.connect(element);
|
||||
MongoCommands.openShell(element);
|
||||
}
|
||||
|
||||
vscode.window.setStatusBarMessage('Mongo: Not connected');
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.connect', (element: Database) => connectToDatabase(element)));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.connectDb', () => {
|
||||
vscode.window.showQuickPick(getDatabaseQuickPicks()).then(pick => connectToDatabase(pick.database));
|
||||
}));
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.execute', () => MongoCommands.executeScript(model, resultDocument, outputChannel, true)));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.executeLine', () => MongoCommands.executeScript(model, resultDocument, outputChannel, false)));
|
||||
|
||||
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor((editor => {
|
||||
if (editor) {
|
||||
const database = MongoCommands.getDatabaseForDocument(editor.document, model);
|
||||
if (database) {
|
||||
vscode.window.setStatusBarMessage('Connected to ' + database.id);
|
||||
}
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.newScrapbook', (element: IMongoResource) => {
|
||||
if (element instanceof Database) {
|
||||
connectToDatabase(element);
|
||||
}
|
||||
})));
|
||||
let uri = vscode.Uri.file(path.join(vscode.workspace.rootPath, `Scrapbook-${++mongoDocumentCounter}.mongo`));
|
||||
uri = uri.with({ scheme: 'untitled' });
|
||||
vscode.workspace.openTextDocument(uri)
|
||||
.then(textDocument => vscode.window.showTextDocument(textDocument));
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('mongo.execute', () => MongoCommands.executeScript(connectedDb)));
|
||||
});
|
||||
} else {
|
||||
context.subscriptions.push(vscode.window.createTreeView('mongoExplorer', {
|
||||
provideRootNode(): any {
|
||||
vscode.window.showInformationMessage('Open a workspace first.')
|
||||
return {};
|
||||
},
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function addServer(): void {
|
||||
vscode.window.showInputBox({
|
||||
placeHolder: 'mongodb://host:port'
|
||||
}).then(value => {
|
||||
if (value) {
|
||||
model.add(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class DatabaseQuickPick implements vscode.QuickPickItem {
|
||||
readonly label: string;
|
||||
readonly description: string;
|
||||
constructor(readonly database: Database) {
|
||||
this.label = database.label;
|
||||
this.description = database.server.label + '/' + database.label;
|
||||
}
|
||||
}
|
||||
|
||||
function getDatabaseQuickPicks(): Thenable<DatabaseQuickPick[]> {
|
||||
const quickPicks: DatabaseQuickPick[] = [];
|
||||
return model.getChildren().then(servers => {
|
||||
return Promise.all(servers.map(server => server.getChildren()))
|
||||
.then(allDatabases => {
|
||||
allDatabases.forEach(databases => {
|
||||
quickPicks.push(...databases.map(database => new DatabaseQuickPick(<Database>database)));
|
||||
});
|
||||
return quickPicks;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function connectToDatabase(database: Database): void {
|
||||
connectedDb = database;
|
||||
languageClient.connect(database);
|
||||
vscode.window.setStatusBarMessage('Mongo: Connected to ' + database.server.host + '/' + connectedDb.id);
|
||||
}
|
||||
|
||||
async function createStorageFolder(context: vscode.ExtensionContext): Promise<void> {
|
||||
|
|
|
@ -3,103 +3,35 @@ import * as vscode from 'vscode';
|
|||
import { Model, Server, Database } from './mongo';
|
||||
import * as fs from 'fs';
|
||||
|
||||
export class ResultDocument implements vscode.TextDocumentContentProvider {
|
||||
|
||||
private _result: Map<string, string> = new Map<string, any>();
|
||||
|
||||
private _onDidChange: vscode.EventEmitter<vscode.Uri> = new vscode.EventEmitter<vscode.Uri>();
|
||||
public readonly onDidChange: vscode.Event<vscode.Uri> = this._onDidChange.event;
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider('mongo', this));
|
||||
}
|
||||
|
||||
provideTextDocumentContent(uri: vscode.Uri, token: vscode.CancellationToken): vscode.ProviderResult<string> {
|
||||
const result = this._result.get(uri.toString())
|
||||
return result ? result : '';
|
||||
}
|
||||
|
||||
setResult(uri: vscode.Uri, result: string) {
|
||||
this._result.set(uri.toString(), result);
|
||||
this._onDidChange.fire(uri);
|
||||
}
|
||||
}
|
||||
|
||||
export class MongoCommands {
|
||||
|
||||
public static addServer(model: Model): void {
|
||||
vscode.window.showInputBox({
|
||||
placeHolder: 'mongodb://host:port'
|
||||
}).then(value => {
|
||||
if (value) {
|
||||
model.add(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static openShell(database: Database): void {
|
||||
let uri = vscode.Uri.file(path.join(vscode.workspace.rootPath, database.server.host + '_' + database.server.port + '_' + database.label + '.mongo'));
|
||||
const exists = fs.existsSync(uri.fsPath);
|
||||
if (!exists) {
|
||||
uri = uri.with({ scheme: 'untitled' });
|
||||
public static executeScript(database: Database): void {
|
||||
if (!database) {
|
||||
vscode.window.showErrorMessage('Please connect to the database first');
|
||||
return;
|
||||
}
|
||||
|
||||
const activeEditor = vscode.window.activeTextEditor;
|
||||
if (activeEditor.document.languageId !== 'mongo') {
|
||||
return;
|
||||
}
|
||||
|
||||
const text = activeEditor.document.lineAt(activeEditor.selection.start.line).text;
|
||||
let uri = vscode.Uri.file(path.join(vscode.workspace.rootPath, 'result.json'));
|
||||
uri = uri.with({ scheme: 'untitled' });
|
||||
vscode.workspace.openTextDocument(uri)
|
||||
.then(textDocument => {
|
||||
return vscode.window.showTextDocument(textDocument)
|
||||
.then(editor => {
|
||||
if (!exists && !MongoCommands.isShellDocument(textDocument, database)) {
|
||||
editor.edit(builder => {
|
||||
builder.insert(new vscode.Position(0, 0), database.connectionString + '\n');
|
||||
});
|
||||
}
|
||||
.then(textDocument => vscode.window.showTextDocument(textDocument, vscode.ViewColumn.Two, true))
|
||||
.then(editor => {
|
||||
database.executeScript(text)
|
||||
.then(result => {
|
||||
editor.edit(editorBuilder => {
|
||||
if (editor.document.lineCount > 0) {
|
||||
const lastLine = editor.document.lineAt(editor.document.lineCount - 1);
|
||||
editorBuilder.delete(new vscode.Range(new vscode.Position(0, 0), new vscode.Position(lastLine.range.start.line, lastLine.range.end.character)));
|
||||
}
|
||||
editorBuilder.insert(new vscode.Position(0, 0), result);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static executeScript(model: Model, resultDocument: ResultDocument, outputChannel: vscode.OutputChannel, selection: boolean): void {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (editor.document.languageId === 'mongo' || editor.document.uri.fsPath.endsWith('.mongo')) {
|
||||
const text = selection ? MongoCommands.getSelectedText(editor) : editor.document.lineAt(editor.selection.start.line).text;
|
||||
const database = MongoCommands.getDatabaseForDocument(editor.document, model);
|
||||
if (database) {
|
||||
database.executeScript(text)
|
||||
.then(result => {
|
||||
const uri = vscode.Uri.parse('mongo://test/result.json');
|
||||
resultDocument.setResult(uri, result);
|
||||
vscode.workspace.openTextDocument(uri)
|
||||
.then(textDocument => {
|
||||
vscode.window.showTextDocument(textDocument, vscode.ViewColumn.Two, true);
|
||||
});
|
||||
outputChannel.append(result);
|
||||
});
|
||||
} else {
|
||||
vscode.window.showErrorMessage('Please connect to the database first');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static getSelectedText(editor: vscode.TextEditor): string {
|
||||
const selection = editor.selection;
|
||||
if (selection.start.isEqual(selection.end)) {
|
||||
editor.document.getText();
|
||||
}
|
||||
return editor.document.getText(selection);
|
||||
}
|
||||
|
||||
public static getDatabaseForDocument(document: vscode.TextDocument, model: Model) {
|
||||
if (document.languageId === 'mongo' || document.uri.fsPath.endsWith('.mongo')) {
|
||||
for (const server of model.servers) {
|
||||
for (const database of server.databases) {
|
||||
if (MongoCommands.isShellDocument(document, database)) {
|
||||
return database;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static isShellDocument(document: vscode.TextDocument, database: Database): boolean {
|
||||
return database.connectionString === document.lineAt(0).text;
|
||||
}
|
||||
}
|
|
@ -32,6 +32,10 @@ export class MongoExplorer implements TreeDataProvider<IMongoResource> {
|
|||
};
|
||||
}
|
||||
|
||||
getContextKey(node: IMongoResource): string {
|
||||
return node.contextKey;
|
||||
}
|
||||
|
||||
resolveChildren(node: IMongoResource): Thenable<IMongoResource[]> {
|
||||
const disposables = this._disposables.get(node);
|
||||
if (disposables) {
|
||||
|
|
|
@ -1,28 +1,23 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as cp from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import { MongoClient, Db, ReadPreference, Code, Server as MongoServer } from 'mongodb';
|
||||
import { MongoClient, Db, ReadPreference, Code, Server as MongoServer, Collection as MongoCollection } from 'mongodb';
|
||||
import { Shell } from './shell';
|
||||
import { EventEmitter, Event, Command } from 'vscode';
|
||||
|
||||
export interface IMongoContext {
|
||||
extensionContext: vscode.ExtensionContext;
|
||||
outputChannel: vscode.OutputChannel;
|
||||
}
|
||||
|
||||
export interface IMongoResource {
|
||||
label: string;
|
||||
type: string;
|
||||
getChildren?(): Thenable<IMongoResource[]>;
|
||||
onChange?: Event<void>
|
||||
contextKey?: string;
|
||||
}
|
||||
|
||||
class ServersJson {
|
||||
|
||||
private _filePath: string;
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
this._filePath = context.storagePath + '/servers.json';
|
||||
constructor(storagePath: string) {
|
||||
this._filePath = storagePath + '/servers.json';
|
||||
}
|
||||
|
||||
async load(): Promise<string[]> {
|
||||
|
@ -66,8 +61,8 @@ export class Model implements IMongoResource {
|
|||
private _onChange: EventEmitter<void> = new EventEmitter<void>();
|
||||
readonly onChange: Event<void> = this._onChange.event;
|
||||
|
||||
constructor(private context: IMongoContext) {
|
||||
this._serversJson = new ServersJson(context.extensionContext);
|
||||
constructor(storagePath: string) {
|
||||
this._serversJson = new ServersJson(storagePath);
|
||||
}
|
||||
|
||||
getChildren(): Promise<IMongoResource[]> {
|
||||
|
@ -105,18 +100,18 @@ export class Model implements IMongoResource {
|
|||
private resolveServer(connectionString: string): Promise<Server> {
|
||||
return <Promise<Server>>MongoClient.connect(connectionString)
|
||||
.then(db => {
|
||||
return new Server(connectionString, db.serverConfig, this.context);
|
||||
return new Server(connectionString, db.serverConfig);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Server implements IMongoResource {
|
||||
|
||||
readonly type: string = 'mongoServer';
|
||||
readonly contextKey: string = 'mongoServer';
|
||||
|
||||
private _databases: Database[] = [];
|
||||
|
||||
constructor(public readonly id: string, private readonly mongoServer: MongoServer, private context: IMongoContext) {
|
||||
constructor(public readonly id: string, private readonly mongoServer: MongoServer) {
|
||||
}
|
||||
|
||||
get host(): string {
|
||||
|
@ -137,7 +132,7 @@ export class Server implements IMongoResource {
|
|||
return <Promise<IMongoResource[]>>MongoClient.connect(this.id)
|
||||
.then(db => db.admin().listDatabases()
|
||||
.then((value: { databases: { name }[] }) => {
|
||||
this._databases = value.databases.map(database => new Database(database.name, this, this.context));
|
||||
this._databases = value.databases.map(database => new Database(database.name, this));
|
||||
db.close();
|
||||
return <IMongoResource[]>this._databases;
|
||||
}));
|
||||
|
@ -150,19 +145,26 @@ export class Server implements IMongoResource {
|
|||
|
||||
export class Database implements IMongoResource {
|
||||
|
||||
readonly type: string = 'mongoDb';
|
||||
readonly connectionString: string;
|
||||
readonly contextKey: string = 'mongoDb';
|
||||
private shell: Shell;
|
||||
|
||||
constructor(readonly id: string, readonly server: Server, private context: IMongoContext) {
|
||||
this.connectionString = '//connection:' + this.server.id + '/' + this.id;
|
||||
constructor(readonly id: string, readonly server: Server) {
|
||||
}
|
||||
|
||||
get label(): string {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
readonly canHaveChildren: boolean = false;
|
||||
readonly canHaveChildren: boolean = true;
|
||||
|
||||
getChildren(): Promise<IMongoResource[]> {
|
||||
return <Promise<IMongoResource[]>>this.getDb().then(db => {
|
||||
return db.collections().then(collections => {
|
||||
return collections.map(collection => new Collection(collection));
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
getDb(): Promise<Db> {
|
||||
const uri = vscode.Uri.parse(this.server.id);
|
||||
|
@ -223,4 +225,16 @@ export class Database implements IMongoResource {
|
|||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class Collection implements IMongoResource {
|
||||
|
||||
constructor(private collection: MongoCollection) {
|
||||
}
|
||||
|
||||
get label(): string {
|
||||
return this.collection.collectionName;
|
||||
}
|
||||
|
||||
readonly canHaveChildren: boolean = false;
|
||||
}
|
|
@ -524,34 +524,26 @@ declare module 'vscode' {
|
|||
|
||||
export namespace window {
|
||||
|
||||
/**
|
||||
* Show window-wide progress, e.g. in the status bar, for the provided task. The task is
|
||||
* considering running as long as the promise it returned isn't resolved or rejected.
|
||||
*
|
||||
* @param task A function callback that represents a long running operation.
|
||||
*/
|
||||
export function withWindowProgress<R>(title: string, task: (progress: Progress<string>, token: CancellationToken) => Thenable<R>): Thenable<R>;
|
||||
|
||||
export function sampleFunction(): Thenable<any>;
|
||||
}
|
||||
|
||||
export namespace window {
|
||||
|
||||
/**
|
||||
* Create a new [TreeView](#TreeView) instance.
|
||||
* Create a new explorer view.
|
||||
*
|
||||
* @param viewId A unique id that identifies the view.
|
||||
* @param provider A [TreeDataProvider](#TreeDataProvider).
|
||||
* @return An instance of [TreeView](#TreeView).
|
||||
* @param id View id.
|
||||
* @param name View name.
|
||||
* @param dataProvider A [TreeDataProvider](#TreeDataProvider).
|
||||
* @return An instance of [View](#View).
|
||||
*/
|
||||
export function createTreeView<T>(viewId: string, provider: TreeDataProvider<T>): TreeView<T>;
|
||||
export function createExplorerView<T>(id: string, name: string, dataProvider: TreeDataProvider<T>): View<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* An source control is able to provide [resource states](#SourceControlResourceState)
|
||||
* to the editor and interact with the editor in several source control related ways.
|
||||
* A view to interact with nodes
|
||||
*/
|
||||
export interface TreeView<T> {
|
||||
export interface View<T> {
|
||||
|
||||
/**
|
||||
* Refresh the given nodes
|
||||
|
@ -610,6 +602,14 @@ declare module 'vscode' {
|
|||
*/
|
||||
getHasChildren?(node: T): boolean;
|
||||
|
||||
/**
|
||||
* Provider a context key to be set for the node. This can be used to describe actions for each node.
|
||||
*
|
||||
* @param node The node from which the provider computes context key.
|
||||
* @return A context key.
|
||||
*/
|
||||
getContextKey?(node: T): string;
|
||||
|
||||
/**
|
||||
* Get the command to execute when `node` is clicked.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче