From b8f97a17a4f35d351019db6211d9a08cf921693f Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Tue, 20 Aug 2019 14:15:57 -0500 Subject: [PATCH] Add sample for bulk update with continuation token (#402) --- azure-pipelines.yml | 1 + samples/BulkUpdateWithSproc.ts | 87 ++++++++++++++++++++++++++++++++++ samples/package.json | 3 +- 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 samples/BulkUpdateWithSproc.ts diff --git a/azure-pipelines.yml b/azure-pipelines.yml index fb61027c..a3b06d02 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -82,6 +82,7 @@ jobs: npm run ContainerManagement --prefix ./samples npm run ServerSideScripts --prefix ./samples npm run ChangeFeed --prefix ./samples + npm run BulkUpdateWithSproc --prefix ./samples displayName: "Run Samples" # - job: NightlyEmulator # pool: diff --git a/samples/BulkUpdateWithSproc.ts b/samples/BulkUpdateWithSproc.ts new file mode 100644 index 00000000..342fd5e4 --- /dev/null +++ b/samples/BulkUpdateWithSproc.ts @@ -0,0 +1,87 @@ +import { logSampleHeader, handleError, finish, logStep } from "./Shared/handleError"; +import { CosmosClient } from "../dist"; +import { endpoint, key, database as databaseId, container as containerId } from "./Shared/config"; +import uuid from "uuid/v4"; + +logSampleHeader("Bulk Update Using Stored Procedures"); +// Only to make TypeScript happy +var getContext: any; + +function body(continuation: string) { + var collection = getContext().getCollection(); + var response = getContext().getResponse(); + var responseBody: any = { updatedDocumentIds: [] }; // Setup Initial Response + + // Find all documents that need to be updated + collection.queryDocuments( + collection.getSelfLink(), + "SELECT * FROM root r", + { pageSize: 2, continuation }, // Setting this low to show how continuation tokens work + function(err: any, feed: any, options: any) { + if (err) throw err; + // Set continuation token on response if we get one + responseBody.continuation = options.continuation; + // Update this batch of documents + updateDocs(feed, responseBody); + } + ); + + function updateDocs(documents: any, responseBody: any) { + if (documents.length === 0) { + // If no documents are left to update, we are done + response.setBody(responseBody); + } else { + // Grab the next document to update + var document = documents.pop(); + document.state = "open"; + collection.replaceDocument(document._self, document, {}, function(err: any) { + if (err) throw err; + // If we have successfully updated the document, include it in the returned document ids + responseBody.updatedDocumentIds.push(document.id); + // Call update with remaning documents + updateDocs(documents, responseBody); + }); + } + } +} + +// Establish a new instance of the CosmosClient to be used throughout this demo +const client = new CosmosClient({ endpoint, key }); + +async function run() { + //ensuring a database & container exists for us to work with + logStep("Create database '" + databaseId + "' and container '" + containerId + "'"); + const { database } = await client.databases.createIfNotExists({ id: databaseId }); + const { container } = await database.containers.createIfNotExists({ id: containerId }); + + logStep("Insert 20 items"); + + // Create 20 items with state set to "closed" + for (let index = 0; index < 20; index++) { + await container.items.create({ id: uuid(), state: "closed" }); + } + + logStep("Created stored procedure"); + const { storedProcedure } = await container.scripts.storedProcedures.create({ + id: "queryAndBulkUpdate", + body + }); + + logStep("Execute stored procedure and follow continuation tokens"); + let continuation: string = undefined; + let totalUpdatedDocuments = 0; + while (true) { + const response = await storedProcedure.execute(undefined, [continuation]); + const result: any = response.resource; + totalUpdatedDocuments = totalUpdatedDocuments + result.updatedDocumentIds.length; + console.log(`Updated Documents: ${result.updatedDocumentIds}`); + continuation = result.continuation; + if (!result.continuation) { + console.log("No continuation token! Updates complete"); + console.log(`Total Updated Document Count:`, totalUpdatedDocuments); + break; + } + } + await finish(); +} +run().catch(handleError); diff --git a/samples/package.json b/samples/package.json index 7a65644a..d48b6cc0 100644 --- a/samples/package.json +++ b/samples/package.json @@ -12,6 +12,7 @@ "ItemManagement": "npx ts-node ./ItemManagement", "DatabaseManagement": "npx ts-node ./DatabaseManagement", "IndexeManagement": "npx ts-node ./IndexeManagement", - "ChangeFeed": "npx ts-node ./ChangeFeed" + "ChangeFeed": "npx ts-node ./ChangeFeed", + "BulkUpdateWithSproc": "npx ts-node ./BulkUpdateWithSproc" } }