From 03b19fc87542d3eb8c6a6ac60c893f635f25fde6 Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Tue, 15 Sep 2020 13:31:30 -0500 Subject: [PATCH] Split all script data access methods (#197) * Split all script data access methods * More cleanup * Fix Typo --- src/Common/DataAccessUtilityBase.ts | 341 ++-------- src/Common/DocumentClientUtilityBase.ts | 601 ++---------------- .../dataAccess/createStoredProcedure.ts | 28 + src/Common/dataAccess/createTrigger.ts | 28 + .../dataAccess/createUserDefinedFunction.ts | 28 + .../dataAccess/deleteStoredProcedure.ts | 26 + src/Common/dataAccess/deleteTrigger.ts | 22 + .../dataAccess/deleteUserDefinedFunction.ts | 22 + src/Common/dataAccess/readStoredProcedures.ts | 27 + src/Common/dataAccess/readTriggers.ts | 27 + .../dataAccess/readUserDefinedFunctions.ts | 27 + .../dataAccess/updateStoredProcedure.ts | 29 + src/Common/dataAccess/updateTrigger.ts | 29 + .../dataAccess/updateUserDefinedFunction.ts | 29 + src/Contracts/DataModels.ts | 152 ----- src/Contracts/ViewModels.ts | 34 +- src/Explorer/Tabs/ScriptTabBase.ts | 24 +- src/Explorer/Tabs/StoredProcedureTab.ts | 56 +- src/Explorer/Tabs/TriggerTab.ts | 61 +- src/Explorer/Tabs/UserDefinedFunctionTab.ts | 42 +- src/Explorer/Tree/Collection.ts | 43 +- src/Explorer/Tree/StoredProcedure.ts | 27 +- src/Explorer/Tree/Trigger.ts | 23 +- src/Explorer/Tree/UserDefinedFunction.ts | 24 +- 24 files changed, 591 insertions(+), 1159 deletions(-) create mode 100644 src/Common/dataAccess/createStoredProcedure.ts create mode 100644 src/Common/dataAccess/createTrigger.ts create mode 100644 src/Common/dataAccess/createUserDefinedFunction.ts create mode 100644 src/Common/dataAccess/deleteStoredProcedure.ts create mode 100644 src/Common/dataAccess/deleteTrigger.ts create mode 100644 src/Common/dataAccess/deleteUserDefinedFunction.ts create mode 100644 src/Common/dataAccess/readStoredProcedures.ts create mode 100644 src/Common/dataAccess/readTriggers.ts create mode 100644 src/Common/dataAccess/readUserDefinedFunctions.ts create mode 100644 src/Common/dataAccess/updateStoredProcedure.ts create mode 100644 src/Common/dataAccess/updateTrigger.ts create mode 100644 src/Common/dataAccess/updateUserDefinedFunction.ts diff --git a/src/Common/DataAccessUtilityBase.ts b/src/Common/DataAccessUtilityBase.ts index 51b32e2ec..56da586d9 100644 --- a/src/Common/DataAccessUtilityBase.ts +++ b/src/Common/DataAccessUtilityBase.ts @@ -1,28 +1,26 @@ -import * as _ from "underscore"; -import * as Constants from "./Constants"; -import * as DataModels from "../Contracts/DataModels"; -import * as HeadersUtility from "./HeadersUtility"; -import * as ViewModels from "../Contracts/ViewModels"; -import Q from "q"; import { ConflictDefinition, FeedOptions, ItemDefinition, + OfferDefinition, QueryIterator, - Resource, - TriggerDefinition, - OfferDefinition + Resource } from "@azure/cosmos"; -import { client } from "./CosmosClient"; -import { LocalStorageUtility, StorageKey } from "../Shared/StorageUtility"; -import { sendCachedDataMessage } from "./MessageHandler"; -import { MessageTypes } from "../Contracts/ExplorerContracts"; -import { OfferUtils } from "../Utils/OfferUtils"; import { RequestOptions } from "@azure/cosmos/dist-esm"; -import StoredProcedure from "../Explorer/Tree/StoredProcedure"; -import { Platform, configContext } from "../ConfigContext"; -import DocumentId from "../Explorer/Tree/DocumentId"; +import Q from "q"; +import { configContext, Platform } from "../ConfigContext"; +import * as DataModels from "../Contracts/DataModels"; +import { MessageTypes } from "../Contracts/ExplorerContracts"; +import * as ViewModels from "../Contracts/ViewModels"; import ConflictId from "../Explorer/Tree/ConflictId"; +import DocumentId from "../Explorer/Tree/DocumentId"; +import StoredProcedure from "../Explorer/Tree/StoredProcedure"; +import { LocalStorageUtility, StorageKey } from "../Shared/StorageUtility"; +import { OfferUtils } from "../Utils/OfferUtils"; +import * as Constants from "./Constants"; +import { client } from "./CosmosClient"; +import * as HeadersUtility from "./HeadersUtility"; +import { sendCachedDataMessage } from "./MessageHandler"; export function getCommonQueryOptions(options: FeedOptions): any { const storedItemPerPageSetting: number = LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage); @@ -55,85 +53,55 @@ export function queryDocuments( return Q(documentsIterator); } -export function readStoredProcedures( - collection: ViewModels.Collection, - options?: any -): Q.Promise { +export function getPartitionKeyHeaderForConflict(conflictId: ConflictId): Object { + const partitionKeyDefinition: DataModels.PartitionKey = conflictId.partitionKey; + const partitionKeyValue: any = conflictId.partitionKeyValue; + + return getPartitionKeyHeader(partitionKeyDefinition, partitionKeyValue); +} + +export function getPartitionKeyHeader(partitionKeyDefinition: DataModels.PartitionKey, partitionKeyValue: any): Object { + if (!partitionKeyDefinition) { + return undefined; + } + + if (partitionKeyValue === undefined) { + return [{}]; + } + + return [partitionKeyValue]; +} + +export function updateOffer( + offer: DataModels.Offer, + newOffer: DataModels.Offer, + options?: RequestOptions +): Q.Promise { return Q( client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.storedProcedures.readAll(options) - .fetchAll() - .then(response => response.resources as DataModels.StoredProcedure[]) + .offer(offer.id) + // TODO Remove casting when SDK types are fixed (https://github.com/Azure/azure-sdk-for-js/issues/10660) + .replace((newOffer as unknown) as OfferDefinition, options) + .then(response => { + return Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => response.resource); + }) ); } -export function readStoredProcedure( - collection: ViewModels.Collection, - requestedResource: DataModels.Resource, - options?: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.storedProcedure(requestedResource.id) - .read(options) - .then(response => response.resource as DataModels.StoredProcedure) - ); -} -export function readUserDefinedFunctions( - collection: ViewModels.Collection, - options: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.userDefinedFunctions.readAll(options) - .fetchAll() - .then(response => response.resources as DataModels.UserDefinedFunction[]) - ); -} -export function readUserDefinedFunction( - collection: ViewModels.Collection, - requestedResource: DataModels.Resource, - options?: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.userDefinedFunction(requestedResource.id) - .read(options) - .then(response => response.resource as DataModels.UserDefinedFunction) - ); -} +export function updateDocument( + collection: ViewModels.CollectionBase, + documentId: DocumentId, + newDocument: any +): Q.Promise { + const partitionKey = documentId.partitionKeyValue; -export function readTriggers(collection: ViewModels.Collection, options: any): Q.Promise { return Q( client() .database(collection.databaseId) .container(collection.id()) - .scripts.triggers.readAll(options) - .fetchAll() - .then(response => response.resources as DataModels.Trigger[]) - ); -} - -export function readTrigger( - collection: ViewModels.Collection, - requestedResource: DataModels.Resource, - options?: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.trigger(requestedResource.id) - .read(options) - .then(response => response.resource as DataModels.Trigger) + .item(documentId.id(), partitionKey) + .replace(newDocument) + .then(response => response.resource) ); } @@ -165,6 +133,16 @@ export function executeStoredProcedure( ); } +export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise { + return Q( + client() + .database(collection.databaseId) + .container(collection.id()) + .items.create(newDocument) + .then(response => response.resource) + ); +} + export function readDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise { const partitionKey = documentId.partitionKeyValue; @@ -178,155 +156,6 @@ export function readDocument(collection: ViewModels.CollectionBase, documentId: ); } -export function getPartitionKeyHeaderForConflict(conflictId: ConflictId): Object { - const partitionKeyDefinition: DataModels.PartitionKey = conflictId.partitionKey; - const partitionKeyValue: any = conflictId.partitionKeyValue; - - return getPartitionKeyHeader(partitionKeyDefinition, partitionKeyValue); -} - -export function getPartitionKeyHeader(partitionKeyDefinition: DataModels.PartitionKey, partitionKeyValue: any): Object { - if (!partitionKeyDefinition) { - return undefined; - } - - if (partitionKeyValue === undefined) { - return [{}]; - } - - return [partitionKeyValue]; -} - -export function updateDocument( - collection: ViewModels.CollectionBase, - documentId: DocumentId, - newDocument: any -): Q.Promise { - const partitionKey = documentId.partitionKeyValue; - - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .item(documentId.id(), partitionKey) - .replace(newDocument) - .then(response => response.resource) - ); -} - -export function updateOffer( - offer: DataModels.Offer, - newOffer: DataModels.Offer, - options?: RequestOptions -): Q.Promise { - return Q( - client() - .offer(offer.id) - // TODO Remove casting when SDK types are fixed (https://github.com/Azure/azure-sdk-for-js/issues/10660) - .replace((newOffer as unknown) as OfferDefinition, options) - .then(response => { - return Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => response.resource); - }) - ); -} - -export function updateStoredProcedure( - collection: ViewModels.Collection, - storedProcedure: DataModels.StoredProcedure, - options: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.storedProcedure(storedProcedure.id) - .replace(storedProcedure, options) - .then(response => response.resource as DataModels.StoredProcedure) - ); -} - -export function updateUserDefinedFunction( - collection: ViewModels.Collection, - userDefinedFunction: DataModels.UserDefinedFunction, - options?: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.userDefinedFunction(userDefinedFunction.id) - .replace(userDefinedFunction, options) - .then(response => response.resource as DataModels.StoredProcedure) - ); -} - -export function updateTrigger( - collection: ViewModels.Collection, - trigger: DataModels.Trigger, - options?: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.trigger(trigger.id) - .replace(trigger as TriggerDefinition, options) - .then(response => response.resource as DataModels.Trigger) - ); -} - -export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .items.create(newDocument) - .then(response => response.resource as DataModels.StoredProcedure) - ); -} - -export function createStoredProcedure( - collection: ViewModels.Collection, - newStoredProcedure: DataModels.StoredProcedure, - options?: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.storedProcedures.create(newStoredProcedure, options) - .then(response => response.resource as DataModels.StoredProcedure) - ); -} - -export function createUserDefinedFunction( - collection: ViewModels.Collection, - newUserDefinedFunction: DataModels.UserDefinedFunction, - options: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.userDefinedFunctions.create(newUserDefinedFunction, options) - .then(response => response.resource as DataModels.UserDefinedFunction) - ); -} - -export function createTrigger( - collection: ViewModels.Collection, - newTrigger: DataModels.Trigger, - options?: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.triggers.create(newTrigger as TriggerDefinition, options) - .then(response => response.resource as DataModels.Trigger) - ); -} - export function deleteDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise { const partitionKey = documentId.partitionKeyValue; @@ -355,48 +184,6 @@ export function deleteConflict( ); } -export function deleteStoredProcedure( - collection: ViewModels.Collection, - storedProcedure: DataModels.StoredProcedure, - options: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.storedProcedure(storedProcedure.id) - .delete() - ); -} - -export function deleteUserDefinedFunction( - collection: ViewModels.Collection, - userDefinedFunction: DataModels.UserDefinedFunction, - options: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.userDefinedFunction(userDefinedFunction.id) - .delete() - ); -} - -export function deleteTrigger( - collection: ViewModels.Collection, - trigger: DataModels.Trigger, - options: any -): Q.Promise { - return Q( - client() - .database(collection.databaseId) - .container(collection.id()) - .scripts.trigger(trigger.id) - .delete() - ); -} - export function readCollectionQuotaInfo( collection: ViewModels.Collection, options: any diff --git a/src/Common/DocumentClientUtilityBase.ts b/src/Common/DocumentClientUtilityBase.ts index 2ae5a4d39..a1d47476a 100644 --- a/src/Common/DocumentClientUtilityBase.ts +++ b/src/Common/DocumentClientUtilityBase.ts @@ -1,18 +1,17 @@ -import * as Constants from "./Constants"; +import { ConflictDefinition, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos"; +import { RequestOptions } from "@azure/cosmos/dist-esm"; +import Q from "q"; import * as DataModels from "../Contracts/DataModels"; import * as ViewModels from "../Contracts/ViewModels"; -import Q from "q"; -import { ConflictDefinition, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos"; -import { ConsoleDataType } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent"; -import * as DataAccessUtilityBase from "./DataAccessUtilityBase"; -import * as Logger from "./Logger"; -import { MinimalQueryIterator, nextPage } from "./IteratorUtilities"; -import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils"; -import { RequestOptions } from "@azure/cosmos/dist-esm"; -import StoredProcedure from "../Explorer/Tree/StoredProcedure"; import ConflictId from "../Explorer/Tree/ConflictId"; import DocumentId from "../Explorer/Tree/DocumentId"; +import StoredProcedure from "../Explorer/Tree/StoredProcedure"; +import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../Utils/NotificationConsoleUtils"; +import * as Constants from "./Constants"; import { sendNotificationForError } from "./dataAccess/sendNotificationForError"; +import * as DataAccessUtilityBase from "./DataAccessUtilityBase"; +import { MinimalQueryIterator, nextPage } from "./IteratorUtilities"; +import * as Logger from "./Logger"; // TODO: Log all promise resolutions and errors with verbosity levels export function queryDocuments( @@ -42,121 +41,6 @@ export function getEntityName() { return "item"; } -export function readStoredProcedures( - collection: ViewModels.Collection, - options: any = {} -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Querying stored procedures for container ${collection.id()}` - ); - DataAccessUtilityBase.readStoredProcedures(collection, options) - .then( - (storedProcedures: DataModels.StoredProcedure[]) => { - deferred.resolve(storedProcedures); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Failed to query stored procedures for container ${collection.id()}: ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "ReadStoredProcedures", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function readStoredProcedure( - collection: ViewModels.Collection, - requestedResource: DataModels.Resource, - options?: any -): Q.Promise { - return DataAccessUtilityBase.readStoredProcedure(collection, requestedResource, options); -} - -export function readUserDefinedFunctions( - collection: ViewModels.Collection, - options: any = {} -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Querying user defined functions for collection ${collection.id()}` - ); - DataAccessUtilityBase.readUserDefinedFunctions(collection, options) - .then( - (userDefinedFunctions: DataModels.UserDefinedFunction[]) => { - deferred.resolve(userDefinedFunctions); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Failed to query user defined functions for container ${collection.id()}: ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "ReadUDFs", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function readUserDefinedFunction( - collection: ViewModels.Collection, - requestedResource: DataModels.Resource, - options: any -): Q.Promise { - return DataAccessUtilityBase.readUserDefinedFunction(collection, requestedResource, options); -} - -export function readTriggers(collection: ViewModels.Collection, options: any): Q.Promise { - var deferred = Q.defer(); - - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Querying triggers for container ${collection.id()}` - ); - DataAccessUtilityBase.readTriggers(collection, options) - .then( - (triggers: DataModels.Trigger[]) => { - deferred.resolve(triggers); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Failed to query triggers for container ${collection.id()}: ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "ReadTriggers", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function readTrigger( - collection: ViewModels.Collection, - requestedResource: DataModels.Resource, - options?: any -): Q.Promise { - return DataAccessUtilityBase.readTrigger(collection, requestedResource, options); -} - export function executeStoredProcedure( collection: ViewModels.Collection, storedProcedure: StoredProcedure, @@ -165,22 +49,17 @@ export function executeStoredProcedure( ): Q.Promise { var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Executing stored procedure ${storedProcedure.id()}` - ); + const clearMessage = logConsoleProgress(`Executing stored procedure ${storedProcedure.id()}`); DataAccessUtilityBase.executeStoredProcedure(collection, storedProcedure, partitionKeyValue, params) .then( (response: any) => { deferred.resolve(response); - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, + logConsoleInfo( `Finished executing stored procedure ${storedProcedure.id()} for container ${storedProcedure.collection.id()}` ); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, + logConsoleError( `Failed to execute stored procedure ${storedProcedure.id()} for container ${storedProcedure.collection.id()}: ${JSON.stringify( error )}` @@ -191,7 +70,7 @@ export function executeStoredProcedure( } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -205,32 +84,23 @@ export function queryDocumentsPage( ): Q.Promise { var deferred = Q.defer(); const entityName = getEntityName(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Querying ${entityName} for container ${resourceName}` - ); + const clearMessage = logConsoleProgress(`Querying ${entityName} for container ${resourceName}`); Q(nextPage(documentsIterator, firstItemIndex)) .then( (result: ViewModels.QueryResults) => { const itemCount = (result.documents && result.documents.length) || 0; - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully fetched ${itemCount} ${entityName} for container ${resourceName}` - ); + logConsoleInfo(`Successfully fetched ${itemCount} ${entityName} for container ${resourceName}`); deferred.resolve(result); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Failed to query ${entityName} for container ${resourceName}: ${JSON.stringify(error)}` - ); + logConsoleError(`Failed to query ${entityName} for container ${resourceName}: ${JSON.stringify(error)}`); Logger.logError(JSON.stringify(error), "QueryDocumentsPage", error.code); sendNotificationForError(error); deferred.reject(error); } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -239,27 +109,21 @@ export function queryDocumentsPage( export function readDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise { var deferred = Q.defer(); const entityName = getEntityName(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Reading ${entityName} ${documentId.id()}` - ); + const clearMessage = logConsoleProgress(`Reading ${entityName} ${documentId.id()}`); DataAccessUtilityBase.readDocument(collection, documentId) .then( (document: any) => { deferred.resolve(document); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Failed to read ${entityName} ${documentId.id()}: ${JSON.stringify(error)}` - ); + logConsoleError(`Failed to read ${entityName} ${documentId.id()}: ${JSON.stringify(error)}`); Logger.logError(JSON.stringify(error), "ReadDocument", error.code); sendNotificationForError(error); deferred.reject(error); } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -272,31 +136,22 @@ export function updateDocument( ): Q.Promise { var deferred = Q.defer(); const entityName = getEntityName(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Updating ${entityName} ${documentId.id()}` - ); + const clearMessage = logConsoleProgress(`Updating ${entityName} ${documentId.id()}`); DataAccessUtilityBase.updateDocument(collection, documentId, newDocument) .then( (updatedDocument: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully updated ${entityName} ${documentId.id()}` - ); + logConsoleInfo(`Successfully updated ${entityName} ${documentId.id()}`); deferred.resolve(updatedDocument); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Failed to update ${entityName} ${documentId.id()}: ${JSON.stringify(error)}` - ); + logConsoleError(`Failed to update ${entityName} ${documentId.id()}: ${JSON.stringify(error)}`); Logger.logError(JSON.stringify(error), "UpdateDocument", error.code); sendNotificationForError(error); deferred.reject(error); } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -308,24 +163,15 @@ export function updateOffer( options: RequestOptions ): Q.Promise { var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Updating offer for resource ${offer.resource}` - ); + const clearMessage = logConsoleProgress(`Updating offer for resource ${offer.resource}`); DataAccessUtilityBase.updateOffer(offer, newOffer, options) .then( (replacedOffer: DataModels.Offer) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully updated offer for resource ${offer.resource}` - ); + logConsoleInfo(`Successfully updated offer for resource ${offer.resource}`); deferred.resolve(replacedOffer); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error updating offer for resource ${offer.resource}: ${JSON.stringify(error)}` - ); + logConsoleError(`Error updating offer for resource ${offer.resource}: ${JSON.stringify(error)}`); Logger.logError( JSON.stringify({ oldOffer: offer, @@ -340,108 +186,7 @@ export function updateOffer( } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function updateStoredProcedure( - collection: ViewModels.Collection, - storedProcedure: DataModels.StoredProcedure, - options?: any -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Updating stored procedure ${storedProcedure.id}` - ); - DataAccessUtilityBase.updateStoredProcedure(collection, storedProcedure, options) - .then( - (updatedStoredProcedure: DataModels.StoredProcedure) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully updated stored procedure ${storedProcedure.id}` - ); - deferred.resolve(updatedStoredProcedure); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while updating stored procedure ${storedProcedure.id}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "UpdateStoredProcedure", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function updateUserDefinedFunction( - collection: ViewModels.Collection, - userDefinedFunction: DataModels.UserDefinedFunction, - options: any = {} -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Updating user defined function ${userDefinedFunction.id}` - ); - DataAccessUtilityBase.updateUserDefinedFunction(collection, userDefinedFunction, options) - .then( - (updatedUserDefinedFunction: DataModels.UserDefinedFunction) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully updated user defined function ${userDefinedFunction.id}` - ); - deferred.resolve(updatedUserDefinedFunction); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while updating user defined function ${userDefinedFunction.id}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "UpdateUDF", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function updateTrigger( - collection: ViewModels.Collection, - trigger: DataModels.Trigger -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, `Updating trigger ${trigger.id}`); - DataAccessUtilityBase.updateTrigger(collection, trigger) - .then( - (updatedTrigger: DataModels.Trigger) => { - NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Info, `Updated trigger ${trigger.id}`); - deferred.resolve(updatedTrigger); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while updating trigger ${trigger.id}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "UpdateTrigger", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -450,22 +195,15 @@ export function updateTrigger( export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise { var deferred = Q.defer(); const entityName = getEntityName(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Creating new ${entityName} for container ${collection.id()}` - ); + const clearMessage = logConsoleProgress(`Creating new ${entityName} for container ${collection.id()}`); DataAccessUtilityBase.createDocument(collection, newDocument) .then( (savedDocument: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully created new ${entityName} for container ${collection.id()}` - ); + logConsoleInfo(`Successfully created new ${entityName} for container ${collection.id()}`); deferred.resolve(savedDocument); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, + logConsoleError( `Error while creating new ${entityName} for container ${collection.id()}:\n ${JSON.stringify(error)}` ); Logger.logError(JSON.stringify(error), "CreateDocument", error.code); @@ -474,115 +212,7 @@ export function createDocument(collection: ViewModels.CollectionBase, newDocumen } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function createStoredProcedure( - collection: ViewModels.Collection, - newStoredProcedure: DataModels.StoredProcedure, - options?: any -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Creating stored procedure for container ${collection.id()}` - ); - DataAccessUtilityBase.createStoredProcedure(collection, newStoredProcedure, options) - .then( - (createdStoredProcedure: DataModels.StoredProcedure) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully created stored procedure for container ${collection.id()}` - ); - deferred.resolve(createdStoredProcedure); - }, - error => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while creating stored procedure for container ${collection.id()}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "CreateStoredProcedure", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function createUserDefinedFunction( - collection: ViewModels.Collection, - newUserDefinedFunction: DataModels.UserDefinedFunction, - options?: any -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Creating user defined function for container ${collection.id()}` - ); - DataAccessUtilityBase.createUserDefinedFunction(collection, newUserDefinedFunction, options) - .then( - (createdUserDefinedFunction: DataModels.UserDefinedFunction) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully created user defined function for container ${collection.id()}` - ); - deferred.resolve(createdUserDefinedFunction); - }, - error => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while creating user defined function for container ${collection.id()}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "CreateUDF", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function createTrigger( - collection: ViewModels.Collection, - newTrigger: DataModels.Trigger, - options: any = {} -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Creating trigger for container ${collection.id()}` - ); - DataAccessUtilityBase.createTrigger(collection, newTrigger, options) - .then( - (createdTrigger: DataModels.Trigger) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully created trigger for container ${collection.id()}` - ); - deferred.resolve(createdTrigger); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while creating trigger for container ${collection.id()}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "CreateTrigger", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -591,31 +221,22 @@ export function createTrigger( export function deleteDocument(collection: ViewModels.CollectionBase, documentId: DocumentId): Q.Promise { var deferred = Q.defer(); const entityName = getEntityName(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Deleting ${entityName} ${documentId.id()}` - ); + const clearMessage = logConsoleProgress(`Deleting ${entityName} ${documentId.id()}`); DataAccessUtilityBase.deleteDocument(collection, documentId) .then( (response: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully deleted ${entityName} ${documentId.id()}` - ); + logConsoleInfo(`Successfully deleted ${entityName} ${documentId.id()}`); deferred.resolve(response); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while deleting ${entityName} ${documentId.id()}:\n ${JSON.stringify(error)}` - ); + logConsoleError(`Error while deleting ${entityName} ${documentId.id()}:\n ${JSON.stringify(error)}`); Logger.logError(JSON.stringify(error), "DeleteDocument", error.code); sendNotificationForError(error); deferred.reject(error); } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -628,134 +249,22 @@ export function deleteConflict( ): Q.Promise { var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Deleting conflict ${conflictId.id()}` - ); + const clearMessage = logConsoleProgress(`Deleting conflict ${conflictId.id()}`); DataAccessUtilityBase.deleteConflict(collection, conflictId, options) .then( (response: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully deleted conflict ${conflictId.id()}` - ); + logConsoleInfo(`Successfully deleted conflict ${conflictId.id()}`); deferred.resolve(response); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while deleting conflict ${conflictId.id()}:\n ${JSON.stringify(error)}` - ); + logConsoleError(`Error while deleting conflict ${conflictId.id()}:\n ${JSON.stringify(error)}`); Logger.logError(JSON.stringify(error), "DeleteConflict", error.code); sendNotificationForError(error); deferred.reject(error); } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function deleteStoredProcedure( - collection: ViewModels.Collection, - storedProcedure: DataModels.StoredProcedure, - options: any = {} -): Q.Promise { - var deferred = Q.defer(); - - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Deleting stored procedure ${storedProcedure.id}` - ); - DataAccessUtilityBase.deleteStoredProcedure(collection, storedProcedure, options) - .then( - (response: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully deleted stored procedure ${storedProcedure.id}` - ); - deferred.resolve(response); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while deleting stored procedure ${storedProcedure.id}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "DeleteStoredProcedure", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function deleteUserDefinedFunction( - collection: ViewModels.Collection, - userDefinedFunction: DataModels.UserDefinedFunction, - options: any = {} -): Q.Promise { - var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Deleting user defined function ${userDefinedFunction.id}` - ); - DataAccessUtilityBase.deleteUserDefinedFunction(collection, userDefinedFunction, options) - .then( - (response: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Info, - `Successfully deleted user defined function ${userDefinedFunction.id}` - ); - deferred.resolve(response); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while deleting user defined function ${userDefinedFunction.id}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "DeleteUDF", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); - }); - - return deferred.promise; -} - -export function deleteTrigger( - collection: ViewModels.Collection, - trigger: DataModels.Trigger, - options: any = {} -): Q.Promise { - var deferred = Q.defer(); - 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}`); - deferred.resolve(response); - }, - (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while deleting trigger ${trigger.id}:\n ${JSON.stringify(error)}` - ); - Logger.logError(JSON.stringify(error), "DeleteTrigger", error.code); - sendNotificationForError(error); - deferred.reject(error); - } - ) - .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -775,27 +284,21 @@ export function readCollectionQuotaInfo( ): Q.Promise { var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - `Querying quota info for container ${collection.id}` - ); + const clearMessage = logConsoleProgress(`Querying quota info for container ${collection.id}`); DataAccessUtilityBase.readCollectionQuotaInfo(collection, options) .then( (quota: DataModels.CollectionQuotaInfo) => { deferred.resolve(quota); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while querying quota info for container ${collection.id}:\n ${JSON.stringify(error)}` - ); + logConsoleError(`Error while querying quota info for container ${collection.id}:\n ${JSON.stringify(error)}`); Logger.logError(JSON.stringify(error), "ReadCollectionQuotaInfo", error.code); sendNotificationForError(error); deferred.reject(error); } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -804,24 +307,21 @@ export function readCollectionQuotaInfo( export function readOffers(options: any = {}): Q.Promise { var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Querying offers"); + const clearMessage = logConsoleProgress("Querying offers"); DataAccessUtilityBase.readOffers(options) .then( (offers: DataModels.Offer[]) => { deferred.resolve(offers); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while querying offers:\n ${JSON.stringify(error)}` - ); + logConsoleError(`Error while querying offers:\n ${JSON.stringify(error)}`); Logger.logError(JSON.stringify(error), "ReadOffers", error.code); sendNotificationForError(error); deferred.reject(error); } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; @@ -833,24 +333,21 @@ export function readOffer( ): Q.Promise { var deferred = Q.defer(); - const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Querying offer"); + const clearMessage = logConsoleProgress("Querying offer"); DataAccessUtilityBase.readOffer(requestedResource, options) .then( (offer: DataModels.OfferWithHeaders) => { deferred.resolve(offer); }, (error: any) => { - NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.Error, - `Error while querying offer:\n ${JSON.stringify(error)}` - ); + logConsoleError(`Error while querying offer:\n ${JSON.stringify(error)}`); Logger.logError(JSON.stringify(error), "ReadOffer", error.code); sendNotificationForError(error); deferred.reject(error); } ) .finally(() => { - NotificationConsoleUtils.clearInProgressMessageWithId(id); + clearMessage(); }); return deferred.promise; diff --git a/src/Common/dataAccess/createStoredProcedure.ts b/src/Common/dataAccess/createStoredProcedure.ts new file mode 100644 index 000000000..f38910beb --- /dev/null +++ b/src/Common/dataAccess/createStoredProcedure.ts @@ -0,0 +1,28 @@ +import { Resource, StoredProcedureDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function createStoredProcedure( + databaseId: string, + collectionId: string, + storedProcedure: StoredProcedureDefinition +): Promise { + let createdStoredProcedure: StoredProcedureDefinition & Resource; + const clearMessage = logConsoleProgress(`Creating stored procedure ${storedProcedure.id}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.storedProcedures.create(storedProcedure); + createdStoredProcedure = response.resource; + } catch (error) { + logConsoleError(`Error while creating stored procedure ${storedProcedure.id}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "CreateStoredProcedure", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return createdStoredProcedure; +} diff --git a/src/Common/dataAccess/createTrigger.ts b/src/Common/dataAccess/createTrigger.ts new file mode 100644 index 000000000..f797e0ded --- /dev/null +++ b/src/Common/dataAccess/createTrigger.ts @@ -0,0 +1,28 @@ +import { Resource, TriggerDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function createTrigger( + databaseId: string, + collectionId: string, + trigger: TriggerDefinition +): Promise { + let createdTrigger: TriggerDefinition & Resource; + const clearMessage = logConsoleProgress(`Creating trigger ${trigger.id}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.triggers.create(trigger); + createdTrigger = response.resource; + } catch (error) { + logConsoleError(`Error while creating trigger ${trigger.id}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "CreateTrigger", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return createdTrigger; +} diff --git a/src/Common/dataAccess/createUserDefinedFunction.ts b/src/Common/dataAccess/createUserDefinedFunction.ts new file mode 100644 index 000000000..8b8ccea50 --- /dev/null +++ b/src/Common/dataAccess/createUserDefinedFunction.ts @@ -0,0 +1,28 @@ +import { Resource, UserDefinedFunctionDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function createUserDefinedFunction( + databaseId: string, + collectionId: string, + userDefinedFunction: UserDefinedFunctionDefinition +): Promise { + let createdUserDefinedFunction: UserDefinedFunctionDefinition & Resource; + const clearMessage = logConsoleProgress(`Creating user defined function ${userDefinedFunction.id}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.userDefinedFunctions.create(userDefinedFunction); + createdUserDefinedFunction = response.resource; + } catch (error) { + logConsoleError(`Error while creating user defined function ${userDefinedFunction.id}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "CreateUserupdateUserDefinedFunction", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return createdUserDefinedFunction; +} diff --git a/src/Common/dataAccess/deleteStoredProcedure.ts b/src/Common/dataAccess/deleteStoredProcedure.ts new file mode 100644 index 000000000..ababc35b3 --- /dev/null +++ b/src/Common/dataAccess/deleteStoredProcedure.ts @@ -0,0 +1,26 @@ +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function deleteStoredProcedure( + databaseId: string, + collectionId: string, + storedProcedureId: string +): Promise { + const clearMessage = logConsoleProgress(`Deleting stored procedure ${storedProcedureId}`); + try { + await client() + .database(databaseId) + .container(collectionId) + .scripts.storedProcedure(storedProcedureId) + .delete(); + } catch (error) { + logConsoleError(`Error while deleting stored procedure ${storedProcedureId}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "DeleteStoredProcedure", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return undefined; +} diff --git a/src/Common/dataAccess/deleteTrigger.ts b/src/Common/dataAccess/deleteTrigger.ts new file mode 100644 index 000000000..b0b6c053e --- /dev/null +++ b/src/Common/dataAccess/deleteTrigger.ts @@ -0,0 +1,22 @@ +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function deleteTrigger(databaseId: string, collectionId: string, triggerId: string): Promise { + const clearMessage = logConsoleProgress(`Deleting trigger ${triggerId}`); + try { + await client() + .database(databaseId) + .container(collectionId) + .scripts.trigger(triggerId) + .delete(); + } catch (error) { + logConsoleError(`Error while deleting trigger ${triggerId}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "DeleteTrigger", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return undefined; +} diff --git a/src/Common/dataAccess/deleteUserDefinedFunction.ts b/src/Common/dataAccess/deleteUserDefinedFunction.ts new file mode 100644 index 000000000..5f82d1070 --- /dev/null +++ b/src/Common/dataAccess/deleteUserDefinedFunction.ts @@ -0,0 +1,22 @@ +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function deleteUserDefinedFunction(databaseId: string, collectionId: string, id: string): Promise { + const clearMessage = logConsoleProgress(`Deleting user defined function ${id}`); + try { + await client() + .database(databaseId) + .container(collectionId) + .scripts.userDefinedFunction(id) + .delete(); + } catch (error) { + logConsoleError(`Error while deleting user defined function ${id}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "DeleteUserDefinedFunction", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return undefined; +} diff --git a/src/Common/dataAccess/readStoredProcedures.ts b/src/Common/dataAccess/readStoredProcedures.ts new file mode 100644 index 000000000..bcba9b072 --- /dev/null +++ b/src/Common/dataAccess/readStoredProcedures.ts @@ -0,0 +1,27 @@ +import { Resource, StoredProcedureDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function readStoredProcedures( + databaseId: string, + collectionId: string +): Promise<(StoredProcedureDefinition & Resource)[]> { + let sprocs: (StoredProcedureDefinition & Resource)[]; + const clearMessage = logConsoleProgress(`Querying stored procedures for container ${collectionId}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.storedProcedures.readAll() + .fetchAll(); + sprocs = response.resources; + } catch (error) { + logConsoleError(`Failed to query stored procedures for container ${collectionId}: ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "ReadStoredProcedures", error.code); + sendNotificationForError(error); + } + clearMessage(); + return sprocs; +} diff --git a/src/Common/dataAccess/readTriggers.ts b/src/Common/dataAccess/readTriggers.ts new file mode 100644 index 000000000..314a015d0 --- /dev/null +++ b/src/Common/dataAccess/readTriggers.ts @@ -0,0 +1,27 @@ +import { Resource, TriggerDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function readTriggers( + databaseId: string, + collectionId: string +): Promise<(TriggerDefinition & Resource)[]> { + let triggers: (TriggerDefinition & Resource)[]; + const clearMessage = logConsoleProgress(`Querying triggers for container ${collectionId}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.triggers.readAll() + .fetchAll(); + triggers = response.resources; + } catch (error) { + logConsoleError(`Failed to query triggers for container ${collectionId}: ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "ReadTriggers", error.code); + sendNotificationForError(error); + } + clearMessage(); + return triggers; +} diff --git a/src/Common/dataAccess/readUserDefinedFunctions.ts b/src/Common/dataAccess/readUserDefinedFunctions.ts new file mode 100644 index 000000000..aa48dc9cf --- /dev/null +++ b/src/Common/dataAccess/readUserDefinedFunctions.ts @@ -0,0 +1,27 @@ +import { Resource, UserDefinedFunctionDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function readUserDefinedFunctions( + databaseId: string, + collectionId: string +): Promise<(UserDefinedFunctionDefinition & Resource)[]> { + let udfs: (UserDefinedFunctionDefinition & Resource)[]; + const clearMessage = logConsoleProgress(`Querying user defined functions for container ${collectionId}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.userDefinedFunctions.readAll() + .fetchAll(); + udfs = response.resources; + } catch (error) { + logConsoleError(`Failed to query user defined functions for container ${collectionId}: ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "ReadUserDefinedFunctions", error.code); + sendNotificationForError(error); + } + clearMessage(); + return udfs; +} diff --git a/src/Common/dataAccess/updateStoredProcedure.ts b/src/Common/dataAccess/updateStoredProcedure.ts new file mode 100644 index 000000000..43ad83663 --- /dev/null +++ b/src/Common/dataAccess/updateStoredProcedure.ts @@ -0,0 +1,29 @@ +import { Resource, StoredProcedureDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function updateStoredProcedure( + databaseId: string, + collectionId: string, + storedProcedure: StoredProcedureDefinition +): Promise { + let updatedStoredProcedure: StoredProcedureDefinition & Resource; + const clearMessage = logConsoleProgress(`Updating stored procedure ${storedProcedure.id}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.storedProcedure(storedProcedure.id) + .replace(storedProcedure); + updatedStoredProcedure = response.resource; + } catch (error) { + logConsoleError(`Error while updating stored procedure ${storedProcedure.id}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "UpdateStoredProcedure", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return updatedStoredProcedure; +} diff --git a/src/Common/dataAccess/updateTrigger.ts b/src/Common/dataAccess/updateTrigger.ts new file mode 100644 index 000000000..016702602 --- /dev/null +++ b/src/Common/dataAccess/updateTrigger.ts @@ -0,0 +1,29 @@ +import { TriggerDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function updateTrigger( + databaseId: string, + collectionId: string, + trigger: TriggerDefinition +): Promise { + let updatedTrigger: TriggerDefinition; + const clearMessage = logConsoleProgress(`Updating trigger ${trigger.id}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.trigger(trigger.id) + .replace(trigger); + updatedTrigger = response.resource; + } catch (error) { + logConsoleError(`Error while updating trigger ${trigger.id}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "UpdateTrigger", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return updatedTrigger; +} diff --git a/src/Common/dataAccess/updateUserDefinedFunction.ts b/src/Common/dataAccess/updateUserDefinedFunction.ts new file mode 100644 index 000000000..cc02124c7 --- /dev/null +++ b/src/Common/dataAccess/updateUserDefinedFunction.ts @@ -0,0 +1,29 @@ +import { Resource, UserDefinedFunctionDefinition } from "@azure/cosmos"; +import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { client } from "../CosmosClient"; +import { logError } from "../Logger"; +import { sendNotificationForError } from "./sendNotificationForError"; + +export async function updateUserDefinedFunction( + databaseId: string, + collectionId: string, + userDefinedFunction: UserDefinedFunctionDefinition +): Promise { + let updatedUserDefinedFunction: UserDefinedFunctionDefinition & Resource; + const clearMessage = logConsoleProgress(`Updating user defined function ${userDefinedFunction.id}`); + try { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.userDefinedFunction(userDefinedFunction.id) + .replace(userDefinedFunction); + updatedUserDefinedFunction = response.resource; + } catch (error) { + logConsoleError(`Error while updating user defined function ${userDefinedFunction.id}:\n ${JSON.stringify(error)}`); + logError(JSON.stringify(error), "UpdateUserupdateUserDefinedFunction", error.code); + sendNotificationForError(error); + } + + clearMessage(); + return updatedUserDefinedFunction; +} diff --git a/src/Contracts/DataModels.ts b/src/Contracts/DataModels.ts index 0a6d13970..ea141bbee 100644 --- a/src/Contracts/DataModels.ts +++ b/src/Contracts/DataModels.ts @@ -88,10 +88,6 @@ export interface Resource { id: string; } -export interface ResourceRequest { - id: string; -} - export interface Collection extends Resource { defaultTtl?: number; indexingPolicy?: IndexingPolicy; @@ -104,39 +100,12 @@ export interface Collection extends Resource { geospatialConfig?: GeospatialConfig; } -export interface CreateCollectionWithRpResponse extends Resource { - properties: Collection; - name: string; - type: string; -} - -export interface CollectionRequest extends ResourceRequest { - defaultTtl?: number; - indexingPolicy?: IndexingPolicy; - partitionKey?: PartitionKey; - uniqueKeyPolicy?: UniqueKeyPolicy; - conflictResolutionPolicy?: ConflictResolutionPolicy; -} - export interface Database extends Resource { collections?: Collection[]; } export interface DocumentId extends Resource {} -export interface Script extends Resource { - body: string; -} - -export interface StoredProcedure extends Script {} - -export interface UserDefinedFunction extends Script {} - -export interface Trigger extends Script { - triggerType: string; - triggerOperation: string; -} - export interface ConflictId extends Resource { resourceId?: string; resourceType?: string; @@ -259,28 +228,6 @@ export interface ErrorDataModel { code?: string; } -/** - * Defines a property bag for telemetry e.g. see ITelemetryError. - */ -export interface ITelemetryProperties { - [propertyName: string]: string; -} - -/** - * Defines a property bag for telemetry e.g. see ITelemetryError. - */ -export interface ITelemetryEvent { - name: string; - properties?: ITelemetryProperties; -} - -/** - * Defines an error to be logged as telemetry data. - */ -export interface ITelemetryError extends ITelemetryEvent { - error: any; -} - export interface CreateDatabaseAndCollectionRequest { databaseId: string; collectionId: string; @@ -307,11 +254,6 @@ export enum AutopilotTier { Tier4 = 4 } -export interface RpOptions { - // tier is sent as string, autoscale as object (AutoPilotCreationSettings) - [key: string]: string | AutoPilotCreationSettings; -} - export interface Query { id: string; resourceId: string; @@ -347,12 +289,6 @@ export interface CreateCollectionParams { uniqueKeyPolicy?: UniqueKeyPolicy; } -export interface SharedThroughputRange { - minimumRU: number; - maximumRU: number; - defaultRU: number; -} - export interface Notification { id: string; kind: string; @@ -495,25 +431,6 @@ export interface NotebookConfigurationEndpointInfo { token: string; } -export interface SparkCluster { - id: string; - name: string; - type: string; - properties: { - kind: string; - driverSize: string; - workerSize: string; - workerInstanceCount: number; - creationTime: string; - status: string; - libraries?: SparkClusterLibrary[]; - }; -} - -export interface SparkClusterFeedResponse { - value: SparkCluster[]; -} - export interface SparkClusterConnectionInfo { userName: string; password: string; @@ -555,79 +472,10 @@ export interface MongoParameters extends RpParameters { analyticalStorageTtl?: number; } -export interface GraphParameters extends RpParameters { - pk: string; - coll: string; - cd: Boolean; - indexingPolicy?: IndexingPolicy; -} - -export interface CreationRequest { - properties: { - resource: { - id: string; - }; - options: RpOptions; - }; -} - -export interface SqlCollectionParameters extends RpParameters { - uniqueKeyPolicy?: UniqueKeyPolicy; - pk: string; - coll: string; - cd: Boolean; - analyticalStorageTtl?: number; - indexingPolicy?: IndexingPolicy; -} - -export interface MongoCreationRequest extends CreationRequest { - properties: { - resource: { - id: string; - analyticalStorageTtl?: number; - shardKey?: {}; - }; - options: RpOptions; - }; -} - -export interface GraphCreationRequest extends CreationRequest { - properties: { - resource: { - id: string; - partitionKey: {}; - indexingPolicy?: IndexingPolicy; - }; - options: RpOptions; - }; -} - -export interface CreateDatabaseWithRpResponse { - id: string; - name: string; - type: string; - properties: { - id: string; - }; -} - export interface SparkClusterLibrary { name: string; } -export interface SqlCollectionCreationRequest extends CreationRequest { - properties: { - resource: { - uniqueKeyPolicy?: UniqueKeyPolicy; - id: string; - partitionKey: {}; - analyticalStorageTtl?: number; - indexingPolicy?: IndexingPolicy; - }; - options: RpOptions; - }; -} - export interface Library extends SparkClusterLibrary { properties: { kind: "Jar"; diff --git a/src/Contracts/ViewModels.ts b/src/Contracts/ViewModels.ts index 464974d7d..ab98e913c 100644 --- a/src/Contracts/ViewModels.ts +++ b/src/Contracts/ViewModels.ts @@ -1,16 +1,22 @@ -import * as DataModels from "./DataModels"; +import { + QueryMetrics, + Resource, + StoredProcedureDefinition, + TriggerDefinition, + UserDefinedFunctionDefinition +} from "@azure/cosmos"; import Q from "q"; -import { CassandraTableKey, CassandraTableKeys } from "../Explorer/Tables/TableDataClient"; import { CommandButtonComponentProps } from "../Explorer/Controls/CommandButton/CommandButtonComponent"; -import { ConsoleData } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent"; -import { QueryMetrics } from "@azure/cosmos"; -import { UploadDetails } from "../workers/upload/definitions"; import Explorer from "../Explorer/Explorer"; -import UserDefinedFunction from "../Explorer/Tree/UserDefinedFunction"; +import { ConsoleData } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent"; +import { CassandraTableKey, CassandraTableKeys } from "../Explorer/Tables/TableDataClient"; +import ConflictId from "../Explorer/Tree/ConflictId"; +import DocumentId from "../Explorer/Tree/DocumentId"; import StoredProcedure from "../Explorer/Tree/StoredProcedure"; import Trigger from "../Explorer/Tree/Trigger"; -import DocumentId from "../Explorer/Tree/DocumentId"; -import ConflictId from "../Explorer/Tree/ConflictId"; +import UserDefinedFunction from "../Explorer/Tree/UserDefinedFunction"; +import { UploadDetails } from "../workers/upload/definitions"; +import * as DataModels from "./DataModels"; export interface TokenProvider { getAuthHeader(): Promise; @@ -153,13 +159,13 @@ export interface Collection extends CollectionBase { collapseUserDefinedFunctions(): void; collapseTriggers(): void; - loadUserDefinedFunctions(): Q.Promise; - loadStoredProcedures(): Q.Promise; - loadTriggers(): Q.Promise; + loadUserDefinedFunctions(): Promise; + loadStoredProcedures(): Promise; + loadTriggers(): Promise; - createStoredProcedureNode(data: DataModels.StoredProcedure): StoredProcedure; - createUserDefinedFunctionNode(data: DataModels.UserDefinedFunction): UserDefinedFunction; - createTriggerNode(data: DataModels.Trigger): Trigger; + createStoredProcedureNode(data: StoredProcedureDefinition & Resource): StoredProcedure; + createUserDefinedFunctionNode(data: UserDefinedFunctionDefinition & Resource): UserDefinedFunction; + createTriggerNode(data: TriggerDefinition & Resource): Trigger; findStoredProcedureWithId(sprocRid: string): StoredProcedure; findTriggerWithId(triggerRid: string): Trigger; findUserDefinedFunctionWithId(udfRid: string): UserDefinedFunction; diff --git a/src/Explorer/Tabs/ScriptTabBase.ts b/src/Explorer/Tabs/ScriptTabBase.ts index ab2d46250..2bcdab272 100644 --- a/src/Explorer/Tabs/ScriptTabBase.ts +++ b/src/Explorer/Tabs/ScriptTabBase.ts @@ -1,15 +1,14 @@ -import * as Constants from "../../Common/Constants"; import * as ko from "knockout"; +import * as monaco from "monaco-editor"; import Q from "q"; - +import DiscardIcon from "../../../images/discard.svg"; +import SaveIcon from "../../../images/save-cosmos.svg"; +import * as Constants from "../../Common/Constants"; +import editable from "../../Common/EditableUtility"; import * as DataModels from "../../Contracts/DataModels"; import * as ViewModels from "../../Contracts/ViewModels"; -import TabsBase from "./TabsBase"; -import editable from "../../Common/EditableUtility"; -import * as monaco from "monaco-editor"; -import SaveIcon from "../../../images/save-cosmos.svg"; -import DiscardIcon from "../../../images/discard.svg"; import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent"; +import TabsBase from "./TabsBase"; export default abstract class ScriptTabBase extends TabsBase implements ViewModels.WaitsForTemplate { public ariaLabel: ko.Observable; @@ -30,7 +29,8 @@ export default abstract class ScriptTabBase extends TabsBase implements ViewMode public formIsValid: ko.Computed; public formIsDirty: ko.Computed; public isNew: ko.Observable; - public resource: ko.Observable; + // TODO: Remove any. The SDK types for all the script.body are slightly incorrect which makes this REALLY hard to type correct. + public resource: ko.Observable; public isTemplateReady: ko.Observable; protected _partitionKey: DataModels.PartitionKey; @@ -194,8 +194,8 @@ export default abstract class ScriptTabBase extends TabsBase implements ViewMode }); } - public abstract onSaveClick: () => Q.Promise; - public abstract onUpdateClick: () => Q.Promise; + public abstract onSaveClick: () => Promise; + public abstract onUpdateClick: () => Promise; public onDiscard = (): Q.Promise => { this.setBaselines(); @@ -206,14 +206,14 @@ export default abstract class ScriptTabBase extends TabsBase implements ViewMode return Q(); }; - public onSaveOrUpdateClick(): Q.Promise { + public onSaveOrUpdateClick(): Promise { if (this.saveButton.visible()) { return this.onSaveClick(); } else if (this.updateButton.visible()) { return this.onUpdateClick(); } - return Q(); + return undefined; } protected getTabsButtons(): CommandButtonComponentProps[] { diff --git a/src/Explorer/Tabs/StoredProcedureTab.ts b/src/Explorer/Tabs/StoredProcedureTab.ts index cffeae959..49065cb9e 100644 --- a/src/Explorer/Tabs/StoredProcedureTab.ts +++ b/src/Explorer/Tabs/StoredProcedureTab.ts @@ -1,17 +1,18 @@ +import { Resource, StoredProcedureDefinition } from "@azure/cosmos"; import * as ko from "knockout"; -import * as _ from "underscore"; import Q from "q"; +import * as _ from "underscore"; +import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg"; import * as Constants from "../../Common/Constants"; -import * as DataModels from "../../Contracts/DataModels"; +import { createStoredProcedure } from "../../Common/dataAccess/createStoredProcedure"; +import { updateStoredProcedure } from "../../Common/dataAccess/updateStoredProcedure"; +import editable from "../../Common/EditableUtility"; import * as ViewModels from "../../Contracts/ViewModels"; import { Action } from "../../Shared/Telemetry/TelemetryConstants"; -import editable from "../../Common/EditableUtility"; -import ScriptTabBase from "./ScriptTabBase"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; -import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg"; -import StoredProcedure from "../Tree/StoredProcedure"; -import { createStoredProcedure, updateStoredProcedure } from "../../Common/DocumentClientUtilityBase"; import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent"; +import StoredProcedure from "../Tree/StoredProcedure"; +import ScriptTabBase from "./ScriptTabBase"; enum ToggleState { Result = "result", @@ -24,7 +25,6 @@ export default class StoredProcedureTab extends ScriptTabBase { public executeResultsEditorId: string; public executeLogsEditorId: string; public toggleState: ko.Observable; - public originalSprocBody: ViewModels.Editable; public resultsData: ko.Observable; public logsData: ko.Observable; @@ -54,13 +54,11 @@ export default class StoredProcedureTab extends ScriptTabBase { this.buildCommandBarOptions(); } - public onSaveClick = (): Q.Promise => { - const resource: DataModels.StoredProcedure = { + public onSaveClick = (): Promise => { + return this._createStoredProcedure({ id: this.id(), body: this.editorContent() - }; - - return this._createStoredProcedure(resource); + }); }; public onDiscard = (): Q.Promise => { @@ -72,8 +70,8 @@ export default class StoredProcedureTab extends ScriptTabBase { return Q(); }; - public onUpdateClick = (): Q.Promise => { - const data: DataModels.StoredProcedure = this._getResource(); + public onUpdateClick = (): Promise => { + const data = this._getResource(); this.isExecutionError(false); this.isExecuting(true); @@ -83,18 +81,18 @@ export default class StoredProcedureTab extends ScriptTabBase { dataExplorerArea: Constants.Areas.Tab, tabTitle: this.tabTitle() }); - return updateStoredProcedure(this.collection, data) + return updateStoredProcedure(this.collection.databaseId, this.collection.id(), data) .then( - (updatedResource: DataModels.StoredProcedure) => { + updatedResource => { this.resource(updatedResource); this.tabTitle(updatedResource.id); this.node.id(updatedResource.id); - this.node.body(updatedResource.body); + this.node.body(updatedResource.body as string); this.setBaselines(); const editorModel = this.editor() && this.editor().getModel(); - editorModel && editorModel.setValue(updatedResource.body); - this.editorContent.setBaseline(updatedResource.body); + editorModel && editorModel.setValue(updatedResource.body as string); + this.editorContent.setBaseline(updatedResource.body as string); TelemetryProcessor.traceSuccess( Action.UpdateStoredProcedure, { @@ -220,18 +218,14 @@ export default class StoredProcedureTab extends ScriptTabBase { }); } - private _getResource(): DataModels.StoredProcedure { - const resource: DataModels.StoredProcedure = { - _rid: this.resource()._rid, - _self: this.resource()._self, + private _getResource() { + return { id: this.id(), body: this.editorContent() }; - - return resource; } - private _createStoredProcedure(resource: DataModels.StoredProcedure): Q.Promise { + private _createStoredProcedure(resource: StoredProcedureDefinition): Promise { this.isExecutionError(false); this.isExecuting(true); const startKey: number = TelemetryProcessor.traceStart(Action.CreateStoredProcedure, { @@ -241,7 +235,7 @@ export default class StoredProcedureTab extends ScriptTabBase { tabTitle: this.tabTitle() }); - return createStoredProcedure(this.collection, resource) + return createStoredProcedure(this.collection.databaseId, this.collection.id(), resource) .then( createdResource => { this.tabTitle(createdResource.id); @@ -256,8 +250,8 @@ export default class StoredProcedureTab extends ScriptTabBase { this.setBaselines(); const editorModel = this.editor() && this.editor().getModel(); - editorModel && editorModel.setValue(createdResource.body); - this.editorContent.setBaseline(createdResource.body); + editorModel && editorModel.setValue(createdResource.body as string); + this.editorContent.setBaseline(createdResource.body as string); this.node = this.collection.createStoredProcedureNode(createdResource); TelemetryProcessor.traceSuccess( Action.CreateStoredProcedure, @@ -284,7 +278,7 @@ export default class StoredProcedureTab extends ScriptTabBase { }, startKey ); - return Q.reject(createError); + return Promise.reject(createError); } ) .finally(() => this.isExecuting(false)); diff --git a/src/Explorer/Tabs/TriggerTab.ts b/src/Explorer/Tabs/TriggerTab.ts index 27c5e5dc7..74e623738 100644 --- a/src/Explorer/Tabs/TriggerTab.ts +++ b/src/Explorer/Tabs/TriggerTab.ts @@ -1,13 +1,13 @@ -import Q from "q"; +import { Resource, TriggerDefinition, TriggerOperation, TriggerType } from "@azure/cosmos"; import * as Constants from "../../Common/Constants"; -import * as DataModels from "../../Contracts/DataModels"; +import { createTrigger } from "../../Common/dataAccess/createTrigger"; +import { updateTrigger } from "../../Common/dataAccess/updateTrigger"; +import editable from "../../Common/EditableUtility"; import * as ViewModels from "../../Contracts/ViewModels"; import { Action } from "../../Shared/Telemetry/TelemetryConstants"; -import ScriptTabBase from "./ScriptTabBase"; -import editable from "../../Common/EditableUtility"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import Trigger from "../Tree/Trigger"; -import { createTrigger, updateTrigger } from "../../Common/DocumentClientUtilityBase"; +import ScriptTabBase from "./ScriptTabBase"; export default class TriggerTab extends ScriptTabBase { public collection: ViewModels.Collection; @@ -27,13 +27,17 @@ export default class TriggerTab extends ScriptTabBase { super.buildCommandBarOptions(); } - public onSaveClick = (): Q.Promise => { - const data: DataModels.Trigger = this._getResource(); - return this._createTrigger(data); + public onSaveClick = (): Promise => { + return this._createTrigger({ + id: this.id(), + body: this.editorContent(), + triggerOperation: this.triggerOperation() as TriggerOperation, + triggerType: this.triggerType() as TriggerType + }); }; - public onUpdateClick = (): Q.Promise => { - const data: DataModels.Trigger = this._getResource(); + public onUpdateClick = (): Promise => { + const data = this._getResource(); this.isExecutionError(false); this.isExecuting(true); const startKey: number = TelemetryProcessor.traceStart(Action.UpdateTrigger, { @@ -42,14 +46,19 @@ export default class TriggerTab extends ScriptTabBase { tabTitle: this.tabTitle() }); - return updateTrigger(this.collection, data) + return updateTrigger(this.collection.databaseId, this.collection.id(), { + id: this.id(), + body: this.editorContent(), + triggerOperation: this.triggerOperation() as TriggerOperation, + triggerType: this.triggerType() as TriggerType + }) .then( - (createdResource: DataModels.Trigger) => { + createdResource => { this.resource(createdResource); this.tabTitle(createdResource.id); this.node.id(createdResource.id); - this.node.body(createdResource.body); + this.node.body(createdResource.body as string); this.node.triggerType(createdResource.triggerOperation); this.node.triggerOperation(createdResource.triggerOperation); TelemetryProcessor.traceSuccess( @@ -66,8 +75,8 @@ export default class TriggerTab extends ScriptTabBase { this.setBaselines(); const editorModel = this.editor().getModel(); - editorModel.setValue(createdResource.body); - this.editorContent.setBaseline(createdResource.body); + editorModel.setValue(createdResource.body as string); + this.editorContent.setBaseline(createdResource.body as string); }, (createError: any) => { this.isExecutionError(true); @@ -89,7 +98,7 @@ export default class TriggerTab extends ScriptTabBase { public setBaselines() { super.setBaselines(); - const resource = this.resource(); + const resource = this.resource(); this.triggerOperation.setBaseline(resource.triggerOperation); this.triggerType.setBaseline(resource.triggerType); } @@ -109,7 +118,7 @@ export default class TriggerTab extends ScriptTabBase { } } - private _createTrigger(resource: DataModels.Trigger): Q.Promise { + private _createTrigger(resource: TriggerDefinition): Promise { this.isExecutionError(false); this.isExecuting(true); const startKey: number = TelemetryProcessor.traceStart(Action.CreateTrigger, { @@ -119,9 +128,9 @@ export default class TriggerTab extends ScriptTabBase { tabTitle: this.tabTitle() }); - return createTrigger(this.collection, resource) + return createTrigger(this.collection.databaseId, this.collection.id(), resource) .then( - (createdResource: DataModels.Trigger) => { + createdResource => { this.tabTitle(createdResource.id); this.isNew(false); this.resource(createdResource); @@ -134,8 +143,8 @@ export default class TriggerTab extends ScriptTabBase { this.setBaselines(); const editorModel = this.editor().getModel(); - editorModel.setValue(createdResource.body); - this.editorContent.setBaseline(createdResource.body); + editorModel.setValue(createdResource.body as string); + this.editorContent.setBaseline(createdResource.body as string); this.node = this.collection.createTriggerNode(createdResource); TelemetryProcessor.traceSuccess( @@ -163,22 +172,18 @@ export default class TriggerTab extends ScriptTabBase { }, startKey ); - return Q.reject(createError); + return Promise.reject(createError); } ) .finally(() => this.isExecuting(false)); } - private _getResource(): DataModels.Trigger { - const resource: DataModels.Trigger = { - _rid: this.resource()._rid, - _self: this.resource()._self, + private _getResource() { + return { id: this.id(), body: this.editorContent(), triggerOperation: this.triggerOperation(), triggerType: this.triggerType() }; - - return resource; } } diff --git a/src/Explorer/Tabs/UserDefinedFunctionTab.ts b/src/Explorer/Tabs/UserDefinedFunctionTab.ts index 8507b3e93..41d803476 100644 --- a/src/Explorer/Tabs/UserDefinedFunctionTab.ts +++ b/src/Explorer/Tabs/UserDefinedFunctionTab.ts @@ -1,12 +1,12 @@ -import Q from "q"; +import { Resource, UserDefinedFunctionDefinition } from "@azure/cosmos"; import * as Constants from "../../Common/Constants"; -import * as DataModels from "../../Contracts/DataModels"; +import { createUserDefinedFunction } from "../../Common/dataAccess/createUserDefinedFunction"; +import { updateUserDefinedFunction } from "../../Common/dataAccess/updateUserDefinedFunction"; import * as ViewModels from "../../Contracts/ViewModels"; import { Action } from "../../Shared/Telemetry/TelemetryConstants"; -import ScriptTabBase from "./ScriptTabBase"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import UserDefinedFunction from "../Tree/UserDefinedFunction"; -import { createUserDefinedFunction, updateUserDefinedFunction } from "../../Common/DocumentClientUtilityBase"; +import ScriptTabBase from "./ScriptTabBase"; export default class UserDefinedFunctionTab extends ScriptTabBase { public collection: ViewModels.Collection; @@ -19,13 +19,13 @@ export default class UserDefinedFunctionTab extends ScriptTabBase { super.buildCommandBarOptions(); } - public onSaveClick = (): Q.Promise => { - const data: DataModels.UserDefinedFunction = this._getResource(); + public onSaveClick = (): Promise => { + const data = this._getResource(); return this._createUserDefinedFunction(data); }; - public onUpdateClick = (): Q.Promise => { - const data: DataModels.UserDefinedFunction = this._getResource(); + public onUpdateClick = (): Promise => { + const data = this._getResource(); this.isExecutionError(false); this.isExecuting(true); const startKey: number = TelemetryProcessor.traceStart(Action.UpdateUDF, { @@ -35,14 +35,14 @@ export default class UserDefinedFunctionTab extends ScriptTabBase { tabTitle: this.tabTitle() }); - return updateUserDefinedFunction(this.collection, data) + return updateUserDefinedFunction(this.collection.databaseId, this.collection.id(), data) .then( - (createdResource: DataModels.UserDefinedFunction) => { + createdResource => { this.resource(createdResource); this.tabTitle(createdResource.id); this.node.id(createdResource.id); - this.node.body(createdResource.body); + this.node.body(createdResource.body as string); TelemetryProcessor.traceSuccess( Action.UpdateUDF, { @@ -57,8 +57,8 @@ export default class UserDefinedFunctionTab extends ScriptTabBase { this.setBaselines(); const editorModel = this.editor().getModel(); - editorModel.setValue(createdResource.body); - this.editorContent.setBaseline(createdResource.body); + editorModel.setValue(createdResource.body as string); + this.editorContent.setBaseline(createdResource.body as string); }, (createError: any) => { this.isExecutionError(true); @@ -93,8 +93,8 @@ export default class UserDefinedFunctionTab extends ScriptTabBase { } private _createUserDefinedFunction( - resource: DataModels.UserDefinedFunction - ): Q.Promise { + resource: UserDefinedFunctionDefinition + ): Promise { this.isExecutionError(false); this.isExecuting(true); const startKey: number = TelemetryProcessor.traceStart(Action.CreateUDF, { @@ -104,9 +104,9 @@ export default class UserDefinedFunctionTab extends ScriptTabBase { tabTitle: this.tabTitle() }); - return createUserDefinedFunction(this.collection, resource) + return createUserDefinedFunction(this.collection.databaseId, this.collection.id(), resource) .then( - (createdResource: DataModels.UserDefinedFunction) => { + createdResource => { this.tabTitle(createdResource.id); this.isNew(false); this.resource(createdResource); @@ -118,8 +118,8 @@ export default class UserDefinedFunctionTab extends ScriptTabBase { this.setBaselines(); const editorModel = this.editor().getModel(); - editorModel.setValue(createdResource.body); - this.editorContent.setBaseline(createdResource.body); + editorModel.setValue(createdResource.body as string); + this.editorContent.setBaseline(createdResource.body as string); this.node = this.collection.createUserDefinedFunctionNode(createdResource); TelemetryProcessor.traceSuccess( @@ -147,14 +147,14 @@ export default class UserDefinedFunctionTab extends ScriptTabBase { }, startKey ); - return Q.reject(createError); + return Promise.reject(createError); } ) .finally(() => this.isExecuting(false)); } private _getResource() { - const resource: DataModels.UserDefinedFunction = { + const resource = { _rid: this.resource()._rid, _self: this.resource()._self, id: this.id(), diff --git a/src/Explorer/Tree/Collection.ts b/src/Explorer/Tree/Collection.ts index 8a0da4f69..835142ea7 100644 --- a/src/Explorer/Tree/Collection.ts +++ b/src/Explorer/Tree/Collection.ts @@ -1,23 +1,28 @@ +import { Resource, StoredProcedureDefinition, TriggerDefinition, UserDefinedFunctionDefinition } from "@azure/cosmos"; import * as ko from "knockout"; import Q from "q"; import * as _ from "underscore"; import UploadWorker from "worker-loader!../../workers/upload"; import { AuthType } from "../../AuthType"; import * as Constants from "../../Common/Constants"; +import { readStoredProcedures } from "../../Common/dataAccess/readStoredProcedures"; +import { readTriggers } from "../../Common/dataAccess/readTriggers"; +import { readUserDefinedFunctions } from "../../Common/dataAccess/readUserDefinedFunctions"; +import { createDocument, readCollectionQuotaInfo, readOffer, readOffers } from "../../Common/DocumentClientUtilityBase"; import * as Logger from "../../Common/Logger"; +import { configContext } from "../../ConfigContext"; import * as DataModels from "../../Contracts/DataModels"; import * as ViewModels from "../../Contracts/ViewModels"; import { PlatformType } from "../../PlatformType"; import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; +import { userContext } from "../../UserContext"; import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils"; import { OfferUtils } from "../../Utils/OfferUtils"; import { StartUploadMessageParams, UploadDetails, UploadDetailsRecord } from "../../workers/upload/definitions"; +import Explorer from "../Explorer"; import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent"; import { CassandraAPIDataClient, CassandraTableKey, CassandraTableKeys } from "../Tables/TableDataClient"; -import ConflictId from "./ConflictId"; - -import DocumentId from "./DocumentId"; import ConflictsTab from "../Tabs/ConflictsTab"; import DocumentsTab from "../Tabs/DocumentsTab"; import GraphTab from "../Tabs/GraphTab"; @@ -27,21 +32,11 @@ import MongoShellTab from "../Tabs/MongoShellTab"; import QueryTab from "../Tabs/QueryTab"; import QueryTablesTab from "../Tabs/QueryTablesTab"; import SettingsTab from "../Tabs/SettingsTab"; +import ConflictId from "./ConflictId"; +import DocumentId from "./DocumentId"; import StoredProcedure from "./StoredProcedure"; import Trigger from "./Trigger"; import UserDefinedFunction from "./UserDefinedFunction"; -import { configContext } from "../../ConfigContext"; -import Explorer from "../Explorer"; -import { - createDocument, - readTriggers, - readUserDefinedFunctions, - readStoredProcedures, - readCollectionQuotaInfo, - readOffer, - readOffers -} from "../../Common/DocumentClientUtilityBase"; -import { userContext } from "../../UserContext"; export default class Collection implements ViewModels.Collection { public nodeKind: string; @@ -854,21 +849,21 @@ export default class Collection implements ViewModels.Collection { Trigger.create(source, event); } - public createStoredProcedureNode(data: DataModels.StoredProcedure): StoredProcedure { + public createStoredProcedureNode(data: StoredProcedureDefinition & Resource): StoredProcedure { const node = new StoredProcedure(this.container, this, data); this.container.selectedNode(node); this.children.push(node); return node; } - public createUserDefinedFunctionNode(data: DataModels.UserDefinedFunction): UserDefinedFunction { + public createUserDefinedFunctionNode(data: UserDefinedFunctionDefinition & Resource): UserDefinedFunction { const node = new UserDefinedFunction(this.container, this, data); this.container.selectedNode(node); this.children.push(node); return node; } - public createTriggerNode(data: DataModels.Trigger): Trigger { + public createTriggerNode(data: TriggerDefinition & Resource): Trigger { const node = new Trigger(this.container, this, data); this.container.selectedNode(node); this.children.push(node); @@ -1062,8 +1057,8 @@ export default class Collection implements ViewModels.Collection { }); } - public loadStoredProcedures(): Q.Promise { - return readStoredProcedures(this).then((storedProcedures: DataModels.StoredProcedure[]) => { + public loadStoredProcedures(): Promise { + return readStoredProcedures(this.databaseId, this.id()).then(storedProcedures => { const storedProceduresNodes: ViewModels.TreeNode[] = storedProcedures.map( storedProcedure => new StoredProcedure(this.container, this, storedProcedure) ); @@ -1073,8 +1068,8 @@ export default class Collection implements ViewModels.Collection { }); } - public loadUserDefinedFunctions(): Q.Promise { - return readUserDefinedFunctions(this).then((userDefinedFunctions: DataModels.UserDefinedFunction[]) => { + public loadUserDefinedFunctions(): Promise { + return readUserDefinedFunctions(this.databaseId, this.id()).then(userDefinedFunctions => { const userDefinedFunctionsNodes: ViewModels.TreeNode[] = userDefinedFunctions.map( udf => new UserDefinedFunction(this.container, this, udf) ); @@ -1084,8 +1079,8 @@ export default class Collection implements ViewModels.Collection { }); } - public loadTriggers(): Q.Promise { - return readTriggers(this, null /*options*/).then((triggers: DataModels.Trigger[]) => { + public loadTriggers(): Promise { + return readTriggers(this.databaseId, this.id()).then(triggers => { 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); diff --git a/src/Explorer/Tree/StoredProcedure.ts b/src/Explorer/Tree/StoredProcedure.ts index 3629c574f..8622f3fd0 100644 --- a/src/Explorer/Tree/StoredProcedure.ts +++ b/src/Explorer/Tree/StoredProcedure.ts @@ -1,13 +1,13 @@ +import { Resource, StoredProcedureDefinition } from "@azure/cosmos"; import * as ko from "knockout"; -import * as ViewModels from "../../Contracts/ViewModels"; import * as Constants from "../../Common/Constants"; -import * as DataModels from "../../Contracts/DataModels"; +import { deleteStoredProcedure } from "../../Common/dataAccess/deleteStoredProcedure"; +import { executeStoredProcedure } from "../../Common/DocumentClientUtilityBase"; +import * as ViewModels from "../../Contracts/ViewModels"; import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants"; - -import StoredProcedureTab from "../Tabs/StoredProcedureTab"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import Explorer from "../Explorer"; -import { deleteStoredProcedure, executeStoredProcedure } from "../../Common/DocumentClientUtilityBase"; +import StoredProcedureTab from "../Tabs/StoredProcedureTab"; import TabsBase from "../Tabs/TabsBase"; const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE @@ -47,20 +47,20 @@ export default class StoredProcedure { public body: ko.Observable; public isExecuteEnabled: boolean; - constructor(container: Explorer, collection: ViewModels.Collection, data: DataModels.StoredProcedure) { + constructor(container: Explorer, collection: ViewModels.Collection, data: StoredProcedureDefinition & Resource) { this.nodeKind = "StoredProcedure"; this.container = container; this.collection = collection; this.self = data._self; this.rid = data._rid; this.id = ko.observable(data.id); - this.body = ko.observable(data.body); + this.body = ko.observable(data.body as string); this.isExecuteEnabled = this.container.isFeatureEnabled(Constants.Features.executeSproc); } public static create(source: ViewModels.Collection, event: MouseEvent) { const id = source.container.tabsManager.getTabs(ViewModels.CollectionTabKind.StoredProcedures).length + 1; - const storedProcedure = { + const storedProcedure = { id: "", body: sampleStoredProcedureBody }; @@ -104,7 +104,7 @@ export default class StoredProcedure { if (storedProcedureTab) { this.container.tabsManager.activateTab(storedProcedureTab); } else { - const storedProcedureData = { + const storedProcedureData = { _rid: this.rid, _self: this.self, id: this.id(), @@ -137,14 +137,7 @@ export default class StoredProcedure { return; } - const storedProcedureData = { - _rid: this.rid, - _self: this.self, - id: this.id(), - body: this.body() - }; - - deleteStoredProcedure(this.collection, storedProcedureData).then( + deleteStoredProcedure(this.collection.databaseId, this.collection.id(), this.id()).then( () => { this.container.tabsManager.removeTabByComparator((tab: TabsBase) => tab.node && tab.node.rid === this.rid); this.collection.children.remove(this); diff --git a/src/Explorer/Tree/Trigger.ts b/src/Explorer/Tree/Trigger.ts index b191f1569..6e9a72481 100644 --- a/src/Explorer/Tree/Trigger.ts +++ b/src/Explorer/Tree/Trigger.ts @@ -1,12 +1,12 @@ +import { StoredProcedureDefinition } from "@azure/cosmos"; import * as ko from "knockout"; -import * as ViewModels from "../../Contracts/ViewModels"; import * as Constants from "../../Common/Constants"; -import * as DataModels from "../../Contracts/DataModels"; +import { deleteTrigger } from "../../Common/dataAccess/deleteTrigger"; +import * as ViewModels from "../../Contracts/ViewModels"; import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants"; -import TriggerTab from "../Tabs/TriggerTab"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import Explorer from "../Explorer"; -import { deleteTrigger } from "../../Common/DocumentClientUtilityBase"; +import TriggerTab from "../Tabs/TriggerTab"; export default class Trigger { public nodeKind: string; @@ -43,7 +43,7 @@ export default class Trigger { public static create(source: ViewModels.Collection, event: MouseEvent) { const id = source.container.tabsManager.getTabs(ViewModels.CollectionTabKind.Triggers).length + 1; - const trigger = { + const trigger = { id: "", body: "function trigger(){}", triggerOperation: "All", @@ -79,7 +79,7 @@ export default class Trigger { if (triggerTab) { this.container.tabsManager.activateTab(triggerTab); } else { - const triggerData = { + const triggerData = { _rid: this.rid, _self: this.self, id: this.id(), @@ -114,16 +114,7 @@ export default class Trigger { return; } - const triggerData = { - _rid: this.rid, - _self: this.self, - id: this.id(), - body: this.body(), - triggerOperation: this.triggerOperation(), - triggerType: this.triggerType() - }; - - deleteTrigger(this.collection, triggerData).then( + deleteTrigger(this.collection.databaseId, this.collection.id(), this.id()).then( () => { this.container.tabsManager.removeTabByComparator(tab => tab.node && tab.node.rid === this.rid); this.collection.children.remove(this); diff --git a/src/Explorer/Tree/UserDefinedFunction.ts b/src/Explorer/Tree/UserDefinedFunction.ts index cf0864788..92ef9406c 100644 --- a/src/Explorer/Tree/UserDefinedFunction.ts +++ b/src/Explorer/Tree/UserDefinedFunction.ts @@ -1,12 +1,12 @@ +import { Resource, UserDefinedFunctionDefinition } from "@azure/cosmos"; import * as ko from "knockout"; -import * as ViewModels from "../../Contracts/ViewModels"; import * as Constants from "../../Common/Constants"; -import * as DataModels from "../../Contracts/DataModels"; +import { deleteUserDefinedFunction } from "../../Common/dataAccess/deleteUserDefinedFunction"; +import * as ViewModels from "../../Contracts/ViewModels"; import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants"; -import UserDefinedFunctionTab from "../Tabs/UserDefinedFunctionTab"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import Explorer from "../Explorer"; -import { deleteUserDefinedFunction } from "../../Common/DocumentClientUtilityBase"; +import UserDefinedFunctionTab from "../Tabs/UserDefinedFunctionTab"; export default class UserDefinedFunction { public nodeKind: string; @@ -17,7 +17,7 @@ export default class UserDefinedFunction { public id: ko.Observable; public body: ko.Observable; - constructor(container: Explorer, collection: ViewModels.Collection, data: DataModels.UserDefinedFunction) { + constructor(container: Explorer, collection: ViewModels.Collection, data: UserDefinedFunctionDefinition & Resource) { this.nodeKind = "UserDefinedFunction"; this.container = container; @@ -25,12 +25,12 @@ export default class UserDefinedFunction { this.self = data._self; this.rid = data._rid; this.id = ko.observable(data.id); - this.body = ko.observable(data.body); + this.body = ko.observable(data.body as string); } public static create(source: ViewModels.Collection, event: MouseEvent) { const id = source.container.tabsManager.getTabs(ViewModels.CollectionTabKind.UserDefinedFunctions).length + 1; - const userDefinedFunction = { + const userDefinedFunction = { id: "", body: "function userDefinedFunction(){}" }; @@ -64,7 +64,7 @@ export default class UserDefinedFunction { if (userDefinedFunctionTab) { this.container.tabsManager.activateTab(userDefinedFunctionTab); } else { - const userDefinedFunctionData = { + const userDefinedFunctionData = { _rid: this.rid, _self: this.self, id: this.id(), @@ -107,13 +107,7 @@ export default class UserDefinedFunction { return; } - const userDefinedFunctionData = { - _rid: this.rid, - _self: this.self, - id: this.id(), - body: this.body() - }; - deleteUserDefinedFunction(this.collection, userDefinedFunctionData).then( + deleteUserDefinedFunction(this.collection.databaseId, this.collection.id(), this.id()).then( () => { this.container.tabsManager.removeTabByComparator(tab => tab.node && tab.node.rid === this.rid); this.collection.children.remove(this);