private async Task <TableResult> HandleMergeAsync(TableOperation operation, CloudTableClient client, CloudTable table, TableRequestOptions options, OperationContext context)
        {
            ResourceResponse <Document> readResponse = await client.DocumentClient.ReadDocumentAsync(
                UriFactory.CreateDocumentUri(StellarConstants.TableDatabaseName, table.Name, operation.Entity.RowKey),
                new RequestOptions { PartitionKey = new PartitionKey(operation.Entity.PartitionKey) });

            Document mergedDocument = readResponse.Resource;
            Document newDocument    = EntityHelpers.GetDocumentFromEntity(operation.Entity, context, options);

            foreach (KeyValuePair <string, EntityProperty> property in operation.Entity.WriteEntity(context))
            {
                mergedDocument.SetPropertyValue(property.Key, newDocument.GetPropertyValue <object>(property.Key));
            }

            ResourceResponse <Document> updateResponse = await client.DocumentClient.ReplaceDocumentAsync(
                mergedDocument,
                new RequestOptions
            {
                AccessCondition =
                    new Microsoft.Azure.Documents.Client.AccessCondition
                {
                    Type      = AccessConditionType.IfMatch,
                    Condition = readResponse.Resource.ETag
                }
            });

            context.RequestResults.Add(updateResponse.ToRequestResult());
            return(this.GetTableResultFromResponse(operation, updateResponse, context, options));
        }
        private async Task <TableResult> HandleInsertOrMergeAsync(
            TableOperation operation,
            CloudTableClient client,
            CloudTable table,
            TableRequestOptions options,
            OperationContext context)
        {
            Document document = EntityHelpers.GetDocumentFromEntity(operation.Entity, context, options);

            try
            {
                ResourceResponse <Document> response = await client.DocumentClient.CreateDocumentAsync(table.GetCollectionUri(), document);

                context.RequestResults.Add(response.ToRequestResult());
                return(this.GetTableResultFromResponse(operation, response, context, options));
            }
            catch (DocumentClientException exception)
            {
                if (exception.StatusCode != HttpStatusCode.Conflict)
                {
                    throw;
                }
            }

            return(await this.HandleMergeAsync(operation, client, table, options, context));
        }
        private async Task <TableResult> HandleUpsertAsync(TableOperation operation, CloudTableClient client, CloudTable table, TableRequestOptions options, OperationContext context)
        {
            Document document = EntityHelpers.GetDocumentFromEntity(operation.Entity, context, options);
            ResourceResponse <Document> response = await client.DocumentClient.UpsertDocumentAsync(table.GetCollectionUri(), document);

            context.RequestResults.Add(response.ToRequestResult());
            return(this.GetTableResultFromResponse(operation, response, context, options));
        }
        private async Task <TableResult> HandleReplaceAsync(TableOperation operation, CloudTableClient client, CloudTable table, TableRequestOptions options, OperationContext context)
        {
            Document       document       = EntityHelpers.GetDocumentFromEntity(operation.Entity, context, options);
            RequestOptions requestOptions = null;
            Uri            documentUri    = this.GetDocumentUri(operation, table, out requestOptions);

            if (!string.IsNullOrEmpty(operation.Entity.ETag))
            {
                requestOptions.AccessCondition = new Microsoft.Azure.Documents.Client.AccessCondition {
                    Type = AccessConditionType.IfMatch, Condition = operation.Entity.ETag
                };
            }

            ResourceResponse <Document> response = await client.DocumentClient.ReplaceDocumentAsync(documentUri, document, requestOptions);

            context.RequestResults.Add(response.ToRequestResult());
            return(this.GetTableResultFromResponse(operation, response, context, options));
        }
        private async Task <TableResult> HandleInsertAsync(TableOperation operation, CloudTableClient client, CloudTable table, TableRequestOptions options, OperationContext context)
        {
            if (operation.IsTableEntity)
            {
                await client.DocumentClient.CreateDatabaseIfNotExistsAsync(new Database { Id = StellarConstants.TableDatabaseName });

                string collectionName = ((DynamicTableEntity)operation.Entity).Properties[TableConstants.TableName].StringValue;

                RequestOptions requestOptions     = null;
                string         collectionRUConfig = ConfigurationManager.AppSettings["DocumentDbCollectionRU"];
                int            collectionRU       = 0;
                if (!string.IsNullOrEmpty(collectionRUConfig) && int.TryParse(collectionRUConfig, out collectionRU))
                {
                    requestOptions = new RequestOptions {
                        OfferThroughput = collectionRU
                    };
                }

                ResourceResponse <DocumentCollection> response
                    = await client.DocumentClient.CreateDocumentCollectionAsync(
                          UriFactory.CreateDatabaseUri(StellarConstants.TableDatabaseName),
                          new DocumentCollection
                {
                    Id           = collectionName,
                    PartitionKey = new PartitionKeyDefinition()
                    {
                        Paths = { "/" + StellarConstants.PartitionKeyPropertyName }
                    },
                }, requestOptions);

                context.RequestResults.Add(response.ToRequestResult());
                return(EntityHelpers.GetTableResultFromResponse(response, context));
            }
            else
            {
                Document document = EntityHelpers.GetDocumentFromEntity(operation.Entity, context, options);

                ResourceResponse <Document> response = await client.DocumentClient.CreateDocumentAsync(table.GetCollectionUri(), document);

                context.RequestResults.Add(response.ToRequestResult());
                return(this.GetTableResultFromResponse(operation, response, context, options));
            }
        }
