mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-27 01:25:36 -05:00
add samples (#920)
This commit is contained in:
5
samples/extensionSamples/src/constants.ts
Normal file
5
samples/extensionSamples/src/constants.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
// CONFIG VALUES ///////////////////////////////////////////////////////////
|
||||
export const extensionConfigSectionName = 'extensionSamples';
|
||||
export const configLogDebugInfo = 'logDebugInfo';
|
||||
16
samples/extensionSamples/src/controllers/button.html
Normal file
16
samples/extensionSamples/src/controllers/button.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<header>
|
||||
</header>
|
||||
<body>
|
||||
<button onclick="count()">Count</button>
|
||||
<button onclick="openFlyout()">Open Flyout</button>
|
||||
<script>
|
||||
function count() {
|
||||
parent.postMessage('count', '*');
|
||||
}
|
||||
function openFlyout() {
|
||||
parent.postMessage('openFlyout', '*');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
25
samples/extensionSamples/src/controllers/controllerBase.ts
Normal file
25
samples/extensionSamples/src/controllers/controllerBase.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export default abstract class ControllerBase implements vscode.Disposable {
|
||||
protected _context: vscode.ExtensionContext;
|
||||
|
||||
public constructor(context: vscode.ExtensionContext) {
|
||||
this._context = context;
|
||||
}
|
||||
|
||||
abstract activate(): Promise<boolean>;
|
||||
|
||||
abstract deactivate(): void;
|
||||
|
||||
public dispose(): void {
|
||||
this.deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
15
samples/extensionSamples/src/controllers/counter.html
Normal file
15
samples/extensionSamples/src/controllers/counter.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<html>
|
||||
<header>
|
||||
|
||||
</header>
|
||||
<body>
|
||||
<div id="output">Total Counts: 0</div>
|
||||
<script>
|
||||
let output = document.getElementById('output');
|
||||
window.addEventListener("message", receiveMessage, false);
|
||||
function receiveMessage(e) {
|
||||
output.innerText = 'Total Counts: ' + e.data;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
61
samples/extensionSamples/src/controllers/mainController.ts
Normal file
61
samples/extensionSamples/src/controllers/mainController.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as Utils from '../utils';
|
||||
import ControllerBase from './controllerBase';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
/**
|
||||
* The main controller class that initializes the extension
|
||||
*/
|
||||
export default class MainController extends ControllerBase {
|
||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||
/**
|
||||
* Deactivates the extension
|
||||
*/
|
||||
public deactivate(): void {
|
||||
Utils.logDebug('Main controller deactivated');
|
||||
}
|
||||
|
||||
public activate(): Promise<boolean> {
|
||||
const webviewExampleHtml = fs.readFileSync(path.join(__dirname, 'webviewExample.html')).toString();
|
||||
const buttonHtml = fs.readFileSync(path.join(__dirname, 'button.html')).toString();
|
||||
const counterHtml = fs.readFileSync(path.join(__dirname, 'counter.html')).toString();
|
||||
|
||||
let countWidget: sqlops.DashboardWebview;
|
||||
let buttonWidget: sqlops.DashboardWebview;
|
||||
let count = 0;
|
||||
|
||||
let dialog: sqlops.ModalDialog = sqlops.window.createDialog('Flyout extension');
|
||||
dialog.html = '<div>This is a flyout extension.</div>';
|
||||
|
||||
sqlops.dashboard.registerWebviewProvider('webview-count', e => {
|
||||
e.html = counterHtml;
|
||||
countWidget = e;
|
||||
});
|
||||
sqlops.dashboard.registerWebviewProvider('webview-button', e => {
|
||||
e.html = buttonHtml;
|
||||
buttonWidget = e;
|
||||
e.onMessage(event => {
|
||||
if (event === 'openFlyout') {
|
||||
dialog.open();
|
||||
} else {
|
||||
count++;
|
||||
countWidget.postMessage(count);
|
||||
}
|
||||
});
|
||||
});
|
||||
sqlops.dashboard.registerWebviewProvider('webviewExample', e => {
|
||||
e.html = webviewExampleHtml;
|
||||
});
|
||||
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
19
samples/extensionSamples/src/controllers/webviewExample.html
Normal file
19
samples/extensionSamples/src/controllers/webviewExample.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<html>
|
||||
<header>
|
||||
<style>
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: skyblue;
|
||||
}
|
||||
</style>
|
||||
</header>
|
||||
<body>
|
||||
Hello :)
|
||||
</body>
|
||||
</html>
|
||||
39
samples/extensionSamples/src/extension.ts
Normal file
39
samples/extensionSamples/src/extension.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import ControllerBase from './controllers/controllerBase';
|
||||
import MainController from './controllers/mainController';
|
||||
|
||||
let controllers: ControllerBase[] = [];
|
||||
|
||||
export function activate(context: vscode.ExtensionContext): Promise<boolean> {
|
||||
let activations: Promise<boolean>[] = [];
|
||||
|
||||
// Start the main controller
|
||||
let mainController = new MainController(context);
|
||||
controllers.push(mainController);
|
||||
context.subscriptions.push(mainController);
|
||||
activations.push(mainController.activate());
|
||||
|
||||
return Promise.all(activations)
|
||||
.then((results: boolean[]) => {
|
||||
for (let result of results) {
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function deactivate(): void {
|
||||
for (let controller of controllers) {
|
||||
controller.deactivate();
|
||||
}
|
||||
}
|
||||
5
samples/extensionSamples/src/localizedConstants.ts
Normal file
5
samples/extensionSamples/src/localizedConstants.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
// TODO: localize!
|
||||
|
||||
export const msgErrorLoadingTab = 'An error occurred while loading the tab.';
|
||||
1
samples/extensionSamples/src/media/file.svg
Normal file
1
samples/extensionSamples/src/media/file.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#231f20;}.cls-2{fill:#212121;}</style></defs><title>file_16x16</title><polygon class="cls-1" points="13.59 2.21 13.58 2.22 13.58 2.2 13.59 2.21"/><path class="cls-2" d="M8.71,0,14,5.29V16H2V0ZM3,15H13V6H8V1H3ZM9,1.71V5h3.29Z"/></svg>
|
||||
|
After Width: | Height: | Size: 351 B |
1
samples/extensionSamples/src/media/file_inverse.svg
Normal file
1
samples/extensionSamples/src/media/file_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>file_inverse_16x16</title><polygon class="cls-1" points="13.59 2.21 13.58 2.22 13.58 2.2 13.59 2.21"/><path class="cls-1" d="M8.71,0,14,5.29V16H2V0ZM3,15H13V6H8V1H3ZM9,1.71V5h3.29Z"/></svg>
|
||||
|
After Width: | Height: | Size: 335 B |
39
samples/extensionSamples/src/sql/qds.sql
Normal file
39
samples/extensionSamples/src/sql/qds.sql
Normal file
@@ -0,0 +1,39 @@
|
||||
declare @qds_status int = (SELECT actual_state
|
||||
FROM sys.database_query_store_options)
|
||||
if @qds_status > 0
|
||||
Begin
|
||||
WITH SlowestQry AS(
|
||||
SELECT TOP 5
|
||||
q.query_id,
|
||||
MAX(rs.max_duration ) max_duration
|
||||
FROM sys.query_store_query_text AS qt
|
||||
JOIN sys.query_store_query AS q
|
||||
ON qt.query_text_id = q.query_text_id
|
||||
JOIN sys.query_store_plan AS p
|
||||
ON q.query_id = p.query_id
|
||||
JOIN sys.query_store_runtime_stats AS rs
|
||||
ON p.plan_id = rs.plan_id
|
||||
WHERE rs.last_execution_time > DATEADD(week, -1, GETUTCDATE())
|
||||
AND is_internal_query = 0
|
||||
GROUP BY q.query_id
|
||||
ORDER BY MAX(rs.max_duration ) DESC)
|
||||
SELECT
|
||||
q.query_id,
|
||||
format(rs.last_execution_time,'yyyy-MM-dd hh:mm:ss') as [last_execution_time],
|
||||
rs.max_duration,
|
||||
p.plan_id
|
||||
FROM sys.query_store_query_text AS qt
|
||||
JOIN sys.query_store_query AS q
|
||||
ON qt.query_text_id = q.query_text_id
|
||||
JOIN sys.query_store_plan AS p
|
||||
ON q.query_id = p.query_id
|
||||
JOIN sys.query_store_runtime_stats AS rs
|
||||
ON p.plan_id = rs.plan_id
|
||||
JOIN SlowestQry tq
|
||||
ON tq.query_id = q.query_id
|
||||
WHERE rs.last_execution_time > DATEADD(week, -1, GETUTCDATE())
|
||||
AND is_internal_query = 0
|
||||
order by format(rs.last_execution_time,'yyyy-MM-dd hh:mm:ss')
|
||||
END
|
||||
else
|
||||
select 0 as [query_id], getdate() as [QDS is not enabled], 0 as [max_duration]
|
||||
45
samples/extensionSamples/src/utils.ts
Normal file
45
samples/extensionSamples/src/utils.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
'use strict';
|
||||
|
||||
import * as fs from 'fs-extra';
|
||||
import * as handlebars from 'handlebars';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import * as Constants from './constants';
|
||||
import * as LocalizedConstants from './localizedConstants';
|
||||
|
||||
/**
|
||||
* Helper to log messages to the developer console if enabled
|
||||
* @param msg Message to log to the console
|
||||
*/
|
||||
export function logDebug(msg: any): void {
|
||||
let config = vscode.workspace.getConfiguration(Constants.extensionConfigSectionName);
|
||||
let logDebugInfo = config[Constants.configLogDebugInfo];
|
||||
if (logDebugInfo === true) {
|
||||
let currentTime = new Date().toLocaleTimeString();
|
||||
let outputMsg = '[' + currentTime + ']: ' + msg ? msg.toString() : '';
|
||||
console.log(outputMsg);
|
||||
}
|
||||
}
|
||||
|
||||
export function renderTemplateHtml(extensionPath: string, templateName: string, templateValues: object): Thenable<string> {
|
||||
let templatePath = path.join(extensionPath, 'resources', templateName);
|
||||
|
||||
// 1) Read the template from the disk
|
||||
// 2) Compile it as a handlebars template and render the HTML
|
||||
// 3) On failure, return a simple string as an error
|
||||
return fs.readFile(templatePath, 'utf-8')
|
||||
.then(templateText => {
|
||||
let template = handlebars.compile(templateText);
|
||||
return template(templateValues);
|
||||
})
|
||||
.then(
|
||||
undefined,
|
||||
error => {
|
||||
logDebug(error);
|
||||
return LocalizedConstants.msgErrorLoadingTab;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user