Esempio n. 1
0
        private void AddSingleCounterGroup(LazyStringValue docId, BlittableJsonReaderObject counterGroupDocument, string function = null)
        {
            if (counterGroupDocument.TryGet(CountersStorage.Values, out BlittableJsonReaderObject counters) == false)
            {
                return;
            }

            var prop = new BlittableJsonReaderObject.PropertyDetails();

            for (var i = 0; i < counters.Count; i++)
            {
                counters.GetPropertyByIndex(i, ref prop);

                if (GetCounterValueAndCheckIfShouldSkip(docId, function, prop, out long value, out bool delete))
                {
                    continue;
                }

                if (delete)
                {
                    _currentRun.DeleteCounter(docId, prop.Name);
                }
                else
                {
                    _currentRun.AddCounter(docId, prop.Name, value);
                }
            }
        }
        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());
        }
Esempio n. 3
0
        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());
        }