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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 1567 additions and 1754 deletions

View File

@ -52,6 +52,7 @@ jobs:
- run: npm run test
build:
runs-on: ubuntu-latest
needs: [lint, format, compile, unittest]
name: "Build"
steps:
- uses: actions/checkout@v2
@ -75,6 +76,7 @@ jobs:
path: dist/
endtoendemulator:
name: "End To End Tests | Emulator | SQL"
needs: [lint, format, compile, unittest]
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
@ -101,6 +103,7 @@ jobs:
CYPRESS_CACHE_FOLDER: ~/.cache/Cypress
endtoendsql:
name: "End To End Tests | SQL"
needs: [lint, format, compile, unittest]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@ -129,6 +132,7 @@ jobs:
CYPRESS_CONNECTION_STRING: ${{ secrets.CONNECTION_STRING_SQL }}
endtoendmongo:
name: "End To End Tests | Mongo"
needs: [lint, format, compile, unittest]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@ -157,6 +161,7 @@ jobs:
CYPRESS_CONNECTION_STRING: ${{ secrets.CONNECTION_STRING_MONGO }}
accessibility:
name: "Accessibility | Hosted"
needs: [lint, format, compile, unittest]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

View File

@ -39,10 +39,10 @@ module.exports = {
// An object that configures minimum threshold enforcement for coverage results
coverageThreshold: {
global: {
branches: 18,
functions: 22,
lines: 28,
statements: 27
branches: 19.5,
functions: 24,
lines: 29.5,
statements: 28.5
}
},

View File

@ -15,38 +15,37 @@ import { RequestOptions } from "@azure/cosmos/dist-esm";
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
// TODO: Log all promise resolutions and errors with verbosity levels
export default class DocumentClientUtilityBase {
public queryDocuments(
export function queryDocuments(
databaseId: string,
containerId: string,
query: string,
options: any
): Q.Promise<QueryIterator<ItemDefinition & Resource>> {
): Q.Promise<QueryIterator<ItemDefinition & Resource>> {
return DataAccessUtilityBase.queryDocuments(databaseId, containerId, query, options);
}
}
public queryConflicts(
export function queryConflicts(
databaseId: string,
containerId: string,
query: string,
options: any
): Q.Promise<QueryIterator<ConflictDefinition & Resource>> {
): Q.Promise<QueryIterator<ConflictDefinition & Resource>> {
return DataAccessUtilityBase.queryConflicts(databaseId, containerId, query, options);
}
}
public getEntityName() {
export function getEntityName() {
const defaultExperience =
window.dataExplorer && window.dataExplorer.defaultExperience && window.dataExplorer.defaultExperience();
if (defaultExperience === Constants.DefaultAccountExperience.MongoDB) {
return "document";
}
return "item";
}
}
public readStoredProcedures(
export function readStoredProcedures(
collection: ViewModels.Collection,
options: any = {}
): Q.Promise<DataModels.StoredProcedure[]> {
): Q.Promise<DataModels.StoredProcedure[]> {
var deferred = Q.defer<DataModels.StoredProcedure[]>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -63,7 +62,7 @@ export default class DocumentClientUtilityBase {
`Failed to query stored procedures for container ${collection.id()}: ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadStoredProcedures", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -72,20 +71,20 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readStoredProcedure(
export function readStoredProcedure(
collection: ViewModels.Collection,
requestedResource: DataModels.Resource,
options?: any
): Q.Promise<DataModels.StoredProcedure> {
): Q.Promise<DataModels.StoredProcedure> {
return DataAccessUtilityBase.readStoredProcedure(collection, requestedResource, options);
}
}
public readUserDefinedFunctions(
export function readUserDefinedFunctions(
collection: ViewModels.Collection,
options: any = {}
): Q.Promise<DataModels.UserDefinedFunction[]> {
): Q.Promise<DataModels.UserDefinedFunction[]> {
var deferred = Q.defer<DataModels.UserDefinedFunction[]>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -102,7 +101,7 @@ export default class DocumentClientUtilityBase {
`Failed to query user defined functions for container ${collection.id()}: ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadUDFs", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -111,17 +110,17 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readUserDefinedFunction(
export function readUserDefinedFunction(
collection: ViewModels.Collection,
requestedResource: DataModels.Resource,
options: any
): Q.Promise<DataModels.UserDefinedFunction> {
): Q.Promise<DataModels.UserDefinedFunction> {
return DataAccessUtilityBase.readUserDefinedFunction(collection, requestedResource, options);
}
}
public readTriggers(collection: ViewModels.Collection, options: any): Q.Promise<DataModels.Trigger[]> {
export function readTriggers(collection: ViewModels.Collection, options: any): Q.Promise<DataModels.Trigger[]> {
var deferred = Q.defer<DataModels.Trigger[]>();
const id = NotificationConsoleUtils.logConsoleMessage(
@ -139,7 +138,7 @@ export default class DocumentClientUtilityBase {
`Failed to query triggers for container ${collection.id()}: ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadTriggers", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -148,22 +147,22 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readTrigger(
export function readTrigger(
collection: ViewModels.Collection,
requestedResource: DataModels.Resource,
options?: any
): Q.Promise<DataModels.Trigger> {
): Q.Promise<DataModels.Trigger> {
return DataAccessUtilityBase.readTrigger(collection, requestedResource, options);
}
}
public executeStoredProcedure(
export function executeStoredProcedure(
collection: ViewModels.Collection,
storedProcedure: StoredProcedure,
partitionKeyValue: any,
params: any[]
): Q.Promise<any> {
): Q.Promise<any> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
@ -187,7 +186,7 @@ export default class DocumentClientUtilityBase {
)}`
);
Logger.logError(JSON.stringify(error), "ExecuteStoredProcedure", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -196,16 +195,16 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public queryDocumentsPage(
export function queryDocumentsPage(
resourceName: string,
documentsIterator: MinimalQueryIterator,
firstItemIndex: number,
options: any
): Q.Promise<ViewModels.QueryResults> {
): Q.Promise<ViewModels.QueryResults> {
var deferred = Q.defer<ViewModels.QueryResults>();
const entityName = this.getEntityName();
const entityName = getEntityName();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
`Querying ${entityName} for container ${resourceName}`
@ -226,7 +225,7 @@ export default class DocumentClientUtilityBase {
`Failed to query ${entityName} for container ${resourceName}: ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "QueryDocumentsPage", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -235,11 +234,11 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readDocument(collection: ViewModels.CollectionBase, documentId: ViewModels.DocumentId): Q.Promise<any> {
export function readDocument(collection: ViewModels.CollectionBase, documentId: ViewModels.DocumentId): Q.Promise<any> {
var deferred = Q.defer<any>();
const entityName = this.getEntityName();
const entityName = getEntityName();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
`Reading ${entityName} ${documentId.id()}`
@ -255,7 +254,7 @@ export default class DocumentClientUtilityBase {
`Failed to read ${entityName} ${documentId.id()}: ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadDocument", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -264,13 +263,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public updateCollection(
export function updateCollection(
databaseId: string,
collection: ViewModels.Collection,
newCollection: DataModels.Collection
): Q.Promise<DataModels.Collection> {
): Q.Promise<DataModels.Collection> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -291,7 +290,7 @@ export default class DocumentClientUtilityBase {
`Failed to update container ${collection.id()}: ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "UpdateCollection", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -300,15 +299,15 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public updateDocument(
export function updateDocument(
collection: ViewModels.CollectionBase,
documentId: ViewModels.DocumentId,
newDocument: any
): Q.Promise<any> {
): Q.Promise<any> {
var deferred = Q.defer<any>();
const entityName = this.getEntityName();
const entityName = getEntityName();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
`Updating ${entityName} ${documentId.id()}`
@ -328,7 +327,7 @@ export default class DocumentClientUtilityBase {
`Failed to update ${entityName} ${documentId.id()}: ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "UpdateDocument", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -337,13 +336,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public updateOffer(
export function updateOffer(
offer: DataModels.Offer,
newOffer: DataModels.Offer,
options: RequestOptions
): Q.Promise<DataModels.Offer> {
): Q.Promise<DataModels.Offer> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -372,7 +371,7 @@ export default class DocumentClientUtilityBase {
"UpdateOffer",
error.code
);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -381,9 +380,11 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public updateOfferThroughputBeyondLimit(requestPayload: DataModels.UpdateOfferThroughputRequest): Q.Promise<void> {
export function updateOfferThroughputBeyondLimit(
requestPayload: DataModels.UpdateOfferThroughputRequest
): Q.Promise<void> {
const deferred: Q.Deferred<void> = Q.defer<void>();
const resourceDescriptionInfo: string = requestPayload.collectionName
? `database ${requestPayload.databaseName} and container ${requestPayload.collectionName}`
@ -406,20 +407,20 @@ export default class DocumentClientUtilityBase {
ConsoleDataType.Error,
`Failed to request an increase in throughput for ${requestPayload.throughput}: ${JSON.stringify(error)}`
);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));
return deferred.promise.timeout(Constants.ClientDefaults.requestTimeoutMs);
}
}
public updateStoredProcedure(
export function updateStoredProcedure(
collection: ViewModels.Collection,
storedProcedure: DataModels.StoredProcedure,
options?: any
): Q.Promise<DataModels.StoredProcedure> {
): Q.Promise<DataModels.StoredProcedure> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -440,7 +441,7 @@ export default class DocumentClientUtilityBase {
`Error while updating stored procedure ${storedProcedure.id}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "UpdateStoredProcedure", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -449,13 +450,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public updateUserDefinedFunction(
export function updateUserDefinedFunction(
collection: ViewModels.Collection,
userDefinedFunction: DataModels.UserDefinedFunction,
options: any = {}
): Q.Promise<DataModels.UserDefinedFunction> {
): Q.Promise<DataModels.UserDefinedFunction> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -476,7 +477,7 @@ export default class DocumentClientUtilityBase {
`Error while updating user defined function ${userDefinedFunction.id}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "UpdateUDF", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -485,9 +486,12 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public updateTrigger(collection: ViewModels.Collection, trigger: DataModels.Trigger): Q.Promise<DataModels.Trigger> {
export function updateTrigger(
collection: ViewModels.Collection,
trigger: DataModels.Trigger
): Q.Promise<DataModels.Trigger> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, `Updating trigger ${trigger.id}`);
DataAccessUtilityBase.updateTrigger(collection, trigger)
@ -502,7 +506,7 @@ export default class DocumentClientUtilityBase {
`Error while updating trigger ${trigger.id}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "UpdateTrigger", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -511,11 +515,11 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise<any> {
export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise<any> {
var deferred = Q.defer<any>();
const entityName = this.getEntityName();
const entityName = getEntityName();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
`Creating new ${entityName} for container ${collection.id()}`
@ -535,7 +539,7 @@ export default class DocumentClientUtilityBase {
`Error while creating new ${entityName} for container ${collection.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "CreateDocument", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -544,13 +548,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public createStoredProcedure(
export function createStoredProcedure(
collection: ViewModels.Collection,
newStoredProcedure: DataModels.StoredProcedure,
options?: any
): Q.Promise<DataModels.StoredProcedure> {
): Q.Promise<DataModels.StoredProcedure> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -571,7 +575,7 @@ export default class DocumentClientUtilityBase {
`Error while creating stored procedure for container ${collection.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "CreateStoredProcedure", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -580,13 +584,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public createUserDefinedFunction(
export function createUserDefinedFunction(
collection: ViewModels.Collection,
newUserDefinedFunction: DataModels.UserDefinedFunction,
options?: any
): Q.Promise<DataModels.UserDefinedFunction> {
): Q.Promise<DataModels.UserDefinedFunction> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -607,7 +611,7 @@ export default class DocumentClientUtilityBase {
`Error while creating user defined function for container ${collection.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "CreateUDF", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -616,13 +620,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public createTrigger(
export function createTrigger(
collection: ViewModels.Collection,
newTrigger: DataModels.Trigger,
options: any = {}
): Q.Promise<DataModels.Trigger> {
): Q.Promise<DataModels.Trigger> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -643,7 +647,7 @@ export default class DocumentClientUtilityBase {
`Error while creating trigger for container ${collection.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "CreateTrigger", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -652,11 +656,14 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public deleteDocument(collection: ViewModels.CollectionBase, documentId: ViewModels.DocumentId): Q.Promise<any> {
export function deleteDocument(
collection: ViewModels.CollectionBase,
documentId: ViewModels.DocumentId
): Q.Promise<any> {
var deferred = Q.defer<any>();
const entityName = this.getEntityName();
const entityName = getEntityName();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
`Deleting ${entityName} ${documentId.id()}`
@ -676,7 +683,7 @@ export default class DocumentClientUtilityBase {
`Error while deleting ${entityName} ${documentId.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "DeleteDocument", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -685,13 +692,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public deleteConflict(
export function deleteConflict(
collection: ViewModels.CollectionBase,
conflictId: ViewModels.ConflictId,
options?: any
): Q.Promise<any> {
): Q.Promise<any> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
@ -713,7 +720,7 @@ export default class DocumentClientUtilityBase {
`Error while deleting conflict ${conflictId.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "DeleteConflict", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -722,9 +729,9 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public deleteCollection(collection: ViewModels.Collection, options: any = {}): Q.Promise<any> {
export function deleteCollection(collection: ViewModels.Collection, options: any = {}): Q.Promise<any> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
@ -746,7 +753,7 @@ export default class DocumentClientUtilityBase {
`Error while deleting container ${collection.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "DeleteCollection", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -755,9 +762,9 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public deleteDatabase(database: ViewModels.Database, options: any = {}): Q.Promise<any> {
export function deleteDatabase(database: ViewModels.Database, options: any = {}): Q.Promise<any> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
@ -779,7 +786,7 @@ export default class DocumentClientUtilityBase {
`Error while deleting database ${database.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "DeleteDatabase", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -788,13 +795,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public deleteStoredProcedure(
export function deleteStoredProcedure(
collection: ViewModels.Collection,
storedProcedure: DataModels.StoredProcedure,
options: any = {}
): Q.Promise<DataModels.StoredProcedure> {
): Q.Promise<DataModels.StoredProcedure> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
@ -816,7 +823,7 @@ export default class DocumentClientUtilityBase {
`Error while deleting stored procedure ${storedProcedure.id}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "DeleteStoredProcedure", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -825,13 +832,13 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public deleteUserDefinedFunction(
export function deleteUserDefinedFunction(
collection: ViewModels.Collection,
userDefinedFunction: DataModels.UserDefinedFunction,
options: any = {}
): Q.Promise<DataModels.UserDefinedFunction> {
): Q.Promise<DataModels.UserDefinedFunction> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -852,7 +859,7 @@ export default class DocumentClientUtilityBase {
`Error while deleting user defined function ${userDefinedFunction.id}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "DeleteUDF", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -861,22 +868,19 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public deleteTrigger(
export function deleteTrigger(
collection: ViewModels.Collection,
trigger: DataModels.Trigger,
options: any = {}
): Q.Promise<DataModels.Trigger> {
): Q.Promise<DataModels.Trigger> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, `Deleting trigger ${trigger.id}`);
DataAccessUtilityBase.deleteTrigger(collection, trigger, options)
.then(
(response: any) => {
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Info,
`Successfully deleted trigger ${trigger.id}`
);
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Info, `Successfully deleted trigger ${trigger.id}`);
deferred.resolve(response);
},
(error: any) => {
@ -885,7 +889,7 @@ export default class DocumentClientUtilityBase {
`Error while deleting trigger ${trigger.id}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "DeleteTrigger", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -894,17 +898,17 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public refreshCachedResources(options: any = {}): Q.Promise<void> {
export function refreshCachedResources(options: any = {}): Q.Promise<void> {
return DataAccessUtilityBase.refreshCachedResources(options);
}
}
public refreshCachedOffers(): Q.Promise<void> {
export function refreshCachedOffers(): Q.Promise<void> {
return DataAccessUtilityBase.refreshCachedOffers();
}
}
public readCollections(database: ViewModels.Database, options: any = {}): Q.Promise<DataModels.Collection[]> {
export function readCollections(database: ViewModels.Database, options: any = {}): Q.Promise<DataModels.Collection[]> {
var deferred = Q.defer<DataModels.Collection[]>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -921,7 +925,7 @@ export default class DocumentClientUtilityBase {
`Error while querying containers for database ${database.id()}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadCollections", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -930,9 +934,9 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readCollection(databaseId: string, collectionId: string): Q.Promise<DataModels.Collection> {
export function readCollection(databaseId: string, collectionId: string): Q.Promise<DataModels.Collection> {
const deferred = Q.defer<DataModels.Collection>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -950,7 +954,7 @@ export default class DocumentClientUtilityBase {
`Error while querying containers for database ${databaseId}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadCollections", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -959,12 +963,12 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readCollectionQuotaInfo(
export function readCollectionQuotaInfo(
collection: ViewModels.Collection,
options?: any
): Q.Promise<DataModels.CollectionQuotaInfo> {
): Q.Promise<DataModels.CollectionQuotaInfo> {
var deferred = Q.defer<DataModels.CollectionQuotaInfo>();
const id = NotificationConsoleUtils.logConsoleMessage(
@ -982,7 +986,7 @@ export default class DocumentClientUtilityBase {
`Error while querying quota info for container ${collection.id}:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadCollectionQuotaInfo", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -991,9 +995,9 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readOffers(options: any = {}): Q.Promise<DataModels.Offer[]> {
export function readOffers(options: any = {}): Q.Promise<DataModels.Offer[]> {
var deferred = Q.defer<DataModels.Offer[]>();
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Querying offers");
@ -1008,7 +1012,7 @@ export default class DocumentClientUtilityBase {
`Error while querying offers:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadOffers", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -1017,9 +1021,12 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readOffer(requestedResource: DataModels.Offer, options: any = {}): Q.Promise<DataModels.OfferWithHeaders> {
export function readOffer(
requestedResource: DataModels.Offer,
options: any = {}
): Q.Promise<DataModels.OfferWithHeaders> {
var deferred = Q.defer<DataModels.OfferWithHeaders>();
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Querying offer");
@ -1034,7 +1041,7 @@ export default class DocumentClientUtilityBase {
`Error while querying offer:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadOffer", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -1043,9 +1050,9 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public readDatabases(options: any): Q.Promise<DataModels.Database[]> {
export function readDatabases(options: any): Q.Promise<DataModels.Database[]> {
var deferred = Q.defer<any>();
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Querying databases");
DataAccessUtilityBase.readDatabases(options)
@ -1059,7 +1066,7 @@ export default class DocumentClientUtilityBase {
`Error while querying databases:\n ${JSON.stringify(error)}`
);
Logger.logError(JSON.stringify(error), "ReadDatabases", error.code);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
@ -1068,12 +1075,12 @@ export default class DocumentClientUtilityBase {
});
return deferred.promise;
}
}
public getOrCreateDatabaseAndCollection(
export function getOrCreateDatabaseAndCollection(
request: DataModels.CreateDatabaseAndCollectionRequest,
options: any = {}
): Q.Promise<DataModels.Collection> {
): Q.Promise<DataModels.Collection> {
const deferred: Q.Deferred<DataModels.Collection> = Q.defer<DataModels.Collection>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -1095,16 +1102,19 @@ export default class DocumentClientUtilityBase {
ConsoleDataType.Error,
`Error while creating container ${request.collectionId}:\n ${sanitizedError}`
);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));
return deferred.promise;
}
}
public createDatabase(request: DataModels.CreateDatabaseRequest, options: any = {}): Q.Promise<DataModels.Database> {
export function createDatabase(
request: DataModels.CreateDatabaseRequest,
options: any = {}
): Q.Promise<DataModels.Database> {
const deferred: Q.Deferred<DataModels.Database> = Q.defer<DataModels.Database>();
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@ -1125,16 +1135,16 @@ export default class DocumentClientUtilityBase {
ConsoleDataType.Error,
`Error while creating database ${request.databaseId}:\n ${JSON.stringify(error)}`
);
this.sendNotificationForError(error);
sendNotificationForError(error);
deferred.reject(error);
}
)
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));
return deferred.promise;
}
}
public sendNotificationForError(error: any) {
export function sendNotificationForError(error: any) {
if (error && error.code === Constants.HttpStatusCodes.Forbidden) {
if (error.message && error.message.toLowerCase().indexOf("sharedoffer is disabled for your account") > 0) {
return;
@ -1144,5 +1154,4 @@ export default class DocumentClientUtilityBase {
reason: error && error.message ? error.message : error
});
}
}
}

View File

@ -11,6 +11,13 @@ import * as Logger from "./Logger";
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
import { QueryUtils } from "../Utils/QueryUtils";
import Explorer from "../Explorer/Explorer";
import {
getOrCreateDatabaseAndCollection,
createDocument,
queryDocuments,
queryDocumentsPage,
deleteDocument
} from "./DocumentClientUtilityBase";
export class QueriesClient implements ViewModels.QueriesClient {
private static readonly PartitionKey: DataModels.PartitionKey = {
@ -33,8 +40,7 @@ export class QueriesClient implements ViewModels.QueriesClient {
ConsoleDataType.InProgress,
"Setting up account for saving queries"
);
return this.container.documentClientUtility
.getOrCreateDatabaseAndCollection({
return getOrCreateDatabaseAndCollection({
collectionId: SavedQueries.CollectionName,
databaseId: SavedQueries.DatabaseName,
partitionKey: QueriesClient.PartitionKey,
@ -89,8 +95,7 @@ export class QueriesClient implements ViewModels.QueriesClient {
`Saving query ${query.queryName}`
);
query.id = query.queryName;
return this.container.documentClientUtility
.createDocument(queriesCollection, query)
return createDocument(queriesCollection, query)
.then(
(savedQuery: DataModels.Query) => {
NotificationConsoleUtils.logConsoleMessage(
@ -131,17 +136,11 @@ export class QueriesClient implements ViewModels.QueriesClient {
const options: any = { enableCrossPartitionQuery: true };
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Fetching saved queries");
return this.container.documentClientUtility
.queryDocuments(SavedQueries.DatabaseName, SavedQueries.CollectionName, this.fetchQueriesQuery(), options)
return queryDocuments(SavedQueries.DatabaseName, SavedQueries.CollectionName, this.fetchQueriesQuery(), options)
.then(
(queryIterator: QueryIterator<ItemDefinition & Resource>) => {
const fetchQueries = (firstItemIndex: number): Q.Promise<ViewModels.QueryResults> =>
this.container.documentClientUtility.queryDocumentsPage(
queriesCollection.id(),
queryIterator,
firstItemIndex,
options
);
queryDocumentsPage(queriesCollection.id(), queryIterator, firstItemIndex, options);
return QueryUtils.queryAllPages(fetchQueries).then(
(results: ViewModels.QueryResults) => {
let queries: DataModels.Query[] = _.map(results.documents, (document: DataModels.Query) => {
@ -226,8 +225,7 @@ export class QueriesClient implements ViewModels.QueriesClient {
query.queryName
); // TODO: Remove DocumentId's dependency on DocumentsTab
const options: any = { partitionKey: query.resourceId };
return this.container.documentClientUtility
.deleteDocument(queriesCollection, documentId)
return deleteDocument(queriesCollection, documentId)
.then(
() => {
NotificationConsoleUtils.logConsoleMessage(

View File

@ -1,6 +1,5 @@
import * as DataModels from "./DataModels";
import * as monaco from "monaco-editor";
import DocumentClientUtilityBase from "../Common/DocumentClientUtilityBase";
import Q from "q";
import { AccessibleVerticalList } from "../Explorer/Tree/AccessibleVerticalList";
import { CassandraTableKey, CassandraTableKeys } from "../Explorer/Tables/TableDataClient";
@ -18,7 +17,6 @@ import ConflictsTab from "../Explorer/Tabs/ConflictsTab";
import Trigger from "../Explorer/Tree/Trigger";
export interface ExplorerOptions {
documentClientUtility: DocumentClientUtilityBase;
notificationsClient: NotificationsClient;
isEmulator: boolean;
}
@ -245,13 +243,11 @@ export interface ConflictId {
*/
export interface PaneOptions {
id: string;
documentClientUtility: DocumentClientUtilityBase;
visible: ko.Observable<boolean>;
container?: Explorer;
}
export interface ContextualPane {
documentClientUtility: DocumentClientUtilityBase;
formErrors: ko.Observable<string>;
formErrorsDetails: ko.Observable<string>;
id: string;
@ -406,7 +402,6 @@ export interface TabOptions {
tabKind: CollectionTabKind;
title: string;
tabPath: string;
documentClientUtility: DocumentClientUtilityBase;
selfLink: string;
isActive: ko.Observable<boolean>;
hashLocation: string;
@ -493,11 +488,9 @@ export interface ScriptTabOption extends TabOptions {
// Tabs
export interface Tab {
documentClientUtility: DocumentClientUtilityBase;
node: TreeNode; // Can be null
collection: CollectionBase;
rid: string;
tabKind: CollectionTabKind;
tabId: string;
isActive: ko.Observable<boolean>;

View File

@ -1,10 +1,11 @@
jest.mock("../../Common/DocumentClientUtilityBase");
import * as ko from "knockout";
import * as sinon from "sinon";
import * as ViewModels from "../../Contracts/ViewModels";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import Q from "q";
import { ContainerSampleGenerator } from "./ContainerSampleGenerator";
import { CosmosClient } from "../../Common/CosmosClient";
import * as DocumentClientUtility from "../../Common/DocumentClientUtilityBase";
import { GremlinClient } from "../Graph/GraphExplorerComponent/GremlinClient";
import Explorer from "../Explorer";
@ -62,19 +63,12 @@ describe("ContainerSampleGenerator", () => {
const explorerStub = createExplorerStub(database);
explorerStub.isPreferredApiDocumentDB = ko.computed<boolean>(() => true);
const fakeDocumentClientUtility = sinon.createStubInstance(DocumentClientUtilityBase);
fakeDocumentClientUtility.getOrCreateDatabaseAndCollection.returns(Q.resolve(collection));
fakeDocumentClientUtility.createDocument.returns(Q.resolve());
explorerStub.documentClientUtility = fakeDocumentClientUtility;
const generator = await ContainerSampleGenerator.createSampleGeneratorAsync(explorerStub);
generator.setData(sampleData);
await generator.createSampleContainerAsync();
expect(fakeDocumentClientUtility.createDocument.called).toBe(true);
expect(DocumentClientUtility.createDocument).toHaveBeenCalled();
});
it("should send gremlin queries for Graph API account", async () => {
@ -109,18 +103,12 @@ describe("ContainerSampleGenerator", () => {
const explorerStub = createExplorerStub(database);
explorerStub.isPreferredApiGraph = ko.computed<boolean>(() => true);
const fakeDocumentClientUtility = sinon.createStubInstance(DocumentClientUtilityBase);
fakeDocumentClientUtility.getOrCreateDatabaseAndCollection.returns(Q.resolve(collection));
fakeDocumentClientUtility.createDocument.returns(Q.resolve());
explorerStub.documentClientUtility = fakeDocumentClientUtility;
const generator = await ContainerSampleGenerator.createSampleGeneratorAsync(explorerStub);
generator.setData(sampleData);
await generator.createSampleContainerAsync();
expect(fakeDocumentClientUtility.createDocument.called).toBe(false);
expect(DocumentClientUtility.createDocument).toHaveBeenCalled();
expect(executeStub.called).toBe(true);
});

View File

@ -7,6 +7,7 @@ import { CosmosClient } from "../../Common/CosmosClient";
import { GremlinClient } from "../Graph/GraphExplorerComponent/GremlinClient";
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
import Explorer from "../Explorer";
import { createDocument, getOrCreateDatabaseAndCollection } from "../../Common/DocumentClientUtilityBase";
interface SampleDataFile extends DataModels.CreateDatabaseAndCollectionRequest {
data: any[];
@ -64,7 +65,7 @@ export class ContainerSampleGenerator {
options.initialHeaders[Constants.HttpHeaders.usePolygonsSmallerThanAHemisphere] = true;
}
await this.container.documentClientUtility.getOrCreateDatabaseAndCollection(createRequest, options);
await getOrCreateDatabaseAndCollection(createRequest, options);
await this.container.refreshAllDatabases();
const database = this.container.findDatabaseWithId(this.sampleDataFile.databaseId);
if (!database) {
@ -103,7 +104,7 @@ export class ContainerSampleGenerator {
} else {
// For SQL all queries are executed at the same time
this.sampleDataFile.data.forEach(doc => {
const subPromise = this.container.documentClientUtility.createDocument(collection, doc);
const subPromise = createDocument(collection, doc);
subPromise.catch(reason => NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, reason));
promises.push(subPromise);
});

View File

@ -15,7 +15,7 @@ import CassandraAddCollectionPane from "./Panes/CassandraAddCollectionPane";
import Database from "./Tree/Database";
import DeleteCollectionConfirmationPane from "./Panes/DeleteCollectionConfirmationPane";
import DeleteDatabaseConfirmationPane from "./Panes/DeleteDatabaseConfirmationPane";
import DocumentClientUtilityBase from "../Common/DocumentClientUtilityBase";
import { readDatabases, readCollection, readOffers, refreshCachedResources } from "../Common/DocumentClientUtilityBase";
import EditTableEntityPane from "./Panes/Tables/EditTableEntityPane";
import EnvironmentUtility from "../Common/EnvironmentUtility";
import GraphStylingPane from "./Panes/GraphStylingPane";
@ -127,7 +127,6 @@ export default class Explorer {
public extensionEndpoint: ko.Observable<string>;
public armEndpoint: ko.Observable<string>;
public isTryCosmosDBSubscription: ko.Observable<boolean>;
public documentClientUtility: DocumentClientUtilityBase;
public notificationsClient: ViewModels.NotificationsClient;
public queriesClient: ViewModels.QueriesClient;
public tableDataClient: TableDataClient;
@ -358,7 +357,6 @@ export default class Explorer {
}
});
this.memoryUsageInfo = ko.observable<DataModels.MemoryUsageInfo>();
this.documentClientUtility = options.documentClientUtility;
this.notificationsClient = options.notificationsClient;
this.isEmulator = options.isEmulator;
@ -584,7 +582,6 @@ export default class Explorer {
});
this.addDatabasePane = new AddDatabasePane({
documentClientUtility: this.documentClientUtility,
id: "adddatabasepane",
visible: ko.observable<boolean>(false),
@ -593,7 +590,6 @@ export default class Explorer {
this.addCollectionPane = new AddCollectionPane({
isPreferredApiTable: ko.computed(() => this.isPreferredApiTable()),
documentClientUtility: this.documentClientUtility,
id: "addcollectionpane",
visible: ko.observable<boolean>(false),
@ -601,7 +597,6 @@ export default class Explorer {
});
this.deleteCollectionConfirmationPane = new DeleteCollectionConfirmationPane({
documentClientUtility: this.documentClientUtility,
id: "deletecollectionconfirmationpane",
visible: ko.observable<boolean>(false),
@ -609,7 +604,6 @@ export default class Explorer {
});
this.deleteDatabaseConfirmationPane = new DeleteDatabaseConfirmationPane({
documentClientUtility: this.documentClientUtility,
id: "deletedatabaseconfirmationpane",
visible: ko.observable<boolean>(false),
@ -617,7 +611,6 @@ export default class Explorer {
});
this.graphStylingPane = new GraphStylingPane({
documentClientUtility: this.documentClientUtility,
id: "graphstylingpane",
visible: ko.observable<boolean>(false),
@ -625,7 +618,6 @@ export default class Explorer {
});
this.addTableEntityPane = new AddTableEntityPane({
documentClientUtility: this.documentClientUtility,
id: "addtableentitypane",
visible: ko.observable<boolean>(false),
@ -633,7 +625,6 @@ export default class Explorer {
});
this.editTableEntityPane = new EditTableEntityPane({
documentClientUtility: this.documentClientUtility,
id: "edittableentitypane",
visible: ko.observable<boolean>(false),
@ -641,7 +632,6 @@ export default class Explorer {
});
this.tableColumnOptionsPane = new TableColumnOptionsPane({
documentClientUtility: this.documentClientUtility,
id: "tablecolumnoptionspane",
visible: ko.observable<boolean>(false),
@ -649,7 +639,6 @@ export default class Explorer {
});
this.querySelectPane = new QuerySelectPane({
documentClientUtility: this.documentClientUtility,
id: "queryselectpane",
visible: ko.observable<boolean>(false),
@ -657,7 +646,6 @@ export default class Explorer {
});
this.newVertexPane = new NewVertexPane({
documentClientUtility: this.documentClientUtility,
id: "newvertexpane",
visible: ko.observable<boolean>(false),
@ -665,7 +653,6 @@ export default class Explorer {
});
this.cassandraAddCollectionPane = new CassandraAddCollectionPane({
documentClientUtility: this.documentClientUtility,
id: "cassandraaddcollectionpane",
visible: ko.observable<boolean>(false),
@ -673,7 +660,6 @@ export default class Explorer {
});
this.settingsPane = new SettingsPane({
documentClientUtility: this.documentClientUtility,
id: "settingspane",
visible: ko.observable<boolean>(false),
@ -681,7 +667,6 @@ export default class Explorer {
});
this.executeSprocParamsPane = new ExecuteSprocParamsPane({
documentClientUtility: this.documentClientUtility,
id: "executesprocparamspane",
visible: ko.observable<boolean>(false),
@ -689,7 +674,6 @@ export default class Explorer {
});
this.renewAdHocAccessPane = new RenewAdHocAccessPane({
documentClientUtility: this.documentClientUtility,
id: "renewadhocaccesspane",
visible: ko.observable<boolean>(false),
@ -697,7 +681,6 @@ export default class Explorer {
});
this.uploadItemsPane = new UploadItemsPane({
documentClientUtility: this.documentClientUtility,
id: "uploaditemspane",
visible: ko.observable<boolean>(false),
@ -707,7 +690,6 @@ export default class Explorer {
this.uploadItemsPaneAdapter = new UploadItemsPaneAdapter(this);
this.loadQueryPane = new LoadQueryPane({
documentClientUtility: this.documentClientUtility,
id: "loadquerypane",
visible: ko.observable<boolean>(false),
@ -715,7 +697,6 @@ export default class Explorer {
});
this.saveQueryPane = new SaveQueryPane({
documentClientUtility: this.documentClientUtility,
id: "savequerypane",
visible: ko.observable<boolean>(false),
@ -723,7 +704,6 @@ export default class Explorer {
});
this.browseQueriesPane = new BrowseQueriesPane({
documentClientUtility: this.documentClientUtility,
id: "browsequeriespane",
visible: ko.observable<boolean>(false),
@ -731,7 +711,6 @@ export default class Explorer {
});
this.uploadFilePane = new UploadFilePane({
documentClientUtility: this.documentClientUtility,
id: "uploadfilepane",
visible: ko.observable<boolean>(false),
@ -739,7 +718,6 @@ export default class Explorer {
});
this.stringInputPane = new StringInputPane({
documentClientUtility: this.documentClientUtility,
id: "stringinputpane",
visible: ko.observable<boolean>(false),
@ -747,7 +725,6 @@ export default class Explorer {
});
this.setupNotebooksPane = new SetupNotebooksPane({
documentClientUtility: this.documentClientUtility,
id: "setupnotebookspane",
visible: ko.observable<boolean>(false),
@ -780,7 +757,6 @@ export default class Explorer {
this.setupNotebooksPane
];
this.addDatabaseText.subscribe((addDatabaseText: string) => this.addDatabasePane.title(addDatabaseText));
this.rebindDocumentClientUtility.bind(this);
this.isTabsContentExpanded = ko.observable(false);
document.addEventListener(
@ -862,7 +838,7 @@ export default class Explorer {
this.editTableEntityPane.title("Edit Table Entity");
this.deleteCollectionConfirmationPane.title("Delete Table");
this.deleteCollectionConfirmationPane.collectionIdConfirmationText("Confirm by typing the table id");
this.tableDataClient = new TablesAPIDataClient(this.documentClientUtility);
this.tableDataClient = new TablesAPIDataClient();
break;
case Constants.DefaultAccountExperience.Cassandra.toLowerCase():
this.addCollectionText("New Table");
@ -881,7 +857,7 @@ export default class Explorer {
this.deleteCollectionConfirmationPane.collectionIdConfirmationText("Confirm by typing the table id");
this.deleteDatabaseConfirmationPane.title("Delete Keyspace");
this.deleteDatabaseConfirmationPane.databaseIdConfirmationText("Confirm by typing the keyspace id");
this.tableDataClient = new CassandraAPIDataClient(this.documentClientUtility);
this.tableDataClient = new CassandraAPIDataClient();
break;
}
});
@ -1066,13 +1042,6 @@ export default class Explorer {
// TODO: return result
}
public rebindDocumentClientUtility(documentClientUtility: DocumentClientUtilityBase): void {
this.documentClientUtility = documentClientUtility;
this._panes.forEach((pane: ViewModels.ContextualPane) => {
pane.documentClientUtility = documentClientUtility;
});
}
public copyUrlLink(src: any, event: MouseEvent): void {
const urlLinkInput: HTMLInputElement = document.getElementById("shareUrlLink") as HTMLInputElement;
urlLinkInput && urlLinkInput.select();
@ -1391,7 +1360,7 @@ export default class Explorer {
}
const deferred: Q.Deferred<void> = Q.defer();
this.documentClientUtility.readCollection(databaseId, collectionId).then((collection: DataModels.Collection) => {
readCollection(databaseId, collectionId).then((collection: DataModels.Collection) => {
this.resourceTokenCollection(new ResourceTokenCollection(this, databaseId, collection));
this.selectedNode(this.resourceTokenCollection());
deferred.resolve();
@ -1421,7 +1390,7 @@ export default class Explorer {
const refreshDatabases = (offers?: DataModels.Offer[]) => {
this._setLoadingStatusText("Fetching databases...");
this.documentClientUtility.readDatabases(null /*options*/).then(
readDatabases(null /*options*/).then(
(databases: DataModels.Database[]) => {
this._setLoadingStatusText("Successfully fetched databases.");
TelemetryProcessor.traceSuccess(
@ -1478,7 +1447,7 @@ export default class Explorer {
// Serverless accounts don't support offers call
refreshDatabases();
} else {
const offerPromise: Q.Promise<DataModels.Offer[]> = this.documentClientUtility.readOffers();
const offerPromise: Q.Promise<DataModels.Offer[]> = readOffers();
this._setLoadingStatusText("Fetching offers...");
offerPromise.then(
(offers: DataModels.Offer[]) => {
@ -1554,7 +1523,7 @@ export default class Explorer {
dataExplorerArea: Constants.Areas.ResourceTree
});
this.isRefreshingExplorer(true);
this.documentClientUtility.refreshCachedResources().then(
refreshCachedResources().then(
() => {
TelemetryProcessor.traceSuccess(
Action.LoadDatabases,
@ -2480,8 +2449,6 @@ export default class Explorer {
node: null,
title: notebookContentItem.name,
tabPath: notebookContentItem.path,
documentClientUtility: null,
collection: null,
selfLink: null,
masterKey: CosmosClient.masterKey() || "",
@ -2923,8 +2890,6 @@ export default class Explorer {
node: null,
title: title,
tabPath: title,
documentClientUtility: null,
collection: null,
selfLink: null,
hashLocation: hashLocation,

View File

@ -1,3 +1,4 @@
jest.mock("../../../Common/DocumentClientUtilityBase");
import React from "react";
import * as sinon from "sinon";
import { mount, ReactWrapper } from "enzyme";
@ -7,11 +8,11 @@ import { GraphExplorer, GraphExplorerProps, GraphAccessor, GraphHighlightedNodeD
import * as D3ForceGraph from "./D3ForceGraph";
import { GraphData } from "./GraphData";
import { TabComponent } from "../../Controls/Tabs/TabComponent";
import * as ViewModels from "../../../Contracts/ViewModels";
import * as DataModels from "../../../Contracts/DataModels";
import * as StorageUtility from "../../../Shared/StorageUtility";
import GraphTab from "../../Tabs/GraphTab";
import { ConsoleDataType } from "../../Menus/NotificationConsole/NotificationConsoleComponent";
import { queryDocuments, queryDocumentsPage } from "../../../Common/DocumentClientUtilityBase";
describe("Check whether query result is vertex array", () => {
it("should reject null as vertex array", () => {
@ -134,7 +135,7 @@ describe("GraphExplorer", () => {
const COLLECTION_SELF_LINK = "collectionSelfLink";
const gremlinRU = 789.12;
const createMockProps = (documentClientUtility?: any): GraphExplorerProps => {
const createMockProps = (): GraphExplorerProps => {
const graphConfig = GraphTab.createGraphConfig();
const graphConfigUi = GraphTab.createGraphConfigUiData(graphConfig);
@ -149,7 +150,6 @@ describe("GraphExplorer", () => {
onIsValidQueryChange: (isValidQuery: boolean): void => {},
collectionPartitionKeyProperty: "collectionPartitionKeyProperty",
documentClientUtility: documentClientUtility,
collectionRid: COLLECTION_RID,
collectionSelfLink: COLLECTION_SELF_LINK,
graphBackendEndpoint: "graphBackendEndpoint",
@ -188,7 +188,6 @@ describe("GraphExplorer", () => {
let wrapper: ReactWrapper;
let connectStub: sinon.SinonSpy;
let queryDocStub: sinon.SinonSpy;
let submitToBackendSpy: sinon.SinonSpy;
let renderResultAsJsonStub: sinon.SinonSpy;
let onMiddlePaneInitializedStub: sinon.SinonSpy;
@ -215,46 +214,6 @@ describe("GraphExplorer", () => {
[query: string]: AjaxResponse;
}
const createDocumentClientUtilityMock = (docDBResponse: AjaxResponse) => {
const mock = {
queryDocuments: () => {},
queryDocumentsPage: (
rid: string,
iterator: any,
firstItemIndex: number,
options: any
): Q.Promise<ViewModels.QueryResults> => {
const qresult = {
hasMoreResults: false,
firstItemIndex: firstItemIndex,
lastItemIndex: 0,
itemCount: 0,
documents: docDBResponse.response,
activityId: "",
headers: [] as any[],
requestCharge: gVRU
};
return Q.resolve(qresult);
}
};
const fakeIterator: any = {
nextItem: (callback: (error: any, document: DataModels.DocumentId) => void): void => {},
hasMoreResults: () => false,
executeNext: (callback: (error: any, documents: DataModels.DocumentId[], headers: any) => void): void => {}
};
queryDocStub = sinon.stub(mock, "queryDocuments").callsFake(
(container: ViewModels.DocumentRequestContainer, query: string, options: any): Q.Promise<any> => {
(fakeIterator as any)._query = query;
return Q.resolve(fakeIterator);
}
);
return mock;
};
const setupMocks = (
graphExplorer: GraphExplorer,
backendResponses: BackendResponses,
@ -333,7 +292,29 @@ describe("GraphExplorer", () => {
done: any,
ignoreD3Update: boolean
): GraphExplorer => {
const props: GraphExplorerProps = createMockProps(createDocumentClientUtilityMock(docDBResponse));
(queryDocuments as jest.Mock).mockImplementation((container: any, query: string, options: any) => {
return Q.resolve({
_query: query,
nextItem: (callback: (error: any, document: DataModels.DocumentId) => void): void => {},
hasMoreResults: () => false,
executeNext: (callback: (error: any, documents: DataModels.DocumentId[], headers: any) => void): void => {}
});
});
(queryDocumentsPage as jest.Mock).mockImplementation(
(rid: string, iterator: any, firstItemIndex: number, options: any) => {
return Q.resolve({
hasMoreResults: false,
firstItemIndex: firstItemIndex,
lastItemIndex: 0,
itemCount: 0,
documents: docDBResponse.response,
activityId: "",
headers: [] as any[],
requestCharge: gVRU
});
}
);
const props: GraphExplorerProps = createMockProps();
wrapper = mount(<GraphExplorer {...props} />);
graphExplorerInstance = wrapper.instance() as GraphExplorer;
setupMocks(graphExplorerInstance, backendResponses, done, ignoreD3Update);
@ -341,7 +322,7 @@ describe("GraphExplorer", () => {
};
const cleanUpStubsWrapper = () => {
queryDocStub.restore();
jest.resetAllMocks();
connectStub.restore();
submitToBackendSpy.restore();
renderResultAsJsonStub.restore();
@ -378,22 +359,11 @@ describe("GraphExplorer", () => {
expect((graphExplorerInstance.submitToBackend as sinon.SinonSpy).calledWith("g.V()")).toBe(false);
});
it("should submit g.V() as docdb query with proper query", () => {
expect(
(graphExplorerInstance.props.documentClientUtility.queryDocuments as sinon.SinonSpy).getCall(0).args[2]
).toBe(DOCDB_G_DOT_V_QUERY);
});
it("should submit g.V() as docdb query with proper parameters", () => {
expect(
(graphExplorerInstance.props.documentClientUtility.queryDocuments as sinon.SinonSpy).getCall(0).args[0]
).toEqual("databaseId");
expect(
(graphExplorerInstance.props.documentClientUtility.queryDocuments as sinon.SinonSpy).getCall(0).args[1]
).toEqual("collectionId");
expect(
(graphExplorerInstance.props.documentClientUtility.queryDocuments as sinon.SinonSpy).getCall(0).args[3]
).toEqual({ maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE, enableCrossPartitionQuery: true });
expect(queryDocuments).toBeCalledWith("databaseId", "collectionId", DOCDB_G_DOT_V_QUERY, {
maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE,
enableCrossPartitionQuery: true
});
});
it("should call backend thrice (user query, fetch outE, then fetch inE)", () => {
@ -426,22 +396,11 @@ describe("GraphExplorer", () => {
expect((graphExplorerInstance.submitToBackend as sinon.SinonSpy).calledWith("g.V()")).toBe(false);
});
it("should submit g.V() as docdb query with proper query", () => {
expect(
(graphExplorerInstance.props.documentClientUtility.queryDocuments as sinon.SinonSpy).getCall(0).args[2]
).toBe(DOCDB_G_DOT_V_QUERY);
});
it("should submit g.V() as docdb query with proper parameters", () => {
expect(
(graphExplorerInstance.props.documentClientUtility.queryDocuments as sinon.SinonSpy).getCall(0).args[0]
).toEqual("databaseId");
expect(
(graphExplorerInstance.props.documentClientUtility.queryDocuments as sinon.SinonSpy).getCall(0).args[1]
).toEqual("collectionId");
expect(
(graphExplorerInstance.props.documentClientUtility.queryDocuments as sinon.SinonSpy).getCall(0).args[3]
).toEqual({ maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE, enableCrossPartitionQuery: true });
expect(queryDocuments).toBeCalledWith("databaseId", "collectionId", DOCDB_G_DOT_V_QUERY, {
maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE,
enableCrossPartitionQuery: true
});
});
it("should call backend thrice (user query, fetch outE, then fetch inE)", () => {

View File

@ -28,7 +28,7 @@ import * as Constants from "../../../Common/Constants";
import { InputProperty } from "../../../Contracts/ViewModels";
import { QueryIterator, ItemDefinition, Resource } from "@azure/cosmos";
import LoadingIndicatorIcon from "../../../../images/LoadingIndicator_3Squares.gif";
import DocumentClientUtilityBase from "../../../Common/DocumentClientUtilityBase";
import { queryDocuments, queryDocumentsPage } from "../../../Common/DocumentClientUtilityBase";
export interface GraphAccessor {
applyFilter: () => void;
@ -47,7 +47,6 @@ export interface GraphExplorerProps {
onIsValidQueryChange: (isValidQuery: boolean) => void;
collectionPartitionKeyProperty: string;
documentClientUtility: DocumentClientUtilityBase;
collectionRid: string;
collectionSelfLink: string;
graphBackendEndpoint: string;
@ -697,7 +696,6 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
* @param cmd
*/
public submitToBackend(cmd: string): Q.Promise<GremlinClient.GremlinRequestResult> {
console.log("submit:", cmd);
const id = GraphExplorer.reportToConsole(ConsoleDataType.InProgress, `Executing: ${cmd}`);
this.setExecuteCounter(this.executeCounter + 1);
@ -730,14 +728,12 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
*/
public executeNonPagedDocDbQuery(query: string): Q.Promise<DataModels.DocumentId[]> {
// TODO maxItemCount: this reduces throttling, but won't cap the # of results
return this.props.documentClientUtility
.queryDocuments(this.props.databaseId, this.props.collectionId, query, {
return queryDocuments(this.props.databaseId, this.props.collectionId, query, {
maxItemCount: GraphExplorer.PAGE_ALL,
enableCrossPartitionQuery:
StorageUtility.LocalStorageUtility.getEntryString(StorageUtility.StorageKey.IsCrossPartitionQueryEnabled) ===
"true"
})
.then(
}).then(
(iterator: QueryIterator<ItemDefinition & Resource>) => {
return iterator.fetchNext().then(response => response.resources);
},
@ -1732,11 +1728,9 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
query = `select root.id, root.${this.props.collectionPartitionKeyProperty} from root where IS_DEFINED(root._isEdge) = false order by root._ts asc`;
}
return this.props.documentClientUtility
.queryDocuments(this.props.databaseId, this.props.collectionId, query, {
return queryDocuments(this.props.databaseId, this.props.collectionId, query, {
maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE,
enableCrossPartitionQuery:
LocalStorageUtility.getEntryString(StorageKey.IsCrossPartitionQueryEnabled) === "true"
enableCrossPartitionQuery: LocalStorageUtility.getEntryString(StorageKey.IsCrossPartitionQueryEnabled) === "true"
})
.then(
(iterator: QueryIterator<ItemDefinition & Resource>) => {
@ -1766,8 +1760,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
.currentDocDBQueryInfo.index + GraphExplorer.ROOT_LIST_PAGE_SIZE})`;
const id = GraphExplorer.reportToConsole(ConsoleDataType.InProgress, `Executing: ${queryInfoStr}`);
return this.props.documentClientUtility
.queryDocumentsPage(
return queryDocumentsPage(
this.props.collectionRid,
this.currentDocDBQueryInfo.iterator,
this.currentDocDBQueryInfo.index,

View File

@ -3,7 +3,6 @@ import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
import { GraphConfig } from "../../Tabs/GraphTab";
import * as ViewModels from "../../../Contracts/ViewModels";
import { GraphExplorer, GraphAccessor } from "./GraphExplorer";
import DocumentClientUtilityBase from "../../../Common/DocumentClientUtilityBase";
interface Parameter {
onIsNewVertexDisabledChange: (isEnabled: boolean) => void;
@ -18,7 +17,6 @@ interface Parameter {
graphConfig?: GraphConfig;
collectionPartitionKeyProperty: string;
documentClientUtility: DocumentClientUtilityBase;
collectionRid: string;
collectionSelfLink: string;
graphBackendEndpoint: string;
@ -51,7 +49,6 @@ export class GraphExplorerAdapter implements ReactAdapter {
onIsGraphDisplayed={this.params.onIsGraphDisplayed}
onResetDefaultGraphConfigValues={this.params.onResetDefaultGraphConfigValues}
collectionPartitionKeyProperty={this.params.collectionPartitionKeyProperty}
documentClientUtility={this.params.documentClientUtility}
collectionRid={this.params.collectionRid}
collectionSelfLink={this.params.collectionSelfLink}
graphBackendEndpoint={this.params.graphBackendEndpoint}

View File

@ -57,7 +57,6 @@ export default class NotebookManager {
this.gitHubOAuthService = new GitHubOAuthService(this.junoClient);
this.gitHubClient = new GitHubClient(this.onGitHubClientError);
this.gitHubReposPane = new GitHubReposPane({
documentClientUtility: this.params.container.documentClientUtility,
id: "gitHubReposPane",
visible: ko.observable<boolean>(false),
container: this.params.container,

View File

@ -41,7 +41,7 @@ describe("Add Collection Pane", () => {
};
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
explorer.hasAutoPilotV2FeatureFlag = ko.computed<boolean>(() => true);
});

View File

@ -20,6 +20,7 @@ import { createMongoCollectionWithARM, createMongoCollectionWithProxy } from "..
import { DynamicListItem } from "../Controls/DynamicList/DynamicListComponent";
import { HashMap } from "../../Common/HashMap";
import { PlatformType } from "../../PlatformType";
import { refreshCachedResources, getOrCreateDatabaseAndCollection } from "../../Common/DocumentClientUtilityBase";
export default class AddCollectionPane extends ContextualPaneBase {
public defaultExperience: ko.Computed<string>;
@ -941,8 +942,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
)
);
} else {
createCollectionFunc = () =>
this.container.documentClientUtility.getOrCreateDatabaseAndCollection(createRequest, options);
createCollectionFunc = () => getOrCreateDatabaseAndCollection(createRequest, options);
}
createCollectionFunc().then(
@ -978,7 +978,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
};
TelemetryProcessor.traceSuccess(Action.CreateCollection, addCollectionPaneSuccessMessage, startKey);
this.resetData();
return this.container.documentClientUtility.refreshCachedResources().then(() => {
return refreshCachedResources().then(() => {
this.container.refreshAllDatabases();
});
},

View File

@ -40,7 +40,6 @@ describe("Add Database Pane", () => {
beforeEach(() => {
explorer = new Explorer({
documentClientUtility: null,
notificationsClient: null,
isEmulator: false
});

View File

@ -16,6 +16,7 @@ import { CassandraAPIDataClient } from "../Tables/TableDataClient";
import { ContextualPaneBase } from "./ContextualPaneBase";
import { CosmosClient } from "../../Common/CosmosClient";
import { PlatformType } from "../../PlatformType";
import { refreshCachedOffers, refreshCachedResources, createDatabase } from "../../Common/DocumentClientUtilityBase";
export default class AddDatabasePane extends ContextualPaneBase {
public defaultExperience: ko.Computed<string>;
@ -334,10 +335,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
) {
AddDbUtilities.createSqlDatabase(this.container.armEndpoint(), createDatabaseParameters, autoPilotSettings).then(
() => {
Promise.all([
this.container.documentClientUtility.refreshCachedOffers(),
this.container.documentClientUtility.refreshCachedResources()
]).then(() => {
Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => {
this._onCreateDatabaseSuccess(createDatabaseParameters.offerThroughput, startKey);
});
}
@ -354,10 +352,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
createDatabaseParameters,
autoPilotSettings
).then(() => {
Promise.all([
this.container.documentClientUtility.refreshCachedOffers(),
this.container.documentClientUtility.refreshCachedResources()
]).then(() => {
Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => {
this._onCreateDatabaseSuccess(createDatabaseParameters.offerThroughput, startKey);
});
});
@ -373,10 +368,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
createDatabaseParameters,
autoPilotSettings
).then(() => {
Promise.all([
this.container.documentClientUtility.refreshCachedOffers(),
this.container.documentClientUtility.refreshCachedResources()
]).then(() => {
Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => {
this._onCreateDatabaseSuccess(createDatabaseParameters.offerThroughput, startKey);
});
});
@ -413,7 +405,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
autoPilot,
hasAutoPilotV2FeatureFlag: this.hasAutoPilotV2FeatureFlag()
};
this.container.documentClientUtility.createDatabase(createRequest).then(
createDatabase(createRequest).then(
(database: DataModels.Database) => {
this._onCreateDatabaseSuccess(offerThroughput, telemetryStartKey);
},
@ -464,10 +456,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
startKey: number
): void {
AddDbUtilities.createCassandraKeyspace(armEndpoint, createKeyspaceParameters, autoPilotSettings).then(() => {
Promise.all([
this.container.documentClientUtility.refreshCachedOffers(),
this.container.documentClientUtility.refreshCachedResources()
]).then(() => {
Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => {
this._onCreateDatabaseSuccess(createKeyspaceParameters.offerThroughput, startKey);
});
});

View File

@ -5,7 +5,6 @@ import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstan
import { KeyCodes } from "../../Common/Constants";
import { WaitsForTemplateViewModel } from "../WaitsForTemplateViewModel";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
// TODO: Use specific actions for logging telemetry data
@ -17,14 +16,12 @@ export abstract class ContextualPaneBase extends WaitsForTemplateViewModel imple
public formErrors: ko.Observable<string>;
public title: ko.Observable<string>;
public visible: ko.Observable<boolean>;
public documentClientUtility: DocumentClientUtilityBase;
public isExecuting: ko.Observable<boolean>;
constructor(options: ViewModels.PaneOptions) {
super();
this.id = options.id;
this.container = options.container;
this.documentClientUtility = options.documentClientUtility;
this.visible = options.visible || ko.observable(false);
this.firstFieldHasFocus = ko.observable<boolean>(false);
this.formErrors = ko.observable<string>();

View File

@ -1,3 +1,4 @@
jest.mock("../../Common/DocumentClientUtilityBase");
import * as ko from "knockout";
import * as sinon from "sinon";
import Q from "q";
@ -6,7 +7,7 @@ import * as ViewModels from "../../Contracts/ViewModels";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
import DeleteCollectionConfirmationPane from "./DeleteCollectionConfirmationPane";
import DeleteFeedback from "../../Common/DeleteFeedback";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import { deleteCollection } from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { TreeNode } from "../../Contracts/ViewModels";
@ -16,7 +17,7 @@ describe("Delete Collection Confirmation Pane", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
});
it("should be true if 1 database and 1 collection", () => {
@ -55,15 +56,11 @@ describe("Delete Collection Confirmation Pane", () => {
describe("shouldRecordFeedback()", () => {
it("should return true if last collection and database does not have shared throughput else false", () => {
let fakeDocumentClientUtility = sinon.createStubInstance<DocumentClientUtilityBase>(
DocumentClientUtilityBase as any
);
let fakeExplorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
let fakeExplorer = new Explorer({ notificationsClient: null, isEmulator: false });
fakeExplorer.isNotificationConsoleExpanded = ko.observable<boolean>(false);
fakeExplorer.refreshAllDatabases = () => Q.resolve();
let pane = new DeleteCollectionConfirmationPane({
documentClientUtility: fakeDocumentClientUtility as any,
id: "deletecollectionconfirmationpane",
visible: ko.observable<boolean>(false),
container: fakeExplorer
@ -96,8 +93,7 @@ describe("Delete Collection Confirmation Pane", () => {
it("it should log feedback if last collection and database is not shared", () => {
let selectedCollectionId = "testCol";
let fakeDocumentClientUtility = {} as DocumentClientUtilityBase;
fakeDocumentClientUtility.deleteCollection = () => Q(null);
(deleteCollection as jest.Mock).mockResolvedValue(null);
let fakeExplorer = {} as Explorer;
fakeExplorer.findSelectedCollection = () => {
return {
@ -120,14 +116,12 @@ describe("Delete Collection Confirmation Pane", () => {
return false;
});
fakeExplorer.documentClientUtility = fakeDocumentClientUtility;
fakeExplorer.selectedNode = ko.observable<TreeNode>();
fakeExplorer.isLastCollection = () => true;
fakeExplorer.isSelectedDatabaseShared = () => false;
fakeExplorer.refreshAllDatabases = () => Q.resolve();
let pane = new DeleteCollectionConfirmationPane({
documentClientUtility: fakeDocumentClientUtility as any,
id: "deletecollectionconfirmationpane",
visible: ko.observable<boolean>(false),
container: fakeExplorer as any

View File

@ -11,6 +11,7 @@ import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility"
import DeleteFeedback from "../../Common/DeleteFeedback";
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { deleteCollection } from "../../Common/DocumentClientUtilityBase";
export default class DeleteCollectionConfirmationPane extends ContextualPaneBase {
public collectionIdConfirmationText: ko.Observable<string>;
@ -58,7 +59,7 @@ export default class DeleteCollectionConfirmationPane extends ContextualPaneBase
this.container
);
} else {
promise = this.container.documentClientUtility.deleteCollection(selectedCollection);
promise = deleteCollection(selectedCollection);
}
return promise.then(
() => {

View File

@ -1,23 +1,28 @@
jest.mock("../../Common/DocumentClientUtilityBase");
jest.mock("../../Shared/Telemetry/TelemetryProcessor");
import * as ko from "knockout";
import * as sinon from "sinon";
import Q from "q";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
import DeleteDatabaseConfirmationPane from "./DeleteDatabaseConfirmationPane";
import DeleteFeedback from "../../Common/DeleteFeedback";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { TreeNode } from "../../Contracts/ViewModels";
import { TabsManager } from "../Tabs/TabsManager";
import { deleteDatabase } from "../../Common/DocumentClientUtilityBase";
describe("Delete Database Confirmation Pane", () => {
describe("Explorer.isLastDatabase() and Explorer.isLastNonEmptyDatabase()", () => {
let explorer: Explorer;
beforeAll(() => {
(deleteDatabase as jest.Mock).mockResolvedValue(undefined);
});
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
});
it("should be true if only 1 database", () => {
@ -49,12 +54,10 @@ describe("Delete Database Confirmation Pane", () => {
describe("shouldRecordFeedback()", () => {
it("should return true if last non empty database or is last database that has shared throughput, else false", () => {
let fakeDocumentClientUtility = {} as DocumentClientUtilityBase;
let fakeExplorer = {} as Explorer;
fakeExplorer.isNotificationConsoleExpanded = ko.observable<boolean>(false);
let pane = new DeleteDatabaseConfirmationPane({
documentClientUtility: fakeDocumentClientUtility as any,
id: "deletedatabaseconfirmationpane",
visible: ko.observable<boolean>(false),
container: fakeExplorer as any
@ -78,20 +81,8 @@ describe("Delete Database Confirmation Pane", () => {
});
describe("submit()", () => {
let telemetryProcessorSpy: sinon.SinonSpy;
beforeEach(() => {
telemetryProcessorSpy = sinon.spy(TelemetryProcessor, "trace");
});
afterEach(() => {
telemetryProcessorSpy.restore();
});
it("on submit() it should log feedback if last non empty database or is last database that has shared throughput", () => {
let selectedDatabaseId = "testDB";
let fakeDocumentClientUtility = {} as DocumentClientUtilityBase;
fakeDocumentClientUtility.deleteDatabase = () => Q.resolve(null);
let fakeExplorer = {} as Explorer;
fakeExplorer.findSelectedDatabase = () => {
return {
@ -114,13 +105,11 @@ describe("Delete Database Confirmation Pane", () => {
fakeExplorer.isPreferredApiCassandra = ko.computed(() => {
return false;
});
fakeExplorer.documentClientUtility = fakeDocumentClientUtility;
fakeExplorer.selectedNode = ko.observable<TreeNode>();
fakeExplorer.tabsManager = new TabsManager();
fakeExplorer.isLastNonEmptyDatabase = () => true;
let pane = new DeleteDatabaseConfirmationPane({
documentClientUtility: fakeDocumentClientUtility as any,
id: "deletedatabaseconfirmationpane",
visible: ko.observable<boolean>(false),
container: fakeExplorer as any
@ -130,15 +119,12 @@ describe("Delete Database Confirmation Pane", () => {
pane.databaseDeleteFeedback(Feedback);
return pane.submit().then(() => {
expect(telemetryProcessorSpy.called).toBe(true);
let deleteFeedback = new DeleteFeedback(SubscriptionId, AccountName, DataModels.ApiKind.SQL, Feedback);
expect(
telemetryProcessorSpy.calledWith(
expect(TelemetryProcessor.trace).toHaveBeenCalledWith(
Action.DeleteDatabase,
ActionModifiers.Mark,
JSON.stringify(deleteFeedback, Object.getOwnPropertyNames(deleteFeedback))
)
).toBe(true);
);
});
});
});

View File

@ -12,6 +12,7 @@ import DeleteFeedback from "../../Common/DeleteFeedback";
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { deleteDatabase } from "../../Common/DocumentClientUtilityBase";
export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
public databaseIdConfirmationText: ko.Observable<string>;
@ -59,7 +60,7 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
this.container
);
} else {
promise = this.container.documentClientUtility.deleteDatabase(selectedDatabase);
promise = deleteDatabase(selectedDatabase);
}
return promise.then(
() => {

View File

@ -7,7 +7,7 @@ describe("Settings Pane", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
});
it("should be true for SQL API", () => {

View File

@ -15,8 +15,14 @@ import * as TableEntityProcessor from "./TableEntityProcessor";
import * as ViewModels from "../../Contracts/ViewModels";
import { MessageTypes } from "../../Contracts/ExplorerContracts";
import { sendMessage } from "../../Common/MessageHandler";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
import {
queryDocuments,
refreshCachedResources,
deleteDocument,
updateDocument,
createDocument
} from "../../Common/DocumentClientUtilityBase";
export interface CassandraTableKeys {
partitionKeys: CassandraTableKey[];
@ -29,11 +35,7 @@ export interface CassandraTableKey {
}
export abstract class TableDataClient {
public documentClientUtility: DocumentClientUtilityBase;
constructor(documentClientUtility: DocumentClientUtilityBase) {
this.documentClientUtility = documentClientUtility;
}
constructor() {}
public abstract createDocument(
collection: ViewModels.Collection,
@ -65,12 +67,10 @@ export class TablesAPIDataClient extends TableDataClient {
entity: Entities.ITableEntity
): Q.Promise<Entities.ITableEntity> {
const deferred = Q.defer<Entities.ITableEntity>();
this.documentClientUtility
.createDocument(
createDocument(
collection,
TableEntityProcessor.convertEntityToNewDocument(<Entities.ITableEntityForTablesAPI>entity)
)
.then(
).then(
(newDocument: any) => {
const newEntity = TableEntityProcessor.convertDocumentsToEntities([newDocument])[0];
deferred.resolve(newEntity);
@ -88,13 +88,12 @@ export class TablesAPIDataClient extends TableDataClient {
entity: Entities.ITableEntity
): Q.Promise<Entities.ITableEntity> {
const deferred = Q.defer<Entities.ITableEntity>();
this.documentClientUtility
.updateDocument(
updateDocument(
collection,
originalDocument,
TableEntityProcessor.convertEntityToNewDocument(<Entities.ITableEntityForTablesAPI>entity)
)
.then(
).then(
(newDocument: any) => {
const newEntity = TableEntityProcessor.convertDocumentsToEntities([newDocument])[0];
deferred.resolve(newEntity);
@ -114,7 +113,7 @@ export class TablesAPIDataClient extends TableDataClient {
let options: any = {};
options.enableCrossPartitionQuery = HeadersUtility.shouldEnableCrossPartitionKey();
this.documentClientUtility.queryDocuments(collection.databaseId, collection.id(), query, options).then(
queryDocuments(collection.databaseId, collection.id(), query, options).then(
iterator => {
iterator
.fetchNext()
@ -150,7 +149,7 @@ export class TablesAPIDataClient extends TableDataClient {
documentsToDelete &&
documentsToDelete.forEach(document => {
document.id = ko.observable<string>(document.id);
let promise: Q.Promise<any> = this.documentClientUtility.deleteDocument(collection, document);
let promise: Q.Promise<any> = deleteDocument(collection, document);
promiseArray.push(promise);
});
return Q.all(promiseArray);
@ -425,7 +424,7 @@ export class CassandraAPIDataClient extends TableDataClient {
ConsoleDataType.Info,
`Successfully created a keyspace with query ${createKeyspaceQuery}`
);
explorer.documentClientUtility.refreshCachedResources().finally(() => deferred.resolve());
refreshCachedResources().finally(() => deferred.resolve());
},
reason => {
NotificationConsoleUtils.logConsoleMessage(
@ -472,7 +471,7 @@ export class CassandraAPIDataClient extends TableDataClient {
ConsoleDataType.Info,
`Successfully created a table with query ${createTableQuery}`
);
this.documentClientUtility.refreshCachedResources(null).then(
refreshCachedResources(null).then(
() => {
deferred.resolve();
},
@ -521,7 +520,7 @@ export class CassandraAPIDataClient extends TableDataClient {
ConsoleDataType.Info,
`Successfully deleted resource with query ${deleteQuery}`
);
this.documentClientUtility.refreshCachedResources(null).then(
refreshCachedResources(null).then(
() => {
deferred.resolve();
},

View File

@ -21,6 +21,13 @@ import DeleteIcon from "../../../images/delete.svg";
import { QueryIterator, ItemDefinition, Resource, ConflictDefinition } from "@azure/cosmos";
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
import Explorer from "../Explorer";
import {
queryConflicts,
deleteConflict,
deleteDocument,
createDocument,
updateDocument
} from "../../Common/DocumentClientUtilityBase";
export default class ConflictsTab extends TabsBase {
public selectedConflictId: ko.Observable<ViewModels.ConflictId>;
@ -286,7 +293,7 @@ export default class ConflictsTab extends TabsBase {
if (selectedConflict.operationType === Constants.ConflictOperationType.Replace) {
const documentContent = JSON.parse(this.selectedConflictContent());
operationPromise = this._container.documentClientUtility.updateDocument(
operationPromise = updateDocument(
this.collection,
selectedConflict.buildDocumentIdFromConflict(documentContent[selectedConflict.partitionKeyProperty]),
documentContent
@ -296,13 +303,13 @@ export default class ConflictsTab extends TabsBase {
if (selectedConflict.operationType === Constants.ConflictOperationType.Create) {
const documentContent = JSON.parse(this.selectedConflictContent());
operationPromise = this._container.documentClientUtility.createDocument(this.collection, documentContent);
operationPromise = createDocument(this.collection, documentContent);
}
if (selectedConflict.operationType === Constants.ConflictOperationType.Delete && !!this.selectedConflictContent()) {
const documentContent = JSON.parse(this.selectedConflictContent());
operationPromise = this._container.documentClientUtility.deleteDocument(
operationPromise = deleteDocument(
this.collection,
selectedConflict.buildDocumentIdFromConflict(documentContent[selectedConflict.partitionKeyProperty])
);
@ -311,7 +318,7 @@ export default class ConflictsTab extends TabsBase {
return operationPromise
.then(
() => {
return this._container.documentClientUtility.deleteConflict(this.collection, selectedConflict).then(() => {
return deleteConflict(this.collection, selectedConflict).then(() => {
this.conflictIds.remove((conflictId: ViewModels.ConflictId) => conflictId.rid === selectedConflict.rid);
this.selectedConflictContent("");
this.selectedConflictCurrent("");
@ -370,8 +377,7 @@ export default class ConflictsTab extends TabsBase {
conflictResourceId: selectedConflict.resourceId
});
return this._container.documentClientUtility
.deleteConflict(this.collection, selectedConflict)
return deleteConflict(this.collection, selectedConflict)
.then(
() => {
this.conflictIds.remove((conflictId: ViewModels.ConflictId) => conflictId.rid === selectedConflict.rid);
@ -491,7 +497,7 @@ export default class ConflictsTab extends TabsBase {
const query: string = undefined;
let options: any = {};
options.enableCrossPartitionQuery = HeadersUtility.shouldEnableCrossPartitionKey();
return this.documentClientUtility.queryConflicts(this.collection.databaseId, this.collection.id(), query, options);
return queryConflicts(this.collection.databaseId, this.collection.id(), query, options);
}
public loadNextPage(): Q.Promise<any> {

View File

@ -18,6 +18,7 @@ import { CosmosClient } from "../../Common/CosmosClient";
import { PlatformType } from "../../PlatformType";
import { RequestOptions } from "@azure/cosmos/dist-esm";
import Explorer from "../Explorer";
import { updateOfferThroughputBeyondLimit, updateOffer } from "../../Common/DocumentClientUtilityBase";
const updateThroughputBeyondLimitWarningMessage: string = `
You are about to request an increase in throughput beyond the pre-allocated capacity.
@ -499,13 +500,13 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
delete newOffer.content.offerAutopilotSettings;
}
const updateOfferPromise = this.container.documentClientUtility
.updateOffer(this.database.offer(), newOffer, headerOptions)
.then((updatedOffer: DataModels.Offer) => {
const updateOfferPromise = updateOffer(this.database.offer(), newOffer, headerOptions).then(
(updatedOffer: DataModels.Offer) => {
this.database.offer(updatedOffer);
this.database.offer.valueHasMutated();
this._wasAutopilotOriginallySet(this.isAutoPilotSelected());
});
}
);
promises.push(updateOfferPromise);
} else {
if (this.throughput.editableIsDirty() || this.isAutoPilotSelected.editableIsDirty()) {
@ -527,9 +528,7 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
throughput: newThroughput,
offerIsRUPerMinuteThroughputEnabled: false
};
const updateOfferBeyondLimitPromise: Q.Promise<void> = this.documentClientUtility
.updateOfferThroughputBeyondLimit(requestPayload)
.then(
const updateOfferBeyondLimitPromise: Q.Promise<void> = updateOfferThroughputBeyondLimit(requestPayload).then(
() => {
this.database.offer().content.offerThroughput = originalThroughputValue;
this.throughput(originalThroughputValue);
@ -577,13 +576,13 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
newOffer.content.offerAutopilotSettings = { maxThroughput: 0 };
}
const updateOfferPromise = this.container.documentClientUtility
.updateOffer(this.database.offer(), newOffer, headerOptions)
.then((updatedOffer: DataModels.Offer) => {
const updateOfferPromise = updateOffer(this.database.offer(), newOffer, headerOptions).then(
(updatedOffer: DataModels.Offer) => {
this._wasAutopilotOriginallySet(this.isAutoPilotSelected());
this.database.offer(updatedOffer);
this.database.offer.valueHasMutated();
});
}
);
promises.push(updateOfferPromise);
}

View File

@ -3,7 +3,6 @@ import * as ViewModels from "../../Contracts/ViewModels";
import * as Constants from "../../Common/Constants";
import DocumentsTab from "./DocumentsTab";
import Explorer from "../Explorer";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
describe("Documents tab", () => {
describe("buildQuery", () => {
@ -14,7 +13,6 @@ describe("Documents tab", () => {
tabKind: ViewModels.CollectionTabKind.Documents,
title: "",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
isActive: ko.observable<boolean>(false),
@ -28,13 +26,11 @@ describe("Documents tab", () => {
describe("showPartitionKey", () => {
const explorer = new Explorer({
documentClientUtility: null,
notificationsClient: null,
isEmulator: false
});
const mongoExplorer = new Explorer({
documentClientUtility: null,
notificationsClient: null,
isEmulator: false
});
@ -97,7 +93,6 @@ describe("Documents tab", () => {
tabKind: ViewModels.CollectionTabKind.Documents,
title: "",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
isActive: ko.observable<boolean>(false),
@ -116,7 +111,6 @@ describe("Documents tab", () => {
tabKind: ViewModels.CollectionTabKind.Documents,
title: "",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
isActive: ko.observable<boolean>(false),
@ -135,7 +129,6 @@ describe("Documents tab", () => {
tabKind: ViewModels.CollectionTabKind.Documents,
title: "",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
isActive: ko.observable<boolean>(false),
@ -154,7 +147,6 @@ describe("Documents tab", () => {
tabKind: ViewModels.CollectionTabKind.Documents,
title: "",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
isActive: ko.observable<boolean>(false),
@ -173,7 +165,6 @@ describe("Documents tab", () => {
tabKind: ViewModels.CollectionTabKind.Documents,
title: "",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
isActive: ko.observable<boolean>(false),

View File

@ -26,6 +26,13 @@ import { extractPartitionKey, PartitionKeyDefinition, QueryIterator, ItemDefinit
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
import Explorer from "../Explorer";
import {
readDocument,
queryDocuments,
deleteDocument,
updateDocument,
createDocument
} from "../../Common/DocumentClientUtilityBase";
export default class DocumentsTab extends TabsBase implements ViewModels.DocumentsTab {
public selectedDocumentId: ko.Observable<ViewModels.DocumentId>;
@ -442,8 +449,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
});
const document = JSON.parse(this.selectedDocumentContent());
this.isExecuting(true);
return this.documentClientUtility
.createDocument(this.collection, document)
return createDocument(this.collection, document)
.then(
(savedDocument: any) => {
const value: string = this.renderObjectForEditor(savedDocument || {}, null, 4);
@ -516,8 +522,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
tabTitle: this.tabTitle()
});
this.isExecuting(true);
return this.documentClientUtility
.updateDocument(this.collection, selectedDocumentId, documentContent)
return updateDocument(this.collection, selectedDocumentId, documentContent)
.then(
(updatedDocument: any) => {
const value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
@ -665,7 +670,7 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
};
protected __deleteDocument(documentId: ViewModels.DocumentId): Q.Promise<any> {
return this.documentClientUtility.deleteDocument(this.collection, documentId);
return deleteDocument(this.collection, documentId);
}
private _deleteDocument(selectedDocumentId: ViewModels.DocumentId): Q.Promise<any> {
@ -724,12 +729,12 @@ export default class DocumentsTab extends TabsBase implements ViewModels.Documen
options.partitionKey = this._resourceTokenPartitionKey;
}
return this.documentClientUtility.queryDocuments(this.collection.databaseId, this.collection.id(), query, options);
return queryDocuments(this.collection.databaseId, this.collection.id(), query, options);
}
public selectDocument(documentId: ViewModels.DocumentId): Q.Promise<any> {
this.selectedDocumentId(documentId);
return this.documentClientUtility.readDocument(this.collection, documentId).then((content: any) => {
return readDocument(this.collection, documentId).then((content: any) => {
this.initDocumentEditor(documentId, content);
});
}

View File

@ -83,7 +83,6 @@ export default class GraphTab extends TabsBase implements ViewModels.Tab {
onIsFilterQueryLoading: (isFilterQueryLoading: boolean): void => this.isFilterQueryLoading(isFilterQueryLoading),
onIsValidQuery: (isValidQuery: boolean): void => this.isValidQuery(isValidQuery),
collectionPartitionKeyProperty: options.collectionPartitionKeyProperty,
documentClientUtility: this.documentClientUtility,
collectionRid: this.rid,
collectionSelfLink: options.selfLink,
graphBackendEndpoint: GraphTab.getGremlinEndpoint(options.account),
@ -101,7 +100,6 @@ export default class GraphTab extends TabsBase implements ViewModels.Tab {
this.isFilterQueryLoading = ko.observable(false);
this.isValidQuery = ko.observable(true);
this.documentClientUtility = options.documentClientUtility;
this.toolbarViewModel = ko.observable<Toolbar>();
}

View File

@ -25,7 +25,6 @@ describe("Query Tab", () => {
database: database,
title: "",
tabPath: "",
documentClientUtility: container.documentClientUtility,
selfLink: "",
isActive: ko.observable<boolean>(false),
hashLocation: "",
@ -51,7 +50,7 @@ describe("Query Tab", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
});
it("should be true for accounts using SQL API", () => {
@ -71,7 +70,7 @@ describe("Query Tab", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
});
it("should be visible when using a supported API", () => {

View File

@ -16,6 +16,7 @@ import { QueryUtils } from "../../Utils/QueryUtils";
import SaveQueryIcon from "../../../images/save-cosmos.svg";
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
import { queryDocuments, queryDocumentsPage } from "../../Common/DocumentClientUtilityBase";
enum ToggleState {
Result,
@ -290,12 +291,7 @@ export default class QueryTab extends TabsBase implements ViewModels.QueryTab, V
options.enableCrossPartitionQuery = HeadersUtility.shouldEnableCrossPartitionKey();
const queryDocuments = (firstItemIndex: number) =>
this.documentClientUtility.queryDocumentsPage(
this.collection && this.collection.id(),
this._iterator,
firstItemIndex,
options
);
queryDocumentsPage(this.collection && this.collection.id(), this._iterator, firstItemIndex, options);
this.isExecuting(true);
return QueryUtils.queryPagesUntilContentPresent(firstItemIndex, queryDocuments)
.then(
@ -497,9 +493,9 @@ export default class QueryTab extends TabsBase implements ViewModels.QueryTab, V
}
return Q(
this.documentClientUtility
.queryDocuments(this.collection.databaseId, this.collection.id(), this.sqlStatementToExecute(), options)
.then(iterator => (this._iterator = iterator))
queryDocuments(this.collection.databaseId, this.collection.id(), this.sqlStatementToExecute(), options).then(
iterator => (this._iterator = iterator)
)
);
}

View File

@ -4,7 +4,6 @@ import * as ko from "knockout";
import * as ViewModels from "../../Contracts/ViewModels";
import Collection from "../Tree/Collection";
import Database from "../Tree/Database";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
import SettingsTab from "../Tabs/SettingsTab";
@ -63,8 +62,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: undefined,
selfLink: "",
hashLocation: "",
isActive: ko.observable(false),
@ -80,7 +77,7 @@ describe("Settings tab", () => {
};
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
explorer.hasAutoPilotV2FeatureFlag = ko.computed<boolean>(() => true);
});
@ -179,7 +176,7 @@ describe("Settings tab", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
explorer.hasAutoPilotV2FeatureFlag = ko.computed<boolean>(() => true);
});
@ -188,8 +185,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
isActive: ko.observable(false),
@ -212,7 +207,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
@ -231,7 +225,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
@ -261,7 +254,7 @@ describe("Settings tab", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
explorer.hasAutoPilotV2FeatureFlag = ko.computed<boolean>(() => true);
});
@ -270,7 +263,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
@ -287,7 +279,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
@ -313,7 +304,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
@ -346,7 +336,6 @@ describe("Settings tab", () => {
function getCollection(defaultApi: string, partitionKeyOption: PartitionKeyOption) {
const explorer = new Explorer({
documentClientUtility: null,
notificationsClient: null,
isEmulator: false
});
@ -394,7 +383,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
@ -483,7 +471,6 @@ describe("Settings tab", () => {
describe("AutoPilot", () => {
function getCollection(autoPilotTier: DataModels.AutopilotTier) {
const explorer = new Explorer({
documentClientUtility: null,
notificationsClient: null,
isEmulator: false
});
@ -540,7 +527,6 @@ describe("Settings tab", () => {
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",

View File

@ -18,6 +18,11 @@ import { CosmosClient } from "../../Common/CosmosClient";
import { PlatformType } from "../../PlatformType";
import { RequestOptions } from "@azure/cosmos/dist-esm";
import Explorer from "../Explorer";
import {
updateOfferThroughputBeyondLimit,
updateOffer,
updateCollection
} from "../../Common/DocumentClientUtilityBase";
const ttlWarning: string = `
The system will automatically delete items based on the TTL value (in seconds) you provide, without needing a delete operation explicitly issued by a client application.
@ -1062,9 +1067,8 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
}
const newCollection: DataModels.Collection = _.extend({}, this.collection.rawDataModel, newCollectionAttributes);
const updateCollectionPromise = this.container.documentClientUtility
.updateCollection(this.collection.databaseId, this.collection, newCollection)
.then((updatedCollection: DataModels.Collection) => {
const updateCollectionPromise = updateCollection(this.collection.databaseId, this.collection, newCollection).then(
(updatedCollection: DataModels.Collection) => {
this.collection.rawDataModel = updatedCollection;
this.collection.defaultTtl(updatedCollection.defaultTtl);
this.collection.analyticalStorageTtl(updatedCollection.analyticalStorageTtl);
@ -1073,7 +1077,8 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
this.collection.conflictResolutionPolicy(updatedCollection.conflictResolutionPolicy);
this.collection.changeFeedPolicy(updatedCollection.changeFeedPolicy);
this.collection.geospatialConfig(updatedCollection.geospatialConfig);
});
}
);
promises.push(updateCollectionPromise);
}
@ -1147,9 +1152,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
throughput: newThroughput,
offerIsRUPerMinuteThroughputEnabled: isRUPerMinuteThroughputEnabled
};
const updateOfferBeyondLimitPromise: Q.Promise<void> = this.documentClientUtility
.updateOfferThroughputBeyondLimit(requestPayload)
.then(
const updateOfferBeyondLimitPromise: Q.Promise<void> = updateOfferThroughputBeyondLimit(requestPayload).then(
() => {
this.collection.offer().content.offerThroughput = originalThroughputValue;
this.throughput(originalThroughputValue);
@ -1183,12 +1186,12 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
);
promises.push(updateOfferBeyondLimitPromise);
} else {
const updateOfferPromise = this.documentClientUtility
.updateOffer(this.collection.offer(), newOffer, headerOptions)
.then((updatedOffer: DataModels.Offer) => {
const updateOfferPromise = updateOffer(this.collection.offer(), newOffer, headerOptions).then(
(updatedOffer: DataModels.Offer) => {
this.collection.offer(updatedOffer);
this.collection.offer.valueHasMutated();
});
}
);
promises.push(updateOfferPromise);
}

View File

@ -10,6 +10,7 @@ import ScriptTabBase from "./ScriptTabBase";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg";
import StoredProcedure from "../Tree/StoredProcedure";
import { createStoredProcedure, updateStoredProcedure } from "../../Common/DocumentClientUtilityBase";
enum ToggleState {
Result = "result",
@ -81,8 +82,7 @@ export default class StoredProcedureTab extends ScriptTabBase implements ViewMod
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
});
return this.documentClientUtility
.updateStoredProcedure(this.collection, data)
return updateStoredProcedure(this.collection, data)
.then(
(updatedResource: DataModels.StoredProcedure) => {
this.resource(updatedResource);
@ -240,8 +240,7 @@ export default class StoredProcedureTab extends ScriptTabBase implements ViewMod
tabTitle: this.tabTitle()
});
return this.documentClientUtility
.createStoredProcedure(this.collection, resource)
return createStoredProcedure(this.collection, resource)
.then(
createdResource => {
this.tabTitle(createdResource.id);

View File

@ -7,13 +7,11 @@ import { RouteHandler } from "../../RouteHandlers/RouteHandler";
import { WaitsForTemplateViewModel } from "../WaitsForTemplateViewModel";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import ThemeUtility from "../../Common/ThemeUtility";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
// TODO: Use specific actions for logging telemetry data
export default class TabsBase extends WaitsForTemplateViewModel implements ViewModels.Tab {
public closeTabButton: ViewModels.Button;
public documentClientUtility: DocumentClientUtilityBase;
public node: ViewModels.TreeNode;
public collection: ViewModels.CollectionBase;
public database: ViewModels.Database;
@ -39,7 +37,6 @@ export default class TabsBase extends WaitsForTemplateViewModel implements ViewM
const id = new Date().getTime().toString();
this._theme = ThemeUtility.getMonacoTheme(options.theme);
this.documentClientUtility = options.documentClientUtility;
this.node = options.node;
this.collection = options.collection;
this.database = options.database;

View File

@ -1,7 +1,6 @@
import * as ko from "knockout";
import * as ViewModels from "../../Contracts/ViewModels";
import { TabsManager } from "./TabsManager";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import DocumentsTab from "./DocumentsTab";
import Explorer from "../Explorer";
import QueryTab from "./QueryTab";
@ -15,7 +14,7 @@ describe("Tabs manager tests", () => {
let documentsTab: DocumentsTab;
beforeAll(() => {
explorer = new Explorer({ documentClientUtility: undefined, notificationsClient: undefined, isEmulator: false });
explorer = new Explorer({ notificationsClient: undefined, isEmulator: false });
explorer.databaseAccount = ko.observable<ViewModels.DatabaseAccount>({
id: "test",
name: "test",
@ -49,7 +48,6 @@ describe("Tabs manager tests", () => {
database,
title: "",
tabPath: "",
documentClientUtility: explorer.documentClientUtility,
selfLink: "",
isActive: ko.observable<boolean>(false),
hashLocation: "",
@ -63,7 +61,6 @@ describe("Tabs manager tests", () => {
collection,
title: "",
tabPath: "",
documentClientUtility: new DocumentClientUtilityBase(),
selfLink: "",
hashLocation: "",
isActive: ko.observable<boolean>(false),

View File

@ -7,6 +7,7 @@ import ScriptTabBase from "./ScriptTabBase";
import editable from "../../Common/EditableUtility";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import Trigger from "../Tree/Trigger";
import { createTrigger, updateTrigger } from "../../Common/DocumentClientUtilityBase";
export default class TriggerTab extends ScriptTabBase implements ViewModels.TriggerTab {
public collection: ViewModels.Collection;
@ -41,8 +42,7 @@ export default class TriggerTab extends ScriptTabBase implements ViewModels.Trig
tabTitle: this.tabTitle()
});
return this.documentClientUtility
.updateTrigger(this.collection, data)
return updateTrigger(this.collection, data)
.then(
(createdResource: DataModels.Trigger) => {
this.resource(createdResource);
@ -119,8 +119,7 @@ export default class TriggerTab extends ScriptTabBase implements ViewModels.Trig
tabTitle: this.tabTitle()
});
return this.documentClientUtility
.createTrigger(this.collection, resource)
return createTrigger(this.collection, resource)
.then(
(createdResource: DataModels.Trigger) => {
this.tabTitle(createdResource.id);

View File

@ -6,6 +6,7 @@ import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import ScriptTabBase from "./ScriptTabBase";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import UserDefinedFunction from "../Tree/UserDefinedFunction";
import { createUserDefinedFunction, updateUserDefinedFunction } from "../../Common/DocumentClientUtilityBase";
export default class UserDefinedFunctionTab extends ScriptTabBase implements ViewModels.UserDefinedFunctionTab {
public collection: ViewModels.Collection;
@ -34,8 +35,7 @@ export default class UserDefinedFunctionTab extends ScriptTabBase implements Vie
tabTitle: this.tabTitle()
});
return this.documentClientUtility
.updateUserDefinedFunction(this.collection, data)
return updateUserDefinedFunction(this.collection, data)
.then(
(createdResource: DataModels.UserDefinedFunction) => {
this.resource(createdResource);
@ -104,8 +104,7 @@ export default class UserDefinedFunctionTab extends ScriptTabBase implements Vie
tabTitle: this.tabTitle()
});
return this.documentClientUtility
.createUserDefinedFunction(this.collection, resource)
return createUserDefinedFunction(this.collection, resource)
.then(
(createdResource: DataModels.UserDefinedFunction) => {
this.tabTitle(createdResource.id);

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,9 +680,7 @@ export default class Collection implements ViewModels.Collection {
return;
}
this.container.documentClientUtility
.readOffer(collectionOffer)
.then((offerDetail: DataModels.OfferWithHeaders) => {
readOffer(collectionOffer).then((offerDetail: DataModels.OfferWithHeaders) => {
if (OfferUtils.isNotOfferV1(collectionOffer)) {
const offerThroughputInfo: DataModels.OfferThroughputInfo = {
minimumRUForCollection:
@ -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,9 +1074,7 @@ export default class Collection implements ViewModels.Collection {
}
public loadStoredProcedures(): Q.Promise<any> {
return this.container.documentClientUtility
.readStoredProcedures(this)
.then((storedProcedures: DataModels.StoredProcedure[]) => {
return readStoredProcedures(this).then((storedProcedures: DataModels.StoredProcedure[]) => {
const storedProceduresNodes: ViewModels.TreeNode[] = storedProcedures.map(
storedProcedure => new StoredProcedure(this.container, this, storedProcedure)
);
@ -1088,9 +1085,7 @@ export default class Collection implements ViewModels.Collection {
}
public loadUserDefinedFunctions(): Q.Promise<any> {
return this.container.documentClientUtility
.readUserDefinedFunctions(this)
.then((userDefinedFunctions: DataModels.UserDefinedFunction[]) => {
return readUserDefinedFunctions(this).then((userDefinedFunctions: DataModels.UserDefinedFunction[]) => {
const userDefinedFunctionsNodes: ViewModels.TreeNode[] = userDefinedFunctions.map(
udf => new UserDefinedFunction(this.container, this, udf)
);
@ -1101,9 +1096,7 @@ export default class Collection implements ViewModels.Collection {
}
public loadTriggers(): Q.Promise<any> {
return this.container.documentClientUtility
.readTriggers(this, null /*options*/)
.then((triggers: DataModels.Trigger[]) => {
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);
@ -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,9 +69,7 @@ export default class ConflictId implements ViewModels.ConflictId {
}
this.container.loadingConflictData(true);
return conflictsTab.documentClientUtility
.readDocument(this.container.collection, this.buildDocumentIdFromConflict(this.partitionKeyValue))
.then(
return readDocument(this.container.collection, this.buildDocumentIdFromConflict(this.partitionKeyValue)).then(
(currentDocumentContent: any) => {
this.container.loadingConflictData(false);
if (this.operationType === Constants.ConflictOperationType.Replace) {

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,9 +146,7 @@ export default class Database implements ViewModels.Database {
offerInfoPromise.valueOf(),
databaseDataModel
);
this.container.documentClientUtility
.readOffer(databaseOffer)
.then((offerDetail: DataModels.OfferWithHeaders) => {
readOffer(databaseOffer).then((offerDetail: DataModels.OfferWithHeaders) => {
const offerThroughputInfo: DataModels.OfferThroughputInfo = {
minimumRUForCollection:
offerDetail.content &&
@ -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

View File

@ -3,15 +3,10 @@ import { AccountKind, TagNames, DefaultAccountExperience } from "../../Common/Co
import Explorer from "../../Explorer/Explorer";
import { NotificationsClient } from "./NotificationsClient";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
export default class EmulatorExplorerFactory {
public static createExplorer(): Explorer {
DocumentClientUtilityBase;
const documentClientUtility: DocumentClientUtilityBase = new DocumentClientUtilityBase();
const explorer: Explorer = new Explorer({
documentClientUtility: documentClientUtility,
notificationsClient: new NotificationsClient(),
isEmulator: true
});

View File

@ -1,13 +1,9 @@
import Explorer from "../../Explorer/Explorer";
import { NotificationsClient } from "./NotificationsClient";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
export default class HostedExplorerFactory {
public createExplorer(): Explorer {
var documentClientUtility = new DocumentClientUtilityBase();
const explorer = new Explorer({
documentClientUtility: documentClientUtility,
notificationsClient: new NotificationsClient(),
isEmulator: false
});
@ -17,8 +13,6 @@ export default class HostedExplorerFactory {
public static reInitializeDocumentClientUtilityForExplorer(explorer: Explorer): void {
if (!!explorer) {
const documentClientUtility = new DocumentClientUtilityBase();
explorer.rebindDocumentClientUtility(documentClientUtility);
explorer.notificationConsoleData([]);
}
}

View File

@ -1,14 +1,9 @@
import Explorer from "../../Explorer/Explorer";
import { NotificationsClient } from "./NotificationsClient";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
export default class PortalExplorerFactory {
public createExplorer(): Explorer {
var documentClientUtility = new DocumentClientUtilityBase();
var explorer = new Explorer({
documentClientUtility: documentClientUtility,
notificationsClient: new NotificationsClient(),
isEmulator: false
});

View File

@ -10,7 +10,6 @@ describe("TabRouteHandler", () => {
beforeAll(() => {
(<any>window).dataExplorer = new Explorer({
documentClientUtility: null,
notificationsClient: null,
isEmulator: false
}); // create a mock to avoid null refs