SQL Operations Studio Public Preview 1 (0.23) release source code

This commit is contained in:
Karl Burtram
2017-11-09 14:30:27 -08:00
parent b88ecb8d93
commit 3cdac41339
8829 changed files with 759707 additions and 286 deletions

View File

@@ -0,0 +1,300 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
import { IContextKey, IContext, IContextKeyServiceTarget, IContextKeyService, SET_CONTEXT_COMMAND_ID, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import Event, { Emitter, debounceEvent } from 'vs/base/common/event';
const KEYBINDING_CONTEXT_ATTR = 'data-keybinding-context';
export class Context implements IContext {
protected _parent: Context;
protected _value: { [key: string]: any; };
protected _id: number;
constructor(id: number, parent: Context) {
this._id = id;
this._parent = parent;
this._value = Object.create(null);
this._value['_contextId'] = id;
}
public setValue(key: string, value: any): boolean {
// console.log('SET ' + key + ' = ' + value + ' ON ' + this._id);
if (this._value[key] !== value) {
this._value[key] = value;
return true;
}
return false;
}
public removeValue(key: string): boolean {
// console.log('REMOVE ' + key + ' FROM ' + this._id);
return delete this._value[key];
}
public getValue<T>(key: string): T {
const ret = this._value[key];
if (typeof ret === 'undefined' && this._parent) {
return this._parent.getValue<T>(key);
}
return ret;
}
}
class ConfigAwareContextValuesContainer extends Context {
private _emitter: Emitter<string>;
private _subscription: IDisposable;
constructor(id: number, configurationService: IConfigurationService, emitter: Emitter<string>) {
super(id, null);
this._emitter = emitter;
this._subscription = configurationService.onDidUpdateConfiguration(e => this._updateConfigurationContext(configurationService.getConfiguration()));
this._updateConfigurationContext(configurationService.getConfiguration());
}
public dispose() {
this._subscription.dispose();
}
private _updateConfigurationContext(config: any) {
// remove old config.xyz values
for (let key in this._value) {
if (key.indexOf('config.') === 0) {
delete this._value[key];
}
}
// add new value from config
const walk = (obj: any, keys: string[]) => {
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
keys.push(key);
let value = obj[key];
if (typeof value === 'boolean') {
const configKey = keys.join('.');
this._value[configKey] = value;
this._emitter.fire(configKey);
} else if (typeof value === 'object') {
walk(value, keys);
}
keys.pop();
}
}
};
walk(config, ['config']);
}
}
class ContextKey<T> implements IContextKey<T> {
private _parent: AbstractContextKeyService;
private _key: string;
private _defaultValue: T;
constructor(parent: AbstractContextKeyService, key: string, defaultValue: T) {
this._parent = parent;
this._key = key;
this._defaultValue = defaultValue;
this.reset();
}
public set(value: T): void {
this._parent.setContext(this._key, value);
}
public reset(): void {
if (typeof this._defaultValue === 'undefined') {
this._parent.removeContext(this._key);
} else {
this._parent.setContext(this._key, this._defaultValue);
}
}
public get(): T {
return this._parent.getContextKeyValue<T>(this._key);
}
}
export abstract class AbstractContextKeyService implements IContextKeyService {
public _serviceBrand: any;
protected _onDidChangeContext: Event<string[]>;
protected _onDidChangeContextKey: Emitter<string>;
protected _myContextId: number;
constructor(myContextId: number) {
this._myContextId = myContextId;
this._onDidChangeContextKey = new Emitter<string>();
}
abstract dispose(): void;
public createKey<T>(key: string, defaultValue: T): IContextKey<T> {
return new ContextKey(this, key, defaultValue);
}
public get onDidChangeContext(): Event<string[]> {
if (!this._onDidChangeContext) {
this._onDidChangeContext = debounceEvent(this._onDidChangeContextKey.event, (prev: string[], cur) => {
if (!prev) {
prev = [cur];
} else if (prev.indexOf(cur) < 0) {
prev.push(cur);
}
return prev;
}, 25);
}
return this._onDidChangeContext;
}
public createScoped(domNode: IContextKeyServiceTarget): IContextKeyService {
return new ScopedContextKeyService(this, this._onDidChangeContextKey, domNode);
}
public contextMatchesRules(rules: ContextKeyExpr): boolean {
const context = this.getContextValuesContainer(this._myContextId);
const result = KeybindingResolver.contextMatchesRules(context, rules);
// console.group(rules.serialize() + ' -> ' + result);
// rules.keys().forEach(key => { console.log(key, ctx[key]); });
// console.groupEnd();
return result;
}
public getContextKeyValue<T>(key: string): T {
return this.getContextValuesContainer(this._myContextId).getValue<T>(key);
}
public setContext(key: string, value: any): void {
if (this.getContextValuesContainer(this._myContextId).setValue(key, value)) {
this._onDidChangeContextKey.fire(key);
}
}
public removeContext(key: string): void {
if (this.getContextValuesContainer(this._myContextId).removeValue(key)) {
this._onDidChangeContextKey.fire(key);
}
}
public getContext(target: IContextKeyServiceTarget): IContext {
return this.getContextValuesContainer(findContextAttr(target));
}
public abstract getContextValuesContainer(contextId: number): Context;
public abstract createChildContext(parentContextId?: number): number;
public abstract disposeContext(contextId: number): void;
}
export class ContextKeyService extends AbstractContextKeyService implements IContextKeyService {
private _lastContextId: number;
private _contexts: {
[contextId: string]: Context;
};
private _toDispose: IDisposable[] = [];
constructor( @IConfigurationService configurationService: IConfigurationService) {
super(0);
this._lastContextId = 0;
this._contexts = Object.create(null);
const myContext = new ConfigAwareContextValuesContainer(this._myContextId, configurationService, this._onDidChangeContextKey);
this._contexts[String(this._myContextId)] = myContext;
this._toDispose.push(myContext);
// Uncomment this to see the contexts continuously logged
// let lastLoggedValue: string = null;
// setInterval(() => {
// let values = Object.keys(this._contexts).map((key) => this._contexts[key]);
// let logValue = values.map(v => JSON.stringify(v._value, null, '\t')).join('\n');
// if (lastLoggedValue !== logValue) {
// lastLoggedValue = logValue;
// console.log(lastLoggedValue);
// }
// }, 2000);
}
public dispose(): void {
this._toDispose = dispose(this._toDispose);
}
public getContextValuesContainer(contextId: number): Context {
return this._contexts[String(contextId)];
}
public createChildContext(parentContextId: number = this._myContextId): number {
let id = (++this._lastContextId);
this._contexts[String(id)] = new Context(id, this.getContextValuesContainer(parentContextId));
return id;
}
public disposeContext(contextId: number): void {
delete this._contexts[String(contextId)];
}
}
class ScopedContextKeyService extends AbstractContextKeyService {
private _parent: AbstractContextKeyService;
private _domNode: IContextKeyServiceTarget;
constructor(parent: AbstractContextKeyService, emitter: Emitter<string>, domNode?: IContextKeyServiceTarget) {
super(parent.createChildContext());
this._parent = parent;
this._onDidChangeContextKey = emitter;
if (domNode) {
this._domNode = domNode;
this._domNode.setAttribute(KEYBINDING_CONTEXT_ATTR, String(this._myContextId));
}
}
public dispose(): void {
this._parent.disposeContext(this._myContextId);
if (this._domNode) {
this._domNode.removeAttribute(KEYBINDING_CONTEXT_ATTR);
}
}
public get onDidChangeContext(): Event<string[]> {
return this._parent.onDidChangeContext;
}
public getContextValuesContainer(contextId: number): Context {
return this._parent.getContextValuesContainer(contextId);
}
public createChildContext(parentContextId: number = this._myContextId): number {
return this._parent.createChildContext(parentContextId);
}
public disposeContext(contextId: number): void {
this._parent.disposeContext(contextId);
}
}
function findContextAttr(domNode: IContextKeyServiceTarget): number {
while (domNode) {
if (domNode.hasAttribute(KEYBINDING_CONTEXT_ATTR)) {
return parseInt(domNode.getAttribute(KEYBINDING_CONTEXT_ATTR), 10);
}
domNode = domNode.parentElement;
}
return 0;
}
CommandsRegistry.registerCommand(SET_CONTEXT_COMMAND_ID, function (accessor, contextKey: any, contextValue: any) {
accessor.get(IContextKeyService).createKey(String(contextKey), contextValue);
});

