From 78e220f73fedcb02b4cf9e2d9ca785ea573407b0 Mon Sep 17 00:00:00 2001 From: sachinira Date: Wed, 31 May 2023 11:20:42 +0530 Subject: [PATCH] Add support to replace id field in a document. Resolves: https://github.com/ballerina-platform/ballerina-extended-library/issues/508 --- cosmosdb/client_endpoint.bal | 28 +++++++++------- cosmosdb/tests/test.bal | 64 ++++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 18 deletions(-) diff --git a/cosmosdb/client_endpoint.bal b/cosmosdb/client_endpoint.bal index 371c9dd..671a8ca 100644 --- a/cosmosdb/client_endpoint.bal +++ b/cosmosdb/client_endpoint.bal @@ -63,7 +63,7 @@ public isolated client class DataPlaneClient { # # + databaseId - ID of the database to which the container belongs to # + containerId - ID of the container which contains the existing document - # + documemtId - ID of the document + # + documentId - Current ID of the document # + document - A JSON document which will replace the existing document # + partitionKey - The specific value related to the partition key field of the container # + requestOptions - The `cosmos_db:RequestOptions` which can be used to add additional capabilities that can @@ -72,14 +72,18 @@ public isolated client class DataPlaneClient { @display {label: "Replace Document"} remote isolated function replaceDocument(@display {label: "Database ID"} string databaseId, @display {label: "Container ID"} string containerId, - @display {label: "Document ID"} string documemtId, + @display {label: "Document ID"} string documentId, @display {label: "New Document"} map document, @display {label: "Partition Key"} int|float|decimal|string partitionKey, @display {label: "Optional Header Parameters"} RequestOptions? requestOptions = ()) returns DocumentResponse|error { - json jsonDocument = check document.cloneWithType(json); - json updatedDocument = check jsonDocument.mergeJson({"id": documemtId}); - return replaceDocument(databaseId, containerId, documemtId, >updatedDocument, partitionKey, + json updatedDocument = check document.cloneWithType(json); + // If the doument doesn't contain an id, the document will not replace the id in the database. + // If the document contains an id, it will replace the existing id in the database. + if !document.hasKey("id") { + updatedDocument = check updatedDocument.mergeJson({"id": documentId}); + } + return replaceDocument(databaseId, containerId, documentId, >updatedDocument, partitionKey, requestOptions); } @@ -156,7 +160,7 @@ public isolated client class DataPlaneClient { @display {label: "Container ID"} string containerId, @display {label: "SQL Query"} string sqlQuery, @display {label: "Optional Header Parameters"} QueryOptions? queryOptions - = (), typedesc returnType = <>) + = (), typedesc returnType = <>) returns stream|error = @java:Method { 'class: "io.ballerinax.cosmosdb.DataplaneClient" } external; @@ -168,13 +172,13 @@ public isolated client class DataPlaneClient { # + storedProcedureId - A unique ID for the newly created stored procedure # + storedProcedure - A JavaScript function represented as a string # + options - The `cosmos_db:CosmosStoredProcedureRequestOptions` which can be used to add additional capabilities - # that can override client configuration provided in the inilization + # that can override client configuration provided in the inilization # + return - If successful, returns a `cosmos_db:StoredProcedure`. Else returns error. @display {label: "Create Stored Procedure"} remote isolated function createStoredProcedure(@display {label: "Database ID"} string databaseId, @display {label: "Container ID"} string containerId, @display {label: "Stored Procedure ID"} string storedProcedureId, - @display {label: "Stored Procedure Function"} string + @display {label: "Stored Procedure Function"} string storedProcedure, CosmosStoredProcedureRequestOptions? options = ()) returns StoredProcedureResponse|error { return createStoredProcedure(databaseId, containerId, storedProcedureId, storedProcedure, options); @@ -220,7 +224,7 @@ public isolated client class DataPlaneClient { remote isolated function executeStoredProcedure(@display {label: "Database ID"} string databaseId, @display {label: "Container ID"} string containerId, @display {label: "Stored Procedure ID"} string storedProcedureId, - @display {label: "Partition Key"} int|float|decimal|string + @display {label: "Partition Key"} int|float|decimal|string patitionKey, @display {label: "Execution Options"} StoredProcedureExecuteOptions? storedProcedureExecuteOptions = ()) returns StoredProcedureResponse|error = @java:Method { @@ -239,21 +243,21 @@ customConfig = ()) returns error? = @java:Method { } external; isolated function createDocument(string databaseId, string containerId, - map document, int|float|decimal|string partitionKey, RequestOptions? + map document, int|float|decimal|string partitionKey, RequestOptions? documentCreateOptions = ()) returns DocumentResponse|error = @java:Method { 'class: "io.ballerinax.cosmosdb.DataplaneClient" } external; isolated function replaceDocument(string databaseId, string containerId, string id, map document, int|float|decimal|string partitionKey, - RequestOptions? documentCreateOptions = ()) returns DocumentResponse|error = + RequestOptions? documentCreateOptions = ()) returns DocumentResponse|error = @java:Method { 'class: "io.ballerinax.cosmosdb.DataplaneClient" } external; isolated function createStoredProcedure(string databaseId, string containerId, string storedProcedureId, string storedProcedure, - CosmosStoredProcedureRequestOptions? options = ()) returns + CosmosStoredProcedureRequestOptions? options = ()) returns StoredProcedureResponse|error = @java:Method { 'class: "io.ballerinax.cosmosdb.DataplaneClient" } external; diff --git a/cosmosdb/tests/test.bal b/cosmosdb/tests/test.bal index a538c90..1ea9e08 100644 --- a/cosmosdb/tests/test.bal +++ b/cosmosdb/tests/test.bal @@ -398,7 +398,8 @@ function testCreateDocument() returns error? { testGetOneDocumentWithRequestOptions, testQueryDocuments, testGetDocumentList, - testGetDocumentListWithRequestOptions] + testGetDocumentListWithRequestOptions + ] } function testReplaceDocument() returns error? { log:printInfo("ACTION : replaceDocument()"); @@ -413,6 +414,58 @@ function testReplaceDocument() returns error? { test:assertEquals(response.statusCode, 200); } +@test:Config { + groups: ["document"], + dependsOn: [testCreateContainer] +} +function testReplaceDocumentID() returns error? { + log:printInfo("ACTION : replaceDocumentID()"); + + int valueOfPartitionKey = 1234; + string documentId = string `document_${randomString.toString()}`; + map documentBody = { + "LastName": "Einstein", + "Parents": [ + { + "FamilyName": null, + "FirstName": "Hermann" + }, + { + "FamilyName": null, + "FirstName": "Pauline" + } + ], + "Children": [ + { + "FamilyName": null, + "FirstName": "Hans", + "Gender": "male", + "Grade": 5, + "Pets": [{"GivenName": "Pumpkin"}] + } + ], + "Address": { + "State": "WA", + "Country": "King", + "City": "Seattle" + }, + "IsRegistered": true, + "AccountNumber": 1234 + }; + + DocumentResponse createResponse = check azureCosmosClient->createDocument(databaseId, containerId, documentId, documentBody, valueOfPartitionKey); + test:assertEquals(createResponse.statusCode, 201); + + map updatedDocumentBody = { + "LastName": "Antony", + "AccountNumber": 1234, + "id": "new_document_123" + }; + + DocumentResponse updateResponse = check azureCosmosClient->replaceDocument(databaseId, containerId, documentId, updatedDocumentBody, valueOfPartitionKey); + test:assertEquals(updateResponse.statusCode, 200); +} + @test:Config { groups: ["document"], dependsOn: [testCreateContainer] @@ -478,7 +531,6 @@ public type Pet record { string GivenName; }; - @test:Config { groups: ["document"], dependsOn: [testCreateDocument, testCreateDocumentWithRequestOptions] @@ -486,7 +538,7 @@ public type Pet record { function testGetDocumentList() returns error? { log:printInfo("ACTION : getDocumentList()"); int valueOfPartitionKey = 1234; - stream result = check azureCosmosClient->getDocumentList(databaseId, containerId, + stream result = check azureCosmosClient->getDocumentList(databaseId, containerId, valueOfPartitionKey); check result.forEach(isolated function(Person queryResult) { test:assertEquals(1234, queryResult.AccountNumber); @@ -503,7 +555,7 @@ function testGetDocumentListWithRequestOptions() returns error? { QueryOptions options = { consistencyLevel: EVENTUAL }; - stream result = check azureCosmosClient->getDocumentList(databaseId, containerId, + stream result = check azureCosmosClient->getDocumentList(databaseId, containerId, valueOfPartitionKey, options); check result.forEach(isolated function(Person queryResult) { test:assertEquals(1234, queryResult.AccountNumber); @@ -609,7 +661,7 @@ function testCreateStoredProcedure() returns error? { response.setBody("Hello, World"); }`; - StoredProcedureResponse response = check azureCosmosClient->createStoredProcedure(databaseId, containerId, sprocId, + StoredProcedureResponse response = check azureCosmosClient->createStoredProcedure(databaseId, containerId, sprocId, createSprocBody); test:assertEquals(response.statusCode, 201); } @@ -627,7 +679,7 @@ function testExecuteOneStoredProcedure() returns error? { int partitionKey = 1234; _ = check azureCosmosClient->executeStoredProcedure(databaseId, containerId, sprocId, partitionKey, options); - + } @test:Config {