Esempio n. 6
0
        private async Task <IList <TableResult> > ExecuteAsync(
            TableBatchOperation batch,
            CloudTableClient client,
            CloudTable table,
            TableRequestOptions requestOptions,
            OperationContext operationContext)
        {
            if (batch.Count == 0)
            {
                throw new InvalidOperationException(SR.EmptyBatchOperation);
            }

            if (batch.Count > 100)
            {
                throw new InvalidOperationException(SR.BatchExceededMaximumNumberOfOperations);
            }

            try
            {
                string          script = StellarBatchExecutor.MakeCreateDocumentsScript();
                StoredProcedure sproc  = await this.GetOrCreateStoredProcedureAsync(table, StellarBatchExecutor.BulkInsertOrMergeOrUpdate, script);

                List <Document>           javaScriptParams1 = new List <Document>();
                List <TableOperationType> javaScriptParams2 = new List <TableOperationType>();
                List <string>             javaScriptParams3 = new List <string>();
                string partitionKey = batch.FirstOrDefault().PartitionKey;
                foreach (TableOperation operation in batch)
                {
                    Document document = null;
                    if (operation.OperationType == TableOperationType.Retrieve)
                    {
                        document = this.GetDocumentWithPartitionAndRowKey(operation.RetrievePartitionKey, operation.RetrieveRowKey);
                    }
                    else
                    {
                        document = EntityHelpers.GetDocumentFromEntity(operation.Entity, operationContext, requestOptions);
                    }

                    javaScriptParams1.Add(document);
                    javaScriptParams2.Add(operation.OperationType);
                    javaScriptParams3.Add(operation.Entity == null ? "" : operation.Entity.ETag);
                }

                RequestOptions docdbRequestOptions = new RequestOptions {
                    PartitionKey = new PartitionKey(partitionKey)
                };
                StoredProcedureResponse <string> response =
                    await table.ServiceClient.DocumentClient.ExecuteStoredProcedureAsync <string>(sproc.SelfLink, docdbRequestOptions,
                                                                                                  javaScriptParams1.ToArray(), javaScriptParams2.ToArray(), javaScriptParams3.ToArray());

                JArray jArray = JArray.Parse(response.Response);

                List <TableResult> tableResults = new List <TableResult>();

                for (int i = 0; i < jArray.Count; i++)
                {
                    tableResults.Add(GetTableResultFromDocument(batch[i], jArray[i].ToObject <Document>(), operationContext));
                }

                return(tableResults);
            }
            catch (Exception ex)
            {
                throw EntityHelpers.GetTableResultFromException(ex);
            }
        }