View File

@@ -0,0 +1,477 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import Event from 'vs/base/common/event';
export enum ContextKeyExprType {
Defined = 1,
Not = 2,
Equals = 3,
NotEquals = 4,
And = 5
}
export abstract class ContextKeyExpr {
public static has(key: string): ContextKeyExpr {
return new ContextKeyDefinedExpr(key);
}
public static equals(key: string, value: any): ContextKeyExpr {
return new ContextKeyEqualsExpr(key, value);
}
public static notEquals(key: string, value: any): ContextKeyExpr {
return new ContextKeyNotEqualsExpr(key, value);
}
public static not(key: string): ContextKeyExpr {
return new ContextKeyNotExpr(key);
}
public static and(...expr: ContextKeyExpr[]): ContextKeyExpr {
return new ContextKeyAndExpr(expr);
}
public static deserialize(serialized: string): ContextKeyExpr {
if (!serialized) {
return null;
}
let pieces = serialized.split('&&');
let result = new ContextKeyAndExpr(pieces.map(p => this._deserializeOne(p)));
return result.normalize();
}
private static _deserializeOne(serializedOne: string): ContextKeyExpr {
serializedOne = serializedOne.trim();
if (serializedOne.indexOf('!=') >= 0) {
let pieces = serializedOne.split('!=');
return new ContextKeyNotEqualsExpr(pieces[0].trim(), this._deserializeValue(pieces[1]));
}
if (serializedOne.indexOf('==') >= 0) {
let pieces = serializedOne.split('==');
return new ContextKeyEqualsExpr(pieces[0].trim(), this._deserializeValue(pieces[1]));
}
if (/^\!\s*/.test(serializedOne)) {
return new ContextKeyNotExpr(serializedOne.substr(1).trim());
}
return new ContextKeyDefinedExpr(serializedOne);
}
private static _deserializeValue(serializedValue: string): any {
serializedValue = serializedValue.trim();
if (serializedValue === 'true') {
return true;
}
if (serializedValue === 'false') {
return false;
}
let m = /^'([^']*)'$/.exec(serializedValue);
if (m) {
return m[1].trim();
}
return serializedValue;
}
public abstract getType(): ContextKeyExprType;
public abstract equals(other: ContextKeyExpr): boolean;
public abstract evaluate(context: IContext): boolean;
public abstract normalize(): ContextKeyExpr;
public abstract serialize(): string;
public abstract keys(): string[];
}
function cmp(a: ContextKeyExpr, b: ContextKeyExpr): number {
let aType = a.getType();
let bType = b.getType();
if (aType !== bType) {
return aType - bType;
}
switch (aType) {
case ContextKeyExprType.Defined:
return (<ContextKeyDefinedExpr>a).cmp(<ContextKeyDefinedExpr>b);
case ContextKeyExprType.Not:
return (<ContextKeyNotExpr>a).cmp(<ContextKeyNotExpr>b);
case ContextKeyExprType.Equals:
return (<ContextKeyEqualsExpr>a).cmp(<ContextKeyEqualsExpr>b);
case ContextKeyExprType.NotEquals:
return (<ContextKeyNotEqualsExpr>a).cmp(<ContextKeyNotEqualsExpr>b);
default:
throw new Error('Unknown ContextKeyExpr!');
}
}
export class ContextKeyDefinedExpr implements ContextKeyExpr {
constructor(protected key: string) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.Defined;
}
public cmp(other: ContextKeyDefinedExpr): number {
if (this.key < other.key) {
return -1;
}
if (this.key > other.key) {
return 1;
}
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyDefinedExpr) {
return (this.key === other.key);
}
return false;
}
public evaluate(context: IContext): boolean {
return (!!context.getValue(this.key));
}
public normalize(): ContextKeyExpr {
return this;
}
public serialize(): string {
return this.key;
}
public keys(): string[] {
return [this.key];
}
}
export class ContextKeyEqualsExpr implements ContextKeyExpr {
constructor(private key: string, private value: any) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.Equals;
}
public cmp(other: ContextKeyEqualsExpr): number {
if (this.key < other.key) {
return -1;
}
if (this.key > other.key) {
return 1;
}
if (this.value < other.value) {
return -1;
}
if (this.value > other.value) {
return 1;
}
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyEqualsExpr) {
return (this.key === other.key && this.value === other.value);
}
return false;
}
public evaluate(context: IContext): boolean {
/* tslint:disable:triple-equals */
// Intentional ==
return (context.getValue(this.key) == this.value);
/* tslint:enable:triple-equals */
}
public normalize(): ContextKeyExpr {
if (typeof this.value === 'boolean') {
if (this.value) {
return new ContextKeyDefinedExpr(this.key);
}
return new ContextKeyNotExpr(this.key);
}
return this;
}
public serialize(): string {
if (typeof this.value === 'boolean') {
return this.normalize().serialize();
}
return this.key + ' == \'' + this.value + '\'';
}
public keys(): string[] {
return [this.key];
}
}
export class ContextKeyNotEqualsExpr implements ContextKeyExpr {
constructor(private key: string, private value: any) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.NotEquals;
}
public cmp(other: ContextKeyNotEqualsExpr): number {
if (this.key < other.key) {
return -1;
}
if (this.key > other.key) {
return 1;
}
if (this.value < other.value) {
return -1;
}
if (this.value > other.value) {
return 1;
}
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyNotEqualsExpr) {
return (this.key === other.key && this.value === other.value);
}
return false;
}
public evaluate(context: IContext): boolean {
/* tslint:disable:triple-equals */
// Intentional !=
return (context.getValue(this.key) != this.value);
/* tslint:enable:triple-equals */
}
public normalize(): ContextKeyExpr {
if (typeof this.value === 'boolean') {
if (this.value) {
return new ContextKeyNotExpr(this.key);
}
return new ContextKeyDefinedExpr(this.key);
}
return this;
}
public serialize(): string {
if (typeof this.value === 'boolean') {
return this.normalize().serialize();
}
return this.key + ' != \'' + this.value + '\'';
}
public keys(): string[] {
return [this.key];
}
}
export class ContextKeyNotExpr implements ContextKeyExpr {
constructor(private key: string) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.Not;
}
public cmp(other: ContextKeyNotExpr): number {
if (this.key < other.key) {
return -1;
}
if (this.key > other.key) {
return 1;
}
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyNotExpr) {
return (this.key === other.key);
}
return false;
}
public evaluate(context: IContext): boolean {
return (!context.getValue(this.key));
}
public normalize(): ContextKeyExpr {
return this;
}
public serialize(): string {
return '!' + this.key;
}
public keys(): string[] {
return [this.key];
}
}
export class ContextKeyAndExpr implements ContextKeyExpr {
private expr: ContextKeyExpr[];
constructor(expr: ContextKeyExpr[]) {
this.expr = ContextKeyAndExpr._normalizeArr(expr);
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.And;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyAndExpr) {
if (this.expr.length !== other.expr.length) {
return false;
}
for (let i = 0, len = this.expr.length; i < len; i++) {
if (!this.expr[i].equals(other.expr[i])) {
return false;
}
}
return true;
}
return false;
}
public evaluate(context: IContext): boolean {
for (let i = 0, len = this.expr.length; i < len; i++) {
if (!this.expr[i].evaluate(context)) {
return false;
}
}
return true;
}
private static _normalizeArr(arr: ContextKeyExpr[]): ContextKeyExpr[] {
let expr: ContextKeyExpr[] = [];
if (arr) {
for (let i = 0, len = arr.length; i < len; i++) {
let e = arr[i];
if (!e) {
continue;
}
e = e.normalize();
if (!e) {
continue;
}
if (e instanceof ContextKeyAndExpr) {
expr = expr.concat(e.expr);
continue;
}
expr.push(e);
}
expr.sort(cmp);
}
return expr;
}
public normalize(): ContextKeyExpr {
if (this.expr.length === 0) {
return null;
}
if (this.expr.length === 1) {
return this.expr[0];
}
return this;
}
public serialize(): string {
if (this.expr.length === 0) {
return '';
}
if (this.expr.length === 1) {
return this.normalize().serialize();
}
return this.expr.map(e => e.serialize()).join(' && ');
}
public keys(): string[] {
const result: string[] = [];
for (let expr of this.expr) {
result.push(...expr.keys());
}
return result;
}
}
export class RawContextKey<T> extends ContextKeyDefinedExpr {
private _defaultValue: T;
constructor(key: string, defaultValue: T) {
super(key);
this._defaultValue = defaultValue;
}
public bindTo(target: IContextKeyService): IContextKey<T> {
return target.createKey(this.key, this._defaultValue);
}
public getValue(target: IContextKeyService): T {
return target.getContextKeyValue<T>(this.key);
}
public toNegated(): ContextKeyExpr {
return ContextKeyExpr.not(this.key);
}
public isEqualTo(value: string): ContextKeyExpr {
return ContextKeyExpr.equals(this.key, value);
}
}
export interface IContext {
getValue<T>(key: string): T;
}
export interface IContextKey<T> {
set(value: T): void;
reset(): void;
get(): T;
}
export interface IContextKeyServiceTarget {
parentElement: IContextKeyServiceTarget;
setAttribute(attr: string, value: string): void;
removeAttribute(attr: string): void;
hasAttribute(attr: string): boolean;
getAttribute(attr: string): string;
}
export const IContextKeyService = createDecorator<IContextKeyService>('contextKeyService');
export interface IContextKeyService {
_serviceBrand: any;
dispose(): void;
onDidChangeContext: Event<string[]>;
createKey<T>(key: string, defaultValue: T): IContextKey<T>;
contextMatchesRules(rules: ContextKeyExpr): boolean;
getContextKeyValue<T>(key: string): T;
createScoped(target?: IContextKeyServiceTarget): IContextKeyService;
getContext(target: IContextKeyServiceTarget): IContext;
}
export const SET_CONTEXT_COMMAND_ID = 'setContext';

