public void WriteCounter(CounterGroupDetail counterDetail) { CountersStorage.ConvertFromBlobToNumbers(_context, counterDetail); using (counterDetail) { if (First == false) { Writer.WriteComma(); } First = false; Writer.WriteStartObject(); Writer.WritePropertyName(nameof(CounterItem.DocId)); Writer.WriteString(counterDetail.DocumentId, skipEscaping: true); Writer.WriteComma(); Writer.WritePropertyName(nameof(CounterItem.ChangeVector)); Writer.WriteString(counterDetail.ChangeVector, skipEscaping: true); Writer.WriteComma(); Writer.WritePropertyName(nameof(CounterItem.Batch.Values)); Writer.WriteObject(counterDetail.Values); Writer.WriteEndObject(); } }
private bool GetCounterValueAndCheckIfShouldSkip(LazyStringValue docId, string function, BlittableJsonReaderObject.PropertyDetails prop, out long value, out bool delete) { value = 0; if (prop.Value is LazyStringValue) { // a deleted counter is marked // with a change-vector string delete = true; } else { delete = false; value = CountersStorage.InternalGetCounterValue(prop.Value as BlittableJsonReaderObject.RawBlob, docId, prop.Name); if (function != null) { using (var result = BehaviorsScript.Run(Context, Context, function, new object[] { docId, prop.Name })) { if (result.BooleanValue != true) { return(true); } } } } return(false); }
public HandleCountersReferences(Index index, Dictionary <string, HashSet <CollectionName> > referencedCollections, CountersStorage countersStorage, DocumentsStorage documentsStorage, IndexStorage indexStorage, Config.Categories.IndexingConfiguration configuration) : base(index, referencedCollections, documentsStorage, indexStorage, indexStorage.ReferencesForDocuments, configuration) { _countersStorage = countersStorage; }
public override void Transform(RavenEtlItem item) { Current = item; _currentRun = new RavenEtlScriptRun(); if (item.IsDelete == false) { switch (item.Type) { case EtlItemType.Document: if (_script.HasTransformation) { // first, we need to delete docs prefixed by modified document ID to properly handle updates of // documents loaded to non default collections ApplyDeleteCommands(item, OperationType.Put); DocumentScript.Run(Context, Context, "execute", new object[] { Current.Document }).Dispose(); if (_script.HasLoadCounterBehaviors && _script.TryGetLoadCounterBehaviorFunctionFor(item.Collection, out var function)) { foreach (var counter in GetCountersFor(Current)) { using (var result = BehaviorsScript.Run(Context, Context, function, new object[] { item.DocumentId, counter.Name })) { if (result.BooleanValue == true) { _currentRun.AddCounter(item.DocumentId, counter.Name, counter.Value); } } } } } else { _currentRun.PutFullDocument(item.DocumentId, item.Document.Data, GetAttachmentsFor(item), GetCountersFor(item)); } break; case EtlItemType.Counter: if (_script.HasTransformation) { if (_script.HasLoadCounterBehaviors == false) { break; } if (_script.TryGetLoadCounterBehaviorFunctionFor(item.Collection, out var function) == false) { break; } using (var result = BehaviorsScript.Run(Context, Context, function, new object[] { item.DocumentId, item.CounterName })) { if (result.BooleanValue == true) { _currentRun.AddCounter(item.DocumentId, item.CounterName, item.CounterValue); } } } else { _currentRun.AddCounter(item.DocumentId, item.CounterName, item.CounterValue); } break; } } else { switch (item.Type) { case EtlItemType.Document: if (_script.HasTransformation) { Debug.Assert(item.IsAttachmentTombstone == false, "attachment tombstones are tracked only if script is empty"); bool shouldDelete = true; if (_script.HasDeleteDocumentsBehaviors && _script.TryGetDeleteDocumentBehaviorFunctionFor(item.Collection, out var function)) { using (var result = BehaviorsScript.Run(Context, Context, function, new object[] { item.DocumentId })) { shouldDelete = result.BooleanValue == true; } } if (shouldDelete) { ApplyDeleteCommands(item, OperationType.Delete); } } else { if (item.IsAttachmentTombstone == false) { _currentRun.Delete(new DeleteCommandData(item.DocumentId, null)); } else { var(doc, attachmentName) = AttachmentsStorage.ExtractDocIdAndAttachmentNameFromTombstone(Context, item.AttachmentTombstoneId); _currentRun.DeleteAttachment(doc, attachmentName); } } break; case EtlItemType.Counter: var(docId, counterName) = CountersStorage.ExtractDocIdAndCounterNameFromTombstone(Context, item.CounterTombstoneId); if (_script.HasTransformation) { if (_script.HasLoadCounterBehaviors == false) { break; } if (_script.TryGetLoadCounterBehaviorFunctionFor(item.Collection, out var function) == false) { break; } using (var result = BehaviorsScript.Run(Context, Context, function, new object[] { docId, counterName })) { if (result.BooleanValue == true) { _currentRun.DeleteCounter(docId, counterName); } } } else { _currentRun.DeleteCounter(docId, counterName); } break; } } _commands.AddRange(_currentRun.GetCommands()); }
public MapCounters(Index index, CountersStorage countersStorage, IndexStorage indexStorage, MapReduceIndexingContext mapReduceContext, IndexingConfiguration configuration) : base(index, indexStorage, mapReduceContext, configuration) { _countersStorage = countersStorage; }
public HandleCompareExchangeCountersReferences(Index index, HashSet <string> collectionsWithCompareExchangeReferences, CountersStorage countersStorage, DocumentsStorage documentsStorage, IndexStorage indexStorage, IndexingConfiguration configuration) : base(index, collectionsWithCompareExchangeReferences, documentsStorage, indexStorage, configuration) { _collectionsWithCompareExchangeReferences = collectionsWithCompareExchangeReferences; _countersStorage = countersStorage; }
public override void Transform(RavenEtlItem item) { Current = item; _currentRun = new RavenEtlScriptRun(); if (item.IsDelete == false) { switch (item.Type) { case EtlItemType.Document: if (_script.HasTransformation) { // first, we need to delete docs prefixed by modified document ID to properly handle updates of // documents loaded to non default collections ApplyDeleteCommands(item, OperationType.Put); DocumentScript.Run(Context, Context, "execute", new object[] { Current.Document }).Dispose(); if (_script.HasLoadCounterBehaviors && _script.TryGetLoadCounterBehaviorFunctionFor(item.Collection, out var function)) { var counters = GetCountersFor(Current); if (counters != null && counters.Count > 0) { foreach (var counter in counters) { using (var result = BehaviorsScript.Run(Context, Context, function, new object[] { item.DocumentId, counter.Name })) { if (result.BooleanValue == true) { _currentRun.AddCounter(item.DocumentId, counter.Name, counter.Value); } } } } } } else { _currentRun.PutFullDocument(item.DocumentId, item.Document.Data, GetAttachmentsFor(item), GetCountersFor(item)); } break; case EtlItemType.Counter: if (_script.HasTransformation) { if (_script.HasLoadCounterBehaviors == false) { break; } if (_script.TryGetLoadCounterBehaviorFunctionFor(item.Collection, out var function) == false) { break; } using (var result = BehaviorsScript.Run(Context, Context, function, new object[] { item.DocumentId, item.CounterName })) { if (result.BooleanValue == true) { _currentRun.AddCounter(item.DocumentId, item.CounterName, item.CounterValue); } } } else { _currentRun.AddCounter(item.DocumentId, item.CounterName, item.CounterValue); } break; } } else { switch (item.Type) { case EtlItemType.Document: if (ShouldFilterOutDeletion()) { break; } if (_script.HasTransformation) { Debug.Assert(item.IsAttachmentTombstone == false, "attachment tombstones are tracked only if script is empty"); ApplyDeleteCommands(item, OperationType.Delete); } else { if (item.IsAttachmentTombstone == false) { _currentRun.Delete(new DeleteCommandData(item.DocumentId, null)); } else { var(doc, attachmentName) = AttachmentsStorage.ExtractDocIdAndAttachmentNameFromTombstone(Context, item.AttachmentTombstoneId); _currentRun.DeleteAttachment(doc, attachmentName); } } break; case EtlItemType.Counter: var(docId, counterName) = CountersStorage.ExtractDocIdAndCounterNameFromTombstone(Context, item.CounterTombstoneId); if (_script.HasTransformation) { if (_script.HasLoadCounterBehaviors == false) { break; } if (_script.TryGetLoadCounterBehaviorFunctionFor(item.Collection, out var function) == false) { break; } using (var result = BehaviorsScript.Run(Context, Context, function, new object[] { docId, counterName })) { if (result.BooleanValue == true) { _currentRun.DeleteCounter(docId, counterName); } } } else { if (ShouldFilterOutDeletion()) { break; } _currentRun.DeleteCounter(docId, counterName); } break; } bool ShouldFilterOutDeletion() { if (_script.HasDeleteDocumentsBehaviors) { var collection = item.Collection ?? item.CollectionFromMetadata; var documentId = item.DocumentId; if (item.IsAttachmentTombstone) { documentId = AttachmentsStorage.ExtractDocIdAndAttachmentNameFromTombstone(Context, item.AttachmentTombstoneId).DocId; Debug.Assert(collection == null); var document = Database.DocumentsStorage.Get(Context, documentId); if (document == null) { return(true); // document was deleted, no need to send DELETE of attachment tombstone } collection = Database.DocumentsStorage.ExtractCollectionName(Context, document.Data).Name; } else if (item.Type == EtlItemType.Counter) { documentId = CountersStorage.ExtractDocIdAndCounterNameFromTombstone(Context, item.CounterTombstoneId).DocId; } Debug.Assert(collection != null); if (_script.TryGetDeleteDocumentBehaviorFunctionFor(collection, out var function) || _script.TryGetDeleteDocumentBehaviorFunctionFor(Transformation.GenericDeleteDocumentsBehaviorFunctionKey, out function)) { object[] parameters; if (Transformation.GenericDeleteDocumentsBehaviorFunctionName.Equals(function, StringComparison.OrdinalIgnoreCase)) { parameters = new object[] { documentId, collection } } ; else { parameters = new object[] { documentId } }; using (var result = BehaviorsScript.Run(Context, Context, function, parameters)) { if (result.BooleanValue == null || result.BooleanValue == false) { return(true); } } } } return(false); } } _commands.AddRange(_currentRun.GetCommands()); }