Ejemplo n.º 1
0
        private void UpdateCascadeReferencingCollection(ReferencingCollectionSetting rc, ReferencingCollectionOperation co)
        {
            co.StartedDate          = DateTime.UtcNow;
            co.Status               = UpdateCascadeOperationStatus.Executing;
            co.UpdatedDocumentCount = 0;
            SaveOperationSilentlyIgnoringError();             // we can continue anyway
            log.Trace("Update cascade {0} referencing document collection for update cascade operation {1} started", rc.ReferencingEntityName, operation.Id);
            try
            {
                int  updatedByIndex = 0;
                Guid lastEtag;
                do
                {
                    lastEtag = db.GetLastEtag();
                    var query = new IndexQuery
                    {
                        CutoffEtag = lastEtag,
                        Query      = string.Format("{0}:{1} AND {2}:{3}NULL TO {4}{5}", rc.ReferencedIdPropertyNameInIndex, RavenQuery.Escape(referencedDoc.Key),
                                                   rc.ReferencedEtagPropertyNameInIndex, "{", RavenQuery.Escape(Convert.ToString(referencedDoc.Etag, CultureInfo.InvariantCulture)), "}")
                    };
                    updatedByIndex = db.UpdateByIndex(rc.IndexName, query, doc => UpdateDocumentWithProgressReport(doc, co),
                                                      TimeSpan.FromHours(8), cancellationToken, null);
                } while (updatedByIndex > 0);

                db.UpdateDocumentsAfter(lastEtag, UpdateDocument, cancellationToken, null);
                co.Status = UpdateCascadeOperationStatus.CompletedSuccessfully;
                log.Trace("Update cascade {0} documents for operation {1} completed successfully. {2} documents have been updated in {3}", rc.ReferencingEntityName, operation.Id, co.UpdatedDocumentCount, co.ElapsedTime);
            }
            catch (OperationCanceledException)             // save the operation and rethrow
            {
                co.Status = UpdateCascadeOperationStatus.Canceled;
                throw;
            }
            catch (Exception ex)             // Log the error, save the operation, and move to the next.
            {
                co.ErrorMessage = ex.Message;
                co.Status       = UpdateCascadeOperationStatus.Failed;
                log.ErrorException(string.Format("Update cascade {0} documents for operation {1} failed miserably. Moving on the next one ...", rc.ReferencingEntityName, operation.Id), ex);
            }
            finally
            {
                co.CompletedDate = DateTime.UtcNow;
                if (!(services.IsShutDownInProgress && co.Status == UpdateCascadeOperationStatus.Canceled))
                {
                    SaveOperationSilentlyIgnoringError();                     // we want to preserve OperationCanceledException.
                }
            }
        }
Ejemplo n.º 2
0
        private bool UpdateDocument(JsonDocument referencingDocument)
        {
            var referencingEntityName = referencingDocument.Metadata.Value <string>(Constants.RavenEntityName);
            ReferencingCollectionSetting referencingCollectionSetting = null;

            if (!this.setting.ReferencingCollections.TryGetValue(referencingEntityName, out referencingCollectionSetting))
            {
                log.Debug("{0} document doesn't need to be cascade updated because it doesn't belong to any document collection that hold denormalized references to {1}. Operation {2} ", referencingDocument.Key, setting.ReferencedEntityName, operation.Id);
                return(false);
            }

            var  denormalizedReferences = referencingDocument.DataAsJson.GetObjectsAtPath(referencingCollectionSetting.ReferencingPropertyPath);
            bool shouldUpdate           = false;

            foreach (var reference in denormalizedReferences)
            {
                Guid?referencedEtag  = reference.Value <Guid?>("Etag");
                var  referencedDocId = reference.Value <string>("Id");

                if (referencedDocId == referencedDoc.Key && (referencedEtag == null ||
                                                             Buffers.Compare(referencedEtag.Value.ToByteArray(), referencedDoc.Etag.Value.ToByteArray()) < 0))
                {
                    shouldUpdate = true;
                    foreach (var property in setting.DenormalizedReferencePropertyNames)
                    {
                        reference[property] = referencedDoc.DataAsJson[property].CloneToken();
                    }
                    reference["Etag"] = RavenJToken.FromObject(referencedDoc.Etag.Value);
                }
            }
            if (shouldUpdate)
            {
                log.Debug("{0} document has been cascade updated in memory beacause it references {1} document and its referencing Etag is prior to the referenced document one {2}", referencingDocument.Key, referencedDoc.Key, referencedDoc.Etag);
            }
            else
            {
                log.Debug("{0} document has not been cascade updated in memory beacause it does not references {1} document or its referencing Etag is subsequent to the referenced document one {2}", referencingDocument.Key, referencedDoc.Key, referencedDoc.Etag);
            }
            return(shouldUpdate);
        }
        private void UpdateCascadeReferencingCollection(ReferencingCollectionSetting rc, ReferencingCollectionOperation co)
        {
            co.StartedDate = DateTime.UtcNow;
            co.Status = UpdateCascadeOperationStatus.Executing;
            co.UpdatedDocumentCount = 0;
            SaveOperationSilentlyIgnoringError(); // we can continue anyway
            log.Trace("Update cascade {0} referencing document collection for update cascade operation {1} started", rc.ReferencingEntityName, operation.Id);
            try
            {
                int updatedByIndex = 0;
                Guid lastEtag;
                do
                {
                    lastEtag = db.GetLastEtag();
                    var query = new IndexQuery
                    {
                        CutoffEtag = lastEtag,
                        Query = string.Format("{0}:{1} AND {2}:{3}NULL TO {4}{5}", rc.ReferencedIdPropertyNameInIndex, RavenQuery.Escape(referencedDoc.Key),
                            rc.ReferencedEtagPropertyNameInIndex, "{", RavenQuery.Escape(Convert.ToString(referencedDoc.Etag, CultureInfo.InvariantCulture)), "}")

                    };
                    updatedByIndex = db.UpdateByIndex(rc.IndexName, query, doc => UpdateDocumentWithProgressReport(doc, co),
                        TimeSpan.FromHours(8), cancellationToken, null);

                } while (updatedByIndex > 0);

                db.UpdateDocumentsAfter(lastEtag, UpdateDocument, cancellationToken, null);
                co.Status = UpdateCascadeOperationStatus.CompletedSuccessfully;
                log.Trace("Update cascade {0} documents for operation {1} completed successfully. {2} documents have been updated in {3}", rc.ReferencingEntityName, operation.Id, co.UpdatedDocumentCount, co.ElapsedTime);
            }
            catch (OperationCanceledException) // save the operation and rethrow
            {
                co.Status = UpdateCascadeOperationStatus.Canceled;
                throw;
            }
            catch (Exception ex) // Log the error, save the operation, and move to the next.
            {
                co.ErrorMessage = ex.Message;
                co.Status = UpdateCascadeOperationStatus.Failed;
                log.ErrorException(string.Format("Update cascade {0} documents for operation {1} failed miserably. Moving on the next one ...", rc.ReferencingEntityName, operation.Id), ex);
            }
            finally
            {
                co.CompletedDate = DateTime.UtcNow;
                if (!(services.IsShutDownInProgress && co.Status == UpdateCascadeOperationStatus.Canceled))
                    SaveOperationSilentlyIgnoringError(); // we want to preserve OperationCanceledException.
            }
        }