View File

@@ -0,0 +1,89 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
function createContext(ctx: any) {
return {
getValue: (key: string) => {
return ctx[key];
}
};
}
suite('ContextKeyExpr', () => {
test('ContextKeyExpr.equals', function () {
let a = ContextKeyExpr.and(
ContextKeyExpr.has('a1'),
ContextKeyExpr.and(ContextKeyExpr.has('and.a')),
ContextKeyExpr.has('a2'),
ContextKeyExpr.equals('b1', 'bb1'),
ContextKeyExpr.equals('b2', 'bb2'),
ContextKeyExpr.notEquals('c1', 'cc1'),
ContextKeyExpr.notEquals('c2', 'cc2'),
ContextKeyExpr.not('d1'),
ContextKeyExpr.not('d2')
);
let b = ContextKeyExpr.and(
ContextKeyExpr.equals('b2', 'bb2'),
ContextKeyExpr.notEquals('c1', 'cc1'),
ContextKeyExpr.not('d1'),
ContextKeyExpr.notEquals('c2', 'cc2'),
ContextKeyExpr.has('a2'),
ContextKeyExpr.equals('b1', 'bb1'),
ContextKeyExpr.has('a1'),
ContextKeyExpr.and(ContextKeyExpr.equals('and.a', true)),
ContextKeyExpr.not('d2')
);
assert(a.equals(b), 'expressions should be equal');
});
test('normalize', function () {
let key1IsTrue = ContextKeyExpr.equals('key1', true);
let key1IsNotFalse = ContextKeyExpr.notEquals('key1', false);
let key1IsFalse = ContextKeyExpr.equals('key1', false);
let key1IsNotTrue = ContextKeyExpr.notEquals('key1', true);
assert.ok(key1IsTrue.normalize().equals(ContextKeyExpr.has('key1')));
assert.ok(key1IsNotFalse.normalize().equals(ContextKeyExpr.has('key1')));
assert.ok(key1IsFalse.normalize().equals(ContextKeyExpr.not('key1')));
assert.ok(key1IsNotTrue.normalize().equals(ContextKeyExpr.not('key1')));
});
test('evaluate', function () {
/* tslint:disable:triple-equals */
let context = createContext({
'a': true,
'b': false,
'c': '5'
});
function testExpression(expr: string, expected: boolean): void {
let rules = ContextKeyExpr.deserialize(expr);
assert.equal(rules.evaluate(context), expected, expr);
}
function testBatch(expr: string, value: any): void {
testExpression(expr, !!value);
testExpression(expr + ' == true', !!value);
testExpression(expr + ' != true', !value);
testExpression(expr + ' == false', !value);
testExpression(expr + ' != false', !!value);
testExpression(expr + ' == 5', value == <any>'5');
testExpression(expr + ' != 5', value != <any>'5');
testExpression('!' + expr, !value);
}
testBatch('a', true);
testBatch('b', false);
testBatch('c', '5');
testBatch('z', undefined);
testExpression('a && !b', true && !false);
testExpression('a && b', true && false);
testExpression('a && !b && c == 5', true && !false && '5' == '5');
/* tslint:enable:triple-equals */
});
});