Refactor DocumentClientUtilityBase to not be a class (#115)

This commit is contained in:
Steve Faulkner
2020-07-27 12:58:27 -05:00
committed by GitHub
parent 6d142f16f9
commit 2e49ed45c3
48 changed files with 1567 additions and 1754 deletions

View File

@@ -33,6 +33,15 @@ import Trigger from "./Trigger";
import UserDefinedFunction from "./UserDefinedFunction";
import { config } from "../../Config";
import Explorer from "../Explorer";
import {
createDocument,
readTriggers,
readUserDefinedFunctions,
readStoredProcedures,
readCollectionQuotaInfo,
readOffer,
readOffers
} from "../../Common/DocumentClientUtilityBase";
export default class Collection implements ViewModels.Collection {
public nodeKind: string;
@@ -306,7 +315,6 @@ export default class Collection implements ViewModels.Collection {
documentIds: ko.observableArray<DocumentId>([]),
tabKind: ViewModels.CollectionTabKind.Documents,
title: "Items",
documentClientUtility: this.container.documentClientUtility,
selfLink: this.self,
isActive: ko.observable<boolean>(false),
@@ -358,7 +366,6 @@ export default class Collection implements ViewModels.Collection {
conflictIds: ko.observableArray<ConflictId>([]),
tabKind: ViewModels.CollectionTabKind.Conflicts,
title: "Conflicts",
documentClientUtility: this.container.documentClientUtility,
selfLink: this.self,
isActive: ko.observable<boolean>(false),
@@ -419,7 +426,7 @@ export default class Collection implements ViewModels.Collection {
tabKind: ViewModels.CollectionTabKind.QueryTables,
title: title,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
node: this,
@@ -472,7 +479,7 @@ export default class Collection implements ViewModels.Collection {
node: this,
title: title,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
selfLink: this.self,
masterKey: CosmosClient.masterKey() || "",
@@ -527,7 +534,7 @@ export default class Collection implements ViewModels.Collection {
tabKind: ViewModels.CollectionTabKind.Documents,
title: "Documents",
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
node: this,
@@ -580,7 +587,7 @@ export default class Collection implements ViewModels.Collection {
tabKind: ViewModels.CollectionTabKind.Settings,
title: !this.offer() ? "Settings" : "Scale & Settings",
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
node: this,
selfLink: this.self,
@@ -645,10 +652,8 @@ export default class Collection implements ViewModels.Collection {
defaultExperience: this.container.defaultExperience()
});
// TODO: Use the collection entity cache to get quota info
const quotaInfoPromise: Q.Promise<DataModels.CollectionQuotaInfo> = this.container.documentClientUtility.readCollectionQuotaInfo(
this
);
const offerInfoPromise: Q.Promise<DataModels.Offer[]> = this.container.documentClientUtility.readOffers();
const quotaInfoPromise: Q.Promise<DataModels.CollectionQuotaInfo> = readCollectionQuotaInfo(this);
const offerInfoPromise: Q.Promise<DataModels.Offer[]> = readOffers();
Q.all([quotaInfoPromise, offerInfoPromise]).then(
() => {
this.container.isRefreshingExplorer(false);
@@ -675,41 +680,39 @@ export default class Collection implements ViewModels.Collection {
return;
}
this.container.documentClientUtility
.readOffer(collectionOffer)
.then((offerDetail: DataModels.OfferWithHeaders) => {
if (OfferUtils.isNotOfferV1(collectionOffer)) {
const offerThroughputInfo: DataModels.OfferThroughputInfo = {
minimumRUForCollection:
offerDetail.content &&
offerDetail.content.collectionThroughputInfo &&
offerDetail.content.collectionThroughputInfo.minimumRUForCollection,
numPhysicalPartitions:
offerDetail.content &&
offerDetail.content.collectionThroughputInfo &&
offerDetail.content.collectionThroughputInfo.numPhysicalPartitions
};
readOffer(collectionOffer).then((offerDetail: DataModels.OfferWithHeaders) => {
if (OfferUtils.isNotOfferV1(collectionOffer)) {
const offerThroughputInfo: DataModels.OfferThroughputInfo = {
minimumRUForCollection:
offerDetail.content &&
offerDetail.content.collectionThroughputInfo &&
offerDetail.content.collectionThroughputInfo.minimumRUForCollection,
numPhysicalPartitions:
offerDetail.content &&
offerDetail.content.collectionThroughputInfo &&
offerDetail.content.collectionThroughputInfo.numPhysicalPartitions
};
collectionOffer.content.collectionThroughputInfo = offerThroughputInfo;
}
collectionOffer.content.collectionThroughputInfo = offerThroughputInfo;
}
(collectionOffer as DataModels.OfferWithHeaders).headers = offerDetail.headers;
this.offer(collectionOffer);
this.offer.valueHasMutated();
this.quotaInfo(quotaInfo);
TelemetryProcessor.traceSuccess(
Action.LoadOffers,
{
databaseAccountName: this.container.databaseAccount().name,
databaseName: this.databaseId,
collectionName: this.id(),
defaultExperience: this.container.defaultExperience(),
offerVersion: collectionOffer && collectionOffer.offerVersion
},
startKey
);
deferred.resolve();
});
(collectionOffer as DataModels.OfferWithHeaders).headers = offerDetail.headers;
this.offer(collectionOffer);
this.offer.valueHasMutated();
this.quotaInfo(quotaInfo);
TelemetryProcessor.traceSuccess(
Action.LoadOffers,
{
databaseAccountName: this.container.databaseAccount().name,
databaseName: this.databaseId,
collectionName: this.id(),
defaultExperience: this.container.defaultExperience(),
offerVersion: collectionOffer && collectionOffer.offerVersion
},
startKey
);
deferred.resolve();
});
},
(error: any) => {
this.container.isRefreshingExplorer(false);
@@ -747,7 +750,6 @@ export default class Collection implements ViewModels.Collection {
tabKind: ViewModels.CollectionTabKind.Query,
title: title,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
node: this,
selfLink: this.self,
@@ -780,7 +782,6 @@ export default class Collection implements ViewModels.Collection {
tabKind: ViewModels.CollectionTabKind.Query,
title: title,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
node: this,
selfLink: this.self,
@@ -813,7 +814,6 @@ export default class Collection implements ViewModels.Collection {
node: this,
title: title,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
selfLink: this.self,
masterKey: CosmosClient.masterKey() || "",
@@ -836,7 +836,6 @@ export default class Collection implements ViewModels.Collection {
tabKind: ViewModels.CollectionTabKind.MongoShell,
title: "Shell " + id,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
node: this,
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/mongoShell`,
@@ -1075,40 +1074,34 @@ export default class Collection implements ViewModels.Collection {
}
public loadStoredProcedures(): Q.Promise<any> {
return this.container.documentClientUtility
.readStoredProcedures(this)
.then((storedProcedures: DataModels.StoredProcedure[]) => {
const storedProceduresNodes: ViewModels.TreeNode[] = storedProcedures.map(
storedProcedure => new StoredProcedure(this.container, this, storedProcedure)
);
const otherNodes = this.children().filter(node => node.nodeKind !== "StoredProcedure");
const allNodes = otherNodes.concat(storedProceduresNodes);
this.children(allNodes);
});
return readStoredProcedures(this).then((storedProcedures: DataModels.StoredProcedure[]) => {
const storedProceduresNodes: ViewModels.TreeNode[] = storedProcedures.map(
storedProcedure => new StoredProcedure(this.container, this, storedProcedure)
);
const otherNodes = this.children().filter(node => node.nodeKind !== "StoredProcedure");
const allNodes = otherNodes.concat(storedProceduresNodes);
this.children(allNodes);
});
}
public loadUserDefinedFunctions(): Q.Promise<any> {
return this.container.documentClientUtility
.readUserDefinedFunctions(this)
.then((userDefinedFunctions: DataModels.UserDefinedFunction[]) => {
const userDefinedFunctionsNodes: ViewModels.TreeNode[] = userDefinedFunctions.map(
udf => new UserDefinedFunction(this.container, this, udf)
);
const otherNodes = this.children().filter(node => node.nodeKind !== "UserDefinedFunction");
const allNodes = otherNodes.concat(userDefinedFunctionsNodes);
this.children(allNodes);
});
return readUserDefinedFunctions(this).then((userDefinedFunctions: DataModels.UserDefinedFunction[]) => {
const userDefinedFunctionsNodes: ViewModels.TreeNode[] = userDefinedFunctions.map(
udf => new UserDefinedFunction(this.container, this, udf)
);
const otherNodes = this.children().filter(node => node.nodeKind !== "UserDefinedFunction");
const allNodes = otherNodes.concat(userDefinedFunctionsNodes);
this.children(allNodes);
});
}
public loadTriggers(): Q.Promise<any> {
return this.container.documentClientUtility
.readTriggers(this, null /*options*/)
.then((triggers: DataModels.Trigger[]) => {
const triggerNodes: ViewModels.TreeNode[] = triggers.map(trigger => new Trigger(this.container, this, trigger));
const otherNodes = this.children().filter(node => node.nodeKind !== "Trigger");
const allNodes = otherNodes.concat(triggerNodes);
this.children(allNodes);
});
return readTriggers(this, null /*options*/).then((triggers: DataModels.Trigger[]) => {
const triggerNodes: ViewModels.TreeNode[] = triggers.map(trigger => new Trigger(this.container, this, trigger));
const otherNodes = this.children().filter(node => node.nodeKind !== "Trigger");
const allNodes = otherNodes.concat(triggerNodes);
this.children(allNodes);
});
}
public onDragOver(source: Collection, event: { originalEvent: DragEvent }) {
@@ -1269,7 +1262,7 @@ export default class Collection implements ViewModels.Collection {
const promises: Array<Q.Promise<any>> = [];
const triggerCreateDocument: (documentContent: any) => Q.Promise<any> = (documentContent: any) => {
return this.container.documentClientUtility.createDocument(this, documentContent).then(
return createDocument(this, documentContent).then(
doc => {
record.numSucceeded++;
return Q.resolve();

View File

@@ -6,6 +6,7 @@ import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
import { extractPartitionKey } from "@azure/cosmos";
import ConflictsTab from "../Tabs/ConflictsTab";
import { readDocument } from "../../Common/DocumentClientUtilityBase";
export default class ConflictId implements ViewModels.ConflictId {
public container: ConflictsTab;
@@ -68,33 +69,31 @@ export default class ConflictId implements ViewModels.ConflictId {
}
this.container.loadingConflictData(true);
return conflictsTab.documentClientUtility
.readDocument(this.container.collection, this.buildDocumentIdFromConflict(this.partitionKeyValue))
.then(
(currentDocumentContent: any) => {
this.container.loadingConflictData(false);
if (this.operationType === Constants.ConflictOperationType.Replace) {
this.container.initDocumentEditorForReplace(this, this.content, currentDocumentContent);
} else {
this.container.initDocumentEditorForDelete(this, currentDocumentContent);
}
},
(reason: any) => {
this.container.loadingConflictData(false);
// Document could be deleted
if (
reason &&
reason.code === Constants.HttpStatusCodes.NotFound &&
this.operationType === Constants.ConflictOperationType.Delete
) {
this.container.initDocumentEditorForNoOp(this);
return Q();
}
return Q.reject(reason);
return readDocument(this.container.collection, this.buildDocumentIdFromConflict(this.partitionKeyValue)).then(
(currentDocumentContent: any) => {
this.container.loadingConflictData(false);
if (this.operationType === Constants.ConflictOperationType.Replace) {
this.container.initDocumentEditorForReplace(this, this.content, currentDocumentContent);
} else {
this.container.initDocumentEditorForDelete(this, currentDocumentContent);
}
);
},
(reason: any) => {
this.container.loadingConflictData(false);
// Document could be deleted
if (
reason &&
reason.code === Constants.HttpStatusCodes.NotFound &&
this.operationType === Constants.ConflictOperationType.Delete
) {
this.container.initDocumentEditorForNoOp(this);
return Q();
}
return Q.reject(reason);
}
);
}
public getPartitionKeyValueAsString(): string {

View File

@@ -12,6 +12,7 @@ import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
import * as Logger from "../../Common/Logger";
import Explorer from "../Explorer";
import { readCollections, readOffers, readOffer } from "../../Common/DocumentClientUtilityBase";
export default class Database implements ViewModels.Database {
public nodeKind: string;
@@ -71,7 +72,6 @@ export default class Database implements ViewModels.Database {
tabKind: ViewModels.CollectionTabKind.DatabaseSettings,
title: "Scale",
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
node: this,
rid: this.rid,
database: this,
@@ -137,7 +137,7 @@ export default class Database implements ViewModels.Database {
defaultExperience: this.container.defaultExperience()
});
const offerInfoPromise: Q.Promise<DataModels.Offer[]> = this.container.documentClientUtility.readOffers();
const offerInfoPromise: Q.Promise<DataModels.Offer[]> = readOffers();
Q.all([offerInfoPromise]).then(
() => {
this.container.isRefreshingExplorer(false);
@@ -146,35 +146,33 @@ export default class Database implements ViewModels.Database {
offerInfoPromise.valueOf(),
databaseDataModel
);
this.container.documentClientUtility
.readOffer(databaseOffer)
.then((offerDetail: DataModels.OfferWithHeaders) => {
const offerThroughputInfo: DataModels.OfferThroughputInfo = {
minimumRUForCollection:
offerDetail.content &&
offerDetail.content.collectionThroughputInfo &&
offerDetail.content.collectionThroughputInfo.minimumRUForCollection,
numPhysicalPartitions:
offerDetail.content &&
offerDetail.content.collectionThroughputInfo &&
offerDetail.content.collectionThroughputInfo.numPhysicalPartitions
};
readOffer(databaseOffer).then((offerDetail: DataModels.OfferWithHeaders) => {
const offerThroughputInfo: DataModels.OfferThroughputInfo = {
minimumRUForCollection:
offerDetail.content &&
offerDetail.content.collectionThroughputInfo &&
offerDetail.content.collectionThroughputInfo.minimumRUForCollection,
numPhysicalPartitions:
offerDetail.content &&
offerDetail.content.collectionThroughputInfo &&
offerDetail.content.collectionThroughputInfo.numPhysicalPartitions
};
databaseOffer.content.collectionThroughputInfo = offerThroughputInfo;
(databaseOffer as DataModels.OfferWithHeaders).headers = offerDetail.headers;
this.offer(databaseOffer);
this.offer.valueHasMutated();
databaseOffer.content.collectionThroughputInfo = offerThroughputInfo;
(databaseOffer as DataModels.OfferWithHeaders).headers = offerDetail.headers;
this.offer(databaseOffer);
this.offer.valueHasMutated();
TelemetryProcessor.traceSuccess(
Action.LoadOffers,
{
databaseAccountName: this.container.databaseAccount().name,
defaultExperience: this.container.defaultExperience()
},
startKey
);
deferred.resolve();
});
TelemetryProcessor.traceSuccess(
Action.LoadOffers,
{
databaseAccountName: this.container.databaseAccount().name,
defaultExperience: this.container.defaultExperience()
},
startKey
);
deferred.resolve();
});
},
(error: any) => {
this.container.isRefreshingExplorer(false);
@@ -263,7 +261,7 @@ export default class Database implements ViewModels.Database {
let collectionVMs: Collection[] = [];
let deferred: Q.Deferred<void> = Q.defer<void>();
this.container.documentClientUtility.readCollections(this).then(
readCollections(this).then(
(collections: DataModels.Collection[]) => {
let collectionsToAddVMPromises: Q.Promise<any>[] = [];
let deltaCollections = this.getDeltaCollections(collections);

View File

@@ -91,7 +91,6 @@ export default class ResourceTokenCollection implements ViewModels.CollectionBas
tabKind: ViewModels.CollectionTabKind.Query,
title: title,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this,
node: this,
selfLink: this.self,
@@ -143,8 +142,6 @@ export default class ResourceTokenCollection implements ViewModels.CollectionBas
documentIds: ko.observableArray<DocumentId>([]),
tabKind: ViewModels.CollectionTabKind.Documents,
title: "Items",
documentClientUtility: this.container.documentClientUtility,
selfLink: this.self,
isActive: ko.observable<boolean>(false),
collection: this,

View File

@@ -7,6 +7,7 @@ import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstan
import StoredProcedureTab from "../Tabs/StoredProcedureTab";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import Explorer from "../Explorer";
import { deleteStoredProcedure, executeStoredProcedure } from "../../Common/DocumentClientUtilityBase";
const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE
function sample(prefix) {
@@ -69,7 +70,6 @@ export default class StoredProcedure {
tabKind: ViewModels.CollectionTabKind.StoredProcedures,
title: `New Stored Procedure ${id}`,
tabPath: `${source.databaseId}>${source.id()}>New Stored Procedure ${id}`,
documentClientUtility: source.container.documentClientUtility,
collection: source,
node: source,
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(source.databaseId, source.id())}/sproc`,
@@ -116,7 +116,6 @@ export default class StoredProcedure {
tabKind: ViewModels.CollectionTabKind.StoredProcedures,
title: storedProcedureData.id,
tabPath: `${this.collection.databaseId}>${this.collection.id()}>${storedProcedureData.id}`,
documentClientUtility: this.container.documentClientUtility,
collection: this.collection,
node: this,
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(
@@ -144,7 +143,7 @@ export default class StoredProcedure {
body: this.body()
};
this.container.documentClientUtility.deleteStoredProcedure(this.collection, storedProcedureData).then(
deleteStoredProcedure(this.collection, storedProcedureData).then(
() => {
this.container.tabsManager.removeTabByComparator(
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid
@@ -163,8 +162,7 @@ export default class StoredProcedure {
const sprocTab: ViewModels.StoredProcedureTab = sprocTabs && sprocTabs.length > 0 && sprocTabs[0];
sprocTab.isExecuting(true);
this.container &&
this.container.documentClientUtility
.executeStoredProcedure(this.collection, this, partitionKeyValue, params)
executeStoredProcedure(this.collection, this, partitionKeyValue, params)
.then(
(result: any) => {
sprocTab.onExecuteSprocsResult(result, result.scriptLogs);

View File

@@ -6,6 +6,7 @@ import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstan
import TriggerTab from "../Tabs/TriggerTab";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import Explorer from "../Explorer";
import { deleteTrigger } from "../../Common/DocumentClientUtilityBase";
export default class Trigger {
public nodeKind: string;
@@ -55,7 +56,6 @@ export default class Trigger {
tabKind: ViewModels.CollectionTabKind.Triggers,
title: `New Trigger ${id}`,
tabPath: "",
documentClientUtility: source.container.documentClientUtility,
collection: source,
node: source,
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(source.databaseId, source.id())}/trigger`,
@@ -94,7 +94,6 @@ export default class Trigger {
tabKind: ViewModels.CollectionTabKind.Triggers,
title: triggerData.id,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this.collection,
node: this,
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(
@@ -124,7 +123,7 @@ export default class Trigger {
triggerType: this.triggerType()
};
this.container.documentClientUtility.deleteTrigger(this.collection, triggerData).then(
deleteTrigger(this.collection, triggerData).then(
() => {
this.container.tabsManager.removeTabByComparator(
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid

View File

@@ -6,6 +6,7 @@ import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstan
import UserDefinedFunctionTab from "../Tabs/UserDefinedFunctionTab";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import Explorer from "../Explorer";
import { deleteUserDefinedFunction } from "../../Common/DocumentClientUtilityBase";
export default class UserDefinedFunction {
public nodeKind: string;
@@ -40,7 +41,6 @@ export default class UserDefinedFunction {
tabKind: ViewModels.CollectionTabKind.UserDefinedFunctions,
title: `New UDF ${id}`,
tabPath: "",
documentClientUtility: source.container.documentClientUtility,
collection: source,
node: source,
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(source.databaseId, source.id())}/udf`,
@@ -77,7 +77,6 @@ export default class UserDefinedFunction {
tabKind: ViewModels.CollectionTabKind.UserDefinedFunctions,
title: userDefinedFunctionData.id,
tabPath: "",
documentClientUtility: this.container.documentClientUtility,
collection: this.collection,
node: this,
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(
@@ -114,7 +113,7 @@ export default class UserDefinedFunction {
id: this.id(),
body: this.body()
};
this.container.documentClientUtility.deleteUserDefinedFunction(this.collection, userDefinedFunctionData).then(
deleteUserDefinedFunction(this.collection, userDefinedFunctionData).then(
() => {
this.container.tabsManager.removeTabByComparator(
(tab: ViewModels.Tab) => tab.node && tab.node.rid === this.rid